From 63b838e4853a4380fed94d6e6fb6a7a78c75aea0 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 4 Mar 2026 17:00:23 +0800 Subject: [PATCH 01/31] refactor(wip): svelte4 => svelte5 --- .vscode/settings.json | 3 +- backend/modelscope_studio/__init__.py | 1 - .../modelscope_studio/components/__init__.py | 1 - .../components/base/div/__init__.py | 5 +- .../components/base/slot/__init__.py | 2 - .../components/legacy/Chatbot/__init__.py | 372 - .../legacy/Chatbot/llm_thinking_presets.py | 9 - .../components/legacy/Flow/__init__.py | 146 - .../components/legacy/Flow/edge.py | 17 - .../components/legacy/Flow/node.py | 16 - .../components/legacy/Flow/node_schema.py | 63 - .../components/legacy/Lifecycle/__init__.py | 100 - .../components/legacy/Markdown/__init__.py | 130 - .../legacy/MultimodalInput/__init__.py | 216 - .../legacy/WaterfallGallery/__init__.py | 266 - .../components/legacy/__init__.py | 7 - .../components/legacy/components.py | 14 - backend/modelscope_studio/external.py | 354 - config/changelog/package.json | 6 +- config/lint-config/configs/eslint/basic.mjs | 2 +- config/lint-config/configs/eslint/react.mjs | 13 +- config/lint-config/configs/eslint/svelte.mjs | 3 +- config/lint-config/package.json | 24 +- docs/api/app.py | 19 - docs/api/load-zh_CN.md | 30 - docs/api/load.md | 30 - docs/app.py | 6 - .../components/legacy/Chatbot/README-zh_CN.md | 144 - docs/components/legacy/Chatbot/README.md | 143 - docs/components/legacy/Chatbot/app.py | 6 - .../legacy/Chatbot/demos/accordion.py | 51 - docs/components/legacy/Chatbot/demos/basic.py | 55 - docs/components/legacy/Chatbot/demos/chart.py | 43 - .../legacy/Chatbot/demos/message_config.py | 35 - .../legacy/Chatbot/demos/multi_bots.py | 87 - .../legacy/Chatbot/demos/multimodal.py | 39 - .../legacy/Chatbot/demos/select-box.py | 48 - docs/components/legacy/Docs.py | 178 - docs/components/legacy/Flow/README-zh_CN.md | 109 - docs/components/legacy/Flow/README.md | 108 - docs/components/legacy/Flow/app.py | 6 - .../legacy/Flow/define_schema-zh_CN.md | 266 - docs/components/legacy/Flow/define_schema.md | 262 - docs/components/legacy/Flow/demos/basic.py | 35 - .../legacy/Flow/demos/component_options.py | 109 - .../legacy/Flow/demos/custom_node_type.py | 69 - .../legacy/Flow/schema/agents_schema.json | 66 - .../legacy/Flow/schema/agents_schema.py | 59 - .../legacy/Lifecycle/README-zh_CN.md | 53 - docs/components/legacy/Lifecycle/README.md | 53 - docs/components/legacy/Lifecycle/app.py | 6 - .../legacy/Lifecycle/demos/basic.py | 28 - .../Lifecycle/demos/language_adaptation.py | 41 - .../Lifecycle/demos/theme_adaptation.py | 28 - .../legacy/Markdown/README-zh_CN.md | 97 - docs/components/legacy/Markdown/README.md | 92 - docs/components/legacy/Markdown/app.py | 20 - .../Markdown/custom_tags/accordion-zh_CN.md | 23 - .../legacy/Markdown/custom_tags/accordion.md | 22 - .../Markdown/custom_tags/chart-zh_CN.md | 17 - .../legacy/Markdown/custom_tags/chart.md | 17 - .../Markdown/custom_tags/select-box-zh_CN.md | 45 - .../legacy/Markdown/custom_tags/select-box.md | 45 - .../legacy/Markdown/demos/accordion.py | 28 - .../components/legacy/Markdown/demos/basic.py | 11 - .../components/legacy/Markdown/demos/chart.py | 31 - .../legacy/Markdown/demos/custom-tag.py | 21 - .../legacy/Markdown/demos/custom-tag2.py | 55 - .../legacy/Markdown/demos/custom-tag3.py | 31 - .../legacy/Markdown/demos/custom-tag4.py | 38 - .../custom_tags/accordion/accordion-title.py | 19 - .../demos/custom_tags/accordion/basic.py | 17 - .../Markdown/demos/custom_tags/chart/basic.py | 84 - .../demos/custom_tags/select-box/basic.py | 21 - .../custom_tags/select-box/card_shape.py | 33 - .../select-box/card_shape_width_auto.py | 27 - .../custom_tags/select-box/python_events.py | 24 - .../legacy/Markdown/demos/multimodal.py | 27 - .../legacy/Markdown/demos/select-box.py | 32 - .../legacy/MultimodalInput/README-zh_CN.md | 50 - .../legacy/MultimodalInput/README.md | 50 - docs/components/legacy/MultimodalInput/app.py | 6 - .../legacy/MultimodalInput/demos/basic.py | 16 - .../MultimodalInput/demos/config_buttons.py | 16 - .../MultimodalInput/demos/upload_sources.py | 15 - .../MultimodalInput/demos/with_chatbot.py | 36 - docs/components/legacy/README-zh_CN.md | 33 - docs/components/legacy/README.md | 33 - .../legacy/WaterfallGallery/README-zh_CN.md | 71 - .../legacy/WaterfallGallery/README.md | 71 - .../components/legacy/WaterfallGallery/app.py | 6 - .../legacy/WaterfallGallery/demos/basic.py | 30 - .../demos/like_click_feedback.py | 37 - .../WaterfallGallery/demos/load_more.py | 45 - .../demos/responsive_columns.py | 35 - docs/components/legacy/app.py | 34 - docs/components/legacy/parse_markdown.py | 85 - docs/components/legacy/resources/audio.wav | Bin 44844 -> 0 bytes docs/components/legacy/resources/bot.jpeg | Bin 5231 -> 0 bytes .../custom_components/custom_select.js | 29 - .../legacy/resources/image-bot.jpeg | Bin 286675 -> 0 bytes .../legacy/resources/modelscope.svg | 1 - .../legacy/resources/music-bot.jpeg | Bin 219326 -> 0 bytes docs/components/legacy/resources/screen.jpeg | Bin 7128 -> 0 bytes docs/components/legacy/resources/user.jpeg | Bin 16410 -> 0 bytes docs/components/legacy/tab-link.js | 15 - docs/legacy_app.py | 6 - docs/src/pyproject.toml | 11 - frontend/antd/auto-complete/auto-complete.tsx | 7 +- frontend/antd/button/Index.svelte | 105 +- frontend/antd/config-provider/Index.svelte | 101 +- .../antd/config-provider/config-provider.tsx | 5 - frontend/antd/form/item/form.item.tsx | 2 +- frontend/antd/icon/Index.svelte | 100 +- frontend/antd/icon/icon.tsx | 2 +- .../antd/icon/iconfont-provider/Index.svelte | 66 +- .../iconfont-provider/iconfont-provider.tsx | 2 +- frontend/antd/radio/group/radio.group.tsx | 2 +- frontend/antdx/sender/sender.tsx | 2 +- frontend/antdx/suggestion/suggestion.tsx | 2 +- frontend/antdx/x-provider/XProvider.svelte | 2 +- frontend/base/application/Application.svelte | 69 +- frontend/base/application/Index.svelte | 9 +- frontend/base/application/package.json | 8 +- frontend/base/auto-loading/Index.svelte | 131 +- frontend/base/auto-loading/auto-loading.tsx | 12 +- .../base/auto-loading/useLoadingStatus.ts | 4 +- frontend/base/div/Index.svelte | 98 +- frontend/base/div/div.tsx | 4 +- frontend/base/each/Index.svelte | 15 +- frontend/base/each/each.item.tsx | 2 +- frontend/base/each/each.placeholder.tsx | 2 +- frontend/base/each/each.tsx | 2 +- frontend/base/filter/Index.svelte | 2 +- frontend/base/filter/filter.tsx | 2 +- frontend/base/fragment/Index.svelte | 2 +- frontend/base/slot/Index.svelte | 111 +- frontend/fixtures.d.ts | 8 +- .../globals/components/markdown/index.tsx | 19 +- frontend/globals/components/markdown/utils.ts | 3 +- frontend/legacy/Chatbot/Awaited.svelte | 227 - frontend/legacy/Chatbot/CHANGELOG.md | 335 - frontend/legacy/Chatbot/Index.svelte | 15 - frontend/legacy/Chatbot/gradio.config.js | 3 - frontend/legacy/Chatbot/package.json | 24 - frontend/legacy/Chatbot/shared/ChatBot.svelte | 701 -- frontend/legacy/Chatbot/shared/Copy.svelte | 60 - .../Chatbot/shared/FlushingMarkdown.svelte | 116 - .../legacy/Chatbot/shared/LikeDislike.svelte | 48 - frontend/legacy/Chatbot/shared/Pending.svelte | 60 - .../Chatbot/shared/llm-thinking-presets.ts | 206 - frontend/legacy/Chatbot/shared/utils.ts | 161 - frontend/legacy/Flow/Awaited.svelte | 129 - frontend/legacy/Flow/CHANGELOG.md | 336 - frontend/legacy/Flow/Index.svelte | 15 - frontend/legacy/Flow/gradio.config.js | 3 - frontend/legacy/Flow/package.json | 27 - frontend/legacy/Flow/schema.json | 325 - frontend/legacy/Flow/schema.ts | 1 - frontend/legacy/Flow/shared/Flow.svelte | 95 - frontend/legacy/Flow/shared/utils.ts | 6 - frontend/legacy/Lifecycle/CHANGELOG.md | 218 - frontend/legacy/Lifecycle/Index.svelte | 98 - frontend/legacy/Lifecycle/gradio.config.js | 3 - frontend/legacy/Lifecycle/package.json | 22 - frontend/legacy/Lifecycle/shared/utils.ts | 11 - frontend/legacy/Markdown/Awaited.svelte | 93 - frontend/legacy/Markdown/CHANGELOG.md | 335 - frontend/legacy/Markdown/Example.svelte | 43 - frontend/legacy/Markdown/Index.svelte | 15 - frontend/legacy/Markdown/gradio.config.js | 3 - frontend/legacy/Markdown/package.json | 28 - .../legacy/Markdown/shared/Markdown.svelte | 84 - .../legacy/MultimodalInput/Awaited.svelte | 305 - frontend/legacy/MultimodalInput/CHANGELOG.md | 338 - .../legacy/MultimodalInput/Example.svelte | 71 - frontend/legacy/MultimodalInput/Index.svelte | 17 - .../legacy/MultimodalInput/gradio.config.js | 3 - frontend/legacy/MultimodalInput/package.json | 28 - .../shared/AudioRecorder.svelte | 378 - .../MultimodalInput/shared/FilePreview.svelte | 177 - .../MultimodalInput/shared/Input.svelte | 339 - .../MultimodalInput/shared/Loader.svelte | 13 - .../MultimodalInput/shared/RemoveIcon.svelte | 6 - .../shared/SubmitButton.svelte | 22 - .../shared/UploadButton.svelte | 103 - .../MultimodalInput/shared/UploadIcon.svelte | 15 - .../MultimodalInput/shared/Webcam.svelte | 491 - .../legacy/MultimodalInput/shared/context.ts | 11 - .../legacy/MultimodalInput/shared/global.d.ts | 6 - .../legacy/MultimodalInput/shared/utils.ts | 117 - frontend/legacy/WaterfallGallery/CHANGELOG.md | 238 - frontend/legacy/WaterfallGallery/Index.svelte | 125 - .../legacy/WaterfallGallery/gradio.config.js | 3 - frontend/legacy/WaterfallGallery/package.json | 20 - .../WaterfallGallery/shared/Dislike.svelte | 24 - .../WaterfallGallery/shared/Gallery.svelte | 601 -- .../WaterfallGallery/shared/Image.svelte | 152 - .../shared/Waterfall/createWaterfall.ts | 121 - .../shared/Waterfall/index.ts | 25 - .../shared/Waterfall/layout.ts | 70 - .../legacy/WaterfallGallery/shared/utils.ts | 83 - frontend/legacy/compiled/CHANGELOG.md | 275 - .../compiled/components/FileView/index.svelte | 37 - .../FileView/shared/FileView.svelte | 14 - .../compiled/components/Flow/index.svelte | 16 - .../compiled/components/Markdown/index.svelte | 16 - .../compiled/components/ReactComponent.svelte | 40 - frontend/legacy/compiled/global.d.ts | 3 - frontend/legacy/compiled/index.ts | 5 - frontend/legacy/compiled/package.json | 43 - .../compiled/src/ComponentConfigProvider.tsx | 63 - frontend/legacy/compiled/src/FileView/Pdf.tsx | 178 - .../compiled/src/FileView/hooks/usePreview.ts | 19 - .../legacy/compiled/src/FileView/index.less | 27 - .../legacy/compiled/src/FileView/index.tsx | 120 - .../legacy/compiled/src/Flow/FlowContext.ts | 57 - .../src/Flow/components/CustomComponent.tsx | 58 - .../src/Flow/components/FileUpload.tsx | 68 - .../Flow/components/FormListItemWrapper.tsx | 39 - .../Flow/flow-components/ConnectionHandle.tsx | 16 - .../Flow/flow-components/ConnectionLine.tsx | 30 - .../src/Flow/flow-components/Controls.tsx | 105 - .../src/Flow/flow-components/Edge.tsx | 60 - .../src/Flow/flow-components/Node.tsx | 600 -- .../src/Flow/flow-components/Sidebar.tsx | 154 - frontend/legacy/compiled/src/Flow/i18n.ts | 21 - frontend/legacy/compiled/src/Flow/index.less | 235 - frontend/legacy/compiled/src/Flow/index.tsx | 540 -- frontend/legacy/compiled/src/Flow/type.ts | 346 - frontend/legacy/compiled/src/Flow/utils.ts | 375 - .../src/Markdown/components/Anchor.tsx | 19 - .../src/Markdown/components/Audio.tsx | 7 - .../compiled/src/Markdown/components/Code.tsx | 103 - .../Markdown/components/CustomComponent.tsx | 43 - .../src/Markdown/components/Heading.tsx | 68 - .../src/Markdown/components/Image.tsx | 17 - .../src/Markdown/components/Video.tsx | 7 - .../Markdown/components/custom/Accordion.tsx | 113 - .../src/Markdown/components/custom/Chart.tsx | 79 - .../src/Markdown/components/custom/File.tsx | 65 - .../components/custom/FlushingEnd.tsx | 8 - .../Markdown/components/custom/SelectBox.tsx | 270 - .../legacy/compiled/src/Markdown/context.ts | 27 - .../src/Markdown/hooks/useCustomProps.ts | 34 - .../legacy/compiled/src/Markdown/index.less | 218 - .../legacy/compiled/src/Markdown/index.tsx | 282 - frontend/legacy/compiled/src/Markdown/math.ts | 108 - .../compiled/src/Markdown/react-markdown.d.ts | 21 - .../rehype-Inline-code-property.ts | 16 - .../rehype-plugins/rehype-sanitize/index.d.ts | 4 - .../rehype-plugins/rehype-sanitize/index.js | 794 -- .../rehype-plugins/rehype-sanitize/schema.js | 205 - .../remark-plugins/remark-directive-rehype.ts | 41 - frontend/legacy/compiled/src/Markdown/type.ts | 5 - .../legacy/compiled/src/defineComponent.tsx | 14 - frontend/legacy/compiled/src/index.ts | 8 - frontend/legacy/compiled/src/mount.tsx | 20 - frontend/legacy/compiled/src/polyfills.ts | 7 - .../src/shared/hooks/useCustomComponent.ts | 187 - .../src/shared/hooks/useMemoizedEqualValue.ts | 13 - .../compiled/src/shared/hooks/useRefValue.ts | 7 - frontend/legacy/compiled/src/shared/index.ts | 4 - frontend/legacy/compiled/src/shared/type.ts | 7 - frontend/legacy/compiled/src/utils.ts | 47 - frontend/package.json | 62 +- frontend/plugin.js | 4 +- frontend/pro/chatbot/chatbot.less | 68 +- .../pro/multimodal-input/multimodal-input.tsx | 2 +- frontend/svelte-preprocess-react/component.ts | 218 - .../component/import.ts | 20 + .../component/index.ts | 2 + .../component/props.svelte.ts | 376 + frontend/svelte-preprocess-react/index.ts | 3 +- frontend/svelte-preprocess-react/inject.ts | 59 +- .../internal/{Bridge.ts => Bridge.svelte.ts} | 179 +- .../internal/BridgeContext.tsx | 46 +- .../svelte-preprocess-react/internal/Child.ts | 2 +- .../internal/ReactWrapper.svelte | 92 +- .../svelte-preprocess-react/internal/types.ts | 28 +- .../events.ts} | 0 .../{polyfills.ts => polyfills/index.ts} | 1 + frontend/svelte-preprocess-react/provider.ts | 83 - .../{context.ts => react-contexts/index.ts} | 2 +- .../svelte-preprocess-react/react-slot.tsx | 13 +- frontend/svelte-preprocess-react/slot.ts | 290 - .../svelte-contexts/config.svelte.ts | 20 + .../svelte-contexts/each.svelte.ts | 18 + .../svelte-contexts/loading-status.svelte.ts | 75 + .../svelte-contexts/slot.svelte.ts | 102 + .../svelte-contexts/utils.svelte.ts | 43 + .../sveltify.svelte.ts | 111 + frontend/svelte-preprocess-react/sveltify.ts | 101 - frontend/svelte-preprocess-react/useStore.ts | 37 - frontend/utils/createItemsContext.tsx | 4 +- frontend/utils/hooks/useTargets.ts | 19 +- frontend/utils/patchSlots.ts | 1 + frontend/utils/renderItems.tsx | 2 +- frontend/utils/renderParamsSlot.tsx | 6 +- frontend/utils/renderSlot.tsx | 2 +- package.json | 32 +- pnpm-lock.yaml | 8587 ++++++----------- pnpm-workspace.yaml | 19 +- pyproject.toml | 13 +- svelte-tsconfig.json | 3 +- 305 files changed, 4709 insertions(+), 26703 deletions(-) delete mode 100644 backend/modelscope_studio/components/legacy/Chatbot/__init__.py delete mode 100644 backend/modelscope_studio/components/legacy/Chatbot/llm_thinking_presets.py delete mode 100644 backend/modelscope_studio/components/legacy/Flow/__init__.py delete mode 100644 backend/modelscope_studio/components/legacy/Flow/edge.py delete mode 100644 backend/modelscope_studio/components/legacy/Flow/node.py delete mode 100644 backend/modelscope_studio/components/legacy/Flow/node_schema.py delete mode 100644 backend/modelscope_studio/components/legacy/Lifecycle/__init__.py delete mode 100644 backend/modelscope_studio/components/legacy/Markdown/__init__.py delete mode 100644 backend/modelscope_studio/components/legacy/MultimodalInput/__init__.py delete mode 100644 backend/modelscope_studio/components/legacy/WaterfallGallery/__init__.py delete mode 100644 backend/modelscope_studio/components/legacy/__init__.py delete mode 100644 backend/modelscope_studio/components/legacy/components.py delete mode 100644 backend/modelscope_studio/external.py delete mode 100644 docs/api/app.py delete mode 100644 docs/api/load-zh_CN.md delete mode 100644 docs/api/load.md delete mode 100644 docs/components/legacy/Chatbot/README-zh_CN.md delete mode 100644 docs/components/legacy/Chatbot/README.md delete mode 100644 docs/components/legacy/Chatbot/app.py delete mode 100644 docs/components/legacy/Chatbot/demos/accordion.py delete mode 100644 docs/components/legacy/Chatbot/demos/basic.py delete mode 100644 docs/components/legacy/Chatbot/demos/chart.py delete mode 100644 docs/components/legacy/Chatbot/demos/message_config.py delete mode 100644 docs/components/legacy/Chatbot/demos/multi_bots.py delete mode 100644 docs/components/legacy/Chatbot/demos/multimodal.py delete mode 100644 docs/components/legacy/Chatbot/demos/select-box.py delete mode 100644 docs/components/legacy/Docs.py delete mode 100644 docs/components/legacy/Flow/README-zh_CN.md delete mode 100644 docs/components/legacy/Flow/README.md delete mode 100644 docs/components/legacy/Flow/app.py delete mode 100644 docs/components/legacy/Flow/define_schema-zh_CN.md delete mode 100644 docs/components/legacy/Flow/define_schema.md delete mode 100644 docs/components/legacy/Flow/demos/basic.py delete mode 100644 docs/components/legacy/Flow/demos/component_options.py delete mode 100644 docs/components/legacy/Flow/demos/custom_node_type.py delete mode 100644 docs/components/legacy/Flow/schema/agents_schema.json delete mode 100644 docs/components/legacy/Flow/schema/agents_schema.py delete mode 100644 docs/components/legacy/Lifecycle/README-zh_CN.md delete mode 100644 docs/components/legacy/Lifecycle/README.md delete mode 100644 docs/components/legacy/Lifecycle/app.py delete mode 100644 docs/components/legacy/Lifecycle/demos/basic.py delete mode 100644 docs/components/legacy/Lifecycle/demos/language_adaptation.py delete mode 100644 docs/components/legacy/Lifecycle/demos/theme_adaptation.py delete mode 100644 docs/components/legacy/Markdown/README-zh_CN.md delete mode 100644 docs/components/legacy/Markdown/README.md delete mode 100644 docs/components/legacy/Markdown/app.py delete mode 100644 docs/components/legacy/Markdown/custom_tags/accordion-zh_CN.md delete mode 100644 docs/components/legacy/Markdown/custom_tags/accordion.md delete mode 100644 docs/components/legacy/Markdown/custom_tags/chart-zh_CN.md delete mode 100644 docs/components/legacy/Markdown/custom_tags/chart.md delete mode 100644 docs/components/legacy/Markdown/custom_tags/select-box-zh_CN.md delete mode 100644 docs/components/legacy/Markdown/custom_tags/select-box.md delete mode 100644 docs/components/legacy/Markdown/demos/accordion.py delete mode 100644 docs/components/legacy/Markdown/demos/basic.py delete mode 100644 docs/components/legacy/Markdown/demos/chart.py delete mode 100644 docs/components/legacy/Markdown/demos/custom-tag.py delete mode 100644 docs/components/legacy/Markdown/demos/custom-tag2.py delete mode 100644 docs/components/legacy/Markdown/demos/custom-tag3.py delete mode 100644 docs/components/legacy/Markdown/demos/custom-tag4.py delete mode 100644 docs/components/legacy/Markdown/demos/custom_tags/accordion/accordion-title.py delete mode 100644 docs/components/legacy/Markdown/demos/custom_tags/accordion/basic.py delete mode 100644 docs/components/legacy/Markdown/demos/custom_tags/chart/basic.py delete mode 100644 docs/components/legacy/Markdown/demos/custom_tags/select-box/basic.py delete mode 100644 docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape.py delete mode 100644 docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py delete mode 100644 docs/components/legacy/Markdown/demos/custom_tags/select-box/python_events.py delete mode 100644 docs/components/legacy/Markdown/demos/multimodal.py delete mode 100644 docs/components/legacy/Markdown/demos/select-box.py delete mode 100644 docs/components/legacy/MultimodalInput/README-zh_CN.md delete mode 100644 docs/components/legacy/MultimodalInput/README.md delete mode 100644 docs/components/legacy/MultimodalInput/app.py delete mode 100644 docs/components/legacy/MultimodalInput/demos/basic.py delete mode 100644 docs/components/legacy/MultimodalInput/demos/config_buttons.py delete mode 100644 docs/components/legacy/MultimodalInput/demos/upload_sources.py delete mode 100644 docs/components/legacy/MultimodalInput/demos/with_chatbot.py delete mode 100644 docs/components/legacy/README-zh_CN.md delete mode 100644 docs/components/legacy/README.md delete mode 100644 docs/components/legacy/WaterfallGallery/README-zh_CN.md delete mode 100644 docs/components/legacy/WaterfallGallery/README.md delete mode 100644 docs/components/legacy/WaterfallGallery/app.py delete mode 100644 docs/components/legacy/WaterfallGallery/demos/basic.py delete mode 100644 docs/components/legacy/WaterfallGallery/demos/like_click_feedback.py delete mode 100644 docs/components/legacy/WaterfallGallery/demos/load_more.py delete mode 100644 docs/components/legacy/WaterfallGallery/demos/responsive_columns.py delete mode 100644 docs/components/legacy/app.py delete mode 100644 docs/components/legacy/parse_markdown.py delete mode 100644 docs/components/legacy/resources/audio.wav delete mode 100644 docs/components/legacy/resources/bot.jpeg delete mode 100644 docs/components/legacy/resources/custom_components/custom_select.js delete mode 100644 docs/components/legacy/resources/image-bot.jpeg delete mode 100644 docs/components/legacy/resources/modelscope.svg delete mode 100644 docs/components/legacy/resources/music-bot.jpeg delete mode 100644 docs/components/legacy/resources/screen.jpeg delete mode 100644 docs/components/legacy/resources/user.jpeg delete mode 100644 docs/components/legacy/tab-link.js delete mode 100644 docs/legacy_app.py delete mode 100644 frontend/legacy/Chatbot/Awaited.svelte delete mode 100644 frontend/legacy/Chatbot/CHANGELOG.md delete mode 100644 frontend/legacy/Chatbot/Index.svelte delete mode 100644 frontend/legacy/Chatbot/gradio.config.js delete mode 100644 frontend/legacy/Chatbot/package.json delete mode 100644 frontend/legacy/Chatbot/shared/ChatBot.svelte delete mode 100644 frontend/legacy/Chatbot/shared/Copy.svelte delete mode 100644 frontend/legacy/Chatbot/shared/FlushingMarkdown.svelte delete mode 100644 frontend/legacy/Chatbot/shared/LikeDislike.svelte delete mode 100644 frontend/legacy/Chatbot/shared/Pending.svelte delete mode 100644 frontend/legacy/Chatbot/shared/llm-thinking-presets.ts delete mode 100644 frontend/legacy/Chatbot/shared/utils.ts delete mode 100644 frontend/legacy/Flow/Awaited.svelte delete mode 100644 frontend/legacy/Flow/CHANGELOG.md delete mode 100644 frontend/legacy/Flow/Index.svelte delete mode 100644 frontend/legacy/Flow/gradio.config.js delete mode 100644 frontend/legacy/Flow/package.json delete mode 100644 frontend/legacy/Flow/schema.json delete mode 100644 frontend/legacy/Flow/schema.ts delete mode 100644 frontend/legacy/Flow/shared/Flow.svelte delete mode 100644 frontend/legacy/Flow/shared/utils.ts delete mode 100644 frontend/legacy/Lifecycle/CHANGELOG.md delete mode 100644 frontend/legacy/Lifecycle/Index.svelte delete mode 100644 frontend/legacy/Lifecycle/gradio.config.js delete mode 100644 frontend/legacy/Lifecycle/package.json delete mode 100644 frontend/legacy/Lifecycle/shared/utils.ts delete mode 100644 frontend/legacy/Markdown/Awaited.svelte delete mode 100644 frontend/legacy/Markdown/CHANGELOG.md delete mode 100644 frontend/legacy/Markdown/Example.svelte delete mode 100644 frontend/legacy/Markdown/Index.svelte delete mode 100644 frontend/legacy/Markdown/gradio.config.js delete mode 100644 frontend/legacy/Markdown/package.json delete mode 100644 frontend/legacy/Markdown/shared/Markdown.svelte delete mode 100644 frontend/legacy/MultimodalInput/Awaited.svelte delete mode 100644 frontend/legacy/MultimodalInput/CHANGELOG.md delete mode 100644 frontend/legacy/MultimodalInput/Example.svelte delete mode 100644 frontend/legacy/MultimodalInput/Index.svelte delete mode 100644 frontend/legacy/MultimodalInput/gradio.config.js delete mode 100644 frontend/legacy/MultimodalInput/package.json delete mode 100644 frontend/legacy/MultimodalInput/shared/AudioRecorder.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/FilePreview.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/Input.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/Loader.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/RemoveIcon.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/SubmitButton.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/UploadButton.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/UploadIcon.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/Webcam.svelte delete mode 100644 frontend/legacy/MultimodalInput/shared/context.ts delete mode 100644 frontend/legacy/MultimodalInput/shared/global.d.ts delete mode 100644 frontend/legacy/MultimodalInput/shared/utils.ts delete mode 100644 frontend/legacy/WaterfallGallery/CHANGELOG.md delete mode 100644 frontend/legacy/WaterfallGallery/Index.svelte delete mode 100644 frontend/legacy/WaterfallGallery/gradio.config.js delete mode 100644 frontend/legacy/WaterfallGallery/package.json delete mode 100644 frontend/legacy/WaterfallGallery/shared/Dislike.svelte delete mode 100644 frontend/legacy/WaterfallGallery/shared/Gallery.svelte delete mode 100644 frontend/legacy/WaterfallGallery/shared/Image.svelte delete mode 100644 frontend/legacy/WaterfallGallery/shared/Waterfall/createWaterfall.ts delete mode 100644 frontend/legacy/WaterfallGallery/shared/Waterfall/index.ts delete mode 100644 frontend/legacy/WaterfallGallery/shared/Waterfall/layout.ts delete mode 100644 frontend/legacy/WaterfallGallery/shared/utils.ts delete mode 100644 frontend/legacy/compiled/CHANGELOG.md delete mode 100644 frontend/legacy/compiled/components/FileView/index.svelte delete mode 100644 frontend/legacy/compiled/components/FileView/shared/FileView.svelte delete mode 100644 frontend/legacy/compiled/components/Flow/index.svelte delete mode 100644 frontend/legacy/compiled/components/Markdown/index.svelte delete mode 100644 frontend/legacy/compiled/components/ReactComponent.svelte delete mode 100644 frontend/legacy/compiled/global.d.ts delete mode 100644 frontend/legacy/compiled/index.ts delete mode 100644 frontend/legacy/compiled/package.json delete mode 100644 frontend/legacy/compiled/src/ComponentConfigProvider.tsx delete mode 100644 frontend/legacy/compiled/src/FileView/Pdf.tsx delete mode 100644 frontend/legacy/compiled/src/FileView/hooks/usePreview.ts delete mode 100644 frontend/legacy/compiled/src/FileView/index.less delete mode 100644 frontend/legacy/compiled/src/FileView/index.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/FlowContext.ts delete mode 100644 frontend/legacy/compiled/src/Flow/components/CustomComponent.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/components/FileUpload.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/components/FormListItemWrapper.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/flow-components/ConnectionHandle.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/flow-components/ConnectionLine.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/flow-components/Controls.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/flow-components/Edge.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/flow-components/Node.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/flow-components/Sidebar.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/i18n.ts delete mode 100644 frontend/legacy/compiled/src/Flow/index.less delete mode 100644 frontend/legacy/compiled/src/Flow/index.tsx delete mode 100644 frontend/legacy/compiled/src/Flow/type.ts delete mode 100644 frontend/legacy/compiled/src/Flow/utils.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/components/Anchor.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/Audio.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/Code.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/CustomComponent.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/Heading.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/Image.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/Video.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/custom/Accordion.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/custom/Chart.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/custom/File.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/custom/FlushingEnd.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/components/custom/SelectBox.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/context.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/hooks/useCustomProps.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/index.less delete mode 100644 frontend/legacy/compiled/src/Markdown/index.tsx delete mode 100644 frontend/legacy/compiled/src/Markdown/math.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/react-markdown.d.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-Inline-code-property.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.d.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.js delete mode 100644 frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/schema.js delete mode 100644 frontend/legacy/compiled/src/Markdown/remark-plugins/remark-directive-rehype.ts delete mode 100644 frontend/legacy/compiled/src/Markdown/type.ts delete mode 100644 frontend/legacy/compiled/src/defineComponent.tsx delete mode 100644 frontend/legacy/compiled/src/index.ts delete mode 100644 frontend/legacy/compiled/src/mount.tsx delete mode 100644 frontend/legacy/compiled/src/polyfills.ts delete mode 100644 frontend/legacy/compiled/src/shared/hooks/useCustomComponent.ts delete mode 100644 frontend/legacy/compiled/src/shared/hooks/useMemoizedEqualValue.ts delete mode 100644 frontend/legacy/compiled/src/shared/hooks/useRefValue.ts delete mode 100644 frontend/legacy/compiled/src/shared/index.ts delete mode 100644 frontend/legacy/compiled/src/shared/type.ts delete mode 100644 frontend/legacy/compiled/src/utils.ts delete mode 100644 frontend/svelte-preprocess-react/component.ts create mode 100644 frontend/svelte-preprocess-react/component/import.ts create mode 100644 frontend/svelte-preprocess-react/component/index.ts create mode 100644 frontend/svelte-preprocess-react/component/props.svelte.ts rename frontend/svelte-preprocess-react/internal/{Bridge.ts => Bridge.svelte.ts} (51%) rename frontend/svelte-preprocess-react/{events-polyfills.ts => polyfills/events.ts} (100%) rename frontend/svelte-preprocess-react/{polyfills.ts => polyfills/index.ts} (86%) delete mode 100644 frontend/svelte-preprocess-react/provider.ts rename frontend/svelte-preprocess-react/{context.ts => react-contexts/index.ts} (98%) delete mode 100644 frontend/svelte-preprocess-react/slot.ts create mode 100644 frontend/svelte-preprocess-react/svelte-contexts/config.svelte.ts create mode 100644 frontend/svelte-preprocess-react/svelte-contexts/each.svelte.ts create mode 100644 frontend/svelte-preprocess-react/svelte-contexts/loading-status.svelte.ts create mode 100644 frontend/svelte-preprocess-react/svelte-contexts/slot.svelte.ts create mode 100644 frontend/svelte-preprocess-react/svelte-contexts/utils.svelte.ts create mode 100644 frontend/svelte-preprocess-react/sveltify.svelte.ts delete mode 100644 frontend/svelte-preprocess-react/sveltify.ts delete mode 100644 frontend/svelte-preprocess-react/useStore.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 17e2c8cd..a96bd947 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -51,6 +51,5 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "python-envs.defaultEnvManager": "ms-python.python:conda", - "python-envs.defaultPackageManager": "ms-python.python:conda", - "python-envs.pythonProjects": [] + "python-envs.defaultPackageManager": "ms-python.python:conda" } diff --git a/backend/modelscope_studio/__init__.py b/backend/modelscope_studio/__init__.py index 7bcd44fb..9b7ef04e 100644 --- a/backend/modelscope_studio/__init__.py +++ b/backend/modelscope_studio/__init__.py @@ -1,3 +1,2 @@ from .components import * -from .external import load from .version import __version__ diff --git a/backend/modelscope_studio/components/__init__.py b/backend/modelscope_studio/components/__init__.py index aafcf6e1..77949fda 100644 --- a/backend/modelscope_studio/components/__init__.py +++ b/backend/modelscope_studio/components/__init__.py @@ -1,5 +1,4 @@ from .antd.components import * from .antdx.components import * from .base import * -from .legacy.components import * from .pro.components import * diff --git a/backend/modelscope_studio/components/base/div/__init__.py b/backend/modelscope_studio/components/base/div/__init__.py index 734673bb..215af159 100644 --- a/backend/modelscope_studio/components/base/div/__init__.py +++ b/backend/modelscope_studio/components/base/div/__init__.py @@ -44,7 +44,7 @@ class ModelScopeDiv(ModelScopeLayoutComponent): def __init__( self, value: str | None = None, - props: dict | None = None, + additional_props: dict | None = None, *, as_item: str | None = None, _internal: None = None, @@ -62,9 +62,8 @@ def __init__( as_item=as_item, elem_style=elem_style, **kwargs) - self.value = value - self.props = props + self.additional_props = additional_props FRONTEND_DIR = resolve_frontend_dir("div", type="base") diff --git a/backend/modelscope_studio/components/base/slot/__init__.py b/backend/modelscope_studio/components/base/slot/__init__.py index da27db0e..3a57212c 100644 --- a/backend/modelscope_studio/components/base/slot/__init__.py +++ b/backend/modelscope_studio/components/base/slot/__init__.py @@ -14,7 +14,6 @@ def __init__(self, value: str = '', params_mapping: str | None = None, *, - skip_context_value: bool = True, as_item: str | None = None, _internal: None = None, visible: bool = True, @@ -25,7 +24,6 @@ def __init__(self, as_item=as_item, **kwargs) self.params_mapping = params_mapping - self.skip_context_value = skip_context_value if isinstance(self.parent, ModelScopeSlot): self.value = f"{self.parent.value}.{value}" else: diff --git a/backend/modelscope_studio/components/legacy/Chatbot/__init__.py b/backend/modelscope_studio/components/legacy/Chatbot/__init__.py deleted file mode 100644 index bc0bdd60..00000000 --- a/backend/modelscope_studio/components/legacy/Chatbot/__init__.py +++ /dev/null @@ -1,372 +0,0 @@ -from __future__ import annotations - -import inspect -from pathlib import Path -from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union - -from gradio import processing_utils -from gradio.components.base import Component -from gradio.data_classes import FileData, GradioModel, GradioRootModel -from gradio.events import Events -from gradio_client import utils as client_utils -from gradio_client.documentation import document, set_documentation_group - -from ....utils.dev import (AppContext, CustomComponentDict, process_links, - resolve_frontend_dir) -from ..MultimodalInput import MultimodalInputData - - -class FileMessage(GradioModel): - file: FileData - alt_text: Optional[str] = None - - -class MultimodalMessage(GradioModel): - # By default, message index is used as id. it will cause the message to be re-rendered when id changed. - id: Optional[str] = None - # elem id of message container - elem_id: Optional[str] = None - # elem classes of message container - elem_classes: Optional[Union[List[str], str]] = None - name: Optional[str] = None - text: Optional[str] = '' - flushing: Optional[bool] = None - avatar: Optional[Union[str, FileData]] = '' - files: Optional[List[Union[FileMessage, dict, FileData, str, Path]]] = None - - -MultimodalMessageItem = Optional[Union[MultimodalMessage, MultimodalInputData, - dict, str]] - - -class ChatbotData(GradioRootModel): - root: List[Tuple[Union[MultimodalMessageItem, List[MultimodalMessageItem]], - Union[MultimodalMessageItem, - List[MultimodalMessageItem]]]] - - -set_documentation_group("component") - - -@document() -class ModelScopeLegacyChatbot(Component): - """ - Displays a chatbot output showing both user submitted messages and responses. Supports a subset of Markdown including bold, italics, code, tables. Also supports audio/video/image files, which are displayed in the MultimodalChatbot, and other kinds of files which are displayed as links. - Preprocessing: passes the messages in the MultimodalChatbot as a {List[List[str | None | Tuple]]}, i.e. a list of lists. The inner list has 2 elements: the user message and the response message. See `Postprocessing` for the format of these messages. - Postprocessing: expects function to return a {List[List[str | None | Tuple]]}, i.e. a list of lists. The inner list should have 2 elements: the user message and the response message. The individual messages can be (1) strings in valid Markdown, (2) tuples if sending files: (a filepath or URL to a file, [optional string alt text]) -- if the file is image/video/audio, it is displayed in the MultimodalChatbot, or (3) None, in which case the message is not displayed. - - Demos: chatbot_simple, chatbot_multimodal - Guides: creating-a-chatbot - """ - FRONTEND_DIR = resolve_frontend_dir("Chatbot", type='legacy') - EVENTS = [Events.change, Events.select, Events.like, 'flushed', 'custom'] - data_model = ChatbotData - - @staticmethod - def data_postprocess(component_instance, value): - return value - - @staticmethod - def data_preprocess(component_instance, value): - return value - - def __init__( - self, - value: List[List[str | tuple[str] | tuple[str | Path, str] | None]] - | Callable | None = None, - *, - label: str | None = None, - every: float | None = None, - show_label: bool | None = None, - container: bool = True, - scale: int | None = None, - min_width: int = 160, - visible: bool = True, - elem_id: str | None = None, - elem_classes: List[str] | str | None = None, - render: bool = True, - height: int | None = None, - rtl: bool | None = None, - show_share_button: bool | None = None, - show_copy_button: bool | None = None, - avatar_images: tuple[str | Path | None | dict | list | tuple, - str | Path | None | dict | list | tuple] - | None = None, - avatar_image_align: Literal['top', 'middle', 'bottom'] = 'bottom', - avatar_image_width: Union[int, Literal['auto']] = 45, - sanitize_html: bool = True, - render_markdown: bool = True, - bubble_full_width: bool = True, - line_breaks: bool = True, - likeable: bool | None = None, - layout: Literal["panel", "bubble"] | None = None, - flushing: bool = True, - flushing_speed: int = 5, - enable_base64: bool | None = None, - enable_latex: bool = True, - latex_single_dollar_delimiter: bool = True, - latex_delimiters: list[dict[str, str | bool]] | None = None, - preview: bool = True, - llm_thinking_presets: List[dict] = [], - data_postprocess: Callable | None = None, - data_preprocess: Callable | None = None, - custom_components: Dict[str, CustomComponentDict] | None = None): - """ - Parameters: - value: Default value to show in chatbot. If callable, the function will be called whenever the app loads to set the initial value of the component. - label: The label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to. - every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. - show_label: if True, will display label. - container: If True, will place the component in a container - providing some extra padding around the border. - scale: relative width compared to adjacent Components in a Row. For example, if Component A has scale=2, and Component B has scale=1, A will be twice as wide as B. Should be an integer. - min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first. - visible: If False, component will be hidden. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. - render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. - height: height of the component in pixels. - enable_latex: If True, will enable LaTeX rendering. - latex_single_dollar_delimiter: If True, will enable single dollar delimiter for LaTeX rendering. - latex_delimiters: A list of dicts of the form {"left": open delimiter (str), "right": close delimiter (str), "display": whether to display in newline (bool), "inline": whether to render inline (bool)} that will be used to render LaTeX expressions. For more information, see the [KaTeX documentation](https://katex.org/docs/autorender.html). - rtl: If True, sets the direction of the rendered text to right-to-left. Default is False, which renders text left-to-right. - show_share_button: If True, will show a share icon in the corner of the component that allows user to share outputs. If False, icon does not appear. - show_copy_button: If True, will show a copy button for each chatbot message. - avatar_images: Tuple of two avatar image paths or URLs or dict ("avatar" and "name") or list (each item receives the previous parameters) for user(s) and bot(s) (in that order). Pass None for either the user or bot image to skip. Must be within the working directory of the Gradio app or an external URL and use `gr.update` to update. - sanitize_html: If False, will disable HTML sanitization for chatbot messages. This is not recommended, as it can lead to security vulnerabilities. - avatar_image_width: Width of the avatar image in pixels, pass in `auto` to automatically stretch in each message. - avatar_image_align: Aligns the avatar images to the top, middle, or bottom of the message. - render_markdown: If False, will disable Markdown rendering for chatbot messages. - bubble_full_width: If False, the chat bubble will fit to the content of the message. If True (default), the chat bubble will be the full width of the component. - line_breaks: If True (default), will enable Github-flavored Markdown line breaks in chatbot messages. If False, single new lines will be ignored. Only applies if `render_markdown` is True. - likeable: Whether the chat messages display a like or dislike button. Set automatically by the .like method but has to be present in the signature for it to show up in the config. - layout: If "panel", will display the chatbot in a llm style layout. If "bubble", will display the chatbot with message bubbles, with the user and bot messages on alterating sides. Will default to "bubble". - flushing: If True (default), will stream output the chatbot (not the user) messages to the frontend linearly when they are updated. Can be configured for each message. - flushing_speed: Range 1 to 10, default is 5. - llm_thinking_presets: llm presets, imported from modelscope_studio.Chatbot.llm_thinking_presets . - enable_base64: Enable base64 encoding for markdown rendering. - preview: If True (default), will enable image preview. - custom_components: Define custom tags for markdown rendering. - """ - AppContext.assert_app() - self.likeable = likeable - self.height = height - self.rtl = rtl - self.enable_latex = enable_latex - self.latex_single_dollar_delimiter = latex_single_dollar_delimiter - self.latex_delimiters = latex_delimiters - self.show_share_button = show_share_button - self.render_markdown = render_markdown - self.show_copy_button = show_copy_button - self.sanitize_html = sanitize_html - self.bubble_full_width = bubble_full_width - self.line_breaks = line_breaks - self.layout = layout - self.flushing = flushing - self.flushing_speed = flushing_speed - self.preview = preview - self.avatar_image_width = avatar_image_width - self.enable_base64 = enable_base64 - self.data_preprocess = data_preprocess - self.data_postprocess = data_postprocess - self.llm_thinking_presets = llm_thinking_presets - self.custom_components = custom_components - super().__init__( - label=label, - every=every, - show_label=show_label, - container=container, - scale=scale, - min_width=min_width, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - render=render, - value=value, - ) - self.avatar_images = avatar_images or [None, None] - self.avatar_image_align = avatar_image_align - - if avatar_images is None: - pass - else: - if len(self.avatar_images) != 2: - raise ValueError( - "Expected avatar_images to be a tuple of length 2.") - for i, avatar_image_item in enumerate(self.avatar_images): - if isinstance(avatar_image_item, (list, tuple)): - for j, avatar_image in enumerate(avatar_image_item): - self.avatar_images[i][j] = self._process_avatar_image( - avatar_image) - else: - self.avatar_images[i] = self._process_avatar_image( - avatar_image_item) - - def _process_avatar_image(self, avatar_image: str | dict): - if isinstance(avatar_image, dict): - avatar_image[ - "avatar"] = processing_utils.move_resource_to_block_cache( - avatar_image.get("avatar"), self) - elif isinstance(avatar_image, str): - avatar_image = processing_utils.move_resource_to_block_cache( - avatar_image, self) - return avatar_image - - def _preprocess_chat_messages( - self, chat_message: MultimodalMessage | str | dict | None - ) -> MultimodalMessage | None: - if chat_message is None: - return None - if isinstance(chat_message, dict): - chat_message = MultimodalMessage(**chat_message) - if isinstance(chat_message, MultimodalMessage): - if chat_message.avatar and isinstance(chat_message.avatar, str): - chat_message.avatar = FileData( - path=chat_message.avatar, - orig_name=Path(chat_message.avatar).name, - size=Path(chat_message.avatar).stat().st_size) - if chat_message.files is not None and len(chat_message.files) > 0: - for i, file in enumerate(chat_message.files): - if isinstance(file, FileData): - chat_message.files[i] = FileMessage(file=file) - elif isinstance(file, str): - chat_message.files[i] = FileMessage( - file=FileData(path=file, - orig_name=Path(file).name, - size=Path(file).stat().st_size)) - elif isinstance(file, dict): - chat_message.files[i] = FileMessage(file=FileData( - **file)) - return chat_message - else: - return chat_message - elif isinstance(chat_message, str): - return MultimodalMessage(text=chat_message) - else: - raise ValueError( - f"Invalid message for Chatbot component: {chat_message}") - - def preprocess( - self, - payload: ChatbotData | None, - ) -> List[List[MultimodalMessage | None]]: - if self.data_preprocess: - payload = self.data_preprocess(self, payload) - payload = self.__class__.data_preprocess(self, payload) - if payload is None: - return payload - processed_messages = [] - for message_pair in payload.root: - if not isinstance(message_pair, (tuple, list)): - raise TypeError( - "Expected a list of lists or list of tuples. Received: " + - message_pair) - if len(message_pair) != 2: - raise TypeError( - "Expected a list of lists of length 2 or list of tuples of length 2. Received: " - + {message_pair}) - processed_message = [] - for message in message_pair: - processed_message.append([ - self._preprocess_chat_messages(message_item) - for message_item in message - ] if isinstance(message, ( - tuple, list)) else self._preprocess_chat_messages(message)) - - processed_messages.append(processed_message) - return processed_messages - - def _postprocess_chat_messages( - self, chat_message: MultimodalMessage | MultimodalInputData | str - | dict | None - ) -> MultimodalMessage | None: - if chat_message is None: - return None - if isinstance(chat_message, MultimodalInputData): - chat_message = dict(text=chat_message.text, - files=chat_message.files) - if isinstance(chat_message, str): - chat_message = dict(text=chat_message) - if isinstance(chat_message, dict): - chat_message = MultimodalMessage(**chat_message) - chat_message.text = process_links(inspect.cleandoc(chat_message.text), - self) - if chat_message.avatar: - if isinstance(chat_message.avatar, str): - mime_type = client_utils.get_mimetype(chat_message.avatar) - chat_message.avatar = FileData( - path=chat_message.avatar, - orig_name=Path(chat_message.avatar).name, - size=Path(chat_message.avatar).stat().st_size, - mime_type=mime_type) - # Fix Gradio - chat_message.avatar.url = None - - if chat_message.files: - for i, file in enumerate(chat_message.files): - new_file = file - if isinstance(file, str): - mime_type = client_utils.get_mimetype(file) - new_file = FileMessage( - file=FileData(path=file, - orig_name=Path(file).name, - size=Path(file).stat().st_size, - mime_type=mime_type)) - elif isinstance(file, Path): - mime_type = client_utils.get_mimetype(str(file)) - new_file = FileMessage( - file=FileData(path=str(file), - orig_name=file.name, - size=file.stat().st_size, - mime_type=mime_type)) - elif isinstance(file, FileData): - new_file = FileMessage(file=file.model_copy()) - elif isinstance(file, dict): - new_file = FileMessage(file=FileData(**file)) - new_file.file.mime_type = client_utils.get_mimetype( - new_file.file.path) - # Fix Gradio - new_file.file.url = None - chat_message.files[i] = new_file - - return chat_message - - def postprocess( - self, - value: List[List[str | dict | MultimodalInputData | MultimodalMessage - | None] | tuple], - ) -> ChatbotData: - if self.data_postprocess: - value = self.data_postprocess(self, value) - value = self.__class__.data_postprocess(self, value) - if value is None: - return ChatbotData(root=[]) - processed_messages = [] - for message_pair in value: - if not isinstance(message_pair, (tuple, list)): - raise TypeError( - "Expected a list of lists or list of tuples. Received: " + - message_pair) - if len(message_pair) != 2: - raise TypeError( - "Expected a list of lists of length 2 or list of tuples of length 2. Received: " - + {message_pair}) - processed_message = [] - for message in message_pair: - processed_message.append([ - self._postprocess_chat_messages(message_item) - for message_item in message - ] if isinstance(message, ( - tuple, - list)) else self._postprocess_chat_messages(message)) - - processed_messages.append(processed_message) - return ChatbotData(root=processed_messages) - - def example_inputs(self) -> Any: - return [[{ - "text": "Hello!!", - "files": [] - }, { - "text": "Hello!!", - "flushing": False - }]] diff --git a/backend/modelscope_studio/components/legacy/Chatbot/llm_thinking_presets.py b/backend/modelscope_studio/components/legacy/Chatbot/llm_thinking_presets.py deleted file mode 100644 index 8dee522a..00000000 --- a/backend/modelscope_studio/components/legacy/Chatbot/llm_thinking_presets.py +++ /dev/null @@ -1,9 +0,0 @@ -def qwen(action_input_title: str = "Using ", - action_output_title: str = "Completed", - auto_end: bool = True): - return { - "type": "qwen", - "action_input_title": action_input_title, - "action_output_title": action_output_title, - "auto_end": auto_end - } diff --git a/backend/modelscope_studio/components/legacy/Flow/__init__.py b/backend/modelscope_studio/components/legacy/Flow/__init__.py deleted file mode 100644 index 7a48eec5..00000000 --- a/backend/modelscope_studio/components/legacy/Flow/__init__.py +++ /dev/null @@ -1,146 +0,0 @@ -from __future__ import annotations - -from typing import (Any, Callable, Dict, List, Literal, Optional, Tuple, - TypedDict, Union) - -from gradio import processing_utils -from gradio.components.base import Component -from gradio.data_classes import GradioModel -from gradio.events import Events -from gradio_client.documentation import document - -from ....utils.dev import AppContext, CustomComponentDict, resolve_frontend_dir -from .edge import * -from .edge import Edge -from .node import * -from .node import Node -from .node_schema import * -from .node_schema import NodeSchemaDict - - -class FlowData(GradioModel): - nodes: Optional[List[Union[Node, dict]]] = [] - edges: Optional[List[Union[Edge, dict]]] = [] - - -class FlowSchemaDict(TypedDict): - nodes: Optional[List[Union[NodeSchemaDict, dict]]] = [] - - -class BackgroundPropsDict(TypedDict): - color: Optional[str] - bgColor: Optional[str] - className: Optional[str] - # The gap between patterns. Passing in a tuple allows you to control the x and y gap independently. - gap: Optional[Union[int, Tuple[int, int]]] - # The radius of each dot or the size of each rectangle if BackgroundVariant.Dots or BackgroundVariant.Cross is used. This defaults to 1 or 6 respectively, or ignored if BackgroundVariant.Lines is used. - size: Optional[int] - offset: Optional[int] - lineWidth: Optional[int] - variant: Optional[Literal['dots', 'lines', 'cross']] - - -@document() -class ModelScopeLegacyFlow(Component): - data_model = FlowData - FRONTEND_DIR = resolve_frontend_dir("Flow", type='legacy') - EVENTS = [Events.change, 'data_change', 'custom'] - - def __init__( - self, - value: dict | FlowData | Callable | None = None, - *, - label: str | None = None, - info: str | None = None, - every: float | None = None, - show_label: bool | None = None, - container: bool = True, - scale: int | None = None, - min_width: int = 160, - interactive: bool | None = None, - visible: bool = True, - elem_id: str | None = None, - elem_classes: List[str] | str | None = None, - render: bool = True, - sync_on_data_change: bool | None = None, - height: int | str | None = 600, - schema: Union[FlowSchemaDict, dict] | None = None, - show_sidebar: bool | None = None, - show_minimap: bool | None = None, - show_controls: bool | None = None, - background_props: Union[BackgroundPropsDict, dict, - List[Union[BackgroundPropsDict, dict]]] - | None = None, - min_zoom: float | int | None = 0.1, - max_zoom: float | int | None = 2, - custom_components: Dict[str, CustomComponentDict] | None = None): - """ - Parameters: - value: FlowData or dict - sync_on_data_change: Whether to sync the Python value of the flow only the data changed (eg: node attrs, node count, edge count, connection ports, exclude node position). If you want better page performance instead of full data synchronization, It should be set to True. - height: The height of the flow component, specified in pixels if a number is passed, or in CSS units if a string is passed. - schema: Define the nodes and edges for the flow. - show_sidebar: Display the sidebar of the flow. - show_minimap: Display the minimap of the flow. - show_controls: Display the controls of the flow. - background_props: Modify the background of the flow, accepting the following props: BackgroundPropsDict - min_zoom: The minimum zoom level. - max_zoom: The maximum zoom level. - custom_components: Define the custom node types for the flow schema. - """ - AppContext.assert_app() - self.height = height - self.custom_components = custom_components - self.show_sidebar = show_sidebar - self.show_minimap = show_minimap - self.show_controls = show_controls - self.sync_on_data_change = sync_on_data_change - self.background_props = background_props - self.min_zoom = min_zoom - self.max_zoom = max_zoom - - super().__init__( - label=label, - info=info, - every=every, - show_label=show_label, - container=container, - scale=scale, - min_width=min_width, - interactive=interactive, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - render=render, - value=value, - ) - - self.schema = self._process_schema(schema) - - def _process_schema(self, schema: Union[FlowSchemaDict, dict] | None): - if schema is not None: - nodes = schema.get('nodes', []) - for node in nodes: - icon_url = node.get('icon') - if isinstance(icon_url, str): - node[ - "icon"] = processing_utils.move_resource_to_block_cache( - icon_url, self) - return schema - - def preprocess(self, payload: FlowData | dict | None) -> dict | None: - if payload is None: - return FlowData() - if isinstance(payload, dict): - return FlowData(**payload) - return payload - - def postprocess(self, value: FlowData | dict | None) -> dict | None: - if value is None: - return FlowData() - if isinstance(value, dict): - return FlowData(**value) - return value - - def example_inputs(self) -> Any: - return {"nodes": [], "edges": []} diff --git a/backend/modelscope_studio/components/legacy/Flow/edge.py b/backend/modelscope_studio/components/legacy/Flow/edge.py deleted file mode 100644 index ee813125..00000000 --- a/backend/modelscope_studio/components/legacy/Flow/edge.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Optional, Union - -from gradio.data_classes import GradioModel - - -class EdgePort(GradioModel): - attr: Optional[str] = None - attrItemIndex: Optional[int] = None - handleIndex: Optional[int] = None - - -class Edge(GradioModel): - id: Optional[str] = None - source: str - target: str - sourcePort: Optional[Union[EdgePort, dict]] = None - targetPort: Optional[Union[EdgePort, dict]] = None diff --git a/backend/modelscope_studio/components/legacy/Flow/node.py b/backend/modelscope_studio/components/legacy/Flow/node.py deleted file mode 100644 index 9efd490b..00000000 --- a/backend/modelscope_studio/components/legacy/Flow/node.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Optional, Union - -from gradio.data_classes import GradioModel - - -class NodePosition(GradioModel): - x: Optional[int] = 0 - y: Optional[int] = 0 - - -class Node(GradioModel): - id: Optional[str] = None - name: str - title: Optional[str] = None - position: Optional[Union[NodePosition, dict]] = None - data: Optional[dict] = None diff --git a/backend/modelscope_studio/components/legacy/Flow/node_schema.py b/backend/modelscope_studio/components/legacy/Flow/node_schema.py deleted file mode 100644 index 9be2f202..00000000 --- a/backend/modelscope_studio/components/legacy/Flow/node_schema.py +++ /dev/null @@ -1,63 +0,0 @@ -from typing import List, Literal, Optional, TypedDict, Union - - -class NodeSchemaPortConnectionDict(TypedDict): - attrs: Optional[List[str]] - name: str - - -class NodeSchemaPortsDict(TypedDict): - source: Optional[Literal['left', 'right', 'top', 'bottom']] - target: Optional[Literal['left', 'right', 'top', 'bottom']] - sourceConnections: Optional[Union[str, - Union[dict, - NodeSchemaPortConnectionDict]]] - targetConnections: Optional[Union[str, - Union[dict, - NodeSchemaPortConnectionDict]]] - - -class NodeSchemaAttributeRequiredDict(TypedDict): - message: Optional[str] - - -class NodeSchemaAttributeListDict(TypedDict): - min: Optional[int] - max: Optional[int] - ports: Optional[NodeSchemaPortsDict] - - -class NodeSchemaAttributeDict(TypedDict): - name: str - title: Optional[str] - description: Optional[str] - disabled: Optional[bool] - accordion: Optional[bool] - required: Union[bool, dict, NodeSchemaAttributeRequiredDict] - json_schema_validator: Optional[dict] - type: Optional[Literal['input', 'textarea', 'radio', 'checkbox', 'number', - 'select', 'switch', 'file']] - props: Optional[dict] - ports: Optional[NodeSchemaPortsDict] - list: Optional[Union[NodeSchemaAttributeListDict, dict, str]] - - -class NodeSchemaTemplateDict(TypedDict): - attrs: Optional[dict] - - -class NodeSchemaDict(TypedDict): - name: str - title: Optional[str] - description: Optional[str] - icon: Optional[str] - width: Optional[int] - height: Optional[int] - max: Optional[int] - min: Optional[int] - addable: Optional[bool] - show_toolbar: Optional[bool] - deletable: Optional[bool] - ports: Optional[Union[dict, NodeSchemaPortsDict]] - attrs: Optional[List[Union[NodeSchemaAttributeDict, dict]]] - template: Optional[Union[NodeSchemaTemplateDict, dict]] diff --git a/backend/modelscope_studio/components/legacy/Lifecycle/__init__.py b/backend/modelscope_studio/components/legacy/Lifecycle/__init__.py deleted file mode 100644 index 404ef05e..00000000 --- a/backend/modelscope_studio/components/legacy/Lifecycle/__init__.py +++ /dev/null @@ -1,100 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from gradio.components.base import Component -from gradio.data_classes import GradioModel -from gradio.events import EventListener -from gradio_client.documentation import document, set_documentation_group - -from ....utils.dev import AppContext, resolve_frontend_dir - -set_documentation_group("component") - - -class LifecycleScreenData(GradioModel): - width: float - height: float - scrollX: float - scrollY: float - - -class LifecycleData(GradioModel): - screen: LifecycleScreenData - language: str - theme: str - userAgent: str - - -@document() -class ModelScopeLegacyLifecycle(Component): - FRONTEND_DIR = resolve_frontend_dir("Lifecycle", type='legacy') - - EVENTS = [ - EventListener( - "mount", - doc= - "This listener is triggered when the {{ component }} initially mount in the browser.", - config_data=lambda: {"_bind_mount_event": False}, - callback=lambda block: setattr(block, "_bind_mount_event", True), - ), - EventListener( - "resize", - doc= - "This listener is triggered when the user resizes the browser window.", - config_data=lambda: {"_bind_resize_event": False}, - callback=lambda block: setattr(block, "_bind_resize_event", True), - ), - EventListener( - "unmount", - doc="This listener is triggered when the user leaves the page.", - config_data=lambda: {"_bind_unmount_event": False}, - callback=lambda block: setattr(block, "_bind_unmount_event", True), - ), - ] - data_model = LifecycleData - - def __init__( - self, - value: LifecycleData | dict | None = None, - *, - every: float | None = None, - _bind_mount_event: bool | None = None, - _bind_resize_event: bool | None = None, - _bind_unmount_event: bool | None = None, - ): - """ - Parameters: - every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. - """ - AppContext.assert_app() - self._bind_mount_event = _bind_mount_event - self._bind_resize_event = _bind_resize_event - self._bind_unmount_event = _bind_unmount_event - super().__init__(value=value, every=every) - - def preprocess( - self, payload: LifecycleData | dict | None - ) -> LifecycleData | dict | None: - return payload - - def postprocess( - self, - value: LifecycleData | dict | None) -> LifecycleData | dict | None: - return value - - def example_inputs(self) -> Any: - return { - "screen": { - "width": 1920, - "height": 1080, - "scrollX": 0, - "scrollY": 0, - }, - "theme": - "light", - "language": - "en", - "userAgent": - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", - } diff --git a/backend/modelscope_studio/components/legacy/Markdown/__init__.py b/backend/modelscope_studio/components/legacy/Markdown/__init__.py deleted file mode 100644 index 7fac7a0a..00000000 --- a/backend/modelscope_studio/components/legacy/Markdown/__init__.py +++ /dev/null @@ -1,130 +0,0 @@ -from __future__ import annotations - -import inspect -from typing import Any, Callable, Dict, List - -from gradio.components.base import Component -from gradio.events import Events -from gradio_client.documentation import document, set_documentation_group - -from ....utils.dev import (AppContext, CustomComponentDict, process_links, - resolve_frontend_dir) - -set_documentation_group("component") - - -@document() -class ModelScopeLegacyMarkdown(Component): - """ - Used to render arbitrary Markdown output. Can also render latex enclosed by dollar signs. - Preprocessing: this component does *not* accept input. - Postprocessing: expects a valid {str} that can be rendered as Markdown. - - Demos: blocks_hello, blocks_kinematics - Guides: key-features - """ - FRONTEND_DIR = resolve_frontend_dir("Markdown", type='legacy') - EVENTS = [Events.change, "custom"] - - @staticmethod - def data_postprocess(component_instance, value): - return value - - @staticmethod - def data_preprocess(component_instance, value): - return value - - def __init__( - self, - value: str | Callable = "", - *, - label: str | None = None, - every: float | None = None, - show_label: bool | None = None, - rtl: bool | None = None, - visible: bool = True, - elem_id: str | None = None, - elem_classes: List[str] | str | None = None, - render: bool = True, - sanitize_html: bool = True, - line_breaks: bool | None = None, - header_links: bool | None = None, - enable_base64: bool | None = None, - enable_latex: bool = True, - latex_single_dollar_delimiter: bool = True, - latex_delimiters: list[dict[str, str | bool]] | None = None, - preview: bool = True, - data_postprocess: Callable | None = None, - data_preprocess: Callable | None = None, - custom_components: Dict[str, CustomComponentDict] | None = None, - ): - """ - Parameters: - value: Value to show in Markdown component. If callable, the function will be called whenever the app loads to set the initial value of the component. - label: The label for this component. Is used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to. - every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. - show_label: This parameter has no effect. - rtl: If True, sets the direction of the rendered text to right-to-left. Default is False, which renders text left-to-right. - enable_latex: If True, will enable LaTeX rendering. - latex_single_dollar_delimiter: If True, will enable single dollar delimiter for LaTeX rendering. - latex_delimiters: A list of dicts of the form {"left": open delimiter (str), "right": close delimiter (str), "display": whether to display in newline (bool), "inline": whether to render inline (bool)} that will be used to render LaTeX expressions. For more information, see the [KaTeX documentation](https://katex.org/docs/autorender.html). - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. - render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. - sanitize_html: If False, will disable HTML sanitization when converted from markdown. This is not recommended, as it can lead to security vulnerabilities. - line_breaks: If True, will enable Github-flavored Markdown line breaks in chatbot messages. If False (default), single new lines will be ignored. - enable_base64: Enable base64 encoding for markdown rendering. - preview: If True (default), will enable image preview. - header_links: If True, will automatically create anchors for headings, displaying a link icon on hover. - custom_components: Define custom tags for markdown rendering. - """ - AppContext.assert_app() - self.rtl = rtl - self.enable_latex = enable_latex - self.latex_single_dollar_delimiter = latex_single_dollar_delimiter - self.latex_delimiters = latex_delimiters - self.sanitize_html = sanitize_html - self.preview = preview - self.line_breaks = line_breaks - self.header_links = header_links - self.enable_base64 = enable_base64 - self.preview = preview - self.custom_components = custom_components - self.data_preprocess = data_preprocess - self.data_postprocess = data_postprocess - - super().__init__( - label=label, - every=every, - show_label=show_label, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - render=render, - value=value, - ) - - def postprocess(self, value: str | None) -> str | None: - if self.data_postprocess: - value = self.data_postprocess(self, value) - value = self.__class__.data_postprocess(self, value) - if value is None: - return None - unindented_y = inspect.cleandoc(value) - return process_links(unindented_y, self) - - def as_example(self, input_data: str | None) -> str: - postprocessed = self.postprocess(input_data) - return postprocessed if postprocessed else "" - - def preprocess(self, payload: str | None) -> str | None: - if self.data_preprocess: - payload = self.data_preprocess(self, payload) - payload = self.__class__.data_preprocess(self, payload) - return payload - - def example_inputs(self) -> Any: - return "# Hello!" - - def api_info(self) -> Dict[str, Any]: - return {"type": "string"} diff --git a/backend/modelscope_studio/components/legacy/MultimodalInput/__init__.py b/backend/modelscope_studio/components/legacy/MultimodalInput/__init__.py deleted file mode 100644 index 9a977721..00000000 --- a/backend/modelscope_studio/components/legacy/MultimodalInput/__init__.py +++ /dev/null @@ -1,216 +0,0 @@ -from __future__ import annotations - -from pathlib import Path -from typing import Any, Callable, List, Literal, Union - -from gradio.components.base import FormComponent -from gradio.data_classes import FileData, GradioModel -from gradio.events import Events -from gradio_client import utils as client_utils -from gradio_client.documentation import document, set_documentation_group - -from ....utils.dev import AppContext, resolve_frontend_dir - -set_documentation_group("component") - - -class MultimodalInputData(GradioModel): - files: List[Union[FileData, str]] = [] - text: str - - -@document() -class ModelScopeLegacyMultimodalInput(FormComponent): - """ - Creates a textarea for user to enter string input or display string output. - Preprocessing: passes textarea value as a {dict(text=str, files=List[str])} into the function. - Postprocessing: expects a {str|dict(text=str, files=List[str])} returned from function and sets textarea value to it. - Examples-format: a {str|dict(text=str, files=List[str])} representing the textbox input. - - Demos: hello_world, diff_texts, sentence_builder - Guides: creating-a-chatbot, real-time-speech-recognition - """ - FRONTEND_DIR = resolve_frontend_dir("MultimodalInput", type='legacy') - - EVENTS = [ - Events.change, - Events.input, - Events.select, - Events.submit, - Events.focus, - Events.blur, - Events.upload, - ] - data_model = MultimodalInputData - - @staticmethod - def data_postprocess(component_instance, value): - return value - - @staticmethod - def data_preprocess(component_instance, value): - return value - - def __init__(self, - value: MultimodalInputData | str | None = None, - *, - lines: int = 1, - max_lines: int = 20, - placeholder: str | None = None, - label: str | None = None, - info: str | None = None, - every: float | None = None, - show_label: bool | None = None, - container: bool = True, - scale: int | None = None, - min_width: int = 160, - interactive: bool | None = None, - visible: bool = True, - elem_id: str | None = None, - autofocus: bool | None = None, - autoscroll: bool = True, - elem_classes: List[str] | str | None = None, - render: bool = True, - type: Literal["text", "password", "email"] = "text", - text_align: Literal["left", "right"] | None = None, - rtl: bool | None = None, - show_copy_button: bool | None = None, - data_postprocess: Callable | None = None, - data_preprocess: Callable | None = None, - sources: List[Literal['upload', 'microphone', - 'webcam']] = ['upload'], - upload_button_props: dict | None = None, - submit_button_props: dict | None = None, - file_preview_props: dict | None = None, - webcam_props: dict | None = None): - """ - Parameters: - value: default text to provide in textarea. If callable, the function will be called whenever the app loads to set the initial value of the component. - lines: minimum number of line rows to provide in textarea. - max_lines: maximum number of line rows to provide in textarea. - placeholder: placeholder hint to provide behind textarea. - label: The label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to. - info: additional component description. - every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. - show_label: if True, will display label. - container: If True, will place the component in a container - providing some extra padding around the border. - scale: relative width compared to adjacent Components in a Row. For example, if Component A has scale=2, and Component B has scale=1, A will be twice as wide as B. Should be an integer. - min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first. - interactive: if True, will be rendered as an editable textbox; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output. - visible: If False, component will be hidden. - autofocus: If True, will focus on the textbox when the page loads. Use this carefully, as it can cause usability issues for sighted and non-sighted users. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. - render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. - type: The type of textbox. One of: 'text', 'password', 'email', Default is 'text'. - text_align: How to align the text in the textbox, can be: "left", "right", or None (default). If None, the alignment is left if `rtl` is False, or right if `rtl` is True. Can only be changed if `type` is "text". - rtl: If True and `type` is "text", sets the direction of the text to right-to-left (cursor appears on the left of the text). Default is False, which renders cursor on the right. - show_copy_button: If True, includes a copy button to copy the text in the textbox. Only applies if show_label is True. - autoscroll: If True, will automatically scroll to the bottom of the textbox when the value changes, unless the user scrolls up. If False, will not scroll to the bottom of the textbox when the value changes. - sources: A list of sources permitted. "upload" creates a upload button, "microphone" creates a microphone button. "webcam" creates a webcam button. - upload_button_props: gradio UploadButton props. - submit_button_props: gradio Button props. - file_preview_props: FilePreview will render if `value.files` is not empty, accepting the following props: height(int). - webcam_props: Webcam will render if `sources` contains "webcam", accepting the following props: mirror_webcam(bool), include_audio(bool). - """ - AppContext.assert_app() - if type not in ["text", "password", "email"]: - raise ValueError( - '`type` must be one of "text", "password", or "email".') - - self.lines = lines - if type == "text": - self.max_lines = max(lines, max_lines) - else: - self.max_lines = 1 - self.placeholder = placeholder - self.show_copy_button = show_copy_button - self.autofocus = autofocus - self.autoscroll = autoscroll - self.data_preprocess = data_preprocess - self.data_postprocess = data_postprocess - self.submit_button_props = submit_button_props - self.upload_button_props = upload_button_props - self.file_preview_props = file_preview_props - self.webcam_props = webcam_props - self.sources = sources - super().__init__( - label=label, - info=info, - every=every, - show_label=show_label, - container=container, - scale=scale, - min_width=min_width, - interactive=interactive, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - render=render, - value=value, - ) - - self.type = type - self.rtl = rtl - self.text_align = text_align - - def preprocess( - self, - payload: MultimodalInputData | None) -> MultimodalInputData | None: - if self.data_preprocess: - payload = self.data_preprocess(self, payload) - payload = self.__class__.data_preprocess(self, payload) - if payload.files is not None and len(payload.files) > 0: - for i, file in enumerate(payload.files): - if isinstance(file, str): - payload.files[i] = FileData(path=file, - orig_name=Path(file).name, - size=Path(file).stat().st_size) - return payload - - def postprocess( - self, - value: MultimodalInputData | dict | str | None) -> str | None: - if self.data_postprocess: - value = self.data_postprocess(self, value) - value = self.__class__.data_postprocess(self, value) - if (value is None): - return MultimodalInputData(text="") - if isinstance(value, str): - value = MultimodalInputData(text=value) - elif isinstance(value, dict): - value = MultimodalInputData(**value) - if not value.files: - value.files = [] - if value.text is None: - value.text = "" - for i, file in enumerate(value.files): - if (isinstance(file, str)): - value.files[i] = FileData(path=file, - orig_name=Path(file).name, - size=Path(file).stat().st_size) - value.files[i].mime_type = client_utils.get_mimetype( - value.files[i].path) - return value - - def as_example( - self, - input_data: str | dict | ModelScopeLegacyMultimodalInput) -> dict: - value = input_data - if isinstance(input_data, str): - value = MultimodalInputData(text=input_data, files=[]) - if (isinstance(input_data, dict)): - value = MultimodalInputData(**input_data) - if value.files is not None and len(value.files) > 0: - for i, file in enumerate(value.files): - if (isinstance(file, str)): - value.files[i] = FileData(path=file, - orig_name=Path(file).name, - size=Path(file).stat().st_size) - value.files[i].mime_type = client_utils.get_mimetype( - value.files[i].path) - # gradio fix - return MultimodalInputData(text=value.text, files=value.files) - - def example_inputs(self) -> Any: - return {"text": "Hello!!", "files": []} diff --git a/backend/modelscope_studio/components/legacy/WaterfallGallery/__init__.py b/backend/modelscope_studio/components/legacy/WaterfallGallery/__init__.py deleted file mode 100644 index ee912ccf..00000000 --- a/backend/modelscope_studio/components/legacy/WaterfallGallery/__init__.py +++ /dev/null @@ -1,266 +0,0 @@ -from __future__ import annotations - -from concurrent.futures import ThreadPoolExecutor -from pathlib import Path -from typing import Any, Callable, List, Literal, Optional, Tuple, Union -from urllib.parse import urlparse - -import numpy as np -from gradio import processing_utils, utils -from gradio.components.base import Component -from gradio.data_classes import FileData, GradioModel, GradioRootModel -from gradio.events import EventListener, Events -from gradio_client.documentation import document, set_documentation_group -from gradio_client.utils import is_http_url_like -from PIL import Image as _Image # using _ to minimize namespace pollution - -from ....utils.dev import AppContext, resolve_frontend_dir - -set_documentation_group("component") - -GalleryImageType = Union[np.ndarray, _Image.Image, FileData, Path, str] -CaptionedGalleryImageType = Tuple[GalleryImageType, str] - - -class GalleryImage(GradioModel): - image: Union[FileData, Path, str] - caption: Optional[str] = None - liked: Optional[bool] = None - # custom meta data - meta: Optional[Any] = None - - -class GalleryData(GradioRootModel): - root: List[GalleryImage] - - -@document() -class ModelScopeLegacyWaterfallGallery(Component): - """ - Used to display a list of images as a gallery that can be scrolled through. - Preprocessing: this component does *not* accept input. - Postprocessing: expects a list of images in any format, {List[numpy.array | PIL.Image | str | pathlib.Path]}, or a {List} of (image, {str} caption) tuples and displays them. - - Demos: fake_gan - """ - - EVENTS = [ - Events.select, Events.change, Events.like, - EventListener( - "click", - config_data=lambda: {"clickable": False}, - callback=lambda block: setattr(block, "clickable", True), - doc="Triggered when the image action button is clicked."), - "load_more" - ] - FRONTEND_DIR = resolve_frontend_dir("WaterfallGallery", type='legacy') - data_model = GalleryData - - def __init__(self, - value: (List[GalleryImageType | CaptionedGalleryImageType - | GalleryImage] | Callable - | None) = None, - *, - label: str | None = None, - every: float | None = None, - show_label: bool | None = None, - container: bool = True, - scale: int | None = None, - min_width: int = 160, - visible: bool = True, - elem_id: str | None = None, - elem_classes: List[str] | str | None = None, - render: bool = True, - columns: int | tuple | dict | None = 2, - height: int | float | None = None, - allow_preview: bool = True, - preview: bool | None = None, - object_fit: Literal["contain", "cover", "fill", "none", - "scale-down"] - | None = None, - selected_index: int | None = None, - show_share_button: bool | None = None, - show_download_button: bool | None = True, - interactive: bool | None = None, - type: Literal["numpy", "pil", "filepath"] = "filepath", - action_label: str | None = "Click", - has_more: bool | None = None, - load_more_button_props: dict | None = None, - gap: int | tuple[int, int] | None = 8, - clickable: bool | None = None, - likeable: bool | None = None): - """ - Parameters: - value: List of images to display in the gallery by default. If callable, the function will be called whenever the app loads to set the initial value of the component. - label: The label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to. - every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. - show_label: If True, will display label. - container: If True, will place the component in a container - providing some extra padding around the border. - scale: relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True. - min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first. - visible: If False, component will be hidden. - elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. - elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. - render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. - columns: Represents the number of images that should be shown in one row, for each of the six standard screen sizes (<576px(xs), <768px(sm), <992px(md), <1200px(lg), <1600px(xl), >1600px(xll)). If fewer than 6 are given then the last will be used for all subsequent breakpoints. If a dict is passed in, you can represents the number of images for each size screen with [xs,sm,md,lg,xl,xll] as the key. - height: The height of the gallery component, specified in pixels if a number is passed, or in CSS units if a string is passed. If more images are displayed than can fit in the height, a scrollbar will appear. - allow_preview: If True, images in the gallery will be enlarged when they are clicked. Default is True. - preview: If True, Gallery will start in preview mode, which shows all of the images as thumbnails and allows the user to click on them to view them in full size. Only works if allow_preview is True. - selected_index: The index of the image that should be initially selected. If None, no image will be selected at start. If provided, will set Gallery to preview mode unless allow_preview is set to False. - object_fit: CSS object-fit property for the thumbnail images in the gallery. Can be "contain", "cover", "fill", "none", or "scale-down". - show_share_button: If True, will show a share icon in the corner of the component that allows user to share outputs. If False, icon does not appear. - show_download_button: If True, will show a download button in the corner of the selected image. If False, the icon does not appear. Default is True. - interactive: If True, the gallery will be interactive, allowing the user to upload images. If False, the gallery will be static. Default is True. - type: The format the image is converted to before being passed into the prediction function. "numpy" converts the image to a numpy array with shape (height, width, 3) and values from 0 to 255, "pil" converts the image to a PIL image object, "filepath" passes a str path to a temporary file containing the image. If the image is SVG, the `type` is ignored and the filepath of the SVG is returned. - action_label: The label for the action button. Only displayed if `clickable` is set to True. - has_more: If True, will show the "Load More" button. - load_more_button_props: gradio Button props. - gap: The gap (px) between images. If a tuple is passed, the first value is the gap for width and the second value is the gap for height.If a number is passed, the gap will be the same for width and height. - likeable: Whether the gallery image display a like or dislike button. Set automatically by the .like method but has to be present in the signature for it to show up in the config. - clickable: Whether the gallery image display an action button. Set automatically by the .click method but has to be present in the signature for it to show up in the config. - """ - AppContext.assert_app() - self.columns = columns - self.height = height - self.gap = gap - self.preview = preview - self.allow_preview = allow_preview - self.has_more = has_more - self.load_more_button_props = load_more_button_props - self.likeable = likeable - self.clickable = clickable - self.show_download_button = ((utils.get_space() is not None) - if show_download_button is None else - show_download_button) - self.selected_index = selected_index - self.type = type - self.object_fit = object_fit - self.action_label = action_label - self.show_share_button = show_share_button - self.empty_input = { - "data": [[]], - "append_list": [[]], - } - super().__init__(label=label, - every=every, - show_label=show_label, - container=container, - scale=scale, - min_width=min_width, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - render=render, - value=value, - interactive=interactive) - - def postprocess( - self, - value: List[GalleryImageType | CaptionedGalleryImageType - | GalleryImage | dict] | None, - # **kwargs - ) -> GalleryData: - """ - Parameters: - value: list of images, or list of (image, caption) tuples - Returns: - list of string file paths to images in temp directory - """ - - if value is None: - return GalleryData(root=[]) - output = [] - - def _save(img): - url = None - caption = None - orig_name = None - meta = None - liked = None - - if isinstance(img, (tuple, list)): - img, caption = img - if isinstance(img, dict): - img = GalleryImage(**img) - if isinstance(img, GalleryImage): - liked = img.liked - caption = img.caption - meta = img.meta - img = img.image - if isinstance(img, np.ndarray): - file = processing_utils.save_img_array_to_cache( - img, cache_dir=self.GRADIO_CACHE) - file_path = str(utils.abspath(file)) - elif isinstance(img, _Image.Image): - file = processing_utils.save_pil_to_cache( - img, cache_dir=self.GRADIO_CACHE) - file_path = str(utils.abspath(file)) - elif isinstance(img, FileData): - file_path = img.path - orig_name = img.orig_name - elif isinstance(img, str): - file_path = img - if is_http_url_like(img): - url = img - orig_name = Path(urlparse(img).path).name - else: - url = None - orig_name = Path(img).name - elif isinstance(img, Path): - file_path = str(img) - orig_name = img.name - else: - raise ValueError(f"Cannot process type as image: {type(img)}") - - return GalleryImage(image=FileData(path=file_path, - url=url, - orig_name=orig_name), - caption=caption, - meta=meta, - liked=liked) - - with ThreadPoolExecutor() as executor: - for o in executor.map(_save, value): - output.append(o) - return GalleryData(root=output) - - def preprocess(self, - payload: GalleryData | None) -> List[GalleryImage] | None: - if payload is None or not payload.root: - return None - for gallery_element in payload.root: - image = self.convert_to_type(gallery_element.image.path, - self.type) # type: ignore - if (not isinstance(image, str)): - gallery_element.image = image - return payload.root - - @staticmethod - def convert_to_type(img: str, type: Literal["filepath", "numpy", "pil"]): - if type == "filepath": - return img - else: - converted_image = _Image.Image.open(img) - if type == "numpy": - converted_image = np.array(converted_image) - return converted_image - - def example_inputs(self) -> Any: - return [ - [ - "https://gradio-builds.s3.amazonaws.com/demo-files/cheetah_running.avif", - "A fast cheetahA fast cheetahA fast cheetahA fast cheetahA fast cheetahA fast cheetahA fast cheetahA fast cheetahA fast cheetahA fast cheetahA fast cheetah", - ], - [ - "https://gradio-builds.s3.amazonaws.com/demo-files/cheetah-002.jpg", - "A fast cheetah", - ], - [ - "https://gradio-builds.s3.amazonaws.com/demo-files/cheetah-003.jpg", - "A fast cheetah", - ], - [ - "https://gradio-builds.s3.amazonaws.com/demo-files/cheetah3.webp", - "A fast cheetah2", - ], - ] diff --git a/backend/modelscope_studio/components/legacy/__init__.py b/backend/modelscope_studio/components/legacy/__init__.py deleted file mode 100644 index 79939ff0..00000000 --- a/backend/modelscope_studio/components/legacy/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .Chatbot import ModelScopeLegacyChatbot as Chatbot -from .Flow import ModelScopeLegacyFlow as Flow -from .Lifecycle import ModelScopeLegacyLifecycle as Lifecycle -from .Markdown import ModelScopeLegacyMarkdown as Markdown -from .MultimodalInput import ModelScopeLegacyMultimodalInput as MultimodalInput -from .WaterfallGallery import \ - ModelScopeLegacyWaterfallGallery as WaterfallGallery diff --git a/backend/modelscope_studio/components/legacy/components.py b/backend/modelscope_studio/components/legacy/components.py deleted file mode 100644 index e6e928a1..00000000 --- a/backend/modelscope_studio/components/legacy/components.py +++ /dev/null @@ -1,14 +0,0 @@ -from .Chatbot import ModelScopeLegacyChatbot as Chatbot -from .Chatbot import ModelScopeLegacyChatbot as LegacyChatbot -from .Flow import ModelScopeLegacyFlow as Flow -from .Flow import ModelScopeLegacyFlow as LegacyFlow -from .Lifecycle import ModelScopeLegacyLifecycle as LegacyLifecycle -from .Lifecycle import ModelScopeLegacyLifecycle as Lifecycle -from .Markdown import ModelScopeLegacyMarkdown as LegacyMarkdown -from .MultimodalInput import \ - ModelScopeLegacyMultimodalInput as LegacyMultimodalInput -from .MultimodalInput import ModelScopeLegacyMultimodalInput as MultimodalInput -from .WaterfallGallery import \ - ModelScopeLegacyWaterfallGallery as LegacyWaterfallGallery -from .WaterfallGallery import \ - ModelScopeLegacyWaterfallGallery as WaterfallGallery diff --git a/backend/modelscope_studio/external.py b/backend/modelscope_studio/external.py deleted file mode 100644 index f8234ba5..00000000 --- a/backend/modelscope_studio/external.py +++ /dev/null @@ -1,354 +0,0 @@ -import copy -import warnings -from typing import Callable, List, Union - -import gradio -import gradio.utils -import httpx -import modelscope_studio.components -from gradio.blocks import Block, BlockContext, Blocks -from gradio.context import Context -from gradio.events import EventListenerMethod -from gradio.exceptions import GradioVersionIncompatibleError -from gradio_client import Client -from gradio_client.client import Endpoint -from packaging import version - -_endpoint = "https://modelscope.cn" -_studio_endpoint = "https://s5k.cn" - - -def blocks_from_config(config: dict, fns: List[Callable], - proxy_url: str) -> Blocks: - """ - Factory method that creates a Blocks from a config and list of functions. Used - internally by the gradio.external.load() method. - - Parameters: - config: a dictionary containing the configuration of the Blocks. - fns: a list of functions that are used in the Blocks. Must be in the same order as the dependencies in the config. - proxy_url: an external url to use as a root URL when serving files for components in the Blocks. - """ - config = copy.deepcopy(config) - components_config = config["components"] - theme = config.get("theme", "default") - original_mapping: dict[int, Block] = {} - proxy_urls = {proxy_url} - - def get_block_instance(id: int) -> Block: - for block_config in components_config: - if block_config["id"] == id: - break - else: - raise ValueError(f"Cannot find block with id {id}") - cls = gradio.utils.component_or_layout_class( - block_config["props"]["name"]) - - # If a Gradio app B is loaded into a Gradio app A, and B itself loads a - # Gradio app C, then the proxy_urls of the components in A need to be the - # URL of C, not B. The else clause below handles this case. - if block_config["props"].get("proxy_url") is None: - block_config["props"]["proxy_url"] = f"{proxy_url}/" - postprocessed_value = block_config["props"].pop("value", None) - - constructor_args = cls.recover_kwargs(block_config["props"]) - block = cls(**constructor_args) - if postprocessed_value is not None: - block.value = postprocessed_value # type: ignore - - block_proxy_url = block_config["props"]["proxy_url"] - block.proxy_url = block_proxy_url - proxy_urls.add(block_proxy_url) - if (_selectable := block_config["props"].pop("_selectable", - None)) is not None: - block._selectable = _selectable # type: ignore - - return block - - def iterate_over_children(children_list): - for child_config in children_list: - id = child_config["id"] - block = get_block_instance(id) - - original_mapping[id] = block - - children = child_config.get("children") - if children is not None: - if not isinstance(block, BlockContext): - raise ValueError( - f"Invalid config, Block with id {id} has children but is not a BlockContext." - ) - with block: - iterate_over_children(children) - - derived_fields = ["types"] - - with Blocks(theme=theme) as blocks: - # ID 0 should be the root Blocks component - original_mapping[0] = Context.root_block or blocks - - iterate_over_children(config["layout"]["children"]) - - first_dependency = None - - # add the event triggers - for dependency, fn in zip(config["dependencies"], fns): - # We used to add a "fake_event" to the config to cache examples - # without removing it. This was causing bugs in calling gr.load - # We fixed the issue by removing "fake_event" from the config in examples.py - # but we still need to skip these events when loading the config to support - # older demos - if "trigger" in dependency and dependency[ - "trigger"] == "fake_event": - continue - for field in derived_fields: - dependency.pop(field, None) - - # older versions had a separate trigger field, but now it is part of the - # targets field - _targets = dependency.pop("targets") - trigger = dependency.pop("trigger", None) - is_then_event = False - is_success_event = False - - # This assumes that you cannot combine multiple .then() events in a single - # gr.on() event, which is true for now. If this changes, we will need to - # update this code. - if not isinstance(_targets[0], int) and _targets[0][1] == "then": - if len(_targets) != 1: - raise ValueError( - "This logic assumes that .then() events are not combined with other events in a single gr.on() event" - ) - is_then_event = True - elif (not isinstance(_targets[0], int) - and _targets[0][1] == "success"): - if len(_targets) != 1: - raise ValueError( - "This logic assumes that .success() events are not combined with other events in a single gr.on() event" - ) - is_success_event = True - - dependency.pop("backend_fn") - dependency.pop("documentation", None) - dependency["inputs"] = [ - original_mapping[i] for i in dependency["inputs"] - ] - dependency["outputs"] = [ - original_mapping[o] for o in dependency["outputs"] - ] - dependency.pop("status_tracker", None) - dependency.pop("zerogpu", None) - dependency["preprocess"] = False - dependency["postprocess"] = False - if is_then_event: - targets = [EventListenerMethod(None, "then")] - dependency["trigger_after"] = dependency.pop("trigger_after") - dependency["trigger_only_on_success"] = dependency.pop( - "trigger_only_on_success") - dependency["no_target"] = True - elif is_success_event: - targets = [EventListenerMethod(None, _targets[0][1])] - dependency["trigger_after"] = dependency.pop("trigger_after") - dependency["trigger_only_on_success"] = dependency.pop( - "trigger_only_on_success") - dependency["no_target"] = True - else: - targets = [ - getattr( - original_mapping[ - target if isinstance(target, int) else target[0]], - trigger if isinstance(target, int) else target[1], - ) for target in _targets - ] - targets = [ - EventListenerMethod( - t.__self__ if t.has_trigger else None, - t.event_name, # type: ignore - ) for t in targets - ] - dependency = blocks.set_event_trigger(targets=targets, - fn=fn, - **dependency)[0] - if first_dependency is None: - first_dependency = dependency - - # Allows some use of Interface-specific methods with loaded Spaces - if first_dependency and Context.root_block: - blocks.predict = [fns[0]] - if version.Version(gradio.__version__) < version.Version("4.28.0"): - blocks.input_components = [ - Context.root_block.blocks[i] - for i in first_dependency["inputs"] - ] - blocks.output_components = [ - Context.root_block.blocks[o] - for o in first_dependency["outputs"] - ] - else: - blocks.input_components = first_dependency.inputs - blocks.output_components = first_dependency.outputs - blocks.__name__ = "Interface" - blocks.api_mode = True - blocks.proxy_urls = proxy_urls - return blocks - - -def load( - name: str, - token: Union[str, None] = None, - **kwargs, -) -> Blocks: - """ - Constructs a demo from a ModelScope Studio repo. The input - and output components are automatically loaded from the repo. Note that if a Space is loaded, certain high-level attributes of the Blocks (e.g. - custom `css`, `js`, and `head` attributes) will not be loaded. - Parameters: - name: the name of the ModelScope Studio repo (e.g. "modelscope/modelscope-studio"). - token: optional access token for loading private ModelScope Studio repo. Find your sdk token here: https://modelscope.cn/my/myaccesstoken. - Returns: - a Gradio Blocks object for the given model - Example: - import modelscope_studio.components.legacy as mgr - demo = gr.load("modelscope/modelscope-studio") - demo.launch() - """ - return load_blocks_from_repo(name=name, token=token, **kwargs) - - -def load_blocks_from_repo( - name: str, - token: Union[str, None], - **kwargs, -) -> Blocks: - """Creates and returns a Blocks instance from a ModelScope Studio repo.""" - src = 'spaces' - - factory_methods: dict[str, Callable] = { - "spaces": from_spaces, - } - if src.lower() not in factory_methods: - raise ValueError( - f"parameter: src must be one of {factory_methods.keys()}") - - blocks: gradio.Blocks = factory_methods[src](name, token, **kwargs) - return blocks - - -def from_spaces(space_name: str, token: Union[str, None], **kwargs) -> Blocks: - space_url = f"{_endpoint}/studios/{space_name}" - - print(f"Fetching Space from: {space_url}") - access = False - - response = httpx.get( - f"{_endpoint}/api/v1/studio/{space_name}/access?sdk_token={token}", ) - if response.status_code == 200: - access = response.json().get("Data", {}).get('access') - - if not access: - raise ValueError( - f"Could not find Space: {space_name}. If it is a private or gated Space, please provide your ModelScope access token (https://modelscope.cn/my/myaccesstoken) as the argument for the `token` parameter." - ) - - if kwargs: - warnings.warn( - "You cannot override parameters for this Space by passing in kwargs. " - "Instead, please load the Space as a function and use it to create a " - "Blocks or Interface locally. You may find this Guide helpful: " - "https://gradio.app/using_blocks_like_functions/") - return from_spaces_blocks( - space_name=space_name, - token=token, - ) - - -def from_spaces_blocks( - space_name: str, - token: Union[str, None], -) -> Blocks: - component_or_layout_class = gradio.utils.component_or_layout_class - try: - space = f"{_studio_endpoint}/api/v1/studio/{space_name}/gradio/" - kwargs = {} - if version.Version(gradio.__version__) > version.Version('4.35.0'): - kwargs["download_files"] = False - kwargs["_skip_components"] = False - elif version.Version(gradio.__version__) > version.Version('4.19.1'): - kwargs["download_files"] = False - kwargs["_skip_components"] = False - kwargs["upload_files"] = False - elif version.Version(gradio.__version__) == version.Version('4.19.1'): - kwargs["download_files"] = False - client = Client( - space, - # convert to modelscope token - hf_token=token, - **kwargs) - # We set deserialize to False to avoid downloading output files from the server. - # Instead, we serve them as URLs using the /proxy/ endpoint directly from the server. - - if client.app_version < version.Version("4.0.0b14"): - raise GradioVersionIncompatibleError( - f"Gradio version 4.x cannot load spaces with versions less than 4.x ({client.app_version})." - "Please downgrade to version 3 to load this space.") - - if client.app_version != version.Version(gradio.__version__): - print( - f"Gradio local version {gradio.__version__} does not match the space version {client.app_version}, it might lead to some compatibility issues." - ) - - # Use end_to_end_fn here to properly upload/download all files - predict_fns = [] - - for fn_index, endpoint in enumerate(client.endpoints) if isinstance( - client.endpoints, list) else client.endpoints.items(): - if not isinstance(endpoint, Endpoint): - raise TypeError( - f"Expected endpoint to be an Endpoint, but got {type(endpoint)}" - ) - helper = client.new_helper(fn_index) - if endpoint.backend_fn: - predict_fns.append(endpoint.make_end_to_end_fn(helper)) - else: - predict_fns.append(None) - client_src = client.src[:-1] if client.src.endswith( - '/') else client.src - if version.Version(gradio.__version__) >= version.Version('4.29.0'): - blocks = Blocks.from_config(client.config, predict_fns, client_src) - else: - has_custom_component = False - - components = [ - (name, cls) - for name, cls in modelscope_studio.components.__dict__.items() - if isinstance(cls, type) - ] - - def override_component_or_layout_class(cls_name: str): - for name, cls in components: - if name.lower() == cls_name.replace("_", "") and ( - issubclass(cls, gradio.components.Component) - or issubclass(cls, gradio.blocks.BlockContext)): - return cls - return component_or_layout_class(cls_name) - - for component in client.config.get("components", []): - for (name, cls) in components: - if (name.lower() == component["props"]["name"].replace( - "_", "")): - has_custom_component = True - break - if has_custom_component: - break - - if has_custom_component: - gradio.utils.component_or_layout_class = override_component_or_layout_class - blocks = blocks_from_config(client.config, predict_fns, - client_src) - else: - blocks = Blocks.from_config(client.config, predict_fns, - client_src) - finally: - gradio.utils.component_or_layout_class = component_or_layout_class - - return blocks diff --git a/config/changelog/package.json b/config/changelog/package.json index f65a88bf..d9aad15b 100644 --- a/config/changelog/package.json +++ b/config/changelog/package.json @@ -19,13 +19,13 @@ "build": "tsup" }, "dependencies": { - "@changesets/get-github-info": "^0.6.0", + "@changesets/get-github-info": "^0.7.0", "@manypkg/get-packages": "^3.1.0", "detect-indent": "^7.0.2" }, "devDependencies": { "@changesets/types": "^6.1.0", - "@types/node": "^24.10.0", - "tsup": "^8.5.0" + "@types/node": "^25.3.1", + "tsup": "^8.5.1" } } diff --git a/config/lint-config/configs/eslint/basic.mjs b/config/lint-config/configs/eslint/basic.mjs index 2f10e72d..a6b0b8f5 100644 --- a/config/lint-config/configs/eslint/basic.mjs +++ b/config/lint-config/configs/eslint/basic.mjs @@ -62,7 +62,7 @@ export const basic = [ 'import/no-named-as-default-member': 'off', // prettier config - 'prettier/prettier': 'warn', + 'prettier/prettier': 'off', 'no-unused-vars': ['warn', { vars: 'all', varsIgnorePattern: '^_' }], 'require-await': 'warn', diff --git a/config/lint-config/configs/eslint/react.mjs b/config/lint-config/configs/eslint/react.mjs index 043c61d2..7a4b9589 100644 --- a/config/lint-config/configs/eslint/react.mjs +++ b/config/lint-config/configs/eslint/react.mjs @@ -1,6 +1,6 @@ import eslintPluginReactRecommendedConfig from 'eslint-plugin-react/configs/recommended.js'; import eslintPluginReactHooks from 'eslint-plugin-react-hooks'; -import reactRefresh from 'eslint-plugin-react-refresh'; +import { reactRefresh } from 'eslint-plugin-react-refresh'; import { fixupPluginRules } from '@eslint/compat'; import jsxA11y from 'eslint-plugin-jsx-a11y'; /** @@ -13,7 +13,7 @@ export const react = [ name: '@modelscope-studio/eslint-config/react', plugins: { 'react-hooks': fixupPluginRules(eslintPluginReactHooks), - 'react-refresh': fixupPluginRules(reactRefresh), + 'react-refresh': reactRefresh.plugin, }, languageOptions: { parserOptions: { @@ -40,10 +40,11 @@ export const react = [ 'jsx-a11y/mouse-events-have-key-events': 'off', 'jsx-a11y/no-noninteractive-element-interactions': 'off', 'jsx-a11y/alt-text': 'warn', - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], + // 'react-refresh/only-export-components': [ + // 'warn', + // { allowConstantExport: true }, + // ], + 'react-refresh/only-export-components': 'off', }, }, { diff --git a/config/lint-config/configs/eslint/svelte.mjs b/config/lint-config/configs/eslint/svelte.mjs index 2bbdf834..bf519a9b 100644 --- a/config/lint-config/configs/eslint/svelte.mjs +++ b/config/lint-config/configs/eslint/svelte.mjs @@ -6,7 +6,7 @@ import eslintPluginSvelte from 'eslint-plugin-svelte'; export const svelte = [ ...eslintPluginSvelte.configs['flat/recommended'], { - files: ['**/*.svelte', '*.svelte'], + files: ['**/*.svelte', '*.svelte', '**/*.svelte.ts'], languageOptions: { parserOptions: { parser: '@typescript-eslint/parser', @@ -15,6 +15,7 @@ export const svelte = [ rules: { 'svelte/no-at-html-tags': 'off', 'svelte/valid-compile': 'warn', + 'svelte/prefer-writable-derived': 'off', }, }, ]; diff --git a/config/lint-config/package.json b/config/lint-config/package.json index 1be364e3..36a59bda 100644 --- a/config/lint-config/package.json +++ b/config/lint-config/package.json @@ -16,29 +16,29 @@ } }, "dependencies": { - "@eslint/compat": "^1.4.1", - "@eslint/js": "^9.39.1", - "@typescript-eslint/parser": "^8.46.3", + "@eslint/compat": "^2.0.2", + "@eslint/js": "^10.0.1", + "@typescript-eslint/parser": "^8.56.1", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-prettier": "5.5.4", + "eslint-plugin-prettier": "5.5.5", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.4.24", + "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-svelte": "^3.13.0", - "globals": "^16.5.0", + "eslint-plugin-svelte": "^3.15.0", + "globals": "^17.3.0", "postcss": "^8.5.6", "postcss-less": "^6.0.0", "stylelint-config-rational-order": "^0.1.2", - "stylelint-config-standard": "^39.0.1", - "stylelint-declaration-block-no-ignored-properties": "^2.8.0", - "stylelint-order": "^7.0.0", + "stylelint-config-standard": "^40.0.0", + "stylelint-declaration-block-no-ignored-properties": "^3.0.0", + "stylelint-order": "^7.0.1", "stylelint-prettier": "^5.0.3", - "svelte-eslint-parser": "^1.4.0", - "typescript-eslint": "^8.46.3" + "svelte-eslint-parser": "^1.5.1", + "typescript-eslint": "^8.56.1" }, "devDependencies": { "@types/eslint": "^9.6.1", diff --git a/docs/api/app.py b/docs/api/app.py deleted file mode 100644 index 6f651d0b..00000000 --- a/docs/api/app.py +++ /dev/null @@ -1,19 +0,0 @@ -import os - -from components.legacy.Docs import Docs - - -def resolve(relative_path: str): - return os.path.join(os.path.dirname(__file__), relative_path) - - -docs = Docs( - __file__, - markdown_files=([ - filename for filename in os.listdir(resolve('.')) - if filename.endswith(".md") - ]), -) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/docs/api/load-zh_CN.md b/docs/api/load-zh_CN.md deleted file mode 100644 index e2335833..00000000 --- a/docs/api/load-zh_CN.md +++ /dev/null @@ -1,30 +0,0 @@ -# load - -该特性与 [gr.load](https://www.gradio.app/docs/gradio/load) 类似。允许用户从已有创空间 [ModelScope Studio](https://modelscope.cn/studios) 仓库构造 demo。 - -## 如何使用 - -### 基本使用 - -```python -import modelscope_studio.components.legacy as mgr -demo = mgr.load("modelscope/modelscope-studio") -demo.launch() -``` - -### 使用访问令牌 - -使用访问令牌来加载私有创空间。在这里找到您的 sdk 令牌:https://modelscope.cn/my/myaccesstoken。 - -```python -import modelscope_studio.components.legacy as mgr -demo = mgr.load("modelscope/modelscope-studio", token="YOUR_ACCESS_TOKEN") -demo.launch() -``` - -## 初始化 - -| 属性 | 类型 | 默认值 | 描述 | -| ----- | ---- | ------ | ---------------------------------------------------------------------------------------------------- | -| name | str | None | 必填。 创空间名称(如: "modelscope/modelscope-studio")。 | -| token | str | None | 用于加载私有创空间的可选访问令牌。 在这里找到您的 sdk 令牌:https://modelscope.cn/my/myaccesstoken。 | diff --git a/docs/api/load.md b/docs/api/load.md deleted file mode 100644 index 114baa15..00000000 --- a/docs/api/load.md +++ /dev/null @@ -1,30 +0,0 @@ -# load - -This feature is similar to [gr.load](https://www.gradio.app/docs/gradio/load). Allow users to Construct a demo from a [ModelScope Studio](https://modelscope.cn/studios) repo. - -## How to Use - -### Basic Usage - -```python -import modelscope_studio.components.legacy as mgr -demo = mgr.load("modelscope/modelscope-studio") -demo.launch() -``` - -### With Access Token - -Use the access token to load a private ModelScope Studio repo. Find your sdk token here: https://modelscope.cn/my/myaccesstoken. - -```python -import modelscope_studio.components.legacy as mgr -demo = mgr.load("modelscope/modelscope-studio", token="YOUR_ACCESS_TOKEN") -demo.launch() -``` - -## Initialization - -| Parameter | Type | Default Value | Description | -| --------- | ---- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| name | str | None | required. the name of the ModelScope Studio repo (e.g. "modelscope/modelscope-studio"). | -| token | str | None | optional access token for loading private ModelScope Studio repo. Find your sdk token here: https://modelscope.cn/my/myaccesstoken. | diff --git a/docs/app.py b/docs/app.py index a185c0d3..9af292be 100644 --- a/docs/app.py +++ b/docs/app.py @@ -6,7 +6,6 @@ from helper.Docs import Docs from helper.env import is_modelscope_studio from helper.Site import Site -from legacy_app import legacy_demo is_dev = os.environ.get("GRADIO_WATCH_MODULE_NAME") == 'docs.app' @@ -573,11 +572,6 @@ def more_components(): "default_active_key": "overview", "menus": antdx_menu_items, }, - { - "label": get_text("Version 0.x", "0.x 版本"), - "key": "legacy", - "content": legacy_demo - } if not is_dev else None, ] site = Site( diff --git a/docs/components/legacy/Chatbot/README-zh_CN.md b/docs/components/legacy/Chatbot/README-zh_CN.md deleted file mode 100644 index 8b8398ae..00000000 --- a/docs/components/legacy/Chatbot/README-zh_CN.md +++ /dev/null @@ -1,144 +0,0 @@ -# Chatbot - -升级版的 gradio Chatbot。 - -- 支持前端匀速流式输出 message -- 支持输出多模态内容(音频、视频、图片、文本) -- 内置标签(chart、select-box、accordion) -- 支持多 agent 场景 -- 支持自定义渲染组件,并与 Python 事件交互 - -## 如何使用 - -### 基本使用 - - - -### 多模态 & 支持本地文件的展示 - - - -### 控制打字机单句 message 开关 - - - -### 支持手风琴内容展示 - -在返回的内容中加入 `accordion` 标签,可以在内容中加入手风琴,更多用法详见 Markdown 内置自定义标签 - -同时为了适配大模型的工具调用链路,额外对某些大模型的格式做了预设配置,支持下述格式的预设处理(会将下面的格式转换成上方`accordion`标签包裹形式) - -```python -import modelscope_studio.components.legacy as mgr -from modelscope_studio.components.legacy.Chatbot.llm_thinking_presets import qwen - -# 添加 qwen 解析预设 -mgr.Chatbot(llm_thinking_presets=[qwen()]) -``` - -```text -Action: image_gen -Action Input: {"text": "glorious weather", "resolution": "1024*1024"} -Observation: ![IMAGEGEN](https://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/1d/a2/20231213/723609ee/1926736d-7c6e-4d2f-b438-b7746b3d89f5-1.png?Expires=1702537773&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=H%2B0rIn6BMfE%2BOr1uPb7%2Br9G3%2B5w%3D) 根据您的描述"glorious weather",我生成了一张图片。![](https://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/1d/a2/20231213/723609ee/1926736d-7c6e-4d2f-b438-b7746b3d89f5-1.png?Expires=1702537773&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=H%2B0rIn6BMfE%2BOr1uPb7%2Br9G3%2B5w%3D) - -Action: 「任意文本表示,将展示为思考链调用的名称」 -Action Input: 「任意json or md 内容,将展示到调用过程的下拉框」 -Observation: 「任意 md 内容,将作为完成调用的展示的下拉框内」 -``` - - - -### 支持用户选择交互 - -在返回的内容中加入 `select-box` 标签,更多用法详见 Markdown 内置自定义标签 - - - -### 支持图表展示 - -在返回的内容中加入 `chart` 标签,更多用法详见 Markdown 内置自定义标签 - - - -### 多 bot 场景 - - - -### 自定义标签(高阶用法,需要了解前端知识) - -详见 Markdown 组件 - -## API 及参数列表 - -以下 API 均为在原有 gradio Chatbot 外的额外拓展参数。 - -### value - -接口定义: - -```python - -class FileMessage(GradioModel): - file: FileData - alt_text: Optional[str] = None - - -class MultimodalMessage(GradioModel): - # 默认以 index 为作为 id,id 改变会导致 message 重新渲染 - id: Optional[str] = None - # message 容器的 elem id - elem_id: Optional[str] = None - # message 容器的 elem classes - elem_classes: Optional[List[str] | str] = None - name: Optional[str] = None - text: Optional[str] = None - flushing: Optional[bool] = None - avatar: Optional[Union[str, FileData]] = '' - files: Optional[List[Union[FileMessage, dict, FileData, str]]] = None - -# 支持多 bot 场景 -MultimodalMessageItem = Optional[Union[MultimodalMessage, MultimodalInputData, - dict, str]] - - -class ChatbotData(GradioRootModel): - root: List[Tuple[Union[MultimodalMessageItem, List[MultimodalMessageItem]], - Union[MultimodalMessageItem, - List[MultimodalMessageItem]]]] -``` - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ----------------------------- | -------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| flushing | bool | True | 是否开启打字机效果。默认只有 bot 的 message 会开启,可以通过单独修改 message 的 flushing 属性精确控制每一条 message 的显示效果 | -| enable_base64 | bool | False | 是否支持渲染的内容为 base64,因为直接渲染 base64 会带来安全问题,默认为 False。 | -| enable_latex | bool | True | 是否支持 Latex 公式渲染 | -| latex_single_dollar_delimiter | bool | True | 是否支持单`$`符号在 Latex 公式中渲染 | -| preview | bool | True | 是否开启图片预览功能 | -| avatar_images | tuple\[str \| Path \| None \| dict \| list, str \| Path \| None \| dict\| list\] | None | 拓展gr.Chatbot的参数值,除了接收 url 外还可以接收 dict 和 list,dict 可以传入avatar和name字段,name字段在渲染时会显示在头像下方。
- 当传入 dict 时,必须包含有avatar字段。
- 当传入 list 时,一般对应多 bot 模式,每一项可以接收前面所有的值,每个 bot 的头像与 message 中 bot 的位置一一对应 | -| avatar_image_align | Literal['top', 'middle', 'bottom'] | 'bottom' | 控制头像与 message 的对齐方式,默认为下对齐 | -| avatar_image_width | int | 45 | 头像与名称的宽度 | -| flushing_speed | int | 3 | 打字机速度,值为 1 - 10,值越大速度越快 | -| llm_thinking_presets | list\[dict\] | \[\] | llm 思考链路解析预设,可以将 llm 调用工具的输出格式转为固定的前端展示格式,需要从modelscope_studio.Chatbot.llm_thinking_presets引入,目前支持:qwen | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户定义自定义标签,并通过 js 控制标签渲染样式与触发 python 事件。 | - -**CustomComponentDict 定义如下** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### 内置的自定义标签 - -见 Markdown 内置自定义标签 - -### event listeners - -| 事件 | 描述 | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.Chatbot.flushed(fn, ···)` | 当打字机效果结束时触发。EventData 为:
- index:当前 message 的 index tuple。
- value:当前 message value。 | -| `mgr.Chatbot.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- index:当前 message 的 index tuple ([message index, user group(index 0) or bot group(index 1), user/bot group index])。
- tag:当前触发的标签。
- tag_index:当前触发标签的 index,此 index 在 message 的 index tuple 基础上重新计算。
- value:自定义传入的值。 | diff --git a/docs/components/legacy/Chatbot/README.md b/docs/components/legacy/Chatbot/README.md deleted file mode 100644 index ef41002e..00000000 --- a/docs/components/legacy/Chatbot/README.md +++ /dev/null @@ -1,143 +0,0 @@ -# Chatbot - -Upgraded gradio Chatbot. - -- Supports uniform frontend streaming output of messages -- Supports output of multimodal content (audio, video, image, text) -- Built-in tags (chart, select-box, accordion) -- Supports multi-agent scenarios -- Supports custom rendering components and interaction with Python events - -## How to Use - -### Basic Usage - - - -### Multimodal & Support for Local File Display - - - -### Control for Typewriter Single Sentence Message - - - -### Support for Accordion Content Display - -Include the `accordion` tag in the returned content to add an accordion within the content. For more usage details, see Markdown Built-in Custom Tags. -Additionally, to adapt to the toolchain usage of large models, some preset configurations for certain large models have been made. Support for the following preset formats (which will be converted into the form wrapped by the above `accordion` tag). - -```python -import modelscope_studio.components.legacy as mgr -from modelscope_studio.components.legacy.Chatbot.llm_thinking_presets import qwen - -# Add qwen preset -mgr.Chatbot(llm_thinking_presets=[qwen()]) -``` - -```text -Action: image_gen -Action Input: {"text": "glorious weather", "resolution": "1024*1024"} -Observation: ![IMAGEGEN](https://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/1d/a2/20231213/723609ee/1926736d-7c6e-4d2f-b438-b7746b3d89f5-1.png?Expires=1702537773&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=H%2B0rIn6BMfE%2BOr1uPb7%2Br9G3%2B5w%3D) Based on your description: glorious weather,I generated a picture.[](https://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/1d/a2/20231213/723609ee/1926736d-7c6e-4d2f-b438-b7746b3d89f5-1.png?Expires=1702537773&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=H%2B0rIn6BMfE%2BOr1uPb7%2Br9G3%2B5w%3D) - -Action: 「An arbitrary text representation that will be displayed as the name of the thought chain call」 -Action Input: 「Any json or md content will be displayed in the drop-down box of the calling process」 -Observation: 「Any md content will be displayed in the drop-down box when the call is completed」 -``` - - - -### Support for User Selection Interaction - -Include the `select-box` tag in the returned content. For more usage details, see Markdown Built-in Custom Tags . - - - -### Support for Chart Display - -Include the `chart` tag in the returned content. For more usage details, see Markdown Built-in Custom Tags . - - - -### Multi-bot Scenarios - - - -### Custom Tags (Advanced Usage, Requires Frontend Knowledge) - -See the Markdown component for details. - -## API and Parameter List - -The following APIs are additional extended parameters beyond the original gradio Chatbot. - -### value - -Interface definition: - -```python - -class FileMessage(GradioModel): - file: FileData - alt_text: Optional[str] = None - - -class MultimodalMessage(GradioModel): - # By default, message index is used as id. it will cause the message to be re-rendered when id changed. - id: Optional[str] = None - # elem id of message container - elem_id: Optional[str] = None - # elem classes of message container - elem_classes: Optional[List[str] | str] = None - name: Optional[str] = None - text: Optional[str] = None - flushing: Optional[bool] = None - avatar: Optional[Union[str, FileData]] = '' - files: Optional[List[Union[FileMessage, dict, FileData, str]]] = None - -# Support multi-bot scenarios -MultimodalMessageItem = Optional[Union[MultimodalMessage, MultimodalInputData, - dict, str]] - - -class ChatbotData(GradioRootModel): - root: List[Tuple[Union[MultimodalMessageItem, List[MultimodalMessageItem]], - Union[MultimodalMessageItem, - List[MultimodalMessageItem]]]] -``` - -### props - -| Attribute | Type | Default Value | Description | -| ----------------------------- | -------------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| flushing | bool | True | Whether to enable the typewriter effect. By default, only the bot's messages will have this effect, but you can control the display effect of each message precisely by modifying the flushing attribute of a message individually. | -| enable_base64 | bool | False | Whether to support rendering content as base64, since rendering base64 is unsafe, the default is False. | -| enable_latex | bool | True | Whether to enable LaTeX rendering. | -| latex_single_dollar_delimiter | bool | True | Whether to enable single dollar delimiter `$` for LaTeX rendering. | -| preview | bool | True | Whether to enable image preview functionality. | -| avatar_images | tuple\[str \| Path \| None \| dict \| list, str \| Path \| None \| dict\| list\] | None | An extended parameter value for gr.Chatbot, in addition to accepting a URL, it can also accept a dict and list. The dict can include the fields avatar and name, where the name field will be displayed under the avatar when rendered.
- When passing a dict, it must include an avatar field.
- When passing a list, it generally corresponds to the multi-bot mode, where each item can receive all the aforementioned values, and each bot’s avatar matches with the position of the bot in the messages. | -| avatar_image_align | Literal['top', 'middle', 'bottom'] | 'bottom' | Controls the alignment of the avatar with the messages, default is bottom-aligned. | -| avatar_image_width | int | 45 | The width of the avatar and name. | -| flushing_speed | int | 3 | Typewriter speed, values range from 1 - 10, with larger values indicating faster speeds. | -| llm_thinking_presets | list\[dict\] | \[\] | llm thinking link presets, which can convert the output format of llm calling tools into a fixed front-end display format. It needs to be imported from modelscope_studio.Chatbot.llm_thinking_presets, and currently supports: qwen. | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict is defined below | None | Allows users to define custom tags and control tag rendering styles and trigger Python events through JS. | - -**Definition of CustomComponent is as follows:** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### Built-in Custom Tags - -See Markdown Built-in Custom Tags - -### event listeners - -| Event | Description | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.Chatbot.flushed(fn, ···)` | Triggered when the typewriter effect ends. EventData is:
- index: The index tuple of the current message.
- value: The current message value. | -| `mgr.Chatbot.custom(fn, ···)` | Triggered when a custom tag event occurs. EventData is:
- index: The index tuple of the current message ([message index, user group(index 0) or bot group(index 1), user/bot group index]).
- tag: The current tag that triggered the event.
- tag_index: The index of the current triggered tag, re-calculated based on the message’s index tuple.
- value: The custom value passed in. | diff --git a/docs/components/legacy/Chatbot/app.py b/docs/components/legacy/Chatbot/app.py deleted file mode 100644 index ea841f78..00000000 --- a/docs/components/legacy/Chatbot/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.legacy.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/docs/components/legacy/Chatbot/demos/accordion.py b/docs/components/legacy/Chatbot/demos/accordion.py deleted file mode 100644 index 2c00ebfc..00000000 --- a/docs/components/legacy/Chatbot/demos/accordion.py +++ /dev/null @@ -1,51 +0,0 @@ -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr -from modelscope_studio.components.legacy.Chatbot.llm_thinking_presets import \ - qwen - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -conversation = [ - [ - None, { - "text": f""" -Use accordion tag: - - - -```json -{{"text": "glorious weather", "resolution": "1024*1024"}} -``` - - - -Qwen preset: -Action: image_gen -Action Input: {{"text": "glorious weather", "resolution": "1024*1024"}} -Observation: ![IMAGEGEN]({resolve_assets("screen.jpeg")}) Based on your description"glorious weather",I generated a picture.![]({resolve_assets("screen.jpeg")}) - -Action: 「An arbitrary text representation that will be displayed as the name of the thought chain call」 -Action Input: 「Any json or md content will be displayed in the drop-down box of the calling process」 -Observation: 「Any md content will be displayed in the drop-down box when the call is completed」 -""", - "flushing": False - } - ], -] - -with gr.Blocks() as demo, ms.Application(): - mgr.Chatbot( - value=conversation, - llm_thinking_presets=[qwen()], - height=600, - ) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Chatbot/demos/basic.py b/docs/components/legacy/Chatbot/demos/basic.py deleted file mode 100644 index 13570f9a..00000000 --- a/docs/components/legacy/Chatbot/demos/basic.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import time - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -conversation = [ - [ - None, - { - # The first message of bot closes the typewriter. - "text": "Hello I'm a chatbot", - "flushing": False - } - ], -] - - -def submit(_input, _chatbot): - _chatbot.append([_input, None]) - yield gr.update(interactive=False, value=None), _chatbot - time.sleep(2) - _chatbot[-1][1] = {"text": _input.text + '!'} - yield { - chatbot: _chatbot, - } - - -def flushed(): - return gr.update(interactive=True) - - -with gr.Blocks() as demo, ms.Application(): - chatbot = mgr.Chatbot( - value=conversation, - avatar_images=[ - os.path.join(os.path.dirname(__file__), - "../../resources/user.jpeg"), { - "name": - "bot", - "avatar": - os.path.join(os.path.dirname(__file__), - "../../resources/bot.jpeg") - } - ], - height=600, - ) - - input = mgr.MultimodalInput() - input.submit(fn=submit, inputs=[input, chatbot], outputs=[input, chatbot]) - chatbot.flushed(fn=flushed, outputs=[input]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Chatbot/demos/chart.py b/docs/components/legacy/Chatbot/demos/chart.py deleted file mode 100644 index e73cf301..00000000 --- a/docs/components/legacy/Chatbot/demos/chart.py +++ /dev/null @@ -1,43 +0,0 @@ -import json - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -# echarts options, see: https://echarts.apache.org/en/index.html -option1 = { - "xAxis": { - "type": 'category', - "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], - }, - "yAxis": { - "type": 'value', - }, - "series": [ - { - "data": [150, 230, 224, 218, 135, 147, 260], - "type": 'line', - }, - ], -} - -conversation = [ - [ - None, { - "text": f""" -Chart: - -""" - } - ], -] - -with gr.Blocks() as demo, ms.Application(): - mgr.Chatbot( - value=conversation, - flushing=False, - height=600, - ) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Chatbot/demos/message_config.py b/docs/components/legacy/Chatbot/demos/message_config.py deleted file mode 100644 index cddb958e..00000000 --- a/docs/components/legacy/Chatbot/demos/message_config.py +++ /dev/null @@ -1,35 +0,0 @@ -import time - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def submit(_chatbot): - _chatbot.append(["test user", - "test bot"]) # bot starts the typewriter by default - yield _chatbot - time.sleep(2) - _chatbot.append(["test user", { - "text": "test bot", - "flushing": False - }]) # both start the typewriter - yield _chatbot - time.sleep(2) - _chatbot.append([{ - "text": "test user", - "flushing": True - }, { - "text": "test bot", - "flushing": False - }]) # user starts the typewriter - yield _chatbot - - -with gr.Blocks() as demo, ms.Application(): - chatbot = mgr.Chatbot(height=600, ) - button = gr.Button("Submit") - button.click(fn=submit, inputs=[chatbot], outputs=[chatbot]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Chatbot/demos/multi_bots.py b/docs/components/legacy/Chatbot/demos/multi_bots.py deleted file mode 100644 index 21795b02..00000000 --- a/docs/components/legacy/Chatbot/demos/multi_bots.py +++ /dev/null @@ -1,87 +0,0 @@ -import os -import time - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -conversation = [ - [None, { - "text": "Hello I'm a chatbot", - "flushing": False - }], -] - - -def get_last_bot_message(chatbot): - return chatbot[-1][1] - - -def create_music_bot_message(text: str): - return { - "text": text, - } - - -def create_image_bot_message(text: str): - return { - "text": text, - } - - -def submit(_input, _chatbot): - _chatbot.append([_input, None]) - yield gr.update(interactive=False, value=None), _chatbot - _chatbot[-1][1] = [ - "Hello", - create_image_bot_message("Hello"), - create_music_bot_message("Hello") - ] - - time.sleep(2) - get_last_bot_message(_chatbot)[1][ - "text"] = f"""Hello, I\'m a image bot\n![image]({resolve_assets("user.jpeg")})""" - get_last_bot_message(_chatbot)[2][ - "text"] = f"""Hello, I\'m a music bot """ - yield { - chatbot: _chatbot, - } - - -def flushed(): - return gr.update(interactive=True) - - -with gr.Blocks() as demo, ms.Application(): - chatbot = mgr.Chatbot( - value=conversation, - avatar_image_width=40, - avatar_images=[ - resolve_assets('user.jpeg'), - # default bot avatar and name - [{ - "name": "bot", - "avatar": resolve_assets('bot.jpeg') - }, { - "name": "image bot", - "avatar": resolve_assets('image-bot.jpeg') - }, { - "name": "music bot", - "avatar": resolve_assets('music-bot.jpeg') - }] - ], - height=600, - ) - - input = mgr.MultimodalInput() - input.submit(fn=submit, inputs=[input, chatbot], outputs=[input, chatbot]) - chatbot.flushed(fn=flushed, outputs=[input]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Chatbot/demos/multimodal.py b/docs/components/legacy/Chatbot/demos/multimodal.py deleted file mode 100644 index cbb2fae8..00000000 --- a/docs/components/legacy/Chatbot/demos/multimodal.py +++ /dev/null @@ -1,39 +0,0 @@ -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -conversation = [ - [ - None, { - "text": f""" -Image - -![image]({resolve_assets("bot.jpeg")}) - - - -Audio - - -""", - "flushing": False - } - ], -] - -with gr.Blocks() as demo, ms.Application(): - mgr.Chatbot( - value=conversation, - height=600, - ) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Chatbot/demos/select-box.py b/docs/components/legacy/Chatbot/demos/select-box.py deleted file mode 100644 index cfbae22e..00000000 --- a/docs/components/legacy/Chatbot/demos/select-box.py +++ /dev/null @@ -1,48 +0,0 @@ -import json - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -# `label` will display on the page, and `value` is the actual selected value. -options = [{"label": "A", "value": "a"}, "b", "c"] - -conversation = [[ - None, f""" -Single Select: - -Multiple Select: - -Vertical Direction: - - - -Card Shape: - - - - - - - - -""" -]] - - -# The custom data must be marked by `gr.EventData` -def fn(data: gr.EventData): - print(data._data) - - -with gr.Blocks() as demo, ms.Application(): - chatbot = mgr.Chatbot( - value=conversation, - flushing=False, - height=600, - ) - # All custom tags will trigger the custom event - chatbot.custom(fn=fn) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Docs.py b/docs/components/legacy/Docs.py deleted file mode 100644 index 6c1eb421..00000000 --- a/docs/components/legacy/Docs.py +++ /dev/null @@ -1,178 +0,0 @@ -import os -import re -from typing import Callable - -import gradio as gr -import modelscope_studio.components.legacy as mgr -from helper.env import is_modelscope_studio - -from .parse_markdown import parse_markdown - -with open(os.path.join(os.path.dirname(__file__), "tab-link.js")) as f: - tab_link_js = f.read() - -custom_components = { - "tab-link": { - "props": ["tab", "component-tab"], - "js": tab_link_js - } -} - - -def remove_formatter(markdown_text): - pattern = r"^ *---[\s\S]*?---" - - replaced_text = re.sub(pattern, "", markdown_text) - - return replaced_text - - -def list_demos(dir_path: str, prefix=''): - result = [] - if (not os.path.isdir(dir_path)): - return result - for name in os.listdir(dir_path): - path = os.path.join(dir_path, name) - - if os.path.isfile(path): - result.append(prefix + name) - elif os.path.isdir(path): - sub_prefix = prefix + name + '/' - result.extend(list_demos(path, sub_prefix)) - - return result - - -def get_demo_modules(file_path: str): - import importlib.util - - demos = [ - demo for demo in list_demos( - os.path.join(os.path.dirname(file_path), "demos")) - if demo.endswith(".py") and not demo.startswith("__") - ] - demo_modules = {} - for demo in demos: - demo_name = demo.split(".")[0] - spec = importlib.util.spec_from_file_location( - "demo", os.path.join(os.path.dirname(file_path), "demos", demo)) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - demo_modules[demo_name] = module - return demo_modules - - -class Docs: - - def __init__(self, file_path: str, markdown_files: list = None): - self.file_path = file_path - self.demo_modules = get_demo_modules(file_path) - # default current directory - self.markdown_files = markdown_files if markdown_files else [ - filename for filename in os.listdir(os.path.dirname(file_path)) - if filename.endswith(".md") - ] - if is_modelscope_studio: - self.markdown_files = list( - filter( - lambda x: x.endswith("-zh_CN.md") or - (f"{'.'.join(x.split('.')[:-1])}-zh_CN.md" not in self. - markdown_files), self.markdown_files)) - else: - self.markdown_files = list( - filter(lambda x: not x.endswith("-zh_CN.md"), - self.markdown_files)) - - self.tabs = None - - def read_file(self, relative_path: str): - with open(os.path.join(os.path.dirname(self.file_path), relative_path), - "r") as f: - return f.read() - - def render_demo(self, - demo_name, - code_position='left', - prefix='', - suffix=''): - content = self.read_file(f"./demos/{demo_name}.py") - module = self.demo_modules[demo_name] - with gr.Accordion("Show Demo", open=False): - - def render_code(): - mgr.Markdown(f"""{prefix} -````python -{content} -```` -{suffix}""", - header_links=True, - custom_components=custom_components) - - if code_position == 'top': - with gr.Row(): - with gr.Column(): - render_code() - with gr.Row(): - if code_position == 'left': - with gr.Column(): - render_code() - with gr.Column(): - module.demo.render() - if code_position == 'right': - with gr.Column(): - render_code() - if code_position == 'bottom': - with gr.Row(): - with gr.Column(): - render_code() - - def render_markdown(self, - markdown_file, - on_tab_link_click: Callable = None, - components_tabs=None): - items = parse_markdown(remove_formatter(self.read_file(markdown_file)), - read_file=self.read_file) - for item in items: - if item["type"] == "text": - md = mgr.Markdown(item["value"], - header_links=True, - custom_components=custom_components, - preview=False) - deps = [dep for dep in [components_tabs, self.tabs] if dep] - if len(deps) > 0: - md.custom(fn=on_tab_link_click, outputs=deps) - elif item["type"] == "demo": - self.render_demo(item["name"], - prefix=item["prefix"], - suffix=item["suffix"], - code_position=item["code_position"]) - - def render(self, components_tabs=None): - - def tab_link_click(data: gr.EventData): - tab: str = data._data.get("value", {}).get("tab", '') - component_tab: str = data._data["value"].get("component_tab", '') - if tab and tabs: - return {tabs: gr.update(selected=tab)} - elif components_tabs and component_tab: - return {components_tabs: gr.update(selected=component_tab)} - - with gr.Blocks() as demo: - - if len(self.markdown_files) > 1: - with gr.Tabs() as tabs: - self.tabs = tabs - - for markdown_file in self.markdown_files: - tab_name = ".".join(markdown_file.split(".")[:-1]) - tab_name = tab_name.split("-zh_CN")[0] - with gr.TabItem(tab_name, id=tab_name): - self.render_markdown( - markdown_file, - on_tab_link_click=tab_link_click, - components_tabs=components_tabs) - elif (len(self.markdown_files) == 1): - self.render_markdown(self.markdown_files[0], - on_tab_link_click=tab_link_click, - components_tabs=components_tabs) - return demo diff --git a/docs/components/legacy/Flow/README-zh_CN.md b/docs/components/legacy/Flow/README-zh_CN.md deleted file mode 100644 index 0c4afb7e..00000000 --- a/docs/components/legacy/Flow/README-zh_CN.md +++ /dev/null @@ -1,109 +0,0 @@ -# Flow - -基于 [reactflow](https://reactflow.dev/) 实现的 Flow 组件。 - -- 支持通过 schema 自定义渲染节点 -- 支持自定义节点的渲染组件,并与 Python 事件交互 - -## 如何使用 - -### 定义 schema 节点 (重要) - -详见:Define Schema - -### 基本使用 - - - -### 组件配置项 - - - -### 自定义节点类型(高阶用法,需要了解前端知识) - - - -## API 及参数列表 - -### value - -接口定义: - -```python -class NodePosition(GradioModel): - x: Optional[int] = 0 - y: Optional[int] = 0 - - -class Node(GradioModel): - id: Optional[str] = None - name: str - title: Optional[str] = None - position: Optional[Union[NodePosition, dict]] = None - data: Optional[dict] = None - -class EdgePort(GradioModel): - attr: Optional[str] = None - attrItemIndex: Optional[int] = None - handleIndex: Optional[int] = None - -class Edge(GradioModel): - id: Optional[str] = None - source: str - target: str - sourcePort: Optional[Union[EdgePort, dict]] = None - targetPort: Optional[Union[EdgePort, dict]] = None - - -class FlowData(GradioModel): - nodes: Optional[List[Union[Node, dict]]] = [] - edges: Optional[List[Union[Edge, dict]]] = [] - -``` - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ------------------- | --------------------------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| height | int \| str | 600 | Flow 组件高度。 | -| sync_on_data_change | bool | None | 是否仅在数据更改时同步 Python 值(例如:节点属性、节点计数、边缘计数、连接端口等,不包括节点位置)。 如果您想要更好的页面性能而不是完整数据同步,则应将其设置为 True。 | -| schema | FlowSchemaDict \| dict | None | 定义 Flow 组件的 nodes 与 edges。 | -| show_sidebar | bool | True | 是否展示侧 Flow 组件侧边栏。 | -| show_minimap | bool | True | 是否展示侧 Flow 组件小地图。 | -| show_controls | bool | True | 是否展示侧Flow 组件控制栏。 | -| background_props | BackgroundPropsDict \| dict CustomComponentDict 定义见下方 | None | 修改 Flow组件背景,详见 BackgroundPropsDict 类型。 | -| min_zoom | int | 0.1 | Flow 组件最小缩放倍率。 | -| max_zoom | int | 2 | Flow 组件最大缩放倍率。 | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户自定义节点类型,并通过 js 控制渲染样式与触发 python 事件。 | - -**BackgroundPropsDict 定义如下** - -```python -class BackgroundPropsDict(TypedDict): - color: Optional[str] - className: Optional[str] - # The gap between patterns. Passing in a tuple allows you to control the x and y gap independently. - gap: Optional[Union[int, Tuple[int, int]]] - # The radius of each dot or the size of each rectangle if BackgroundVariant.Dots or BackgroundVariant.Cross is used. This defaults to 1 or 6 respectively, or ignored if BackgroundVariant.Lines is used. - size: Optional[int] - offset: Optional[int] - lineWidth: Optional[int] - variant: Optional[Literal['dots', 'lines', 'cross']] -``` - -**CustomComponentDict 定义如下** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### event listeners - -| 事件 | 描述 | -| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mgr.Flow.change(fn, ···)` | 当 value 更新时触发,如果 sync_on_data_change 值为 True 时,此时 flow 的实际数据可能并不是实时的,建议监听 data_change 事件。 | -| `mgr.Flow.data_change(fn, ···)` | 当在数据更改时触发(例如:节点属性、节点计数、边缘计数、连接端口等,不包括节点位置) | -| `mgr.Flow.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- id:当前触发节点 id。
- node:当前触发节点类型。
- attr:当前触发节点属性。
- index:当前触发节点属性索引,当节点属性为 list 时有值。
- value:自定义传入的值。 | diff --git a/docs/components/legacy/Flow/README.md b/docs/components/legacy/Flow/README.md deleted file mode 100644 index b7ebf875..00000000 --- a/docs/components/legacy/Flow/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# Flow - -A Flow component implemented based on [reactflow](https://reactflow.dev/). - -- Supports customization of node rendering through a schema. -- Allows for custom node render components with interaction from Python. - -## How to Use - -### Defining Schema Nodes (Important) - -See: Define Schema - -### Basic Usage - - - -### Component Options - - - -### Custom Node Types (Advanced usage, requires frontend knowledge) - - - -## API and Parameter List - -### value - -Interface definition: - -```python -class NodePosition(GradioModel): - x: Optional[int] = 0 - y: Optional[int] = 0 - - -class Node(GradioModel): - id: Optional[str] = None - name: str - title: Optional[str] = None - position: Optional[Union[NodePosition, dict]] = None - data: Optional[dict] = None - -class EdgePort(GradioModel): - attr: Optional[str] = None - attrItemIndex: Optional[int] = None - handleIndex: Optional[int] = None - -class Edge(GradioModel): - id: Optional[str] = None - source: str - target: str - sourcePort: Optional[Union[EdgePort, dict]] = None - targetPort: Optional[Union[EdgePort, dict]] = None - - -class FlowData(GradioModel): - nodes: Optional[List[Union[Node, dict]]] = [] - edges: Optional[List[Union[Edge, dict]]] = [] -``` - -### props - -| Attribute | Type | Default Value | Description | -| ------------------- | --------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| height | int \| str | 600 | Height of the Flow component. | -| sync_on_data_change | bool | None | Whether to sync the Python value only on data change (e.g., node attributes, node count, edge count, connection ports, not including node positions). If you want better page performance without full data sync, set this to True. | -| schema | FlowSchemaDict \| dict | None | Defines the nodes and edges of the Flow component. | -| show_sidebar | bool | True | Whether to display the sidebar in the Flow component. | -| show_minimap | bool | True | Whether to display the minimap in the Flow component. | -| show_controls | bool | True | Whether to display the controls bar in the Flow component. | -| background_props | BackgroundPropsDict \| dict BackgroundPropsDict definition below | None | Modify the background of the Flow component, see the BackgroundPropsDict type. | -| min_zoom | int | 0.1 | Minimum zoom level for the Flow component. | -| max_zoom | int | 2 | Maximum zoom level for the Flow component. | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict definition below | None | Supports user-defined custom tags and controls tag rendering styles and triggers Python events through js. | - -**BackgroundPropsDict definition:** - -```python -class BackgroundPropsDict(TypedDict): - color: Optional[str] - className: Optional[str] - # The gap between patterns. Passing in a tuple allows you to control the x and y gap independently. - gap: Optional[Union[int, Tuple[int, int]]] - # The radius of each dot or the size of each rectangle if BackgroundVariant.Dots or BackgroundVariant.Cross is used. This defaults to 1 or 6 respectively, or ignored if BackgroundVariant.Lines is used. - size: Optional[int] - offset: Optional[int] - lineWidth: Optional[int] - variant: Optional[Literal['dots', 'lines', 'cross']] -``` - -**CustomComponentDict definition:** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### Event Listeners - -| Event | Description | -| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mgr.Flow.change(fn, ...)` | Triggers when the `value` updates. If `sync_on_data_change` is True, the actual data at this point might not be up-to-date; consider listening to the `data_change` event instead. | -| `mgr.Flow.data_change(fn, ...)` | Triggers when there's a data change (e.g., node attributes, node count, edge count, connection ports), but not node positions. | -| `mgr.Flow.custom(fn, ...)` | Triggers when a custom label event occurs. The `EventData` includes:
- `id`: ID of the currently triggered node.
- `node`: Type of the currently triggered node.
- `attr`: Attributes of the currently triggered node.
- `index`: Index of the attribute if it's a list.
- `value`: Custom passed-in value. | diff --git a/docs/components/legacy/Flow/app.py b/docs/components/legacy/Flow/app.py deleted file mode 100644 index ea841f78..00000000 --- a/docs/components/legacy/Flow/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.legacy.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/docs/components/legacy/Flow/define_schema-zh_CN.md b/docs/components/legacy/Flow/define_schema-zh_CN.md deleted file mode 100644 index dfd15303..00000000 --- a/docs/components/legacy/Flow/define_schema-zh_CN.md +++ /dev/null @@ -1,266 +0,0 @@ -# Define Schema - -在使用 Flow 组件前,需要预先创建 Schema 定义 node 节点,schema 类型定义如下: - -```ts -export interface FlowSchema { - nodes: FlowNodeSchema[]; -} - -export interface FlowNodeSchema { - /** - * 作为节点的唯一标识。必填。 - */ - name: string; - - /** - * 节点显示图标。 - */ - icon?: string; - - /** - * 节点标题,如果没有提供则默认使用 name。 - */ - title?: string; - - /** - * 节点的简短描述。 - */ - description?: string; - - /** - * 节点宽度。 - */ - width?: number; - - /** - * 节点高度。 - */ - height?: number; - - /** - * 显示/隐藏工具栏(删除、复制、重命名等)。 - * @default true - */ - show_toolbar?: boolean; - - /** - * 启用/禁止添加更多此类节点实例。 - * @default true - */ - addable?: boolean; - - /** - * 启用/禁止删除现有此类节点实例。 - * @default true - */ - deletable?: boolean; - - /** - * 可以同时存在的此类节点的最大数量。 - */ - max?: number; - - /** - * 可以同时存在的此类节点的最小数量。 - */ - min?: number; - - /** - * 节点连接端口的配置。 - */ - ports?: { - /** - * 节点作为连接的源端口。 - * @default ['right'] - */ - source?: Position[]; - - /** - * 允许此节点 source 端口连接到的其他节点或属性。默认为所有节点和属性。 - * @default [] - */ - sourceConnections?: PortConnection[]; - - /** - * 节点作为连接的目标端口。 - * @default ['left'] - */ - target?: Position[]; - - /** - * 其他允许连接到此节点 target 端口的节点或属性。默认为所有节点和属性 - * @default [] - */ - targetConnections?: PortConnection[]; - }; - - /** - * 节点的属性配置。 - */ - attrs?: FlowNodeAttrSchema[]; - - /** - * 创建新实例时节点属性的初始值。 - */ - template?: { - /** - * 在`attrs`字段中与其名称相对应的属性值,例如 { "a": 1, "b": 2 }。 - */ - attrs?: Attrs; - }; -} - -export interface FlowNodeAttrSchema { - /** - * 唯一的属性名称,在 node data 中用作 key。必填。 - */ - name: string; - - /** - * 属性标题,如果没有提供则默认使用 name。 - */ - title?: string; - - /** - * 属性的简短描述 - */ - description?: string; - - /** - * 禁用用户编辑属性值。默认情况下,属性是可编辑的。 - * @default false - */ - disabled?: boolean; - - /** - * 属性输入类型。可以是内置的 Ant Design 组件或自定义组件之一。默认为'input'。 - * @default 'input' - */ - type?: - | 'input' - | 'textarea' - | 'radio' - | 'checkbox' - | 'number' - | 'select' - | 'switch' - | 'upload' - // 自定义 - | (string & {}); - - /** - * 针对所选组件类型的特定配置选项,支持 Ant Design 组件({@link https://ant.design/components/overview/})或自定义组件的属性。 - */ - props?: Record; - - /** - * 节点属性连接端口的配置。 - */ - ports?: { - /** - * 节点属性作为连接的源端口。 - * @default [] - */ - source?: Position[]; - - /** - * 允许此节点属性 source 端口连接到的其他节点或属性。 - * @default [] - */ - sourceConnections?: PortConnection[]; - - /** - * 节点属性作为连接的目标端口。 - * @default [] - */ - target?: Position[]; - - /** - * 其他允许连接到此节点属性 target 端口的节点或属性。 - * @default [] - */ - targetConnections?: PortConnection[]; - }; - - /** - * 表示该属性是否为列表值。 - * @default false - */ - list?: - | boolean - | { - /** - * 列表中每个 item 的端口配置。 - */ - ports?: { - /** - * 列表 item 作为连接的源端口。 - * @default [] - */ - source?: Position[]; - - /** - * 允许此列表 item source 端口连接到的其他节点或属性。 - * @default [] - */ - sourceConnections?: PortConnection[]; - - /** - * 列表 item 作为连接的目标端口。 - */ - target?: Position[]; - - /** - * 其他允许连接到此列表 item target 端口的节点或属性。 - */ - targetConnections?: PortConnection[]; - }; - - /** - * 列表中的最小 item 数量。 - */ - min?: number; - - /** - * 列表中的最大 item 数量。 - */ - max?: number; - }; - - /** - * 启用/禁用手风琴 UI。 - * @default true - */ - accordion?: boolean; - - /** - * 指定该属性值是否为必填项。默认情况为非必填项。 - * @default false - */ - required?: - | boolean - | { - message?: string; - }; - - /** - * 使用 JSON schema 验证属性值。 - */ - json_schema_validator?: Record; -} -``` - -你可以通过 json 文件(推荐)或直接在 Python 端通过导出类型定义: - -- 通过 json 定义: - -```json - -``` - -- 通过 Python 定义: - -```python - -``` diff --git a/docs/components/legacy/Flow/define_schema.md b/docs/components/legacy/Flow/define_schema.md deleted file mode 100644 index bb2c78c1..00000000 --- a/docs/components/legacy/Flow/define_schema.md +++ /dev/null @@ -1,262 +0,0 @@ -# Define Schema - -Before using the Flow component, need to create a Schema definition node in advance. The schema type is defined as follows: - -```ts -export interface FlowSchema { - nodes: FlowNodeSchema[]; -} - -export interface FlowNodeSchema { - /** - * As a unique identifier for the node. Mandatory. - */ - name: string; - - /** - * Display icon for the node. - */ - icon?: string; - - /** - * Display title for the node, defaults to the node name if not provided. - */ - title?: string; - - /** - * A short description of the node's purpose. - */ - description?: string; - - /** - * Width of the node. - */ - width?: number; - - /** - * Height of the node. - */ - height?: number; - - /** - * Shows/hides the toolbar (delete, copy, rename, etc.). - * @default true - */ - show_toolbar?: boolean; - - /** - * Enables/disables adding more instances of this node. - * @default true - */ - addable?: boolean; - - /** - * Enables/disables deleting existing instances of this node. - * @default true - */ - deletable?: boolean; - - /** - * Maximum number of this node type that can exist simultaneously. - */ - max?: number; - - /** - * Minimum number of this node type that must exist simultaneously. - */ - min?: number; - - /** - * Configurations for the node's connection ports. - */ - ports?: { - /** - * Source ports for the node as a connection. - * @default ['right'] - */ - source?: Position[]; - - /** - * Allowed the source ports of this node to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the node as a connection - * @default ['left'] - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this node. Defaults to all nodes and attributes - * - */ - targetConnections?: PortConnection[]; - }; - - /** - * Configuration of the node's attributes. - */ - attrs?: FlowNodeAttrSchema[]; - - /** - * Initial values for the node's attributes when creating a new instance. - */ - template?: { - /** - * Attribute values corresponding to their names in the `attrs` field, e.g., `{ "a": 1, "b": 2 }`. - */ - attrs?: Attrs; - }; -} - -export interface FlowNodeAttrSchema { - /** - * Unique attribute name used as a key in the node data. Mandatory. - */ - name: string; - - /** - * Display title for the attribute, defaults to the attribute name if not provided. - */ - title?: string; - - /** - * A brief explanation about the attribute purpose. - */ - description?: string; - - /** - * Disables user editing of the attribute value. By default, attributes are editable. - * @default false - */ - disabled?: boolean; - - /** - * Attribute input type. Can be one of the built-in Ant Design components or a custom component. Defaults to 'input'. - * @default 'input' - */ - type?: - | 'input' - | 'textarea' - | 'radio' - | 'checkbox' - | 'number' - | 'select' - | 'switch' - | 'upload' - // custom - | (string & {}); - - /** - * Configuration options specific to the chosen component type, supporting Ant Design ({@link https://ant.design/components/overview/}) or custom component properties. - */ - props?: Record; - - /** - * Configurations for the node attribute ports. - */ - ports?: { - /** - * Source ports for the attribute as a connection. - * @default [] - */ - source?: Position[]; - - /** - * Allowed the source ports of this attribute to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the attribute as a connection - * @default [] - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this attribute. Defaults to all nodes and attributes - */ - targetConnections?: PortConnection[]; - }; - - /** - * Indicates whether the attribute is a list. - * @default false - */ - list?: - | boolean - | { - /** - * Port configurations for each item in the list. - */ - ports?: { - /** - * Source ports for the list item as a connection. - * @default [] - */ - source?: Position[]; - - /** - * Allowed the source ports of this list item to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the list item as a connection - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this list item. Defaults to all nodes and attributes - */ - targetConnections?: PortConnection[]; - }; - - /** - * Minimum number of items in the list. - */ - min?: number; - - /** - * Maximum number of items in the list. - */ - max?: number; - }; - - /** - * Enable/disable accordion UI. - * @default true - */ - accordion?: boolean; - - /** - * Specifies if the attribute value is mandatory. By default, attributes are optional. - * @default false - */ - required?: - | boolean - | { - message?: string; - }; - - /** - * Validates attribute values using JSON schema. - */ - json_schema_validator?: Record; -} -``` - -You can define the schema by a json file (recommended) or directly on the Python by the exported types: - -- Defined by json: - -```json - -``` - -- Defined by Python: - -```python - -``` diff --git a/docs/components/legacy/Flow/demos/basic.py b/docs/components/legacy/Flow/demos/basic.py deleted file mode 100644 index 48f18eff..00000000 --- a/docs/components/legacy/Flow/demos/basic.py +++ /dev/null @@ -1,35 +0,0 @@ -import json -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr -from modelscope_studio.components.legacy.Flow import Edge, Node - -with open((os.path.join(os.path.dirname(__file__), - "../schema/agents_schema.json"))) as f: - schema = json.load(f) - -# define the initial value of the flow -data = { - "nodes": [ - Node(id="start-node", name="start", position=dict(x=0, y=0)), - Node(id="initial-agent-node", - name="agent", - position=dict(x=200, y=0), - data=dict(condition=[''])) - ], - "edges": [Edge(source='start-node', target="initial-agent-node")], -} - - -def on_data_change(_flow): - print(_flow) - - -with gr.Blocks() as demo, ms.Application(): - flow = mgr.Flow(value=data, schema=schema, sync_on_data_change=True) - flow.data_change(fn=on_data_change, inputs=[flow]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Flow/demos/component_options.py b/docs/components/legacy/Flow/demos/component_options.py deleted file mode 100644 index 79ccb9f0..00000000 --- a/docs/components/legacy/Flow/demos/component_options.py +++ /dev/null @@ -1,109 +0,0 @@ -import json -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr -from modelscope_studio.components.legacy.Flow import (BackgroundPropsDict, - Edge, Node) - -with open((os.path.join(os.path.dirname(__file__), - "../schema/agents_schema.json"))) as f: - schema = json.load(f) - -# define the initial value of the flow -data = { - "nodes": [ - Node(id="start-node", name="start", position=dict(x=0, y=0)), - Node(id="initial-agent-node", - name="agent", - position=dict(x=200, y=0), - data=dict(condition=[''])) - ], - "edges": [Edge(source='start-node', target="initial-agent-node")], -} - - -def on_data_change(_flow): - print(_flow) - - -flow_props = ["show_sidebar", "show_minimap", "show_controls"] - - -def on_change(_flow_config, _bgc_variant, _bgc_color, _bgc_bg_color, _bgc_gap, - _bgc_size, _bgc_offset, _bgc_line_width): - new_props = {} - new_background_props = { - "variant": _bgc_variant, - "bgColor": _bgc_bg_color, - "color": _bgc_color, - "gap": _bgc_gap, - "size": _bgc_size, - "offset": _bgc_offset, - 'lineWidth': _bgc_line_width - } - for choice in flow_props: - if choice in _flow_config: - new_props[choice] = True - else: - new_props[choice] = False - return gr.update(**new_props, background_props=new_background_props) - - -with gr.Blocks() as demo, ms.Application(): - with gr.Accordion(label="Flow Options"): - flow_config = gr.CheckboxGroup( - container=False, - value=["show_sidebar", "show_minimap", "show_controls"], - choices=flow_props) - with gr.Accordion(label="Background Props"): - with gr.Row(): - with gr.Column(): - bgc_variant = gr.Radio(choices=["dots", "lines", "cross"], - label="variant", - value="dots") - with gr.Column(): - bgc_color = gr.ColorPicker(label="color", value="") - with gr.Column(): - bgc_bg_color = gr.ColorPicker(label="bgColor", value="") - with gr.Column(): - bgc_gap = gr.Slider(label="gap", value=28) - with gr.Column(): - bgc_size = gr.Slider(label="size", - value=1, - maximum=10, - step=1) - with gr.Column(): - bgc_offset = gr.Slider(label="offset", - value=1, - step=1, - maximum=10) - with gr.Column(): - bgc_line_width = gr.Slider(label="lineWidth", - value=1, - step=1, - maximum=10) - - flow = mgr.Flow(value=data, - schema=schema, - show_controls=True, - show_minimap=True, - show_sidebar=True, - sync_on_data_change=True, - background_props=BackgroundPropsDict(variant='dots')) - gr.on(triggers=[ - flow_config.change, bgc_variant.change, bgc_color.change, - bgc_bg_color.change, bgc_gap.change, bgc_size.change, - bgc_offset.change, bgc_line_width.change - ], - fn=on_change, - inputs=[ - flow_config, bgc_variant, bgc_color, bgc_bg_color, bgc_gap, - bgc_size, bgc_offset, bgc_line_width - ], - outputs=[flow]) - flow.data_change(fn=on_data_change, inputs=[flow]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Flow/demos/custom_node_type.py b/docs/components/legacy/Flow/demos/custom_node_type.py deleted file mode 100644 index d2b50b1e..00000000 --- a/docs/components/legacy/Flow/demos/custom_node_type.py +++ /dev/null @@ -1,69 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr -from modelscope_studio.components.legacy.Flow import (FlowSchemaDict, Node, - NodeSchemaAttributeDict, - NodeSchemaDict) - - -def on_data_change(_flow): - print(_flow) - - -def on_custom(data: gr.EventData): - print(data._data) - - -custom_components = { - "my-input": { - "js": - """ -(props, cc, { el, theme, onMount, onUpdate }) => { - onMount(() => { - el.innerHTML = `` - const input = el.querySelector('input') - input.style.color = theme === 'dark' ? 'white' : 'black' - input.style.backgroundColor = theme === 'dark' ? 'black' : 'white' - input.addEventListener('change', (e) => { - cc.dispatch(e.target.value) - }) - }) - // props update - onUpdate( - () => { - const input = el.querySelector('input') - input.setAttribute('value', props.value || '') - }, - // By default, the callback will not be called when the component is being mounted. Set `callAfterMount` to true to enable it. - { callAfterMount: true } - ) -} -""" - } -} - -schema = FlowSchemaDict(nodes=[ - NodeSchemaDict(name="my-input-node", - title="MyInputNode", - attrs=[NodeSchemaAttributeDict(name="a", type="my-input")]) -]) - -data = { - "nodes": [ - Node(name="my-input-node", - position=dict(x=0, y=0), - data=dict(a='Hello')) - ] -} - -with gr.Blocks() as demo, ms.Application(): - flow = mgr.Flow(value=data, - schema=schema, - custom_components=custom_components, - sync_on_data_change=True) - flow.data_change(fn=on_data_change, inputs=[flow]) - # called when custom component dispatch event - flow.custom(fn=on_custom) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Flow/schema/agents_schema.json b/docs/components/legacy/Flow/schema/agents_schema.json deleted file mode 100644 index 3134b2dc..00000000 --- a/docs/components/legacy/Flow/schema/agents_schema.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/modelscope/modelscope-studio/main/frontend/Flow/schema.json", - "nodes": [ - { - "max": 1, - "min": 1, - "addable": false, - "show_toolbar": false, - "name": "start", - "title": "Start", - "ports": { - "source": ["right"], - "target": [] - } - }, - { - "icon": "https://img.alicdn.com/imgextra/i4/O1CN01fvt4it25rEZU4Gjso_!!6000000007579-2-tps-128-128.png", - "name": "agent", - "title": "Agent Node", - "description": "Agent Flow Node", - "ports": { - "target": ["left"], - "source": [] - }, - "attrs": [ - { - "name": "prompt", - "title": "Agent Prompt", - "type": "textarea", - "required": { - "message": "Agent Prompt is required" - } - }, - { - "name": "tool", - "title": "Tools", - "type": "select", - "props": { - "mode": "multiple", - "options": [ - { "label": "Wanx Image Generation", "value": "image_gen" }, - { "label": "Code Interpreter", "value": "code_interpreter" }, - { "label": "Web Browsing", "value": "web_browser" } - ] - } - }, - { - "name": "condition", - "title": "Jump Condition", - "list": { - "min": 1, - "ports": { - "source": ["right"] - } - }, - "accordion": false - } - ], - "template": { - "attrs": { - "condition": [""] - } - } - } - ] -} diff --git a/docs/components/legacy/Flow/schema/agents_schema.py b/docs/components/legacy/Flow/schema/agents_schema.py deleted file mode 100644 index d80f7848..00000000 --- a/docs/components/legacy/Flow/schema/agents_schema.py +++ /dev/null @@ -1,59 +0,0 @@ -import os - -from modelscope_studio.components.legacy.Flow import ( - FlowSchemaDict, NodeSchemaAttributeDict, NodeSchemaAttributeListDict, - NodeSchemaAttributeRequiredDict, NodeSchemaDict, NodeSchemaPortsDict, - NodeSchemaTemplateDict) - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -schema = FlowSchemaDict(nodes=[ - NodeSchemaDict(max=1, - min=1, - addable=False, - show_toolbar=False, - name="start", - title="Start", - ports=NodeSchemaPortsDict(source=['right'], target=[])), - NodeSchemaDict( - icon=resolve_assets('./bot.jpeg'), - name="agent", - title="Agent Node", - description="Agent Flow Node", - ports=NodeSchemaPortsDict(source=[], target=['left']), - attrs=[ - NodeSchemaAttributeDict(name="prompt", - title="Agent Prompt", - type='textarea', - required=NodeSchemaAttributeRequiredDict( - message="Agent Prompt is required")), - NodeSchemaAttributeDict(name="tool", - title="Tools", - type="select", - props={ - "mode": - "multiple", - "options": [{ - "label": "Wanx Image Generation", - "value": "image_gen" - }, { - "label": "Code Interpreter", - "value": "code_interpreter" - }, { - "label": "Web Browsing", - "value": "web_browser" - }] - }), - NodeSchemaAttributeDict( - name="condition", - title="Jump Condition", - list=NodeSchemaAttributeListDict( - min=1, ports=NodeSchemaPortsDict(source=['right'])), - accordion=False) - ], - template=NodeSchemaTemplateDict(attrs=dict(condition=['']))) -]) diff --git a/docs/components/legacy/Lifecycle/README-zh_CN.md b/docs/components/legacy/Lifecycle/README-zh_CN.md deleted file mode 100644 index 2a110cbd..00000000 --- a/docs/components/legacy/Lifecycle/README-zh_CN.md +++ /dev/null @@ -1,53 +0,0 @@ -# Lifecycle - -生命周期组件,用于获取当前用户的环境信息。 - -- 获取当前用户的语言、页面主题、user agent 和屏幕状态。 -- 监听页面行为并触发相应事件(页面加载、尺寸变化、页面关闭等)。 - -## 如何使用 - -### 基本使用 - - - -### 自动适配用户语言环境 - - - -### 根据用户界面主题返回不同权重内容 - - - -## API 及参数列表 - -### value - -接口定义: - -```python -class LifecycleScreenData(GradioModel): - width: float - height: float - scrollX: float - scrollY: float - - -class LifecycleData(GradioModel): - screen: LifecycleScreenData - language: str - theme: str - userAgent: str -``` - -### props - -该组件不支持传入 props。 - -### event listeners - -| 事件 | 描述 | -| -------------------------------- | --------------------------------------------------------------------- | -| `mgr.Lifecycle.mount(fn, ···)` | 用户页面加载时触发,EventData 为当前组件 value 的 dict 类型值。 | -| `mgr.Lifecycle.unmount(fn, ···)` | 用户页面关闭时触发,EventData 为当前组件 value 的 dict 类型值。 | -| `mgr.Lifecycle.resize(fn, ···)` | 自定义标签触发事件时触发,EventData 为当前组件 value 的 dict 类型值。 | diff --git a/docs/components/legacy/Lifecycle/README.md b/docs/components/legacy/Lifecycle/README.md deleted file mode 100644 index 66c646f9..00000000 --- a/docs/components/legacy/Lifecycle/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Lifecycle - -A Lifecycle component for getting the current user's environment information. - -- Get the current user's language, page theme, user agent, and screen state. -- Listen to page actions and trigger corresponding events (page loading, size changes, page closing, etc.). - -## How to Use - -### Basic Usage - - - -### Automatically Adapt to User Language Environment - - - -### Return Different Weighted Content Based on UI Theme - - - -## API and Parameter List - -### Value - -Interface definition: - -```python -class LifecycleScreenData(GradioModel): - width: float - height: float - scrollX: float - scrollY: float - - -class LifecycleData(GradioModel): - screen: LifecycleScreenData - language: str - theme: str - userAgent: str -``` - -### Props - -This component does not support passing in props. - -### Event Listeners - -| Event | Description | -| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -| `mgr.Lifecycle.mount(fn, ···)` | Triggered when the user's page loads. The EventData is a dictionary type value of the current component's value. | -| `mgr.Lifecycle.unmount(fn, ···)` | Triggered when the user's page closes. The EventData is a dictionary type value of the current component's value. | -| `mgr.Lifecycle.resize(fn, ···)` | Triggered when custom labels trigger events. The EventData is a dictionary type value of the current component's value. | diff --git a/docs/components/legacy/Lifecycle/app.py b/docs/components/legacy/Lifecycle/app.py deleted file mode 100644 index ea841f78..00000000 --- a/docs/components/legacy/Lifecycle/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.legacy.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/docs/components/legacy/Lifecycle/demos/basic.py b/docs/components/legacy/Lifecycle/demos/basic.py deleted file mode 100644 index dc35dd8a..00000000 --- a/docs/components/legacy/Lifecycle/demos/basic.py +++ /dev/null @@ -1,28 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def mount(e: gr.EventData): - # current page state - print("onMount", e._data) - - -def resize(e: gr.EventData): - print("onResize", e._data) - - -def onUnmount(e: gr.EventData): - print("onUnmount", e._data) - - -with gr.Blocks() as demo, ms.Application(): - gr.Markdown("The Lifecycle component will not be rendered on the page.") - lifecycle = mgr.Lifecycle() - # listen to the page lifecycle - lifecycle.mount(fn=mount) - lifecycle.resize(fn=resize) - lifecycle.unmount(fn=onUnmount) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Lifecycle/demos/language_adaptation.py b/docs/components/legacy/Lifecycle/demos/language_adaptation.py deleted file mode 100644 index c6f53551..00000000 --- a/docs/components/legacy/Lifecycle/demos/language_adaptation.py +++ /dev/null @@ -1,41 +0,0 @@ -import time - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -messages = { - 'en': { - "hello": "Hello" - }, - 'en-US': { - "hello": "Hello" - }, - 'zh-CN': { - "hello": "你好" - } -} - -default_lang = "en" - - -def mount(_lifecycle, _state): - lang = _lifecycle.language - if (lang in messages): - _state["current_lang"] = lang - yield 'Switch Language...', _state - time.sleep(2) - yield messages[lang]["hello"], _state - - -with gr.Blocks() as demo, ms.Application(): - lifecycle = mgr.Lifecycle() - state = gr.State({"current_lang": default_lang}) - markdown = gr.Markdown(value=messages[default_lang]["hello"]) - - lifecycle.mount(fn=mount, - inputs=[lifecycle, state], - outputs=[markdown, state]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Lifecycle/demos/theme_adaptation.py b/docs/components/legacy/Lifecycle/demos/theme_adaptation.py deleted file mode 100644 index e1b87b6b..00000000 --- a/docs/components/legacy/Lifecycle/demos/theme_adaptation.py +++ /dev/null @@ -1,28 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def mount(_lifecycle, _state): - _state["theme"] = _lifecycle.theme - yield _state - - -def fn(_state): - theme = _state["theme"] - color = '000/fff' if theme == 'dark' else 'fff/000' - yield gr.update( - value=f"https://dummyimage.com/200x100/{color}.png&text={theme}") - - -with gr.Blocks() as demo, ms.Application(): - lifecycle = mgr.Lifecycle() - state = gr.State({"theme": "light"}) - btn = gr.Button() - image = gr.Image() - - lifecycle.mount(fn=mount, inputs=[lifecycle, state], outputs=[state]) - btn.click(fn=fn, inputs=[state], outputs=[image]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/README-zh_CN.md b/docs/components/legacy/Markdown/README-zh_CN.md deleted file mode 100644 index 00b406ac..00000000 --- a/docs/components/legacy/Markdown/README-zh_CN.md +++ /dev/null @@ -1,97 +0,0 @@ -# Markdown - -升级版的 gradio Markdown。 - -- 支持输出多模态内容(音频、视频、图片、文本) -- 内置标签(chart、select-box、accordion) -- 支持自定义渲染组件,并与 Python 事件交互 - -## 如何使用 - -### 基本使用 - - - -### 多模态 & 支持本地文件的展示 - - - -### 支持手风琴内容展示 - -在返回的内容中加入 `accordion` 标签,更多用法详见 accordion - - - -### 支持用户选择交互 - -在返回的内容中加入 `select-box` 标签,更多用法详见 select-box - - - -### 支持图表展示 - -在返回的内容中加入 `chart` 标签,更多用法详见 chart - - - -### 自定义标签(高阶用法,需要了解前端知识) - - - -#### 引入 js - - - -template只能做简单的变量替换,如果想要引入更多自定义的行为,如条件判断、循环渲染等,请使用 js 控制 el 自行处理,下面是简单的示例: - - - -custom_select.js - -```js - -``` - - - - -#### 与 Python 交互 - -在 js 中可以使用`cc.dispatch`触发 Python 侧监听的`custom`事件,以前面的custom_select.js为例,我们在前端调用了`cc.dispatch(options[i])`,则会向 Python 侧同时发送通知。 - - - -## API 及参数列表 - -以下 API 均为在原有 gradio Markdown 外的额外拓展参数。 - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ----------------------------- | --------------------------------------------------------------- | ------ | --------------------------------------------------------------------------- | -| enable_base64 | bool | False | 是否支持渲染的内容为 base64,因为直接渲染 base64 有安全问题,默认为 False。 | -| enable_latex | bool | True | 是否支持 Latex 公式渲染 | -| latex_single_dollar_delimiter | bool | True | 是否支持单`$`符号在 Latex 公式中渲染 | -| preview | bool | True | 是否开启图片预览功能 | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户定义自定义标签,并通过 js 控制标签渲染样式与触发 python 事件。 | - -**CustomComponentDict 定义如下** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### 内置的自定义标签 - -- select-box -- accordion -- chart - -### event listeners - -| 事件 | 描述 | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -| `mgr.Markdown.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- tag_index:当前触发标签的 index。
- value:自定义传入的值。 | diff --git a/docs/components/legacy/Markdown/README.md b/docs/components/legacy/Markdown/README.md deleted file mode 100644 index 9a705158..00000000 --- a/docs/components/legacy/Markdown/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# Markdown - -Upgraded gradio Markdown. - -- Supports output of multimodal content (audio, video, image, text) -- Built-in tags (chart, select-box, accordion) -- Supports custom rendering components and interaction with Python events - -## How to Use - -### Basic Usage - - - -### Multimodal & Support for Local File Display - - - -### Support for Accordion Content Display - -Include the `accordion` tag in the returned content. For more usage details, see accordion - - -### Support for User Selection Interaction - -Include the `select-box` tag in the returned content. For more usage details, see select-box - - -### Support for Chart Display - -Include the `chart` tag in the returned content. For more usage details, see chart - - -### Custom Tags (Advanced Usage, Requires Frontend Knowledge) - - - -#### Import JS - - -The template can only perform simple variable replacements. If you want to introduce more custom behaviors, such as conditional judgments, loop rendering, etc., please use js to control the element for processing. Here is a simple example: - - -custom_select.js - -```js - -``` - - - - -#### Interaction with Python - -In js, you can use `cc.dispatch` to trigger the `custom` event listened to on the Python side. Taking the previous custom_select.js as an example, when we call `cc.dispatch(options[i])` on the frontend, a notification will be sent to the Python side simultaneously. - - -## API and Parameter List - -The following APIs are additional extended parameters beyond the original gradio Markdown. - -### props - -| Attribute | Type | Default Value | Description | -| ----------------------------- | ------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------- | -| enable_base64 | bool | False | Whether to support rendering content as base64, since rendering base64 is unsafe, the default is False. | -| preview | bool | True | Whether to enable image preview functionality. | -| enable_latex | bool | True | Whether to enable LaTeX rendering. | -| latex_single_dollar_delimiter | bool | True | Whe ther to enable single dollar delimiter `$` for LaTeX rendering. | -| custom_components | Dict[str, CustomComponentDict] CustomComponentDict definition below | None | Supports user-defined custom tags and controls tag rendering styles and triggers Python events through js. | -| | - -**CustomComponent definition is as follows:** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### Built-in Custom Tags - -- select-box -- accordion -- chart - -### Event Listeners - -| Event | Description | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mgr.Markdown.custom(fn, ···)` | Triggered when a custom tag event occurs. EventData is:
- tag: The current tag that triggered the event.
- tag_index: The index of the current triggered tag.
- value: The custom value passed in. | diff --git a/docs/components/legacy/Markdown/app.py b/docs/components/legacy/Markdown/app.py deleted file mode 100644 index 7b991a9d..00000000 --- a/docs/components/legacy/Markdown/app.py +++ /dev/null @@ -1,20 +0,0 @@ -import os - -from components.legacy.Docs import Docs - - -def resolve(relative_path: str): - return os.path.join(os.path.dirname(__file__), relative_path) - - -docs = Docs( - __file__, - markdown_files=(["README.md", "README-zh_CN.md"] + [ - f"custom_tags/{filename}" - for filename in os.listdir(resolve('custom_tags')) - if filename.endswith(".md") - ]), -) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/docs/components/legacy/Markdown/custom_tags/accordion-zh_CN.md b/docs/components/legacy/Markdown/custom_tags/accordion-zh_CN.md deleted file mode 100644 index 6a627125..00000000 --- a/docs/components/legacy/Markdown/custom_tags/accordion-zh_CN.md +++ /dev/null @@ -1,23 +0,0 @@ -# accordion - -在 markdown 文本中添加手风琴效果。 - -## 如何使用 - -### 基本使用 - - - -### 使用 accordion-title 标记 - -使用`::accordion-title[content]`的形式可以在标题输入 markdown 文本。 - - - -## API 及参数列表 - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ----- | ------ | ------ | ------------ | -| title | string | | 手风琴的标题 | diff --git a/docs/components/legacy/Markdown/custom_tags/accordion.md b/docs/components/legacy/Markdown/custom_tags/accordion.md deleted file mode 100644 index 66f1d1e9..00000000 --- a/docs/components/legacy/Markdown/custom_tags/accordion.md +++ /dev/null @@ -1,22 +0,0 @@ -# accordion - -Add an accordion effect to markdown text. - -## How to Use - -### Basic Usage - - - -### Using the accordion-title Marker - -Using the form `::accordion-title[content]`, you can input markdown text into the title. - - -## API and Parameter List - -### props - -| Attribute | Type | Default Value | Description | -| --------- | ------ | ------------- | -------------------------- | -| title | string | | The title of the accordion | diff --git a/docs/components/legacy/Markdown/custom_tags/chart-zh_CN.md b/docs/components/legacy/Markdown/custom_tags/chart-zh_CN.md deleted file mode 100644 index caca68a9..00000000 --- a/docs/components/legacy/Markdown/custom_tags/chart-zh_CN.md +++ /dev/null @@ -1,17 +0,0 @@ -# chart - -在 markdown 文本中添加图表。 - -## 如何使用 - -### 基本使用 - - - -## API 及参数列表 - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ------- | ------ | ------ | ----------------------------------------------------------------------------------------- | -| options | object | | `echarts`的 options 配置,详见:[echarts docs](https://echarts.apache.org/en/option.html) | diff --git a/docs/components/legacy/Markdown/custom_tags/chart.md b/docs/components/legacy/Markdown/custom_tags/chart.md deleted file mode 100644 index c5fa26a2..00000000 --- a/docs/components/legacy/Markdown/custom_tags/chart.md +++ /dev/null @@ -1,17 +0,0 @@ -# chart - -Add a chart to markdown text. - -## How to Use - -### Basic Usage - - - -## API and Parameter List - -### props - -| Attribute | Type | Default Value | Description | -| --------- | ------ | ------------- | --------------------------------------------------------------------------------- | -| options | object | | `echarts` options, see: [echarts docs](https://echarts.apache.org/en/option.html) | diff --git a/docs/components/legacy/Markdown/custom_tags/select-box-zh_CN.md b/docs/components/legacy/Markdown/custom_tags/select-box-zh_CN.md deleted file mode 100644 index c3092875..00000000 --- a/docs/components/legacy/Markdown/custom_tags/select-box-zh_CN.md +++ /dev/null @@ -1,45 +0,0 @@ -# select-box - -在 markdown 文本中添加选择交互框。 - -## 如何使用 - -### 基本使用 - - - -### Card 样式 - - - -### Card 自适应内部元素宽度 - - - -### 监听 Python 事件 - - - -## API 及参数列表 - -### value - -custom 事件中 custom_data value 对应值, 返回值为用户 options 传入的对应 value ,如果type="checkbox",则返回一个 list。 - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ------------ | ------------------------------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| type | 'checkbox' \| 'radio' | 'radio' | 选择框类型,'radio' 为单选框、'checkbox'为多选框。 | -| disabled | boolean | | 禁用选择,通常在需要读取历史信息二次渲染时会用到。 | -| value | string | | 默认选中值,通常适用于`type="checkbox"`时提前为用户选择部分选项和设置`disabled`后的默认值渲染。 | -| direction |  'horizontal' \| 'vertical' | 'horizontal' | 横向或竖向排列选择框 | -| shape | 'card' \| 'default' | 'default' | 选择框样式 | -| options | (string\| { label?: string, value?: string, imgSrc?: string})\[\] | | 为用户提供的选项值,每一项可以为 string 或 object。 当值为 object 时可以接收更多自定义值,其中imgSrc只有当shape="card"时才生效。 | -| select-once | boolean | false | 是否只允许用户选择一次 | -| submit-text | string | | 提交按钮的展示值,当该属性有值时,会展示提交按钮,此时用户只有点击提交按钮后才会触发选择事件。 | -| columns | number \| { xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?: number } | { xs: 1, sm:  2, md: 2, lg:  4} | 当shape="card"时才生效。每一行选项占用列数,值的范围为1 - 24,建议此项取值可以被 24 整除,否则可能列数会不符合预期。 当此项传入值为对象时,可以响应式控制每一行渲染列数,响应阈值如下:
- xs:屏幕 < 576px
- sm:屏幕 ≥ 576px
- md:屏幕 ≥ 768px
- lg:屏幕 ≥ 992px
- xl:屏幕 ≥ 1200px
- xxl:屏幕 ≥ 1600px 当direction为vertical时此配置不生效。 | -| item-width | string | | 当shape="card"时才生效。每个选项的宽度,如:'auto'、'100px',默认使用 columns 自动分配的宽度。 | -| item-height | string | | 当shape="card"时才生效。每个选项的高度,默认自适应元素高度。 | -| img-height | string | '160px' | 当shape="card"时才生效。每个选项中图片的高度。 | -| equal-height | boolean | false | 当shape="card"时才生效。是否每一行的选项高度都相等,会使用高度最高的选项。 | diff --git a/docs/components/legacy/Markdown/custom_tags/select-box.md b/docs/components/legacy/Markdown/custom_tags/select-box.md deleted file mode 100644 index fb2b210a..00000000 --- a/docs/components/legacy/Markdown/custom_tags/select-box.md +++ /dev/null @@ -1,45 +0,0 @@ -# select-box - -Add a selection interaction box to markdown text. - -## How to Use - -### Basic Usage - - - -### Card Style - - - -### Card Adapts to Width of Inner Elements - - - -### Listening to Python Events - - - -## API and Parameter List - -### value - -The corresponding value of custom_data value in the custom event; returns the user's inputted value for options. If type="checkbox", it returns a list. - -### props - -| Attribute | Type | Default Value | Description | -| ------------ | ------------------------------------------------------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| type | 'checkbox' \| 'radio' | 'radio' | The type of selection box: 'radio' for radio buttons, 'checkbox' for checkboxes. | -| disabled | boolean | | Disable the selection, usually used when reading historical information for re-rendering. | -| value | string | | The default selected value, usually used to pre-select some options for the user when `type="checkbox"` and to set the default value for rendering after setting `disabled`. | -| direction | 'horizontal' \| 'vertical' | 'horizontal' | Arrange selection boxes horizontally or vertically. | -| shape | 'card' \| 'default' | 'default' | The style of the selection box. | -| options | (string \| { label?: string, value?: string, imgSrc?: string })[] | | The options provided to the user, each item can be a string or an object. When the value is an object, it can accept more custom values, where imgSrc only takes effect when shape="card". | -| select-once | boolean | false | Whether to allow the user to make a selection only once. | -| submit-text | string | | The display value of the submit button. When this attribute has a value, the submit button will be displayed, and the selection event will only be triggered after the user clicks the submit button. | -| columns | number \| { xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?: number } | { xs: 1, sm: 2, md: 2, lg: 4 } | Effective only when shape="card". The number of columns each row of options occupies, the value range is 1 - 24, it is recommended that this value is divisible by 24, otherwise, the number of columns may not meet expectations. When this item is passed as an object, it can responsively control the number of rendered columns per row, responsive thresholds are as follows:
- xs: screen < 576px
- sm: screen ≥ 576px
- md: screen ≥ 768px
- lg: screen ≥ 992px
- xl: screen ≥ 1200px
- xxl: screen ≥ 1600px This configuration does not take effect when direction is vertical. | -| item-width | string | | Effective only when shape="card". The width of each option, such as: 'auto', '100px', the default uses the width automatically allocated by columns. | -| item-height | string | | Effective only when shape="card". The height of each option, defaults to adapt to the height of the element. | -| img-height | string | '160px' | Effective only when shape="card". The height of the images within each option. | -| equal-height | boolean | false | Effective only when shape="card". Whether the height of the options in each row should be equal, using the height of the tallest option. | diff --git a/docs/components/legacy/Markdown/demos/accordion.py b/docs/components/legacy/Markdown/demos/accordion.py deleted file mode 100644 index 6bc3615a..00000000 --- a/docs/components/legacy/Markdown/demos/accordion.py +++ /dev/null @@ -1,28 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown(""" - - -```json -{"text": "glorious weather", "resolution": "1024*1024"} -``` - - - -Use `::accordion-title` to support markdown: - - - -::accordion-title[Using `tool`] - -```json -{"text": "glorious weather", "resolution": "1024*1024"} -``` - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/basic.py b/docs/components/legacy/Markdown/demos/basic.py deleted file mode 100644 index 4f2332a7..00000000 --- a/docs/components/legacy/Markdown/demos/basic.py +++ /dev/null @@ -1,11 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown( - "This _example_ was **written** in [Markdown](https://en.wikipedia.org/wiki/Markdown)\n" - ) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/chart.py b/docs/components/legacy/Markdown/demos/chart.py deleted file mode 100644 index e4c492b0..00000000 --- a/docs/components/legacy/Markdown/demos/chart.py +++ /dev/null @@ -1,31 +0,0 @@ -import json - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -# echarts options, see: https://echarts.apache.org/en/index.html -option1 = { - "xAxis": { - "type": 'category', - "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], - }, - "yAxis": { - "type": 'value', - }, - "series": [ - { - "data": [150, 230, 224, 218, 135, 147, 260], - "type": 'line', - }, - ], -} - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown(f""" -Chart: - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom-tag.py b/docs/components/legacy/Markdown/demos/custom-tag.py deleted file mode 100644 index 8e053a56..00000000 --- a/docs/components/legacy/Markdown/demos/custom-tag.py +++ /dev/null @@ -1,21 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown( - """ -custom tag: -""", - custom_components={ - # Key is the tag name - "custom-tag": { - # The tag props. - "props": ["value"], - # The tag template, use `{prop}` as placeholder. - "template": "
{value}
" - } - }) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom-tag2.py b/docs/components/legacy/Markdown/demos/custom-tag2.py deleted file mode 100644 index ecb3acef..00000000 --- a/docs/components/legacy/Markdown/demos/custom-tag2.py +++ /dev/null @@ -1,55 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown( - """ -custom tag: -""", - custom_components={ - "custom-tag": { - "props": ["value"], - "template": - "", - # The `js` property should be a string containing a JavaScript Function. - "js": - """ -(props, cc, { el, onMount, onUpdate }) => { - // `onMount` will be called after the template first rendered - onMount(() => { - // `el` is the container element - console.log(el) - - // the return function will be called when the component is being unmounted - return () => { - console.log('unmount') - } - }) - - // `onUpdate` will be called when the props changed - onUpdate(() => { - console.log(props) - }) - onUpdate( - () => { - console.log(props, 'after mount') - }, - // By default, the callback will not be called when the component is being mounted. Set `callAfterMount` to true to enable it. - { callAfterMount: true } - ) - console.log(props.children) // By default, `props` will be passed a property named `children`, which can get the content in the tag, such as 'xx' in 'xx'. - - // The return value will be merged with `props` and passed to the template. - return { - value: 'Click Me: ' + props.value, - onClick: () => { - alert('hello') - } - } -}""" - } - }) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom-tag3.py b/docs/components/legacy/Markdown/demos/custom-tag3.py deleted file mode 100644 index 6d92315c..00000000 --- a/docs/components/legacy/Markdown/demos/custom-tag3.py +++ /dev/null @@ -1,31 +0,0 @@ -import json -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -options = ["a", "b", "c"] - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -with open(resolve_assets("./custom_components/custom_select.js"), 'r') as f: - custom_select_js = f.read() - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown(value=f""" -custom tag: -""", - custom_components={ - "custom-select": { - "props": ["options"], - "js": custom_select_js, - } - }) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom-tag4.py b/docs/components/legacy/Markdown/demos/custom-tag4.py deleted file mode 100644 index 405c52c0..00000000 --- a/docs/components/legacy/Markdown/demos/custom-tag4.py +++ /dev/null @@ -1,38 +0,0 @@ -import json -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -options = ["a", "b", "c"] - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -with open(resolve_assets("./custom_components/custom_select.js"), 'r') as f: - custom_select_js = f.read() - - -def fn(data: gr.EventData): - # custom {'index': [0, 1, 0], 'tag': 'custom-select', 'tag_index': 0, 'value': 'option A'} - print("custom value", data._data) - - -with gr.Blocks() as demo, ms.Application(): - md = mgr.Markdown(value=f""" -custom tag: -""", - custom_components={ - "custom-select": { - "props": ["options"], - "js": custom_select_js, - } - }) - md.custom(fn=fn) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom_tags/accordion/accordion-title.py b/docs/components/legacy/Markdown/demos/custom_tags/accordion/accordion-title.py deleted file mode 100644 index 9057415f..00000000 --- a/docs/components/legacy/Markdown/demos/custom_tags/accordion/accordion-title.py +++ /dev/null @@ -1,19 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown(""" - - -::accordion-title[Using `tool`] - -```json -{"text": "glorious weather", "resolution": "1024*1024"} -``` - - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom_tags/accordion/basic.py b/docs/components/legacy/Markdown/demos/custom_tags/accordion/basic.py deleted file mode 100644 index 4020df36..00000000 --- a/docs/components/legacy/Markdown/demos/custom_tags/accordion/basic.py +++ /dev/null @@ -1,17 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown(""" - - -```json -{"text": "glorious weather", "resolution": "1024*1024"} -``` - - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom_tags/chart/basic.py b/docs/components/legacy/Markdown/demos/custom_tags/chart/basic.py deleted file mode 100644 index ad3ac880..00000000 --- a/docs/components/legacy/Markdown/demos/custom_tags/chart/basic.py +++ /dev/null @@ -1,84 +0,0 @@ -import json - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -# echarts options, see: https://echarts.apache.org/en/index.html -option1 = { - "xAxis": { - "type": 'category', - "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], - }, - "yAxis": { - "type": 'value', - }, - "series": [ - { - "data": [150, 230, 224, 218, 135, 147, 260], - "type": 'line', - }, - ], -} - -option2 = { - "tooltip": { - "trigger": 'item' - }, - "legend": { - "top": '5%', - "left": 'center' - }, - "series": [{ - "name": - 'Access From', - "type": - 'pie', - "radius": ['40%', '70%'], - "avoidLabelOverlap": - False, - "itemStyle": { - "borderRadius": 10, - "borderColor": '#fff', - "borderWidth": 2 - }, - "label": { - "show": False, - "position": 'center' - }, - "emphasis": { - "label": { - "show": True, - "fontSize": 40, - "fontWeight": 'bold' - } - }, - "labelLine": { - "show": False - }, - "data": [{ - "value": 1048, - "name": 'Search Engine' - }, { - "value": 735, - "name": 'Direct' - }, { - "value": 580, - "name": 'Email' - }, { - "value": 484, - "name": 'Union Ads' - }, { - "value": 300, - "name": 'Video Ads' - }] - }] -} - -with gr.Blocks() as demo, ms.Application(): - chatbot = mgr.Markdown(f""" - - -""") -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom_tags/select-box/basic.py b/docs/components/legacy/Markdown/demos/custom_tags/select-box/basic.py deleted file mode 100644 index da185877..00000000 --- a/docs/components/legacy/Markdown/demos/custom_tags/select-box/basic.py +++ /dev/null @@ -1,21 +0,0 @@ -import json - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -options = [{"label": "A", "value": "a"}, "b", "c"] - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown( - f"""Single Select: - -Multiple Select: - -Vertical Direction: - - -""", ) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape.py b/docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape.py deleted file mode 100644 index 3ba4fccd..00000000 --- a/docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape.py +++ /dev/null @@ -1,33 +0,0 @@ -import json -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -# Card shape supports setting `imgSrc` as the cover. -options = [{ - "label": - "A", - "imgSrc": - os.path.join(os.path.dirname(__file__), - '../../../../resources/screen.jpeg'), - "value": - "a" -}, "b", "c", "d"] - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown( - f""" - -Custom Columns: - - - -Vertical Direction: - - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py b/docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py deleted file mode 100644 index 2ea9fb95..00000000 --- a/docs/components/legacy/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py +++ /dev/null @@ -1,27 +0,0 @@ -import json -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -# Card shape supports setting `imgSrc` as the cover. -options = [{ - "label": - "A", - "imgSrc": - os.path.join(os.path.dirname(__file__), - '../../../../resources/screen.jpeg'), - "value": - "a" -}, "b", "c", "d"] - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown( - # item-width="auto" - f""" - -""", ) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/custom_tags/select-box/python_events.py b/docs/components/legacy/Markdown/demos/custom_tags/select-box/python_events.py deleted file mode 100644 index 4cff53b6..00000000 --- a/docs/components/legacy/Markdown/demos/custom_tags/select-box/python_events.py +++ /dev/null @@ -1,24 +0,0 @@ -import json - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -options = [{"label": "A", "value": "a"}, "b", "c"] - - -def fn(data: gr.EventData): - custom_data = data._data - if (custom_data["tag"] == "select-box"): - print(custom_data["value"] - ) # 'a' or 'b' or 'c', the value set in the options. - - -with gr.Blocks() as demo, ms.Application(): - md = mgr.Markdown( - f"" - ) - md.custom(fn=fn) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/multimodal.py b/docs/components/legacy/Markdown/demos/multimodal.py deleted file mode 100644 index ec205ef7..00000000 --- a/docs/components/legacy/Markdown/demos/multimodal.py +++ /dev/null @@ -1,27 +0,0 @@ -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown(f""" -Image - -![image]({resolve_assets("bot.jpeg")}) - - - -Audio - - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/Markdown/demos/select-box.py b/docs/components/legacy/Markdown/demos/select-box.py deleted file mode 100644 index ae2cff10..00000000 --- a/docs/components/legacy/Markdown/demos/select-box.py +++ /dev/null @@ -1,32 +0,0 @@ -import json - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -# `label` will display on the page, and `value` is the actual selected value. -options = [{"label": "A", "value": "a"}, "b", "c"] - -with gr.Blocks() as demo, ms.Application(): - mgr.Markdown(f""" -Single Select: - -Multiple Select: - -Vertical Direction: - - - -Card Shape: - - - - - - - - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/MultimodalInput/README-zh_CN.md b/docs/components/legacy/MultimodalInput/README-zh_CN.md deleted file mode 100644 index d98029e5..00000000 --- a/docs/components/legacy/MultimodalInput/README-zh_CN.md +++ /dev/null @@ -1,50 +0,0 @@ -# MutilmodalInput  - -多模态输入框,支持上传文件、录音、照相等功能。 - -- 支持文本输入+文件上传共同提交 -- 支持文件上传时的图片、音频预览 -- 提交内容作为 Chatbot 输入多模态内容作为用户输入问题自动匹配 -- 支持用户录音和拍照 - -## 如何使用 - -### 基本使用 - - - -### 与 Chatbot 配合使用 - - - -### 配置上传/提交按钮 - - - -### 允许用户录音或拍照 - - - -## API 及参数列表 - -以下 API 均为在原有 gradio Textbox 外的额外拓展参数。 - -### value - -接口定义: - -```python -class MultimodalInputData(GradioModel): - files: List[Union[FileData, str]] = [] - text: str -``` - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ------------------- | -------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------- | -| sources | list\[Literal\['upload', 'microphone','webcam'\]\] | \['upload'\] | 上传文件的类型列表。 "upload"会提供上文文件按钮。 "microphone"支持用户录音输入。 "webcam"支持用户照相生成图片或视频 | -| webcam_props | dict | None | webcam 组件属性,目前支持传入mirror_webcam(bool)、include_audio(bool) | -| upload_button_props | dict | None | 上传文件按钮属性,同 gradio UploadButton | -| submit_button_props | dict | None | 提交按钮属性,同 gradio Button | -| file_preview_props | dict | None | 文件预览组件属性,目前支持传入 height (int) | diff --git a/docs/components/legacy/MultimodalInput/README.md b/docs/components/legacy/MultimodalInput/README.md deleted file mode 100644 index e82c502f..00000000 --- a/docs/components/legacy/MultimodalInput/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# MutilmodalInput - -A multimodal input field that supports uploading files, recording audio, taking photos, etc. - -- Supports text input and file upload for joint submission -- Supports image and audio previews during file upload -- Submissions serve as Chatbot input, matching multimodal content as user input questions automatically -- Supports user recording and photography - -## How to Use - -### Basic Usage - - - -### Using with Chatbot - - - -### Configuring Upload/Submit Buttons - - - -### Allowing User Recording or Photography - - - -## API and Parameter List - -The following APIs are additional expanded parameters beyond the original gradio Textbox. - -### value - -Interface definition: - -```python -class MultimodalInputData(GradioModel): - files: List[Union[FileData, str]] = [] - text: str -``` - -### props - -| Attribute | Type | Default Value | Description | -| ------------------- | ----------------------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| sources | List[Literal['upload', 'microphone', 'webcam']] | ['upload'] | A list of types for uploading files. "upload" provides an upload file button. "microphone" supports user audio input. "webcam" supports user photography to generate images or videos. | -| webcam_props | dict | None | webcam component properties, currently supports passing mirror_webcam(bool), include_audio(bool) | -| upload_button_props | dict | None | Upload file button properties, same as gradio UploadButton | -| submit_button_props | dict | None | Submit button properties, same as gradio Button | -| file_preview_props | dict | None | File preview component properties, currently supports passing height (int) | diff --git a/docs/components/legacy/MultimodalInput/app.py b/docs/components/legacy/MultimodalInput/app.py deleted file mode 100644 index ea841f78..00000000 --- a/docs/components/legacy/MultimodalInput/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.legacy.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/docs/components/legacy/MultimodalInput/demos/basic.py b/docs/components/legacy/MultimodalInput/demos/basic.py deleted file mode 100644 index ee3ade2b..00000000 --- a/docs/components/legacy/MultimodalInput/demos/basic.py +++ /dev/null @@ -1,16 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def fn(value): - # value includes `text`` and `files`` - print(value.text, value.files) - - -with gr.Blocks() as demo, ms.Application(): - input = mgr.MultimodalInput() - input.change(fn=fn, inputs=[input]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/MultimodalInput/demos/config_buttons.py b/docs/components/legacy/MultimodalInput/demos/config_buttons.py deleted file mode 100644 index 84a5a4bd..00000000 --- a/docs/components/legacy/MultimodalInput/demos/config_buttons.py +++ /dev/null @@ -1,16 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def fn(value): - print(value.text, value.files) - - -with gr.Blocks() as demo, ms.Application(): - input = mgr.MultimodalInput(upload_button_props=dict(variant="primary"), - submit_button_props=dict(visible=False)) - input.change(fn=fn, inputs=[input]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/MultimodalInput/demos/upload_sources.py b/docs/components/legacy/MultimodalInput/demos/upload_sources.py deleted file mode 100644 index 7358329e..00000000 --- a/docs/components/legacy/MultimodalInput/demos/upload_sources.py +++ /dev/null @@ -1,15 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def fn(value): - print(value.text, value.files) - - -with gr.Blocks() as demo, ms.Application(): - input = mgr.MultimodalInput(sources=["upload", "microphone", "webcam"]) - input.change(fn=fn, inputs=[input]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/MultimodalInput/demos/with_chatbot.py b/docs/components/legacy/MultimodalInput/demos/with_chatbot.py deleted file mode 100644 index 64cf913c..00000000 --- a/docs/components/legacy/MultimodalInput/demos/with_chatbot.py +++ /dev/null @@ -1,36 +0,0 @@ -import time - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def fn(input, chatbot): - chatbot.append([{ - "text": input.text, - "files": input.files, - }, None]) - yield { - user_input: mgr.MultimodalInput(interactive=False), - user_chatbot: chatbot - } - time.sleep(2) - chatbot[-1][1] = {"text": "Hello!"} - yield {user_chatbot: chatbot} - - -# Triggered when the typewriter is ending. -def flushed(): - return mgr.MultimodalInput(interactive=True) - - -with gr.Blocks() as demo, ms.Application(): - user_chatbot = mgr.Chatbot() - user_input = mgr.MultimodalInput() - user_input.submit(fn=fn, - inputs=[user_input, user_chatbot], - outputs=[user_input, user_chatbot]) - user_chatbot.flushed(fn=flushed, outputs=[user_input]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/README-zh_CN.md b/docs/components/legacy/README-zh_CN.md deleted file mode 100644 index 578a1739..00000000 --- a/docs/components/legacy/README-zh_CN.md +++ /dev/null @@ -1,33 +0,0 @@ -

ModelScope Studio

- -

- - - ✖️ - - -

- -

-GitHub | 🤖 ModelScope Studio | 🤗 Hugging Face Space - -`modelscope_studio` 是一套基于 gradio 4.x 的扩展组件库,致力于服务于 ModelScope 创空间中对于 gradio 应用的各类扩展需求,目前主要聚集在对话场景增强、多模态场景以及一些其他垂直场景支持。 - -## Install - -```sh -pip install modelscope_studio -``` - -## API - -- load - -## Components - -- Chatbot -- MultimodalInput -- Markdown -- WaterfallGallery -- Lifecycle -- Flow diff --git a/docs/components/legacy/README.md b/docs/components/legacy/README.md deleted file mode 100644 index 821b96fa..00000000 --- a/docs/components/legacy/README.md +++ /dev/null @@ -1,33 +0,0 @@ -

ModelScope Studio

- -

- - - ✖️ - - -

- -

-GitHub | 🤖 ModelScope Studio | 🤗 Hugging Face Space - -`modelscope_studio` is a set of extension component libraries based on gradio 4.x, dedicated to serving the various extension needs of gradio applications within the ModelScope Studio. It mainly focuses on enhancing conversational scenarios, supporting multimodal contexts, and providing assistance for various other specialized scenarios. - -## Install - -```sh -pip install modelscope_studio -``` - -## API - -- load - -## Components - -- Chatbot -- MultimodalInput -- Markdown -- Lifecycle -- WaterfallGallery -- Flow diff --git a/docs/components/legacy/WaterfallGallery/README-zh_CN.md b/docs/components/legacy/WaterfallGallery/README-zh_CN.md deleted file mode 100644 index 94552d6c..00000000 --- a/docs/components/legacy/WaterfallGallery/README-zh_CN.md +++ /dev/null @@ -1,71 +0,0 @@ -# WaterfallGallery - -瀑布流形式的 gradio Gallery。 - -- 支持瀑布流展示图片 -- 增加点赞按钮,支持图片额外绑定`like`事件 -- 增加 action 按钮,支持图片额外绑定`click`事件 -- 响应式 columns - -## 如何使用 - -### 基本使用 - - - -### 响应式 columns - - - -### 加载更多 - - - -### 点赞/点击反馈 - - - -## API 及参数列表 - -以下 API 均为在原有 gradio Gallery 外的额外拓展参数。 - -### value - -接口定义: - -```python -GalleryImageType = Union[np.ndarray, _Image.Image, FileData, Path, str] -CaptionedGalleryImageType = Tuple[GalleryImageType, str] - - -class GalleryImage(GradioModel): - image: Union[FileData, Path, str] - caption: Optional[str] = None - liked: Optional[bool] = None - # custom meta data - meta: Optional[Any] = None - - -class GalleryData(GradioRootModel): - root: List[GalleryImage] -``` - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ---------------------- | -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| has_more | bool | None | 如果为 True,会显示 "加载更多" 按钮 | -| load_more_button_props | dict | None | ”加载更多“按钮属性,同 gradio Button | -| columns | int \| tuple \| dict | 2 | 展示在以下尺寸屏幕(<576px(xs)、<768px(sm)、<992px(md)、<1200px(lg)、<1600px(xl)、>1600px(xll))中在一行显示的图像数量。
- 如果传入 int, 则应用于所有尺寸屏幕;
- 如果传入 tuple, 当给出的断点少于 6 个, 则最后一个断点将用于所有后续断点;
- 如果传入 dict, 则可以以 [xs,sm,md,lg,xl,xll] 为键表示每个尺寸屏幕的图像数量。 | -| gap | tuple \| int | 8 | 图片之间的间隙 (px)。 如果传递一个元组,则第一个值是宽度的间隙,第二个值是高度的间隙。如果传递数字,则宽度和高度的间隙相同 | -| action_label | str | 'Click' | action 按钮的文案。当 `clickable`为 True 时才展示 | -| likeable | bool | None | 是否显示喜欢或不喜欢按钮。 可以通过显示绑定 `.like` 方法自动设置。 | -| clickable | bool | None | 是否显示 action 按钮。 可以通过显示绑定 `.click` 方法自动设置。 | - -### event listeners - -| 事件 | 描述 | -| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.WaterfallGallery.load_more(fn, ···)` | “加载更多”按钮被点击时触发。 | -| `mgr.WaterfallGallery.like(fn, ···)` | 当点赞/点踩按钮被点击时触发,EventData 为:
- index:当前图片索引。
- value:当前图片信息。
- liked:当前图片的喜欢/不喜欢状态,可以为 None,代表用户取消操作。 | -| `mgr.WaterfallGallery.click(fn, ···)` | action 按钮被点击时触发,EventData 为:
- index:当前图片索引。
- value:当前图片信息。 | diff --git a/docs/components/legacy/WaterfallGallery/README.md b/docs/components/legacy/WaterfallGallery/README.md deleted file mode 100644 index 392fe320..00000000 --- a/docs/components/legacy/WaterfallGallery/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# WaterfallGallery - -gradio Gallery with waterfall flow. - -- Support waterfall flow display images -- Added a like button, support additional binding of `like` events to images -- Added an action button, support additional binding of `click` event to images -- Responsive columns - -## How to Use - -### Basic Usage - - - -### Responsive columns - - - -### Load More - - - -### Like/Click Feedback - - - -## API and Parameter List - -The following APIs are additional extended parameters beyond the original gradio Gallery. - -### value - -Interface definition: - -```python -GalleryImageType = Union[np.ndarray, _Image.Image, FileData, Path, str] -CaptionedGalleryImageType = Tuple[GalleryImageType, str] - - -class GalleryImage(GradioModel): - image: Union[FileData, Path, str] - caption: Optional[str] = None - liked: Optional[bool] = None - # custom meta data - meta: Optional[Any] = None - - -class GalleryData(GradioRootModel): - root: List[GalleryImage] -``` - -### props - -| Attribute | Type | Default Value | Description | -| ---------------------- | -------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| has_more | bool | None | If True, will show the "Load More" button. | -| lode_more_button_props | dict | None | “Load More” button properties, same as gradio Button | -| columns | int \| tuple \| dict | 2 | Displays the number of images displayed in a row on the following screen sizes (<576px(xs), <768px(sm), <992px(md), <1200px(lg), <1600px(xl), >1600px(xll)).
- If int is passed in, it will apply to all screen sizes;
- If tuple is passed in, when less than 6 breakpoints are given, the last breakpoint will be used for all subsequent breakpoints ;
- If a dict is passed in, you can represents the number of images for each size screen with [xs,sm,md,lg,xl,xll] as the key. | -| gap | tuple \| int | 8 | The gap (px) between images. If a tuple is passed, the first value is the gap for width and the second value is the gap for height.If a number is passed, the gap will be the same for width and height. | -| action_label | str | 'Click' | The label for the action button. Only displayed if `clickable` is set to True. | -| likeable | bool | None | Whether the gallery image display a like or dislike button. Set automatically by the .like method but has to be present in the signature for it to show up in the config. | -| clickable | bool | None | Whether the gallery image display an action button. Set automatically by the .click method but has to be present in the signature for it to show up in the config. | - -### Event Listeners - -| Event | Description | -| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.WaterfallGallery.load_more(fn, ···)` | Triggered when the "Load More" button is clicked. | -| `mgr.WaterfallGallery.like(fn, ···)` | Triggered when the Like/Dislike button is clicked. EventData is:
- index: current image index.
- value: current image info.
- liked: like/dislike status of the current image, which can be None, indicating that the user cancels the operation. | -| `mgr.WaterfallGallery.click(fn, ···)` | Triggered when the action button is clicked, EventData is:
- index: current image index.
- value: current image info. | diff --git a/docs/components/legacy/WaterfallGallery/app.py b/docs/components/legacy/WaterfallGallery/app.py deleted file mode 100644 index ea841f78..00000000 --- a/docs/components/legacy/WaterfallGallery/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.legacy.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/docs/components/legacy/WaterfallGallery/demos/basic.py b/docs/components/legacy/WaterfallGallery/demos/basic.py deleted file mode 100644 index 1071ef06..00000000 --- a/docs/components/legacy/WaterfallGallery/demos/basic.py +++ /dev/null @@ -1,30 +0,0 @@ -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -with gr.Blocks() as demo, ms.Application(): - mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - columns=2, - height=600) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/WaterfallGallery/demos/like_click_feedback.py b/docs/components/legacy/WaterfallGallery/demos/like_click_feedback.py deleted file mode 100644 index 64299d85..00000000 --- a/docs/components/legacy/WaterfallGallery/demos/like_click_feedback.py +++ /dev/null @@ -1,37 +0,0 @@ -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -def fn(data: gr.EventData): - print(data._data) - - -with gr.Blocks() as demo, ms.Application(): - gallery = mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - action_label="Click Me!", - columns=2, - height=600) - gallery.like(fn=fn) - gallery.click(fn=fn) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/WaterfallGallery/demos/load_more.py b/docs/components/legacy/WaterfallGallery/demos/load_more.py deleted file mode 100644 index 28fe008e..00000000 --- a/docs/components/legacy/WaterfallGallery/demos/load_more.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -import time - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -def load_more(_gallery): - time.sleep(1) - _gallery.append(resolve_assets('modelscope.svg')) - _gallery.append(resolve_assets('bot.jpeg')) - _gallery.append(resolve_assets('user.jpeg')) - _gallery.append(resolve_assets('screen.jpeg')) - has_more = True - if (len(_gallery) > 10): - has_more = False - return gr.update(value=_gallery, has_more=has_more) - - -with gr.Blocks() as demo, ms.Application(): - gallery = mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - has_more=True, - columns=2, - height=600) - gallery.load_more(fn=load_more, inputs=[gallery], outputs=[gallery]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/WaterfallGallery/demos/responsive_columns.py b/docs/components/legacy/WaterfallGallery/demos/responsive_columns.py deleted file mode 100644 index dcea88d8..00000000 --- a/docs/components/legacy/WaterfallGallery/demos/responsive_columns.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -def fn(): - return gr.update(columns={"xs": 2, "lg": 3}) - - -with gr.Blocks() as demo, ms.Application(): - gallery = mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - columns=[2, 3, 4], - height=600) - gr.Button("Update Columns").click(fn=fn, outputs=[gallery]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/legacy/app.py b/docs/components/legacy/app.py deleted file mode 100644 index 3606901a..00000000 --- a/docs/components/legacy/app.py +++ /dev/null @@ -1,34 +0,0 @@ -import gradio as gr -import modelscope_studio.components.base as ms -from api.app import docs as api_docs -from components.legacy.Chatbot.app import docs as chatbot_docs -from components.legacy.Docs import Docs -from components.legacy.Flow.app import docs as flow_docs -from components.legacy.Lifecycle.app import docs as lifecycle_docs -from components.legacy.Markdown.app import docs as markdown_docs -from components.legacy.MultimodalInput.app import docs as multimodel_input_docs -from components.legacy.WaterfallGallery.app import \ - docs as waterfall_gallery_docs - -readme_docs = Docs(__file__) - -docs = [ - ["Quick Start", readme_docs], - ["API", api_docs], - ["Chatbot", chatbot_docs], - ["MultimodalInput", multimodel_input_docs], - ["Markdown", markdown_docs], - ["Lifecycle", lifecycle_docs], - ["WaterfallGallery", waterfall_gallery_docs], - ["Flow", flow_docs], -] - -with gr.Blocks() as legacy_demo: - with ms.Application(): - with gr.Tabs() as components_tabs: - for doc in docs: - with gr.TabItem(doc[0], id=doc[0]): - doc[1].render(components_tabs) - -if __name__ == "__main__": - legacy_demo.launch() diff --git a/docs/components/legacy/parse_markdown.py b/docs/components/legacy/parse_markdown.py deleted file mode 100644 index 56074f51..00000000 --- a/docs/components/legacy/parse_markdown.py +++ /dev/null @@ -1,85 +0,0 @@ -from html.parser import HTMLParser - - -def default_read_file(path): - with open(path, "r") as f: - return f.read() - - -enable_tags = ["demo", "demo-prefix", "demo-suffix", "file"] - - -class MarkdownParser(HTMLParser): - - def __init__(self, read_file=None): - super().__init__() - self.value = [{"type": "text", "value": ""}] - self.tag_stack = [] - self.read_file = read_file or default_read_file - self.current_tag = None - - def get_value(self): - return self.value - - def handle_data(self, data: str) -> None: - if self.value[-1]["type"] == "text": - self.value[-1]["value"] += data - elif self.current_tag is None: - self.value.append({"type": "text", "value": data}) - elif self.current_tag == "demo-prefix": - self.value[-1]["prefix"] += data - elif self.current_tag == "demo-suffix": - self.value[-1]["suffix"] += data - - def handle_startendtag(self, tag: str, attrs) -> None: - if tag not in enable_tags: - self.handle_data(self.get_starttag_text()) - return - - def handle_starttag(self, tag: str, attrs) -> None: - if (tag not in enable_tags): - self.handle_data(self.get_starttag_text()) - return - if tag == "demo": - self.value.append({ - "type": - "demo", - "code_position": - dict(attrs).get("code-position", 'left'), - "name": - dict(attrs)["name"], - "prefix": - "", - "suffix": - "" - }) - elif tag == "file": - content = self.read_file(dict(attrs)["src"]) - if self.value[-1]["type"] == "text": - self.value[-1]["value"] += content - elif self.current_tag == "demo-prefix": - self.value[-1]["prefix"] += content - elif self.current_tag == "demo-suffix": - self.value[-1]["suffix"] += content - self.current_tag = tag - self.tag_stack.append(self.current_tag) - - def handle_endtag(self, tag: str) -> None: - - if (tag not in enable_tags): - self.handle_data(f"") - return - if (len(self.tag_stack) > 0): - self.tag_stack.pop() - if (len(self.tag_stack) > 0): - self.current_tag = self.tag_stack[-1] - else: - self.current_tag = None - else: - self.current_tag = None - - -def parse_markdown(markdown: str, read_file=None): - parser = MarkdownParser(read_file=read_file) - parser.feed(markdown) - return parser.get_value() diff --git a/docs/components/legacy/resources/audio.wav b/docs/components/legacy/resources/audio.wav deleted file mode 100644 index 105190ad88e2e177540361de340e54feb1587f3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44844 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 TIhAR}L)jl{2^JwQuu}aO*glBb diff --git a/docs/components/legacy/resources/bot.jpeg b/docs/components/legacy/resources/bot.jpeg deleted file mode 100644 index 5fde8cc45f61b677c0581e6889b11e269c35be08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5231 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 XG_Cu5e|92&T;ZQB%KzEGa5nZ|lZv(q diff --git a/docs/components/legacy/resources/custom_components/custom_select.js b/docs/components/legacy/resources/custom_components/custom_select.js deleted file mode 100644 index f4a1cb40..00000000 --- a/docs/components/legacy/resources/custom_components/custom_select.js +++ /dev/null @@ -1,29 +0,0 @@ -(props, cc, { el, onUpdate }) => { - const options = JSON.parse(props.options); - el.innerHTML = ` - ${options - .map((option) => { - return `

- -
`; - }) - .join('')} - `; - onUpdate( - () => { - const inputs = Array.from(el.getElementsByTagName('input')); - Array.from(el.getElementsByTagName('label')).forEach((label, i) => { - label.addEventListener('click', () => { - inputs.forEach((input) => { - input.checked = false; - }); - const input = label.getElementsByTagName('input')[0]; - input.checked = true; - // Use cc.dispatch to trigger events. - cc.dispatch(options[i]); - }); - }); - }, - { callAfterMount: true } - ); -}; diff --git a/docs/components/legacy/resources/image-bot.jpeg b/docs/components/legacy/resources/image-bot.jpeg deleted file mode 100644 index 5df101fedca7e0b76eaa1119506ca4c1941c9fc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 286675 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'NFR6-(FJ`y7rn`aDWur|3={dpj}`mLX{j`k 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
lJ+QCB-j^2dmL_5G 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Ⓢ<=o}PVNULEkXL|p?}f5`X3%`fbR$BE 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 WEzHe09+{6mqPV9DtD$j@r~lbK5=)i< diff --git a/docs/components/legacy/resources/modelscope.svg b/docs/components/legacy/resources/modelscope.svg deleted file mode 100644 index 093ba6fe..00000000 --- a/docs/components/legacy/resources/modelscope.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/components/legacy/resources/music-bot.jpeg b/docs/components/legacy/resources/music-bot.jpeg deleted file mode 100644 index 00288fb576845921bbc3247ca8da3fbbdea12800..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219326 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 z 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 diff --git a/docs/components/legacy/resources/screen.jpeg b/docs/components/legacy/resources/screen.jpeg deleted file mode 100644 index 574735acb117e86c5c0850e2b5489b8f8efa20cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7128 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 Y6di0vQ#-%w2S-1N|I>=z>AGM1e_wAE>Hq)$ diff --git a/docs/components/legacy/resources/user.jpeg b/docs/components/legacy/resources/user.jpeg deleted file mode 100644 index 536948b6bd19cb0b49c44b74e2790198301520e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16410 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 diff --git a/docs/components/legacy/tab-link.js b/docs/components/legacy/tab-link.js deleted file mode 100644 index bcd9143d..00000000 --- a/docs/components/legacy/tab-link.js +++ /dev/null @@ -1,15 +0,0 @@ -(props, cc, { onMount, el }) => { - onMount(() => { - el.addEventListener('click', () => { - cc.dispatch({ - tab: props.tab, - component_tab: props['component-tab'], - }); - }); - }); - const children = props.children[0].value; - el.innerHTML = `${children}`; - el.style.display = 'inline-block'; - el.style.cursor = 'pointer'; - el.style.color = 'var(--link-text-color)'; -}; diff --git a/docs/legacy_app.py b/docs/legacy_app.py deleted file mode 100644 index d7b855df..00000000 --- a/docs/legacy_app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.legacy.app import legacy_demo - -demo = legacy_demo - -if __name__ == "__main__": - demo.launch() diff --git a/docs/src/pyproject.toml b/docs/src/pyproject.toml index 9b7984c0..f21508f9 100644 --- a/docs/src/pyproject.toml +++ b/docs/src/pyproject.toml @@ -45,12 +45,6 @@ dev = ["build", "twine"] [tool.hatch.build] artifacts = [ "*.pyi", - "backend/modelscope_studio/components/legacy/Chatbot/templates", - "backend/modelscope_studio/components/legacy/Flow/templates", - "backend/modelscope_studio/components/legacy/MultimodalInput/templates", - "backend/modelscope_studio/components/legacy/Markdown/templates", - "backend/modelscope_studio/components/legacy/WaterfallGallery/templates", - "/backend/modelscope_studio/components/legacy/Lifecycle/templates", "/backend/modelscope_studio/components/antd/button/templates", "/backend/modelscope_studio/components/antd/card/templates", "/backend/modelscope_studio/components/antd/card/grid/templates", @@ -198,11 +192,6 @@ artifacts = [ "/backend/modelscope_studio/components/antd/upload/dragger/templates", "/backend/modelscope_studio/components/antd/splitter/templates", "/backend/modelscope_studio/components/antd/splitter/panel/templates", - "/backend/modelscope_studio/components/legacy/Chatbot/templates", - "/backend/modelscope_studio/components/legacy/Flow/templates", - "/backend/modelscope_studio/components/legacy/Markdown/templates", - "/backend/modelscope_studio/components/legacy/MultimodalInput/templates", - "/backend/modelscope_studio/components/legacy/WaterfallGallery/templates", "/backend/modelscope_studio/components/antd/form/provider/templates", "/backend/modelscope_studio/components/antd/modal/static/templates", "/backend/modelscope_studio/components/antdx/bubble/templates", diff --git a/frontend/antd/auto-complete/auto-complete.tsx b/frontend/antd/auto-complete/auto-complete.tsx index 877c3e8e..5dd5d915 100644 --- a/frontend/antd/auto-complete/auto-complete.tsx +++ b/frontend/antd/auto-complete/auto-complete.tsx @@ -1,7 +1,6 @@ import { sveltify } from '@svelte-preprocess-react'; -import { AutoCompleteContext } from '@svelte-preprocess-react/context'; +import { AutoCompleteContext } from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { forwardRef, useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; @@ -33,7 +32,6 @@ const AutoCompleteChildrenWrapper = forwardRef< export const AutoComplete = sveltify< GetProps & { onValueChange: (value: string) => void; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -56,7 +54,6 @@ export const AutoComplete = sveltify< dropdownRender, popupRender, elRef, - setSlotParams, ...props }) => { const getPopupContainerFunction = useFunction(getPopupContainer); @@ -119,7 +116,6 @@ export const AutoComplete = sveltify< ? renderParamsSlot( { slots, - setSlotParams, key: 'popupRender', }, { clone: true } @@ -131,7 +127,6 @@ export const AutoComplete = sveltify< ? renderParamsSlot( { slots, - setSlotParams, key: 'dropdownRender', }, { clone: true } diff --git a/frontend/antd/button/Index.svelte b/frontend/antd/button/Index.svelte index 0ebbd2de..8706d0b7 100644 --- a/frontend/antd/button/Index.svelte +++ b/frontend/antd/button/Index.svelte @@ -1,83 +1,74 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedButton then Button} {/await} {/if} - - diff --git a/frontend/antd/config-provider/Index.svelte b/frontend/antd/config-provider/Index.svelte index 078bc8f4..ce77d3ea 100644 --- a/frontend/antd/config-provider/Index.svelte +++ b/frontend/antd/config-provider/Index.svelte @@ -1,74 +1,65 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedConfigProvider then ConfigProvider} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/config-provider/config-provider.tsx b/frontend/antd/config-provider/config-provider.tsx index 8c66d414..71baf639 100644 --- a/frontend/antd/config-provider/config-provider.tsx +++ b/frontend/antd/config-provider/config-provider.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useEffect, useState } from 'react'; import { StyleProvider } from '@ant-design/cssinjs'; import { useFunction } from '@utils/hooks/useFunction'; @@ -66,7 +65,6 @@ export const ConfigProvider = sveltify< style?: React.CSSProperties; id?: string; component?: React.ComponentType; - setSlotParams: SetSlotParams; }, ['renderEmpty'] >( @@ -80,7 +78,6 @@ export const ConfigProvider = sveltify< getTargetContainer, getPopupContainer, renderEmpty, - setSlotParams, children, component, ...props @@ -120,7 +117,6 @@ export const ConfigProvider = sveltify< slots.renderEmpty ? renderParamsSlot({ slots, - setSlotParams, key: 'renderEmpty', }) : renderEmptyFunction @@ -128,7 +124,6 @@ export const ConfigProvider = sveltify< // switch bug // key={`${algorithm.dark}`} theme={{ - cssVar: true, ...props.theme, algorithm: Object.keys(algorithm) .map((algo) => { diff --git a/frontend/antd/form/item/form.item.tsx b/frontend/antd/form/item/form.item.tsx index 6cb78d6d..7eb691c6 100644 --- a/frontend/antd/form/item/form.item.tsx +++ b/frontend/antd/form/item/form.item.tsx @@ -1,5 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; -import { FormItemContext } from '@svelte-preprocess-react/context'; +import { FormItemContext } from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; diff --git a/frontend/antd/icon/Index.svelte b/frontend/antd/icon/Index.svelte index 5756ac3a..3876aad7 100644 --- a/frontend/antd/icon/Index.svelte +++ b/frontend/antd/icon/Index.svelte @@ -1,75 +1,63 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedIcon then Icon} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/icon/icon.tsx b/frontend/antd/icon/icon.tsx index e02375c3..66c1ebef 100644 --- a/frontend/antd/icon/icon.tsx +++ b/frontend/antd/icon/icon.tsx @@ -1,5 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; -import { useIconFontContext } from '@svelte-preprocess-react/context'; +import { useIconFontContext } from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React, { useMemo } from 'react'; import * as icons from '@ant-design/icons'; diff --git a/frontend/antd/icon/iconfont-provider/Index.svelte b/frontend/antd/icon/iconfont-provider/Index.svelte index 4befebdd..4e955b9f 100644 --- a/frontend/antd/icon/iconfont-provider/Index.svelte +++ b/frontend/antd/icon/iconfont-provider/Index.svelte @@ -1,46 +1,52 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitIconFontProvider then IconFontProvider} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/icon/iconfont-provider/iconfont-provider.tsx b/frontend/antd/icon/iconfont-provider/iconfont-provider.tsx index a500e3c2..455f7276 100644 --- a/frontend/antd/icon/iconfont-provider/iconfont-provider.tsx +++ b/frontend/antd/icon/iconfont-provider/iconfont-provider.tsx @@ -1,5 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; -import { IconFontContext } from '@svelte-preprocess-react/context'; +import { IconFontContext } from '@svelte-preprocess-react/react-contexts'; import React, { useMemo, useRef } from 'react'; import { createFromIconfontCN } from '@ant-design/icons'; import type { CustomIconOptions } from '@ant-design/icons/es/components/IconFont'; diff --git a/frontend/antd/radio/group/radio.group.tsx b/frontend/antd/radio/group/radio.group.tsx index 427afdee..ea8cfa60 100644 --- a/frontend/antd/radio/group/radio.group.tsx +++ b/frontend/antd/radio/group/radio.group.tsx @@ -1,5 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; -import { FormItemContext } from '@svelte-preprocess-react/context'; +import { FormItemContext } from '@svelte-preprocess-react/react-contexts'; import { useMemo } from 'react'; import { renderItems } from '@utils/renderItems'; import { type GetProps, Radio as ARadio } from 'antd'; diff --git a/frontend/antdx/sender/sender.tsx b/frontend/antdx/sender/sender.tsx index 1aee84d8..231eafaa 100644 --- a/frontend/antdx/sender/sender.tsx +++ b/frontend/antdx/sender/sender.tsx @@ -1,5 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; -import { useSuggestionOpenContext } from '@svelte-preprocess-react/context'; +import { useSuggestionOpenContext } from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; diff --git a/frontend/antdx/suggestion/suggestion.tsx b/frontend/antdx/suggestion/suggestion.tsx index d798fa84..063a379e 100644 --- a/frontend/antdx/suggestion/suggestion.tsx +++ b/frontend/antdx/suggestion/suggestion.tsx @@ -2,7 +2,7 @@ import { sveltify } from '@svelte-preprocess-react'; import { SuggestionContext, SuggestionOpenContext, -} from '@svelte-preprocess-react/context'; +} from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React, { forwardRef, useEffect, useMemo, useState } from 'react'; import { Suggestion as XSuggestion, type SuggestionProps } from '@ant-design/x'; diff --git a/frontend/antdx/x-provider/XProvider.svelte b/frontend/antdx/x-provider/XProvider.svelte index 8d73e144..bec9ac81 100644 --- a/frontend/antdx/x-provider/XProvider.svelte +++ b/frontend/antdx/x-provider/XProvider.svelte @@ -2,7 +2,7 @@ {#await awaitedApplication then Application} - - + + {@render children()} {/await} diff --git a/frontend/base/application/package.json b/frontend/base/application/package.json index 55354de3..24e241df 100644 --- a/frontend/base/application/package.json +++ b/frontend/base/application/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/auto-loading/Index.svelte b/frontend/base/auto-loading/Index.svelte index 83a4e14f..cfb626a7 100644 --- a/frontend/base/auto-loading/Index.svelte +++ b/frontend/base/auto-loading/Index.svelte @@ -1,93 +1,80 @@ - - -{#if visible} +{#if proceedProps.visible} {#await AwaitedAutoLoading then AutoLoading} - + {@render children()} {/await} {/if} - - diff --git a/frontend/base/auto-loading/auto-loading.tsx b/frontend/base/auto-loading/auto-loading.tsx index 555b01fa..c0bf8f1f 100644 --- a/frontend/base/auto-loading/auto-loading.tsx +++ b/frontend/base/auto-loading/auto-loading.tsx @@ -1,8 +1,7 @@ import { sveltify } from '@svelte-preprocess-react'; -import { type ConfigType } from '@svelte-preprocess-react/provider'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; +import { type ConfigType } from '@svelte-preprocess-react/svelte-contexts/config.svelte'; import React from 'react'; -import type { LoadingStatus } from '@gradio/statustracker'; +import type { ILoadingStatus } from '@gradio/statustracker'; import { renderParamsSlot } from '@utils/renderParamsSlot'; import { Alert, Spin, theme } from 'antd'; @@ -29,10 +28,9 @@ export const AutoLoading = sveltify< configType: ConfigType; showMask?: boolean; showTimer?: boolean; - loadingStatus?: LoadingStatus | null; + loadingStatus?: ILoadingStatus | null; loadingText?: string; children?: React.ReactNode; - setSlotParams: SetSlotParams; }, ['render', 'errorRender', 'loadingText'] >( @@ -44,7 +42,6 @@ export const AutoLoading = sveltify< className, id, style, - setSlotParams, showMask, showTimer, loadingText, @@ -74,7 +71,6 @@ export const AutoLoading = sveltify< if (isLoading) { if (slots.render) { loadingContent = renderParamsSlot({ - setSlotParams, slots, key: 'render', })?.(loadingStatus); @@ -93,7 +89,6 @@ export const AutoLoading = sveltify< showLoadingText ? ( slots.loadingText ? ( renderParamsSlot({ - setSlotParams, slots, key: 'loadingText', })?.(loadingStatus) @@ -144,7 +139,6 @@ export const AutoLoading = sveltify< if (status === 'error' && !instance) { if (slots.errorRender) { errorContent = renderParamsSlot({ - setSlotParams, slots, key: 'errorRender', })?.(loadingStatus); diff --git a/frontend/base/auto-loading/useLoadingStatus.ts b/frontend/base/auto-loading/useLoadingStatus.ts index 15b2c039..9fbcaf1c 100644 --- a/frontend/base/auto-loading/useLoadingStatus.ts +++ b/frontend/base/auto-loading/useLoadingStatus.ts @@ -1,8 +1,8 @@ import { useEffect, useRef, useState } from 'react'; -import type { LoadingStatus } from '@gradio/statustracker'; +import type { ILoadingStatus } from '@gradio/statustracker'; import { useMemoizedFn } from '@utils/hooks/useMemoizedFn'; -export function useLoadingStatus(loadingStatus?: LoadingStatus | null) { +export function useLoadingStatus(loadingStatus?: ILoadingStatus | null) { const [eta, setEta] = useState(loadingStatus?.eta ?? null); const { status, progress, queue_position, message, queue_size } = loadingStatus || {}; diff --git a/frontend/base/div/Index.svelte b/frontend/base/div/Index.svelte index 90b9d911..35caf375 100644 --- a/frontend/base/div/Index.svelte +++ b/frontend/base/div/Index.svelte @@ -1,74 +1,64 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDiv then Div}
    - + {@render children()}
    {/await} {/if} diff --git a/frontend/base/div/div.tsx b/frontend/base/div/div.tsx index fa1c2a2f..7f813a64 100644 --- a/frontend/base/div/div.tsx +++ b/frontend/base/div/div.tsx @@ -11,9 +11,7 @@ export const Div = sveltify< } >(({ slots: _slots, value, children, ...props }) => { const targets = useTargets(children); - return ( -
    {targets.length > 0 ? children : value || children}
    - ); + return
    {targets.length > 0 ? children : value}
    ; }); export default Div; diff --git a/frontend/base/each/Index.svelte b/frontend/base/each/Index.svelte index e378840b..e53f20f8 100644 --- a/frontend/base/each/Index.svelte +++ b/frontend/base/each/Index.svelte @@ -1,12 +1,13 @@ -{#if $mergedProps.visible} - +{#if proceedProps.visible} + + {@render children()} + {/if} diff --git a/frontend/legacy/Chatbot/CHANGELOG.md b/frontend/legacy/Chatbot/CHANGELOG.md deleted file mode 100644 index 0cc21227..00000000 --- a/frontend/legacy/Chatbot/CHANGELOG.md +++ /dev/null @@ -1,335 +0,0 @@ -# @modelscope-studio/legacy-chatbot - -## 1.6.1 - -No significant changes to this package were made in this release. - -## 1.6.0 - -No significant changes to this package were made in this release. - -## 1.5.2 - -No significant changes to this package were made in this release. - -## 1.5.2 - -### Patch Changes - -- Updated dependencies [[`4888b2b`](https://github.com/modelscope/modelscope-studio/commit/4888b2b209b8758c92c33f932b61992c3fe4362a)]: - - @modelscope-studio/legacy-compiled@1.5.2 - -## 1.5.1 - -No significant changes to this package were made in this release. - -## 1.5.0 - -No significant changes to this package were made in this release. - -## 1.4.7 - -### Patch Changes - -- Updated dependencies [[`5af9cdc`](https://github.com/modelscope/modelscope-studio/commit/5af9cdcb011e3bda1ea9419f34cffd93b81590e7)]: - - @modelscope-studio/legacy-compiled@1.4.7 - -## 1.4.6 - -No significant changes to this package were made in this release. - -## 1.4.5 - -No significant changes to this package were made in this release. - -## 1.4.5 - -### Patch Changes - -- Updated dependencies [[`cb4a962`](https://github.com/modelscope/modelscope-studio/commit/cb4a9623833ec345e86a16d4e2f202e949c3875b)]: - - @modelscope-studio/legacy-compiled@1.4.5 - -## 1.4.4 - -No significant changes to this package were made in this release. - -## 1.4.4 - -### Patch Changes - -- Updated dependencies [[`6d9b760`](https://github.com/modelscope/modelscope-studio/commit/6d9b760ea3132be488155e67a1c816f260fa7e4c)]: - - @modelscope-studio/legacy-compiled@1.4.4 - -## 1.4.3 - -No significant changes to this package were made in this release. - -## 1.4.3 - -### Patch Changes - -- Updated dependencies [[`ca7519f`](https://github.com/modelscope/modelscope-studio/commit/ca7519f439e00e0d99d921e88ec38dc4689d7849)]: - - @modelscope-studio/legacy-compiled@1.4.3 - -## 1.4.2 - -No significant changes to this package were made in this release. - -## 1.4.1 - -No significant changes to this package were made in this release. - -## 1.4.0 - -No significant changes to this package were made in this release. - -## 1.3.2 - -### Patch Changes - -- Updated dependencies [[`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861), [`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861)]: - - @modelscope-studio/legacy-compiled@1.3.2 - -## 1.3.1 - -No significant changes to this package were made in this release. - -## 1.3.0 - -No significant changes to this package were made in this release. - -## 1.2.5 - -### Patch Changes - -- Updated dependencies [[`d3259ab`](https://github.com/modelscope/modelscope-studio/commit/d3259abd179f7953b81f8d76c82cd2d3dd59766c)]: - - @modelscope-studio/legacy-compiled@1.2.5 - -## 1.2.4 - -No significant changes to this package were made in this release. - -## 1.2.3 - -No significant changes to this package were made in this release. - -## 1.2.3 - -### Patch Changes - -- Updated dependencies [[`034c4e3`](https://github.com/modelscope/modelscope-studio/commit/034c4e33ffa552e91d821171a68a1ab21eb35441)]: - - @modelscope-studio/legacy-compiled@1.2.3 - -## 1.2.2 - -No significant changes to this package were made in this release. - -## 1.2.1 - -No significant changes to this package were made in this release. - -## 1.2.0 - -No significant changes to this package were made in this release. - -## 1.1.7 - -No significant changes to this package were made in this release. - -## 1.1.6 - -No significant changes to this package were made in this release. - -## 1.1.5 - -No significant changes to this package were made in this release. - -## 1.1.5 - -### Patch Changes - -- Updated dependencies [[`4ab53e4`](https://github.com/modelscope/modelscope-studio/commit/4ab53e424c43a1db9d33b8883bb71a22cc59275b)]: - - @modelscope-studio/legacy-compiled@1.1.5 - -## 1.1.4 - -No significant changes to this package were made in this release. - -## 1.1.3 - -No significant changes to this package were made in this release. - -## 1.1.2 - -No significant changes to this package were made in this release. - -## 1.1.1 - -No significant changes to this package were made in this release. - -## 1.1.0 - -No significant changes to this package were made in this release. - -## 1.0.3 - -### Patch Changes - -- Updated dependencies [[`f4f8a15`](https://github.com/modelscope/modelscope-studio/commit/f4f8a155f30995984c5f46bdd638385c9a230856)]: - - @modelscope-studio/legacy-compiled@1.1.0 - -## 1.0.2 - -No significant changes to this package were made in this release. - -## 1.0.1 - -No significant changes to this package were made in this release. - -## 1.0.0 - -### Features - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Fixes - -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.11 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.10 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.9 - -### Fixes - -- [`e7fa278`](https://github.com/modelscope/modelscope-studio/commit/e7fa2782af83a7e78cddb700cd8d5e63ad62342f) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.8 - -### Fixes - -- [`a692793`](https://github.com/modelscope/modelscope-studio/commit/a6927930fa0cbb62b8e91d98fbfda7434586e758) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.7 - -### Fixes - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.6 - -### Fixes - -- [`6a38225`](https://github.com/modelscope/modelscope-studio/commit/6a38225363c7db871c9593e524fe73ebebff1016) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.5 - -### Features - -- [`af9aa4f`](https://github.com/modelscope/modelscope-studio/commit/af9aa4fe598ae23dbe88163202aab2d44d5a133d) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.4 - -### Fixes - -- [`107d733`](https://github.com/modelscope/modelscope-studio/commit/107d733cb4ee01f346d165cbe192c514b38ac905) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.3 - -### Features - -- [`9f3c59c`](https://github.com/modelscope/modelscope-studio/commit/9f3c59c9c5a0bf8af3980588cb07a467323b1d17) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.2 - -### Features - -- [`9e5da52`](https://github.com/modelscope/modelscope-studio/commit/9e5da52fc739c6862225192fecf95f6bfd7923ad) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.1 - -### Features - -- [`025f728`](https://github.com/modelscope/modelscope-studio/commit/025f72825bdafbc60b4a09e577a363e43189bd1d) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.0 - -### Features - -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.2 - -### Fixes - -- [`c742328`](https://github.com/modelscope/modelscope-studio/commit/c742328f04992c5461211d8153f5166d784678ee) - gradio5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.1 - -No significant changes to this package were made in this release. - -## 0.5.1 - -### Patch Changes - -- Updated dependencies [[`fca4451`](https://github.com/modelscope/modelscope-studio/commit/fca4451f433294e074507c62b4f5af7c1fb89be5)]: - - @modelscope-studio/compiled@0.5.1 - -## 0.5.0 - -### Features - -- [`e271eb4`](https://github.com/modelscope/modelscope-studio/commit/e271eb493c98f1af0abf35d7109188fc7bf1e8c0) - support cutom latex delimiters in Markdown and Chatbot. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.4.2 - -No significant changes to this package were made in this release. - -## 0.4.1 - -No significant changes to this package were made in this release. - -## 0.4.0 - -No significant changes to this package were made in this release. - -## 0.3.1 - -No significant changes to this package were made in this release. - -## 0.3.0 - -### Features - -- [#20](https://github.com/modelscope/modelscope-studio/pull/20) [`9a5dd22`](https://github.com/modelscope/modelscope-studio/commit/9a5dd226ee117d6130baa87cacdf902546ad952a) - upload logic with new gradio version. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.1 - -No significant changes to this package were made in this release. - -## 0.2.1 - -### Patch Changes - -- Updated dependencies [[`68400a3`](https://github.com/modelscope/modelscope-studio/commit/68400a366d5a8af9a8d14f51577d8db1ebdcceb3)]: - - @modelscope-studio/legacy-compiled@0.2.1 - -## 0.2.0 - -### Features - -- [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`d1829d3`](https://github.com/modelscope/modelscope-studio/commit/d1829d34dd0bce8834d2e257b612d79705e57d6d) - update the timing of onMount call and new onUpdate lifecycle of custom component. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/legacy/Chatbot/Index.svelte b/frontend/legacy/Chatbot/Index.svelte deleted file mode 100644 index 9888cea2..00000000 --- a/frontend/legacy/Chatbot/Index.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - - -{#await AwaitedChatbot then Chatbot} - - - -{/await} diff --git a/frontend/legacy/Chatbot/gradio.config.js b/frontend/legacy/Chatbot/gradio.config.js deleted file mode 100644 index abd9137f..00000000 --- a/frontend/legacy/Chatbot/gradio.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../defineConfig.js'; - -export default config({ external: true }); diff --git a/frontend/legacy/Chatbot/package.json b/frontend/legacy/Chatbot/package.json deleted file mode 100644 index f71a0060..00000000 --- a/frontend/legacy/Chatbot/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@modelscope-studio/legacy-chatbot", - "version": "1.6.1", - "private": false, - "description": "ModelScope Gradio Components", - "repository": "git@github.com:modelscope/modelscope-studio.git", - "license": "Apache-2.0", - "type": "module", - "exports": { - ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" - }, - "./package.json": { - "default": "./package.json", - "gradio": "./package.json" - } - }, - "dependencies": { - "@modelscope-studio/legacy-compiled": "workspace:*" - }, - "devDependencies": {}, - "main_changeset": true -} diff --git a/frontend/legacy/Chatbot/shared/ChatBot.svelte b/frontend/legacy/Chatbot/shared/ChatBot.svelte deleted file mode 100644 index 6d8ab067..00000000 --- a/frontend/legacy/Chatbot/shared/ChatBot.svelte +++ /dev/null @@ -1,701 +0,0 @@ - - -{#if show_share_button && value && value.length > 0} - -{/if} - -
    -
    - {#if value} - {#each value as message_pair, i (i)} - {#each message_pair as message_item, j (j)} - {#if message_item} - {#each message_item as message, k (message?.id || `${i}-${j}-${k}`)} - {#if message} -
    - {#if message.avatar || avatar_images[j][k]} - {@const message_name = get_message_name(message, j, k)} -
    - {j == 0 ? 'user' : 'bot'} avatar - {#if message_name} - {message_name} - {/if} -
    - {/if} - -
    - - {#if (likeable && j !== 0) || (show_copy_button && message && typeof message.text === 'string')} -
    - {#if likeable && j == 1} - - handle_like(i, j, k, message, true)} - /> - - handle_like(i, j, k, message, false)} - /> - {/if} - - {#if show_copy_button && message && typeof message.text === 'string'} - - {/if} -
    - {/if} -
    -
    - {/if} - {/each} - {/if} - {/each} - {/each} - {#if pending_message} - - {/if} - {/if} -
    -
    - - diff --git a/frontend/legacy/Chatbot/shared/Copy.svelte b/frontend/legacy/Chatbot/shared/Copy.svelte deleted file mode 100644 index 7c96cc70..00000000 --- a/frontend/legacy/Chatbot/shared/Copy.svelte +++ /dev/null @@ -1,60 +0,0 @@ - - - - - diff --git a/frontend/legacy/Chatbot/shared/FlushingMarkdown.svelte b/frontend/legacy/Chatbot/shared/FlushingMarkdown.svelte deleted file mode 100644 index 4ddc827a..00000000 --- a/frontend/legacy/Chatbot/shared/FlushingMarkdown.svelte +++ /dev/null @@ -1,116 +0,0 @@ - - - diff --git a/frontend/legacy/Chatbot/shared/LikeDislike.svelte b/frontend/legacy/Chatbot/shared/LikeDislike.svelte deleted file mode 100644 index cd9ee966..00000000 --- a/frontend/legacy/Chatbot/shared/LikeDislike.svelte +++ /dev/null @@ -1,48 +0,0 @@ - - - - - diff --git a/frontend/legacy/Chatbot/shared/Pending.svelte b/frontend/legacy/Chatbot/shared/Pending.svelte deleted file mode 100644 index 4da0f1b4..00000000 --- a/frontend/legacy/Chatbot/shared/Pending.svelte +++ /dev/null @@ -1,60 +0,0 @@ - - -
    - Loading content -
    -   -
    -   -
    -
    - - diff --git a/frontend/legacy/Chatbot/shared/llm-thinking-presets.ts b/frontend/legacy/Chatbot/shared/llm-thinking-presets.ts deleted file mode 100644 index 0b623205..00000000 --- a/frontend/legacy/Chatbot/shared/llm-thinking-presets.ts +++ /dev/null @@ -1,206 +0,0 @@ -const trimString = (str: string) => { - return str.replace(/^\s+|\s+$/g, ''); -}; - -const findNextPattern = (text: string, pattern: string, start_pos = 0) => { - const idx = text.indexOf(pattern, start_pos); - if (idx < 0) { - return { - found: false, - pos: -1, - }; - } - return { - found: true, - pos: idx, - }; -}; - -const consumePattern = ( - text: string, - patternStart: string, - patternEnd: string, - start_pos = 0 -) => { - const flagStart = findNextPattern(text, patternStart, start_pos); - if (flagStart.found) { - const flagEnd = findNextPattern(text, patternEnd, flagStart.pos); - if (flagEnd.found) { - return { - pos: flagEnd.pos, - content: text.substring( - flagStart.pos + patternStart.length, - flagEnd.pos - ), - finish: true, - }; - } else { - return { - pos: text.length - 1, - content: text.substring(flagStart.pos + patternStart.length), - finish: false, - }; - } - } else { - return false; - } -}; - -/** - * - -<场景描述>:你在古墓派的后山修炼内功,突然听到远处传来一阵异样的声音。你决定去查看一下。 - -调用工具: -Action: image_gen -Action Input: {"text": "小龙女在古墓派后山修炼内功", "resolution": "1280*720"} -Observation: ![IMAGEGEN](https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/f1/20231207/8d820c8d/463b323b-6209-4095-b1c3-f7c4dd337e6c-1.png?Expires=1702002840&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=zg6mIsIU3XDNrQxhwNWSt9QWTDI%3D) -![小龙女在古墓派后山修炼内功](https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/f1/20231207/8d820c8d/463b323b-6209-4095-b1c3-f7c4dd337e6c-1.png?Expires=1702002840&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=zg6mIsIU3XDNrQxhwNWSt9QWTDI%3D) - - -<选择>: -A: 继续修炼,不理睬那声音。 -B: 走向声音的来源,查看发生了什么。 -C: 召唤你的蜜蜂去调查情况。 -D: 输入玩家的选择。 - - */ -const find_json_pattern = /{[\s\S]+}/; - -// Convert the output of qwen -export const qwen = ( - text: string, - options?: { - action_input_title?: string; - action_output_title?: string; - auto_end?: boolean; - } -) => { - let loop_pos = 0; - let result = ''; - - const ACTION = 'Action:'; - const ACTION_INPUT = 'Action Input:'; - const OBSERVATION = 'Observation:'; - const RESULT_START = ''; - const RESULT_END = ''; - - const findChainOfThinking = (thinking_text: string, start_pos: number) => { - let pos = start_pos; - let actionName = ''; - let actionBody = ''; - let resultBody = ''; - let finished = false; - const flag_action = findNextPattern(thinking_text, ACTION, pos); - if (!flag_action.found) { - return { - found: false, - pos, - }; - } - const actionNameRet = consumePattern( - thinking_text, - ACTION, - ACTION_INPUT, - pos - ); - if (actionNameRet) { - actionName = trimString(actionNameRet.content); - pos = actionNameRet.pos; - if (actionNameRet.finish) { - const actionBodyRet = consumePattern( - thinking_text, - ACTION_INPUT, - OBSERVATION, - pos - ); - if (actionBodyRet) { - actionBody = trimString(actionBodyRet.content); - pos = actionBodyRet.pos; - if (actionBodyRet.finish) { - const observationFlag = findNextPattern( - thinking_text, - OBSERVATION, - pos - ); - if (observationFlag) { - const resultBodyRet = consumePattern( - thinking_text, - RESULT_START, - RESULT_END, - pos - ); - if (resultBodyRet) { - resultBody = resultBodyRet.content; - pos = resultBodyRet.pos + RESULT_END.length; - finished = true; - } - } - } - } - } - } - return { - beforeContent: thinking_text.substring(start_pos, flag_action.pos), - found: true, - finished, - pos, - actionName, - actionBody, - resultBody, - }; - }; - - do { - const { - found, - finished, - beforeContent, - actionName, - actionBody, - resultBody, - pos, - } = findChainOfThinking(text, loop_pos); - - loop_pos = pos; - if (beforeContent) { - result += beforeContent; - } - if (found) { - if (actionName) { - let actionBodyContent = ''; - if (actionBody) { - const is_json = find_json_pattern.exec(actionBody); - if (is_json) { - actionBodyContent = `\`\`\`json\n${actionBody}\n\n\`\`\``; - } else { - actionBodyContent = actionBody; - } - } - result += [ - '\n:::llm-thinking', - `::llm-thinking-title[${options?.action_input_title?.replaceAll( - '', - actionName - )}]`, - actionBodyContent, - ':::\n', - ].join('\n'); - } - if (resultBody) { - result += [ - '\n:::llm-thinking', - `::llm-thinking-title[${options?.action_output_title}]`, - resultBody, - ':::\n', - options?.auto_end && finished ? ':flushing-end' : '', - ].join('\n'); - } - } - if (!found || (found && !finished)) { - break; - } - } while (true); // eslint-disable-line - result += text.substring(loop_pos); - return result; -}; diff --git a/frontend/legacy/Chatbot/shared/utils.ts b/frontend/legacy/Chatbot/shared/utils.ts deleted file mode 100644 index 464ef72d..00000000 --- a/frontend/legacy/Chatbot/shared/utils.ts +++ /dev/null @@ -1,161 +0,0 @@ -import type { FileData } from '@gradio/client'; - -import { qwen } from './llm-thinking-presets'; - -export interface LLMThinkingPreset { - type: 'qwen'; - action_input_title: string; - action_output_title: string; -} - -export type AvatarImage = { avatar: string; name?: string } | string | null; - -export type AvatarImageItem = AvatarImage | AvatarImage[]; - -export interface SelectData { - index: [number, number, number]; - value: any; - selected?: boolean; -} - -export interface LikeData { - index: [number, number, number]; - value: any; - liked?: boolean; -} - -export interface FlushData { - value: string; - index: [number, number, number]; -} - -export type FileMessage = { - file: FileData; - alt_text?: string; -}; - -export type MultimodalMessage = { - id?: string; - text: string; - elem_id?: string; - elem_classes?: string | string[]; - name?: string; - avatar?: string | FileData | null; - flushing?: boolean; - files?: FileMessage[]; -}; - -export type MultimodalMessageItem = MultimodalMessage | MultimodalMessage[]; - -export function ensureArray(value: T) { - return (Array.isArray(value) ? value : [value]) as T extends any[] ? T : T[]; -} - -export async function copy_to_clipboard(value: string) { - if ('clipboard' in navigator) { - await navigator.clipboard.writeText(value); - } else { - const textArea = document.createElement('textarea'); - textArea.value = value; - - textArea.style.position = 'absolute'; - textArea.style.left = '-999999px'; - - document.body.prepend(textArea); - textArea.select(); - - try { - document.execCommand('copy'); - } catch (error) { - return Promise.reject(error); - } finally { - textArea.remove(); - } - } -} - -export const format_chat_for_sharing = async ( - chat: [ - (MultimodalMessage | null)[] | null, - (MultimodalMessage | null)[] | null, - ][] -): Promise => { - const messages = await Promise.all( - chat.map(async (message_pair) => { - return await Promise.all( - message_pair.map((message_item, i) => { - if (!message_item) { - return []; - } - const speaker_emoji = i === 0 ? '😃' : '🤖'; - return message_item.map((message) => { - if (!message) { - return ''; - } - let html_content = message.text; - - if (Array.isArray(message.files) && message.files.length > 0) { - html_content += '
    '; - message.files.forEach((fileMessage) => { - const file = fileMessage.file; - if (!file?.url) return ''; - const file_url = file.url; - if (file.mime_type?.includes('audio')) { - html_content += ``; - } else if (file.mime_type?.includes('video')) { - html_content += ``; - } else if (file.mime_type?.includes('image')) { - html_content += ``; - } else { - html_content += `
    ${fileMessage.alt_text || fileMessage.file.alt_text || fileMessage.file.orig_name}`; - } - }); - } - - return `${speaker_emoji}${message.name ? ` ${message.name}` : ''}: ${html_content}`; - }); - }) - ); - }) - ); - return messages - .map((message_pair) => { - return message_pair.map((message_item) => { - return message_item.join('\n'); - }); - }) - .map((message_pair) => { - return message_pair.join( - message_pair[0] !== '' && message_pair[1] !== '' ? '\n' : '' - ); - }) - .join('\n'); -}; - -export const should_flushing = ( - type: 'chatbot' | 'user', - message: MultimodalMessage -) => { - if (type === 'chatbot') { - return message.flushing !== false; - } else if (type === 'user') { - return message.flushing; - } -}; - -export function resolve_llm_thinking_presets( - message: string, - presets: LLMThinkingPreset[] = [] -): string { - let result = message; - - for (const preset of presets) { - switch (preset.type) { - case 'qwen': - result = qwen(result, preset); - break; - } - } - - return result; -} diff --git a/frontend/legacy/Flow/Awaited.svelte b/frontend/legacy/Flow/Awaited.svelte deleted file mode 100644 index 90e2ee06..00000000 --- a/frontend/legacy/Flow/Awaited.svelte +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - {#if loading_status} - - {/if} - gradio.dispatch('custom', e.detail)} - on:change={(e) => { - const { value: newValue, data_changed } = e.detail; - if (sync_on_data_change) { - if (!data_changed) { - // eslint-disable-next-line svelte/no-reactive-reassign - _value = newValue; - } - } else { - value = newValue; - } - gradio.dispatch('change', newValue); - if (data_changed) { - if (sync_on_data_change) { - value = newValue; - } - gradio.dispatch('data_change', newValue); - } - }} - /> - diff --git a/frontend/legacy/Flow/CHANGELOG.md b/frontend/legacy/Flow/CHANGELOG.md deleted file mode 100644 index c8e37398..00000000 --- a/frontend/legacy/Flow/CHANGELOG.md +++ /dev/null @@ -1,336 +0,0 @@ -# @modelscope-studio/legacy-flow - -## 1.6.1 - -No significant changes to this package were made in this release. - -## 1.6.0 - -No significant changes to this package were made in this release. - -## 1.5.2 - -No significant changes to this package were made in this release. - -## 1.5.2 - -### Patch Changes - -- Updated dependencies [[`4888b2b`](https://github.com/modelscope/modelscope-studio/commit/4888b2b209b8758c92c33f932b61992c3fe4362a)]: - - @modelscope-studio/legacy-compiled@1.5.2 - -## 1.5.1 - -No significant changes to this package were made in this release. - -## 1.5.0 - -No significant changes to this package were made in this release. - -## 1.4.7 - -### Patch Changes - -- Updated dependencies [[`5af9cdc`](https://github.com/modelscope/modelscope-studio/commit/5af9cdcb011e3bda1ea9419f34cffd93b81590e7)]: - - @modelscope-studio/legacy-compiled@1.4.7 - -## 1.4.6 - -No significant changes to this package were made in this release. - -## 1.4.5 - -No significant changes to this package were made in this release. - -## 1.4.5 - -### Patch Changes - -- Updated dependencies [[`cb4a962`](https://github.com/modelscope/modelscope-studio/commit/cb4a9623833ec345e86a16d4e2f202e949c3875b)]: - - @modelscope-studio/legacy-compiled@1.4.5 - -## 1.4.4 - -No significant changes to this package were made in this release. - -## 1.4.4 - -### Patch Changes - -- Updated dependencies [[`6d9b760`](https://github.com/modelscope/modelscope-studio/commit/6d9b760ea3132be488155e67a1c816f260fa7e4c)]: - - @modelscope-studio/legacy-compiled@1.4.4 - -## 1.4.3 - -### Misc Changes - -- [#82](https://github.com/modelscope/modelscope-studio/pull/82) [`ca7519f`](https://github.com/modelscope/modelscope-studio/commit/ca7519f439e00e0d99d921e88ec38dc4689d7849) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.2 - -No significant changes to this package were made in this release. - -## 1.4.1 - -No significant changes to this package were made in this release. - -## 1.4.0 - -No significant changes to this package were made in this release. - -## 1.3.2 - -### Patch Changes - -- Updated dependencies [[`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861), [`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861)]: - - @modelscope-studio/legacy-compiled@1.3.2 - -## 1.3.1 - -No significant changes to this package were made in this release. - -## 1.3.0 - -No significant changes to this package were made in this release. - -## 1.2.5 - -### Patch Changes - -- Updated dependencies [[`d3259ab`](https://github.com/modelscope/modelscope-studio/commit/d3259abd179f7953b81f8d76c82cd2d3dd59766c)]: - - @modelscope-studio/legacy-compiled@1.2.5 - -## 1.2.4 - -No significant changes to this package were made in this release. - -## 1.2.3 - -No significant changes to this package were made in this release. - -## 1.2.3 - -### Patch Changes - -- Updated dependencies [[`034c4e3`](https://github.com/modelscope/modelscope-studio/commit/034c4e33ffa552e91d821171a68a1ab21eb35441)]: - - @modelscope-studio/legacy-compiled@1.2.3 - -## 1.2.2 - -No significant changes to this package were made in this release. - -## 1.2.1 - -No significant changes to this package were made in this release. - -## 1.2.0 - -No significant changes to this package were made in this release. - -## 1.1.7 - -No significant changes to this package were made in this release. - -## 1.1.6 - -No significant changes to this package were made in this release. - -## 1.1.5 - -No significant changes to this package were made in this release. - -## 1.1.5 - -### Patch Changes - -- Updated dependencies [[`4ab53e4`](https://github.com/modelscope/modelscope-studio/commit/4ab53e424c43a1db9d33b8883bb71a22cc59275b)]: - - @modelscope-studio/legacy-compiled@1.1.5 - -## 1.1.4 - -No significant changes to this package were made in this release. - -## 1.1.3 - -No significant changes to this package were made in this release. - -## 1.1.2 - -No significant changes to this package were made in this release. - -## 1.1.1 - -No significant changes to this package were made in this release. - -## 1.1.0 - -No significant changes to this package were made in this release. - -## 1.0.3 - -### Patch Changes - -- Updated dependencies [[`f4f8a15`](https://github.com/modelscope/modelscope-studio/commit/f4f8a155f30995984c5f46bdd638385c9a230856)]: - - @modelscope-studio/legacy-compiled@1.1.0 - -## 1.0.2 - -No significant changes to this package were made in this release. - -## 1.0.1 - -No significant changes to this package were made in this release. - -## 1.0.0 - -### Features - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Fixes - -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.11 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.10 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.9 - -### Fixes - -- [`e7fa278`](https://github.com/modelscope/modelscope-studio/commit/e7fa2782af83a7e78cddb700cd8d5e63ad62342f) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.8 - -### Fixes - -- [`a692793`](https://github.com/modelscope/modelscope-studio/commit/a6927930fa0cbb62b8e91d98fbfda7434586e758) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.7 - -### Fixes - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.6 - -### Fixes - -- [`6a38225`](https://github.com/modelscope/modelscope-studio/commit/6a38225363c7db871c9593e524fe73ebebff1016) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.5 - -### Features - -- [`af9aa4f`](https://github.com/modelscope/modelscope-studio/commit/af9aa4fe598ae23dbe88163202aab2d44d5a133d) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.4 - -### Fixes - -- [`107d733`](https://github.com/modelscope/modelscope-studio/commit/107d733cb4ee01f346d165cbe192c514b38ac905) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.3 - -### Features - -- [`9f3c59c`](https://github.com/modelscope/modelscope-studio/commit/9f3c59c9c5a0bf8af3980588cb07a467323b1d17) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.2 - -### Features - -- [`9e5da52`](https://github.com/modelscope/modelscope-studio/commit/9e5da52fc739c6862225192fecf95f6bfd7923ad) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.1 - -### Features - -- [`025f728`](https://github.com/modelscope/modelscope-studio/commit/025f72825bdafbc60b4a09e577a363e43189bd1d) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.0 - -### Features - -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.2 - -No significant changes to this package were made in this release. - -## 0.5.2 - -### Patch Changes - -- Updated dependencies [[`c742328`](https://github.com/modelscope/modelscope-studio/commit/c742328f04992c5461211d8153f5166d784678ee)]: - - @modelscope-studio/shared@0.5.2 - -## 0.5.1 - -No significant changes to this package were made in this release. - -## 0.5.1 - -### Patch Changes - -- Updated dependencies [[`fca4451`](https://github.com/modelscope/modelscope-studio/commit/fca4451f433294e074507c62b4f5af7c1fb89be5)]: - - @modelscope-studio/compiled@0.5.1 - - @modelscope-studio/shared@0.5.1 - -## 0.5.0 - -No significant changes to this package were made in this release. - -## 0.4.3 - -### Patch Changes - -- Updated dependencies [[`e271eb4`](https://github.com/modelscope/modelscope-studio/commit/e271eb493c98f1af0abf35d7109188fc7bf1e8c0)]: - - @modelscope-studio/compiled@0.5.0 - -## 0.4.2 - -No significant changes to this package were made in this release. - -## 0.4.1 - -No significant changes to this package were made in this release. - -## 0.4.0 - -No significant changes to this package were made in this release. - -## 0.3.1 - -No significant changes to this package were made in this release. - -## 0.3.0 - -### Features - -- [#20](https://github.com/modelscope/modelscope-studio/pull/20) [`9a5dd22`](https://github.com/modelscope/modelscope-studio/commit/9a5dd226ee117d6130baa87cacdf902546ad952a) - upload logic with new gradio version. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.1 - -### Fixes - -- [`68400a3`](https://github.com/modelscope/modelscope-studio/commit/68400a366d5a8af9a8d14f51577d8db1ebdcceb3) - unique id to each flow. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.0 - -### Features - -- [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`96e1682`](https://github.com/modelscope/modelscope-studio/commit/96e1682b7cb63907aafba06afb820f55d7df8ff0) - add Flow component. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/legacy/Flow/Index.svelte b/frontend/legacy/Flow/Index.svelte deleted file mode 100644 index ed37b002..00000000 --- a/frontend/legacy/Flow/Index.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - - -{#await AwaitedFlow then Flow} - - - -{/await} diff --git a/frontend/legacy/Flow/gradio.config.js b/frontend/legacy/Flow/gradio.config.js deleted file mode 100644 index abd9137f..00000000 --- a/frontend/legacy/Flow/gradio.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../defineConfig.js'; - -export default config({ external: true }); diff --git a/frontend/legacy/Flow/package.json b/frontend/legacy/Flow/package.json deleted file mode 100644 index 79a24422..00000000 --- a/frontend/legacy/Flow/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "@modelscope-studio/legacy-flow", - "version": "1.6.1", - "private": false, - "description": "ModelScope Gradio Components", - "repository": "git@github.com:modelscope/modelscope-studio.git", - "license": "Apache-2.0", - "type": "module", - "exports": { - ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" - }, - "./package.json": { - "default": "./package.json", - "gradio": "./package.json" - } - }, - "scripts": { - "build": "typescript-json-schema --skipLibCheck ./schema.ts FlowSchema > ./schema.json" - }, - "dependencies": { - "@modelscope-studio/legacy-compiled": "workspace:*" - }, - "devDependencies": {}, - "main_changeset": true -} diff --git a/frontend/legacy/Flow/schema.json b/frontend/legacy/Flow/schema.json deleted file mode 100644 index a29ee191..00000000 --- a/frontend/legacy/Flow/schema.json +++ /dev/null @@ -1,325 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "definitions": { - "Attrs": { - "type": "object" - }, - "FlowNodeAttrSchema": { - "properties": { - "accordion": { - "default": true, - "description": "Enable/disable accordion UI.", - "type": "boolean" - }, - "description": { - "description": "A brief explanation about the attribute purpose.", - "type": "string" - }, - "disabled": { - "default": false, - "description": "Disables user editing of the attribute value. By default, attributes are editable.", - "type": "boolean" - }, - "json_schema_validator": { - "$ref": "#/definitions/Record", - "description": "Validates attribute values using JSON schema." - }, - "list": { - "anyOf": [ - { - "properties": { - "max": { - "description": "Maximum number of items in the list.", - "type": "number" - }, - "min": { - "description": "Minimum number of items in the list.", - "type": "number" - }, - "ports": { - "description": "Port configurations for each item in the list.", - "properties": { - "source": { - "default": [], - "description": "Source ports for the list item as a connection.", - "items": { - "$ref": "#/definitions/Position" - }, - "type": "array" - }, - "sourceConnections": { - "description": "Allowed the source ports of this list item to connect to other nodes or attributes. Defaults to all nodes and attributes", - "items": { - "$ref": "#/definitions/PortConnection" - }, - "type": "array" - }, - "target": { - "description": "Target ports for the list item as a connection", - "items": { - "$ref": "#/definitions/Position" - }, - "type": "array" - }, - "targetConnections": { - "description": "Allowed other nodes or attributes allowed to connect to the target ports of this list item. Defaults to all nodes and attributes", - "items": { - "$ref": "#/definitions/PortConnection" - }, - "type": "array" - } - }, - "type": "object" - } - }, - "type": "object" - }, - { - "type": "boolean" - } - ], - "default": false, - "description": "Indicates whether the attribute is a list." - }, - "name": { - "description": "Unique attribute name used as a key in the node data. Mandatory.", - "type": "string" - }, - "ports": { - "description": "Configurations for the node attribute ports.", - "properties": { - "source": { - "default": [], - "description": "Source ports for the attribute as a connection.", - "items": { - "$ref": "#/definitions/Position" - }, - "type": "array" - }, - "sourceConnections": { - "description": "Allowed the source ports of this attribute to connect to other nodes or attributes. Defaults to all nodes and attributes", - "items": { - "$ref": "#/definitions/PortConnection" - }, - "type": "array" - }, - "target": { - "default": [], - "description": "Target ports for the attribute as a connection", - "items": { - "$ref": "#/definitions/Position" - }, - "type": "array" - }, - "targetConnections": { - "description": "Allowed other nodes or attributes allowed to connect to the target ports of this attribute. Defaults to all nodes and attributes", - "items": { - "$ref": "#/definitions/PortConnection" - }, - "type": "array" - } - }, - "type": "object" - }, - "props": { - "$ref": "#/definitions/Record", - "description": "Configuration options specific to the chosen component type, supporting Ant Design ({@link https://ant.design/components/overview/}) or custom component properties." - }, - "required": { - "anyOf": [ - { - "properties": { - "message": { - "type": "string" - } - }, - "type": "object" - }, - { - "type": "boolean" - } - ], - "default": false, - "description": "Specifies if the attribute value is mandatory. By default, attributes are optional." - }, - "title": { - "description": "Display title for the attribute, defaults to the attribute name if not provided.", - "type": "string" - }, - "type": { - "anyOf": [ - { - "allOf": [ - { - "properties": {}, - "type": "object" - }, - { - "type": "string" - } - ] - }, - { - "enum": [ - "checkbox", - "input", - "number", - "radio", - "select", - "switch", - "textarea", - "upload" - ], - "type": "string" - } - ], - "default": "'input'", - "description": "Attribute input type. Can be one of the built-in Ant Design components or a custom component. Defaults to 'input'." - } - }, - "type": "object" - }, - "FlowNodeSchema": { - "properties": { - "addable": { - "default": true, - "description": "Enables/disables adding more instances of this node.", - "type": "boolean" - }, - "attrs": { - "description": "Configuration of the node's attributes.", - "items": { - "$ref": "#/definitions/FlowNodeAttrSchema" - }, - "type": "array" - }, - "deletable": { - "default": true, - "description": "Enables/disables deleting existing instances of this node.", - "type": "boolean" - }, - "description": { - "description": "A short description of the node's purpose.", - "type": "string" - }, - "height": { - "description": "Height of the node.", - "type": "number" - }, - "icon": { - "description": "Display icon for the node.", - "type": "string" - }, - "max": { - "description": "Maximum number of this node type that can exist simultaneously.", - "type": "number" - }, - "min": { - "description": "Minimum number of this node type that must exist simultaneously.", - "type": "number" - }, - "name": { - "description": "As a unique identifier for the node. Mandatory.", - "type": "string" - }, - "ports": { - "description": "Configurations for the node's connection ports.", - "properties": { - "source": { - "default": "['right']", - "description": "Source ports for the node as a connection.", - "items": { - "$ref": "#/definitions/Position" - }, - "type": "array" - }, - "sourceConnections": { - "description": "Allowed the source ports of this node to connect to other nodes or attributes. Defaults to all nodes and attributes", - "items": { - "$ref": "#/definitions/PortConnection" - }, - "type": "array" - }, - "target": { - "default": "['left']", - "description": "Target ports for the node as a connection", - "items": { - "$ref": "#/definitions/Position" - }, - "type": "array" - }, - "targetConnections": { - "description": "Allowed other nodes or attributes allowed to connect to the target ports of this node. Defaults to all nodes and attributes", - "items": { - "$ref": "#/definitions/PortConnection" - }, - "type": "array" - } - }, - "type": "object" - }, - "show_toolbar": { - "default": true, - "description": "Shows/hides the toolbar (delete, copy, rename, etc.).", - "type": "boolean" - }, - "template": { - "description": "Initial values for the node's attributes when creating a new instance.", - "properties": { - "attrs": { - "$ref": "#/definitions/Attrs", - "description": "Attribute values corresponding to their names in the `attrs` field, e.g., `{ \"a\": 1, \"b\": 2 }`." - } - }, - "type": "object" - }, - "title": { - "description": "Display title for the node, defaults to the node name if not provided.", - "type": "string" - }, - "width": { - "description": "Width of the node.", - "type": "number" - } - }, - "type": "object" - }, - "PortConnection": { - "anyOf": [ - { - "properties": { - "attrs": { - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - { - "type": "string" - } - ] - }, - "Position": { - "enum": ["left", "top", "right", "bottom"], - "type": "string" - }, - "Record": { - "type": "object" - } - }, - "properties": { - "nodes": { - "items": { - "$ref": "#/definitions/FlowNodeSchema" - }, - "type": "array" - } - }, - "type": "object" -} diff --git a/frontend/legacy/Flow/schema.ts b/frontend/legacy/Flow/schema.ts deleted file mode 100644 index df3e3907..00000000 --- a/frontend/legacy/Flow/schema.ts +++ /dev/null @@ -1 +0,0 @@ -export { type FlowSchema } from '@modelscope-studio/legacy-compiled/src/Flow/type'; diff --git a/frontend/legacy/Flow/shared/Flow.svelte b/frontend/legacy/Flow/shared/Flow.svelte deleted file mode 100644 index 74f3bdd8..00000000 --- a/frontend/legacy/Flow/shared/Flow.svelte +++ /dev/null @@ -1,95 +0,0 @@ - - - diff --git a/frontend/legacy/Flow/shared/utils.ts b/frontend/legacy/Flow/shared/utils.ts deleted file mode 100644 index 565293b3..00000000 --- a/frontend/legacy/Flow/shared/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { FlowRenderData } from '@modelscope-studio/legacy-compiled'; - -export interface FlowData { - nodes?: NonNullable; - edges?: NonNullable; -} diff --git a/frontend/legacy/Lifecycle/CHANGELOG.md b/frontend/legacy/Lifecycle/CHANGELOG.md deleted file mode 100644 index c9aa47ce..00000000 --- a/frontend/legacy/Lifecycle/CHANGELOG.md +++ /dev/null @@ -1,218 +0,0 @@ -# @modelscope-studio/legacy-lifecycle - -## 1.6.1 - -No significant changes to this package were made in this release. - -## 1.6.0 - -No significant changes to this package were made in this release. - -## 1.5.2 - -No significant changes to this package were made in this release. - -## 1.5.1 - -No significant changes to this package were made in this release. - -## 1.5.0 - -No significant changes to this package were made in this release. - -## 1.4.6 - -No significant changes to this package were made in this release. - -## 1.4.5 - -No significant changes to this package were made in this release. - -## 1.4.4 - -No significant changes to this package were made in this release. - -## 1.4.3 - -No significant changes to this package were made in this release. - -## 1.4.2 - -No significant changes to this package were made in this release. - -## 1.4.1 - -No significant changes to this package were made in this release. - -## 1.4.0 - -No significant changes to this package were made in this release. - -## 1.3.1 - -No significant changes to this package were made in this release. - -## 1.3.0 - -No significant changes to this package were made in this release. - -## 1.2.4 - -No significant changes to this package were made in this release. - -## 1.2.3 - -No significant changes to this package were made in this release. - -## 1.2.2 - -No significant changes to this package were made in this release. - -## 1.2.1 - -No significant changes to this package were made in this release. - -## 1.2.0 - -No significant changes to this package were made in this release. - -## 1.1.7 - -No significant changes to this package were made in this release. - -## 1.1.6 - -No significant changes to this package were made in this release. - -## 1.1.5 - -No significant changes to this package were made in this release. - -## 1.1.4 - -No significant changes to this package were made in this release. - -## 1.1.3 - -No significant changes to this package were made in this release. - -## 1.1.2 - -No significant changes to this package were made in this release. - -## 1.1.1 - -No significant changes to this package were made in this release. - -## 1.1.0 - -No significant changes to this package were made in this release. - -## 1.0.2 - -No significant changes to this package were made in this release. - -## 1.0.1 - -No significant changes to this package were made in this release. - -## 1.0.0 - -### Features - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Fixes - -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.11 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.10 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.9 - -### Fixes - -- [`e7fa278`](https://github.com/modelscope/modelscope-studio/commit/e7fa2782af83a7e78cddb700cd8d5e63ad62342f) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.8 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.7 - -### Fixes - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.6 - -### Fixes - -- [`6a38225`](https://github.com/modelscope/modelscope-studio/commit/6a38225363c7db871c9593e524fe73ebebff1016) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.5 - -### Features - -- [`af9aa4f`](https://github.com/modelscope/modelscope-studio/commit/af9aa4fe598ae23dbe88163202aab2d44d5a133d) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.4 - -### Fixes - -- [`107d733`](https://github.com/modelscope/modelscope-studio/commit/107d733cb4ee01f346d165cbe192c514b38ac905) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.3 - -### Features - -- [`9f3c59c`](https://github.com/modelscope/modelscope-studio/commit/9f3c59c9c5a0bf8af3980588cb07a467323b1d17) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.2 - -### Features - -- [`9e5da52`](https://github.com/modelscope/modelscope-studio/commit/9e5da52fc739c6862225192fecf95f6bfd7923ad) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.1 - -### Features - -- [`025f728`](https://github.com/modelscope/modelscope-studio/commit/025f72825bdafbc60b4a09e577a363e43189bd1d) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.0 - -### Features - -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.0 - -No significant changes to this package were made in this release. - -## 0.4.2 - -No significant changes to this package were made in this release. - -## 0.4.1 - -No significant changes to this package were made in this release. - -## 0.4.0 - -### Misc Changes - -- [#24](https://github.com/modelscope/modelscope-studio/pull/24) [`1b01a0b`](https://github.com/modelscope/modelscope-studio/commit/1b01a0b2e551d6afa26a9d8e6d34c2af2b92c57c) - add Lifecycle component. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/legacy/Lifecycle/Index.svelte b/frontend/legacy/Lifecycle/Index.svelte deleted file mode 100644 index 014e97a0..00000000 --- a/frontend/legacy/Lifecycle/Index.svelte +++ /dev/null @@ -1,98 +0,0 @@ - - -
    - - diff --git a/frontend/legacy/Lifecycle/gradio.config.js b/frontend/legacy/Lifecycle/gradio.config.js deleted file mode 100644 index abd9137f..00000000 --- a/frontend/legacy/Lifecycle/gradio.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../defineConfig.js'; - -export default config({ external: true }); diff --git a/frontend/legacy/Lifecycle/package.json b/frontend/legacy/Lifecycle/package.json deleted file mode 100644 index 06cae053..00000000 --- a/frontend/legacy/Lifecycle/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "@modelscope-studio/legacy-lifecycle", - "version": "1.6.1", - "private": false, - "description": "ModelScope Gradio Components", - "repository": "git@github.com:modelscope/modelscope-studio.git", - "license": "Apache-2.0", - "type": "module", - "exports": { - ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" - }, - "./package.json": { - "default": "./package.json", - "gradio": "./package.json" - } - }, - "dependencies": {}, - "devDependencies": {}, - "main_changeset": true -} diff --git a/frontend/legacy/Lifecycle/shared/utils.ts b/frontend/legacy/Lifecycle/shared/utils.ts deleted file mode 100644 index 88c176c7..00000000 --- a/frontend/legacy/Lifecycle/shared/utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface LifecycleData { - language: string; - userAgent: string; - theme: string; - screen: { - width: number; - height: number; - scrollY: number; - scrollX: number; - }; -} diff --git a/frontend/legacy/Markdown/Awaited.svelte b/frontend/legacy/Markdown/Awaited.svelte deleted file mode 100644 index 73923629..00000000 --- a/frontend/legacy/Markdown/Awaited.svelte +++ /dev/null @@ -1,93 +0,0 @@ - - - - -
    - gradio.dispatch('change')} - on:custom={(e) => gradio.dispatch('custom', e.detail)} - {enable_latex} - {latex_single_dollar_delimiter} - {latex_delimiters} - {sanitize_html} - {line_breaks} - {header_links} - /> -
    -
    - - diff --git a/frontend/legacy/Markdown/CHANGELOG.md b/frontend/legacy/Markdown/CHANGELOG.md deleted file mode 100644 index 06ddf27b..00000000 --- a/frontend/legacy/Markdown/CHANGELOG.md +++ /dev/null @@ -1,335 +0,0 @@ -# @modelscope-studio/legacy-markdown - -## 1.6.1 - -No significant changes to this package were made in this release. - -## 1.6.0 - -No significant changes to this package were made in this release. - -## 1.5.2 - -No significant changes to this package were made in this release. - -## 1.5.2 - -### Patch Changes - -- Updated dependencies [[`4888b2b`](https://github.com/modelscope/modelscope-studio/commit/4888b2b209b8758c92c33f932b61992c3fe4362a)]: - - @modelscope-studio/legacy-compiled@1.5.2 - -## 1.5.1 - -No significant changes to this package were made in this release. - -## 1.5.0 - -No significant changes to this package were made in this release. - -## 1.4.7 - -### Patch Changes - -- Updated dependencies [[`5af9cdc`](https://github.com/modelscope/modelscope-studio/commit/5af9cdcb011e3bda1ea9419f34cffd93b81590e7)]: - - @modelscope-studio/legacy-compiled@1.4.7 - -## 1.4.6 - -No significant changes to this package were made in this release. - -## 1.4.5 - -No significant changes to this package were made in this release. - -## 1.4.5 - -### Patch Changes - -- Updated dependencies [[`cb4a962`](https://github.com/modelscope/modelscope-studio/commit/cb4a9623833ec345e86a16d4e2f202e949c3875b)]: - - @modelscope-studio/legacy-compiled@1.4.5 - -## 1.4.4 - -No significant changes to this package were made in this release. - -## 1.4.4 - -### Patch Changes - -- Updated dependencies [[`6d9b760`](https://github.com/modelscope/modelscope-studio/commit/6d9b760ea3132be488155e67a1c816f260fa7e4c)]: - - @modelscope-studio/legacy-compiled@1.4.4 - -## 1.4.3 - -### Misc Changes - -- [#82](https://github.com/modelscope/modelscope-studio/pull/82) [`ca7519f`](https://github.com/modelscope/modelscope-studio/commit/ca7519f439e00e0d99d921e88ec38dc4689d7849) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.2 - -No significant changes to this package were made in this release. - -## 1.4.1 - -No significant changes to this package were made in this release. - -## 1.4.0 - -No significant changes to this package were made in this release. - -## 1.3.2 - -### Patch Changes - -- Updated dependencies [[`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861), [`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861)]: - - @modelscope-studio/legacy-compiled@1.3.2 - -## 1.3.1 - -No significant changes to this package were made in this release. - -## 1.3.0 - -No significant changes to this package were made in this release. - -## 1.2.5 - -### Patch Changes - -- Updated dependencies [[`d3259ab`](https://github.com/modelscope/modelscope-studio/commit/d3259abd179f7953b81f8d76c82cd2d3dd59766c)]: - - @modelscope-studio/legacy-compiled@1.2.5 - -## 1.2.4 - -No significant changes to this package were made in this release. - -## 1.2.3 - -No significant changes to this package were made in this release. - -## 1.2.3 - -### Patch Changes - -- Updated dependencies [[`034c4e3`](https://github.com/modelscope/modelscope-studio/commit/034c4e33ffa552e91d821171a68a1ab21eb35441)]: - - @modelscope-studio/legacy-compiled@1.2.3 - -## 1.2.2 - -No significant changes to this package were made in this release. - -## 1.2.1 - -No significant changes to this package were made in this release. - -## 1.2.0 - -No significant changes to this package were made in this release. - -## 1.1.7 - -No significant changes to this package were made in this release. - -## 1.1.6 - -No significant changes to this package were made in this release. - -## 1.1.5 - -No significant changes to this package were made in this release. - -## 1.1.5 - -### Patch Changes - -- Updated dependencies [[`4ab53e4`](https://github.com/modelscope/modelscope-studio/commit/4ab53e424c43a1db9d33b8883bb71a22cc59275b)]: - - @modelscope-studio/legacy-compiled@1.1.5 - -## 1.1.4 - -No significant changes to this package were made in this release. - -## 1.1.3 - -No significant changes to this package were made in this release. - -## 1.1.2 - -No significant changes to this package were made in this release. - -## 1.1.1 - -No significant changes to this package were made in this release. - -## 1.1.0 - -No significant changes to this package were made in this release. - -## 1.0.3 - -### Patch Changes - -- Updated dependencies [[`f4f8a15`](https://github.com/modelscope/modelscope-studio/commit/f4f8a155f30995984c5f46bdd638385c9a230856)]: - - @modelscope-studio/legacy-compiled@1.1.0 - -## 1.0.2 - -No significant changes to this package were made in this release. - -## 1.0.1 - -No significant changes to this package were made in this release. - -## 1.0.0 - -### Features - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Fixes - -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.11 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.10 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.9 - -### Fixes - -- [`e7fa278`](https://github.com/modelscope/modelscope-studio/commit/e7fa2782af83a7e78cddb700cd8d5e63ad62342f) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.8 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.8 - -### Patch Changes - -- Updated dependencies [[`a692793`](https://github.com/modelscope/modelscope-studio/commit/a6927930fa0cbb62b8e91d98fbfda7434586e758)]: - - @modelscope-studio/legacy-compiled@1.0.0-beta.8 - -## 1.0.0-beta.7 - -### Fixes - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.6 - -### Fixes - -- [`6a38225`](https://github.com/modelscope/modelscope-studio/commit/6a38225363c7db871c9593e524fe73ebebff1016) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.5 - -### Features - -- [`af9aa4f`](https://github.com/modelscope/modelscope-studio/commit/af9aa4fe598ae23dbe88163202aab2d44d5a133d) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.4 - -### Fixes - -- [`107d733`](https://github.com/modelscope/modelscope-studio/commit/107d733cb4ee01f346d165cbe192c514b38ac905) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.3 - -### Features - -- [`9f3c59c`](https://github.com/modelscope/modelscope-studio/commit/9f3c59c9c5a0bf8af3980588cb07a467323b1d17) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.2 - -### Features - -- [`9e5da52`](https://github.com/modelscope/modelscope-studio/commit/9e5da52fc739c6862225192fecf95f6bfd7923ad) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.1 - -### Features - -- [`025f728`](https://github.com/modelscope/modelscope-studio/commit/025f72825bdafbc60b4a09e577a363e43189bd1d) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.0 - -### Features - -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.2 - -### Fixes - -- [`c742328`](https://github.com/modelscope/modelscope-studio/commit/c742328f04992c5461211d8153f5166d784678ee) - gradio5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.1 - -No significant changes to this package were made in this release. - -## 0.5.1 - -### Patch Changes - -- Updated dependencies [[`fca4451`](https://github.com/modelscope/modelscope-studio/commit/fca4451f433294e074507c62b4f5af7c1fb89be5)]: - - @modelscope-studio/compiled@0.5.1 - - @modelscope-studio/shared@0.5.1 - -## 0.5.0 - -### Features - -- [`e271eb4`](https://github.com/modelscope/modelscope-studio/commit/e271eb493c98f1af0abf35d7109188fc7bf1e8c0) - support cutom latex delimiters in Markdown and Chatbot. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.4.2 - -No significant changes to this package were made in this release. - -## 0.4.1 - -No significant changes to this package were made in this release. - -## 0.4.0 - -No significant changes to this package were made in this release. - -## 0.3.1 - -No significant changes to this package were made in this release. - -## 0.3.0 - -### Features - -- [#20](https://github.com/modelscope/modelscope-studio/pull/20) [`9a5dd22`](https://github.com/modelscope/modelscope-studio/commit/9a5dd226ee117d6130baa87cacdf902546ad952a) - upload logic with new gradio version. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.1 - -No significant changes to this package were made in this release. - -## 0.2.1 - -### Patch Changes - -- Updated dependencies [[`68400a3`](https://github.com/modelscope/modelscope-studio/commit/68400a366d5a8af9a8d14f51577d8db1ebdcceb3)]: - - @modelscope-studio/legacy-compiled@0.2.1 - -## 0.2.0 - -### Features - -- [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`d1829d3`](https://github.com/modelscope/modelscope-studio/commit/d1829d34dd0bce8834d2e257b612d79705e57d6d) - update the timing of onMount call and new onUpdate lifecycle of custom component. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/legacy/Markdown/Example.svelte b/frontend/legacy/Markdown/Example.svelte deleted file mode 100644 index faeb8f69..00000000 --- a/frontend/legacy/Markdown/Example.svelte +++ /dev/null @@ -1,43 +0,0 @@ - - -
    - -
    - - diff --git a/frontend/legacy/Markdown/Index.svelte b/frontend/legacy/Markdown/Index.svelte deleted file mode 100644 index c60b47a2..00000000 --- a/frontend/legacy/Markdown/Index.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - - -{#await AwaitedMarkdown then Markdown} - - - -{/await} diff --git a/frontend/legacy/Markdown/gradio.config.js b/frontend/legacy/Markdown/gradio.config.js deleted file mode 100644 index abd9137f..00000000 --- a/frontend/legacy/Markdown/gradio.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../defineConfig.js'; - -export default config({ external: true }); diff --git a/frontend/legacy/Markdown/package.json b/frontend/legacy/Markdown/package.json deleted file mode 100644 index e9bdb4ca..00000000 --- a/frontend/legacy/Markdown/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@modelscope-studio/legacy-markdown", - "version": "1.6.1", - "private": false, - "description": "ModelScope Gradio Components", - "repository": "git@github.com:modelscope/modelscope-studio.git", - "license": "Apache-2.0", - "type": "module", - "exports": { - "./example": { - "default": "./Example.svelte", - "gradio": "./Example.svelte" - }, - ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" - }, - "./package.json": { - "default": "./package.json", - "gradio": "./package.json" - } - }, - "dependencies": { - "@modelscope-studio/legacy-compiled": "workspace:*" - }, - "devDependencies": {}, - "main_changeset": true -} diff --git a/frontend/legacy/Markdown/shared/Markdown.svelte b/frontend/legacy/Markdown/shared/Markdown.svelte deleted file mode 100644 index a3984cd4..00000000 --- a/frontend/legacy/Markdown/shared/Markdown.svelte +++ /dev/null @@ -1,84 +0,0 @@ - - -
    - -
    - - diff --git a/frontend/legacy/MultimodalInput/Awaited.svelte b/frontend/legacy/MultimodalInput/Awaited.svelte deleted file mode 100644 index d4ed4214..00000000 --- a/frontend/legacy/MultimodalInput/Awaited.svelte +++ /dev/null @@ -1,305 +0,0 @@ - - - - - - - - {#if loading_status} - - {/if} - {#if show_label && label} - {label} - {/if} -
    - { - value.text = e.detail; - gradio.dispatch('change', value); - }} - on:input={() => gradio.dispatch('input')} - on:submit={() => { - if (uploading) { - return; - } - gradio.dispatch('submit'); - }} - on:blur={() => gradio.dispatch('blur')} - on:select={(e) => gradio.dispatch('select', e.detail)} - on:focus={() => gradio.dispatch('focus')} - disabled={!interactive} - /> -
    -
    - - {#each _sources as source, i (i)} - {#if source === 'upload'} - - { - if (_upload_button_props.file_count === 'single') { - value.files = e.detail; - } else { - value.files = [...value.files, ...e.detail]; - } - gradio.dispatch('upload'); - gradio.dispatch('change', value); - }} - on:click - /> - - {:else if source === 'microphone'} - - { - gradio.dispatch('error', e.detail); - }} - on:change={(e) => { - if (_upload_button_props.file_count === 'single') { - value.files = [e.detail]; - } else { - value.files = [...value.files, e.detail]; - } - gradio.dispatch('upload'); - gradio.dispatch('change', value); - }} - /> - - {:else if source === 'webcam'} - - { - gradio.dispatch('error', e.detail); - }} - on:change={(e) => { - if (_upload_button_props.file_count === 'single') { - value.files = [e.detail]; - } else { - value.files = [...value.files, e.detail]; - } - gradio.dispatch('upload'); - gradio.dispatch('change', value); - }} - /> - - {/if} - {/each} - - - gradio.dispatch('submit')} - /> - -
    - {#if value.files?.length} - { - value.files = value.files.filter((_, i) => i !== e.detail); - gradio.dispatch('change', value); - }} - loading={uploading} - theme={gradio.theme} - i18n={gradio.i18n} - value={value.files} - props={_file_preview_props} - disabled={!interactive} - /> - {/if} -
    - - diff --git a/frontend/legacy/MultimodalInput/CHANGELOG.md b/frontend/legacy/MultimodalInput/CHANGELOG.md deleted file mode 100644 index aa0ed509..00000000 --- a/frontend/legacy/MultimodalInput/CHANGELOG.md +++ /dev/null @@ -1,338 +0,0 @@ -# @modelscope-studio/legacy-multimodal-input - -## 1.6.1 - -No significant changes to this package were made in this release. - -## 1.6.0 - -No significant changes to this package were made in this release. - -## 1.5.2 - -No significant changes to this package were made in this release. - -## 1.5.2 - -### Patch Changes - -- Updated dependencies [[`4888b2b`](https://github.com/modelscope/modelscope-studio/commit/4888b2b209b8758c92c33f932b61992c3fe4362a)]: - - @modelscope-studio/legacy-compiled@1.5.2 - -## 1.5.1 - -No significant changes to this package were made in this release. - -## 1.5.0 - -No significant changes to this package were made in this release. - -## 1.4.7 - -### Patch Changes - -- Updated dependencies [[`5af9cdc`](https://github.com/modelscope/modelscope-studio/commit/5af9cdcb011e3bda1ea9419f34cffd93b81590e7)]: - - @modelscope-studio/legacy-compiled@1.4.7 - -## 1.4.6 - -No significant changes to this package were made in this release. - -## 1.4.5 - -### Misc Changes - -- [#87](https://github.com/modelscope/modelscope-studio/pull/87) [`cb4a962`](https://github.com/modelscope/modelscope-studio/commit/cb4a9623833ec345e86a16d4e2f202e949c3875b) - upgrade to antd 5.27.0, antdx 1.6.0. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.4 - -No significant changes to this package were made in this release. - -## 1.4.4 - -### Patch Changes - -- Updated dependencies [[`6d9b760`](https://github.com/modelscope/modelscope-studio/commit/6d9b760ea3132be488155e67a1c816f260fa7e4c)]: - - @modelscope-studio/legacy-compiled@1.4.4 - -## 1.4.3 - -### Misc Changes - -- [#82](https://github.com/modelscope/modelscope-studio/pull/82) [`ca7519f`](https://github.com/modelscope/modelscope-studio/commit/ca7519f439e00e0d99d921e88ec38dc4689d7849) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.2 - -No significant changes to this package were made in this release. - -## 1.4.1 - -No significant changes to this package were made in this release. - -## 1.4.0 - -No significant changes to this package were made in this release. - -## 1.3.2 - -### Patch Changes - -- Updated dependencies [[`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861), [`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861)]: - - @modelscope-studio/legacy-compiled@1.3.2 - -## 1.3.1 - -No significant changes to this package were made in this release. - -## 1.3.0 - -No significant changes to this package were made in this release. - -## 1.2.5 - -### Patch Changes - -- Updated dependencies [[`d3259ab`](https://github.com/modelscope/modelscope-studio/commit/d3259abd179f7953b81f8d76c82cd2d3dd59766c)]: - - @modelscope-studio/legacy-compiled@1.2.5 - -## 1.2.4 - -No significant changes to this package were made in this release. - -## 1.2.3 - -No significant changes to this package were made in this release. - -## 1.2.3 - -### Patch Changes - -- Updated dependencies [[`034c4e3`](https://github.com/modelscope/modelscope-studio/commit/034c4e33ffa552e91d821171a68a1ab21eb35441)]: - - @modelscope-studio/legacy-compiled@1.2.3 - -## 1.2.2 - -### Features - -- [#67](https://github.com/modelscope/modelscope-studio/pull/67) [`f7edea8`](https://github.com/modelscope/modelscope-studio/commit/f7edea8a448f05dd69fa121d913dd16e159dcedd) - add `file_type` property for Webcam. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.2.1 - -No significant changes to this package were made in this release. - -## 1.2.0 - -No significant changes to this package were made in this release. - -## 1.1.7 - -No significant changes to this package were made in this release. - -## 1.1.6 - -No significant changes to this package were made in this release. - -## 1.1.5 - -No significant changes to this package were made in this release. - -## 1.1.5 - -### Patch Changes - -- Updated dependencies [[`4ab53e4`](https://github.com/modelscope/modelscope-studio/commit/4ab53e424c43a1db9d33b8883bb71a22cc59275b)]: - - @modelscope-studio/legacy-compiled@1.1.5 - -## 1.1.4 - -No significant changes to this package were made in this release. - -## 1.1.3 - -No significant changes to this package were made in this release. - -## 1.1.2 - -No significant changes to this package were made in this release. - -## 1.1.1 - -No significant changes to this package were made in this release. - -## 1.1.0 - -No significant changes to this package were made in this release. - -## 1.0.3 - -### Patch Changes - -- Updated dependencies [[`f4f8a15`](https://github.com/modelscope/modelscope-studio/commit/f4f8a155f30995984c5f46bdd638385c9a230856)]: - - @modelscope-studio/legacy-compiled@1.1.0 - -## 1.0.2 - -No significant changes to this package were made in this release. - -## 1.0.1 - -No significant changes to this package were made in this release. - -## 1.0.0 - -### Features - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Fixes - -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.11 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.10 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.9 - -### Fixes - -- [`e7fa278`](https://github.com/modelscope/modelscope-studio/commit/e7fa2782af83a7e78cddb700cd8d5e63ad62342f) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.8 - -### Fixes - -- [`a692793`](https://github.com/modelscope/modelscope-studio/commit/a6927930fa0cbb62b8e91d98fbfda7434586e758) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.7 - -### Fixes - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.6 - -### Fixes - -- [`6a38225`](https://github.com/modelscope/modelscope-studio/commit/6a38225363c7db871c9593e524fe73ebebff1016) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.5 - -### Features - -- [`af9aa4f`](https://github.com/modelscope/modelscope-studio/commit/af9aa4fe598ae23dbe88163202aab2d44d5a133d) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.4 - -### Fixes - -- [`107d733`](https://github.com/modelscope/modelscope-studio/commit/107d733cb4ee01f346d165cbe192c514b38ac905) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.3 - -### Features - -- [`9f3c59c`](https://github.com/modelscope/modelscope-studio/commit/9f3c59c9c5a0bf8af3980588cb07a467323b1d17) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.2 - -### Features - -- [`9e5da52`](https://github.com/modelscope/modelscope-studio/commit/9e5da52fc739c6862225192fecf95f6bfd7923ad) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.1 - -### Features - -- [`025f728`](https://github.com/modelscope/modelscope-studio/commit/025f72825bdafbc60b4a09e577a363e43189bd1d) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.0 - -### Features - -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.2 - -No significant changes to this package were made in this release. - -## 0.5.2 - -### Patch Changes - -- Updated dependencies [[`c742328`](https://github.com/modelscope/modelscope-studio/commit/c742328f04992c5461211d8153f5166d784678ee)]: - - @modelscope-studio/shared@0.5.2 - -## 0.5.1 - -No significant changes to this package were made in this release. - -## 0.5.1 - -### Patch Changes - -- Updated dependencies [[`fca4451`](https://github.com/modelscope/modelscope-studio/commit/fca4451f433294e074507c62b4f5af7c1fb89be5)]: - - @modelscope-studio/compiled@0.5.1 - - @modelscope-studio/shared@0.5.1 - -## 0.5.0 - -No significant changes to this package were made in this release. - -## 0.4.3 - -### Patch Changes - -- Updated dependencies [[`e271eb4`](https://github.com/modelscope/modelscope-studio/commit/e271eb493c98f1af0abf35d7109188fc7bf1e8c0)]: - - @modelscope-studio/compiled@0.5.0 - -## 0.4.2 - -No significant changes to this package were made in this release. - -## 0.4.1 - -### Fixes - -- [#27](https://github.com/modelscope/modelscope-studio/pull/27) [`62fe3f6`](https://github.com/modelscope/modelscope-studio/commit/62fe3f6410bce8403da6f92b6ab567644ff4656b) - audio recorder of MultimodalInput. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.4.0 - -No significant changes to this package were made in this release. - -## 0.3.1 - -No significant changes to this package were made in this release. - -## 0.3.0 - -### Features - -- [#20](https://github.com/modelscope/modelscope-studio/pull/20) [`9a5dd22`](https://github.com/modelscope/modelscope-studio/commit/9a5dd226ee117d6130baa87cacdf902546ad952a) - upload logic with new gradio version. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.1 - -No significant changes to this package were made in this release. - -## 0.2.1 - -### Patch Changes - -- Updated dependencies [[`68400a3`](https://github.com/modelscope/modelscope-studio/commit/68400a366d5a8af9a8d14f51577d8db1ebdcceb3)]: - - @modelscope-studio/legacy-compiled@0.2.1 - -## 0.2.0 - -No significant changes to this package were made in this release. diff --git a/frontend/legacy/MultimodalInput/Example.svelte b/frontend/legacy/MultimodalInput/Example.svelte deleted file mode 100644 index c39e544e..00000000 --- a/frontend/legacy/MultimodalInput/Example.svelte +++ /dev/null @@ -1,71 +0,0 @@ - - -
    - {value.text} - {#if value.files?.length > 0} - - - - - {value.files.map((file) => file.orig_name).join(', ')} - - {/if} -
    - - diff --git a/frontend/legacy/MultimodalInput/Index.svelte b/frontend/legacy/MultimodalInput/Index.svelte deleted file mode 100644 index 2a27f751..00000000 --- a/frontend/legacy/MultimodalInput/Index.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - - -{#await AwaitedMultimodalInput then MultimodalInput} - - - -{/await} diff --git a/frontend/legacy/MultimodalInput/gradio.config.js b/frontend/legacy/MultimodalInput/gradio.config.js deleted file mode 100644 index abd9137f..00000000 --- a/frontend/legacy/MultimodalInput/gradio.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../defineConfig.js'; - -export default config({ external: true }); diff --git a/frontend/legacy/MultimodalInput/package.json b/frontend/legacy/MultimodalInput/package.json deleted file mode 100644 index 4b69c129..00000000 --- a/frontend/legacy/MultimodalInput/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@modelscope-studio/legacy-multimodal-input", - "version": "1.6.1", - "private": false, - "description": "ModelScope Gradio Components", - "repository": "git@github.com:modelscope/modelscope-studio.git", - "license": "Apache-2.0", - "type": "module", - "exports": { - "./example": { - "default": "./Example.svelte", - "gradio": "./Example.svelte" - }, - ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" - }, - "./package.json": { - "default": "./package.json", - "gradio": "./package.json" - } - }, - "dependencies": { - "@modelscope-studio/legacy-compiled": "workspace:*" - }, - "devDependencies": {}, - "main_changeset": true -} diff --git a/frontend/legacy/MultimodalInput/shared/AudioRecorder.svelte b/frontend/legacy/MultimodalInput/shared/AudioRecorder.svelte deleted file mode 100644 index 11643cae..00000000 --- a/frontend/legacy/MultimodalInput/shared/AudioRecorder.svelte +++ /dev/null @@ -1,378 +0,0 @@ - - -
    - -
    -
    -
    - {#if timing} - - - - {:else} - - {/if} -
    - -
    - -
    - - diff --git a/frontend/legacy/MultimodalInput/shared/FilePreview.svelte b/frontend/legacy/MultimodalInput/shared/FilePreview.svelte deleted file mode 100644 index d782aafc..00000000 --- a/frontend/legacy/MultimodalInput/shared/FilePreview.svelte +++ /dev/null @@ -1,177 +0,0 @@ - - -
    - {#if loading} - - {/if} - - - {#each normalized_files as file, i ((file.url || file.orig_name || '') + i)} - - dispatch('select', { - value: file.orig_name, - index: i, - })} - > - - - - - - {/each} - -
    - - - {#if file.url} - - {@html file.size != null - ? prettyBytes(file.size) - : '(size unknown)'} ⇣ - - {:else} - {i18n('file.uploading')} - {/if} - - { - dispatch('delete', i); - }} - /> -
    -
    - - diff --git a/frontend/legacy/MultimodalInput/shared/Input.svelte b/frontend/legacy/MultimodalInput/shared/Input.svelte deleted file mode 100644 index 5f76e1ac..00000000 --- a/frontend/legacy/MultimodalInput/shared/Input.svelte +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - diff --git a/frontend/legacy/MultimodalInput/shared/Loader.svelte b/frontend/legacy/MultimodalInput/shared/Loader.svelte deleted file mode 100644 index 22bfe237..00000000 --- a/frontend/legacy/MultimodalInput/shared/Loader.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - - v} - autoscroll={false} - timer={false} - loading_text="" - status="pending" -/> diff --git a/frontend/legacy/MultimodalInput/shared/RemoveIcon.svelte b/frontend/legacy/MultimodalInput/shared/RemoveIcon.svelte deleted file mode 100644 index 027c5c5f..00000000 --- a/frontend/legacy/MultimodalInput/shared/RemoveIcon.svelte +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/frontend/legacy/MultimodalInput/shared/SubmitButton.svelte b/frontend/legacy/MultimodalInput/shared/SubmitButton.svelte deleted file mode 100644 index 31708548..00000000 --- a/frontend/legacy/MultimodalInput/shared/SubmitButton.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - - dispatch('click')} - disabled={disabled || props.disabled} -> - {i18n(props.value || props.label || 'common.submit')} - diff --git a/frontend/legacy/MultimodalInput/shared/UploadButton.svelte b/frontend/legacy/MultimodalInput/shared/UploadButton.svelte deleted file mode 100644 index 74d792c2..00000000 --- a/frontend/legacy/MultimodalInput/shared/UploadButton.svelte +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - {#if !props.icon} - - - - {/if} - {i18n(props.label || 'upload_text.click_to_upload')} - - - diff --git a/frontend/legacy/MultimodalInput/shared/UploadIcon.svelte b/frontend/legacy/MultimodalInput/shared/UploadIcon.svelte deleted file mode 100644 index 276ff100..00000000 --- a/frontend/legacy/MultimodalInput/shared/UploadIcon.svelte +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/frontend/legacy/MultimodalInput/shared/Webcam.svelte b/frontend/legacy/MultimodalInput/shared/Webcam.svelte deleted file mode 100644 index 04afc230..00000000 --- a/frontend/legacy/MultimodalInput/shared/Webcam.svelte +++ /dev/null @@ -1,491 +0,0 @@ - - - - -
    - - -
    -
    -
    - - -
    -
    - - diff --git a/frontend/legacy/MultimodalInput/shared/context.ts b/frontend/legacy/MultimodalInput/shared/context.ts deleted file mode 100644 index 78615988..00000000 --- a/frontend/legacy/MultimodalInput/shared/context.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { type FileData } from '@gradio/client'; -import { getContext, setContext } from 'svelte'; - -const context_key = {}; - -export interface ContextValue { - upload: (files: File[]) => Promise; -} -export const setContextValue = (value: ContextValue) => - setContext(context_key, value); -export const getContextValue = () => getContext(context_key); diff --git a/frontend/legacy/MultimodalInput/shared/global.d.ts b/frontend/legacy/MultimodalInput/shared/global.d.ts deleted file mode 100644 index ef691799..00000000 --- a/frontend/legacy/MultimodalInput/shared/global.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare namespace svelteHTML { - interface HTMLAttributes { - webkitdirectory?: boolean | string; - mozdirectory?: boolean | string; - } -} diff --git a/frontend/legacy/MultimodalInput/shared/utils.ts b/frontend/legacy/MultimodalInput/shared/utils.ts deleted file mode 100644 index 64041d0f..00000000 --- a/frontend/legacy/MultimodalInput/shared/utils.ts +++ /dev/null @@ -1,117 +0,0 @@ -import type { FileData } from '@gradio/client'; - -export interface MutilmodalInputData { - text: string; - files: FileData[]; -} - -export const prettyBytes = (bytes: number): string => { - const units = ['B', 'KB', 'MB', 'GB', 'PB']; - let i = 0; - while (bytes > 1024) { - bytes /= 1024; - i++; - } - const unit = units[i]; - return bytes.toFixed(1) + ' ' + unit; -}; - -export function audioBufferToWav( - audioBuffer: AudioBuffer -): Uint8Array { - // Write WAV header - const writeString = function ( - view: DataView, - offset: number, - string: string - ): void { - for (let i = 0; i < string.length; i++) { - view.setUint8(offset + i, string.charCodeAt(i)); - } - }; - - const numOfChan = audioBuffer.numberOfChannels; - const length = audioBuffer.length * numOfChan * 2 + 44; - const buffer = new ArrayBuffer(length); - const view = new DataView(buffer); - let offset = 0; - - writeString(view, offset, 'RIFF'); - offset += 4; - view.setUint32(offset, length - 8, true); - offset += 4; - writeString(view, offset, 'WAVE'); - offset += 4; - writeString(view, offset, 'fmt '); - offset += 4; - view.setUint32(offset, 16, true); - offset += 4; // Sub-chunk size, 16 for PCM - view.setUint16(offset, 1, true); - offset += 2; // PCM format - view.setUint16(offset, numOfChan, true); - offset += 2; - view.setUint32(offset, audioBuffer.sampleRate, true); - offset += 4; - view.setUint32(offset, audioBuffer.sampleRate * 2 * numOfChan, true); - offset += 4; - view.setUint16(offset, numOfChan * 2, true); - offset += 2; - view.setUint16(offset, 16, true); - offset += 2; - writeString(view, offset, 'data'); - offset += 4; - view.setUint32(offset, audioBuffer.length * numOfChan * 2, true); - offset += 4; - - // Write PCM audio data - for (let i = 0; i < audioBuffer.numberOfChannels; i++) { - const channel = audioBuffer.getChannelData(i); - for (let j = 0; j < channel.length; j++) { - view.setInt16(offset, channel[j] * 0xffff, true); - offset += 2; - } - } - - return new Uint8Array(buffer); -} - -export const process_audio = ( - audioBuffer: AudioBuffer, - start?: number, - end?: number -): Promise> => { - const audioContext = new AudioContext(); - const numberOfChannels = audioBuffer.numberOfChannels; - const sampleRate = audioBuffer.sampleRate; - - let trimmedLength = audioBuffer.length; - let startOffset = 0; - - if (start && end) { - startOffset = Math.round(start * sampleRate); - const endOffset = Math.round(end * sampleRate); - trimmedLength = endOffset - startOffset; - } - - const trimmedAudioBuffer = audioContext.createBuffer( - numberOfChannels, - trimmedLength, - sampleRate - ); - - for (let channel = 0; channel < numberOfChannels; channel++) { - const channelData = audioBuffer.getChannelData(channel); - const trimmedData = trimmedAudioBuffer.getChannelData(channel); - for (let i = 0; i < trimmedLength; i++) { - trimmedData[i] = channelData[startOffset + i]; - } - } - - return Promise.resolve(audioBufferToWav(trimmedAudioBuffer)); -}; -export const format_time = (time: number): string => { - const minutes = Math.floor(time / 60); - const secondsRemainder = Math.round(time) % 60; - const paddedSeconds = `0${secondsRemainder}`.slice(-2); - return `${minutes}:${paddedSeconds}`; -}; diff --git a/frontend/legacy/WaterfallGallery/CHANGELOG.md b/frontend/legacy/WaterfallGallery/CHANGELOG.md deleted file mode 100644 index ad0500cf..00000000 --- a/frontend/legacy/WaterfallGallery/CHANGELOG.md +++ /dev/null @@ -1,238 +0,0 @@ -# @modelscope-studio/legacy-waterfall-gallery - -## 1.6.1 - -No significant changes to this package were made in this release. - -## 1.6.0 - -No significant changes to this package were made in this release. - -## 1.5.2 - -No significant changes to this package were made in this release. - -## 1.5.1 - -No significant changes to this package were made in this release. - -## 1.5.0 - -No significant changes to this package were made in this release. - -## 1.4.6 - -No significant changes to this package were made in this release. - -## 1.4.5 - -No significant changes to this package were made in this release. - -## 1.4.4 - -No significant changes to this package were made in this release. - -## 1.4.3 - -### Misc Changes - -- [#82](https://github.com/modelscope/modelscope-studio/pull/82) [`ca7519f`](https://github.com/modelscope/modelscope-studio/commit/ca7519f439e00e0d99d921e88ec38dc4689d7849) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.2 - -No significant changes to this package were made in this release. - -## 1.4.1 - -No significant changes to this package were made in this release. - -## 1.4.0 - -No significant changes to this package were made in this release. - -## 1.3.1 - -No significant changes to this package were made in this release. - -## 1.3.0 - -No significant changes to this package were made in this release. - -## 1.2.4 - -No significant changes to this package were made in this release. - -## 1.2.3 - -### Features - -- [#68](https://github.com/modelscope/modelscope-studio/pull/68) [`034c4e3`](https://github.com/modelscope/modelscope-studio/commit/034c4e33ffa552e91d821171a68a1ab21eb35441) - update deps, antdx 1.0.5 => 1.1.0. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.2.2 - -No significant changes to this package were made in this release. - -## 1.2.1 - -No significant changes to this package were made in this release. - -## 1.2.0 - -No significant changes to this package were made in this release. - -## 1.1.7 - -No significant changes to this package were made in this release. - -## 1.1.6 - -No significant changes to this package were made in this release. - -## 1.1.5 - -No significant changes to this package were made in this release. - -## 1.1.4 - -No significant changes to this package were made in this release. - -## 1.1.3 - -No significant changes to this package were made in this release. - -## 1.1.2 - -No significant changes to this package were made in this release. - -## 1.1.1 - -No significant changes to this package were made in this release. - -## 1.1.0 - -No significant changes to this package were made in this release. - -## 1.0.2 - -No significant changes to this package were made in this release. - -## 1.0.1 - -No significant changes to this package were made in this release. - -## 1.0.0 - -### Features - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Fixes - -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.11 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.10 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.9 - -### Fixes - -- [`e7fa278`](https://github.com/modelscope/modelscope-studio/commit/e7fa2782af83a7e78cddb700cd8d5e63ad62342f) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.8 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.7 - -### Fixes - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.6 - -### Fixes - -- [`6a38225`](https://github.com/modelscope/modelscope-studio/commit/6a38225363c7db871c9593e524fe73ebebff1016) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.5 - -### Features - -- [`af9aa4f`](https://github.com/modelscope/modelscope-studio/commit/af9aa4fe598ae23dbe88163202aab2d44d5a133d) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.4 - -### Fixes - -- [`107d733`](https://github.com/modelscope/modelscope-studio/commit/107d733cb4ee01f346d165cbe192c514b38ac905) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.3 - -### Features - -- [`9f3c59c`](https://github.com/modelscope/modelscope-studio/commit/9f3c59c9c5a0bf8af3980588cb07a467323b1d17) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.2 - -### Features - -- [`9e5da52`](https://github.com/modelscope/modelscope-studio/commit/9e5da52fc739c6862225192fecf95f6bfd7923ad) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.1 - -### Features - -- [`025f728`](https://github.com/modelscope/modelscope-studio/commit/025f72825bdafbc60b4a09e577a363e43189bd1d) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.0 - -### Features - -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.0 - -No significant changes to this package were made in this release. - -## 0.4.2 - -No significant changes to this package were made in this release. - -## 0.4.1 - -No significant changes to this package were made in this release. - -## 0.4.0 - -No significant changes to this package were made in this release. - -## 0.3.1 - -No significant changes to this package were made in this release. - -## 0.3.0 - -### Features - -- [#20](https://github.com/modelscope/modelscope-studio/pull/20) [`9a5dd22`](https://github.com/modelscope/modelscope-studio/commit/9a5dd226ee117d6130baa87cacdf902546ad952a) - upload logic with new gradio version. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.1 - -No significant changes to this package were made in this release. - -## 0.2.0 - -No significant changes to this package were made in this release. diff --git a/frontend/legacy/WaterfallGallery/Index.svelte b/frontend/legacy/WaterfallGallery/Index.svelte deleted file mode 100644 index 12a18bd5..00000000 --- a/frontend/legacy/WaterfallGallery/Index.svelte +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - {#if loading_status} - - {/if} - gradio.dispatch('click', e.detail)} - on:change={() => gradio.dispatch('change', value)} - on:like={(e) => handle_like(e.detail)} - on:select={(e) => gradio.dispatch('select', e.detail)} - on:share={(e) => gradio.dispatch('share', e.detail)} - on:error={(e) => gradio.dispatch('error', e.detail)} - on:load_more={() => { - gradio.dispatch('load_more', value); - }} - pending={loading_status?.status === 'pending'} - {likeable} - {clickable} - {label} - {action_label} - {value} - {root} - {proxy_url} - {show_label} - {object_fit} - load_more_button_props={_load_more_button_props} - {has_more} - {columns} - {height} - {preview} - {gap} - {allow_preview} - bind:selected_index - {show_share_button} - {show_download_button} - i18n={gradio.i18n} - /> - diff --git a/frontend/legacy/WaterfallGallery/gradio.config.js b/frontend/legacy/WaterfallGallery/gradio.config.js deleted file mode 100644 index abd9137f..00000000 --- a/frontend/legacy/WaterfallGallery/gradio.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../defineConfig.js'; - -export default config({ external: true }); diff --git a/frontend/legacy/WaterfallGallery/package.json b/frontend/legacy/WaterfallGallery/package.json deleted file mode 100644 index 9ba626cc..00000000 --- a/frontend/legacy/WaterfallGallery/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@modelscope-studio/legacy-waterfall-gallery", - "version": "1.6.1", - "description": "ModelScope Gradio Components", - "repository": "git@github.com:modelscope/modelscope-studio.git", - "license": "Apache-2.0", - "author": "", - "type": "module", - "exports": { - ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" - }, - "./package.json": { - "default": "./package.json", - "gradio": "./package.json" - } - }, - "main_changeset": true -} diff --git a/frontend/legacy/WaterfallGallery/shared/Dislike.svelte b/frontend/legacy/WaterfallGallery/shared/Dislike.svelte deleted file mode 100644 index e756b213..00000000 --- a/frontend/legacy/WaterfallGallery/shared/Dislike.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/frontend/legacy/WaterfallGallery/shared/Gallery.svelte b/frontend/legacy/WaterfallGallery/shared/Gallery.svelte deleted file mode 100644 index 17a874b4..00000000 --- a/frontend/legacy/WaterfallGallery/shared/Gallery.svelte +++ /dev/null @@ -1,601 +0,0 @@ - - - - -{#if show_label} - -{/if} -{#if !value || !resolved_value || resolved_value.length === 0} - -{:else} - {#if selected_image && allow_preview} - - {#if selected_image?.caption} - - {selected_image.caption} - - {/if} -
    - {#each resolved_value as entry, i (i)} - - {/each} -
    - - {/if} -
    -
    - {#if show_share_button} -
    - { - copy_to_clipboard(e.detail.description); - }} - on:error - value={resolved_value} - formatter={format_gallery_for_sharing} - /> -
    - {/if} -
    - {#each resolved_value as entry, i (i)} -
    - (selected_index = i)} - on:label_click={() => { - dispatch('click', { - index: i, - value: entry, - }); - }} - on:like={(e) => { - dispatch('like', { - index: i, - value: entry, - liked: e.detail, - }); - }} - {action_label} - /> -
    - {/each} -
    -
    -

    - {#if pending} - - {:else} - { - dispatch('load_more'); - }} - > - {i18n( - load_more_button_props.value || - load_more_button_props.label || - 'Load More' - )} - {/if} -

    -
    -{/if} - - diff --git a/frontend/legacy/WaterfallGallery/shared/Image.svelte b/frontend/legacy/WaterfallGallery/shared/Image.svelte deleted file mode 100644 index d734b340..00000000 --- a/frontend/legacy/WaterfallGallery/shared/Image.svelte +++ /dev/null @@ -1,152 +0,0 @@ - - - - -
    - - - dispatch('click')} - alt={value.caption || ''} - src={value.image.url} - class="thumbnail-img" - loading="lazy" - /> - - {#if value.caption} -
    - {value.caption} -
    - {/if} - - {#if clickable} - - {/if} - {#if likeable} - - {/if} -
    - - diff --git a/frontend/legacy/WaterfallGallery/shared/Waterfall/createWaterfall.ts b/frontend/legacy/WaterfallGallery/shared/Waterfall/createWaterfall.ts deleted file mode 100644 index 1eb3300f..00000000 --- a/frontend/legacy/WaterfallGallery/shared/Waterfall/createWaterfall.ts +++ /dev/null @@ -1,121 +0,0 @@ -import type { WaterfallOptions } from './layout'; -import { waterfall_layout } from './layout'; - -export const isElement = (el: Node): el is Element => el.nodeType == 1; - -const heightSymbol = Symbol(); -const widthSymbol = Symbol(); - -interface LayoutObserverElement extends HTMLElement { - [widthSymbol]?: number; - [heightSymbol]?: number; -} - -/** - * layout observer - * @example - * const layout = createLayoutObserver(div, () => console.log('layout changed')) - * layout.mount() - */ -export function createLayoutObserver( - el: LayoutObserverElement, - rerender: () => void -) { - let sizeObserver: ResizeObserver; // size changes - let childrenObserver: MutationObserver; // element changes - - let isLayingOut = false; - - function layout() { - if (isLayingOut) return; - isLayingOut = true; - requestAnimationFrame(() => { - rerender(); - el[widthSymbol] = el.offsetWidth; - el[heightSymbol] = el.offsetHeight; - isLayingOut = false; - }); - } - - function mount() { - if (!el) return; - sizeObserver = new ResizeObserver((entries) => { - if ( - entries.some((entry) => { - const target = entry.target as LayoutObserverElement; - return ( - target[widthSymbol] !== target.offsetWidth || - target[heightSymbol] !== target.offsetHeight - ); - }) - ) { - layout(); - } - }); - - sizeObserver.observe(el); - - Array.from(el.children).forEach((child) => { - sizeObserver.observe(child); - }); - - childrenObserver = new MutationObserver((entries) => { - entries.forEach((entry) => { - entry.addedNodes.forEach( - (node) => isElement(node) && sizeObserver.observe(node) - ); - entry.removedNodes.forEach( - (node) => isElement(node) && sizeObserver.unobserve(node) - ); - }); - layout(); - }); - childrenObserver.observe(el, { childList: true, attributes: false }); - - layout(); - } - - function unmount() { - sizeObserver?.disconnect(); - childrenObserver?.disconnect(); - } - - return { layout, mount, unmount }; -} - -/** - * waterfall layout - * - * @example - * const layout = createWaterfall(div, { cols: 4, gap: 4 }) - * layout.mount() - */ -export const createWaterfall = (el: HTMLElement, options: WaterfallOptions) => - createLayoutObserver(el, () => { - waterfall_layout( - el as LayoutObserverElement, - { - getWidth: (element) => element.offsetWidth, - setWidth: (element, v) => (element.style.width = v + 'px'), - getHeight: (element) => ( - (element[widthSymbol] = element.offsetWidth), - (element[heightSymbol] = element.offsetHeight) - ), - setHeight: (element, v) => (element.style.height = v + 'px'), - getPadding: (element) => { - const pad = getComputedStyle(element); - return [ - parseInt(pad.paddingTop), - parseInt(pad.paddingRight), - parseInt(pad.paddingBottom), - parseInt(pad.paddingLeft), - ]; - }, - setX: (element, v) => (element.style.left = v + 'px'), - setY: (element, v) => (element.style.top = v + 'px'), - getChildren: (element) => - Array.from(element.children) as LayoutObserverElement[], - }, - options - ); - }); diff --git a/frontend/legacy/WaterfallGallery/shared/Waterfall/index.ts b/frontend/legacy/WaterfallGallery/shared/Waterfall/index.ts deleted file mode 100644 index 93518af5..00000000 --- a/frontend/legacy/WaterfallGallery/shared/Waterfall/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createWaterfall } from './createWaterfall'; -import type { WaterfallOptions } from './layout'; - -export class Waterfall { - _layout: ReturnType; - - constructor( - el: HTMLElement, - options: WaterfallOptions = { - cols: 2, - gap: 4, - } - ) { - this._layout = createWaterfall(el, options); - this._layout.mount(); - } - - unmount() { - this._layout.unmount(); - } - - render() { - this._layout.layout(); - } -} diff --git a/frontend/legacy/WaterfallGallery/shared/Waterfall/layout.ts b/frontend/legacy/WaterfallGallery/shared/Waterfall/layout.ts deleted file mode 100644 index 85d3c9db..00000000 --- a/frontend/legacy/WaterfallGallery/shared/Waterfall/layout.ts +++ /dev/null @@ -1,70 +0,0 @@ -export function minIndex(arr: number[]) { - let acc = 0; - for (let i = 0; i < arr.length; i++) acc = arr[acc] <= arr[i] ? acc : i; - return acc; -} - -export interface WaterfallOptions { - cols: number; - gap: number | [width: number, height: number]; -} - -export interface WaterfallEvents { - // w - getWidth(el: T): number; - setWidth(el: T, v: number): void; - // h - getHeight(el: T): number; - setHeight(el: T, v: number): void; - // padding - getPadding(el: T): [number, number, number, number]; - // xy - setX(el: T, v: number): void; - setY(el: T, v: number): void; - // children - getChildren(el: T): T[]; -} - -export function waterfall_layout( - container: T, - { - getWidth, - setWidth, - getHeight, - setHeight, - getPadding, - setX, - setY, - getChildren, - }: WaterfallEvents, - { cols, gap }: WaterfallOptions -) { - const [pt, pr, pb, pl] = getPadding(container); - const children = getChildren(container); - const len = children.length; - const [widthGap, heightGap] = Array.isArray(gap) ? gap : [gap, gap]; - - if (len) { - const width = - (getWidth(container) - widthGap * (cols - 1) - (pl + pr)) / cols; - children.forEach((el) => { - setWidth(el, width); - }); - - const childrenHeights = children.map((el) => getHeight(el)); - - const stack = Array(cols).fill(pt); - - for (let i = 0; i < len; i++) { - const el = children[i]; - const col = minIndex(stack); - setY(el, stack[col]); - setX(el, pl + (width + widthGap) * col); - stack[col] += childrenHeights[i] + heightGap; - } - - setHeight(container, Math.max(...stack) - heightGap + pb); - } else { - setHeight(container, pt + pb); - } -} diff --git a/frontend/legacy/WaterfallGallery/shared/utils.ts b/frontend/legacy/WaterfallGallery/shared/utils.ts deleted file mode 100644 index 295651f4..00000000 --- a/frontend/legacy/WaterfallGallery/shared/utils.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { FileData } from '@gradio/client'; - -export interface GalleryImage { - image: FileData; - caption?: string | null; - liked?: boolean; - meta?: any; -} -export type GalleryData = GalleryImage[]; - -export interface Breakpoints { - xs?: number; - sm?: number; - md?: number; - lg?: number; - xl?: number; - xxl?: number; -} -export const breakpoints: { key: keyof Breakpoints; width: number }[] = [ - { - key: 'xs', - width: 0, - }, - { - key: 'sm', - width: 576, - }, - { - key: 'md', - width: 768, - }, - { - key: 'lg', - width: 992, - }, - { - key: 'xl', - width: 1200, - }, - { - key: 'xxl', - width: 1600, - }, -]; - -export async function copy_to_clipboard(value: string) { - if ('clipboard' in navigator) { - await navigator.clipboard.writeText(value); - } else { - const textArea = document.createElement('textarea'); - textArea.value = value; - - textArea.style.position = 'absolute'; - textArea.style.left = '-999999px'; - - document.body.prepend(textArea); - textArea.select(); - - try { - document.execCommand('copy'); - } catch (error) { - return Promise.reject(error); - } finally { - textArea.remove(); - } - } -} - -export async function format_gallery_for_sharing( - value: GalleryData | null -): Promise { - if (!value) return ''; - const urls = await Promise.all( - value.map((data) => { - if (!data.image || !data.image.url) return ''; - return data.image.url; - }) - ); - - return `
    ${urls - .map((url) => ``) - .join('')}
    `; -} diff --git a/frontend/legacy/compiled/CHANGELOG.md b/frontend/legacy/compiled/CHANGELOG.md deleted file mode 100644 index 53480416..00000000 --- a/frontend/legacy/compiled/CHANGELOG.md +++ /dev/null @@ -1,275 +0,0 @@ -# @modelscope-studio/legacy-compiled - -## 1.6.1 - -No significant changes to this package were made in this release. - -## 1.6.0 - -No significant changes to this package were made in this release. - -## 1.5.2 - -### Features - -- [#111](https://github.com/modelscope/modelscope-studio/pull/111) [`4888b2b`](https://github.com/modelscope/modelscope-studio/commit/4888b2b209b8758c92c33f932b61992c3fe4362a) - upgrade to antd 5.28.0, antdx 1.6.1. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.5.1 - -No significant changes to this package were made in this release. - -## 1.5.0 - -### Misc Changes - -- [`5af9cdc`](https://github.com/modelscope/modelscope-studio/commit/5af9cdcb011e3bda1ea9419f34cffd93b81590e7) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.6 - -No significant changes to this package were made in this release. - -## 1.4.5 - -### Misc Changes - -- [#87](https://github.com/modelscope/modelscope-studio/pull/87) [`cb4a962`](https://github.com/modelscope/modelscope-studio/commit/cb4a9623833ec345e86a16d4e2f202e949c3875b) - upgrade to antd 5.27.0, antdx 1.6.0. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.4 - -### Misc Changes - -- [#83](https://github.com/modelscope/modelscope-studio/pull/83) [`6d9b760`](https://github.com/modelscope/modelscope-studio/commit/6d9b760ea3132be488155e67a1c816f260fa7e4c) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.3 - -### Misc Changes - -- [#82](https://github.com/modelscope/modelscope-studio/pull/82) [`ca7519f`](https://github.com/modelscope/modelscope-studio/commit/ca7519f439e00e0d99d921e88ec38dc4689d7849) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.4.2 - -No significant changes to this package were made in this release. - -## 1.4.1 - -No significant changes to this package were made in this release. - -## 1.4.0 - -### Features - -- [#77](https://github.com/modelscope/modelscope-studio/pull/77) [`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Misc Changes - -- [#77](https://github.com/modelscope/modelscope-studio/pull/77) [`30804ea`](https://github.com/modelscope/modelscope-studio/commit/30804eab8ae0817dad72766d932f4a84e3850861) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.3.1 - -No significant changes to this package were made in this release. - -## 1.3.0 - -### Features - -- [#72](https://github.com/modelscope/modelscope-studio/pull/72) [`d3259ab`](https://github.com/modelscope/modelscope-studio/commit/d3259abd179f7953b81f8d76c82cd2d3dd59766c) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.2.4 - -No significant changes to this package were made in this release. - -## 1.2.3 - -### Features - -- [#68](https://github.com/modelscope/modelscope-studio/pull/68) [`034c4e3`](https://github.com/modelscope/modelscope-studio/commit/034c4e33ffa552e91d821171a68a1ab21eb35441) - update deps, antdx 1.0.5 => 1.1.0. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.2.2 - -No significant changes to this package were made in this release. - -## 1.2.1 - -No significant changes to this package were made in this release. - -## 1.2.0 - -No significant changes to this package were made in this release. - -## 1.1.7 - -No significant changes to this package were made in this release. - -## 1.1.6 - -No significant changes to this package were made in this release. - -## 1.1.5 - -### Misc Changes - -- [`4ab53e4`](https://github.com/modelscope/modelscope-studio/commit/4ab53e424c43a1db9d33b8883bb71a22cc59275b) - update deps. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.1.4 - -No significant changes to this package were made in this release. - -## 1.1.3 - -No significant changes to this package were made in this release. - -## 1.1.2 - -No significant changes to this package were made in this release. - -## 1.1.1 - -No significant changes to this package were made in this release. - -## 1.1.0 - -### Misc Changes - -- [#45](https://github.com/modelscope/modelscope-studio/pull/45) [`f4f8a15`](https://github.com/modelscope/modelscope-studio/commit/f4f8a155f30995984c5f46bdd638385c9a230856) - component rendering and props context. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.2 - -No significant changes to this package were made in this release. - -## 1.0.1 - -No significant changes to this package were made in this release. - -## 1.0.0 - -### Features - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#32](https://github.com/modelscope/modelscope-studio/pull/32) [`5332229`](https://github.com/modelscope/modelscope-studio/commit/5332229f20c0ec1ad7ec598f3b30808502b9cd70) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -### Fixes - -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component parameters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#36](https://github.com/modelscope/modelscope-studio/pull/36) [`3944960`](https://github.com/modelscope/modelscope-studio/commit/394496074b842cb20103d7967b4ec4f9422f6229) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.11 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.10 - -No significant changes to this package were made in this release. - -## 1.0.0-beta.9 - -### Fixes - -- [`e7fa278`](https://github.com/modelscope/modelscope-studio/commit/e7fa2782af83a7e78cddb700cd8d5e63ad62342f) - bugfix of remaining components. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.8 - -### Fixes - -- [`a692793`](https://github.com/modelscope/modelscope-studio/commit/a6927930fa0cbb62b8e91d98fbfda7434586e758) - gbk error. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.7 - -### Fixes - -- [#35](https://github.com/modelscope/modelscope-studio/pull/35) [`5875180`](https://github.com/modelscope/modelscope-studio/commit/5875180feb7c07720108e30d01ec606209d36e59) - component paramters in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.6 - -### Fixes - -- [`6a38225`](https://github.com/modelscope/modelscope-studio/commit/6a38225363c7db871c9593e524fe73ebebff1016) - auto_loading & cloned node. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.5 - -### Features - -- [`af9aa4f`](https://github.com/modelscope/modelscope-studio/commit/af9aa4fe598ae23dbe88163202aab2d44d5a133d) - add AutoLoading. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.4 - -### Fixes - -- [`107d733`](https://github.com/modelscope/modelscope-studio/commit/107d733cb4ee01f346d165cbe192c514b38ac905) - known component issues. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.3 - -### Features - -- [`9f3c59c`](https://github.com/modelscope/modelscope-studio/commit/9f3c59c9c5a0bf8af3980588cb07a467323b1d17) - add new features. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.2 - -### Features - -- [`9e5da52`](https://github.com/modelscope/modelscope-studio/commit/9e5da52fc739c6862225192fecf95f6bfd7923ad) - complete components params in Python. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.1 - -### Features - -- [`025f728`](https://github.com/modelscope/modelscope-studio/commit/025f72825bdafbc60b4a09e577a363e43189bd1d) - migrate to gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 1.0.0-beta.0 - -### Features - -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.2 - -No significant changes to this package were made in this release. - -## 0.5.1 - -### Features - -- [#31](https://github.com/modelscope/modelscope-studio/pull/31) [`fca4451`](https://github.com/modelscope/modelscope-studio/commit/fca4451f433294e074507c62b4f5af7c1fb89be5) - migrating to Gradio 5. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.5.0 - -### Features - -- [`e271eb4`](https://github.com/modelscope/modelscope-studio/commit/e271eb493c98f1af0abf35d7109188fc7bf1e8c0) - support cutom latex delimiters in Markdown and Chatbot. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.4.2 - -No significant changes to this package were made in this release. - -## 0.4.1 - -No significant changes to this package were made in this release. - -## 0.4.0 - -No significant changes to this package were made in this release. - -## 0.3.1 - -No significant changes to this package were made in this release. - -## 0.3.0 - -### Features - -- [#20](https://github.com/modelscope/modelscope-studio/pull/20) [`9a5dd22`](https://github.com/modelscope/modelscope-studio/commit/9a5dd226ee117d6130baa87cacdf902546ad952a) - upload logic with new gradio version. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.1 - -### Fixes - -- [`68400a3`](https://github.com/modelscope/modelscope-studio/commit/68400a366d5a8af9a8d14f51577d8db1ebdcceb3) - unique id to each flow. Thanks [@Col0ring](https://github.com/Col0ring)! - -## 0.2.0 - -No significant changes to this package were made in this release. diff --git a/frontend/legacy/compiled/components/FileView/index.svelte b/frontend/legacy/compiled/components/FileView/index.svelte deleted file mode 100644 index 09dc573f..00000000 --- a/frontend/legacy/compiled/components/FileView/index.svelte +++ /dev/null @@ -1,37 +0,0 @@ - - - diff --git a/frontend/legacy/compiled/components/FileView/shared/FileView.svelte b/frontend/legacy/compiled/components/FileView/shared/FileView.svelte deleted file mode 100644 index f9cf9a88..00000000 --- a/frontend/legacy/compiled/components/FileView/shared/FileView.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/frontend/legacy/compiled/components/Flow/index.svelte b/frontend/legacy/compiled/components/Flow/index.svelte deleted file mode 100644 index b9707c00..00000000 --- a/frontend/legacy/compiled/components/Flow/index.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/frontend/legacy/compiled/components/Markdown/index.svelte b/frontend/legacy/compiled/components/Markdown/index.svelte deleted file mode 100644 index 0cc4fdc5..00000000 --- a/frontend/legacy/compiled/components/Markdown/index.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/frontend/legacy/compiled/components/ReactComponent.svelte b/frontend/legacy/compiled/components/ReactComponent.svelte deleted file mode 100644 index 8c535b2d..00000000 --- a/frontend/legacy/compiled/components/ReactComponent.svelte +++ /dev/null @@ -1,40 +0,0 @@ - - -
    diff --git a/frontend/legacy/compiled/global.d.ts b/frontend/legacy/compiled/global.d.ts deleted file mode 100644 index 80204093..00000000 --- a/frontend/legacy/compiled/global.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -interface Window { - __is_colab__?: boolean; -} diff --git a/frontend/legacy/compiled/index.ts b/frontend/legacy/compiled/index.ts deleted file mode 100644 index 218e134a..00000000 --- a/frontend/legacy/compiled/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* eslint-disable import/export */ -export { default as FileView } from './components/FileView/index.svelte'; -export { default as Flow } from './components/Flow/index.svelte'; -export { default as Markdown } from './components/Markdown/index.svelte'; -export type * from './src'; diff --git a/frontend/legacy/compiled/package.json b/frontend/legacy/compiled/package.json deleted file mode 100644 index 26f28329..00000000 --- a/frontend/legacy/compiled/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@modelscope-studio/legacy-compiled", - "version": "1.6.1", - "private": false, - "description": "ModelScope Gradio Components", - "repository": "git@github.com:modelscope/modelscope-studio.git", - "license": "Apache-2.0", - "sideEffects": [ - "*.css" - ], - "type": "module", - "main": "./index.ts", - "dependencies": { - "@subscribe-kit/core": "^2.1.1", - "@subscribe-kit/react": "^2.1.1", - "@ungap/structured-clone": "^1.3.0", - "@xyflow/react": "12.8.4", - "ajv": "^8.17.1", - "ajv-i18n": "^4.2.0", - "deepmerge": "^4.3.1", - "echarts": "^5.6.0", - "elkjs": "^0.10.0", - "github-markdown-css": "^5.8.1", - "github-slugger": "^2.0.0", - "hastscript": "^9.0.1", - "katex": "^0.16.25", - "pdfjs-dist": "^3.11.174", - "react-markdown": "^9.0.3", - "react-syntax-highlighter": "^15.6.6", - "rehype-katex": "^7.0.1", - "rehype-raw": "^7.0.0", - "remark-breaks": "^4.0.0", - "remark-directive": "^3.0.1", - "remark-gfm": "^4.0.1", - "remark-math": "^6.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0" - }, - "devDependencies": { - "@types/react-syntax-highlighter": "^15.5.13" - }, - "main_changeset": true -} diff --git a/frontend/legacy/compiled/src/ComponentConfigProvider.tsx b/frontend/legacy/compiled/src/ComponentConfigProvider.tsx deleted file mode 100644 index 55eb4ac2..00000000 --- a/frontend/legacy/compiled/src/ComponentConfigProvider.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React, { useMemo } from 'react'; -import { - legacyLogicalPropertiesTransformer, - StyleProvider, -} from '@ant-design/cssinjs'; -import { ConfigProvider, theme as AntdTheme } from 'antd'; -import type { Locale } from 'antd/es/locale'; -import en_US from 'antd/locale/en_US'; -import zh_CN from 'antd/locale/zh_CN'; - -const langs: Record = { - 'en-US': en_US, - 'zh-CN': zh_CN, -}; - -const primaryColor = window - .getComputedStyle(document.documentElement) - .getPropertyValue('--color-accent'); - -export interface ComponentConfigProviderProps { - locale?: string | null; - theme?: string | null; - children?: React.ReactNode; -} - -export const ComponentConfigProvider: React.FC = ( - props -) => { - const { locale, theme, children } = props; - - const localeConfig = useMemo(() => { - if (locale) { - return langs[locale]; - } - }, [locale]); - - return ( - ({ - cssVar: true, - token: { - colorPrimary: primaryColor, - }, - algorithm: - theme === 'dark' - ? AntdTheme.darkAlgorithm - : AntdTheme.defaultAlgorithm, - }), - [theme] - )} - locale={localeConfig} - > - [legacyLogicalPropertiesTransformer], [])} - > - {children} - - - ); -}; diff --git a/frontend/legacy/compiled/src/FileView/Pdf.tsx b/frontend/legacy/compiled/src/FileView/Pdf.tsx deleted file mode 100644 index 32841236..00000000 --- a/frontend/legacy/compiled/src/FileView/Pdf.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import React, { useEffect, useRef, useState } from 'react'; -import { CaretLeftOutlined, CaretRightOutlined } from '@ant-design/icons'; -import { Button } from 'antd'; -import type { PDFDocumentProxy, RenderTask } from 'pdfjs-dist'; -import * as pdfjsLib from 'pdfjs-dist'; - -import { isMobile } from '../utils'; - -pdfjsLib.GlobalWorkerOptions.workerSrc = - 'https://g.alicdn.com/code/lib/pdf.js/3.11.174/pdf.worker.min.js'; - -// let registered = false; - -// async function importWorker() { -// if (registered) { -// return; -// } -// // @ts-ignore worker -// const pdfWorker = (await import('pdfjs-dist/build/pdf.worker.min.js')) -// .default; -// const workerBlob = new Blob([pdfWorker], { -// type: 'application/javascript', -// }); -// const workerUrl = URL.createObjectURL(workerBlob); -// pdfjsLib.GlobalWorkerOptions.workerSrc = workerUrl; -// registered = true; -// } - -export interface PdfProps { - src?: string; - width?: number; - height?: number; -} - -export const Pdf: React.FC = ({ src, height, width = '100%' }) => { - const [currentPage, setCurrentPage] = useState(0); - const [totalPage, setTotalPage] = useState(0); - const lastWidthRef = useRef(0); - const canvasContainerRef = useRef(null); - const canvasRef = useRef(null); - const renderTaskRef = useRef(null); - const [pdfDoc, setPdfDoc] = useState(null); - - function renderPdf() { - // Render a specific page of the PDF onto the canvas - pdfDoc?.getPage(currentPage).then((page) => { - renderTaskRef?.current?.cancel(); - const el = canvasRef.current; - const container = canvasContainerRef.current; - const ctx = el?.getContext('2d'); - if (!container || !el || !ctx) { - return; - } - const maxWidth = container.getBoundingClientRect().width; - ctx.clearRect(0, 0, el.width, el.height); - let viewport = page.getViewport({ scale: 1 }); - const maxScale = maxWidth / viewport.width; - let scale = maxScale; - if (height) { - scale = Math.min(height / viewport.height, maxScale); - } else { - // pc - if (!isMobile()) { - scale = maxScale * 0.6; - } - container.style.height = `${viewport.height * scale}px`; - } - - viewport = page.getViewport({ scale: scale }); - - const renderContext = { - canvasContext: ctx, - viewport, - }; - el.width = viewport.width; - el.height = viewport.height; - const renderTask = page.render(renderContext); - renderTaskRef.current = renderTask; - renderTask.promise.catch(() => { - // cancel error - }); - }); - } - async function getPdfDoc() { - if (!src) { - return; - } - pdfDoc?.destroy(); - const loadingTask = pdfjsLib.getDocument(src); - const doc = await loadingTask.promise; - setCurrentPage(1); - setTotalPage(doc.numPages); - setPdfDoc(doc); - } - - useEffect(() => { - getPdfDoc(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [src]); - - useEffect(() => { - const el = canvasContainerRef.current; - if (!el) { - return; - } - lastWidthRef.current = el.getBoundingClientRect().width; - let timeout: ReturnType; - // listen el width changed - const resizeObserver = new ResizeObserver((entries) => { - const entry = entries[0]; - if (!entry) { - return; - } - const rect = entry.contentRect; - if (rect.width !== lastWidthRef.current) { - timeout && clearTimeout(timeout); - lastWidthRef.current = rect.width; - timeout = setTimeout(() => { - renderPdf(); - }, 500); - } - }); - resizeObserver.observe(el); - renderPdf(); - return () => { - resizeObserver.disconnect(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pdfDoc, currentPage, totalPage]); - - return ( - <> - {!!totalPage && ( -
    -
    - -
    -
    -
    -
    - )} - - ); -}; - -export default Pdf; diff --git a/frontend/legacy/compiled/src/FileView/hooks/usePreview.ts b/frontend/legacy/compiled/src/FileView/hooks/usePreview.ts deleted file mode 100644 index d7d3e65d..00000000 --- a/frontend/legacy/compiled/src/FileView/hooks/usePreview.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useEffect, useState } from 'react'; -import type { ImageProps } from 'antd'; - -export function usePreview(): ImageProps['preview'] { - const [visible, setVisible] = useState(false); - useEffect(() => { - if (visible) { - document.body.classList.add('ms-preview-container'); - } else { - document.body.classList.remove('ms-preview-container'); - } - }, [visible]); - return { - visible, - onVisibleChange: (value) => { - setVisible(value); - }, - }; -} diff --git a/frontend/legacy/compiled/src/FileView/index.less b/frontend/legacy/compiled/src/FileView/index.less deleted file mode 100644 index 416f4ba7..00000000 --- a/frontend/legacy/compiled/src/FileView/index.less +++ /dev/null @@ -1,27 +0,0 @@ -.ms-file-view-pdf { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - - &-canvas { - display: flex; - align-items: center; - justify-content: center; - } - - &-button-row { - display: flex; - align-items: center; - justify-content: center; - margin-top: 5px; - } - - &-page-count { - margin: 0 4px; - } -} - -.ms-preview-container .generating { - z-index: 999 !important; -} diff --git a/frontend/legacy/compiled/src/FileView/index.tsx b/frontend/legacy/compiled/src/FileView/index.tsx deleted file mode 100644 index bd735e5f..00000000 --- a/frontend/legacy/compiled/src/FileView/index.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import React from 'react'; -import { FileOutlined } from '@ant-design/icons'; -import type { ImageProps } from 'antd'; -import { Image as AntdImage } from 'antd'; - -import { defineComponent } from '../defineComponent'; - -import { usePreview } from './hooks/usePreview'; -import Pdf from './Pdf'; - -import './index.less'; - -const Image: React.FC = ({ preview = true, ...props }) => { - const previewConfig = usePreview(); - return ( -
    - -
    - ); -}; -const Video: React.FC> = ( - props -) => { - return ( - - ); -}; -const Audio: React.FC> = ( - props -) => { - return ( -

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

- } - styles={{ - body: { - padding: hasAttrs ? '10px 20px' : 0, - }, - header: { - border: hasAttrs ? undefined : 'none', - }, - }} - extra={ - showToolbar ? ( - containerRef.current || document.body} - > - - - ) : null - } - > - {hasAttrs ? ( -
- {schema.attrs?.map((attr) => { - let content: React.ReactNode = null; - switch (attr.type) { - case 'input': - content = ; - break; - case 'textarea': - content = ; - break; - case 'radio': - content = ; - break; - case 'checkbox': - content = ; - break; - case 'number': - content = ; - break; - case 'select': - content = ( - ; - } - } - content = React.isValidElement>( - content - ) - ? React.cloneElement(content, { - ...content.props, - ...attr.props, - disabled: attr.disabled || attr.props?.disabled, - className: cls( - attr.props?.className, - content.props.className, - 'nodrag' - ), - }) - : content; - let addFn = () => {}; - - const validate = attr.json_schema_validator - ? compileValidationSchema(attr.json_schema_validator) - : null; - const requiredRule: FormRule = { - required: !!attr.required, - message: isObject(attr.required) - ? attr.required.message - : undefined, - }; - const customRule: FormRule = { - validator(_, value) { - if (validate) { - const valid = validate(value); - if (!valid) { - const msg = getValidationErrorMessage( - validate.errors, - locale - ); - return Promise.reject(new Error(msg)); - } - } - return Promise.resolve(); - }, - }; - const field = attr.list ? ( -
- - {(fields, { add, remove }, meta) => { - addFn = add; - return ( - <> - {fields.map((f, index) => { - return ( -
- - remove(f.name)} - showRemove={ - !isObject(attr.list) || - !isNumber(attr.list.min) || - attr.list.min < attrs[attr.name]?.length - ? true - : false - } - > - {content} - - - {renderPorts( - isObject(attr.list) - ? attr.list.ports - : undefined, - (type, i) => - getHandleId({ - nodeId: nodeId || '', - type, - attr: attr.name, - handleIndex: i, - attrItemIndex: index, - }) - )} -
- ); - })} - - - ); - }} -
- {renderPorts(attr.ports, (type, i) => - getHandleId({ - nodeId: nodeId || '', - type, - handleIndex: i, - attr: attr.name, - }) - )} -
- ) : ( -
- - {content} - - {renderPorts(attr.ports, (type, i) => - getHandleId({ - nodeId: nodeId || '', - type, - handleIndex: i, - attr: attr.name, - }) - )} -
- ); - - const isAccordion = attr.accordion ?? true; - - return ( - - isAccordion ? ( - - ) : null - } - items={[ - { - key: attr.name, - label: ( - - - {attr.title || attr.name} - - {attr.description && ( - - containerRef.current || document.body - } - > - - - )} - - ), - style: { padding: 0 }, - children: field, - extra: - attr.list && - (!isObject(attr.list) || - !isNumber(attr.list.max) || - attr.list.max > attrs[attr.name]?.length) ? ( -
-
- {flowSchema.nodes.map((nodeSchema, index) => { - if (nodeSchema.addable === false) { - return null; - } - const disabled = - flowDisabled || - (typeof nodeSchema.max === 'number' && - nodeCounts[nodeSchema.name] >= nodeSchema.max); - - return ( - onDragStart(e, nodeSchema)} - className="ms-flow-sidebar-item" - key={`${nodeSchema.name}-${index}`} - styles={{ - body: { - padding: 10, - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - }, - }} - > -

-
- {nodeSchema.icon && ( - {nodeSchema.title - )} - {nodeSchema.title || nodeSchema.name} -
-

- {nodeSchema.description && ( -

- {nodeSchema.description} -

- )} -
- ); - })} -
- - ); -}; diff --git a/frontend/legacy/compiled/src/Flow/i18n.ts b/frontend/legacy/compiled/src/Flow/i18n.ts deleted file mode 100644 index 0b2d96db..00000000 --- a/frontend/legacy/compiled/src/Flow/i18n.ts +++ /dev/null @@ -1,21 +0,0 @@ -const messages: Record> = { - delete: { - 'zh-CN': '删除', - 'en-US': 'Delete', - }, - duplicate: { - 'zh-CN': '复制', - 'en-US': 'Duplicate', - }, - rename: { - 'zh-CN': '重命名', - 'en-US': 'Rename', - }, - 'upload.drop_file': { - 'zh-CN': '点击或拖拽文件到此区域上传', - 'en-US': 'Click or drag file to this area to upload', - }, -}; -export const i18n = (key: string, locale = 'en-US') => { - return messages[key]?.[locale] || messages[key]?.['en-US'] || key; -}; diff --git a/frontend/legacy/compiled/src/Flow/index.less b/frontend/legacy/compiled/src/Flow/index.less deleted file mode 100644 index bc884524..00000000 --- a/frontend/legacy/compiled/src/Flow/index.less +++ /dev/null @@ -1,235 +0,0 @@ -/* stylelint-disable selector-class-pattern */ -.ms-flow { - width: 100%; - height: 100%; - - &-sidebar { - position: relative; - box-sizing: border-box; - width: 20%; - min-width: 180px; - max-width: 280px; - height: 100%; - margin: 0; - transition: transform 0.2s linear; - - &-collapse { - transform: translateX(-100%); - } - - &-handle { - position: absolute; - top: 50%; - right: 0; - z-index: 1; - transform: translate(50%, -50%); - - &-collapse { - transform: translate(100%, -50%); - } - } - - &-list { - width: 100%; - height: 100%; - padding: 4px; - overflow: auto; - } - - & &-item { - width: 100%; - margin-bottom: 10px; - - &-header { - display: flex; - align-items: center; - justify-content: space-between; - margin: 0; - font-size: 16px; - - &-title { - display: flex; - align-items: center; - - img { - width: 18px; - height: 18px; - margin-right: 6px; - } - } - - &-add { - flex-shrink: 0; - } - } - - &-desc { - margin: 0; - margin-top: 6px; - font-size: 12px; - } - } - } - - .react-flow__handle { - background: var(--ms-flow-handle-bg); - - &.connectingto { - background: var(--ms-flow-handle-bg-error); - } - - &.valid { - background: var(--ms-flow-handle-bg-success); - } - } - - &-node { - &-form-list-item { - display: flex; - - &-content { - flex: 1; - width: 0; - height: 100%; - margin-left: 8px; - } - } - - .ant-input { - padding: var(--ant-input-padding-block) var(--ant-input-padding-inline); - font-size: var(--ant-input-input-font-size); - line-height: var(--ant-line-height); - border-radius: var(--ant-border-radius); - } - - .ant-input-outlined { - background-color: var(--ant-color-bg-container); - border-color: var(--ant-color-border); - border-width: var(--ant-line-width); - } - - .ant-switch { - background-color: var(--ant-color-text-quaternary); - } - - &-header { - padding: 4px 0; - - &-title { - display: flex; - align-items: center; - height: 34px; - font-size: 14px; - - /* stylelint-disable-next-line no-descending-specificity */ - img { - width: 18px; - height: 18px; - margin-right: 4px; - } - } - - &-description { - margin-bottom: 4px; - font-weight: normal; - font-size: 12px; - opacity: 0.5; - } - } - // fix collapse closed - .ant-collapse-content-hidden { - height: 0; - } - - .ant-collapse-content-inactive { - display: block !important; - overflow: hidden; - - .ms-flow-node-field.ms-flow-node-field-item { - position: unset; - } - } - - &-field-list { - .ant-form-item-explain-error { - color: var(--ms-flow-node-text-error); - } - - .ms-flow-node-field { - .ant-form-item-explain-error { - padding-left: 22px; - } - } - } - - &-field { - padding: 0 8px; - - &-item { - position: relative; - } - } - - &-field-label { - &-required { - &::before { - margin-right: 3px; - color: var(--ms-flow-node-text-error); - content: '*'; - } - } - } - - &-handle { - display: flex; - align-items: center; - justify-content: center; - width: 10px; - height: 10px; - color: #fff; - font-size: 7px; - opacity: 0.7; - transition: 0.2s all linear; - - &-icon { - pointer-events: none; - } - } - } - - .react-flow__node { - &.selected { - z-index: 1002 !important; - } - - &:hover { - .ms-flow-node { - &-handle { - opacity: 1; - - &-left { - transform: translate(-50%, -50%) scale(2); - } - - &-right { - transform: translate(50%, -50%) scale(2); - } - - &-top { - transform: translate(-50%, -50%) scale(2); - } - - &-bottom { - transform: translate(-50%, 50%) scale(2); - } - } - } - } - } - - &-controls { - &-zoom-select { - width: 90px; - } - } -} diff --git a/frontend/legacy/compiled/src/Flow/index.tsx b/frontend/legacy/compiled/src/Flow/index.tsx deleted file mode 100644 index 257cf4ef..00000000 --- a/frontend/legacy/compiled/src/Flow/index.tsx +++ /dev/null @@ -1,540 +0,0 @@ -import { createSelector } from '@subscribe-kit/react'; -import type { BackgroundProps, ReactFlowInstance } from '@xyflow/react'; -import { - addEdge, - applyEdgeChanges, - applyNodeChanges, - Background, - MarkerType, - MiniMap, - ReactFlow, - reconnectEdge, -} from '@xyflow/react'; -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { Store } from '@subscribe-kit/core'; -import { theme as AntdTheme } from 'antd'; -import cls from 'classnames'; -import { isNumber, isObject } from 'lodash-es'; - -import { defineComponent } from '../defineComponent'; -import { useMemoizedEqualValue, useRefValue } from '../shared'; -import { isMobile, safeParseJSON } from '../utils'; - -import { ConnectionLine } from './flow-components/ConnectionLine'; -import { Controls } from './flow-components/Controls'; -import { Edge } from './flow-components/Edge'; -import { Node } from './flow-components/Node'; -import { Sidebar } from './flow-components/Sidebar'; -import type { FlowContextValue } from './FlowContext'; -import { FlowContext } from './FlowContext'; -import type { - FlowDragData, - FlowEdge, - FlowNode, - FlowNodeSchema, - FlowRenderData, - FlowStoreData, - ReactFlowProps, -} from './type'; -import { - createId, - flowData2RenderData, - parseHandleIdObject, - renderData2FlowData, -} from './utils'; - -import '@xyflow/react/dist/style.css'; -import './index.less'; - -export type * from './type'; - -export interface FlowProps { - on_upload: FlowContextValue['onUpload']; - custom_components: FlowContextValue['custom_components']; - on_custom: FlowContextValue['on_custom']; - schema: FlowContextValue['flowSchema']; - nodes: FlowNode[]; - edges: FlowEdge[]; - disabled?: boolean; - theme?: 'dark' | 'light'; - on_change?: (value: FlowRenderData, data_changed?: boolean) => void; - show_sidebar?: boolean; - show_minimap?: boolean; - show_controls?: boolean; - background_props?: BackgroundProps | BackgroundProps[]; - min_zoom?: number; - max_zoom?: number; -} - -const edgeTypes: ReactFlowProps['edgeTypes'] = { - 'ms-edge': Edge, -}; - -const nodeTypes: ReactFlowProps['nodeTypes'] = { - 'ms-node': Node, -}; - -const defaultSchema: FlowProps['schema'] = { - nodes: [], -}; - -const initialNodes: FlowNode[] = []; -const initialEdges: FlowEdge[] = []; - -export const Flow = defineComponent((props) => { - const { - disabled, - schema: userSchema, - theme = 'light', - max_zoom: maxZoom = 2, - min_zoom: minZoom = 0.1, - show_sidebar = true, - show_controls = true, - show_minimap = !isMobile(), - nodes: userNodes = initialNodes, - edges: userEdges = initialEdges, - on_upload, - locale = 'en-US', - on_change, - on_custom, - custom_components, - className, - style, - background_props, - } = props; - const id = useMemo(() => { - return createId(); - }, []); - const schema = useMemoizedEqualValue(userSchema); - - const { token } = AntdTheme.useToken(); - const onChangeRef = useRefValue(on_change); - const { nodes, edges } = useMemo(() => { - return renderData2FlowData( - { - nodes: userNodes, - edges: userEdges, - }, - { - markerEndColor: token.colorPrimary, - } - ); - }, [token.colorPrimary, userEdges, userNodes]); - const nodesRef = useRefValue(nodes); - const edgesRef = useRefValue(edges); - const edgeUpdateSuccessfulRef = useRef(true); - const [reactFlowInstance, setReactFlowInstance] = useState | null>(null); - const undeletableNodes = useMemo(() => { - return schema.nodes.reduce( - (prev, cur) => { - if (cur.deletable === false) { - prev[cur.name] = cur; - } - return prev; - }, - {} as Record - ); - }, [schema.nodes]); - - const nodesSchema = useMemo(() => { - return (schema.nodes || []).reduce( - (acc, node) => { - acc[node.name] = node; - return acc; - }, - {} as Record - ); - }, [schema.nodes]); - const { flowStore, useFlowStore } = useMemo(() => { - const store = new Store({ - initialValues: { - nodeCounts: {}, - nodesString: '', - }, - }); - - return { - flowStore: store, - useFlowStore: createSelector({ store }).useSelector, - }; - }, []); - - const updateNodeCounts = useCallback( - (newNodes: FlowNode[]) => { - const newNodeCounts = newNodes.reduce( - (prev, cur) => { - if (!prev[cur.data.name]) { - prev[cur.data.name] = 0; - } - prev[cur.data.name]++; - return prev; - }, - {} as Record - ); - flowStore.setValues((draft) => { - draft.nodeCounts = newNodeCounts; - draft.nodesString = JSON.stringify(newNodes); - }); - }, - [flowStore] - ); - - // update node counts when nodes changed - useEffect(() => { - updateNodeCounts(nodes); - }, [nodes, updateNodeCounts]); - - const setNodes: FlowContextValue['setNodes'] = useCallback((cb, options) => { - const newNodes = cb(nodesRef.current); - // perf: optimize - // if (options?.updateNodeCounts) { - // updateNodeCounts(newNodes); - // } - - onChangeRef.current?.( - flowData2RenderData({ - nodes: newNodes, - edges: edgesRef.current, - }), - options?.dataChanged - ); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const setEdges: FlowContextValue['setEdges'] = useCallback((cb, options) => { - const newEdges = cb(edgesRef.current); - - onChangeRef.current?.( - flowData2RenderData({ - nodes: nodesRef.current, - edges: newEdges, - }), - options?.dataChanged - ); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const onNodesChange: ReactFlowProps['onNodesChange'] = (changes) => { - const isEditChange = changes.some( - (c) => c.type === 'add' || c.type === 'remove' || c.type === 'replace' - ); - setNodes( - (nds) => { - const newNodes = applyNodeChanges(changes, nds); - return newNodes; - }, - { - updateNodeCounts: isEditChange, - dataChanged: isEditChange, - } - ); - }; - - const onEdgesChange: ReactFlowProps['onEdgesChange'] = (changes) => { - const isEditChange = changes.some( - (c) => c.type === 'add' || c.type === 'remove' || c.type === 'replace' - ); - setEdges( - (eds) => { - const newEdges = applyEdgeChanges(changes, eds); - return newEdges; - }, - { - dataChanged: isEditChange, - } - ); - }; - - const onConnect: ReactFlowProps['onConnect'] = (params) => { - setEdges( - (eds) => { - return addEdge( - { - ...params, - type: 'ms-edge', - markerEnd: { - type: MarkerType.ArrowClosed, - color: token.colorPrimary, - }, - zIndex: 1001, - }, - eds - ); - }, - { - dataChanged: true, - } - ); - }; - const onReconnectStart: ReactFlowProps['onReconnectStart'] = () => { - edgeUpdateSuccessfulRef.current = false; - }; - - const onReconnect: ReactFlowProps['onReconnect'] = ( - oldEdge, - newConnection - ) => { - edgeUpdateSuccessfulRef.current = true; - setEdges((els) => reconnectEdge(oldEdge, newConnection, els), { - dataChanged: true, - }); - }; - - const onReconnectedEnd: ReactFlowProps['onReconnectEnd'] = (_, edge) => { - if (!edgeUpdateSuccessfulRef.current) { - setEdges((eds) => eds.filter((e) => e.id !== edge.id), { - dataChanged: true, - }); - } - - edgeUpdateSuccessfulRef.current = true; - }; - - const onDrop: ReactFlowProps['onDrop'] = (e) => { - if (!reactFlowInstance) { - return; - } - - e.preventDefault(); - - const data = e.dataTransfer.getData('ms-flow-drop-data'); - - // check if the dropped element is valid - if (!data) { - return; - } - - const { name, template } = safeParseJSON(data, { - name: '', - template: {}, - }); - - const position = reactFlowInstance.screenToFlowPosition({ - x: e.clientX, - y: e.clientY, - }); - - setNodes( - (nds) => [ - ...nds.map((nd) => ({ ...nd, selected: false })), - { - id: createId(), - type: 'ms-node', - position, - selected: true, - data: { - name, - attrs: template?.attrs, - }, - }, - ], - { - dataChanged: true, - updateNodeCounts: true, - } - ); - }; - - const onDragOver: ReactFlowProps['onDragOver'] = (e) => { - e.preventDefault(); - e.dataTransfer.dropEffect = 'move'; - }; - - // eslint-disable-next-line require-await - const onBeforeDelete: ReactFlowProps['onBeforeDelete'] = async (params) => { - return { - edges: params.edges, - nodes: params.nodes.filter((n) => { - // if deletable or schema.min < the node count - const isUndeleteableNode = undeletableNodes[n.data.name]; - if (isUndeleteableNode) { - return false; - } - const nodeSchema = nodesSchema[n.data.name]; - - return ( - !isNumber(nodeSchema.min) || - nodeSchema.min < flowStore.values.nodeCounts[n.data.name] - ); - }), - }; - }; - - const isValidConnection: ReactFlowProps['isValidConnection'] = ( - connection - ) => { - const sourceNode = reactFlowInstance?.getNode(connection.source); - const targetNode = reactFlowInstance?.getNode(connection.target); - if (!sourceNode || !targetNode) { - return false; - } - const sourceNodeSchema = nodesSchema[sourceNode.data.name]; - const targetNodeSchema = nodesSchema[targetNode.data.name]; - - if (!sourceNodeSchema || !targetNodeSchema) { - return false; - } - - const { attr: sourceAttr, attrItemIndex: sourceAttrItem } = - parseHandleIdObject(connection.sourceHandle || ''); - const { attr: targetAttr, attrItemIndex: targetAttrItem } = - parseHandleIdObject(connection.targetHandle || ''); - - const getSourceConnections = () => { - if (sourceAttrItem) { - const listOptions = sourceNodeSchema.attrs?.find( - (attr) => attr.name === sourceAttr - )?.list; - if (isObject(listOptions)) { - return listOptions.ports?.sourceConnections; - } - return; - } - if (sourceAttr) { - return sourceNodeSchema.attrs?.find((attr) => attr.name === sourceAttr) - ?.ports?.sourceConnections; - } - return sourceNodeSchema.ports?.sourceConnections; - }; - - const getTargetConnections = () => { - if (targetAttrItem) { - const listOptions = targetNodeSchema.attrs?.find( - (attr) => attr.name === targetAttr - )?.list; - if (isObject(listOptions)) { - return listOptions.ports?.targetConnections; - } - return; - } - if (targetAttr) { - return targetNodeSchema.attrs?.find((attr) => attr.name === targetAttr) - ?.ports?.targetConnections; - } - return targetNodeSchema.ports?.targetConnections; - }; - - const sourceConnections = getSourceConnections(); - const targetConnections = getTargetConnections(); - // judge if the connection is valid - if ( - (!sourceConnections || - (sourceConnections && - sourceConnections.some((conn) => { - // only for node - if (typeof conn === 'string') { - return conn === targetNodeSchema.name; - } - // for node and node attrs - return ( - conn.name === targetNodeSchema.name && - targetAttr && - conn.attrs?.includes(targetAttr) - ); - }))) && - (!targetConnections || - (targetConnections && - targetConnections.some((conn) => { - if (typeof conn === 'string') { - return conn === sourceNodeSchema.name; - } - return ( - conn.name === sourceNodeSchema.name && - sourceAttr && - conn.attrs?.includes(sourceAttr) - ); - }))) - ) { - return true; - } - return false; - }; - - return ( -
- { - return { - theme, - maxZoom, - minZoom, - disabled, - onUpload: on_upload, - useFlowStore, - setEdges, - setNodes, - locale, - on_custom, - custom_components, - nodesSchema, - flowSchema: { - ...defaultSchema, - ...schema, - }, - }; - }, [ - theme, - maxZoom, - minZoom, - disabled, - on_upload, - useFlowStore, - setEdges, - setNodes, - locale, - on_custom, - custom_components, - nodesSchema, - schema, - ])} - > - - nodeTypes={nodeTypes} - id={`flow_${id}`} - edgeTypes={edgeTypes} - proOptions={{ - hideAttribution: true, - }} - nodesDraggable={!disabled} - nodesConnectable={!disabled} - elementsSelectable={!disabled} - nodes={nodes} - onBeforeDelete={onBeforeDelete} - onReconnectStart={onReconnectStart} - onReconnect={onReconnect} - onReconnectEnd={onReconnectedEnd} - onNodesChange={onNodesChange} - isValidConnection={isValidConnection} - edges={edges} - onEdgesChange={onEdgesChange} - onConnect={onConnect} - onInit={setReactFlowInstance} - fitView - onDrop={onDrop} - onDragOver={onDragOver} - connectionLineComponent={ConnectionLine} - minZoom={minZoom} - maxZoom={maxZoom} - nodesFocusable={false} - colorMode={theme} - > - {show_sidebar && } - {Array.isArray(background_props) ? ( - background_props.map((item, index) => ( - - )) - ) : ( - - )} - {show_controls && } - {show_minimap && } - - -
- ); -}); - -export default Flow; diff --git a/frontend/legacy/compiled/src/Flow/type.ts b/frontend/legacy/compiled/src/Flow/type.ts deleted file mode 100644 index c3fda6ae..00000000 --- a/frontend/legacy/compiled/src/Flow/type.ts +++ /dev/null @@ -1,346 +0,0 @@ -import type { - Edge, - Node, - Position, - ReactFlowProps as OriginReactFlowProps, -} from '@xyflow/react'; - -export type ReactFlowProps = Required>; - -export type Attrs = Record; - -export interface FlowCustomData { - value?: any; - node: string; - attr: string; - id: string; - index?: number; -} - -export interface FlowStoreData { - nodeCounts: Record; - nodesString: string; -} - -export type PortConnection = - | string - | { - name: string; - attrs?: string[]; - }; - -export interface FlowNodeAttrSchema { - /** - * Unique attribute name used as a key in the node data. Mandatory. - */ - name: string; - - /** - * Display title for the attribute, defaults to the attribute name if not provided. - */ - title?: string; - - /** - * A brief explanation about the attribute purpose. - */ - description?: string; - - /** - * Disables user editing of the attribute value. By default, attributes are editable. - * @default false - */ - disabled?: boolean; - - /** - * Attribute input type. Can be one of the built-in Ant Design components or a custom component. Defaults to 'input'. - * @default 'input' - */ - type?: - | 'input' - | 'textarea' - | 'radio' - | 'checkbox' - | 'number' - | 'select' - | 'switch' - | 'upload' - // custom - | (string & {}); - - /** - * Configuration options specific to the chosen component type, supporting Ant Design ({@link https://ant.design/components/overview/}) or custom component properties. - */ - props?: Record; - - /** - * Configurations for the node attribute ports. - */ - ports?: { - /** - * Source ports for the attribute as a connection. - * @default [] - */ - source?: Position[]; - - /** - * Allowed the source ports of this attribute to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the attribute as a connection - * @default [] - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this attribute. Defaults to all nodes and attributes - */ - targetConnections?: PortConnection[]; - }; - - /** - * Indicates whether the attribute is a list. - * @default false - */ - list?: - | boolean - | { - /** - * Port configurations for each item in the list. - */ - ports?: { - /** - * Source ports for the list item as a connection. - * @default [] - */ - source?: Position[]; - - /** - * Allowed the source ports of this list item to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the list item as a connection - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this list item. Defaults to all nodes and attributes - */ - targetConnections?: PortConnection[]; - }; - - /** - * Minimum number of items in the list. - */ - min?: number; - - /** - * Maximum number of items in the list. - */ - max?: number; - // layout?: 'horizontal' | 'vertical'; - // children?: FlowNodeAttrSchema[]; - }; - - /** - * Enable/disable accordion UI. - * @default true - */ - accordion?: boolean; - - /** - * Specifies if the attribute value is mandatory. By default, attributes are optional. - * @default false - */ - required?: - | boolean - | { - message?: string; - }; - - /** - * Validates attribute values using JSON schema. - */ - json_schema_validator?: Record; -} - -export interface FlowNodeSchema { - /** - * As a unique identifier for the node. Mandatory. - */ - name: string; - - /** - * Display icon for the node. - */ - icon?: string; - - /** - * Display title for the node, defaults to the node name if not provided. - */ - title?: string; - - /** - * A short description of the node's purpose. - */ - description?: string; - - /** - * Width of the node. - */ - width?: number; - - /** - * Height of the node. - */ - height?: number; - - /** - * Shows/hides the toolbar (delete, copy, rename, etc.). - * @default true - */ - show_toolbar?: boolean; - - /** - * Enables/disables adding more instances of this node. - * @default true - */ - addable?: boolean; - - /** - * Enables/disables deleting existing instances of this node. - * @default true - */ - deletable?: boolean; - - /** - * Maximum number of this node type that can exist simultaneously. - */ - max?: number; - - /** - * Minimum number of this node type that must exist simultaneously. - */ - min?: number; - - /** - * Configurations for the node's connection ports. - */ - ports?: { - /** - * Source ports for the node as a connection. - * @default ['right'] - */ - source?: Position[]; - - /** - * Allowed the source ports of this node to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the node as a connection - * @default ['left'] - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this node. Defaults to all nodes and attributes - * - */ - targetConnections?: PortConnection[]; - }; - - // TODO: attr groups - // attrsGroups?: Array<{ - // name: string - // title?: string - // }> - - /** - * Configuration of the node's attributes. - */ - attrs?: FlowNodeAttrSchema[]; - - /** - * Initial values for the node's attributes when creating a new instance. - */ - template?: { - /** - * Attribute values corresponding to their names in the `attrs` field, e.g., `{ "a": 1, "b": 2 }`. - */ - attrs?: Attrs; - }; -} - -export interface FlowSchema { - nodes: FlowNodeSchema[]; -} - -export interface FlowDragData { - name: string; - template?: FlowNodeSchema['template']; -} - -export interface FlowNode extends Node { - data: { - attrs?: Attrs; - title?: string; - name: string; - }; -} - -export interface FlowEdge extends Edge {} - -export interface FlowData { - nodes: FlowNode[]; - edges: FlowEdge[]; -} - -export interface FlowRenderData { - nodes?: Array<{ - id?: string; - position?: FlowNode['position']; - data?: Record; - title?: string; - name?: string; - [key: string]: any; - }>; - edges?: Array<{ - id?: string; - source?: string; - target?: string; - sourcePort?: { - handleIndex?: number; - attr?: string; - attrItemIndex?: number; - }; - targetPort?: { - handleIndex?: number; - attr?: string; - attrItemIndex?: number; - }; - }>; -} - -export interface HandleIdObject { - nodeId: string; - type: 'target' | 'source'; - attr?: string; - attrItemIndex?: number; - handleIndex: number; -} - -export interface ElkPortsId { - id: string; - properties: { side: 'WEST' | 'EAST' | 'NORTH' | 'SOUTH' }; -} - -export interface UploadFile { - path: string; - url: string; - name: string; -} diff --git a/frontend/legacy/compiled/src/Flow/utils.ts b/frontend/legacy/compiled/src/Flow/utils.ts deleted file mode 100644 index c7329517..00000000 --- a/frontend/legacy/compiled/src/Flow/utils.ts +++ /dev/null @@ -1,375 +0,0 @@ -import { MarkerType, Position } from '@xyflow/react'; -import type { ErrorObject, Schema as JSONSchema } from 'ajv'; -import Ajv from 'ajv'; -import localize from 'ajv-i18n/localize/zh'; -import type { ElkNode } from 'elkjs/lib/elk.bundled'; -import ELK from 'elkjs/lib/elk.bundled'; -import { isObject } from 'lodash-es'; - -import type { - ElkPortsId, - FlowData, - FlowEdge, - FlowNode, - FlowNodeSchema, - FlowRenderData, - HandleIdObject, -} from './type'; - -// ***** Layout ***** - -const handleIdSplitter = '__$__'; - -export function stringifyHandleIdObject(options: HandleIdObject) { - return Object.keys(options).reduce((acc, key) => { - if ( - ([undefined, null] as any[]).includes( - options[key as keyof HandleIdObject] - ) - ) { - return acc; - } - let prefix = ''; - if (acc) { - prefix += handleIdSplitter; - } - return acc + prefix + `${key}=${options[key as keyof HandleIdObject]}`; - }, ''); -} - -export function parseHandleIdObject(str: string) { - const handleIdObject = {} as HandleIdObject; - str.split(handleIdSplitter).forEach((item) => { - const [key, ...value] = item.split('='); - (handleIdObject as any)[key] = value.join('='); - }); - return handleIdObject; -} - -export function getHandleId(options: { - nodeId: string; - type: 'target' | 'source'; - attr?: string; - attrItemIndex?: number; - handleIndex: number; -}) { - const { attr, type, nodeId, attrItemIndex, handleIndex } = options; - // return `${nodeId}-${type}-attr(${attr})-attr_item_index(${attrItemIndex})-${handleIndex}`; - // sort props - return stringifyHandleIdObject({ - nodeId, - type, - attr, - attrItemIndex, - handleIndex, - }); -} - -const position2side = { - [Position.Right]: 'EAST', - [Position.Left]: 'WEST', - [Position.Top]: 'NORTH', - [Position.Bottom]: 'SOUTH', -} as const; - -const elk = new ELK(); - -// elk layouting options can be found here: -// https://www.eclipse.org/elk/reference/algorithms/org-eclipse-elk-layered.html -const layoutOptions = { - 'elk.algorithm': 'layered', - 'elk.direction': 'RIGHT', - 'elk.layered.spacing.edgeNodeBetweenLayers': '40', - 'elk.spacing.nodeNode': '40', - 'elk.layered.nodePlacement.strategy': 'SIMPLE', -}; - -const getPortsIds = (node: FlowNode, schema: FlowNodeSchema): ElkPortsId[] => { - const combine = ( - ports: [sourcePorts?: Position[], targetPorts?: Position[]] - ) => { - return [ - { type: 'source', ports: ports[0] }, - { type: 'target', ports: ports[1] }, - ] as const; - }; - const sourcePorts = schema.ports?.source || [Position.Right]; - const targetPorts = schema.ports?.target || [Position.Left]; - const portsIds: ElkPortsId[] = []; - - combine([sourcePorts, targetPorts]).forEach(({ type, ports }) => { - ports?.forEach((port, i) => { - portsIds.push({ - id: getHandleId({ - nodeId: node.id || '', - type, - handleIndex: i, - }), - properties: { - side: position2side[port], - }, - }); - }); - }); - - schema.attrs?.forEach((attr) => { - combine([attr.ports?.source, attr.ports?.target]).forEach( - ({ type, ports }) => { - ports?.forEach((port, handleIndex) => { - portsIds.push({ - id: getHandleId({ - nodeId: node.id || '', - attr: attr.name, - type, - handleIndex, - }), - properties: { - side: position2side[port], - }, - }); - }); - } - ); - - if (isObject(attr.list) && attr.list.ports) { - combine([attr.list.ports.source, attr.list.ports.target]).forEach( - ({ type, ports }) => { - ports?.forEach((port, handleIndex) => { - ((node.data.attrs?.[attr.name] || []) as any[]).forEach( - (_, attrItemIndex) => { - portsIds.push({ - id: getHandleId({ - nodeId: node.id || '', - attr: attr.name, - type, - handleIndex, - attrItemIndex, - }), - properties: { - side: position2side[port], - }, - }); - } - ); - }); - } - ); - } - }); - - return portsIds; -}; - -export const getLayoutedNodes = async ( - nodes: FlowNode[], - edges: FlowEdge[], - getNodeSchema: (node: FlowNode) => FlowNodeSchema -): Promise => { - const graph: ElkNode = { - id: 'root', - layoutOptions, - children: nodes.map((n) => { - return { - id: n.id, - width: n.width ?? 360, - height: n.height ?? 200, - // ⚠️ we need to tell elk that the ports are fixed, in order to reduce edge crossings - properties: { - 'org.eclipse.elk.portConstraints': 'FIXED_ORDER', - }, - // we are also passing the id, so we can also handle edges without a sourceHandle or targetHandle option - ports: getPortsIds(n, getNodeSchema(n)), - }; - }), - edges: edges.map((e) => ({ - id: e.id, - sources: [e.sourceHandle || e.source], - targets: [e.targetHandle || e.target], - })), - }; - - const layoutedGraph = await elk.layout(graph); - - const layoutedNodes: FlowNode[] = nodes.map((node) => { - const layoutedNode = layoutedGraph.children?.find( - (lgNode) => lgNode.id === node.id - ); - - return { - ...node, - position: { - x: layoutedNode?.x ?? 0, - y: layoutedNode?.y ?? 0, - }, - }; - }); - - return layoutedNodes; -}; - -// ***** Layout ***** - -// ***** validation ***** -const ajv = new Ajv(); - -const ajvLocales: Record = { - 'zh-CN': localize, -}; - -export function compileValidationSchema(schema: JSONSchema) { - try { - return ajv.compile(schema); - } catch { - return null; - } -} - -export function getValidationErrorMessage( - errors: - | ErrorObject, unknown>[] - | null - | undefined, - locale?: string -) { - if (locale && ajvLocales[locale]) { - ajvLocales[locale](errors); - } - return ajv.errorsText(errors, { separator: '\n' }); -} - -// ***** validation ***** - -// ***** data ***** -// convert data -export function renderData2FlowData( - renderData: FlowRenderData, - options: { markerEndColor: string } -): FlowData { - return { - nodes: - renderData.nodes?.map((node) => { - return { - ...node, - id: node.id || createId(), - type: 'ms-node', - position: { - x: node.position?.x || 0, - y: node.position?.y || 0, - }, - data: { - title: node.title, - name: node.name || '', - attrs: node.data, - }, - }; - }) || [], - edges: - renderData.edges?.map((edge) => { - return { - ...edge, - id: edge.id || '', - source: edge.source || '', - target: edge.target || '', - type: 'ms-edge', - sourceHandle: getHandleId({ - nodeId: edge.source || '', - type: 'source', - handleIndex: edge.sourcePort?.handleIndex || 0, - attr: edge.sourcePort?.attr, - attrItemIndex: edge.sourcePort?.attrItemIndex, - }), - targetHandle: getHandleId({ - nodeId: edge.target || '', - type: 'target', - handleIndex: edge.targetPort?.handleIndex || 0, - attr: edge.targetPort?.attr, - attrItemIndex: edge.targetPort?.attrItemIndex, - }), - markerEnd: { - type: MarkerType.ArrowClosed, - color: options.markerEndColor, - }, - zIndex: 1001, - }; - }) || [], - }; -} - -export function flowData2RenderData(flowData: FlowData): FlowRenderData { - return { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - nodes: flowData.nodes.map(({ id, data, type, ...node }) => { - return { - ...node, - name: data.name, - id, - title: data.title, - data: data.attrs || {}, - }; - }), - edges: flowData.edges.map( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - ({ sourceHandle, targetHandle, type, markerEnd, zIndex, ...edge }) => { - const { - attr: sourceAttr, - attrItemIndex: sourceAttrItem, - handleIndex: sourceHandleIndex = 0, - } = parseHandleIdObject(sourceHandle || ''); - const { - attr: targetAttr, - attrItemIndex: targetAttrItem, - handleIndex: targetHandleIndex = 0, - } = parseHandleIdObject(targetHandle || ''); - return { - ...edge, - id: edge.id, - sourcePort: { - attr: sourceAttr, - attrItemIndex: sourceAttrItem ? +sourceAttrItem : undefined, - handleIndex: +sourceHandleIndex, - }, - targetPort: { - attr: targetAttr, - attrItemIndex: targetAttrItem ? +targetAttrItem : undefined, - handleIndex: +targetHandleIndex, - }, - }; - } - ), - }; -} - -// ***** data ***** - -// ***** misc ***** - -export function updateNodeAttrs( - node: FlowNode, - attrs: Record, - replace = false -): FlowNode { - return { - ...node, - data: { - ...node.data, - attrs: replace - ? attrs - : { - ...( - node.data as { - attrs: Record; - } - ).attrs, - ...attrs, - }, - }, - }; -} - -export function createId() { - const timestamp = Date.now().toString(36); - const randomPart = Math.random().toString(36).substring(2, 12); - return timestamp + randomPart; -} - -// ***** misc ***** diff --git a/frontend/legacy/compiled/src/Markdown/components/Anchor.tsx b/frontend/legacy/compiled/src/Markdown/components/Anchor.tsx deleted file mode 100644 index 0eb39d45..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/Anchor.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import type { Components } from 'react-markdown'; - -export const Anchor: Components['a'] = ({ children, href }) => { - if (children) { - return ( - e.stopPropagation()} - rel="noreferrer" - > - {React.Children.toArray(children)[0]} - - ); - } else { - return <>{'[](' + href + ')'}; - } -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/Audio.tsx b/frontend/legacy/compiled/src/Markdown/components/Audio.tsx deleted file mode 100644 index 48086cbe..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/Audio.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import type { Components } from 'react-markdown'; - -import { FileView } from '../../FileView'; - -export const Audio: Components['audio'] = (props) => { - return ; -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/Code.tsx b/frontend/legacy/compiled/src/Markdown/components/Code.tsx deleted file mode 100644 index a330521a..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/Code.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import React, { useState } from 'react'; -import type { Components } from 'react-markdown'; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; -import { - oneDark, - oneLight, -} from 'react-syntax-highlighter/dist/esm/styles/prism'; -import { CheckOutlined, CopyOutlined } from '@ant-design/icons'; -import cls from 'classnames'; - -import { useMarkdownContext } from '../context'; - -const CopyButton: React.FC<{ value: string }> = ({ value }) => { - const [copied, setCopied] = useState(false); - - const onCopy = async () => { - const feedback = () => { - setCopied(true); - setTimeout(() => { - setCopied(false); - }, 2000); - }; - if ('clipboard' in navigator) { - await navigator.clipboard.writeText(value); - feedback(); - } else { - const textArea = document.createElement('textarea'); - textArea.value = value; - - textArea.style.position = 'absolute'; - textArea.style.left = '-999999px'; - - document.body.prepend(textArea); - textArea.select(); - - try { - document.execCommand('copy'); - feedback(); - } catch (error) { - console.error(error); - } finally { - textArea.remove(); - } - } - }; - return copied ? : ; -}; - -export const Code: Components['code'] = ({ children, className, ...props }) => { - const { theme } = useMarkdownContext(); - const match = /language-(\w+)/.exec(className || ''); - const matchLang = match && match[1] ? match[1].toLowerCase() : ''; - const childrenArray = React.Children.toArray(children); - const isCodeString = - childrenArray.length === 1 && typeof childrenArray[0] === 'string'; - if ((props as any).inline || !isCodeString) { - return ( - - {children} - - ); - } - const code = String(children).replace(/\n$/, ''); - return ( -
-
- - {matchLang || 'code'} - - - - -
- - {code} - -
- ); -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/CustomComponent.tsx b/frontend/legacy/compiled/src/Markdown/components/CustomComponent.tsx deleted file mode 100644 index bed8f52f..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/CustomComponent.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useMemo, useRef } from 'react'; - -import { useCustomComponent } from '../../shared'; -import { useMarkdownContext } from '../context'; -import { useCustomProps } from '../hooks/useCustomProps'; - -export interface CustomComponentProps { - node: { - children: any[]; - tagName: string; - }; - [prop: PropertyKey]: any; -} - -export const CustomComponent: React.FC = (nodeProps) => { - const [{ node, ...props }, { tagIndex, tagEnd }] = useCustomProps(nodeProps); - const divRef = useRef(null); - const tag = node.tagName; - const { on_custom, custom_components, theme, locale } = useMarkdownContext(); - - const onCustom = (data?: any) => { - on_custom(tag, tagIndex, data); - }; - - const extraProps = useMemo(() => { - return { - children: node.children, - }; - }, [node.children]); - - useCustomComponent({ - target: divRef, - component: custom_components[tag], - componentProps: props, - extraProps, - onCustom, - theme, - locale, - onBeforeRender: () => tagEnd, - }); - - return
; -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/Heading.tsx b/frontend/legacy/compiled/src/Markdown/components/Heading.tsx deleted file mode 100644 index 2b11b158..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/Heading.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { useMemo } from 'react'; -import type { Components } from 'react-markdown'; -import cls from 'classnames'; -import GithubSlugger from 'github-slugger'; - -import { useMarkdownContext } from '../context'; - -const LINK_ICON_CODE = ``; -export interface HeadingProps { - children: React.ReactNode[]; -} -const slugger = new GithubSlugger(); - -export const Heading: Components['h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'] = ({ - children, - node, - ...props -}) => { - const { header_links, text } = useMarkdownContext(); - - const id = useMemo(() => { - if (!header_links) { - return ''; - } - if (node) { - if (node.children[0].type === 'text') { - return 'h-' + slugger.slug(node.children[0].value); - } - const raw = text.slice( - node.position?.start.offset, - node.position?.end.offset - ); - return ( - 'h-' + - slugger.slug( - raw - .replace(/^#*/gi, '') - .replace(/<[!/a-z].*?>/gi, '') - .trim() - ) - ); - } - - return 'h-' + slugger.slug(String(children)); - }, [children, header_links, node, text]); - return ( - <> - {React.createElement( - node?.tagName || 'h1', - { - ...props, - className: cls(props.className, 'ms-markdown-heading'), - }, - <> - {header_links ? ( - - ) : null} - {children} - - )} - - ); -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/Image.tsx b/frontend/legacy/compiled/src/Markdown/components/Image.tsx deleted file mode 100644 index 4dad3c31..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/Image.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import type { Components } from 'react-markdown'; -import type { ImageProps } from 'antd'; - -import { FileView } from '../../FileView'; -import { useMarkdownContext } from '../context'; - -export const Image: Components['img'] = (props) => { - const { preview } = useMarkdownContext(); - return ( - - ); -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/Video.tsx b/frontend/legacy/compiled/src/Markdown/components/Video.tsx deleted file mode 100644 index bec424f8..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/Video.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import type { Components } from 'react-markdown'; - -import { FileView } from '../../FileView'; - -export const Video: Components['video'] = (props) => { - return ; -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/custom/Accordion.tsx b/frontend/legacy/compiled/src/Markdown/components/custom/Accordion.tsx deleted file mode 100644 index 8476a773..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/custom/Accordion.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import type { Components } from 'react-markdown'; -import { CaretRightOutlined } from '@ant-design/icons'; -import { Collapse } from 'antd'; -import cls from 'classnames'; - -import { useMarkdownContext } from '../../context'; -import { useCustomProps } from '../../hooks/useCustomProps'; - -export interface AccordionProps { - children?: React.ReactNode[]; - title?: string; - node: { - tagName: string; - }; -} - -export interface AccordionTitleProps extends AccordionProps { - onClick: () => void; -} - -export const AccordionTitle: Components['accordion-title'] = ({ - children, - onClick, -}) => { - const childrenCount = React.Children.count(children); - const lastInnerElementString = - typeof React.Children.toArray(children)[childrenCount - 1] === 'string'; - return ( -
- {children} -
- ); -}; - -export const AccordionBody: React.FC<{ - children: React.ReactNode; -}> = ({ children }) => { - const childrenCount = React.Children.count(children); - const lastInnerElementString = - typeof React.Children.toArray(children)[childrenCount - 1] === 'string'; - return ( -
- {children} -
- ); -}; - -export const Accordion: Components['accordion'] = (nodeProps) => { - const { flushing, end, last_flushing_end_index } = useMarkdownContext(); - const [{ children, title, node }, { tagEnd }] = useCustomProps(nodeProps); - const textEnd = - typeof end === 'boolean' - ? (last_flushing_end_index || 0) > (node.position?.end.offset || 0) || end - : true; - const flushingEnd = flushing ? tagEnd : true; - - const hasEnd = flushingEnd && textEnd; - const [open, setOpen] = useState(!hasEnd); - let renderTitle: React.ReactNode = null; - const renderBodyChildrenArray: React.ReactNode[] = []; - - React.Children.forEach(children, (child) => { - if ( - React.isValidElement(child) && - child.props?.node?.tagName === 'accordion-title' - ) { - renderTitle = child; - return; - } - - renderBodyChildrenArray.push(child); - }); - const renderBody = {renderBodyChildrenArray}; - useEffect(() => { - // eslint-disable-next-line react-hooks/set-state-in-effect - setOpen(!hasEnd); - }, [hasEnd]); - - return ( -
- { - setOpen(!open); - }} - activeKey={open ? ['default'] : []} - expandIcon={({ isActive }) => ( - - )} - > - - {renderBody} - - -
- ); -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/custom/Chart.tsx b/frontend/legacy/compiled/src/Markdown/components/custom/Chart.tsx deleted file mode 100644 index 398f6b7c..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/custom/Chart.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useEffect, useMemo, useRef, useState } from 'react'; -import type { Components } from 'react-markdown'; -import { Spin } from 'antd'; -import cls from 'classnames'; -import type { EChartsCoreOption } from 'echarts'; - -import { safeParseJSON } from '../../../utils'; -import { useMarkdownContext } from '../../context'; - -export interface ChartProps { - options?: string; - style?: React.CSSProperties; - className?: string; -} - -const langs: Record = { - 'en-US': 'en', - 'zh-CN': 'zh', -}; - -let echarts: typeof import('echarts') | undefined; - -export const Chart: Components['chart'] = (props) => { - const { options: _options = '', style, className } = props; - const { theme, locale } = useMarkdownContext(); - const [asyncEcharts, setAsyncEcharts] = useState< - typeof import('echarts') | undefined - >(echarts); - const divRef = useRef(null); - const options = useMemo(() => { - return safeParseJSON(_options, {} as EChartsCoreOption); - }, [_options]); - - useEffect(() => { - if (!echarts) { - import('echarts').then((r) => { - echarts = r; - setAsyncEcharts(echarts); - }); - return; - } - const el = divRef.current; - if (!el || !asyncEcharts) { - return; - } - const instance = asyncEcharts.init(el, theme, { - locale: langs[locale] || 'en', - }); - instance.setOption(options, true); - let timeout: ReturnType; - const resizeObserver = new ResizeObserver((entries) => { - const entry = entries[0]; - if (!entry) { - return; - } - timeout && clearTimeout(timeout); - timeout = setTimeout(() => { - instance.resize(); - }, 500); - }); - resizeObserver.observe(el); - return () => { - instance.dispose(); - resizeObserver.disconnect(); - }; - }, [asyncEcharts, locale, options, theme]); - - return ( - -
- - ); -}; - -export default Chart; diff --git a/frontend/legacy/compiled/src/Markdown/components/custom/File.tsx b/frontend/legacy/compiled/src/Markdown/components/custom/File.tsx deleted file mode 100644 index 5f9dce05..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/custom/File.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import type { Components } from 'react-markdown'; -import { - FileImageOutlined, - FileOutlined, - FilePdfOutlined, -} from '@ant-design/icons'; - -import { FileView } from '../../../FileView'; -import { getURLFileExtension } from '../../../utils'; -import { useCustomProps } from '../../hooks/useCustomProps'; - -export interface FileProps extends Record { - title?: string; - src?: string; - type?: string; - children: string[]; - height?: number; - viewable?: string; - width?: number; -} - -export const File: Components['file'] = (nodeProps) => { - const [ - { title = '', src, children = [], viewable: _viewable, type, ...props }, - ] = useCustomProps(nodeProps); - const viewable = typeof _viewable === 'string'; - let url = src || children[0]; - if ( - React.isValidElement<{ node: any; href: string }>(url) && - url.props.node.tagName === 'a' - ) { - url = url.props.href; - } - if (typeof url !== 'string') { - return <>{url}; - } - let icon = ; - let view: React.ReactNode = null; - if (viewable) { - const isFiletype = (filetype: string | string[]) => - (Array.isArray(filetype) ? filetype : [filetype]).some( - (item) => - (title && title.endsWith(`.${item}`)) || - (!title && getURLFileExtension(url) === item) - ); - if (type === 'pdf' || isFiletype('pdf')) { - icon = ; - view = ; - } else if ( - type === 'image' || - isFiletype(['png', 'jpg', 'jpeg', 'webp', 'gif']) - ) { - icon = ; - view = ; - } - } - - return ( - <> - - {view} - - ); -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/custom/FlushingEnd.tsx b/frontend/legacy/compiled/src/Markdown/components/custom/FlushingEnd.tsx deleted file mode 100644 index 77566d57..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/custom/FlushingEnd.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import type { Components } from 'react-markdown'; - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface FlushingEndProps {} - -export const FlushingEnd: Components['flushing-end'] = () => { - return null; -}; diff --git a/frontend/legacy/compiled/src/Markdown/components/custom/SelectBox.tsx b/frontend/legacy/compiled/src/Markdown/components/custom/SelectBox.tsx deleted file mode 100644 index e172110c..00000000 --- a/frontend/legacy/compiled/src/Markdown/components/custom/SelectBox.tsx +++ /dev/null @@ -1,270 +0,0 @@ -import { useEffect, useMemo, useState } from 'react'; -import type { Components } from 'react-markdown'; -import type { CheckboxOptionType, ColProps } from 'antd'; -import { Button, Card, Checkbox, Col, Radio, Row, Space } from 'antd'; -import type { CheckboxGroupProps } from 'antd/es/checkbox'; -import cls from 'classnames'; -import { isObject } from 'lodash-es'; - -import { FileView } from '../../../FileView'; -import { safeParseJSON } from '../../../utils'; -import { useMarkdownContext } from '../../context'; -import { useCustomProps } from '../../hooks/useCustomProps'; - -export interface SelectBoxProps { - type?: 'checkbox' | 'radio'; - direction?: 'horizontal' | 'vertical'; - shape?: 'card' | 'default'; - disabled?: boolean; - value?: string; - options?: string; - 'submit-text'?: string; - 'select-once'?: string; // boolean - // card - 'item-width'?: string; - 'item-height'?: string; - 'img-height'?: string; - 'equal-height'?: string; // boolean - columns?: string; // number | { xs: number, sm: number, md: number, lg: number, xl: number, xxl: number } -} - -const custom_tag = 'select-box'; - -export const SelectBox: Components['select-box'] = (nodeProps) => { - const [ - { - direction, - shape = 'default', - type = 'radio', - 'img-height': imgHeight = '160px', - 'item-height': itemHeight, - 'item-width': itemWidth, - 'submit-text': submitText, - 'select-once': _selectOnce, - 'equal-height': _equalHeight, - columns, - ...props - }, - { tagIndex }, - ] = useCustomProps(nodeProps); - - const selectOnce = typeof _selectOnce === 'string'; - const equalHeight = typeof _equalHeight === 'string'; - const { on_custom, preview, disabled: ctxDisabled } = useMarkdownContext(); - const spans: ColProps = useMemo(() => { - if (direction !== 'vertical' && columns) { - if (!Number.isNaN(Number(columns))) { - return { - span: Math.round(24 / Number(columns)), - }; - } - - const columnsObject = safeParseJSON<{ - xs?: number; - sm?: number; - md?: number; - lg?: number; - xl?: number; - xxl?: number; - }>(columns || '', {}); - - const _spans = Object.keys(columnsObject).reduce((acc, key) => { - if (['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key)) { - (acc as any)[key] = Math.round( - 24 / Number(columnsObject[key as keyof typeof columnsObject]) - ); - } - return acc; - }, {} as ColProps); - - if (Object.keys(_spans).length) { - return _spans; - } - } - - return itemWidth - ? { - span: direction === 'vertical' ? 24 : undefined, - } - : { - xs: 24, - sm: direction === 'vertical' ? 24 : 12, - md: direction === 'vertical' ? 24 : 12, - lg: direction === 'vertical' ? 24 : 6, - }; - }, [columns, direction, itemWidth]); - const defaultValue: CheckboxGroupProps['defaultValue'] | string = - useMemo(() => { - if (type === 'radio') { - return props.value; - } - return safeParseJSON(props.value || '', []); - }, [props.value, type]); - const [disabled, setDisabled] = useState(ctxDisabled || !!props.disabled); - - useEffect(() => { - setDisabled(ctxDisabled || !!props.disabled); - }, [ctxDisabled, props.disabled]); - - const options: (CheckboxOptionType & { - imgSrc?: string; - })[] = useMemo(() => { - return safeParseJSON(props.options || '', []).map((option) => { - if (!isObject(option)) { - return { - value: option, - label: option, - }; - } - return option; - }); - }, [props.options]); - const [value, setValue] = useState(defaultValue); - useEffect(() => { - setValue(defaultValue); - }, [defaultValue]); - let selectElement: React.ReactNode = null; - - const onCustom = (v: any) => { - on_custom(custom_tag, tagIndex, v); - }; - - if (shape === 'card') { - selectElement = ( - - {options.map((option, index) => { - const label = option.label || option.value; - const selected = - type === 'checkbox' - ? value?.includes(option.value as string) - : option.value === value; - - return ( - - { - if (disabled) { - return; - } - let newValue: CheckboxGroupProps['value'] | string = - option.value as string; - if (type === 'checkbox' && Array.isArray(value)) { - if (value.includes(option.value as string)) { - newValue = value.filter((v) => v !== option.value); - } else { - newValue = [...value, option.value]; - } - } - setValue(newValue); - if (selectOnce && !submitText) { - onCustom(newValue); - setDisabled(true); - } - }} - className={cls( - 'ms-markdown-select-box-card', - equalHeight && 'ms-markdown-select-box-card-equal-height', - selected && 'ms-markdown-select-box-card-selected', - disabled && 'ms-markdown-select-box-card-disabled' - )} - size="small" - cover={ - option.imgSrc ? ( - - ) : null - } - > - {label} - - - ); - })} - - ); - } else if (type === 'radio') { - selectElement = ( - { - setValue(e.target.value); - if (selectOnce && !submitText) { - onCustom(e.target.value); - setDisabled(true); - } - }} - value={value} - > - - {options.map((option, index) => { - return ( - - {option.label || option.value} - - ); - })} - - - ); - } else if (type === 'checkbox') { - selectElement = ( - { - setValue(v); - if (selectOnce && !submitText) { - onCustom(v); - setDisabled(true); - } - }} - > - - {options.map((option, index) => { - return ( - - {option.label || option.value} - - ); - })} - - - ); - } - - return ( - <> - {selectElement} - {submitText && !disabled && ( -
- -
- )} - - ); -}; diff --git a/frontend/legacy/compiled/src/Markdown/context.ts b/frontend/legacy/compiled/src/Markdown/context.ts deleted file mode 100644 index 9140d809..00000000 --- a/frontend/legacy/compiled/src/Markdown/context.ts +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; - -import type { CustomComponents } from '../shared'; - -export interface MarkdownContextValue { - text: string; - end?: boolean; - preview?: boolean; - disabled?: boolean; - last_flushing_end_index?: number; - header_links?: boolean; - flushing?: boolean; - locale: string; - theme: 'light' | 'dark'; - on_custom: (tag: string, tagIndex: number, data?: any) => void; - custom_components: CustomComponents; -} - -export const MarkdownContext = React.createContext({ - text: '', - theme: 'light', - locale: 'en-US', - on_custom: () => {}, - custom_components: {}, -}); - -export const useMarkdownContext = () => React.useContext(MarkdownContext); diff --git a/frontend/legacy/compiled/src/Markdown/hooks/useCustomProps.ts b/frontend/legacy/compiled/src/Markdown/hooks/useCustomProps.ts deleted file mode 100644 index 1122a73a..00000000 --- a/frontend/legacy/compiled/src/Markdown/hooks/useCustomProps.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { useMemo } from 'react'; - -import { getCustomProps } from '../../utils'; -import { useMarkdownContext } from '../context'; - -export function useCustomProps< - T extends { - node?: Record; - }, ->( - nodeProps: T -): [ - T, - { - tagIndex: number; - tagEnd: boolean; - }, -] { - const { text } = useMarkdownContext(); - const tagProps = useMemo(() => { - const node = nodeProps.node; - const matches = text - ?.slice(0, node?.position?.start?.offset) - .match(new RegExp(`<${node?.tagName}`, 'g')); - return { - tagIndex: matches?.length || 0, - tagEnd: - typeof text[node?.position?.end.offset || 0] === 'string' || - text.endsWith(``), - }; - }, [nodeProps.node, text]); - - return [getCustomProps(nodeProps), tagProps]; -} diff --git a/frontend/legacy/compiled/src/Markdown/index.less b/frontend/legacy/compiled/src/Markdown/index.less deleted file mode 100644 index 0fe58be2..00000000 --- a/frontend/legacy/compiled/src/Markdown/index.less +++ /dev/null @@ -1,218 +0,0 @@ -.ms-markdown { - a, - a:hover { - color: #2f81f7; - } - - &.markdown-body { - color: inherit; - font-size: inherit; - background: none; - - pre:has(.ms-markdown-code) { - padding: 0; - overflow: unset; - background-color: var(--code-background-fill) !important; - } - - /* KaTeX */ - span.katex { - font-size: var(--text-lg); - direction: ltr; - } - } - - & &-select-box-card { - width: 100%; - cursor: pointer; - - &-equal-height { - height: 100%; - } - - &:hover:not(.ms-markdown-select-box-card-disabled) { - border-color: var(--primary-300); - } - - &-disabled { - color: var(--ant-color-text-disabled); - cursor: not-allowed; - } - - &.ms-markdown-select-box-card-selected { - &:hover { - border-color: var(--primary-500); - } - - border-color: var(--primary-500); - } - - .ant-card-cover { - margin: 0; - } - - img, - .ant-image-mask { - width: 100% !important; - border-radius: var(--ant-border-radius-lg) var(--ant-border-radius-lg) 0 0 !important; - } - - .ant-image { - width: 100%; - - img { - width: 100%; - object-fit: cover; - } - } - } - - & &-select-box-submit-btn { - margin-top: 8px; - - button { - background-color: var(--ant-color-primary); - } - } - - &-chart { - width: 100%; - height: 200px; - } - - &-heading { - display: flex; - align-items: center; - - &-anchor { - margin-left: -25px; - padding-right: 8px; - color: var(--body-text-color-subdued); - line-height: 1; - opacity: 0; - - > svg { - color: var(--body-text-color-subdued); - } - } - - &:hover { - .ms-markdown-heading-anchor { - opacity: 1; - } - } - } - - &-accordion { - p, - li { - font-size: 16px; - } - - .ant-collapse-header { - outline: none !important; - } - } - - &-code { - &-header { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - height: 36px; - padding: 5px 1em; - /* stylelint-disable-next-line color-function-alias-notation */ - background-color: rgba(0, 0, 0, 0.03); - - &-copy { - color: var(--body-text-color-subdued); - font-size: 17px; - cursor: pointer; - - &:hover { - color: var(--body-text-color); - } - } - } - - &&-dark { - .ms-markdown-code-header { - background-color: #222; - } - } - } - - .dot-blink() { - margin-left: 3px; - color: var(--color-accent); - font-weight: bold; - vertical-align: baseline; - animation: blink 1s steps(5, start) infinite; - content: '_' !important; - } - .handle-elements() { - .handle() { - & > p, - & > dt, - & > dd, - & > h1, - & > h2, - & > h3, - & > h4, - & > h5, - & > h6, - & > td, - & > pre:last-child code { - &:last-child { - &::after { - .dot-blink(); - } - } - } - } - - .handle(); - - & > ol:last-child li, - & > ul:last-child li { - &:last-child { - &:not(:has(p, dt, dd, h1, h2, h3, h4, h5, h6, td, pre)) { - &::after { - .dot-blink(); - } - } - .handle(); - } - } - } - - &-flushing { - .handle-elements(); - } - - &-flushing > .ms-markdown-accordion.ms-markdown-accordion-typing { - .ms-markdown-accordion-title:last-child, - .ms-markdown-accordion-body:last-child { - &-typing-string { - &::after { - .dot-blink(); - } - } - - .handle-elements(); - } - } - - &-flushing-empty { - &::after { - .dot-blink(); - } - } - - @keyframes blink { - to { - visibility: hidden; - } - } -} diff --git a/frontend/legacy/compiled/src/Markdown/index.tsx b/frontend/legacy/compiled/src/Markdown/index.tsx deleted file mode 100644 index 97cadd9a..00000000 --- a/frontend/legacy/compiled/src/Markdown/index.tsx +++ /dev/null @@ -1,282 +0,0 @@ -import { useEffect, useMemo } from 'react'; -import type { Options as ReactMarkdownOptions } from 'react-markdown'; -import ReactMarkdown, { defaultUrlTransform } from 'react-markdown'; -import cls from 'classnames'; -import deepmerge from 'deepmerge'; -import dark from 'github-markdown-css/github-markdown-dark.css?inline'; -import light from 'github-markdown-css/github-markdown-light.css?inline'; -import rehypeKatex from 'rehype-katex'; -import rehypeRaw from 'rehype-raw'; -import remarkBreaks from 'remark-breaks'; -import remarkDirective from 'remark-directive'; -import remarkGfm from 'remark-gfm'; -import remarkMath from 'remark-math'; - -import { defineComponent } from '../defineComponent'; - -import { Anchor } from './components/Anchor'; -import { Audio } from './components/Audio'; -import { Code } from './components/Code'; -import { Accordion, AccordionTitle } from './components/custom/Accordion'; -import { Chart } from './components/custom/Chart'; -import { File } from './components/custom/File'; -import { FlushingEnd } from './components/custom/FlushingEnd'; -import { SelectBox } from './components/custom/SelectBox'; -import { CustomComponent } from './components/CustomComponent'; -import { Heading } from './components/Heading'; -import { Image } from './components/Image'; -import { Video } from './components/Video'; -import rehypeInlineCodeProperty from './rehype-plugins/rehype-Inline-code-property'; -import rehypeSanitize, { - defaultSchema, -} from './rehype-plugins/rehype-sanitize'; -import remarkDirectiveRehype from './remark-plugins/remark-directive-rehype'; -import type { MarkdownContextValue } from './context'; -import { MarkdownContext } from './context'; -import { - type RenderMathInElementSpecificOptionsDelimiters, - resolveDelimiters, -} from './math'; - -import 'katex/dist/katex.min.css'; -import './index.less'; - -export type * from './type'; -export interface MarkdownProps extends MarkdownContextValue { - sanitize_html?: boolean; - flushing?: boolean; - preview?: boolean; - disabled?: boolean; - render_markdown?: boolean; - line_breaks?: boolean; - on_load?: () => void; - header_links?: boolean; - last_flushing_end_index?: number; - enable_latex?: boolean; - latex_single_dollar_delimiter?: boolean; - enable_base64?: boolean; - latex_delimiters?: RenderMathInElementSpecificOptionsDelimiters[]; -} - -const buildInCustomComponents = { - 'select-box': SelectBox, - 'accordion-title': AccordionTitle, - accordion: Accordion, - 'flushing-end': FlushingEnd, - file: File, - chart: Chart, -}; - -const defaultCustomComponents: MarkdownProps['custom_components'] = {}; - -export const Markdown = defineComponent((props) => { - const { - render_markdown = true, - sanitize_html = true, - text: _text = '', - line_breaks = true, - flushing, - className, - disabled, - style, - preview = true, - theme = 'light', - locale, - end = true, - on_load: _on_load, - last_flushing_end_index, - latex_single_dollar_delimiter = true, - latex_delimiters, - enable_base64, - enable_latex = true, - on_custom, - header_links = false, - custom_components = defaultCustomComponents, - } = props; - const text = useMemo(() => { - const v = _text.trim(); - if (!enable_latex) { - return v; - } - return resolveDelimiters(v, latex_delimiters); - }, [_text, latex_delimiters, enable_latex]); - - useEffect(() => { - const styleTagId = '$MODELSCOPE_STUDIO_MARKDOWN_THEME'; - if (document.getElementById(styleTagId)) { - return; - } - const styleTag = document.createElement('style'); - styleTag.id = styleTagId; - const cssRules = theme === 'dark' ? dark : light; - - if ((styleTag as any).styleSheet) { - // IE8 - (styleTag as any).styleSheet.cssText = cssRules; - } else { - styleTag.appendChild(document.createTextNode(cssRules)); - } - - document.head.appendChild(styleTag); - return () => { - document.head.removeChild(styleTag); - }; - }, [theme]); - - const custom_tags = useMemo( - () => Object.keys(custom_components || {}), - [custom_components] - ); - - const sanitizeSchema = useMemo(() => { - return deepmerge(defaultSchema, { - // deepmerge to https://github.com/syntax-tree/hast-util-sanitize/blob/main/lib/schema.js - tagNames: [ - 'video', - 'audio', - ...Object.keys(buildInCustomComponents), - ...custom_tags, - ], - attributes: { - '*': ['className', 'style', 'id', 'type'], - code: ['inline'], - source: ['src'], - file: ['src', 'viewable', 'title', 'type'], - video: ['src', 'loop', 'autoplay', 'autoPlay', 'muted', 'controls'], - audio: ['src', 'loop', 'autoplay', 'autoPlay', 'muted', 'controls'], - accordion: ['title'], - chart: ['options'], - 'select-box': [ - 'value', - 'options', - 'direction', - 'type', - 'shape', - 'disabled', - 'submit-text', - 'select-once', - 'img-height', - 'item-height', - 'item-width', - 'columns', - 'equal-height', - ], - ...custom_tags.reduce( - (acc, custom_tag) => { - acc[custom_tag] = custom_components[custom_tag].props || []; - return acc; - }, - {} as Record - ), - }, - clobberPrefix: '', - protocols: enable_base64 - ? { - src: ['data'], - } - : {}, - }); - }, [custom_components, custom_tags, enable_base64]); - - if (!render_markdown) { - return ( - - {text} - - ); - } - - return ( - - - } - remarkRehypeOptions={{ - clobberPrefix: '', - }} - rehypePlugins={ - [ - enable_latex ? rehypeKatex : null, - rehypeRaw, - rehypeInlineCodeProperty, - sanitize_html ? [rehypeSanitize, sanitizeSchema] : null, - ].filter(Boolean) as NonNullable< - ReactMarkdownOptions['rehypePlugins'] - > - } - className={cls( - 'ms-markdown', - 'markdown-body', - { - 'ms-markdown-flushing': flushing, - 'ms-markdown-flushing-empty': !text && flushing, - }, - className - )} - urlTransform={ - enable_base64 - ? (url) => { - if (url.startsWith('data:')) { - return url; - } - return defaultUrlTransform(url); - } - : undefined - } - components={{ - a: Anchor, - audio: Audio, - video: Video, - code: Code, - h1: Heading, - h2: Heading, - h3: Heading, - h4: Heading, - h5: Heading, - h6: Heading, - img: Image, - ...buildInCustomComponents, - ...custom_tags.reduce( - (acc, custom_tag) => { - acc[custom_tag] = CustomComponent; - return acc; - }, - {} as Record - ), - }} - > - {text} - - - ); -}); diff --git a/frontend/legacy/compiled/src/Markdown/math.ts b/frontend/legacy/compiled/src/Markdown/math.ts deleted file mode 100644 index 1a72e612..00000000 --- a/frontend/legacy/compiled/src/Markdown/math.ts +++ /dev/null @@ -1,108 +0,0 @@ -// override from https://github.com/KaTeX/KaTeX/blob/main/contrib/auto-render/splitAtDelimiters.js - -export interface RenderMathInElementSpecificOptionsDelimiters { - /** - * A string which starts the math expression (i.e. the left delimiter) - */ - left: string; - /** - * A string which ends the math expression (i.e. the right delimiter) - */ - right: string; - /** - * A boolean of whether the math in the expression should be rendered in display mode or not - */ - display: boolean; - - inline?: boolean; -} - -const findEndOfMath = function ( - delimiter: string, - text: string, - startIndex: number -) { - // Adapted from - // https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx - let index = startIndex; - let braceLevel = 0; - - const delimLength = delimiter.length; - - while (index < text.length) { - const character = text[index]; - - if ( - braceLevel <= 0 && - text.slice(index, index + delimLength) === delimiter - ) { - return index; - } else if (character === '\\') { - index++; - } else if (character === '{') { - braceLevel++; - } else if (character === '}') { - braceLevel--; - } - - index++; - } - - return -1; -}; - -const escapeRegex = function (string: string) { - return string.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); -}; - -const amsRegex = /^\\begin{/; - -export const resolveDelimiters = function ( - text: string, - delimiters: RenderMathInElementSpecificOptionsDelimiters[] = [] -) { - if (!delimiters || (Array.isArray(delimiters) && delimiters.length === 0)) { - return text; - } - let index: number; - let result = ''; - - const regexLeft = new RegExp( - '(' + delimiters.map((x) => escapeRegex(x.left)).join('|') + ')' - ); - - while (true) { - index = text.search(regexLeft); - if (index === -1) { - break; - } - if (index > 0) { - result += text.slice(0, index); - text = text.slice(index); // now text starts with delimiter - } - // ... so this always succeeds: - const i = delimiters.findIndex((delim) => text.startsWith(delim.left)); - index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length); - if (index === -1) { - break; - } - const rawData = text.slice(0, index + delimiters[i].right.length); - const math = amsRegex.test(rawData) - ? rawData - : text.slice(delimiters[i].left.length, index); - - text = text.slice(index + delimiters[i].right.length); - if (delimiters[i].display) { - const symbol = delimiters[i].inline ? '$' : '$$'; - result += symbol + math + symbol; - } else { - result += math; - } - } - - if (text !== '') { - result += text; - } - - return result; -}; diff --git a/frontend/legacy/compiled/src/Markdown/react-markdown.d.ts b/frontend/legacy/compiled/src/Markdown/react-markdown.d.ts deleted file mode 100644 index 9502647f..00000000 --- a/frontend/legacy/compiled/src/Markdown/react-markdown.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { - AccordionProps, - AccordionTitleProps, -} from './components/custom/Accordion'; -import type { ChartProps } from './components/custom/Chart'; -import type { FileProps } from './components/custom/File'; -import type { FlushingEndProps } from './components/custom/FlushingEnd'; -import type { SelectBoxProps } from './components/custom/SelectBox'; - -declare global { - namespace JSX { - interface IntrinsicElements { - file: FileProps; - 'select-box': SelectBoxProps; - accordion: AccordionProps; - 'accordion-title': AccordionTitleProps; - 'flushing-end': FlushingEndProps; - chart: ChartProps; - } - } -} diff --git a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-Inline-code-property.ts b/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-Inline-code-property.ts deleted file mode 100644 index 4e210b1d..00000000 --- a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-Inline-code-property.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { visit } from 'unist-util-visit'; - -function rehypeInlineCodeProperty() { - return function (tree: any) { - visit(tree, function (node, _index, parent) { - if (node.tagName === 'code') { - if (parent && parent.tagName === 'pre') { - node.properties.inline = false; - } else { - node.properties.inline = true; - } - } - }); - }; -} -export default rehypeInlineCodeProperty; diff --git a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.d.ts b/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.d.ts deleted file mode 100644 index f3616635..00000000 --- a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare function rehypeSanitize(options: any): any; -declare const defaultSchema: Record; -export { defaultSchema }; -export default rehypeSanitize; diff --git a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.js b/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.js deleted file mode 100644 index ca0d33e8..00000000 --- a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/index.js +++ /dev/null @@ -1,794 +0,0 @@ -/* eslint-disable no-shadow */ -// copied from https://github.com/syntax-tree/hast-util-sanitize/blob/main/lib/index.js -/** - * @typedef {import('hast').Comment} Comment - * @typedef {import('hast').Doctype} Doctype - * @typedef {import('hast').Element} Element - * @typedef {import('hast').ElementContent} ElementContent - * @typedef {import('hast').Nodes} Nodes - * @typedef {import('hast').Properties} Properties - * @typedef {import('hast').Root} Root - * @typedef {import('hast').RootContent} RootContent - * @typedef {import('hast').Text} Text - */ - -/** - * @typedef {[string, ...Array> | RegExp>] | string} PropertyDefinition - * Definition for a property. - * - * @typedef Schema - * Schema that defines what nodes and properties are allowed. - * - * The default schema is `defaultSchema`, which follows how GitHub cleans. - * If any top-level key is missing in the given schema, the corresponding - * value of the default schema is used. - * - * To extend the standard schema with a few changes, clone `defaultSchema` - * like so: - * - * ```js - * import deepmerge from 'deepmerge' - * import {h} from 'hastscript' - * import {defaultSchema, sanitize} from 'hast-util-sanitize' - * - * // This allows `className` on all elements. - * const schema = deepmerge(defaultSchema, {attributes: {'*': ['className']}}) - * - * const tree = sanitize(h('div', {className: ['foo']}), schema) - * - * // `tree` still has `className`. - * console.log(tree) - * // { - * // type: 'element', - * // tagName: 'div', - * // properties: {className: ['foo']}, - * // children: [] - * // } - * ``` - * @property {boolean | null | undefined} [allowComments=false] - * Whether to allow comment nodes (default: `false`). - * - * For example: - * - * ```js - * allowComments: true - * ``` - * @property {boolean | null | undefined} [allowDoctypes=false] - * Whether to allow doctype nodes (default: `false`). - * - * For example: - * - * ```js - * allowDoctypes: true - * ``` - * @property {Record> | null | undefined} [ancestors] - * Map of tag names to a list of tag names which are required ancestors - * (default: `defaultSchema.ancestors`). - * - * Elements with these tag names will be ignored if they occur outside of one - * of their allowed parents. - * - * For example: - * - * ```js - * ancestors: { - * tbody: ['table'], - * // … - * tr: ['table'] - * } - * ``` - * @property {Record> | null | undefined} [attributes] - * Map of tag names to allowed property names (default: - * `defaultSchema.attributes`). - * - * The special key `'*'` as a tag name defines property names allowed on all - * elements. - * - * The special value `'data*'` as a property name can be used to allow all - * `data` properties. - * - * For example: - * - * ```js - * attributes: { - * 'ariaDescribedBy', 'ariaLabel', 'ariaLabelledBy', …, 'href' - * // … - * '*': [ - * 'abbr', - * 'accept', - * 'acceptCharset', - * // … - * 'vAlign', - * 'value', - * 'width' - * ] - * } - * ``` - * - * Instead of a single string in the array, which allows any property value - * for the field, you can use an array to allow several values. - * For example, `input: ['type']` allows `type` set to any value on `input`s. - * But `input: [['type', 'checkbox', 'radio']]` allows `type` when set to - * `'checkbox'` or `'radio'`. - * - * You can use regexes, so for example `span: [['className', /^hljs-/]]` - * allows any class that starts with `hljs-` on `span`s. - * - * When comma- or space-separated values are used (such as `className`), each - * value in is checked individually. - * For example, to allow certain classes on `span`s for syntax highlighting, - * use `span: [['className', 'number', 'operator', 'token']]`. - * This will allow `'number'`, `'operator'`, and `'token'` classes, but drop - * others. - * @property {Array | null | undefined} [clobber] - * List of property names that clobber (default: `defaultSchema.clobber`). - * - * For example: - * - * ```js - * clobber: ['ariaDescribedBy', 'ariaLabelledBy', 'id', 'name'] - * ``` - * @property {string | null | undefined} [clobberPrefix] - * Prefix to use before clobbering properties (default: - * `defaultSchema.clobberPrefix`). - * - * For example: - * - * ```js - * clobberPrefix: 'user-content-' - * ``` - * @property {Record | null | undefined> | null | undefined} [protocols] - * Map of *property names* to allowed protocols (default: - * `defaultSchema.protocols`). - * - * This defines URLs that are always allowed to have local URLs (relative to - * the current website, such as `this`, `#this`, `/this`, or `?this`), and - * only allowed to have remote URLs (such as `https://example.com`) if they - * use a known protocol. - * - * For example: - * - * ```js - * protocols: { - * cite: ['http', 'https'], - * // … - * src: ['http', 'https'] - * } - * ``` - * @property {Record> | null | undefined} [required] - * Map of tag names to required property names with a default value - * (default: `defaultSchema.required`). - * - * This defines properties that must be set. - * If a field does not exist (after the element was made safe), these will be - * added with the given value. - * - * For example: - * - * ```js - * required: { - * input: {disabled: true, type: 'checkbox'} - * } - * ``` - * - * > 👉 **Note**: properties are first checked based on `schema.attributes`, - * > then on `schema.required`. - * > That means properties could be removed by `attributes` and then added - * > again with `required`. - * @property {Array | null | undefined} [strip] - * List of tag names to strip from the tree (default: `defaultSchema.strip`). - * - * By default, unsafe elements (those not in `schema.tagNames`) are replaced - * by what they contain. - * This option can drop their contents. - * - * For example: - * - * ```js - * strip: ['script'] - * ``` - * @property {Array | null | undefined} [tagNames] - * List of allowed tag names (default: `defaultSchema.tagNames`). - * - * For example: - * - * ```js - * tagNames: [ - * 'a', - * 'b', - * // … - * 'ul', - * 'var' - * ] - * ``` - * - * @typedef State - * Info passed around. - * @property {Readonly} schema - * Schema. - * @property {Array} stack - * Tag names of ancestors. - */ - -import structuredClone from '@ungap/structured-clone'; -import { position } from 'unist-util-position'; - -import { defaultSchema } from './schema'; - -const own = {}.hasOwnProperty; - -export { defaultSchema }; - -/** - * Sanitize a tree. - * - * @param {Readonly} node - * Unsafe tree. - * @param {Readonly | null | undefined} [options] - * Configuration (default: `defaultSchema`). - * @returns {Nodes} - * New, safe tree. - */ -export function sanitize(node, options) { - /** @type {Nodes} */ - let ctx = { type: 'root', children: [] }; - - /** @type {State} */ - const state = { - schema: options ? { ...defaultSchema, ...options } : defaultSchema, - stack: [], - }; - const replace = transform(state, node); - - if (replace) { - if (Array.isArray(replace)) { - if (replace.length === 1) { - ctx = replace[0]; - } else { - ctx.children = replace; - } - } else { - ctx = replace; - } - } - - return ctx; -} - -/** - * Sanitize `node`. - * - * @param {State} state - * Info passed around. - * @param {Readonly} node - * Unsafe node. - * @returns {Array | Nodes | undefined} - * Safe result. - */ -function transform(state, node) { - if (node && typeof node === 'object') { - const unsafe = /** @type {Record>} */ node; - const type = typeof unsafe.type === 'string' ? unsafe.type : ''; - - switch (type) { - case 'comment': { - return comment(state, unsafe); - } - - case 'doctype': { - return doctype(state, unsafe); - } - - case 'element': { - return element(state, unsafe); - } - - case 'root': { - return root(state, unsafe); - } - - case 'text': { - return text(state, unsafe); - } - - default: - return unsafe; - } - } -} - -/** - * Make a safe comment. - * - * @param {State} state - * Info passed around. - * @param {Readonly>>} unsafe - * Unsafe comment-like value. - * @returns {Comment | undefined} - * Safe comment (if with `allowComments`). - */ -function comment(state, unsafe) { - if (state.schema.allowComments) { - // See - const result = typeof unsafe.value === 'string' ? unsafe.value : ''; - const index = result.indexOf('-->'); - const value = index < 0 ? result : result.slice(0, index); - - /** @type {Comment} */ - const node = { type: 'comment', value }; - - patch(node, unsafe); - - return node; - } -} - -/** - * Make a safe doctype. - * - * @param {State} state - * Info passed around. - * @param {Readonly>>} unsafe - * Unsafe doctype-like value. - * @returns {Doctype | undefined} - * Safe doctype (if with `allowDoctypes`). - */ -function doctype(state, unsafe) { - if (state.schema.allowDoctypes) { - /** @type {Doctype} */ - const node = { type: 'doctype' }; - - patch(node, unsafe); - - return node; - } -} - -/** - * Make a safe element. - * - * @param {State} state - * Info passed around. - * @param {Readonly>>} unsafe - * Unsafe element-like value. - * @returns {Array | Element | undefined} - * Safe element. - */ -function element(state, unsafe) { - const name = typeof unsafe.tagName === 'string' ? unsafe.tagName : ''; - - state.stack.push(name); - - const content = /** @type {Array} */ children( - state, - unsafe.children - ); - const props = properties(state, unsafe.properties); - - state.stack.pop(); - - let safeElement = false; - - if ( - name && - name !== '*' && - (!state.schema.tagNames || state.schema.tagNames.includes(name)) - ) { - safeElement = true; - - // Some nodes can break out of their context if they don’t have a certain - // ancestor. - if (state.schema.ancestors && own.call(state.schema.ancestors, name)) { - const ancestors = state.schema.ancestors[name]; - let index = -1; - - safeElement = false; - - while (++index < ancestors.length) { - if (state.stack.includes(ancestors[index])) { - safeElement = true; - } - } - } - } - - if (!safeElement) { - return state.schema.strip && !state.schema.strip.includes(name) - ? content - : undefined; - } - - /** @type {Element} */ - const node = { - type: 'element', - tagName: name, - properties: props, - children: content, - }; - - patch(node, unsafe); - - return node; -} - -/** - * Make a safe root. - * - * @param {State} state - * Info passed around. - * @param {Readonly>>} unsafe - * Unsafe root-like value. - * @returns {Root} - * Safe root. - */ -function root(state, unsafe) { - const content = /** @type {Array} */ children( - state, - unsafe.children - ); - - /** @type {Root} */ - const node = { type: 'root', children: content }; - - patch(node, unsafe); - - return node; -} - -/** - * Make a safe text. - * - * @param {State} _ - * Info passed around. - * @param {Readonly>>} unsafe - * Unsafe text-like value. - * @returns {Text} - * Safe text. - */ -function text(_, unsafe) { - const value = typeof unsafe.value === 'string' ? unsafe.value : ''; - /** @type {Text} */ - const node = { type: 'text', value }; - - patch(node, unsafe); - - return node; -} - -/** - * Make children safe. - * - * @param {State} state - * Info passed around. - * @param {Readonly} children - * Unsafe value. - * @returns {Array} - * Safe children. - */ -function children(state, children) { - /** @type {Array} */ - const results = []; - - if (Array.isArray(children)) { - const childrenUnknown = /** @type {Array>} */ children; - let index = -1; - - while (++index < childrenUnknown.length) { - const value = transform(state, childrenUnknown[index]); - - if (value) { - if (Array.isArray(value)) { - results.push(...value); - } else { - results.push(value); - } - } - } - } - - return results; -} - -/** - * Make element properties safe. - * - * @param {State} state - * Info passed around. - * @param {Readonly} properties - * Unsafe value. - * @returns {Properties} - * Safe value. - */ -function properties(state, properties) { - const tagName = state.stack[state.stack.length - 1]; - const attributes = state.schema.attributes; - const required = state.schema.required; - const specific = - attributes && own.call(attributes, tagName) - ? attributes[tagName] - : undefined; - const defaults = - attributes && own.call(attributes, '*') ? attributes['*'] : undefined; - const props = - /** @type {Readonly>>} */ properties && - typeof properties === 'object' - ? properties - : {}; - /** @type {Properties} */ - const result = {}; - /** @type {string} */ - let key; - - for (key in props) { - if (own.call(props, key)) { - const unsafe = props[key]; - let safe = propertyValue( - state, - findDefinition(specific, key), - key, - unsafe - ); - - if (safe === null || safe === undefined) { - safe = propertyValue(state, findDefinition(defaults, key), key, unsafe); - } - - if (safe !== null && safe !== undefined) { - result[key] = safe; - } - } - } - - if (required && own.call(required, tagName)) { - const properties = required[tagName]; - - for (key in properties) { - if (own.call(properties, key) && !own.call(result, key)) { - result[key] = properties[key]; - } - } - } - - return result; -} - -/** - * Sanitize a property value. - * - * @param {State} state - * Info passed around. - * @param {Readonly | undefined} definition - * Definition. - * @param {string} key - * Field name. - * @param {Readonly} value - * Unsafe value (but an array). - * @returns {Array | boolean | number | string | undefined} - * Safe value. - */ -function propertyValue(state, definition, key, value) { - return definition - ? Array.isArray(value) - ? propertyValueMany(state, definition, key, value) - : propertyValuePrimitive(state, definition, key, value) - : undefined; -} - -/** - * Sanitize a property value which is a list. - * - * @param {State} state - * Info passed around. - * @param {Readonly} definition - * Definition. - * @param {string} key - * Field name. - * @param {Readonly>>} values - * Unsafe value (but an array). - * @returns {Array} - * Safe value. - */ -function propertyValueMany(state, definition, key, values) { - let index = -1; - /** @type {Array} */ - const result = []; - - while (++index < values.length) { - const value = propertyValuePrimitive(state, definition, key, values[index]); - - if (typeof value === 'number' || typeof value === 'string') { - result.push(value); - } - } - - return result; -} - -/** - * Sanitize a property value which is a primitive. - * - * @param {State} state - * Info passed around. - * @param {Readonly} definition - * Definition. - * @param {string} key - * Field name. - * @param {Readonly} value - * Unsafe value (but not an array). - * @returns {boolean | number | string | undefined} - * Safe value. - */ -function propertyValuePrimitive(state, definition, key, value) { - if ( - typeof value !== 'boolean' && - typeof value !== 'number' && - typeof value !== 'string' - ) { - return; - } - - if (!safeProtocol(state, key, value)) { - return; - } - - // Just a string, or only one item in an array, means all values are OK. - // More than one item means an allow list. - if (typeof definition === 'object' && definition.length > 1) { - let ok = false; - let index = 0; // Ignore `key`, which is the first item. - - while (++index < definition.length) { - const allowed = definition[index]; - - // Expression. - if (allowed && typeof allowed === 'object' && 'flags' in allowed) { - if (allowed.test(String(value))) { - ok = true; - break; - } - } - // Primitive. - else if (allowed === value) { - ok = true; - break; - } - } - - if (!ok) return; - } - - return state.schema.clobber && - state.schema.clobberPrefix && - state.schema.clobber.includes(key) - ? state.schema.clobberPrefix + value - : value; -} - -/** - * Check whether `value` is a safe URL. - * - * @param {State} state - * Info passed around. - * @param {string} key - * Field name. - * @param {Readonly} value - * Unsafe value. - * @returns {boolean} - * Whether it’s a safe value. - */ -function safeProtocol(state, key, value) { - const protocols = - state.schema.protocols && own.call(state.schema.protocols, key) - ? state.schema.protocols[key] - : undefined; - - // No protocols defined? Then everything is fine. - if (!protocols || protocols.length === 0) { - return true; - } - - const url = String(value); - const colon = url.indexOf(':'); - const questionMark = url.indexOf('?'); - const numberSign = url.indexOf('#'); - const slash = url.indexOf('/'); - - if ( - colon < 0 || - // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol. - (slash > -1 && colon > slash) || - (questionMark > -1 && colon > questionMark) || - (numberSign > -1 && colon > numberSign) - ) { - return true; - } - - let index = -1; - - while (++index < protocols.length) { - const protocol = protocols[index]; - - if ( - colon === protocol.length && - url.slice(0, protocol.length) === protocol - ) { - return true; - } - } - - return false; -} - -/** - * Add data and position. - * - * @param {Nodes} node - * Node to patch safe data and position on. - * @param {Readonly>>} unsafe - * Unsafe node-like value. - * @returns {undefined} - * Nothing. - */ -function patch(node, unsafe) { - const cleanPosition = position( - // @ts-expect-error: looks like a node. - unsafe - ); - - if (unsafe.data) { - node.data = structuredClone(unsafe.data); - } - - if (cleanPosition) node.position = cleanPosition; -} - -/** - * - * @param {Readonly> | undefined} definitions - * @param {string} key - * @returns {Readonly | undefined} - */ -function findDefinition(definitions, key) { - /** @type {PropertyDefinition | undefined} */ - let dataDefault; - let index = -1; - - if (definitions) { - while (++index < definitions.length) { - const entry = definitions[index]; - const name = typeof entry === 'string' ? entry : entry[0]; - - if (name === key) { - return entry; - } - - if (name === 'data*') dataDefault = entry; - } - } - - if (key.length > 4 && key.slice(0, 4).toLowerCase() === 'data') { - return dataDefault; - } -} - -/** - * Sanitize HTML. - * - * @param {Schema | null | undefined} [options] - * Configuration (optional). - * @returns - * Transform. - */ -export default function rehypeSanitize(options) { - /** - * @param {Root} tree - * Tree. - * @returns {Root} - * New tree. - */ - return function (tree) { - // Assume root in -> root out. - const result = /** @type {Root} */ (sanitize(tree, options)); - return result; - }; -} diff --git a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/schema.js b/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/schema.js deleted file mode 100644 index 8d40871a..00000000 --- a/frontend/legacy/compiled/src/Markdown/rehype-plugins/rehype-sanitize/schema.js +++ /dev/null @@ -1,205 +0,0 @@ -// Couple of ARIA attributes allowed in several, but not all, places. -const aria = ['ariaDescribedBy', 'ariaLabel', 'ariaLabelledBy']; - -/** - * Default schema. - * - * Follows GitHub style sanitation. - * - * @type {import('./index.js').Schema} - */ -export const defaultSchema = { - ancestors: { - tbody: ['table'], - td: ['table'], - th: ['table'], - thead: ['table'], - tfoot: ['table'], - tr: ['table'], - }, - attributes: { - a: [ - ...aria, - // Note: these 3 are used by GFM footnotes, they do work on all links. - 'dataFootnoteBackref', - 'dataFootnoteRef', - ['className', 'data-footnote-backref'], - 'href', - ], - blockquote: ['cite'], - // Note: this class is not normally allowed by GH, when manually writing - // `code` as HTML in markdown, they adds it some other way. - // We can’t do that, so we have to allow it. - code: [['className', /^language-./]], - del: ['cite'], - div: ['itemScope', 'itemType'], - dl: [...aria], - // Note: this is used by GFM footnotes. - h2: [['className', 'sr-only']], - img: [...aria, 'longDesc', 'src'], - // Note: `input` is not normally allowed by GH, when manually writing - // it in markdown, they add it from tasklists some other way. - // We can’t do that, so we have to allow it. - input: [ - ['disabled', true], - ['type', 'checkbox'], - ], - ins: ['cite'], - // Note: this class is not normally allowed by GH, when manually writing - // `li` as HTML in markdown, they adds it some other way. - // We can’t do that, so we have to allow it. - li: [['className', 'task-list-item']], - // Note: this class is not normally allowed by GH, when manually writing - // `ol` as HTML in markdown, they adds it some other way. - // We can’t do that, so we have to allow it. - ol: [...aria, ['className', 'contains-task-list']], - q: ['cite'], - section: ['dataFootnotes', ['className', 'footnotes']], - source: ['srcSet'], - summary: [...aria], - table: [...aria], - // Note: this class is not normally allowed by GH, when manually writing - // `ol` as HTML in markdown, they adds it some other way. - // We can’t do that, so we have to allow it. - ul: [...aria, ['className', 'contains-task-list']], - '*': [ - 'abbr', - 'accept', - 'acceptCharset', - 'accessKey', - 'action', - 'align', - 'alt', - 'axis', - 'border', - 'cellPadding', - 'cellSpacing', - 'char', - 'charOff', - 'charSet', - 'checked', - 'clear', - 'colSpan', - 'color', - 'cols', - 'compact', - 'coords', - 'dateTime', - 'dir', - // Note: `disabled` is technically allowed on all elements by GH. - // But it is useless on everything except `input`. - // Because `input`s are normally not allowed, but we allow them for - // checkboxes due to tasklists, we allow `disabled` only there. - 'encType', - 'frame', - 'hSpace', - 'headers', - 'height', - 'hrefLang', - 'htmlFor', - 'id', - 'isMap', - 'itemProp', - 'label', - 'lang', - 'maxLength', - 'media', - 'method', - 'multiple', - 'name', - 'noHref', - 'noShade', - 'noWrap', - 'open', - 'prompt', - 'readOnly', - 'rev', - 'rowSpan', - 'rows', - 'rules', - 'scope', - 'selected', - 'shape', - 'size', - 'span', - 'start', - 'summary', - 'tabIndex', - 'title', - 'useMap', - 'vAlign', - 'value', - 'width', - ], - }, - clobber: ['ariaDescribedBy', 'ariaLabelledBy', 'id', 'name'], - clobberPrefix: 'user-content-', - protocols: { - cite: ['http', 'https'], - href: ['http', 'https', 'irc', 'ircs', 'mailto', 'xmpp'], - longDesc: ['http', 'https'], - src: ['http', 'https'], - }, - required: { - input: { disabled: true, type: 'checkbox' }, - }, - strip: ['script'], - tagNames: [ - 'a', - 'b', - 'blockquote', - 'br', - 'code', - 'dd', - 'del', - 'details', - 'div', - 'dl', - 'dt', - 'em', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'hr', - 'i', - 'img', - // Note: `input` is not normally allowed by GH, when manually writing - // it in markdown, they add it from tasklists some other way. - // We can’t do that, so we have to allow it. - 'input', - 'ins', - 'kbd', - 'li', - 'ol', - 'p', - 'picture', - 'pre', - 'q', - 'rp', - 'rt', - 'ruby', - 's', - 'samp', - 'section', - 'source', - 'span', - 'strike', - 'strong', - 'sub', - 'summary', - 'sup', - 'table', - 'tbody', - 'td', - 'tfoot', - 'th', - 'thead', - 'tr', - 'tt', - 'ul', - 'var', - ], -}; diff --git a/frontend/legacy/compiled/src/Markdown/remark-plugins/remark-directive-rehype.ts b/frontend/legacy/compiled/src/Markdown/remark-plugins/remark-directive-rehype.ts deleted file mode 100644 index dafad733..00000000 --- a/frontend/legacy/compiled/src/Markdown/remark-plugins/remark-directive-rehype.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { h } from 'hastscript'; -import { visit } from 'unist-util-visit'; - -const directiveTagsMap: Record = { - 'llm-thinking': 'accordion', - 'llm-thinking-title': 'accordion-title', - accordion: 'accordion', - 'accordion-title': 'accordion-title', - 'flushing-end': 'flushing-end', -}; - -const transformNodeTree = (tree: any, file: any) => - visit(tree, (node) => { - if ( - node.type === 'containerDirective' || - node.type === 'leafDirective' || - node.type === 'textDirective' - ) { - if (!directiveTagsMap[node.name]) { - const fileContent: string = file.value; - node.value = fileContent.slice( - node.position?.start?.offset, - node.position?.end?.offset - ); - node.type = 'text'; - return; - } - - const data: Record = node.data || (node.data = {}); - const hast = h( - directiveTagsMap[node.name] || node.name, - node.attributes || {} - ) as any; - data.hName = hast.tagName; - data.hProperties = hast.properties; - } - }); - -const remarkDirectiveRehype = () => transformNodeTree; - -export default remarkDirectiveRehype; diff --git a/frontend/legacy/compiled/src/Markdown/type.ts b/frontend/legacy/compiled/src/Markdown/type.ts deleted file mode 100644 index 62bc0b70..00000000 --- a/frontend/legacy/compiled/src/Markdown/type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface MarkdownCustomData { - tag: string; - tag_index: number; - value?: any; -} diff --git a/frontend/legacy/compiled/src/defineComponent.tsx b/frontend/legacy/compiled/src/defineComponent.tsx deleted file mode 100644 index c4f486c4..00000000 --- a/frontend/legacy/compiled/src/defineComponent.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import type React from 'react'; - -export interface CommonProps { - className?: string; - style?: React.CSSProperties; - locale?: string; - theme?: 'light' | 'dark'; -} - -export function defineComponent

( - Atom: React.FC

-) { - return Atom as typeof Atom & E; -} diff --git a/frontend/legacy/compiled/src/index.ts b/frontend/legacy/compiled/src/index.ts deleted file mode 100644 index 0a214033..00000000 --- a/frontend/legacy/compiled/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { setup } from './polyfills'; - -setup(); -export * from './FileView'; -export * from './Flow'; -export * from './Markdown'; -export * from './mount'; -export * from './shared/type'; diff --git a/frontend/legacy/compiled/src/mount.tsx b/frontend/legacy/compiled/src/mount.tsx deleted file mode 100644 index 947ad5e8..00000000 --- a/frontend/legacy/compiled/src/mount.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; - -import type { ComponentConfigProviderProps } from './ComponentConfigProvider'; -import { ComponentConfigProvider } from './ComponentConfigProvider'; - -export function mount( - container: HTMLElement, - Component: React.ComponentType, - props: ComponentConfigProviderProps & T, - root?: ReactDOM.Root -) { - const _root = root || ReactDOM.createRoot(container); - _root.render( - - - - ); - return _root; -} diff --git a/frontend/legacy/compiled/src/polyfills.ts b/frontend/legacy/compiled/src/polyfills.ts deleted file mode 100644 index b8091bfc..00000000 --- a/frontend/legacy/compiled/src/polyfills.ts +++ /dev/null @@ -1,7 +0,0 @@ -export function setup() { - // Object.hasOwn - if (!Object.hasOwn) { - Object.hasOwn = (obj, key) => - Object.prototype.hasOwnProperty.call(obj, key); - } -} diff --git a/frontend/legacy/compiled/src/shared/hooks/useCustomComponent.ts b/frontend/legacy/compiled/src/shared/hooks/useCustomComponent.ts deleted file mode 100644 index 93ee86bb..00000000 --- a/frontend/legacy/compiled/src/shared/hooks/useCustomComponent.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { useEffect, useMemo, useRef } from 'react'; -import { isFunction } from 'lodash-es'; - -import type { CustomComponents } from '../type'; - -import { useMemoizedEqualValue } from './useMemoizedEqualValue'; -import { useRefValue } from './useRefValue'; - -function getElementNodes(html: string, attrs: Record) { - const replaceTemplate = (template: string) => { - return template.replace(/\{(\w+)\}/g, (str, key) => { - if (Reflect.has(attrs, key)) { - return attrs[key]; - } - return str; - }); - }; - const tmpEl = document.createElement('div'); - tmpEl.innerHTML = html.trim(); - - const convert = (el: HTMLElement) => { - Array.from(el.childNodes).forEach((child) => { - if (child instanceof Text) { - child.textContent = replaceTemplate(child.nodeValue || '') || null; - } else if (child instanceof HTMLElement) { - for (const attr of child.attributes) { - if (attr.name.startsWith('on')) { - const eventName = attr.name.substring(2); - const matched = attr.value.match(/\{(\w+)\}/); - if (matched && attrs[matched[1]]) { - child.addEventListener(eventName, attrs[matched[1]]); - child.removeAttribute(attr.name); - } - } else { - child.setAttribute(attr.name, replaceTemplate(attr.value)); - } - } - - if (el.childNodes.length) { - convert(child); - } - } - }); - }; - convert(tmpEl); - - return Array.from(tmpEl.childNodes); -} - -export interface CustomComponentOptions { - component: CustomComponents[string]; - componentProps: Record; - extraProps?: Record; - target: React.RefObject; - theme: string; - locale: string; - onCustom: (data?: any) => void; - onBeforeRender?: () => boolean; -} - -export function useCustomComponent(options: CustomComponentOptions) { - const { - target, - theme, - locale, - onCustom, - component, - componentProps, - extraProps, - onBeforeRender = () => true, - } = options; - const onCustomRef = useRefValue(onCustom); - const onBeforeRenderRef = useRefValue(onBeforeRender); - const onDestroyFnRef = useRef<() => void>(); - const mountRef = useRef(false); - const template = component.template || ''; - const js = component.js?.trim() || ''; - const filterProps = useMemoizedEqualValue( - useMemo(() => { - const _props = Object.keys(componentProps).reduce( - (acc, prop) => { - if (component.props?.includes(prop)) { - acc[prop] = componentProps[prop]; - } - return acc; - }, - {} as Record - ); - return { - ..._props, - ...extraProps, - }; - }, [component.props, componentProps, extraProps]) - ); - - useEffect(() => { - const el = target.current; - if (!el) { - return; - } - if (!onBeforeRenderRef.current()) { - return; - } - let userProps: Record = {}; - let onMountFn: (el: HTMLDivElement) => void | (() => void) = () => {}; - let onUpdateFn = () => {}; - let updateCallAfterMount = false; - const onMount = (callback: (el: HTMLDivElement) => void | (() => void)) => { - onMountFn = callback; - }; - const onUpdate = ( - callback: () => void, - onUpdateOptions: { callAfterMount?: boolean } - ) => { - onUpdateFn = callback; - updateCallAfterMount = onUpdateOptions?.callAfterMount || false; - }; - - if (js) { - let formattedStr = js.trim(); - if (formattedStr.startsWith(';')) { - formattedStr = formattedStr.slice(1); - } - if (formattedStr.endsWith(';')) { - formattedStr = formattedStr.slice(0, -1); - } - userProps = - new Function(`return ${formattedStr}`)()( - // props - filterProps, - // cc - { - dispatch: (value?: any) => onCustomRef.current(value), - }, - // el options - { - el, - onMount, - onUpdate, - theme, - locale, - } - ) || {}; - } - if (template) { - const attrs = { - ...filterProps, - ...userProps, - }; - const fragment = document.createDocumentFragment(); - getElementNodes(template, attrs).forEach((child) => { - fragment.appendChild(child); - }); - el.appendChild(fragment); - } - if (!mountRef.current) { - onDestroyFnRef.current = onMountFn(el) || (() => {}); - mountRef.current = true; - if (updateCallAfterMount) { - onUpdateFn(); - } - } else { - onUpdateFn(); - } - }, [ - filterProps, - js, - locale, - onBeforeRenderRef, - onCustomRef, - target, - template, - theme, - ]); - useEffect(() => { - return () => { - if (isFunction(onDestroyFnRef.current)) { - onDestroyFnRef.current(); - } - if (target.current) { - // eslint-disable-next-line react-hooks/exhaustive-deps - target.current.innerHTML = ''; - } - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -} diff --git a/frontend/legacy/compiled/src/shared/hooks/useMemoizedEqualValue.ts b/frontend/legacy/compiled/src/shared/hooks/useMemoizedEqualValue.ts deleted file mode 100644 index 7c2ac5a4..00000000 --- a/frontend/legacy/compiled/src/shared/hooks/useMemoizedEqualValue.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { useMemo, useRef } from 'react'; -import { isEqual } from 'lodash-es'; - -export function useMemoizedEqualValue(prop: T): T { - const propRef = useRef(); - return useMemo(() => { - if (isEqual(prop, propRef.current)) { - return propRef.current as T; - } - propRef.current = prop; - return prop; - }, [prop]); -} diff --git a/frontend/legacy/compiled/src/shared/hooks/useRefValue.ts b/frontend/legacy/compiled/src/shared/hooks/useRefValue.ts deleted file mode 100644 index 11976584..00000000 --- a/frontend/legacy/compiled/src/shared/hooks/useRefValue.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { useRef } from 'react'; - -export const useRefValue = (value: T) => { - const ref = useRef(value); - ref.current = value; - return ref; -}; diff --git a/frontend/legacy/compiled/src/shared/index.ts b/frontend/legacy/compiled/src/shared/index.ts deleted file mode 100644 index 20b7c41e..00000000 --- a/frontend/legacy/compiled/src/shared/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './hooks/useCustomComponent'; -export * from './hooks/useMemoizedEqualValue'; -export * from './hooks/useRefValue'; -export * from './type'; diff --git a/frontend/legacy/compiled/src/shared/type.ts b/frontend/legacy/compiled/src/shared/type.ts deleted file mode 100644 index 71337757..00000000 --- a/frontend/legacy/compiled/src/shared/type.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface CustomComponents { - [component: string]: { - template?: string; - js?: string; - props?: string[]; - }; -} diff --git a/frontend/legacy/compiled/src/utils.ts b/frontend/legacy/compiled/src/utils.ts deleted file mode 100644 index e10692b9..00000000 --- a/frontend/legacy/compiled/src/utils.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { isObject } from 'lodash-es'; - -export function getURLFileExtension(url: string) { - let extension = url.split('.').pop(); - extension = extension?.split('?').shift(); - if (extension && extension.includes('/')) { - const components = extension.split('/'); - extension = components[0]; - } - return extension; -} - -export function isMobile() { - return window.innerWidth <= 576; -} -export function safeParseJSON(str: string, defaultValue: T): T { - try { - if (!str) { - return defaultValue; - } - return JSON.parse(str) as T; - } catch { - return defaultValue; - } -} - -/** - * - * @param nodeProps This method must be called if the custom component receives a property named `type`. - * @returns - */ -export function getCustomProps(nodeProps: T): T { - const node = nodeProps.node; - const firstChild = node?.children?.[0]; - if (isObject(firstChild) && !(firstChild as any).position) { - return { - ...nodeProps, - ...firstChild, - node: { - ...node, - children: node.children.slice(1), - }, - } as T; - } - - return nodeProps as T; -} diff --git a/frontend/package.json b/frontend/package.json index 5405363f..535e7f6e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,56 +6,52 @@ "license": "Apache-2.0", "type": "module", "dependencies": { - "@ant-design/cssinjs": "^1.24.0", + "@ant-design/cssinjs": "^2.1.0", "@ant-design/icons": "^6.1.0", - "@ant-design/x": "^1.6.1", - "@babel/standalone": "^7.28.5", - "@gradio/atoms": "0.7.4", - "@gradio/button": "^0.2.43", - "@gradio/client": "^1.14.2", - "@gradio/icons": "0.4.1", - "@gradio/preview": "0.13.0", - "@gradio/statustracker": "^0.7.6", - "@gradio/upload": "0.11.2", - "@gradio/utils": "0.9.0", + "@ant-design/x": "^2.2.2", + "@babel/standalone": "^7.29.1", + "@gradio/client": "^2.0.4", + "@gradio/preview": "0.15.2", + "@gradio/statustracker": "^0.12.4", + "@gradio/utils": "0.11.3", "@monaco-editor/react": "^4.7.0", "amuchina": "^1.0.12", - "antd": "^5.28.0", + "antd": "^6.3.1", "classnames": "^2.5.1", "dayjs": "^1.11.19", "dequal": "^2.0.2", "github-slugger": "^2.0.0", - "immer": "^10.2.0", - "katex": "^0.16.25", - "lodash-es": "^4.17.21", - "marked": "^16.4.1", - "marked-gfm-heading-id": "^4.1.2", - "marked-highlight": "^2.2.2", - "mermaid": "^11.12.1", - "monaco-editor": "^0.54.0", + "immer": "^11.1.4", + "katex": "^0.16.33", + "lodash-es": "^4.17.23", + "marked": "^17.0.3", + "marked-gfm-heading-id": "^4.1.3", + "marked-highlight": "^2.2.3", + "mermaid": "^11.12.3", + "monaco-editor": "^0.55.1", "path-browserify-esm": "^1.0.6", "prismjs": "^1.30.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "svelte": "^4.2.19", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "svelte": "5.53.5", "svelte-i18n": "^4.0.1", - "wavesurfer.js": "^7.11.1" + "wavesurfer.js": "^7.12.1" }, "devDependencies": { - "@babel/core": "^7.28.5", + "@babel/core": "^7.29.0", "@types/babel__core": "^7.20.5", "@types/babel__standalone": "^7.1.9", - "@types/katex": "^0.16.7", + "@types/katex": "^0.16.8", "@types/lodash-es": "^4.17.12", - "@types/prismjs": "^1.26.5", - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", + "@types/prismjs": "^1.26.6", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", "@types/sanitize-html": "^2.16.0", - "@vitejs/plugin-react-swc": "^4.2.0", + "@vitejs/plugin-react-swc": "^4.2.3", "fast-glob": "^3.3.3", - "less": "^4.4.2", - "typescript-json-schema": "^0.65.1", - "vite": "^7.1.12" + "less": "^4.5.1", + "typescript-json-schema": "^0.67.1", + "vite": "^7.3.1" }, "main_changeset": true } diff --git a/frontend/plugin.js b/frontend/plugin.js index 2b713c7a..b4e9d278 100644 --- a/frontend/plugin.js +++ b/frontend/plugin.js @@ -11,7 +11,9 @@ const baseGlobals = { antdx: 'window.ms_globals.antdx', '@ant-design/cssinjs': 'window.ms_globals.antdCssinjs', '@ant-design/icons': 'window.ms_globals.antdIcons', - '@svelte-preprocess-react/context': 'window.ms_globals.internalContext', + + '@svelte-preprocess-react/react-context': + 'window.ms_globals.internalReactContext', dayjs: 'window.ms_globals.dayjs', '@utils/createItemsContext': 'window.ms_globals.createItemsContext', '@globals/components': 'window.ms_globals.components', diff --git a/frontend/pro/chatbot/chatbot.less b/frontend/pro/chatbot/chatbot.less index 2eb007e6..2b6b19fa 100644 --- a/frontend/pro/chatbot/chatbot.less +++ b/frontend/pro/chatbot/chatbot.less @@ -10,57 +10,57 @@ .ms-gr-ant-bubble-content-wrapper { flex: initial !important; } + } - &-file-message { - &-container { - position: relative; - overflow: hidden; - } - - &-toolbar { - position: absolute; - inset: 0; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - visibility: hidden; - opacity: 0; - transition: opacity 0.3s; - pointer-events: none; - } - - &-container:hover &-toolbar { - visibility: visible; - opacity: 1; - pointer-events: auto; - } + &-message-file-message { + &-container { + position: relative; + overflow: hidden; } - &-footer { + &-toolbar { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; width: 100%; + height: 100%; visibility: hidden; opacity: 0; - transition: opacity 0.2s; - - &&-editing { - visibility: visible; - opacity: 1; - } + transition: opacity 0.3s; + pointer-events: none; } - &:last-child &-footer { + &-container:hover &-toolbar { visibility: visible; opacity: 1; + pointer-events: auto; } + } - &:hover &-footer { + &-message-footer { + width: 100%; + visibility: hidden; + opacity: 0; + transition: opacity 0.2s; + + &&-editing { visibility: visible; opacity: 1; } } + &-message:last-child &-message-footer { + visibility: visible; + opacity: 1; + } + + &-message:hover &-message-footer { + visibility: visible; + opacity: 1; + } + &-scroll-to-bottom-button { position: absolute; right: 0; diff --git a/frontend/pro/multimodal-input/multimodal-input.tsx b/frontend/pro/multimodal-input/multimodal-input.tsx index bb762d33..3c59e189 100644 --- a/frontend/pro/multimodal-input/multimodal-input.tsx +++ b/frontend/pro/multimodal-input/multimodal-input.tsx @@ -1,5 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; -import { useSuggestionOpenContext } from '@svelte-preprocess-react/context'; +import { useSuggestionOpenContext } from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useEffect, useMemo, useRef, useState } from 'react'; diff --git a/frontend/svelte-preprocess-react/component.ts b/frontend/svelte-preprocess-react/component.ts deleted file mode 100644 index 25310754..00000000 --- a/frontend/svelte-preprocess-react/component.ts +++ /dev/null @@ -1,218 +0,0 @@ -import type { Gradio } from '@gradio/utils'; -import { convertToCamelCase } from '@utils/convertToCamelCase'; -import { isPlainObject, mapKeys, omit } from 'lodash-es'; - -export async function initialize() { - if (!window.ms_globals) { - window.ms_globals = {} as typeof window.ms_globals; - } - if (!window.ms_globals.initializePromise) { - window.ms_globals.initializePromise = new Promise((resolve) => { - window.ms_globals.initialize = () => { - resolve(); - }; - }); - } - await window.ms_globals.initializePromise; -} - -export async function importComponent( - importer: () => Promise -): Promise { - await initialize(); - return importer().then((m) => m.default); -} - -const skippedGradioProps = [ - 'interactive', - 'gradio', - 'server', - 'target', - 'theme_mode', - 'root', - 'name', - // 'visible', - // 'elem_id', - // 'elem_classes', - // 'elem_style', - '_internal', - 'props', - // 'value', - '_selectable', - 'loading_status', - 'value_is_output', -]; -const gradioProps = skippedGradioProps.concat(['attached_events']); - -export function mapProps>( - props: T, - mapping: Record = {} as Record, - skipGradioProps = false -) { - return mapKeys( - omit(props, skipGradioProps ? [] : skippedGradioProps), - (_, key) => { - return mapping[key] || convertToCamelCase(key); - } - ); -} - -export function bindEvents< - T extends { - gradio: Gradio; - _internal: Record; - props: Record; - restProps?: Record; - originalRestProps?: Record; - }, ->(props: T, eventsMapping?: Record) { - const { - gradio, - _internal: internal, - restProps, - originalRestProps, - ...component - } = props; - // gradio props - const attachedEvents: string[] = restProps?.attachedEvents || []; - - return { - ...Array.from( - new Set([ - ...(Object.keys(internal) - .map((key) => { - const matched = key.match(/bind_(.+)_event/); - if (matched && matched[1]) { - return matched[1]; - } - return null; - }) - .filter(Boolean) as string[]), - ...attachedEvents.map((event) => { - if (eventsMapping && eventsMapping[event]) { - return eventsMapping[event]; - } - return event; - }), - ]) - ).reduce( - (acc, event) => { - const splitted = event.split('_'); - const handler = (...args: any[]) => { - const payload = args.map((arg) => { - if ( - args && - typeof arg === 'object' && - (arg.nativeEvent || arg instanceof Event) - ) { - return { - type: arg.type, - detail: arg.detail, - timestamp: arg.timeStamp, - clientX: arg.clientX, - clientY: arg.clientY, - targetId: arg.target.id, - targetClassName: arg.target.className, - altKey: arg.altKey, - ctrlKey: arg.ctrlKey, - shiftKey: arg.shiftKey, - metaKey: arg.metaKey, - }; - } - return arg; - }); - let serializedPayload: any; - try { - serializedPayload = JSON.parse(JSON.stringify(payload)); - } catch { - function serialize(obj: any) { - try { - JSON.stringify(obj); - return obj; - } catch { - // first level - if (isPlainObject(obj)) { - return Object.fromEntries( - Object.entries(obj) - .map(([k, v]) => { - try { - JSON.stringify(v); - return [k, v]; - } catch { - // second level - if (isPlainObject(v)) { - return [ - k, - Object.fromEntries( - Object.entries(v as object).filter( - ([_, nv]) => { - try { - JSON.stringify(nv); - return true; - } catch { - return false; - } - } - ) - ), - ]; - } - return null; - } - }) - .filter(Boolean) as [k: string, v: any][] - ); - } - return {}; - } - } - serializedPayload = payload.map((item) => { - return serialize(item); - }); - } - - return gradio.dispatch( - event.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase()), - { - payload: serializedPayload, - component: { - ...component, - ...omit(originalRestProps, gradioProps), - }, - } - ); - }; - - if (splitted.length > 1) { - let value: Record = { - ...(component.props[splitted[0]] || restProps?.[splitted[0]] || {}), - }; - acc[splitted[0]] = value; - for (let i = 1; i < splitted.length - 1; i++) { - const prop = { - ...(component.props[splitted[i]] || - restProps?.[splitted[i]] || - {}), - }; - value[splitted[i]] = prop; - value = prop; - } - const listener = splitted[splitted.length - 1]; - value[`on${listener.slice(0, 1).toUpperCase()}${listener.slice(1)}`] = - handler; - - return acc; - } - const listener = splitted[0]; - acc[`on${listener.slice(0, 1).toUpperCase()}${listener.slice(1)}`] = - handler; - return acc; - }, - {} as Record - ), - __render_eventProps: { - props, - eventsMapping, - }, - }; -} diff --git a/frontend/svelte-preprocess-react/component/import.ts b/frontend/svelte-preprocess-react/component/import.ts new file mode 100644 index 00000000..aef83b2b --- /dev/null +++ b/frontend/svelte-preprocess-react/component/import.ts @@ -0,0 +1,20 @@ +export async function initialize() { + if (!window.ms_globals) { + window.ms_globals = {} as typeof window.ms_globals; + } + if (!window.ms_globals.initializePromise) { + window.ms_globals.initializePromise = new Promise((resolve) => { + window.ms_globals.initialize = () => { + resolve(); + }; + }); + } + await window.ms_globals.initializePromise; +} + +export async function importComponent( + importer: () => Promise +): Promise { + await initialize(); + return importer().then((m) => m.default); +} diff --git a/frontend/svelte-preprocess-react/component/index.ts b/frontend/svelte-preprocess-react/component/index.ts new file mode 100644 index 00000000..54ec67cf --- /dev/null +++ b/frontend/svelte-preprocess-react/component/index.ts @@ -0,0 +1,2 @@ +export * from './import'; +export * from './props.svelte'; diff --git a/frontend/svelte-preprocess-react/component/props.svelte.ts b/frontend/svelte-preprocess-react/component/props.svelte.ts new file mode 100644 index 00000000..938372fe --- /dev/null +++ b/frontend/svelte-preprocess-react/component/props.svelte.ts @@ -0,0 +1,376 @@ +import { type Snippet, untrack } from 'svelte'; +import { + getSubIndex, + setSubIndex, +} from '@svelte-preprocess-react/svelte-contexts/each.svelte'; +import { setLoadingStatus } from '@svelte-preprocess-react/svelte-contexts/loading-status.svelte'; +import { + getSlotKey, + getSlotParamsMapping, + resetSlotKey, + setComponentSlotValue, +} from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; +import { SvelteSet } from 'svelte/reactivity'; +import { Gradio, type SharedProps } from '@gradio/utils'; +import { convertToCamelCase } from '@utils/convertToCamelCase'; +import { isPlainObject, mapKeys, omit } from 'lodash-es'; + +const skippedGradioProps = [ + 'interactive', + 'gradio', + 'server', + 'target', + 'theme_mode', + 'root', + 'name', + // 'visible', + // 'elem_id', + // 'elem_classes', + // 'elem_style', + '_internal', + 'props', + // 'value', + '_selectable', + 'loading_status', + 'value_is_output', +]; +export const gradioProps = skippedGradioProps.concat(['attached_events']); + +export function mapComponentProps>( + props: T, + mapping: Record = {} as Record< + keyof T, + string | undefined + >, + skipGradioProps = false +) { + return mapKeys( + omit(props, skipGradioProps ? [] : skippedGradioProps), + (_, key) => { + return mapping[key] || convertToCamelCase(key); + } + ); +} + +export function processEvents< + T extends { + gradio?: Gradio>; + _internal: Record; + additionalProps?: Record; + restProps?: Record; + }, +>(props: T, eventPropsMapping?: Record) { + const { + gradio, + _internal: internal, + restProps, + ...component + } = props as T & { + gradio?: Gradio>; + }; + if (!gradio) { + return {}; + } + // gradio props + const attachedEvents: string[] = restProps?.attached_events || []; + + return { + ...Array.from( + new SvelteSet([ + ...(Object.keys(internal) + .map((key) => { + const matched = key.match(/bind_(.+)_event/); + if (matched && matched[1]) { + return matched[1]; + } + return null; + }) + .filter(Boolean) as string[]), + ...attachedEvents.map((event) => { + if (eventPropsMapping && eventPropsMapping[event]) { + return eventPropsMapping[event]; + } + return event; + }), + ]) + ).reduce( + (acc, event) => { + const splitted = event.split('_'); + const handler = (...args: any[]) => { + const payload = args.map((arg) => { + if ( + args && + typeof arg === 'object' && + (arg.nativeEvent || arg instanceof Event) + ) { + return { + type: arg.type, + detail: arg.detail, + timestamp: arg.timeStamp, + clientX: arg.clientX, + clientY: arg.clientY, + targetId: arg.target.id, + targetClassName: arg.target.className, + altKey: arg.altKey, + ctrlKey: arg.ctrlKey, + shiftKey: arg.shiftKey, + metaKey: arg.metaKey, + }; + } + return arg; + }); + let serializedPayload: any; + try { + serializedPayload = JSON.parse(JSON.stringify(payload)); + } catch { + function serialize(obj: any) { + try { + JSON.stringify(obj); + return obj; + } catch { + // first level + if (isPlainObject(obj)) { + return Object.fromEntries( + Object.entries(obj) + .map(([k, v]) => { + try { + JSON.stringify(v); + return [k, v]; + } catch { + // second level + if (isPlainObject(v)) { + return [ + k, + Object.fromEntries( + Object.entries(v as object).filter( + ([_, nv]) => { + try { + JSON.stringify(nv); + return true; + } catch { + return false; + } + } + ) + ), + ]; + } + return null; + } + }) + .filter(Boolean) as [k: string, v: any][] + ); + } + return {}; + } + } + serializedPayload = payload.map((item) => { + return serialize(item); + }); + } + + return gradio.dispatch( + event.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase()), + { + payload: serializedPayload, + component: { + ...component, + ...omit(restProps, gradioProps), + }, + } + ); + }; + + if (splitted.length > 1) { + let value: Record = { + ...(component.additionalProps?.[splitted[0]] || + restProps?.additional_props?.[splitted[0]] || + restProps?.[splitted[0]] || + {}), + }; + acc[splitted[0]] = value; + for (let i = 1; i < splitted.length - 1; i++) { + const prop = { + ...(component.additionalProps?.[splitted[i]] || + restProps?.additional_props?.[splitted[0]] || + restProps?.[splitted[i]] || + {}), + }; + value[splitted[i]] = prop; + value = prop; + } + const listener = splitted[splitted.length - 1]; + value[`on${listener.slice(0, 1).toUpperCase()}${listener.slice(1)}`] = + handler; + + return acc; + } + const listener = splitted[0]; + acc[`on${listener.slice(0, 1).toUpperCase()}${listener.slice(1)}`] = + handler; + return acc; + }, + {} as Record + ), + }; +} + +export function processProps< + T extends { + as_item: string | undefined; + _internal: Record; + additionalProps: Record; + restProps: Record; + gradio: Gradio>; + }, +>( + getProps: () => T, + restPropsMapping?: Partial>, + options?: { + shouldSetLoadingStatus?: boolean; + shouldResetSlotKey?: boolean; + } +) { + const props = $derived(getProps()); + const shouldResetSlotKey = options?.shouldResetSlotKey ?? true; + const shouldSetLoadingStatus = options?.shouldSetLoadingStatus ?? true; + + // throw error once if the property keys are not exist + if (!Reflect.has(props, 'as_item') || !Reflect.has(props, '_internal')) { + throw new Error('`as_item` and `_internal` is required'); + } + + const slotKey = getSlotKey(); + // get slotParamsMapping for slot + const slotParamsMapping = getSlotParamsMapping(); + + setComponentSlotValue(() => { + return { + slot: slotKey?.value, + index: props._internal.index, + subIndex: props._internal.subIndex, + }; + }); + + // reset slot key to make sure the sub component does not be affected by gr.Slot() + if (shouldResetSlotKey) { + resetSlotKey(); + } + + // for loading_status + if (shouldSetLoadingStatus) { + setLoadingStatus(() => props.restProps.loading_status); + } + + // for ms.Each + const subIndex = getSubIndex(); + + setSubIndex(() => { + if (typeof subIndex?.value === 'number') { + return undefined; + } + if (typeof props._internal.subIndex === 'number') { + return props._internal.subIndex; + } + return subIndex?.value; + }); + + const proceedEvents = $derived(processEvents(props, restPropsMapping)); + + const processRestProps = ( + restProps?: Record, + events?: Record, + __render_as_item?: string + ) => { + const _proceedRestProps = restProps + ? { + ...mapComponentProps( + { + ...restProps, + }, + restPropsMapping + ), + __render_slotParamsMapping: slotParamsMapping + ? slotParamsMapping.value + : undefined, + __render_as_item, + __render_restPropsMapping: restPropsMapping, + } + : {}; + const _proceedEvents = events + ? { ...events, __render_eventsRestProps: restProps } + : {}; + return { + ..._proceedRestProps, + ..._proceedEvents, + }; + }; + + const proceedProps = $derived({ + ...props, + _internal: { + ...props._internal, + index: subIndex?.value ?? props._internal.index, + }, + restProps: processRestProps(props.restProps, proceedEvents, props.as_item), + }); + + return () => proceedProps; +} + +export function getProps< + P extends Record, + E extends Record = Record, +>(getSvelteProps: () => any) { + const { + children, + ...restProps + }: { + children: Snippet; + props: P; + shared_props: SharedProps; + } = getSvelteProps(); + const gradio = new Gradio(restProps); + const updateProps = (updatedProps: Partial

) => { + gradio.update(updatedProps); + }; + + const getComponentProps = () => + omit( + { + elem_id: gradio.shared.elem_id as string | undefined, + elem_classes: gradio.shared.elem_classes as + | string + | string[] + | undefined, + elem_style: gradio.props.elem_style, + visible: gradio.shared.visible, + attached_events: gradio.shared.attached_events, + as_item: gradio.props.as_item as string | undefined, + _internal: gradio.props._internal as {}, + loading_status: gradio.shared.loading_status, + ...gradio.props, + }, + ['i18n', 'api_url', 'name', 'additional_props'] + ); + + let additionalProps = $state( + (() => $state.snapshot(gradio.props.additional_props))() + ); + + $effect(() => { + additionalProps = { + ...untrack(() => $state.snapshot(additionalProps)), + ...gradio.props.additional_props, + }; + }); + const getAdditionalProps = () => additionalProps; + + return { + gradio, + getComponentProps, + getAdditionalProps, + updateProps, + children, + }; +} diff --git a/frontend/svelte-preprocess-react/index.ts b/frontend/svelte-preprocess-react/index.ts index 2c4fd8e7..d0902e1d 100644 --- a/frontend/svelte-preprocess-react/index.ts +++ b/frontend/svelte-preprocess-react/index.ts @@ -4,5 +4,4 @@ * */ export * from './internal/types'; -export * from './sveltify'; -export * from './useStore'; +export * from './sveltify.svelte'; diff --git a/frontend/svelte-preprocess-react/inject.ts b/frontend/svelte-preprocess-react/inject.ts index 831c157b..f0ed3fcb 100644 --- a/frontend/svelte-preprocess-react/inject.ts +++ b/frontend/svelte-preprocess-react/inject.ts @@ -1,3 +1,4 @@ +import * as internalReactContext from './react-contexts'; import type { loader as monacoLoader } from '@monaco-editor/react'; import { loader } from '@monaco-editor/react'; import React from 'react'; @@ -11,20 +12,16 @@ import * as createItemsContext from '@utils/createItemsContext'; import * as antd from 'antd'; import dayjs from 'dayjs'; import { noop } from 'lodash-es'; -import { type Readable, type Writable, writable } from 'svelte/store'; -import './events-polyfills'; import './polyfills'; -import type { BridgeProps } from './internal/Bridge'; -import Bridge from './internal/Bridge'; import type { TreeNode } from './internal/types'; -import * as internalContext from './context'; declare global { interface Window { ms_globals: { dispatch: (...args: any[]) => void; + // libs React: typeof React; ReactDOM: typeof ReactDOM; ReactDOMClient: typeof ReactDOMClient; @@ -33,45 +30,32 @@ declare global { antdCssinjs: typeof antdCssinjs; antdIcons: typeof antdIcons; dayjs: typeof dayjs; - internalContext: typeof internalContext; + + internalReactContext: typeof internalReactContext; initializePromise: Promise | null; initialize: () => void; tickPromise: Promise | null; + // svelte-preprocess-react - target: Writable; - tree: TreeNode; + sharedRoot: TreeNode | undefined; autokey: number; loadingKey: number; monacoLoader: typeof monacoLoader | null; monacoLoaderPromise: Promise | null; - rerender: (props: BridgeProps) => void; + // render items createItemsContext: typeof createItemsContext; itemsContexts: Record< string, ReturnType >; + // globals components: typeof globalComponents; }; } } -// initialize global variables -const target = writable(); -const never = writable() as Readable; - -const rootEl = document.createElement('react-root'); -// global root -const root = ReactDOMClient.createRoot(rootEl); -const targetEl = document.createElement('bridge-root'); -target.set(targetEl); -document.head.appendChild(rootEl); -document.head.appendChild(targetEl); -const rerender = (props: BridgeProps) => { - root.render(React.createElement(Bridge, props)); -}; - window.ms_globals ??= {} as typeof window.ms_globals; window.ms_globals = { @@ -87,23 +71,10 @@ window.ms_globals = { antdCssinjs, antdIcons, dayjs, - internalContext, + internalReactContext, autokey: 0, loadingKey: 0, - target, - tree: { - key: 0, - svelteInstance: never, - reactComponent: ({ children }: any) => children, - target, - props: writable({}), - slot: never, - slotKey: undefined, - slotIndex: undefined, - subSlotIndex: undefined, - nodes: [], - }, - rerender, + sharedRoot: undefined, monacoLoader: loader, monacoLoaderPromise: null, // render items @@ -112,10 +83,14 @@ window.ms_globals = { components: globalComponents, ...(window.ms_globals as Partial), }; + // register custom elements -customElements.define('react-portal-target', class extends HTMLElement {}); -customElements.define('react-child', class extends HTMLElement {}); -customElements.define('svelte-slot', class extends HTMLElement {}); +!customElements.get('react-portal-target') && + customElements.define('react-portal-target', class extends HTMLElement {}); +!customElements.get('react-child') && + customElements.define('react-child', class extends HTMLElement {}); +!customElements.get('svelte-slot') && + customElements.define('svelte-slot', class extends HTMLElement {}); if (!window.ms_globals.initializePromise) { window.ms_globals.initializePromise = new Promise((resolve) => { diff --git a/frontend/svelte-preprocess-react/internal/Bridge.ts b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts similarity index 51% rename from frontend/svelte-preprocess-react/internal/Bridge.ts rename to frontend/svelte-preprocess-react/internal/Bridge.svelte.ts index aab21fe8..c1cefaf9 100644 --- a/frontend/svelte-preprocess-react/internal/Bridge.ts +++ b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts @@ -2,61 +2,113 @@ import { useAutoCompleteContext, useFormItemContext, useSuggestionContext, -} from '@svelte-preprocess-react/context'; -import React, { useMemo } from 'react'; +} from '@svelte-preprocess-react/react-contexts'; +import React, { + createElement, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { patchProps } from '@utils/patchProps'; -import { writable } from 'svelte/store'; - -import useStore, { useStores } from '../useStore'; import { BridgeContext } from './BridgeContext'; import Child from './Child'; import type { TreeNode } from './types'; +// omit attached_events +function omitNodeProps(props: Record) { + const excludes = ['attachedEvents', '$$slots']; + const newProps = { ...props }; + for (const exclude of excludes) { + if (Reflect.has(newProps, exclude)) { + Reflect.deleteProperty(newProps, exclude); + } + } + return newProps; +} + export type BridgeProps = { + node: TreeNode; + // for hooks: useTarget, useSlotsChildren + nodeSlotKey?: string; createPortal: ( children: React.ReactNode, container: Element | DocumentFragment, key?: null | string ) => React.ReactPortal; - node: TreeNode; - nodeSlotKey?: string; }; -// omit attached_events -function omitNodeProps(props: Record) { - if (Reflect.has(props, 'attachedEvents')) { - const newProps = { ...props }; - Reflect.deleteProperty(newProps, 'attachedEvents'); - return newProps; +const Bridge: React.FC = ({ node, createPortal }) => { + const fresh = useRef(false); + const [result, setResult] = useState(() => { + return React.createElement(BridgeInternal, { + node, + createPortal, + }); + }); + useEffect( + () => + $effect.root(() => { + $effect(() => { + fresh.current = true; + + setResult( + React.createElement(BridgeInternal, { + // read the object when the property of node changes + node: $state.snapshot(node) as TreeNode, + createPortal, + }) + ); + }); + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + if (fresh.current) { + fresh.current = false; + return result; } - return props; -} + return React.createElement(BridgeInternal, { + node, + createPortal, + }); +}; -const Bridge: React.FC = ({ createPortal, node }) => { - // rerender when target or slot changed - const target = useStore(node.target); - const originalNodeProps = useStore(node.props); +function BridgeInternal({ + node, + createPortal, +}: { + node: TreeNode; + createPortal: BridgeProps['createPortal']; +}) { + let children: React.ReactNode[] = []; + + const { + portalTarget, + svelteChildren, + childrenSource, + props: originalNodeProps, + } = node; const nodeProps = useMemo(() => { return patchProps(omitNodeProps(originalNodeProps)); }, [originalNodeProps]); - const slot = useStore(node.slot); - const subSlotKeys = useStores( - useMemo( - () => node.nodes.map((subnode) => subnode.slotKey || writable()), - [node.nodes] - ) - ); + const subSlotKeys = useMemo( + () => node.nodes.map((subnode) => subnode.slotKey), + [node.nodes] + ); let formItemContext = useFormItemContext(); - const slotKey = useStore(node.slotKey || writable()); + const slotKey = node.slotKey; if (slotKey) { formItemContext = {}; } + const autoCompleteContext = useAutoCompleteContext(); const suggestionContext = useSuggestionContext(); - let props: typeof nodeProps = useMemo(() => { + const props: typeof nodeProps = useMemo(() => { return omitUndefinedProps({ ...nodeProps, // If the component is ignore, then its value should ignore the influence of the context. @@ -102,52 +154,43 @@ const Bridge: React.FC = ({ createPortal, node }) => { suggestionContext, ]); - if (!target) { - return null; + if (svelteChildren) { + // console.log(childrenSource); + children = [ + createElement(Child, { + el: childrenSource, + __slot__: true, + key: 'svelte$Children', + }), + ]; } - - let children: React.ReactElement[] | undefined; - if (node.nodes.length === 0 && slot === undefined) { - if (props.children) { - children = props.children; - props = { ...props }; - delete props.children; - } - } else { - children = node.nodes.map((subnode, i) => - React.createElement(Bridge, { - key: `bridge${subnode.key}`, - createPortal, - node: subnode, - // slotKey - nodeSlotKey: subSlotKeys[i], - }) - ); - if (props.children) { - children.push(props.children); - props = { ...props }; - delete props.children; - } - if (slot) { - children.push( - React.createElement(Child, { - key: 'svelte-slot', - __slot__: true, - el: slot, - }) - ); - } + if (node.nodes.length !== 0) { + children = [ + children, + ...node.nodes.map((subnode, i) => { + return createElement(Bridge, { + key: `bridge${subnode.key}`, + createPortal, + node: subnode, + // slotKey + nodeSlotKey: subSlotKeys[i], + }); + }), + ]; } - // render in different container // eslint-disable-next-line react/no-children-prop - const element = React.createElement(BridgeContext, { + const element = createElement(BridgeContext, { props, reactComponent: node.reactComponent, children, }); - // eslint-disable-next-line react-hooks/immutability - target._reactElement = element; - return createPortal(element, target); -}; + + if (portalTarget) { + // eslint-disable-next-line react-hooks/immutability + portalTarget._reactElement = element; + return createPortal(element, portalTarget); + } + return null; +} export default Bridge; diff --git a/frontend/svelte-preprocess-react/internal/BridgeContext.tsx b/frontend/svelte-preprocess-react/internal/BridgeContext.tsx index 0f544ee5..a04f4d2a 100644 --- a/frontend/svelte-preprocess-react/internal/BridgeContext.tsx +++ b/frontend/svelte-preprocess-react/internal/BridgeContext.tsx @@ -1,15 +1,27 @@ -import { bindEvents, mapProps } from '@svelte-preprocess-react/component'; +import { + mapComponentProps, + processEvents, +} from '@svelte-preprocess-react/component'; import { AutoCompleteContext, ContextPropsProvider, FormItemContext, SuggestionContext, useContextPropsContext, -} from '@svelte-preprocess-react/context'; -import { ensureObjectCtxValue } from '@svelte-preprocess-react/slot'; +} from '@svelte-preprocess-react/react-contexts'; import React, { useMemo } from 'react'; import { patchProps } from '@utils/patchProps'; +import { isUndefined } from 'lodash-es'; + +function ensureObjectCtxValue(ctxValue: any) { + if (isUndefined(ctxValue)) { + return {}; + } + return typeof ctxValue === 'object' && !Array.isArray(ctxValue) + ? ctxValue + : { value: ctxValue }; +} export interface BridgeContextProps { reactComponent: React.ComponentType; props: Record; @@ -25,19 +37,18 @@ export const BridgeContext: React.FC = ({ const { params, ctx, initial } = propsContext; const { // for params - __render_slotParamsMappingFn: slotParamsMappingFn, + __render_slotParamsMapping: slotParamsMapping, __render_as_item: as_item, __render_restPropsMapping: restPropsMapping, - // for events - __render_eventProps: eventProps, + __render_eventsRestProps: eventsRestProps, ...rest } = props || {}; // for render slot like this: (...args) => React.ReactNode const ctxProps = useMemo(() => { - if (!initial || (!slotParamsMappingFn && !ctx)) { + if (!initial || (!slotParamsMapping && !ctx)) { return {}; } - let value = params ? slotParamsMappingFn?.(...params) : undefined; + let value = params ? slotParamsMapping?.(...params) : undefined; let ctxValue = ctx; const merged_as_item = ctx?.as_item ?? as_item; @@ -53,7 +64,7 @@ export const BridgeContext: React.FC = ({ } ctxValue = ensureObjectCtxValue(ctxValue); value = ensureObjectCtxValue(value); - const mergedCtxValue = mapProps( + const mergedCtxValue = mapComponentProps( { ...ctxValue, ...value, @@ -62,21 +73,18 @@ export const BridgeContext: React.FC = ({ true ); const restProps = patchProps(mergedCtxValue); - if (!eventProps) { + if (!eventsRestProps) { return { restProps, originalRestProps, }; } - const { __render_eventProps, ...events } = bindEvents( + const events = processEvents( { - ...eventProps.props, - originalRestProps: { - ...eventProps.props.originalRestProps, - ...mergedCtxValue, - }, + ...eventsRestProps, + ...mergedCtxValue, }, - eventProps.eventsMapping + restPropsMapping ); return { restProps, @@ -85,12 +93,12 @@ export const BridgeContext: React.FC = ({ }; }, [ initial, - slotParamsMappingFn, + slotParamsMapping, ctx, params, as_item, restPropsMapping, - eventProps, + eventsRestProps, ]); return ( diff --git a/frontend/svelte-preprocess-react/internal/Child.ts b/frontend/svelte-preprocess-react/internal/Child.ts index d1791b46..107eb4b0 100644 --- a/frontend/svelte-preprocess-react/internal/Child.ts +++ b/frontend/svelte-preprocess-react/internal/Child.ts @@ -6,7 +6,7 @@ export interface ChildProps { children?: React.ReactNode[]; } const Child: React.FC = ({ el, children }) => { - const ref = useRef(); + const ref = useRef(null); useEffect(() => { if (!ref.current) { return; diff --git a/frontend/svelte-preprocess-react/internal/ReactWrapper.svelte b/frontend/svelte-preprocess-react/internal/ReactWrapper.svelte index 12b9dde8..2f5251f6 100644 --- a/frontend/svelte-preprocess-react/internal/ReactWrapper.svelte +++ b/frontend/svelte-preprocess-react/internal/ReactWrapper.svelte @@ -1,52 +1,74 @@ - - -{#if $$slots.default} - + +{#if children} + {@render children()} {/if} diff --git a/frontend/antd/carousel/Index.svelte b/frontend/antd/carousel/Index.svelte index 35df4afc..6e0e15f4 100644 --- a/frontend/antd/carousel/Index.svelte +++ b/frontend/antd/carousel/Index.svelte @@ -1,70 +1,60 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCarousel then Carousel} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/cascader/Index.svelte b/frontend/antd/cascader/Index.svelte index 10ffea6f..5bbedd2d 100644 --- a/frontend/antd/cascader/Index.svelte +++ b/frontend/antd/cascader/Index.svelte @@ -1,86 +1,80 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCascader then Cascader} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/checkbox/Index.svelte b/frontend/antd/checkbox/Index.svelte index bb98b92d..385658e2 100644 --- a/frontend/antd/checkbox/Index.svelte +++ b/frontend/antd/checkbox/Index.svelte @@ -1,79 +1,71 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCheckbox then Checkbox} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/collapse/Index.svelte b/frontend/antd/collapse/Index.svelte index 347a432d..5100376a 100644 --- a/frontend/antd/collapse/Index.svelte +++ b/frontend/antd/collapse/Index.svelte @@ -1,75 +1,61 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCollapse then Collapse} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/color-picker/Index.svelte b/frontend/antd/color-picker/Index.svelte index 5b369399..7f18eec2 100644 --- a/frontend/antd/color-picker/Index.svelte +++ b/frontend/antd/color-picker/Index.svelte @@ -1,91 +1,90 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedColorPicker then ColorPicker} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/config-provider/Index.svelte b/frontend/antd/config-provider/Index.svelte index ce77d3ea..27dbd25c 100644 --- a/frontend/antd/config-provider/Index.svelte +++ b/frontend/antd/config-provider/Index.svelte @@ -4,10 +4,9 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; + import { setConfigType } from '@svelte-preprocess-react/svelte-contexts/config.svelte'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; - import type React from 'react'; import cls from 'classnames'; - import { setConfigType } from '@svelte-preprocess-react/svelte-contexts/config.svelte'; const AwaitedConfigProvider = importComponent( () => import('./config-provider') @@ -15,8 +14,8 @@ const props = $props(); const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ - additional_props: Record; - elem_style: React.CSSProperties; + additional_props?: Record; + as_item?: string | undefined; }>(() => props); diff --git a/frontend/antd/date-picker/Index.svelte b/frontend/antd/date-picker/Index.svelte index 80637993..55a8f8af 100644 --- a/frontend/antd/date-picker/Index.svelte +++ b/frontend/antd/date-picker/Index.svelte @@ -1,87 +1,79 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDatePicker then DatePicker} { - value = val; + updateProps({ + value: val, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/icon/Index.svelte b/frontend/antd/icon/Index.svelte index 14f3f564..3efe2b66 100644 --- a/frontend/antd/icon/Index.svelte +++ b/frontend/antd/icon/Index.svelte @@ -1,17 +1,17 @@ -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedFilter then Filter} - + {@render children()} {/await} {/if} diff --git a/frontend/base/fragment/Index.svelte b/frontend/base/fragment/Index.svelte index a95fc5b8..7c384d5b 100644 --- a/frontend/base/fragment/Index.svelte +++ b/frontend/base/fragment/Index.svelte @@ -1,43 +1,46 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedFragment then Fragment} - - + + {@render children()} {/await} {/if} diff --git a/frontend/base/markdown/Index.svelte b/frontend/base/markdown/Index.svelte index 14f4787a..5e6ae838 100644 --- a/frontend/base/markdown/Index.svelte +++ b/frontend/base/markdown/Index.svelte @@ -1,77 +1,62 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedMarkdown then Markdown} - + {@render children()} {/await} {/if} diff --git a/frontend/base/slot/Index.svelte b/frontend/base/slot/Index.svelte index a11ba91b..726a2dfa 100644 --- a/frontend/base/slot/Index.svelte +++ b/frontend/base/slot/Index.svelte @@ -2,18 +2,15 @@ import { getProps, processProps } from '@svelte-preprocess-react/component'; import { getSetSlot, - setSlotParamsMapping, setSlotKey, + setSlotParamsMapping, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import { createFunction } from '@utils/createFunction'; const props = $props(); const { getComponentProps, getAdditionalProps, children } = getProps<{ value: string; - visible: boolean; params_mapping: string; - as_item?: string | undefined; - _internal: {}; }>(() => props); const getProceedProps = processProps(() => { diff --git a/frontend/base/span/Index.svelte b/frontend/base/span/Index.svelte index a1296bcc..5994ceb4 100644 --- a/frontend/base/span/Index.svelte +++ b/frontend/base/span/Index.svelte @@ -1,74 +1,62 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSpan then Span} - + {@render children()} {/await} {/if} diff --git a/frontend/base/text/Index.svelte b/frontend/base/text/Index.svelte index 1d7248e0..58369254 100644 --- a/frontend/base/text/Index.svelte +++ b/frontend/base/text/Index.svelte @@ -1,35 +1,40 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedText then Text} - + {/await} {/if} diff --git a/frontend/svelte-preprocess-react/component/props.svelte.ts b/frontend/svelte-preprocess-react/component/props.svelte.ts index 6c73a392..5ec1ea48 100644 --- a/frontend/svelte-preprocess-react/component/props.svelte.ts +++ b/frontend/svelte-preprocess-react/component/props.svelte.ts @@ -1,4 +1,3 @@ -import { type Snippet, untrack } from 'svelte'; import { getSubIndex, setSubIndex, @@ -10,10 +9,12 @@ import { resetSlotKey, setComponentSlotValue, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; +import type React from 'react'; import { SvelteSet } from 'svelte/reactivity'; import { Gradio, type SharedProps } from '@gradio/utils'; import { convertToCamelCase } from '@utils/convertToCamelCase'; import { isPlainObject, mapKeys, omit } from 'lodash-es'; +import { type Snippet, untrack } from 'svelte'; const skippedGradioProps = [ 'interactive', @@ -224,14 +225,14 @@ export function processProps< gradio?: Gradio>; }, >( - getProps: () => T, + getPlainProps: () => T, restPropsMapping?: Partial>, options?: { shouldSetLoadingStatus?: boolean; shouldResetSlotKey?: boolean; } ) { - const props = $derived(getProps()); + const props = $derived(getPlainProps()); const shouldResetSlotKey = options?.shouldResetSlotKey ?? true; const shouldSetLoadingStatus = options?.shouldSetLoadingStatus ?? true; @@ -343,7 +344,7 @@ export function getProps< | string | string[] | undefined, - elem_style: gradio.props.elem_style, + elem_style: gradio.props.elem_style as React.CSSProperties, visible: gradio.shared.visible, attached_events: gradio.shared.attached_events, as_item: gradio.props.as_item as string | undefined, @@ -355,13 +356,13 @@ export function getProps< ); let additionalProps = $state( - (() => $state.snapshot(gradio.props.additional_props))() + (() => $state.snapshot(gradio.props.additional_props) || {})() ); $effect(() => { additionalProps = { ...untrack(() => $state.snapshot(additionalProps)), - ...gradio.props.additional_props, + ...(gradio.props.additional_props || {}), }; }); const getAdditionalProps = () => additionalProps; From 3f50b938de62e9413294efa6c66b29c93b1888b8 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Mon, 9 Mar 2026 19:50:56 +0800 Subject: [PATCH 04/31] refactor(wip): component props --- .../antd/breadcrumb/item/__init__.py | 2 +- .../components/antd/card/__init__.py | 2 +- .../antd/icon/iconfont_provider/__init__.py | 2 +- .../components/antd/modal/__init__.py | 4 +- .../components/antd/modal/static/__init__.py | 4 +- .../components/antd/popconfirm/__init__.py | 4 +- .../components/antd/table/column/__init__.py | 2 +- .../components/antd/tour/step/__init__.py | 4 +- .../components/antdx/attachments/__init__.py | 2 +- .../antdx/attachments/file_card/__init__.py | 2 +- .../components/base/div/__init__.py | 2 +- .../modelscope_studio/utils/dev/component.py | 58 +- config/changelog/package.json | 4 +- config/lint-config/package.json | 10 +- frontend/antd/alert/Index.svelte | 5 +- .../antd/alert/error-boundary/Index.svelte | 92 +- frontend/antd/anchor/item/Index.svelte | 106 +- .../antd/auto-complete/option/Index.svelte | 110 +- frontend/antd/avatar/group/Index.svelte | 96 +- frontend/antd/badge/ribbon/Index.svelte | 99 +- frontend/antd/breadcrumb/Index.svelte | 124 +- frontend/antd/breadcrumb/breadcrumb.tsx | 8 +- frontend/antd/breadcrumb/item/Index.svelte | 117 +- .../antd/breadcrumb/item/breadcrumb.item.tsx | 8 +- frontend/antd/button/Index.svelte | 4 +- frontend/antd/button/group/Index.svelte | 96 +- frontend/antd/calendar/calendar.tsx | 8 +- frontend/antd/card/card.tsx | 4 - frontend/antd/card/grid/Index.svelte | 89 +- frontend/antd/card/meta/Index.svelte | 92 +- frontend/antd/cascader/Index.svelte | 3 - frontend/antd/cascader/cascader.tsx | 9 - frontend/antd/cascader/option/Index.svelte | 118 +- frontend/antd/cascader/panel/Index.svelte | 111 +- frontend/antd/checkbox/Index.svelte | 2 +- frontend/antd/checkbox/group/Index.svelte | 104 +- .../antd/checkbox/group/option/Index.svelte | 130 +- frontend/antd/collapse/collapse.tsx | 5 +- frontend/antd/collapse/item/Index.svelte | 139 +- frontend/antd/color-picker/color-picker.tsx | 7 +- .../antd/color-picker/preset/Index.svelte | 111 +- frontend/antd/config-provider/Index.svelte | 2 +- frontend/antd/date-picker/Index.svelte | 2 +- frontend/antd/date-picker/date-picker.tsx | 12 +- frontend/antd/date-picker/preset/Index.svelte | 123 +- .../date-picker/range-picker/Index.svelte | 125 +- .../range-picker/date-picker.range-picker.tsx | 8 +- frontend/antd/descriptions/Index.svelte | 101 +- frontend/antd/descriptions/item/Index.svelte | 123 +- frontend/antd/divider/Index.svelte | 115 +- frontend/antd/drawer/Index.svelte | 96 +- frontend/antd/drawer/drawer.tsx | 86 +- frontend/antd/dropdown/Index.svelte | 113 +- frontend/antd/dropdown/button/Index.svelte | 115 +- .../antd/dropdown/button/dropdown.button.tsx | 9 +- frontend/antd/dropdown/dropdown.tsx | 7 +- frontend/antd/empty/Index.svelte | 93 +- frontend/antd/empty/empty.tsx | 19 +- frontend/antd/flex/Index.svelte | 93 +- frontend/antd/float-button/Index.svelte | 97 +- .../antd/float-button/back-top/Index.svelte | 103 +- frontend/antd/float-button/group/Index.svelte | 97 +- frontend/antd/form/Index.svelte | 137 +- frontend/antd/form/form.tsx | 6 +- frontend/antd/form/item/Index.svelte | 97 +- frontend/antd/form/item/rule/Index.svelte | 97 +- frontend/antd/form/provider/Index.svelte | 99 +- frontend/antd/grid/col/Index.svelte | 102 +- frontend/antd/grid/row/Index.svelte | 94 +- frontend/antd/icon/Index.svelte | 11 +- frontend/antd/image/Index.svelte | 133 +- frontend/antd/image/image.tsx | 6 +- .../antd/image/preview-group/Index.svelte | 116 +- frontend/antd/input-number/Index.svelte | 119 +- frontend/antd/input/Index.svelte | 125 +- frontend/antd/input/input.tsx | 4 - frontend/antd/input/otp/Index.svelte | 109 +- frontend/antd/input/otp/input.otp.tsx | 4 - frontend/antd/input/password/Index.svelte | 124 +- .../antd/input/password/input.password.tsx | 5 - frontend/antd/input/search/Index.svelte | 119 +- frontend/antd/input/search/input.search.tsx | 4 - frontend/antd/input/textarea/Index.svelte | 131 +- .../antd/input/textarea/input.textarea.tsx | 4 - frontend/antd/layout/Base.svelte | 102 +- frontend/antd/layout/Index.svelte | 13 +- frontend/antd/layout/content/Index.svelte | 16 +- frontend/antd/layout/footer/Index.svelte | 16 +- frontend/antd/layout/header/Index.svelte | 16 +- frontend/antd/layout/sider/Index.svelte | 96 +- frontend/antd/list/Index.svelte | 109 +- frontend/antd/list/item/Index.svelte | 92 +- frontend/antd/list/item/meta/Index.svelte | 91 +- frontend/antd/list/list.tsx | 6 +- frontend/antd/mentions/Index.svelte | 116 +- frontend/antd/mentions/option/Index.svelte | 126 +- frontend/antd/menu/Index.svelte | 108 +- frontend/antd/menu/item/Index.svelte | 112 +- frontend/antd/menu/menu.tsx | 4 - frontend/antd/message/Index.svelte | 108 +- frontend/antd/modal/Index.svelte | 100 +- frontend/antd/modal/modal.tsx | 10 +- frontend/antd/modal/static/Index.svelte | 104 +- frontend/antd/modal/static/modal.static.tsx | 7 +- frontend/antd/notification/Index.svelte | 110 +- frontend/antd/pagination/Index.svelte | 108 +- frontend/antd/pagination/pagination.tsx | 5 +- frontend/antd/popconfirm/Index.svelte | 117 +- frontend/antd/popover/Index.svelte | 111 +- frontend/antd/progress/Index.svelte | 95 +- frontend/antd/qr-code/Index.svelte | 102 +- frontend/antd/qr-code/qr-code.tsx | 6 +- frontend/antd/radio/Index.svelte | 110 +- frontend/antd/radio/button/Index.svelte | 111 +- frontend/antd/radio/group/Index.svelte | 107 +- frontend/antd/radio/group/option/Index.svelte | 144 +- frontend/antd/rate/Index.svelte | 128 +- frontend/antd/rate/rate.tsx | 5 +- frontend/antd/result/Index.svelte | 91 +- frontend/antd/segmented/Index.svelte | 111 +- frontend/antd/segmented/option/Index.svelte | 113 +- frontend/antd/segmented/segmented.tsx | 3 +- frontend/antd/select/Index.svelte | 130 +- frontend/antd/select/option/Index.svelte | 130 +- frontend/antd/select/select.tsx | 9 - frontend/antd/skeleton/Index.svelte | 94 +- frontend/antd/skeleton/avatar/Index.svelte | 93 +- frontend/antd/skeleton/button/Index.svelte | 93 +- frontend/antd/skeleton/image/Index.svelte | 93 +- frontend/antd/skeleton/input/Index.svelte | 93 +- frontend/antd/skeleton/node/Index.svelte | 90 +- frontend/antd/slider/Index.svelte | 122 +- frontend/antd/slider/mark/Index.svelte | 127 +- frontend/antd/slider/slider.tsx | 4 - frontend/antd/space/Index.svelte | 93 +- frontend/antd/space/compact/Index.svelte | 93 +- frontend/antd/spin/Index.svelte | 97 +- frontend/antd/splitter/Index.svelte | 106 +- frontend/antd/splitter/panel/Index.svelte | 110 +- frontend/antd/statistic/Index.svelte | 107 +- .../antd/statistic/countdown/Index.svelte | 108 +- frontend/antd/statistic/statistic.tsx | 6 +- frontend/antd/statistic/timer/Index.svelte | 118 +- .../antd/statistic/timer/statistic.timer.tsx | 8 +- frontend/antd/steps/Index.svelte | 102 +- frontend/antd/steps/item/Index.svelte | 114 +- frontend/antd/steps/steps.tsx | 7 +- frontend/antd/switch/Index.svelte | 103 +- frontend/antd/table/Index.svelte | 100 +- frontend/antd/table/column-group/Index.svelte | 118 +- frontend/antd/table/column/Index.svelte | 323 ++-- frontend/antd/table/column/table.column.tsx | 21 +- frontend/antd/table/expandable/Index.svelte | 160 +- .../antd/table/row-selection/Index.svelte | 147 +- .../row-selection/selection/Index.svelte | 133 +- frontend/antd/table/table.tsx | 10 +- frontend/antd/tabs/Index.svelte | 110 +- frontend/antd/tabs/item/Index.svelte | 123 +- frontend/antd/tabs/tabs.tsx | 4 - frontend/antd/tag/Index.svelte | 103 +- frontend/antd/tag/checkable-tag/Index.svelte | 111 +- frontend/antd/time-picker/Index.svelte | 125 +- .../time-picker/range-picker/Index.svelte | 121 +- .../range-picker/time-picker.range-picker.tsx | 7 +- frontend/antd/time-picker/time-picker.tsx | 11 +- frontend/antd/timeline/Index.svelte | 90 +- frontend/antd/timeline/item/Index.svelte | 112 +- frontend/antd/tooltip/Index.svelte | 107 +- frontend/antd/tour/Index.svelte | 98 +- frontend/antd/tour/step/Index.svelte | 126 +- frontend/antd/tour/tour.tsx | 5 - frontend/antd/transfer/Index.svelte | 121 +- frontend/antd/transfer/transfer.tsx | 7 +- frontend/antd/tree-select/Index.svelte | 135 +- .../antd/tree-select/tree-node/Index.svelte | 143 +- frontend/antd/tree-select/tree-select.tsx | 15 +- frontend/antd/tree/Index.svelte | 124 +- .../antd/tree/directory-tree/Index.svelte | 129 +- frontend/antd/tree/tree-node/Index.svelte | 134 +- frontend/antd/tree/tree.tsx | 11 +- frontend/antd/typography/Base.svelte | 130 +- frontend/antd/typography/link/Index.svelte | 12 +- .../antd/typography/paragraph/Index.svelte | 12 +- frontend/antd/typography/text/Index.svelte | 12 +- frontend/antd/typography/title/Index.svelte | 12 +- frontend/antd/typography/typography.base.tsx | 4 - frontend/antd/upload/Index.svelte | 125 +- frontend/antd/upload/dragger/Index.svelte | 139 +- .../antd/upload/dragger/upload.dragger.tsx | 11 +- frontend/antd/upload/upload.tsx | 11 +- frontend/antd/watermark/Index.svelte | 99 +- frontend/antdx/actions/Index.svelte | 93 +- frontend/antdx/actions/item/Index.svelte | 113 +- frontend/antdx/attachments/Index.svelte | 122 +- frontend/antdx/attachments/attachments.tsx | 18 +- .../antdx/attachments/file-card/Index.svelte | 113 +- .../file-card/attachments.file-card.tsx | 6 +- frontend/antdx/bubble/Index.svelte | 111 +- frontend/antdx/bubble/bubble.tsx | 5 - frontend/antdx/bubble/list/Index.svelte | 95 +- frontend/antdx/bubble/list/item/Index.svelte | 25 +- frontend/antdx/bubble/list/item/Item.svelte | 181 +-- frontend/antdx/bubble/list/role/Index.svelte | 25 +- frontend/antdx/bubble/list/role/Role.svelte | 195 +-- frontend/antdx/conversations/Index.svelte | 108 +- .../antdx/conversations/conversations.tsx | 11 +- .../antdx/conversations/item/Index.svelte | 116 +- frontend/antdx/prompts/Index.svelte | 102 +- frontend/antdx/prompts/item/Index.svelte | 110 +- frontend/antdx/sender/Index.svelte | 140 +- frontend/antdx/sender/header/Index.svelte | 94 +- frontend/antdx/sender/sender.tsx | 2 - frontend/antdx/suggestion/Index.svelte | 111 +- frontend/antdx/suggestion/item/Index.svelte | 138 +- frontend/antdx/thought-chain/Index.svelte | 93 +- .../antdx/thought-chain/item/Index.svelte | 116 +- frontend/antdx/welcome/Index.svelte | 105 +- frontend/antdx/x-provider/Index.svelte | 27 +- frontend/antdx/x-provider/XProvider.svelte | 118 +- frontend/base/application/Application.svelte | 4 +- frontend/base/application/Index.svelte | 6 +- frontend/base/application/gradio.config.js | 4 +- frontend/base/div/Index.svelte | 2 + frontend/base/each/EachItem.svelte | 3 +- frontend/base/each/Index.svelte | 7 +- frontend/base/fragment/ShowFragment.svelte | 19 +- frontend/package.json | 19 +- frontend/plugin.js | 15 +- frontend/pro/chatbot/Index.svelte | 131 +- frontend/pro/monaco-editor/Index.svelte | 137 +- .../monaco-editor/diff-editor/Index.svelte | 133 +- frontend/pro/multimodal-input/Index.svelte | 136 +- .../pro/multimodal-input/multimodal-input.tsx | 2 - frontend/pro/web-sandbox/Index.svelte | 123 +- frontend/pro/web-sandbox/web-sandbox.tsx | 4 - .../component/props.svelte.ts | 34 +- .../internal/Bridge.svelte.ts | 8 + .../sveltify.svelte.ts | 15 +- frontend/utils/hooks/useMemoizedEqualValue.ts | 2 +- package.json | 17 +- pnpm-lock.yaml | 1313 ++++++++++------- scripts/create-tag-n-release.ts | 4 +- tsconfig.json | 5 +- 243 files changed, 8338 insertions(+), 10212 deletions(-) diff --git a/backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py b/backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py index 9e412248..8f38773c 100644 --- a/backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py +++ b/backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py @@ -63,7 +63,7 @@ def __init__( title: str | None = None, additional_props: dict | None = None, *, - dropdown_additional_props: dict | None = None, + dropdown_props: dict | None = None, href: str | None = None, path: str | None = None, menu: dict | None = None, diff --git a/backend/modelscope_studio/components/antd/card/__init__.py b/backend/modelscope_studio/components/antd/card/__init__.py index 767f61bd..2b399b08 100644 --- a/backend/modelscope_studio/components/antd/card/__init__.py +++ b/backend/modelscope_studio/components/antd/card/__init__.py @@ -69,7 +69,7 @@ def __init__( size: Literal["default", "small"] | None = None, tab_bar_extra_content: str | None = None, tab_list: list[str] | str | None = None, - tab_additional_props: dict | None = None, + tab_props: dict | None = None, title: str | None = None, type: str | None = None, class_names: dict | None = None, diff --git a/backend/modelscope_studio/components/antd/icon/iconfont_provider/__init__.py b/backend/modelscope_studio/components/antd/icon/iconfont_provider/__init__.py index c386e38f..6cd2be14 100644 --- a/backend/modelscope_studio/components/antd/icon/iconfont_provider/__init__.py +++ b/backend/modelscope_studio/components/antd/icon/iconfont_provider/__init__.py @@ -21,7 +21,7 @@ def __init__( script_url: str | list[str] | None = None, additional_props: dict | None = None, *, - extra_common_additional_props: dict | None = None, + extra_common_props: dict | None = None, as_item: str | None = None, _internal: None = None, # gradio properties diff --git a/backend/modelscope_studio/components/antd/modal/__init__.py b/backend/modelscope_studio/components/antd/modal/__init__.py index 8443c5e6..5cfab9b4 100644 --- a/backend/modelscope_studio/components/antd/modal/__init__.py +++ b/backend/modelscope_studio/components/antd/modal/__init__.py @@ -38,7 +38,7 @@ def __init__( after_close: str | None = None, class_names: dict | None = None, styles: dict | None = None, - cancel_button_additional_props: dict | None = None, + cancel_button_props: dict | None = None, cancel_text: str | None = None, centered: bool | None = None, closable: bool | dict | None = None, @@ -56,7 +56,7 @@ def __init__( modal_render: str | None = None, ok_text: str | None = None, ok_type: str | None = None, - ok_button_additional_props: dict | None = None, + ok_button_props: dict | None = None, loading: bool | None = None, title: str | None = None, open: bool | None = None, diff --git a/backend/modelscope_studio/components/antd/modal/static/__init__.py b/backend/modelscope_studio/components/antd/modal/static/__init__.py index 850f2bb3..6b107da8 100644 --- a/backend/modelscope_studio/components/antd/modal/static/__init__.py +++ b/backend/modelscope_studio/components/antd/modal/static/__init__.py @@ -37,7 +37,7 @@ def __init__( | None = None, class_names: dict | None = None, styles: dict | None = None, - cancel_button_additional_props: dict | None = None, + cancel_button_props: dict | None = None, cancel_text: str | None = None, centered: bool | None = None, closable: bool | dict | None = None, @@ -55,7 +55,7 @@ def __init__( modal_render: str | None = None, ok_text: str | None = None, ok_type: str | None = None, - ok_button_additional_props: dict | None = None, + ok_button_props: dict | None = None, loading: bool | None = None, title: str | None = None, width: int | float | str | None = None, diff --git a/backend/modelscope_studio/components/antd/popconfirm/__init__.py b/backend/modelscope_studio/components/antd/popconfirm/__init__.py index 95ee459c..a50c7b1d 100644 --- a/backend/modelscope_studio/components/antd/popconfirm/__init__.py +++ b/backend/modelscope_studio/components/antd/popconfirm/__init__.py @@ -42,11 +42,11 @@ def __init__( description: str | None = None, additional_props: dict | None = None, *, - cancel_button_additional_props: dict | None = None, + cancel_button_props: dict | None = None, cancel_text: str | None = None, disabled: bool | None = None, icon: str | None = None, - ok_button_additional_props: dict | None = None, + ok_button_props: dict | None = None, ok_text: str | None = None, ok_type: str | None = None, show_cancel: bool | None = None, diff --git a/backend/modelscope_studio/components/antd/table/column/__init__.py b/backend/modelscope_studio/components/antd/table/column/__init__.py index 5bdbb2e0..29931244 100644 --- a/backend/modelscope_studio/components/antd/table/column/__init__.py +++ b/backend/modelscope_studio/components/antd/table/column/__init__.py @@ -53,7 +53,7 @@ def __init__( filter_mode: Literal['menu', 'tree'] | None = None, filter_search: bool | str | None = None, filters: list[dict] | None = None, - filter_dropdown_additional_props: dict | None = None, + filter_dropdown_props: dict | None = None, fixed: str | bool | None = None, key: str | None = None, column_render: str | None = None, diff --git a/backend/modelscope_studio/components/antd/tour/step/__init__.py b/backend/modelscope_studio/components/antd/tour/step/__init__.py index a8717956..f971255f 100644 --- a/backend/modelscope_studio/components/antd/tour/step/__init__.py +++ b/backend/modelscope_studio/components/antd/tour/step/__init__.py @@ -46,8 +46,8 @@ def __init__( 'bottomRight'] = 'bottom', mask: bool | dict = True, type: Literal['default', 'primary'] = 'default', - next_button_additional_props: dict | None = None, - prev_button_additional_props: dict | None = None, + next_button_props: dict | None = None, + prev_button_props: dict | None = None, scroll_into_view_options: bool | dict = True, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antdx/attachments/__init__.py b/backend/modelscope_studio/components/antdx/attachments/__init__.py index aaa48946..0b7e2c0d 100644 --- a/backend/modelscope_studio/components/antdx/attachments/__init__.py +++ b/backend/modelscope_studio/components/antdx/attachments/__init__.py @@ -71,7 +71,7 @@ def __init__( value: list[str] | Callable | None = None, additional_props: dict | None = None, *, - image_additional_props: dict | None = None, + image_props: dict | None = None, accept: str | None = None, action: str | None = None, before_upload: str | None = None, diff --git a/backend/modelscope_studio/components/antdx/attachments/file_card/__init__.py b/backend/modelscope_studio/components/antdx/attachments/file_card/__init__.py index a1d3345c..95ae551b 100644 --- a/backend/modelscope_studio/components/antdx/attachments/file_card/__init__.py +++ b/backend/modelscope_studio/components/antdx/attachments/file_card/__init__.py @@ -28,7 +28,7 @@ def __init__( self, additional_props: dict | None = None, *, - image_additional_props: dict | None = None, + image_props: dict | None = None, icon: Union[Literal['default', 'excel', 'image', 'markdown', 'pdf', 'ppt', 'word', 'zip', 'video', 'audio'], str] | None = None, diff --git a/backend/modelscope_studio/components/base/div/__init__.py b/backend/modelscope_studio/components/base/div/__init__.py index 5f86bc65..215af159 100644 --- a/backend/modelscope_studio/components/base/div/__init__.py +++ b/backend/modelscope_studio/components/base/div/__init__.py @@ -44,7 +44,7 @@ class ModelScopeDiv(ModelScopeLayoutComponent): def __init__( self, value: str | None = None, - additional_additional_props: dict | None = None, + additional_props: dict | None = None, *, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/utils/dev/component.py b/backend/modelscope_studio/utils/dev/component.py index a09aa90c..cd006003 100644 --- a/backend/modelscope_studio/utils/dev/component.py +++ b/backend/modelscope_studio/utils/dev/component.py @@ -1,11 +1,8 @@ -import inspect from timeit import Timer from typing import Any, Callable, List, Set, Union - -import gradio from gradio.component_meta import ComponentMeta -from gradio.components.base import BlockContext, Component -from packaging import version +from gradio.components.base import Component +from gradio.blocks import BlockContext from .app_context import AppContext @@ -62,15 +59,6 @@ class ModelScopeComponent(Component): def skip_api(self): return False - def api_info(self): - if version.Version(gradio.__version__) >= version.Version("5.49.0"): - return super().api_info() - - if hasattr(self, "_api_info"): - return self._api_info - self._api_info = super().api_info() - return self._api_info - def __init__( self, value: Any = None, @@ -124,14 +112,14 @@ class ModelScopeDataLayoutComponent(ModelScopeComponent, def skip_api(self): return False - # fix gradio's bug - @property - def component_class_id(self): - return self.get_component_class_id() + # # fix gradio's bug + # @property + # def component_class_id(self): + # return self.get_component_class_id() - @component_class_id.setter - def component_class_id(self, value): - pass + # @component_class_id.setter + # def component_class_id(self, value): + # pass def __exit__(self, *args, **kwargs): self._internal.update(layout=True) @@ -166,22 +154,14 @@ def __init__( load_fn=load_fn, as_item=as_item, # disable render twice - render=False, + render=render, **kwargs) - sig = inspect.signature(BlockContext.__init__) - has_preserved_by_key_parameter = "preserved_by_key" in sig.parameters - if has_preserved_by_key_parameter: - preserved_by_key = kwargs.get("preserved_by_key", "value") - BlockContext.__init__(self, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - render=render, - key=key, - preserved_by_key=preserved_by_key) - else: - BlockContext.__init__(self, - visible=visible, - elem_id=elem_id, - elem_classes=elem_classes, - render=render) + + preserved_by_key = kwargs.get("preserved_by_key", "value") + BlockContext.__init__(self, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + key=key, + preserved_by_key=preserved_by_key) diff --git a/config/changelog/package.json b/config/changelog/package.json index d9aad15b..e9bb47a0 100644 --- a/config/changelog/package.json +++ b/config/changelog/package.json @@ -19,13 +19,13 @@ "build": "tsup" }, "dependencies": { - "@changesets/get-github-info": "^0.7.0", + "@changesets/get-github-info": "^0.8.0", "@manypkg/get-packages": "^3.1.0", "detect-indent": "^7.0.2" }, "devDependencies": { "@changesets/types": "^6.1.0", - "@types/node": "^25.3.1", + "@types/node": "^25.3.5", "tsup": "^8.5.1" } } diff --git a/config/lint-config/package.json b/config/lint-config/package.json index 36a59bda..9fa6b567 100644 --- a/config/lint-config/package.json +++ b/config/lint-config/package.json @@ -16,7 +16,7 @@ } }, "dependencies": { - "@eslint/compat": "^2.0.2", + "@eslint/compat": "^2.0.3", "@eslint/js": "^10.0.1", "@typescript-eslint/parser": "^8.56.1", "eslint-config-prettier": "^10.1.8", @@ -28,16 +28,16 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-svelte": "^3.15.0", - "globals": "^17.3.0", - "postcss": "^8.5.6", + "eslint-plugin-svelte": "^3.15.1", + "globals": "^17.4.0", + "postcss": "^8.5.8", "postcss-less": "^6.0.0", "stylelint-config-rational-order": "^0.1.2", "stylelint-config-standard": "^40.0.0", "stylelint-declaration-block-no-ignored-properties": "^3.0.0", "stylelint-order": "^7.0.1", "stylelint-prettier": "^5.0.3", - "svelte-eslint-parser": "^1.5.1", + "svelte-eslint-parser": "^1.6.0", "typescript-eslint": "^8.56.1" }, "devDependencies": { diff --git a/frontend/antd/alert/Index.svelte b/frontend/antd/alert/Index.svelte index 70af067d..3edf75bc 100644 --- a/frontend/antd/alert/Index.svelte +++ b/frontend/antd/alert/Index.svelte @@ -1,5 +1,3 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedAlertErrorBoundary then AlertErrorBoundary} - + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/anchor/item/Index.svelte b/frontend/antd/anchor/item/Index.svelte index d072b51b..2fad045d 100644 --- a/frontend/antd/anchor/item/Index.svelte +++ b/frontend/antd/anchor/item/Index.svelte @@ -1,83 +1,73 @@ - - {#await AwaitedAnchorItem then AnchorItem} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/auto-complete/option/Index.svelte b/frontend/antd/auto-complete/option/Index.svelte index ab39d106..f5aeb09c 100644 --- a/frontend/antd/auto-complete/option/Index.svelte +++ b/frontend/antd/auto-complete/option/Index.svelte @@ -1,90 +1,72 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedAutoCompleteOption then AutoCompleteOption} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/avatar/group/Index.svelte b/frontend/antd/avatar/group/Index.svelte index 8a0568c1..b4b9546c 100644 --- a/frontend/antd/avatar/group/Index.svelte +++ b/frontend/antd/avatar/group/Index.svelte @@ -1,74 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedAvatarGroup then AvatarGroup} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/badge/ribbon/Index.svelte b/frontend/antd/badge/ribbon/Index.svelte index 44dd3e19..2eb16501 100644 --- a/frontend/antd/badge/ribbon/Index.svelte +++ b/frontend/antd/badge/ribbon/Index.svelte @@ -1,77 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedBadgeRibbon then BadgeRibbon} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/breadcrumb/Index.svelte b/frontend/antd/breadcrumb/Index.svelte index a8487ee9..2f692a5e 100644 --- a/frontend/antd/breadcrumb/Index.svelte +++ b/frontend/antd/breadcrumb/Index.svelte @@ -1,86 +1,76 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedBreadcrumb then Breadcrumb} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/breadcrumb/breadcrumb.tsx b/frontend/antd/breadcrumb/breadcrumb.tsx index 35dc6a78..0641b7f4 100644 --- a/frontend/antd/breadcrumb/breadcrumb.tsx +++ b/frontend/antd/breadcrumb/breadcrumb.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { renderItems } from '@utils/renderItems'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -10,14 +9,12 @@ import type { ItemType } from 'antd/es/breadcrumb/Breadcrumb'; import { useItems, withItemsContextProvider } from './context'; export const Breadcrumb = sveltify< - GetProps & { - setSlotParams: SetSlotParams; - }, + GetProps, ['separator', 'itemRender'] >( withItemsContextProvider( ['default', 'items'], - ({ slots, items, setSlotParams, children, ...props }) => { + ({ slots, items, children, ...props }) => { const { items: slotItems } = useItems<['default', 'items']>(); const resolvedSlotItems = slotItems.items.length > 0 ? slotItems.items : slotItems.default; @@ -30,7 +27,6 @@ export const Breadcrumb = sveltify< slots['itemRender'] ? renderParamsSlot( { - setSlotParams, slots, key: 'itemRender', }, diff --git a/frontend/antd/breadcrumb/item/Index.svelte b/frontend/antd/breadcrumb/item/Index.svelte index edb4d636..7576a855 100644 --- a/frontend/antd/breadcrumb/item/Index.svelte +++ b/frontend/antd/breadcrumb/item/Index.svelte @@ -1,93 +1,70 @@ - - {#await AwaitedBreadcrumbItem then BreadcrumbItem} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/breadcrumb/item/breadcrumb.item.tsx b/frontend/antd/breadcrumb/item/breadcrumb.item.tsx index 996b54c5..a593ce4e 100644 --- a/frontend/antd/breadcrumb/item/breadcrumb.item.tsx +++ b/frontend/antd/breadcrumb/item/breadcrumb.item.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { createFunction } from '@utils/createFunction'; import { renderItems } from '@utils/renderItems'; @@ -16,13 +15,12 @@ import { ItemHandler, type ItemHandlerProps } from '../context'; export const BreadcrumbItem = sveltify< BreadcrumbItemProps & ItemHandlerProps & { - setSlotParams: SetSlotParams; itemSlots: Record; } >( withMenuItemsContextProvider( ['menu.items', 'dropdownProps.menu.items'], - ({ setSlotParams, itemSlots: slots, ...props }) => { + ({ itemSlots: slots, ...props }) => { const { items: { 'menu.items': menuItems, @@ -44,7 +42,6 @@ export const BreadcrumbItem = sveltify< expandIcon: renderParamsSlot( { - setSlotParams, slots: slots, key: 'menu.expandIcon', }, @@ -68,7 +65,6 @@ export const BreadcrumbItem = sveltify< expandIcon: renderParamsSlot( { - setSlotParams, slots: slots, key: 'dropdownProps.menu.expandIcon', }, @@ -86,7 +82,6 @@ export const BreadcrumbItem = sveltify< dropdownRender: slots['dropdownProps.dropdownRender'] ? renderParamsSlot( { - setSlotParams, slots: slots, key: 'dropdownProps.dropdownRender', }, @@ -98,7 +93,6 @@ export const BreadcrumbItem = sveltify< popupRender: slots['dropdownProps.popupRender'] ? renderParamsSlot( { - setSlotParams, slots: slots, key: 'dropdownProps.popupRender', }, diff --git a/frontend/antd/button/Index.svelte b/frontend/antd/button/Index.svelte index d73df7d9..9d9df552 100644 --- a/frontend/antd/button/Index.svelte +++ b/frontend/antd/button/Index.svelte @@ -5,13 +5,12 @@ processProps, } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; - import type React from 'react'; import cls from 'classnames'; const AwaitedButton = importComponent(() => import('./button')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; value: string | undefined; @@ -44,6 +43,7 @@ elem_id, elem_classes, elem_style, + gradio, }; }, { diff --git a/frontend/antd/button/group/Index.svelte b/frontend/antd/button/group/Index.svelte index ff762b60..6f4e3aba 100644 --- a/frontend/antd/button/group/Index.svelte +++ b/frontend/antd/button/group/Index.svelte @@ -1,74 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedButtonGroup then ButtonGroup} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/calendar/calendar.tsx b/frontend/antd/calendar/calendar.tsx index 5b0eaf3e..4e4f7b63 100644 --- a/frontend/antd/calendar/calendar.tsx +++ b/frontend/antd/calendar/calendar.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -21,7 +20,6 @@ export const Calendar = sveltify< onPanelChange?: (date: number, ...args: any[]) => void; onSelect?: (date: number, ...args: any[]) => void; onValueChange: (date: number) => void; - setSlotParams: SetSlotParams; children?: React.ReactNode; }, ['cellRender', 'fullCellRender', 'headerRender'] @@ -35,7 +33,6 @@ export const Calendar = sveltify< onPanelChange, onSelect, onValueChange, - setSlotParams, cellRender, fullCellRender, headerRender, @@ -69,21 +66,20 @@ export const Calendar = sveltify< disabledDate={disabledDateFunction} cellRender={ slots.cellRender - ? renderParamsSlot({ slots, setSlotParams, key: 'cellRender' }) + ? renderParamsSlot({ slots, key: 'cellRender' }) : cellRenderFunction } fullCellRender={ slots.fullCellRender ? renderParamsSlot({ slots, - setSlotParams, key: 'fullCellRender', }) : fullCellRenderFunction } headerRender={ slots.headerRender - ? renderParamsSlot({ slots, setSlotParams, key: 'headerRender' }) + ? renderParamsSlot({ slots, key: 'headerRender' }) : headerRenderFunction } onChange={(date, ...args) => { diff --git a/frontend/antd/card/card.tsx b/frontend/antd/card/card.tsx index 693f5ead..1f973869 100644 --- a/frontend/antd/card/card.tsx +++ b/frontend/antd/card/card.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useTargets } from '@utils/hooks/useTargets'; @@ -17,7 +16,6 @@ import { export const Card = sveltify< GetProps & { containsGrid?: boolean; - setSlotParams: SetSlotParams; }, [ 'actions', @@ -44,7 +42,6 @@ export const Card = sveltify< slots, tabList, tabProps, - setSlotParams, ...props }) => { const targets = useTargets(children, 'actions'); @@ -71,7 +68,6 @@ export const Card = sveltify< renderTabBar: slots['tabProps.renderTabBar'] ? renderParamsSlot({ slots, - setSlotParams, key: 'tabProps.renderTabBar', }) : renderTabBarFunction, diff --git a/frontend/antd/card/grid/Index.svelte b/frontend/antd/card/grid/Index.svelte index 67b08232..96d82298 100644 --- a/frontend/antd/card/grid/Index.svelte +++ b/frontend/antd/card/grid/Index.svelte @@ -1,65 +1,58 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCardGrid then CardGrid} - + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/card/meta/Index.svelte b/frontend/antd/card/meta/Index.svelte index 18c1b36c..636947ad 100644 --- a/frontend/antd/card/meta/Index.svelte +++ b/frontend/antd/card/meta/Index.svelte @@ -1,70 +1,58 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCardMeta then CardMeta} - + {@render children?.()} {/await} {/if} - - diff --git a/frontend/antd/cascader/Index.svelte b/frontend/antd/cascader/Index.svelte index 5bbedd2d..47b786ba 100644 --- a/frontend/antd/cascader/Index.svelte +++ b/frontend/antd/cascader/Index.svelte @@ -29,7 +29,6 @@ visible, _internal, as_item, - value, elem_classes, elem_id, elem_style, @@ -39,7 +38,6 @@ additionalProps: getAdditionalProps(), _internal, as_item, - value, restProps, visible, elem_id, @@ -66,7 +64,6 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} - value={proceedProps.additionalProps.value ?? proceedProps.value} slots={slots.value} onValueChange={(v) => { updateProps({ diff --git a/frontend/antd/cascader/cascader.tsx b/frontend/antd/cascader/cascader.tsx index 97454a13..5a702d59 100644 --- a/frontend/antd/cascader/cascader.tsx +++ b/frontend/antd/cascader/cascader.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; @@ -21,7 +20,6 @@ export const Cascader = sveltify< CascaderProps & { onValueChange: (value: string[] | number[]) => void; onLoadData?: (...args: any[]) => void; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -55,7 +53,6 @@ export const Cascader = sveltify< optionRender, showSearch, options, - setSlotParams, onLoadData, ...props }) => { @@ -105,7 +102,6 @@ export const Cascader = sveltify< render: slots['showSearch.render'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showSearch.render', }) : showSearchRenderFunction || showSearchConfig.render, @@ -123,7 +119,6 @@ export const Cascader = sveltify< slots.dropdownRender ? renderParamsSlot({ slots, - setSlotParams, key: 'dropdownRender', }) : dropdownRenderFunction @@ -132,7 +127,6 @@ export const Cascader = sveltify< slots.popupRender ? renderParamsSlot({ slots, - setSlotParams, key: 'popupRender', }) : popupRenderFunction @@ -141,7 +135,6 @@ export const Cascader = sveltify< slots.displayRender ? renderParamsSlot({ slots, - setSlotParams, key: 'displayRender', }) : displayRenderFunction @@ -150,7 +143,6 @@ export const Cascader = sveltify< slots.tagRender ? renderParamsSlot({ slots, - setSlotParams, key: 'tagRender', }) : tagRenderFunction @@ -191,7 +183,6 @@ export const Cascader = sveltify< slots.maxTagPlaceholder ? renderParamsSlot({ slots, - setSlotParams, key: 'maxTagPlaceholder', }) : maxTagPlaceholderFunction || maxTagPlaceholder diff --git a/frontend/antd/cascader/option/Index.svelte b/frontend/antd/cascader/option/Index.svelte index d0a6842f..50682dc8 100644 --- a/frontend/antd/cascader/option/Index.svelte +++ b/frontend/antd/cascader/option/Index.svelte @@ -1,94 +1,66 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCascaderOption then CascaderOption} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/cascader/panel/Index.svelte b/frontend/antd/cascader/panel/Index.svelte index 017e44df..ff201257 100644 --- a/frontend/antd/cascader/panel/Index.svelte +++ b/frontend/antd/cascader/panel/Index.svelte @@ -1,80 +1,75 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCascaderPanel then CascaderPanel} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/checkbox/Index.svelte b/frontend/antd/checkbox/Index.svelte index 385658e2..f5a6972a 100644 --- a/frontend/antd/checkbox/Index.svelte +++ b/frontend/antd/checkbox/Index.svelte @@ -12,7 +12,7 @@ const props = $props(); const { getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ - value: boolean; + value?: boolean; additional_props?: Record; as_item?: string | undefined; diff --git a/frontend/antd/checkbox/group/Index.svelte b/frontend/antd/checkbox/group/Index.svelte index 836544f8..042351bf 100644 --- a/frontend/antd/checkbox/group/Index.svelte +++ b/frontend/antd/checkbox/group/Index.svelte @@ -1,81 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCheckboxGroup then CheckboxGroup} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/checkbox/group/option/Index.svelte b/frontend/antd/checkbox/group/option/Index.svelte index 5dcfae9e..5b108184 100644 --- a/frontend/antd/checkbox/group/option/Index.svelte +++ b/frontend/antd/checkbox/group/option/Index.svelte @@ -1,107 +1,97 @@ - - {#await AwaitedCheckboxGroupOption then CheckboxGroupOption} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/collapse/collapse.tsx b/frontend/antd/collapse/collapse.tsx index a22d18b5..64ff9027 100644 --- a/frontend/antd/collapse/collapse.tsx +++ b/frontend/antd/collapse/collapse.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderItems } from '@utils/renderItems'; @@ -11,7 +10,6 @@ import { useItems, withItemsContextProvider } from './context'; type CollapseProps = GetProps; export const Collapse = sveltify< CollapseProps & { - setSlotParams: SetSlotParams; }, ['expandIcon'] >( @@ -22,7 +20,6 @@ export const Collapse = sveltify< items, children, onChange, - setSlotParams, expandIcon, ...props }) => { @@ -40,7 +37,7 @@ export const Collapse = sveltify< }} expandIcon={ slots.expandIcon - ? renderParamsSlot({ slots, setSlotParams, key: 'expandIcon' }) + ? renderParamsSlot({ slots, key: 'expandIcon' }) : expandIconFunction } items={useMemo(() => { diff --git a/frontend/antd/collapse/item/Index.svelte b/frontend/antd/collapse/item/Index.svelte index d64c790c..9643ca7f 100644 --- a/frontend/antd/collapse/item/Index.svelte +++ b/frontend/antd/collapse/item/Index.svelte @@ -1,99 +1,86 @@ - - + +{#await AwaitedCollapseItem then CollapseItem} + - -{#await AwaitedCollapseItem then CollapseItem} - - {#if $mergedProps.visible} - - + {#if proceedProps.visible} + + {@render children()} {/if} diff --git a/frontend/antd/color-picker/color-picker.tsx b/frontend/antd/color-picker/color-picker.tsx index 34912791..ed5ed6f6 100644 --- a/frontend/antd/color-picker/color-picker.tsx +++ b/frontend/antd/color-picker/color-picker.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useTargets } from '@utils/hooks/useTargets'; @@ -19,7 +18,6 @@ export const ColorPicker = sveltify< ...args: any[] ) => void; value_format: 'rgb' | 'hex' | 'hsb'; - setSlotParams: SetSlotParams; }, ['panelRender', 'showText'] >( @@ -34,7 +32,6 @@ export const ColorPicker = sveltify< presets, children, value_format, - setSlotParams, slots, ...props }) => { @@ -63,12 +60,12 @@ export const ColorPicker = sveltify< }, [presets, presetItems])} showText={ slots.showText - ? renderParamsSlot({ slots, setSlotParams, key: 'showText' }) + ? renderParamsSlot({ slots, key: 'showText' }) : showTextFunction || showText } panelRender={ slots.panelRender - ? renderParamsSlot({ slots, setSlotParams, key: 'panelRender' }) + ? renderParamsSlot({ slots, key: 'panelRender' }) : panelRenderFunction } onChange={(v, ...args) => { diff --git a/frontend/antd/color-picker/preset/Index.svelte b/frontend/antd/color-picker/preset/Index.svelte index 2b5bb398..fd49553a 100644 --- a/frontend/antd/color-picker/preset/Index.svelte +++ b/frontend/antd/color-picker/preset/Index.svelte @@ -1,89 +1,68 @@ - - {#await AwaitedColorPickerPreset then ColorPickerPreset} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/config-provider/Index.svelte b/frontend/antd/config-provider/Index.svelte index 27dbd25c..f5c5ebd2 100644 --- a/frontend/antd/config-provider/Index.svelte +++ b/frontend/antd/config-provider/Index.svelte @@ -56,7 +56,7 @@ {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} - themeMode={proceedProps.gradio.shared.theme} + themeMode={proceedProps.gradio.shared.theme || 'light'} > {@render children()} diff --git a/frontend/antd/date-picker/Index.svelte b/frontend/antd/date-picker/Index.svelte index 55a8f8af..441eeabc 100644 --- a/frontend/antd/date-picker/Index.svelte +++ b/frontend/antd/date-picker/Index.svelte @@ -18,7 +18,7 @@ _internal: { layout?: boolean; }; - value?: string | number | (string | number | null)[]; + value?: string | number | (string | number | null)[] | null; panel_change?: any; open_change?: any; }>(() => props); diff --git a/frontend/antd/date-picker/date-picker.tsx b/frontend/antd/date-picker/date-picker.tsx index 9a0ae08d..b9cf7437 100644 --- a/frontend/antd/date-picker/date-picker.tsx +++ b/frontend/antd/date-picker/date-picker.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderItems } from '@utils/renderItems'; @@ -24,7 +23,9 @@ function formatDayjs(date: any): dayjs.Dayjs { return dayjs(date); } -function formatDate(dates: (dayjs.Dayjs | null | undefined)[] | dayjs.Dayjs) { +function formatDate( + dates: (dayjs.Dayjs | null | undefined)[] | dayjs.Dayjs | null +) { if (Array.isArray(dates)) { return dates.map((date) => { return date ? date.valueOf() / 1000 : null; @@ -44,7 +45,6 @@ export const DatePicker = sveltify< ...args: any[] ) => void; onValueChange: (date: ReturnType) => void; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -80,7 +80,6 @@ export const DatePicker = sveltify< onValueChange, onPanelChange, children, - setSlotParams, elRef, ...props }) => { @@ -139,12 +138,12 @@ export const DatePicker = sveltify< getPopupContainer={getPopupContainerFunction} cellRender={ slots.cellRender - ? renderParamsSlot({ slots, setSlotParams, key: 'cellRender' }) + ? renderParamsSlot({ slots, key: 'cellRender' }) : cellRenderFunction } panelRender={ slots.panelRender - ? renderParamsSlot({ slots, setSlotParams, key: 'panelRender' }) + ? renderParamsSlot({ slots, key: 'panelRender' }) : panelRenderFunction } presets={useMemo(() => { @@ -173,7 +172,6 @@ export const DatePicker = sveltify< slots.renderExtraFooter ? renderParamsSlot({ slots, - setSlotParams, key: 'renderExtraFooter', }) : props.renderExtraFooter diff --git a/frontend/antd/date-picker/preset/Index.svelte b/frontend/antd/date-picker/preset/Index.svelte index ccacba7e..8084f315 100644 --- a/frontend/antd/date-picker/preset/Index.svelte +++ b/frontend/antd/date-picker/preset/Index.svelte @@ -1,97 +1,72 @@ - - {#await AwaitedDatePickerPreset then DatePickerPreset} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/date-picker/range-picker/Index.svelte b/frontend/antd/date-picker/range-picker/Index.svelte index 793821ce..5f38aa53 100644 --- a/frontend/antd/date-picker/range-picker/Index.svelte +++ b/frontend/antd/date-picker/range-picker/Index.svelte @@ -1,91 +1,78 @@ - - -{#if $mergedProps.visible} - {#await AwaitedDatePickerRangePicker then DateRangePicker} - { - value = val; + updateProps({ value: val }); }} - {setSlotParams} > - - + {@render children()} + {/await} {/if} diff --git a/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx b/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx index 6cc60e5e..4fc37f52 100644 --- a/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx +++ b/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderItems } from '@utils/renderItems'; @@ -39,7 +38,6 @@ export const DateRangePicker = sveltify< ...args: any[] ) => void; onValueChange: (dates: [number | null, number | null]) => void; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -76,7 +74,6 @@ export const DateRangePicker = sveltify< onPanelChange, onCalendarChange, children, - setSlotParams, elRef, ...props }) => { @@ -144,12 +141,12 @@ export const DateRangePicker = sveltify< getPopupContainer={getPopupContainerFunction} cellRender={ slots.cellRender - ? renderParamsSlot({ slots, setSlotParams, key: 'cellRender' }) + ? renderParamsSlot({ slots, key: 'cellRender' }) : cellRenderFunction } panelRender={ slots.panelRender - ? renderParamsSlot({ slots, setSlotParams, key: 'panelRender' }) + ? renderParamsSlot({ slots, key: 'panelRender' }) : panelRenderFunction } presets={useMemo(() => { @@ -182,7 +179,6 @@ export const DateRangePicker = sveltify< slots.renderExtraFooter ? renderParamsSlot({ slots, - setSlotParams, key: 'renderExtraFooter', }) : props.renderExtraFooter diff --git a/frontend/antd/descriptions/Index.svelte b/frontend/antd/descriptions/Index.svelte index 4f91b9ba..a343a096 100644 --- a/frontend/antd/descriptions/Index.svelte +++ b/frontend/antd/descriptions/Index.svelte @@ -1,76 +1,63 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDescriptions then Descriptions} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/descriptions/item/Index.svelte b/frontend/antd/descriptions/item/Index.svelte index a19a04f6..d2526838 100644 --- a/frontend/antd/descriptions/item/Index.svelte +++ b/frontend/antd/descriptions/item/Index.svelte @@ -1,95 +1,74 @@ - - {#await AwaitedDescriptionsItem then DescriptionsItem} - {#if $mergedProps.visible} - - + {#if proceedProps.visible} + + {@render children()} {/if} diff --git a/frontend/antd/divider/Index.svelte b/frontend/antd/divider/Index.svelte index b9ef09c0..a74d528e 100644 --- a/frontend/antd/divider/Index.svelte +++ b/frontend/antd/divider/Index.svelte @@ -1,86 +1,73 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDivider then Divider} - {#if $mergedProps._internal.layout} - - + {#if proceedProps._internal.layout} + + {@render children()} - {:else if $mergedProps.value} - - {$mergedProps.value} + {:else if proceedProps.value} + + {proceedProps.value} {:else} - + {/if} {/await} {/if} - - diff --git a/frontend/antd/drawer/Index.svelte b/frontend/antd/drawer/Index.svelte index fe0e849c..86b7cea9 100644 --- a/frontend/antd/drawer/Index.svelte +++ b/frontend/antd/drawer/Index.svelte @@ -1,76 +1,60 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDrawer then Drawer} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/drawer/drawer.tsx b/frontend/antd/drawer/drawer.tsx index f9a71f1f..eda69daf 100644 --- a/frontend/antd/drawer/drawer.tsx +++ b/frontend/antd/drawer/drawer.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -13,9 +12,7 @@ function getConfig(value: T): Partial> { return {} as any; } export const Drawer = sveltify< - GetProps & { - setSlotParams: SetSlotParams; - }, + GetProps, [ 'closeIcon', 'closable.closeIcon', @@ -24,52 +21,39 @@ export const Drawer = sveltify< 'title', 'drawerRender', ] ->( - ({ - slots, - afterOpenChange, - getContainer, - drawerRender, - setSlotParams, - ...props - }) => { - const afterOpenChangeFunction = useFunction(afterOpenChange); - const getContainerFunction = useFunction(getContainer); - const drawerRenderFunction = useFunction(drawerRender); - const closableConfig = getConfig(props.closable); - return ( - , - } - : props.closable - } - closeIcon={ - slots.closeIcon ? ( - - ) : ( - props.closeIcon - ) - } - extra={slots.extra ? : props.extra} - footer={slots.footer ? : props.footer} - title={slots.title ? : props.title} - drawerRender={ - slots.drawerRender - ? renderParamsSlot({ slots, setSlotParams, key: 'drawerRender' }) - : drawerRenderFunction - } - getContainer={ - typeof getContainer === 'string' ? getContainerFunction : getContainer - } - /> - ); - } -); +>(({ slots, afterOpenChange, getContainer, drawerRender, ...props }) => { + const afterOpenChangeFunction = useFunction(afterOpenChange); + const getContainerFunction = useFunction(getContainer); + const drawerRenderFunction = useFunction(drawerRender); + const closableConfig = getConfig(props.closable); + return ( + , + } + : props.closable + } + closeIcon={ + slots.closeIcon ? : props.closeIcon + } + extra={slots.extra ? : props.extra} + footer={slots.footer ? : props.footer} + title={slots.title ? : props.title} + drawerRender={ + slots.drawerRender + ? renderParamsSlot({ slots, key: 'drawerRender' }) + : drawerRenderFunction + } + getContainer={ + typeof getContainer === 'string' ? getContainerFunction : getContainer + } + /> + ); +}); export default Drawer; diff --git a/frontend/antd/dropdown/Index.svelte b/frontend/antd/dropdown/Index.svelte index 3baddbdf..24c5e862 100644 --- a/frontend/antd/dropdown/Index.svelte +++ b/frontend/antd/dropdown/Index.svelte @@ -1,81 +1,68 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDropdown then Dropdown} - + {@render children?.()} {/await} {/if} - - diff --git a/frontend/antd/dropdown/button/Index.svelte b/frontend/antd/dropdown/button/Index.svelte index 947c2029..a25e8af9 100644 --- a/frontend/antd/dropdown/button/Index.svelte +++ b/frontend/antd/dropdown/button/Index.svelte @@ -1,88 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDropdownButton then DropdownButton} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/dropdown/button/dropdown.button.tsx b/frontend/antd/dropdown/button/dropdown.button.tsx index 35a4b901..78b45c49 100644 --- a/frontend/antd/dropdown/button/dropdown.button.tsx +++ b/frontend/antd/dropdown/button/dropdown.button.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useTargets } from '@utils/hooks/useTargets'; @@ -16,7 +15,6 @@ import { export const DropdownButton = sveltify< GetProps & { - setSlotParams: SetSlotParams; value?: string; }, [ @@ -37,7 +35,6 @@ export const DropdownButton = sveltify< dropdownRender, popupRender, buttonsRender, - setSlotParams, value, ...props }) => { @@ -62,7 +59,6 @@ export const DropdownButton = sveltify< ? renderParamsSlot({ key: 'buttonsRender', slots, - setSlotParams, targets: buttonsRenderTargets, }) : buttonsRenderFunction @@ -80,7 +76,7 @@ export const DropdownButton = sveltify< }, [menuItems, props.menu?.items]), expandIcon: slots['menu.expandIcon'] ? renderParamsSlot( - { slots, setSlotParams, key: 'menu.expandIcon' }, + { slots, key: 'menu.expandIcon' }, { clone: true } ) : props.menu?.expandIcon, @@ -95,7 +91,6 @@ export const DropdownButton = sveltify< slots.dropdownRender ? renderParamsSlot({ slots, - setSlotParams, key: 'dropdownRender', }) : dropdownRenderFunction @@ -103,7 +98,7 @@ export const DropdownButton = sveltify< popupRender={ slots.popupRender ? renderParamsSlot( - { slots, setSlotParams, key: 'popupRender' }, + { slots, key: 'popupRender' }, { clone: true } ) : popupRenderFunction diff --git a/frontend/antd/dropdown/dropdown.tsx b/frontend/antd/dropdown/dropdown.tsx index a5c9fcda..5349bd25 100644 --- a/frontend/antd/dropdown/dropdown.tsx +++ b/frontend/antd/dropdown/dropdown.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderItems } from '@utils/renderItems'; @@ -16,7 +15,6 @@ import { export const Dropdown = sveltify< GetProps & { innerStyle?: React.CSSProperties; - setSlotParams: SetSlotParams; }, [ 'menu.expandIcon', @@ -34,7 +32,6 @@ export const Dropdown = sveltify< slots, dropdownRender, popupRender, - setSlotParams, ...props }) => { const getPopupContainerFunction = useFunction(getPopupContainer); @@ -60,7 +57,7 @@ export const Dropdown = sveltify< }, [menuItems, props.menu?.items]), expandIcon: slots['menu.expandIcon'] ? renderParamsSlot( - { slots, setSlotParams, key: 'menu.expandIcon' }, + { slots, key: 'menu.expandIcon' }, { clone: true } ) : props.menu?.expandIcon, @@ -76,7 +73,6 @@ export const Dropdown = sveltify< ? renderParamsSlot( { slots, - setSlotParams, key: 'dropdownRender', }, { clone: true } @@ -88,7 +84,6 @@ export const Dropdown = sveltify< ? renderParamsSlot( { slots, - setSlotParams, key: 'popupRender', }, { clone: true } diff --git a/frontend/antd/empty/Index.svelte b/frontend/antd/empty/Index.svelte index 521a0c6b..86c8850f 100644 --- a/frontend/antd/empty/Index.svelte +++ b/frontend/antd/empty/Index.svelte @@ -1,73 +1,60 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedEmpty then Empty} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/empty/empty.tsx b/frontend/antd/empty/empty.tsx index 1ad4d9ea..6b4a69b5 100644 --- a/frontend/antd/empty/empty.tsx +++ b/frontend/antd/empty/empty.tsx @@ -1,6 +1,7 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import { Empty as AEmpty, type GetProps } from 'antd'; +import { isFunction } from 'lodash-es'; export const Empty = sveltify< GetProps, @@ -19,6 +20,7 @@ export const Empty = sveltify< return props.image; } }; + return ( { + if (isFunction(styles)) { + return styles(info); + } + return { + ...styles, + image: { + display: 'inline-block', + ...styles?.image, + }, + }; }} image={getImage()} /> diff --git a/frontend/antd/flex/Index.svelte b/frontend/antd/flex/Index.svelte index 76182e64..716e20f6 100644 --- a/frontend/antd/flex/Index.svelte +++ b/frontend/antd/flex/Index.svelte @@ -1,73 +1,60 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedFlex then Flex} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/float-button/Index.svelte b/frontend/antd/float-button/Index.svelte index 1891fe5e..eef824a5 100644 --- a/frontend/antd/float-button/Index.svelte +++ b/frontend/antd/float-button/Index.svelte @@ -1,77 +1,68 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedFloatButton then FloatButton} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/float-button/back-top/Index.svelte b/frontend/antd/float-button/back-top/Index.svelte index bb49bb8f..6627b3fb 100644 --- a/frontend/antd/float-button/back-top/Index.svelte +++ b/frontend/antd/float-button/back-top/Index.svelte @@ -1,78 +1,71 @@ - - -{#if $mergedProps.visible} - {#await AwaitedFloatButtonBackTop then FloatButtonBackTop} - + id={proceedProps.elem_id} + {...proceedProps.restProps} + {...proceedProps.additionalProps} + slots={slots.value} + > + {@render children()} + {/await} {/if} diff --git a/frontend/antd/float-button/group/Index.svelte b/frontend/antd/float-button/group/Index.svelte index 414f8ae4..29f71f6a 100644 --- a/frontend/antd/float-button/group/Index.svelte +++ b/frontend/antd/float-button/group/Index.svelte @@ -1,83 +1,70 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedFloatButtonGroup then FloatButtonGroup} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/form/Index.svelte b/frontend/antd/form/Index.svelte index 94345fda..8d9ed0a7 100644 --- a/frontend/antd/form/Index.svelte +++ b/frontend/antd/form/Index.svelte @@ -1,103 +1,92 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedForm then Form}

{ - value = v; + updateProps({ + value: v, + }); }} onResetFormAction={() => { - form_action = null; + updateProps({ + form_action: null, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/form/form.tsx b/frontend/antd/form/form.tsx index da546642..c3b86d03 100644 --- a/frontend/antd/form/form.tsx +++ b/frontend/antd/form/form.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useEffect } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useMemoizedFn } from '@utils/hooks/useMemoizedFn'; @@ -7,9 +6,8 @@ import { renderParamsSlot } from '@utils/renderParamsSlot'; import { Form as AForm, type GetProps } from 'antd'; export interface FormProps extends GetProps { - value: Record; + value?: Record; onValueChange: (value: Record) => void; - setSlotParams: SetSlotParams; formAction?: 'reset' | 'submit' | 'validate' | null; onResetFormAction: () => void; } @@ -22,7 +20,6 @@ export const Form = sveltify( requiredMark, onValuesChange, feedbackIcons, - setSlotParams, slots, onResetFormAction, ...props @@ -62,7 +59,6 @@ export const Form = sveltify( slots.requiredMark ? renderParamsSlot({ key: 'requiredMark', - setSlotParams, slots, }) : requiredMark === 'optional' diff --git a/frontend/antd/form/item/Index.svelte b/frontend/antd/form/item/Index.svelte index 7ce66328..947baf1e 100644 --- a/frontend/antd/form/item/Index.svelte +++ b/frontend/antd/form/item/Index.svelte @@ -1,76 +1,65 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedFormItem then FormItem} - + {@render children?.()} {/await} {/if} - - diff --git a/frontend/antd/form/item/rule/Index.svelte b/frontend/antd/form/item/rule/Index.svelte index 69e1ba98..12e6a9d0 100644 --- a/frontend/antd/form/item/rule/Index.svelte +++ b/frontend/antd/form/item/rule/Index.svelte @@ -1,73 +1,66 @@ - - {#await AwaitedFormItemRule then FormItemRule} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/form/provider/Index.svelte b/frontend/antd/form/provider/Index.svelte index ac15cd75..d6a7bb80 100644 --- a/frontend/antd/form/provider/Index.svelte +++ b/frontend/antd/form/provider/Index.svelte @@ -1,69 +1,62 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedFormProvider then FormProvider} - + {@render children?.()} {/await} {/if} - - diff --git a/frontend/antd/grid/col/Index.svelte b/frontend/antd/grid/col/Index.svelte index f4a20f7d..de3b95af 100644 --- a/frontend/antd/grid/col/Index.svelte +++ b/frontend/antd/grid/col/Index.svelte @@ -1,76 +1,68 @@ - - {#await AwaitedCol then Col} - {#if $mergedProps.visible} - - + {#if proceedProps.visible} + + {@render children()} {/if} diff --git a/frontend/antd/grid/row/Index.svelte b/frontend/antd/grid/row/Index.svelte index 22a4861f..4af3e6c6 100644 --- a/frontend/antd/grid/row/Index.svelte +++ b/frontend/antd/grid/row/Index.svelte @@ -1,73 +1,59 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedRow then Row} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/icon/Index.svelte b/frontend/antd/icon/Index.svelte index 3efe2b66..34431024 100644 --- a/frontend/antd/icon/Index.svelte +++ b/frontend/antd/icon/Index.svelte @@ -15,7 +15,7 @@ _internal: { layout?: boolean; }; - value: string | undefined; + value?: string; }>(() => props); const getProceedProps = processProps(() => { @@ -23,10 +23,10 @@ visible, _internal, as_item, - value, elem_classes, elem_id, elem_style, + value, ...restProps } = getComponentProps(); return { @@ -34,15 +34,18 @@ _internal, as_item, restProps, - value, visible, elem_id, elem_classes, elem_style, + value, }; }); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); + const value = $derived( + proceedProps.additionalProps.value || proceedProps.value || '' + ); {#if proceedProps.visible} @@ -53,8 +56,8 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} + {value} slots={slots.value} - value={proceedProps.value} > {@render children()} diff --git a/frontend/antd/image/Index.svelte b/frontend/antd/image/Index.svelte index 57a701f6..49ceb00c 100644 --- a/frontend/antd/image/Index.svelte +++ b/frontend/antd/image/Index.svelte @@ -1,94 +1,81 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedImage then Image} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/image/image.tsx b/frontend/antd/image/image.tsx index 4be0f667..ed5e184a 100644 --- a/frontend/antd/image/image.tsx +++ b/frontend/antd/image/image.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useFunction } from '@utils/hooks/useFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -15,7 +14,6 @@ function getConfig(value: T): Partial> { type ImageProps = GetProps; export const Image = sveltify< ImageProps & { - setSlotParams: SetSlotParams; }, [ 'placeholder', @@ -24,7 +22,7 @@ export const Image = sveltify< 'preview.toolbarRender', 'preview.imageRender', ] ->(({ slots, preview, setSlotParams, children, ...props }) => { +>(({ slots, preview, children, ...props }) => { const previewConfig = getConfig(preview); const supportPreview = slots['preview.mask'] || @@ -49,14 +47,12 @@ export const Image = sveltify< toolbarRender: slots['preview.toolbarRender'] ? renderParamsSlot({ slots, - setSlotParams, key: 'preview.toolbarRender', }) : previewToolbarRenderFunction, imageRender: slots['preview.imageRender'] ? renderParamsSlot({ slots, - setSlotParams, key: 'preview.imageRender', }) : previewImageRenderFunction, diff --git a/frontend/antd/image/preview-group/Index.svelte b/frontend/antd/image/preview-group/Index.svelte index 56bf9834..215109a5 100644 --- a/frontend/antd/image/preview-group/Index.svelte +++ b/frontend/antd/image/preview-group/Index.svelte @@ -1,84 +1,70 @@ - - - -{#if $mergedProps.visible} - {#await AwaitedImagePreviewGroup then ImagePreviewGroup} - - - + {@render children()} + {/await} {/if} - - diff --git a/frontend/antd/input-number/Index.svelte b/frontend/antd/input-number/Index.svelte index 53ce7501..b0cc3226 100644 --- a/frontend/antd/input-number/Index.svelte +++ b/frontend/antd/input-number/Index.svelte @@ -1,81 +1,78 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedInputNumber then InputNumber} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/input/Index.svelte b/frontend/antd/input/Index.svelte index 6a18655e..4354dfd8 100644 --- a/frontend/antd/input/Index.svelte +++ b/frontend/antd/input/Index.svelte @@ -1,86 +1,77 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedInput then Input} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/input/input.tsx b/frontend/antd/input/input.tsx index 88792c1c..8d7d4c9d 100644 --- a/frontend/antd/input/input.tsx +++ b/frontend/antd/input/input.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; @@ -11,7 +10,6 @@ import { type GetProps, Input as AInput } from 'antd'; export const Input = sveltify< GetProps & { onValueChange: (value: string) => void; - setSlotParams: SetSlotParams; }, [ 'addonAfter', @@ -29,7 +27,6 @@ export const Input = sveltify< showCount, onValueChange, onChange, - setSlotParams, elRef, ...props }) => { @@ -60,7 +57,6 @@ export const Input = sveltify< ? { formatter: renderParamsSlot({ slots, - setSlotParams, key: 'showCount.formatter', })!, } diff --git a/frontend/antd/input/otp/Index.svelte b/frontend/antd/input/otp/Index.svelte index 4780596a..10f39c39 100644 --- a/frontend/antd/input/otp/Index.svelte +++ b/frontend/antd/input/otp/Index.svelte @@ -1,80 +1,67 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedInputOTP then InputOTP} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} - /> + > + {@render children()} + {/await} {/if} diff --git a/frontend/antd/input/otp/input.otp.tsx b/frontend/antd/input/otp/input.otp.tsx index 3c65591f..27449183 100644 --- a/frontend/antd/input/otp/input.otp.tsx +++ b/frontend/antd/input/otp/input.otp.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -8,7 +7,6 @@ import { type GetProps, Input as AInput } from 'antd'; export const InputOTP = sveltify< GetProps & { onValueChange: (value: string) => void; - setSlotParams: SetSlotParams; }, ['separator'] >( @@ -17,7 +15,6 @@ export const InputOTP = sveltify< onValueChange, onChange, children, - setSlotParams, elRef, slots, separator, @@ -42,7 +39,6 @@ export const InputOTP = sveltify< slots.separator ? renderParamsSlot({ slots, - setSlotParams, key: 'separator', }) : separatorFunction || separator diff --git a/frontend/antd/input/password/Index.svelte b/frontend/antd/input/password/Index.svelte index 67ae2612..d546726e 100644 --- a/frontend/antd/input/password/Index.svelte +++ b/frontend/antd/input/password/Index.svelte @@ -1,92 +1,76 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedInputPassword then InputPassword} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/input/password/input.password.tsx b/frontend/antd/input/password/input.password.tsx index ece85034..dae6efcd 100644 --- a/frontend/antd/input/password/input.password.tsx +++ b/frontend/antd/input/password/input.password.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; @@ -11,7 +10,6 @@ import { type GetProps, Input as AInput } from 'antd'; export const InputPassword = sveltify< GetProps & { onValueChange: (value: string) => void; - setSlotParams: SetSlotParams; }, [ 'iconRender', @@ -32,7 +30,6 @@ export const InputPassword = sveltify< onChange, iconRender, elRef, - setSlotParams, ...props }) => { const countStrategyFunction = useFunction(count?.strategy); @@ -61,7 +58,6 @@ export const InputPassword = sveltify< slots.iconRender ? renderParamsSlot({ slots, - setSlotParams, key: 'iconRender', }) : iconRenderFunction @@ -71,7 +67,6 @@ export const InputPassword = sveltify< ? { formatter: renderParamsSlot({ slots, - setSlotParams, key: 'showCount.formatter', })!, } diff --git a/frontend/antd/input/search/Index.svelte b/frontend/antd/input/search/Index.svelte index bfdd86a6..8be16daa 100644 --- a/frontend/antd/input/search/Index.svelte +++ b/frontend/antd/input/search/Index.svelte @@ -1,89 +1,72 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedInputSearch then InputSearch} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/input/search/input.search.tsx b/frontend/antd/input/search/input.search.tsx index 1556b954..57db2de8 100644 --- a/frontend/antd/input/search/input.search.tsx +++ b/frontend/antd/input/search/input.search.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; @@ -11,7 +10,6 @@ import { type GetProps, Input as AInput } from 'antd'; export const InputSearch = sveltify< GetProps & { onValueChange: (value: string) => void; - setSlotParams: SetSlotParams; }, [ 'addonAfter', @@ -31,7 +29,6 @@ export const InputSearch = sveltify< onValueChange, onChange, elRef, - setSlotParams, ...props }) => { const countStrategyFunction = useFunction(count?.strategy); @@ -60,7 +57,6 @@ export const InputSearch = sveltify< ? { formatter: renderParamsSlot({ slots, - setSlotParams, key: 'showCount.formatter', })!, } diff --git a/frontend/antd/input/textarea/Index.svelte b/frontend/antd/input/textarea/Index.svelte index e087d762..fbe93556 100644 --- a/frontend/antd/input/textarea/Index.svelte +++ b/frontend/antd/input/textarea/Index.svelte @@ -1,91 +1,72 @@ - - -{#if $mergedProps.visible} - {#await AwaitedInputTextarea then InputTextarea} - { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - - + {@render children()} + {/await} {/if} - - diff --git a/frontend/antd/input/textarea/input.textarea.tsx b/frontend/antd/input/textarea/input.textarea.tsx index 2472c12e..da06f54c 100644 --- a/frontend/antd/input/textarea/input.textarea.tsx +++ b/frontend/antd/input/textarea/input.textarea.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; @@ -11,7 +10,6 @@ import { type GetProps, Input as AInput } from 'antd'; export const InputTextarea = sveltify< GetProps & { onValueChange: (value: string) => void; - setSlotParams: SetSlotParams; }, ['allowClear.clearIcon', 'showCount.formatter'] >( @@ -23,7 +21,6 @@ export const InputTextarea = sveltify< onValueChange, onChange, elRef, - setSlotParams, ...props }) => { const countStrategyFunction = useFunction(count?.strategy); @@ -52,7 +49,6 @@ export const InputTextarea = sveltify< ? { formatter: renderParamsSlot({ slots, - setSlotParams, key: 'showCount.formatter', })!, } diff --git a/frontend/antd/layout/Base.svelte b/frontend/antd/layout/Base.svelte index c4eab932..ee5e4698 100644 --- a/frontend/antd/layout/Base.svelte +++ b/frontend/antd/layout/Base.svelte @@ -1,71 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedLayoutBase then LayoutBase} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/layout/Index.svelte b/frontend/antd/layout/Index.svelte index bc283720..1758c9d3 100644 --- a/frontend/antd/layout/Index.svelte +++ b/frontend/antd/layout/Index.svelte @@ -1,10 +1,17 @@ - - - +{@render children()} diff --git a/frontend/antd/layout/content/Index.svelte b/frontend/antd/layout/content/Index.svelte index 33b0ffdf..1e2733dc 100644 --- a/frontend/antd/layout/content/Index.svelte +++ b/frontend/antd/layout/content/Index.svelte @@ -1,10 +1,14 @@ - - - + const { + children, + ...props + }: { + children?: Snippet; + } = $props(); + - +{@render children?.()} diff --git a/frontend/antd/layout/footer/Index.svelte b/frontend/antd/layout/footer/Index.svelte index de1f73b4..776d275a 100644 --- a/frontend/antd/layout/footer/Index.svelte +++ b/frontend/antd/layout/footer/Index.svelte @@ -1,10 +1,14 @@ - - - + const { + children, + ...props + }: { + children?: Snippet; + } = $props(); + - +{@render children?.()} diff --git a/frontend/antd/layout/header/Index.svelte b/frontend/antd/layout/header/Index.svelte index cedb6145..594e3729 100644 --- a/frontend/antd/layout/header/Index.svelte +++ b/frontend/antd/layout/header/Index.svelte @@ -1,10 +1,14 @@ - - - + const { + children, + ...props + }: { + children?: Snippet; + } = $props(); + - +{@render children?.()} diff --git a/frontend/antd/layout/sider/Index.svelte b/frontend/antd/layout/sider/Index.svelte index ad309d83..93793e9b 100644 --- a/frontend/antd/layout/sider/Index.svelte +++ b/frontend/antd/layout/sider/Index.svelte @@ -1,74 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedLayoutSider then LayoutSider} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/list/Index.svelte b/frontend/antd/list/Index.svelte index 75eafc60..055e7eb8 100644 --- a/frontend/antd/list/Index.svelte +++ b/frontend/antd/list/Index.svelte @@ -1,80 +1,67 @@ - - - -{#if $mergedProps.visible} + +{#if proceedProps.visible} {#await AwaitedList then List} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/list/item/Index.svelte b/frontend/antd/list/item/Index.svelte index 94ff9edd..02cdf615 100644 --- a/frontend/antd/list/item/Index.svelte +++ b/frontend/antd/list/item/Index.svelte @@ -1,68 +1,58 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedListItem then ListItem} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/list/item/meta/Index.svelte b/frontend/antd/list/item/meta/Index.svelte index 6f86bc1d..7dbb7071 100644 --- a/frontend/antd/list/item/meta/Index.svelte +++ b/frontend/antd/list/item/meta/Index.svelte @@ -1,68 +1,57 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedListItemMeta then ListItemMeta} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/list/list.tsx b/frontend/antd/list/list.tsx index 920635c7..6405aacc 100644 --- a/frontend/antd/list/list.tsx +++ b/frontend/antd/list/list.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -8,10 +7,9 @@ import { type GetProps, List as AList } from 'antd'; export const List = sveltify< GetProps & { - setSlotParams: SetSlotParams; }, ['footer', 'header', 'loadMore', 'renderItem'] ->(({ slots, renderItem, setSlotParams, ...props }) => { +>(({ slots, renderItem, ...props }) => { const renderItemFunction = useFunction(renderItem); return ( - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedMentions then Mentions} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/mentions/option/Index.svelte b/frontend/antd/mentions/option/Index.svelte index c1086d55..8f6d981b 100644 --- a/frontend/antd/mentions/option/Index.svelte +++ b/frontend/antd/mentions/option/Index.svelte @@ -1,102 +1,70 @@ - - {#await AwaitedMentionsOption then MentionsOption} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/menu/Index.svelte b/frontend/antd/menu/Index.svelte index 97f87e0b..33064588 100644 --- a/frontend/antd/menu/Index.svelte +++ b/frontend/antd/menu/Index.svelte @@ -1,77 +1,67 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedMenu then Menu} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/menu/item/Index.svelte b/frontend/antd/menu/item/Index.svelte index a1d86111..163b3aac 100644 --- a/frontend/antd/menu/item/Index.svelte +++ b/frontend/antd/menu/item/Index.svelte @@ -1,86 +1,78 @@ - - {#await AwaitedMenuItem then MenuItem} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/menu/menu.tsx b/frontend/antd/menu/menu.tsx index d2d3457a..a82ffdac 100644 --- a/frontend/antd/menu/menu.tsx +++ b/frontend/antd/menu/menu.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { renderItems } from '@utils/renderItems'; @@ -14,7 +13,6 @@ import './menu.less'; export const Menu = sveltify< GetProps & { - setSlotParams: SetSlotParams; }, ['expandIcon', 'overflowedIndicator'] >( @@ -27,7 +25,6 @@ export const Menu = sveltify< onOpenChange, onSelect, onDeselect, - setSlotParams, ...props }) => { const { items: slotItems } = useItems<['default', 'items']>(); @@ -62,7 +59,6 @@ export const Menu = sveltify< { key: 'expandIcon', slots, - setSlotParams, }, { clone: true, diff --git a/frontend/antd/message/Index.svelte b/frontend/antd/message/Index.svelte index ea2c175a..6abc2364 100644 --- a/frontend/antd/message/Index.svelte +++ b/frontend/antd/message/Index.svelte @@ -1,81 +1,71 @@ - - {#await AwaitedMessage then Message} { - visible = v; + updateProps({ + visible: v, + }); }} > - + {@render children()} {/await} - - diff --git a/frontend/antd/modal/Index.svelte b/frontend/antd/modal/Index.svelte index c42604b0..faea1288 100644 --- a/frontend/antd/modal/Index.svelte +++ b/frontend/antd/modal/Index.svelte @@ -1,79 +1,61 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedModal then Modal} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/modal/modal.tsx b/frontend/antd/modal/modal.tsx index 52ea77df..b871bead 100644 --- a/frontend/antd/modal/modal.tsx +++ b/frontend/antd/modal/modal.tsx @@ -1,15 +1,12 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; import { type GetProps, Modal as AModal } from 'antd'; export const Modal = sveltify< - GetProps & { - setSlotParams: SetSlotParams; - }, + GetProps, [ 'cancelButtonProps.icon', 'cancelText', @@ -29,7 +26,6 @@ export const Modal = sveltify< getContainer, children, modalRender, - setSlotParams, ...props }) => { const afterOpenChangeFunction = useFunction(afterOpenChange); @@ -83,7 +79,7 @@ export const Modal = sveltify< } footer={ slots.footer - ? renderParamsSlot({ slots, setSlotParams, key: 'footer' }) + ? renderParamsSlot({ slots, key: 'footer' }) : footerFunction || (props.footer === 'DEFAULT_FOOTER' ? undefined @@ -94,7 +90,7 @@ export const Modal = sveltify< title={slots.title ? : props.title} modalRender={ slots.modalRender - ? renderParamsSlot({ slots, setSlotParams, key: 'modalRender' }) + ? renderParamsSlot({ slots, key: 'modalRender' }) : modalRenderFunction } getContainer={ diff --git a/frontend/antd/modal/static/Index.svelte b/frontend/antd/modal/static/Index.svelte index 3250bc4d..94f0b10c 100644 --- a/frontend/antd/modal/static/Index.svelte +++ b/frontend/antd/modal/static/Index.svelte @@ -1,81 +1,63 @@ - - {#await AwaitedModalStatic then ModalStatic} { - visible = v; + updateProps({ visible: v }); }} > - + {@render children()} {/await} - - diff --git a/frontend/antd/modal/static/modal.static.tsx b/frontend/antd/modal/static/modal.static.tsx index 48004912..97fbbef5 100644 --- a/frontend/antd/modal/static/modal.static.tsx +++ b/frontend/antd/modal/static/modal.static.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useEffect, useRef } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -9,7 +8,6 @@ import type { ModalFuncWithPromise } from 'antd/es/modal/useModal'; export const ModalStatic = sveltify< ModalFuncProps & { - setSlotParams: SetSlotParams; visible?: boolean; type?: 'info' | 'success' | 'error' | 'warning' | 'confirm'; onVisible?: (visible: boolean) => void; @@ -34,7 +32,6 @@ export const ModalStatic = sveltify< getContainer, children, modalRender, - setSlotParams, onVisible, onCancel, onOk, @@ -101,11 +98,11 @@ export const ModalStatic = sveltify< props.closeIcon ), footer: slots.footer - ? renderParamsSlot({ slots, setSlotParams, key: 'footer' }) + ? renderParamsSlot({ slots, key: 'footer' }) : props.footer, title: slots.title ? : props.title, modalRender: slots.modalRender - ? renderParamsSlot({ slots, setSlotParams, key: 'modalRender' }) + ? renderParamsSlot({ slots, key: 'modalRender' }) : modalRenderFunction, onCancel(...args) { onCancel?.(...args); diff --git a/frontend/antd/notification/Index.svelte b/frontend/antd/notification/Index.svelte index b2fb750f..2370aed3 100644 --- a/frontend/antd/notification/Index.svelte +++ b/frontend/antd/notification/Index.svelte @@ -1,81 +1,73 @@ - - {#await AwaitedNotification then Notification} { - visible = v; + updateProps({ + visible: v, + }); }} > - + {@render children()} {/await} - - diff --git a/frontend/antd/pagination/Index.svelte b/frontend/antd/pagination/Index.svelte index 3b566649..b8405fe4 100644 --- a/frontend/antd/pagination/Index.svelte +++ b/frontend/antd/pagination/Index.svelte @@ -1,80 +1,66 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedPagination then Pagination} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/pagination/pagination.tsx b/frontend/antd/pagination/pagination.tsx index af3e7492..42154a78 100644 --- a/frontend/antd/pagination/pagination.tsx +++ b/frontend/antd/pagination/pagination.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -9,7 +8,6 @@ import { type GetProps, Pagination as APagination } from 'antd'; export const Pagination = sveltify< GetProps & { children?: React.ReactNode; - setSlotParams: SetSlotParams; }, ['showQuickJumper.goButton', 'itemRender'] >( @@ -20,7 +18,6 @@ export const Pagination = sveltify< onChange, children, itemRender, - setSlotParams, ...props }) => { const itemRenderFunction = useFunction(itemRender); @@ -34,7 +31,7 @@ export const Pagination = sveltify< itemRender={ slots.itemRender ? renderParamsSlot( - { slots, setSlotParams, key: 'itemRender' }, + { slots, key: 'itemRender' }, { clone: true } ) : itemRenderFunction diff --git a/frontend/antd/popconfirm/Index.svelte b/frontend/antd/popconfirm/Index.svelte index f2c22de7..e4c01ec9 100644 --- a/frontend/antd/popconfirm/Index.svelte +++ b/frontend/antd/popconfirm/Index.svelte @@ -1,79 +1,74 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedPopconfirm then Popconfirm} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/popover/Index.svelte b/frontend/antd/popover/Index.svelte index 0587d97f..0608b933 100644 --- a/frontend/antd/popover/Index.svelte +++ b/frontend/antd/popover/Index.svelte @@ -1,74 +1,71 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedPopover then Popover} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/progress/Index.svelte b/frontend/antd/progress/Index.svelte index e0e8c4a9..a07f5109 100644 --- a/frontend/antd/progress/Index.svelte +++ b/frontend/antd/progress/Index.svelte @@ -1,73 +1,62 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedProgress then Progress} {/await} {/if} diff --git a/frontend/antd/qr-code/Index.svelte b/frontend/antd/qr-code/Index.svelte index 3eaac18f..38b8448d 100644 --- a/frontend/antd/qr-code/Index.svelte +++ b/frontend/antd/qr-code/Index.svelte @@ -1,78 +1,62 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedQRCode then QRCode} {/await} {/if} diff --git a/frontend/antd/qr-code/qr-code.tsx b/frontend/antd/qr-code/qr-code.tsx index f87b4d16..687ba7c9 100644 --- a/frontend/antd/qr-code/qr-code.tsx +++ b/frontend/antd/qr-code/qr-code.tsx @@ -1,22 +1,20 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; import { type GetProps, QRCode as AQRCode } from 'antd'; export const QRCode = sveltify< GetProps & { - setSlotParams: SetSlotParams; }, ['statusRender'] ->(({ setSlotParams, slots, statusRender, ...props }) => { +>(({ slots, statusRender, ...props }) => { const statusRenderFunction = useFunction(statusRender); return ( diff --git a/frontend/antd/radio/Index.svelte b/frontend/antd/radio/Index.svelte index 7ffa72c4..34cd81d1 100644 --- a/frontend/antd/radio/Index.svelte +++ b/frontend/antd/radio/Index.svelte @@ -1,84 +1,76 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedRadio then Radio} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/radio/button/Index.svelte b/frontend/antd/radio/button/Index.svelte index 38cfef38..3f4014bd 100644 --- a/frontend/antd/radio/button/Index.svelte +++ b/frontend/antd/radio/button/Index.svelte @@ -1,84 +1,77 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedRadioButton then RadioButton} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/radio/group/Index.svelte b/frontend/antd/radio/group/Index.svelte index 4b236f1c..f19f4501 100644 --- a/frontend/antd/radio/group/Index.svelte +++ b/frontend/antd/radio/group/Index.svelte @@ -1,84 +1,73 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedRadioGroup then RadioGroup} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/radio/group/option/Index.svelte b/frontend/antd/radio/group/option/Index.svelte index 0b5dcd76..707ee92c 100644 --- a/frontend/antd/radio/group/option/Index.svelte +++ b/frontend/antd/radio/group/option/Index.svelte @@ -1,109 +1,99 @@ - - {#await AwaitedRadioGroupOption then RadioGroupOption} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/rate/Index.svelte b/frontend/antd/rate/Index.svelte index 2ba203ca..eb6775a3 100644 --- a/frontend/antd/rate/Index.svelte +++ b/frontend/antd/rate/Index.svelte @@ -1,88 +1,80 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedRate then Rate} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/rate/rate.tsx b/frontend/antd/rate/rate.tsx index 31a9a009..b643902f 100644 --- a/frontend/antd/rate/rate.tsx +++ b/frontend/antd/rate/rate.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; import { type GetProps, Rate as ARate } from 'antd'; @@ -8,7 +7,6 @@ export const Rate = sveltify< GetProps & { onValueChange: (value: number) => void; children?: React.ReactNode; - setSlotParams: SetSlotParams; }, ['character'] >( @@ -18,7 +16,6 @@ export const Rate = sveltify< onValueChange, character, onChange, - setSlotParams, elRef, ...props }) => { @@ -35,7 +32,7 @@ export const Rate = sveltify< }} character={ slots.character - ? renderParamsSlot({ slots, setSlotParams, key: 'character' }) + ? renderParamsSlot({ slots, key: 'character' }) : characterFunction || character } /> diff --git a/frontend/antd/result/Index.svelte b/frontend/antd/result/Index.svelte index 5f28ee14..8aacd506 100644 --- a/frontend/antd/result/Index.svelte +++ b/frontend/antd/result/Index.svelte @@ -1,70 +1,59 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedResult then Result} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/segmented/Index.svelte b/frontend/antd/segmented/Index.svelte index 2af9c81f..b091b066 100644 --- a/frontend/antd/segmented/Index.svelte +++ b/frontend/antd/segmented/Index.svelte @@ -1,83 +1,82 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSegmented then Segmented} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/segmented/option/Index.svelte b/frontend/antd/segmented/option/Index.svelte index ba33c847..6906a3f5 100644 --- a/frontend/antd/segmented/option/Index.svelte +++ b/frontend/antd/segmented/option/Index.svelte @@ -1,90 +1,69 @@ - - {#await AwaitedSegmentedOption then SegmentedOption} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/segmented/segmented.tsx b/frontend/antd/segmented/segmented.tsx index d6ac06bc..9389dc58 100644 --- a/frontend/antd/segmented/segmented.tsx +++ b/frontend/antd/segmented/segmented.tsx @@ -5,7 +5,8 @@ import { type GetProps, Segmented as ASegmented } from 'antd'; import { useItems, withItemsContextProvider } from './context'; -type SegmentedProps = GetProps; +export type SegmentedProps = GetProps; + export const Segmented = sveltify< SegmentedProps & { onValueChange: (value: string | number) => void; diff --git a/frontend/antd/select/Index.svelte b/frontend/antd/select/Index.svelte index 647c882f..2a28e83e 100644 --- a/frontend/antd/select/Index.svelte +++ b/frontend/antd/select/Index.svelte @@ -1,89 +1,81 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSelect then Select} {/await} {/if} - - diff --git a/frontend/antd/select/option/Index.svelte b/frontend/antd/select/option/Index.svelte index 0f05e733..5e7dc86c 100644 --- a/frontend/antd/select/option/Index.svelte +++ b/frontend/antd/select/option/Index.svelte @@ -1,104 +1,64 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSelectOption then SelectOption} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/select/select.tsx b/frontend/antd/select/select.tsx index ccc061d9..8615f3a5 100644 --- a/frontend/antd/select/select.tsx +++ b/frontend/antd/select/select.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderItems } from '@utils/renderItems'; @@ -12,7 +11,6 @@ import { useItems, withItemsContextProvider } from './context'; export const Select = sveltify< GetProps & { onValueChange: (value: string | number | (string | number)[]) => void; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -46,7 +44,6 @@ export const Select = sveltify< labelRender, filterSort, elRef, - setSlotParams, ...props }) => { const getPopupContainerFunction = useFunction(getPopupContainer); @@ -127,7 +124,6 @@ export const Select = sveltify< slots.maxTagPlaceholder ? renderParamsSlot({ slots, - setSlotParams, key: 'maxTagPlaceholder', }) : props.maxTagPlaceholder @@ -137,7 +133,6 @@ export const Select = sveltify< slots.dropdownRender ? renderParamsSlot({ slots, - setSlotParams, key: 'dropdownRender', }) : dropdownRenderFunction @@ -146,7 +141,6 @@ export const Select = sveltify< slots.popupRender ? renderParamsSlot({ slots, - setSlotParams, key: 'popupRender', }) : popupRenderFunction @@ -155,7 +149,6 @@ export const Select = sveltify< slots.optionRender ? renderParamsSlot({ slots, - setSlotParams, key: 'optionRender', }) : optionRenderFunction @@ -164,7 +157,6 @@ export const Select = sveltify< slots.tagRender ? renderParamsSlot({ slots, - setSlotParams, key: 'tagRender', }) : tagRenderFunction @@ -173,7 +165,6 @@ export const Select = sveltify< slots.labelRender ? renderParamsSlot({ slots, - setSlotParams, key: 'labelRender', }) : labelRenderFunction diff --git a/frontend/antd/skeleton/Index.svelte b/frontend/antd/skeleton/Index.svelte index 52f891ca..cec8af90 100644 --- a/frontend/antd/skeleton/Index.svelte +++ b/frontend/antd/skeleton/Index.svelte @@ -1,73 +1,59 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSkeleton then Skeleton} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/skeleton/avatar/Index.svelte b/frontend/antd/skeleton/avatar/Index.svelte index 75e7bb1e..7d1bb6e7 100644 --- a/frontend/antd/skeleton/avatar/Index.svelte +++ b/frontend/antd/skeleton/avatar/Index.svelte @@ -1,75 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSkeletonAvatar then SkeletonAvatar} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/skeleton/button/Index.svelte b/frontend/antd/skeleton/button/Index.svelte index 1417e492..b5fc22de 100644 --- a/frontend/antd/skeleton/button/Index.svelte +++ b/frontend/antd/skeleton/button/Index.svelte @@ -1,75 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSkeletonButton then SkeletonButton} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/skeleton/image/Index.svelte b/frontend/antd/skeleton/image/Index.svelte index c4fb677a..63f67abd 100644 --- a/frontend/antd/skeleton/image/Index.svelte +++ b/frontend/antd/skeleton/image/Index.svelte @@ -1,75 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSkeletonImage then SkeletonImage} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/skeleton/input/Index.svelte b/frontend/antd/skeleton/input/Index.svelte index d673621c..0c45ab3d 100644 --- a/frontend/antd/skeleton/input/Index.svelte +++ b/frontend/antd/skeleton/input/Index.svelte @@ -1,75 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSkeletonInput then SkeletonNodeInput} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/skeleton/node/Index.svelte b/frontend/antd/skeleton/node/Index.svelte index dae77478..c3467e75 100644 --- a/frontend/antd/skeleton/node/Index.svelte +++ b/frontend/antd/skeleton/node/Index.svelte @@ -1,70 +1,58 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSkeletonNode then SkeletonNode} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/slider/Index.svelte b/frontend/antd/slider/Index.svelte index c81e6b67..854b2124 100644 --- a/frontend/antd/slider/Index.svelte +++ b/frontend/antd/slider/Index.svelte @@ -1,84 +1,78 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSlider then Slider} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/slider/mark/Index.svelte b/frontend/antd/slider/mark/Index.svelte index 0017f877..73ae2695 100644 --- a/frontend/antd/slider/mark/Index.svelte +++ b/frontend/antd/slider/mark/Index.svelte @@ -1,97 +1,72 @@ - - {#await AwaitedSliderMark then SliderMark} - {#if $mergedProps.visible} - - + {#if proceedProps.visible} + + {@render children()} {/if} diff --git a/frontend/antd/slider/slider.tsx b/frontend/antd/slider/slider.tsx index d6090485..5b11bb16 100644 --- a/frontend/antd/slider/slider.tsx +++ b/frontend/antd/slider/slider.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -39,7 +38,6 @@ export const Slider = sveltify< SliderProps & { onValueChange: (value: number | number[]) => void; children?: React.ReactNode; - setSlotParams: SetSlotParams; }, ['tooltip.formatter'] >( @@ -54,7 +52,6 @@ export const Slider = sveltify< tooltip, step, slots, - setSlotParams, ...props }) => { const onSliderChange = (v: number | number[]) => { @@ -79,7 +76,6 @@ export const Slider = sveltify< formatter: slots['tooltip.formatter'] ? renderParamsSlot({ key: 'tooltip.formatter', - setSlotParams, slots, }) : tooltipFormatterFunction, diff --git a/frontend/antd/space/Index.svelte b/frontend/antd/space/Index.svelte index 00a37121..6fe9c072 100644 --- a/frontend/antd/space/Index.svelte +++ b/frontend/antd/space/Index.svelte @@ -1,72 +1,59 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSpace then Space} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/space/compact/Index.svelte b/frontend/antd/space/compact/Index.svelte index 2a118b09..84a86644 100644 --- a/frontend/antd/space/compact/Index.svelte +++ b/frontend/antd/space/compact/Index.svelte @@ -1,73 +1,58 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSpaceCompact then SpaceCompact} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/spin/Index.svelte b/frontend/antd/spin/Index.svelte index 2a7fda1b..2d2e7b40 100644 --- a/frontend/antd/spin/Index.svelte +++ b/frontend/antd/spin/Index.svelte @@ -1,75 +1,60 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSpin then Spin} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/splitter/Index.svelte b/frontend/antd/splitter/Index.svelte index b500ea58..2e426aec 100644 --- a/frontend/antd/splitter/Index.svelte +++ b/frontend/antd/splitter/Index.svelte @@ -1,75 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSplitter then Splitter} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/splitter/panel/Index.svelte b/frontend/antd/splitter/panel/Index.svelte index 730eb8fa..46ed4ca8 100644 --- a/frontend/antd/splitter/panel/Index.svelte +++ b/frontend/antd/splitter/panel/Index.svelte @@ -1,85 +1,69 @@ - - {#await AwaitedSplitterPanel then SplitterPanel} - {#if $mergedProps.visible} - - + {#if proceedProps.visible} + + {@render children()} {/if} diff --git a/frontend/antd/statistic/Index.svelte b/frontend/antd/statistic/Index.svelte index e34cc794..e95a9b40 100644 --- a/frontend/antd/statistic/Index.svelte +++ b/frontend/antd/statistic/Index.svelte @@ -1,78 +1,63 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedStatistic then Statistic} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/statistic/countdown/Index.svelte b/frontend/antd/statistic/countdown/Index.svelte index 608e608b..7362cd4b 100644 --- a/frontend/antd/statistic/countdown/Index.svelte +++ b/frontend/antd/statistic/countdown/Index.svelte @@ -1,76 +1,64 @@ - - -{#if $mergedProps.visible} - {#await AwaitedStatisticCountdown then StatisticCountdown} - - - + {@render children()} + {/await} {/if} - - diff --git a/frontend/antd/statistic/statistic.tsx b/frontend/antd/statistic/statistic.tsx index adaf1d4c..4aec9e06 100644 --- a/frontend/antd/statistic/statistic.tsx +++ b/frontend/antd/statistic/statistic.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -9,10 +8,9 @@ import { type GetProps, Statistic as AStatistic } from 'antd'; export const Statistic = sveltify< GetProps & { children: React.ReactNode; - setSlotParams: SetSlotParams; }, ['prefix', 'suffix', 'title', 'formatter'] ->(({ children, slots, setSlotParams, formatter, ...props }) => { +>(({ children, slots, formatter, ...props }) => { const formatterFunction = useFunction(formatter); return ( <> @@ -21,7 +19,7 @@ export const Statistic = sveltify< {...props} formatter={ slots.formatter - ? renderParamsSlot({ slots, setSlotParams, key: 'formatter' }) + ? renderParamsSlot({ slots, key: 'formatter' }) : formatterFunction } title={slots.title ? : props.title} diff --git a/frontend/antd/statistic/timer/Index.svelte b/frontend/antd/statistic/timer/Index.svelte index 21bc97b9..171c9bb3 100644 --- a/frontend/antd/statistic/timer/Index.svelte +++ b/frontend/antd/statistic/timer/Index.svelte @@ -1,74 +1,68 @@ - - -{#if $mergedProps.visible} - {#await AwaitedStatisticTimer then StatisticTimer} - - - + {@render children()} + {/await} {/if} - - diff --git a/frontend/antd/statistic/timer/statistic.timer.tsx b/frontend/antd/statistic/timer/statistic.timer.tsx index 26d704c6..628e971b 100644 --- a/frontend/antd/statistic/timer/statistic.timer.tsx +++ b/frontend/antd/statistic/timer/statistic.timer.tsx @@ -3,10 +3,12 @@ import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React from 'react'; import { type GetProps, Statistic as AStatistic } from 'antd'; +export type StatisticTimer = GetProps & { + children: React.ReactNode; +}; + export const StatisticTimer = sveltify< - GetProps & { - children: React.ReactNode; - }, + StatisticTimer, ['prefix', 'suffix', 'title'] >(({ children, value, slots, ...props }) => { return ( diff --git a/frontend/antd/steps/Index.svelte b/frontend/antd/steps/Index.svelte index d38bfde4..05540f83 100644 --- a/frontend/antd/steps/Index.svelte +++ b/frontend/antd/steps/Index.svelte @@ -1,79 +1,61 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSteps then Steps} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/steps/item/Index.svelte b/frontend/antd/steps/item/Index.svelte index 04723552..646ff4af 100644 --- a/frontend/antd/steps/item/Index.svelte +++ b/frontend/antd/steps/item/Index.svelte @@ -1,81 +1,63 @@ - - -{#await AwaitedStepsItem then StepsItem} - - {#if $mergedProps.visible} - - {/if} - -{/await} +{#if proceedProps.visible} + {#await AwaitedStepsItem then StepsItem} + + {@render children()} + + {/await} +{/if} diff --git a/frontend/antd/steps/steps.tsx b/frontend/antd/steps/steps.tsx index 0f96be8a..7ed04bad 100644 --- a/frontend/antd/steps/steps.tsx +++ b/frontend/antd/steps/steps.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderItems } from '@utils/renderItems'; @@ -10,13 +9,13 @@ import { useItems, withItemsContextProvider } from './context'; export const Steps = sveltify< GetProps & { - setSlotParams: SetSlotParams; + children?: React.ReactNode; }, ['progressDot'] >( withItemsContextProvider( ['items', 'default'], - ({ slots, items, setSlotParams, children, progressDot, ...props }) => { + ({ slots, items, children, progressDot, ...props }) => { const { items: slotItems } = useItems<['items', 'default']>(); const resolvedSlotItems = slotItems.items.length > 0 ? slotItems.items : slotItems.default; @@ -37,7 +36,7 @@ export const Steps = sveltify< progressDot={ slots.progressDot ? renderParamsSlot( - { slots, setSlotParams, key: 'progressDot' }, + { slots, key: 'progressDot' }, { clone: true } ) : progressDotFunction || progressDot diff --git a/frontend/antd/switch/Index.svelte b/frontend/antd/switch/Index.svelte index 776e2160..e48cb582 100644 --- a/frontend/antd/switch/Index.svelte +++ b/frontend/antd/switch/Index.svelte @@ -1,78 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSwitch then Switch} { - value = v; + updateProps({ + value: v, + }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/table/Index.svelte b/frontend/antd/table/Index.svelte index a942d39b..ccb39198 100644 --- a/frontend/antd/table/Index.svelte +++ b/frontend/antd/table/Index.svelte @@ -1,73 +1,59 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTable then Table} - + {@render children()}
{/await} {/if} - - diff --git a/frontend/antd/table/column-group/Index.svelte b/frontend/antd/table/column-group/Index.svelte index a0c71dd3..58dda65d 100644 --- a/frontend/antd/table/column-group/Index.svelte +++ b/frontend/antd/table/column-group/Index.svelte @@ -1,90 +1,66 @@ - - -{#await AwaitedTableColumnGroup then TableColumnGroup} - - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} - + {/await} diff --git a/frontend/antd/table/column/Index.svelte b/frontend/antd/table/column/Index.svelte index d1864e2c..8c0c5f0e 100644 --- a/frontend/antd/table/column/Index.svelte +++ b/frontend/antd/table/column/Index.svelte @@ -1,186 +1,201 @@ - - {#await AwaitedTableColumn then TableColumn} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/table/column/table.column.tsx b/frontend/antd/table/column/table.column.tsx index 8429fe16..3bbf30da 100644 --- a/frontend/antd/table/column/table.column.tsx +++ b/frontend/antd/table/column/table.column.tsx @@ -1,11 +1,10 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { createFunction } from '@utils/createFunction'; import { renderItems } from '@utils/renderItems'; import { renderParamsSlot } from '@utils/renderParamsSlot'; import { renderSlot } from '@utils/renderSlot'; -import { type TableColumnProps } from 'antd'; +import { type TableColumnProps as ATableColumnProps } from 'antd'; import { useItems as useMenuItems, @@ -13,16 +12,15 @@ import { } from '../../menu/context'; import { ColumnItemHandler, type ItemHandlerProps } from '../context'; -export const TableColumn = sveltify< - TableColumnProps & - ItemHandlerProps & { - setSlotParams: SetSlotParams; - itemSlots: Record; - } ->( +export type TableColumnProps = ATableColumnProps & + ItemHandlerProps & { + itemSlots: Record; + }; + +export const TableColumn = sveltify( withMenuItemsContextProvider( ['filterDropdownProps.menu.items'], - ({ setSlotParams, itemSlots: slots, ...props }) => { + ({ itemSlots: slots, ...props }) => { const { items: { 'filterDropdownProps.menu.items': dropdownMenuItems }, } = useMenuItems<['filterDropdownProps.menu.items']>(); @@ -42,7 +40,6 @@ export const TableColumn = sveltify< expandIcon: renderParamsSlot( { - setSlotParams, slots: slots, key: 'filterDropdownProps.menu.expandIcon', }, @@ -61,7 +58,6 @@ export const TableColumn = sveltify< dropdownRender: slots['filterDropdownProps.dropdownRender'] ? renderParamsSlot( { - setSlotParams, slots: slots, key: 'filterDropdownProps.dropdownRender', }, @@ -73,7 +69,6 @@ export const TableColumn = sveltify< popupRender: slots['filterDropdownProps.popupRender'] ? renderParamsSlot( { - setSlotParams, slots: slots, key: 'filterDropdownProps.popupRender', }, diff --git a/frontend/antd/table/expandable/Index.svelte b/frontend/antd/table/expandable/Index.svelte index d7469d29..778b7c9b 100644 --- a/frontend/antd/table/expandable/Index.svelte +++ b/frontend/antd/table/expandable/Index.svelte @@ -1,120 +1,122 @@ - - -{#await AwaitedTableExpandable then TableExpandable} - - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} - + {/await} diff --git a/frontend/antd/table/row-selection/Index.svelte b/frontend/antd/table/row-selection/Index.svelte index 3b46e8ac..58a79030 100644 --- a/frontend/antd/table/row-selection/Index.svelte +++ b/frontend/antd/table/row-selection/Index.svelte @@ -1,127 +1,114 @@ - - -{#await AwaitedTableRowSelection then TableRowSelection} - - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} - + {/await} diff --git a/frontend/antd/table/row-selection/selection/Index.svelte b/frontend/antd/table/row-selection/selection/Index.svelte index aeafd99e..07a0a111 100644 --- a/frontend/antd/table/row-selection/selection/Index.svelte +++ b/frontend/antd/table/row-selection/selection/Index.svelte @@ -1,94 +1,77 @@ - - -{#await AwaitedTableRowSelectionSelection then TableRowSelectionSelection} - - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} - + {/await} diff --git a/frontend/antd/table/table.tsx b/frontend/antd/table/table.tsx index d1037bdc..60003301 100644 --- a/frontend/antd/table/table.tsx +++ b/frontend/antd/table/table.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { createFunction } from '@utils/createFunction'; import { useFunction } from '@utils/hooks/useFunction'; @@ -28,7 +27,6 @@ function getConfig(value: T): Partial> { type TableProps = GetProps; export const Table = sveltify< TableProps & { - setSlotParams: SetSlotParams; }, [ 'footer', @@ -65,7 +63,6 @@ export const Table = sveltify< onRow, onHeaderRow, components, - setSlotParams, ...props }) => { const { @@ -172,7 +169,7 @@ export const Table = sveltify< onHeaderRow={onHeaderRowFunction} summary={ slots.summary - ? renderParamsSlot({ slots, setSlotParams, key: 'summary' }) + ? renderParamsSlot({ slots, key: 'summary' }) : summaryFunction } rowSelection={useMemo(() => { @@ -236,7 +233,6 @@ export const Table = sveltify< itemRender: slots['pagination.itemRender'] ? renderParamsSlot({ slots, - setSlotParams, key: 'pagination.itemRender', }) : paginationConfig.itemRender, @@ -263,12 +259,12 @@ export const Table = sveltify< } footer={ slots.footer - ? renderParamsSlot({ slots, setSlotParams, key: 'footer' }) + ? renderParamsSlot({ slots, key: 'footer' }) : footerFunction } title={ slots.title - ? renderParamsSlot({ slots, setSlotParams, key: 'title' }) + ? renderParamsSlot({ slots, key: 'title' }) : props.title } /> diff --git a/frontend/antd/tabs/Index.svelte b/frontend/antd/tabs/Index.svelte index 4eb78584..6820b639 100644 --- a/frontend/antd/tabs/Index.svelte +++ b/frontend/antd/tabs/Index.svelte @@ -1,81 +1,67 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTabs then Tabs} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/tabs/item/Index.svelte b/frontend/antd/tabs/item/Index.svelte index b80b1427..d06673cd 100644 --- a/frontend/antd/tabs/item/Index.svelte +++ b/frontend/antd/tabs/item/Index.svelte @@ -1,93 +1,76 @@ - - + +{#await AwaitedTabsItem then TabsItem} + - -{#await AwaitedTabsItem then TabsItem} - - {#if $mergedProps.visible} - - + {#if proceedProps.visible} + + {@render children()} {/if} diff --git a/frontend/antd/tabs/tabs.tsx b/frontend/antd/tabs/tabs.tsx index 92ca3183..37067933 100644 --- a/frontend/antd/tabs/tabs.tsx +++ b/frontend/antd/tabs/tabs.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; @@ -12,7 +11,6 @@ import { useItems, withItemsContextProvider } from './context'; export const Tabs = sveltify< GetProps & { - setSlotParams: SetSlotParams; }, [ 'addIcon', @@ -34,7 +32,6 @@ export const Tabs = sveltify< more, children, renderTabBar, - setSlotParams, ...props }) => { const indicatorSizeFunction = useFunction(indicator?.size); @@ -62,7 +59,6 @@ export const Tabs = sveltify< slots.renderTabBar ? renderParamsSlot({ slots, - setSlotParams, key: 'renderTabBar', }) : renderTabBarFunction diff --git a/frontend/antd/tag/Index.svelte b/frontend/antd/tag/Index.svelte index 868f17fb..8b04bad9 100644 --- a/frontend/antd/tag/Index.svelte +++ b/frontend/antd/tag/Index.svelte @@ -1,80 +1,65 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTag then Tag} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/tag/checkable-tag/Index.svelte b/frontend/antd/tag/checkable-tag/Index.svelte index 847e2111..31fad660 100644 --- a/frontend/antd/tag/checkable-tag/Index.svelte +++ b/frontend/antd/tag/checkable-tag/Index.svelte @@ -1,89 +1,70 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedCheckableTag then CheckableTag} { - value = checked; + updateProps({ value: checked }); }} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/time-picker/Index.svelte b/frontend/antd/time-picker/Index.svelte index d0e20338..d9a2f192 100644 --- a/frontend/antd/time-picker/Index.svelte +++ b/frontend/antd/time-picker/Index.svelte @@ -1,87 +1,80 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTimePicker then TimePicker} { - value = val; + style={proceedProps.elem_style} + className={cls(proceedProps.elem_classes, 'ms-gr-antd-time-picker')} + id={proceedProps.elem_id} + {...proceedProps.restProps} + {...proceedProps.additionalProps} + slots={slots.value} + value={proceedProps.additionalProps.value ?? proceedProps.value} + onValueChange={(v) => { + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/time-picker/range-picker/Index.svelte b/frontend/antd/time-picker/range-picker/Index.svelte index 46e0cbf4..26a9a985 100644 --- a/frontend/antd/time-picker/range-picker/Index.svelte +++ b/frontend/antd/time-picker/range-picker/Index.svelte @@ -1,90 +1,79 @@ - - -{#if $mergedProps.visible} - {#await AwaitedTimePickerRangePicker then TimeRangePicker} +{#if proceedProps.visible} + {#await AwaitedTimeRangePicker then TimeRangePicker} { - value = val; + updateProps({ value: val }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} diff --git a/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx b/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx index ed952a15..bae15003 100644 --- a/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx +++ b/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -36,7 +35,6 @@ export const TimeRangePicker = sveltify< ...args: any[] ) => void; onValueChange: (dates: [number | null, number | null]) => void; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -69,7 +67,6 @@ export const TimeRangePicker = sveltify< onPanelChange, onCalendarChange, children, - setSlotParams, elRef, ...props }) => { @@ -126,12 +123,12 @@ export const TimeRangePicker = sveltify< getPopupContainer={getPopupContainerFunction} cellRender={ slots.cellRender - ? renderParamsSlot({ slots, setSlotParams, key: 'cellRender' }) + ? renderParamsSlot({ slots, key: 'cellRender' }) : cellRenderFunction } panelRender={ slots.panelRender - ? renderParamsSlot({ slots, setSlotParams, key: 'panelRender' }) + ? renderParamsSlot({ slots, key: 'panelRender' }) : panelRenderFunction } onPanelChange={(dates, ...args) => { diff --git a/frontend/antd/time-picker/time-picker.tsx b/frontend/antd/time-picker/time-picker.tsx index 39f78f1d..a7e8b7e4 100644 --- a/frontend/antd/time-picker/time-picker.tsx +++ b/frontend/antd/time-picker/time-picker.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -21,7 +20,9 @@ function formatDayjs(date: any): dayjs.Dayjs { return dayjs(date); } -function formatDate(dates: (dayjs.Dayjs | null | undefined)[] | dayjs.Dayjs) { +function formatDate( + dates: (dayjs.Dayjs | null | undefined)[] | dayjs.Dayjs | null +) { if (Array.isArray(dates)) { return dates.map((date) => { return date ? date.valueOf() / 1000 : null; @@ -45,7 +46,6 @@ export const TimePicker = sveltify< ...args: any[] ) => void; onValueChange: (date: number | string) => void; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -77,7 +77,6 @@ export const TimePicker = sveltify< onPanelChange, onCalendarChange, children, - setSlotParams, elRef, ...props }) => { @@ -121,12 +120,12 @@ export const TimePicker = sveltify< getPopupContainer={getPopupContainerFunction} cellRender={ slots.cellRender - ? renderParamsSlot({ slots, setSlotParams, key: 'cellRender' }) + ? renderParamsSlot({ slots, key: 'cellRender' }) : cellRenderFunction } panelRender={ slots.panelRender - ? renderParamsSlot({ slots, setSlotParams, key: 'panelRender' }) + ? renderParamsSlot({ slots, key: 'panelRender' }) : panelRenderFunction } onPanelChange={(date, ...args) => { diff --git a/frontend/antd/timeline/Index.svelte b/frontend/antd/timeline/Index.svelte index 7b2b3299..660cd8d4 100644 --- a/frontend/antd/timeline/Index.svelte +++ b/frontend/antd/timeline/Index.svelte @@ -1,72 +1,58 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTimeline then Timeline} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/timeline/item/Index.svelte b/frontend/antd/timeline/item/Index.svelte index 14e0bfe7..05c0e250 100644 --- a/frontend/antd/timeline/item/Index.svelte +++ b/frontend/antd/timeline/item/Index.svelte @@ -1,85 +1,69 @@ - - {#await AwaitedTimelineItem then TimelineItem} - {#if $mergedProps.visible} - - + {#if proceedProps.visible} + + {@render children()} {/if} diff --git a/frontend/antd/tooltip/Index.svelte b/frontend/antd/tooltip/Index.svelte index cde36b81..a84b2e0e 100644 --- a/frontend/antd/tooltip/Index.svelte +++ b/frontend/antd/tooltip/Index.svelte @@ -1,73 +1,68 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTooltip then Tooltip} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/tour/Index.svelte b/frontend/antd/tour/Index.svelte index e37de287..bde4506f 100644 --- a/frontend/antd/tour/Index.svelte +++ b/frontend/antd/tour/Index.svelte @@ -1,76 +1,58 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTour then Tour} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/tour/step/Index.svelte b/frontend/antd/tour/step/Index.svelte index 1a1e83de..2d2268e9 100644 --- a/frontend/antd/tour/step/Index.svelte +++ b/frontend/antd/tour/step/Index.svelte @@ -1,96 +1,80 @@ - - {#await AwaitedTourStep then TourStep} - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} {/await} diff --git a/frontend/antd/tour/tour.tsx b/frontend/antd/tour/tour.tsx index c5b17ef6..bf5db7cc 100644 --- a/frontend/antd/tour/tour.tsx +++ b/frontend/antd/tour/tour.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { renderItems } from '@utils/renderItems'; @@ -12,7 +11,6 @@ import { useItems, withItemsContextProvider } from './context'; export const Tour = sveltify< GetProps & { children?: React.ReactNode; - setSlotParams: SetSlotParams; }, ['closeIcon', 'indicatorsRender', 'actionsRender'] >( @@ -25,7 +23,6 @@ export const Tour = sveltify< onChange, onClose, getPopupContainer, - setSlotParams, indicatorsRender, actionsRender, ...props @@ -63,7 +60,6 @@ export const Tour = sveltify< slots.actionsRender ? renderParamsSlot({ slots, - setSlotParams, key: 'actionsRender', }) : actionsRenderFunction @@ -72,7 +68,6 @@ export const Tour = sveltify< slots.indicatorsRender ? renderParamsSlot({ slots, - setSlotParams, key: 'indicatorsRender', }) : indicatorsRenderFunction diff --git a/frontend/antd/transfer/Index.svelte b/frontend/antd/transfer/Index.svelte index 3887b7a7..42698c9a 100644 --- a/frontend/antd/transfer/Index.svelte +++ b/frontend/antd/transfer/Index.svelte @@ -1,91 +1,80 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTransfer then Transfer} { - value = v; + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/transfer/transfer.tsx b/frontend/antd/transfer/transfer.tsx index ba4cd1a9..b55eabc4 100644 --- a/frontend/antd/transfer/transfer.tsx +++ b/frontend/antd/transfer/transfer.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useTargets } from '@utils/hooks/useTargets'; @@ -11,7 +10,6 @@ export const Transfer = sveltify< GetProps & { children?: React.ReactNode; onValueChange: (value: (string | number)[]) => void; - setSlotParams: SetSlotParams; }, [ 'selectionsIcon', @@ -32,7 +30,6 @@ export const Transfer = sveltify< locale, onChange, onValueChange, - setSlotParams, ...props }) => { const titles = useTargets(children, 'titles'); @@ -69,7 +66,7 @@ export const Transfer = sveltify< } render={ slots.render - ? renderParamsSlot({ slots, setSlotParams, key: 'render' }) + ? renderParamsSlot({ slots, key: 'render' }) : renderFunction || ((item) => ({ label: item.title || item.label, @@ -79,7 +76,7 @@ export const Transfer = sveltify< filterOption={filterOptionFunction} footer={ slots.footer - ? renderParamsSlot({ slots, setSlotParams, key: 'footer' }) + ? renderParamsSlot({ slots, key: 'footer' }) : footerFunction || footer } titles={ diff --git a/frontend/antd/tree-select/Index.svelte b/frontend/antd/tree-select/Index.svelte index a011d474..9962a528 100644 --- a/frontend/antd/tree-select/Index.svelte +++ b/frontend/antd/tree-select/Index.svelte @@ -1,90 +1,85 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTreeSelect then TreeSelect} { - value = val; + style={proceedProps.elem_style} + className={cls(proceedProps.elem_classes, 'ms-gr-antd-tree-select')} + id={proceedProps.elem_id} + {...proceedProps.restProps} + {...proceedProps.additionalProps} + slots={slots.value} + onValueChange={(v) => { + updateProps({ + value: v, + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/tree-select/tree-node/Index.svelte b/frontend/antd/tree-select/tree-node/Index.svelte index c4e5699a..1e889875 100644 --- a/frontend/antd/tree-select/tree-node/Index.svelte +++ b/frontend/antd/tree-select/tree-node/Index.svelte @@ -1,103 +1,78 @@ - - -{#if $mergedProps.visible} - {#await AwaitedTreeSelectTreeNode then TreeSelectTreeNode} - - - + {@render children()} + {/await} {/if} diff --git a/frontend/antd/tree-select/tree-select.tsx b/frontend/antd/tree-select/tree-select.tsx index 4ca01312..f8aa25d2 100644 --- a/frontend/antd/tree-select/tree-select.tsx +++ b/frontend/antd/tree-select/tree-select.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; @@ -16,7 +15,6 @@ export const TreeSelect = sveltify< TreeSelectProps & { onValueChange: (options: string | string[]) => void; onLoadData?: (...args: any[]) => Promise; - setSlotParams: SetSlotParams; }, [ 'allowClear.clearIcon', @@ -47,7 +45,6 @@ export const TreeSelect = sveltify< children, maxTagPlaceholder, elRef, - setSlotParams, onLoadData, ...props }) => { @@ -87,10 +84,10 @@ export const TreeSelect = sveltify< } ), dropdownRender: slots.dropdownRender - ? renderParamsSlot({ slots, setSlotParams, key: 'dropdownRender' }) + ? renderParamsSlot({ slots, key: 'dropdownRender' }) : dropdownRenderFunction, popupRender: slots.popupRender - ? renderParamsSlot({ slots, setSlotParams, key: 'popupRender' }) + ? renderParamsSlot({ slots, key: 'popupRender' }) : popupRenderFunction, allowClear: slots['allowClear.clearIcon'] ? { @@ -108,20 +105,19 @@ export const TreeSelect = sveltify< props.prefix ), switcherIcon: slots.switcherIcon - ? renderParamsSlot({ slots, setSlotParams, key: 'switcherIcon' }) + ? renderParamsSlot({ slots, key: 'switcherIcon' }) : props.switcherIcon, getPopupContainer: getPopupContainerFunction, tagRender: slots.tagRender - ? renderParamsSlot({ slots, setSlotParams, key: 'tagRender' }) + ? renderParamsSlot({ slots, key: 'tagRender' }) : tagRenderFunction, treeTitleRender: slots.treeTitleRender - ? renderParamsSlot({ slots, setSlotParams, key: 'treeTitleRender' }) + ? renderParamsSlot({ slots, key: 'treeTitleRender' }) : treeTitleRenderFunction, filterTreeNode: filterTreeNodeFunction || filterTreeNode, maxTagPlaceholder: slots.maxTagPlaceholder ? renderParamsSlot({ slots, - setSlotParams, key: 'maxTagPlaceholder', }) : maxTagPlaceholder, @@ -140,7 +136,6 @@ export const TreeSelect = sveltify< maxTagPlaceholder, onLoadData, props, - setSlotParams, resolvedSlotItems, slots, tagRenderFunction, diff --git a/frontend/antd/tree/Index.svelte b/frontend/antd/tree/Index.svelte index 717b1e47..763fdab4 100644 --- a/frontend/antd/tree/Index.svelte +++ b/frontend/antd/tree/Index.svelte @@ -1,84 +1,78 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTree then Tree} - + {@render children()} {/await} {/if} diff --git a/frontend/antd/tree/directory-tree/Index.svelte b/frontend/antd/tree/directory-tree/Index.svelte index 25a233f3..c74d04f2 100644 --- a/frontend/antd/tree/directory-tree/Index.svelte +++ b/frontend/antd/tree/directory-tree/Index.svelte @@ -1,88 +1,81 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedDirectoryTree then DirectoryTree} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/tree/tree-node/Index.svelte b/frontend/antd/tree/tree-node/Index.svelte index 3a486a04..b4245c2d 100644 --- a/frontend/antd/tree/tree-node/Index.svelte +++ b/frontend/antd/tree/tree-node/Index.svelte @@ -1,97 +1,73 @@ - - + +{#await AwaitedTreeNode then TreeNode} + - -{#await AwaitedTreeTreeNode then TreeTreeNode} - - {#if $mergedProps.visible} - + {#if proceedProps.visible} + {@render children()} {/if} - + {/await} diff --git a/frontend/antd/tree/tree.tsx b/frontend/antd/tree/tree.tsx index 18218f34..7f49dcd7 100644 --- a/frontend/antd/tree/tree.tsx +++ b/frontend/antd/tree/tree.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; @@ -15,7 +14,6 @@ type TreeProps = GetProps; export const Tree = sveltify< TreeProps & { directory?: boolean; - setSlotParams: SetSlotParams; onLoadData?: (...args: any[]) => Promise; }, [ @@ -40,7 +38,6 @@ export const Tree = sveltify< onExpand, children, directory, - setSlotParams, onLoadData, titleRender, ...props @@ -84,13 +81,12 @@ export const Tree = sveltify< ? { showLeafIcon: renderParamsSlot({ slots, - setSlotParams, key: 'showLine.showLeafIcon', }), } : props.showLine, icon: slots.icon - ? renderParamsSlot({ slots, setSlotParams, key: 'icon' }) + ? renderParamsSlot({ slots, key: 'icon' }) : props.icon, switcherLoadingIcon: slots.switcherLoadingIcon ? ( @@ -98,10 +94,10 @@ export const Tree = sveltify< props.switcherLoadingIcon ), switcherIcon: slots.switcherIcon - ? renderParamsSlot({ slots, setSlotParams, key: 'switcherIcon' }) + ? renderParamsSlot({ slots, key: 'switcherIcon' }) : props.switcherIcon, titleRender: slots.titleRender - ? renderParamsSlot({ slots, setSlotParams, key: 'titleRender' }) + ? renderParamsSlot({ slots, key: 'titleRender' }) : titleRenderFunction, draggable: slots['draggable.icon'] || draggableNodeDraggableFunction @@ -122,7 +118,6 @@ export const Tree = sveltify< treeData, resolvedSlotItems, slots, - setSlotParams, draggableNodeDraggableFunction, draggable, titleRenderFunction, diff --git a/frontend/antd/typography/Base.svelte b/frontend/antd/typography/Base.svelte index f8e06df2..4ae564db 100644 --- a/frontend/antd/typography/Base.svelte +++ b/frontend/antd/typography/Base.svelte @@ -1,98 +1,86 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedTypographyBase then TypographyBase} - {#if $mergedProps._internal.layout} - + {#if proceedProps._internal.layout} + {@render children()} {:else} - {$mergedProps.value} + {proceedProps.value} {/if} {/await} {/if} - - diff --git a/frontend/antd/typography/link/Index.svelte b/frontend/antd/typography/link/Index.svelte index aa30731f..76b81ad1 100644 --- a/frontend/antd/typography/link/Index.svelte +++ b/frontend/antd/typography/link/Index.svelte @@ -1,12 +1,10 @@ - - - - - + + {@render children?.()} + diff --git a/frontend/antd/typography/paragraph/Index.svelte b/frontend/antd/typography/paragraph/Index.svelte index ea4edc6e..00a4ecca 100644 --- a/frontend/antd/typography/paragraph/Index.svelte +++ b/frontend/antd/typography/paragraph/Index.svelte @@ -1,12 +1,10 @@ - - - - - + + {@render children?.()} + diff --git a/frontend/antd/typography/text/Index.svelte b/frontend/antd/typography/text/Index.svelte index 3877ea92..8b10e766 100644 --- a/frontend/antd/typography/text/Index.svelte +++ b/frontend/antd/typography/text/Index.svelte @@ -1,12 +1,10 @@ - - - - - + + {@render children?.()} + diff --git a/frontend/antd/typography/title/Index.svelte b/frontend/antd/typography/title/Index.svelte index c5f2f89c..fc54916e 100644 --- a/frontend/antd/typography/title/Index.svelte +++ b/frontend/antd/typography/title/Index.svelte @@ -1,12 +1,10 @@ - - - - - + + {@render children?.()} + diff --git a/frontend/antd/typography/typography.base.tsx b/frontend/antd/typography/typography.base.tsx index 0188f423..f501f176 100644 --- a/frontend/antd/typography/typography.base.tsx +++ b/frontend/antd/typography/typography.base.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { useSlotsChildren } from '@utils/hooks/useSlotsChildren'; import { useTargets } from '@utils/hooks/useTargets'; @@ -23,7 +22,6 @@ export const TypographyBase = sveltify< GetProps & GetProps & { component: 'title' | 'paragraph' | 'text' | 'link'; - setSlotParams: SetSlotParams; value?: string; }, [ @@ -47,7 +45,6 @@ export const TypographyBase = sveltify< copyable, editable, ellipsis, - setSlotParams, value, ...props }) => { @@ -141,7 +138,6 @@ export const TypographyBase = sveltify< ? renderParamsSlot( { key: 'ellipsis.symbol', - setSlotParams, slots, }, { clone: true } diff --git a/frontend/antd/upload/Index.svelte b/frontend/antd/upload/Index.svelte index 2613108f..0a8d70c5 100644 --- a/frontend/antd/upload/Index.svelte +++ b/frontend/antd/upload/Index.svelte @@ -1,88 +1,85 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedUpload then Upload} { - value = v; + updateProps({ + value: v, + }); }} upload={async (files) => { return ( - (await gradio.client.upload(await prepare_files(files), root)) || [] + (await proceedProps.gradio.shared.client.upload( + await prepare_files(files), + proceedProps.gradio.shared.root + )) || [] ).map((file, i) => { if (!file) { return file; @@ -93,12 +90,8 @@ }; }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/upload/dragger/Index.svelte b/frontend/antd/upload/dragger/Index.svelte index 0c75d548..83f2e0f1 100644 --- a/frontend/antd/upload/dragger/Index.svelte +++ b/frontend/antd/upload/dragger/Index.svelte @@ -1,94 +1,99 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedUploadDragger then UploadDragger} { - value = v; + updateProps({ + value: v, + }); }} upload={async (files) => { return ( - (await gradio.client.upload(await prepare_files(files), root)) || [] - ); + (await proceedProps.gradio.shared.client.upload( + await prepare_files(files), + proceedProps.gradio.shared.root + )) || [] + ).map((file, i) => { + if (!file) { + return file; + } + return { + ...file, + uid: files[i].uid, + }; + }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antd/upload/dragger/upload.dragger.tsx b/frontend/antd/upload/dragger/upload.dragger.tsx index 2395e3d9..7517f2df 100644 --- a/frontend/antd/upload/dragger/upload.dragger.tsx +++ b/frontend/antd/upload/dragger/upload.dragger.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useEffect, useMemo, useState } from 'react'; import type { FileData } from '@gradio/client'; import { useFunction } from '@utils/hooks/useFunction'; @@ -24,7 +23,6 @@ export const UploadDragger = sveltify< onChange?: (value: string[]) => void; upload: (files: RcFile[]) => Promise<(FileData | null)[]>; fileList: FileData[]; - setSlotParams: SetSlotParams; }, [ 'showUploadList.extra', @@ -51,7 +49,6 @@ export const UploadDragger = sveltify< onValueChange, onRemove, fileList: fileListProp, - setSlotParams, maxCount, ...props }) => { @@ -124,12 +121,12 @@ export const UploadDragger = sveltify< isImageUrl={isImageUrlFunction} itemRender={ slots.itemRender - ? renderParamsSlot({ slots, setSlotParams, key: 'itemRender' }) + ? renderParamsSlot({ slots, key: 'itemRender' }) : itemRenderFunction } iconRender={ slots.iconRender - ? renderParamsSlot({ slots, setSlotParams, key: 'iconRender' }) + ? renderParamsSlot({ slots, key: 'iconRender' }) : iconRenderFunction } // onRemove={(file) => { @@ -251,28 +248,24 @@ export const UploadDragger = sveltify< downloadIcon: slots['showUploadList.downloadIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.downloadIcon', }) : showUploadListConfig.downloadIcon, removeIcon: slots['showUploadList.removeIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.removeIcon', }) : showUploadListConfig.removeIcon, previewIcon: slots['showUploadList.previewIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.previewIcon', }) : showUploadListConfig.previewIcon, extra: slots['showUploadList.extra'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.extra', }) : showUploadListConfig.extra, diff --git a/frontend/antd/upload/upload.tsx b/frontend/antd/upload/upload.tsx index 1c6c1123..f8bec374 100644 --- a/frontend/antd/upload/upload.tsx +++ b/frontend/antd/upload/upload.tsx @@ -1,5 +1,4 @@ import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useEffect, useMemo, useState } from 'react'; import type { FileData } from '@gradio/client'; import { useFunction } from '@utils/hooks/useFunction'; @@ -25,7 +24,6 @@ export const Upload = sveltify< onChange?: (value: string[]) => void; upload: (files: RcFile[]) => Promise<(FileData | null)[]>; fileList: FileData[]; - setSlotParams: SetSlotParams; }, [ 'showUploadList.extra', @@ -53,7 +51,6 @@ export const Upload = sveltify< onRemove, maxCount, fileList: fileListProp, - setSlotParams, ...props }) => { const supportShowUploadListConfig = @@ -127,12 +124,12 @@ export const Upload = sveltify< maxCount={maxCount} itemRender={ slots.itemRender - ? renderParamsSlot({ slots, setSlotParams, key: 'itemRender' }) + ? renderParamsSlot({ slots, key: 'itemRender' }) : itemRenderFunction } iconRender={ slots.iconRender - ? renderParamsSlot({ slots, setSlotParams, key: 'iconRender' }) + ? renderParamsSlot({ slots, key: 'iconRender' }) : iconRenderFunction } // onRemove={(file) => { @@ -252,28 +249,24 @@ export const Upload = sveltify< downloadIcon: slots['showUploadList.downloadIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.downloadIcon', }) : showUploadListConfig.downloadIcon, removeIcon: slots['showUploadList.removeIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.removeIcon', }) : showUploadListConfig.removeIcon, previewIcon: slots['showUploadList.previewIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.previewIcon', }) : showUploadListConfig.previewIcon, extra: slots['showUploadList.extra'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.extra', }) : showUploadListConfig.extra, diff --git a/frontend/antd/watermark/Index.svelte b/frontend/antd/watermark/Index.svelte index eb78d15d..6c5b7485 100644 --- a/frontend/antd/watermark/Index.svelte +++ b/frontend/antd/watermark/Index.svelte @@ -1,76 +1,63 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedWatermark then Watermark} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antdx/actions/Index.svelte b/frontend/antdx/actions/Index.svelte index ec9e7ede..ee9bf7a6 100644 --- a/frontend/antdx/actions/Index.svelte +++ b/frontend/antdx/actions/Index.svelte @@ -1,70 +1,61 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedActions then Actions} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/actions/item/Index.svelte b/frontend/antdx/actions/item/Index.svelte index 56f1b184..9245d4f8 100644 --- a/frontend/antdx/actions/item/Index.svelte +++ b/frontend/antdx/actions/item/Index.svelte @@ -1,87 +1,64 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedActionsItem then ActionsItem} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/attachments/Index.svelte b/frontend/antdx/attachments/Index.svelte index 34104f44..edcc2bae 100644 --- a/frontend/antdx/attachments/Index.svelte +++ b/frontend/antdx/attachments/Index.svelte @@ -1,88 +1,82 @@ - - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedAttachments then Attachments} { - value = v; + updateProps({ + value: v, + }); }} upload={async (files) => { return ( - (await gradio.client.upload(await prepare_files(files), root)) || [] + (await proceedProps.additionalProps.gradio.client.upload( + await prepare_files(files), + proceedProps.root + )) || [] ).map((file, i) => { if (!file) { return file; @@ -93,12 +87,8 @@ }; }); }} - {setSlotParams} > - + {@render children()} {/await} {/if} - - diff --git a/frontend/antdx/attachments/attachments.tsx b/frontend/antdx/attachments/attachments.tsx index df4db24b..520bff9e 100644 --- a/frontend/antdx/attachments/attachments.tsx +++ b/frontend/antdx/attachments/attachments.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useEffect, useMemo, useState } from 'react'; import { Attachments as XAttachments, @@ -34,7 +33,6 @@ export const Attachments = sveltify< onChange?: (value: string[]) => void; upload: (files: RcFile[]) => Promise<(FileData | null)[]>; items: FileData[]; - setSlotParams: SetSlotParams; }, [ 'showUploadList.extra', @@ -70,7 +68,6 @@ export const Attachments = sveltify< onValueChange, onRemove, items, - setSlotParams, placeholder, getDropContainer, children, @@ -181,14 +178,12 @@ export const Attachments = sveltify< toolbarRender: slots['imageProps.preview.toolbarRender'] ? renderParamsSlot({ slots, - setSlotParams, key: 'imageProps.preview.toolbarRender', }) : previewToolbarRenderFunction, imageRender: slots['imageProps.preview.imageRender'] ? renderParamsSlot({ slots, - setSlotParams, key: 'imageProps.preview.imageRender', }) : previewImageRenderFunction, @@ -219,7 +214,7 @@ export const Attachments = sveltify< getDropContainer={getDropContainerFunction} placeholder={ slots.placeholder - ? renderParamsSlot({ slots, setSlotParams, key: 'placeholder' }) + ? renderParamsSlot({ slots, key: 'placeholder' }) : supportPlaceholderConfig ? (...args) => { return { @@ -227,21 +222,18 @@ export const Attachments = sveltify< icon: slots['placeholder.icon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'placeholder.icon', })?.(...args) : placeholderConfig.icon, title: slots['placeholder.title'] ? renderParamsSlot({ slots, - setSlotParams, key: 'placeholder.title', })?.(...args) : placeholderConfig.title, description: slots['placeholder.description'] ? renderParamsSlot({ slots, - setSlotParams, key: 'placeholder.description', })?.(...args) : placeholderConfig.description, @@ -255,12 +247,12 @@ export const Attachments = sveltify< isImageUrl={isImageUrlFunction} itemRender={ slots.itemRender - ? renderParamsSlot({ slots, setSlotParams, key: 'itemRender' }) + ? renderParamsSlot({ slots, key: 'itemRender' }) : itemRenderFunction } iconRender={ slots.iconRender - ? renderParamsSlot({ slots, setSlotParams, key: 'iconRender' }) + ? renderParamsSlot({ slots, key: 'iconRender' }) : iconRenderFunction } maxCount={maxCount} @@ -380,28 +372,24 @@ export const Attachments = sveltify< downloadIcon: slots['showUploadList.downloadIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.downloadIcon', }) : showUploadListConfig.downloadIcon, removeIcon: slots['showUploadList.removeIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.removeIcon', }) : showUploadListConfig.removeIcon, previewIcon: slots['showUploadList.previewIcon'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.previewIcon', }) : showUploadListConfig.previewIcon, extra: slots['showUploadList.extra'] ? renderParamsSlot({ slots, - setSlotParams, key: 'showUploadList.extra', }) : showUploadListConfig.extra, diff --git a/frontend/antdx/attachments/file-card/Index.svelte b/frontend/antdx/attachments/file-card/Index.svelte index 0f072ab1..f42fe8f1 100644 --- a/frontend/antdx/attachments/file-card/Index.svelte +++ b/frontend/antdx/attachments/file-card/Index.svelte @@ -1,84 +1,69 @@ - - -{#if $mergedProps.visible} - {#await AwaitedAttachmentsFileCard then AttachmentsFileCard} - - - + {@render children()} + {/await} {/if} diff --git a/frontend/antdx/attachments/file-card/attachments.file-card.tsx b/frontend/antdx/attachments/file-card/attachments.file-card.tsx index e5afa407..266e0ef6 100644 --- a/frontend/antdx/attachments/file-card/attachments.file-card.tsx +++ b/frontend/antdx/attachments/file-card/attachments.file-card.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import { useFunction } from '@utils/hooks/useFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -15,7 +14,6 @@ function getConfig(value: T): Partial> { } export const AttachmentsFileCard = sveltify< FileCardProps & { - setSlotParams: SetSlotParams; children?: React.ReactNode; }, [ @@ -26,7 +24,7 @@ export const AttachmentsFileCard = sveltify< 'imageProps.preview.imageRender', 'icon', ] ->(({ setSlotParams, imageProps, slots, children, ...props }) => { +>(({ imageProps, slots, children, ...props }) => { const previewConfig = getConfig(imageProps?.preview); const supportPreview = slots['imageProps.preview.mask'] || @@ -53,14 +51,12 @@ export const AttachmentsFileCard = sveltify< toolbarRender: slots['imageProps.preview.toolbarRender'] ? renderParamsSlot({ slots, - setSlotParams, key: 'imageProps.preview.toolbarRender', }) : previewToolbarRenderFunction, imageRender: slots['imageProps.preview.imageRender'] ? renderParamsSlot({ slots, - setSlotParams, key: 'imageProps.preview.imageRender', }) : previewImageRenderFunction, diff --git a/frontend/antdx/bubble/Index.svelte b/frontend/antdx/bubble/Index.svelte index 7bc2312a..53df6394 100644 --- a/frontend/antdx/bubble/Index.svelte +++ b/frontend/antdx/bubble/Index.svelte @@ -1,81 +1,68 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedBubble then Bubble} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antdx/bubble/bubble.tsx b/frontend/antdx/bubble/bubble.tsx index 79f18548..41cda5c0 100644 --- a/frontend/antdx/bubble/bubble.tsx +++ b/frontend/antdx/bubble/bubble.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { Bubble as XBubble, type BubbleProps } from '@ant-design/x'; import { useFunction } from '@utils/hooks/useFunction'; @@ -10,7 +9,6 @@ import { isObject } from 'lodash-es'; export const Bubble = sveltify< BubbleProps & { - setSlotParams: SetSlotParams; }, [ 'avatar', @@ -28,7 +26,6 @@ export const Bubble = sveltify< loadingRender, messageRender, slots, - setSlotParams, children, ...props }) => { @@ -92,7 +89,6 @@ export const Bubble = sveltify< slots.loadingRender ? renderParamsSlot({ slots, - setSlotParams, key: 'loadingRender', }) : loadingRenderFunction @@ -101,7 +97,6 @@ export const Bubble = sveltify< slots.messageRender ? renderParamsSlot({ slots, - setSlotParams, key: 'messageRender', }) : messageRenderFunction diff --git a/frontend/antdx/bubble/list/Index.svelte b/frontend/antdx/bubble/list/Index.svelte index b4f889e6..23c63608 100644 --- a/frontend/antdx/bubble/list/Index.svelte +++ b/frontend/antdx/bubble/list/Index.svelte @@ -1,73 +1,60 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedBubbleList then BubbleList} - + {@render children()} {/await} {/if} - - diff --git a/frontend/antdx/bubble/list/item/Index.svelte b/frontend/antdx/bubble/list/item/Index.svelte index 496f911e..dfa33c9a 100644 --- a/frontend/antdx/bubble/list/item/Index.svelte +++ b/frontend/antdx/bubble/list/item/Index.svelte @@ -1,32 +1,13 @@ - - {#await AwaitedBubbleListItem then BubbleListItem} - - + + {@render props.children?.()} {/await} diff --git a/frontend/antdx/bubble/list/item/Item.svelte b/frontend/antdx/bubble/list/item/Item.svelte index 9238408c..478a1e2d 100644 --- a/frontend/antdx/bubble/list/item/Item.svelte +++ b/frontend/antdx/bubble/list/item/Item.svelte @@ -1,143 +1,66 @@ - - -{#await AwaitedBubbleListItem then BubbleListItem} - - {#if $mergedProps.visible} - - {/if} - -{/await} +{#if proceedProps.visible} + {#await AwaitedBubbleListItem then BubbleListItem} + + {@render children()} + + {/await} +{/if} diff --git a/frontend/antdx/bubble/list/role/Index.svelte b/frontend/antdx/bubble/list/role/Index.svelte index 0364c61e..554093bc 100644 --- a/frontend/antdx/bubble/list/role/Index.svelte +++ b/frontend/antdx/bubble/list/role/Index.svelte @@ -1,32 +1,13 @@ - - {#await AwaitedBubbleListRole then BubbleListRole} - - + + {@render props.children?.()} {/await} diff --git a/frontend/antdx/bubble/list/role/Role.svelte b/frontend/antdx/bubble/list/role/Role.svelte index 41bddf29..167bc7c5 100644 --- a/frontend/antdx/bubble/list/role/Role.svelte +++ b/frontend/antdx/bubble/list/role/Role.svelte @@ -1,161 +1,62 @@ - - -{#await AwaitedBubbleListRole then BubbleListRole} - - {#if $mergedProps.visible} - - {/if} - -{/await} +{#if proceedProps.visible} + {#await AwaitedBubbleListRole then BubbleListRole} + + {@render children()} + + {/await} +{/if} diff --git a/frontend/antdx/conversations/Index.svelte b/frontend/antdx/conversations/Index.svelte index b460d9d7..7c4dde82 100644 --- a/frontend/antdx/conversations/Index.svelte +++ b/frontend/antdx/conversations/Index.svelte @@ -1,78 +1,68 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedConversations then Conversations} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/conversations/conversations.tsx b/frontend/antdx/conversations/conversations.tsx index 9b0ca261..550d5a69 100644 --- a/frontend/antdx/conversations/conversations.tsx +++ b/frontend/antdx/conversations/conversations.tsx @@ -1,6 +1,5 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useMemo } from 'react'; import { Conversations as XConversations, @@ -56,7 +55,6 @@ function patchMenuEvents(menuProps: MenuProps, conversation: Conversation) { export const Conversations = sveltify< ConversationsProps & { - setSlotParams: SetSlotParams; }, [ 'menu.expandIcon', @@ -69,7 +67,7 @@ export const Conversations = sveltify< ['menu.items'], withItemsContextProvider( ['default', 'items'], - ({ slots, setSlotParams, children, items, ...props }) => { + ({ slots, children, items, ...props }) => { const { items: { 'menu.items': menuItems }, } = useMenuItems<['menu.items']>(); @@ -100,13 +98,13 @@ export const Conversations = sveltify< [], trigger: slots['menu.trigger'] ? renderParamsSlot( - { slots, setSlotParams, key: 'menu.trigger' }, + { slots, key: 'menu.trigger' }, { clone: true } ) : createFunction(menuProps.trigger, true) || menuProps.trigger, expandIcon: slots['menu.expandIcon'] ? renderParamsSlot( - { slots, setSlotParams, key: 'menu.expandIcon' }, + { slots, key: 'menu.expandIcon' }, { clone: true } ) : menuProps.expandIcon, @@ -117,7 +115,7 @@ export const Conversations = sveltify< ), }); } - }, [menuFunction, menuItems, props.menu, setSlotParams, slots]); + }, [menuFunction, menuItems, props.menu, slots]); const { items: slotItems } = useItems<['default', 'items']>(); const resolvedSlotItems = slotItems.items.length > 0 ? slotItems.items : slotItems.default; @@ -155,7 +153,6 @@ export const Conversations = sveltify< title: slots['groupable.title'] ? renderParamsSlot({ slots, - setSlotParams, key: 'groupable.title', }) : groupableConfig.title, diff --git a/frontend/antdx/conversations/item/Index.svelte b/frontend/antdx/conversations/item/Index.svelte index 1249c0f5..bbb12c6b 100644 --- a/frontend/antdx/conversations/item/Index.svelte +++ b/frontend/antdx/conversations/item/Index.svelte @@ -1,89 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedConversationsItem then ConversationsItem} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/prompts/Index.svelte b/frontend/antdx/prompts/Index.svelte index 22f63384..f57a72ec 100644 --- a/frontend/antdx/prompts/Index.svelte +++ b/frontend/antdx/prompts/Index.svelte @@ -1,72 +1,68 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedPrompts then Prompts} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/prompts/item/Index.svelte b/frontend/antdx/prompts/item/Index.svelte index 9690784b..0c74f774 100644 --- a/frontend/antdx/prompts/item/Index.svelte +++ b/frontend/antdx/prompts/item/Index.svelte @@ -1,84 +1,64 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedPromptsItem then PromptsItem} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/sender/Index.svelte b/frontend/antdx/sender/Index.svelte index 264c2ef0..238adca2 100644 --- a/frontend/antdx/sender/Index.svelte +++ b/frontend/antdx/sender/Index.svelte @@ -1,98 +1,98 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSender then Sender} { - value = v; + updateProps({ + value: v, + }); }} {upload} > - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/sender/header/Index.svelte b/frontend/antdx/sender/header/Index.svelte index ea69a309..858896f5 100644 --- a/frontend/antdx/sender/header/Index.svelte +++ b/frontend/antdx/sender/header/Index.svelte @@ -1,72 +1,60 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSenderHeader then SenderHeader} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/sender/sender.tsx b/frontend/antdx/sender/sender.tsx index 231eafaa..9068554c 100644 --- a/frontend/antdx/sender/sender.tsx +++ b/frontend/antdx/sender/sender.tsx @@ -1,7 +1,6 @@ import { sveltify } from '@svelte-preprocess-react'; import { useSuggestionOpenContext } from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React from 'react'; import { Sender as XSender, type SenderProps } from '@ant-design/x'; import type { FileData } from '@gradio/client'; @@ -11,7 +10,6 @@ import { useValueChange } from '@utils/hooks/useValueChange'; export const Sender = sveltify< Omit & { children?: React.ReactNode; - setSlotParams: SetSlotParams; upload: (files: File[]) => Promise; onPasteFile?: (value: string[]) => void; onValueChange: (value: string) => void; diff --git a/frontend/antdx/suggestion/Index.svelte b/frontend/antdx/suggestion/Index.svelte index 01465d54..d1e7491b 100644 --- a/frontend/antdx/suggestion/Index.svelte +++ b/frontend/antdx/suggestion/Index.svelte @@ -1,76 +1,73 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSuggestion then Suggestion} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/suggestion/item/Index.svelte b/frontend/antdx/suggestion/item/Index.svelte index d7f97be8..8f1c2c85 100644 --- a/frontend/antdx/suggestion/item/Index.svelte +++ b/frontend/antdx/suggestion/item/Index.svelte @@ -1,112 +1,66 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedSuggestionItem then SuggestionItem} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/thought-chain/Index.svelte b/frontend/antdx/thought-chain/Index.svelte index 453865c6..2a6b642a 100644 --- a/frontend/antdx/thought-chain/Index.svelte +++ b/frontend/antdx/thought-chain/Index.svelte @@ -1,70 +1,61 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedThoughtChain then ThoughtChain} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/thought-chain/item/Index.svelte b/frontend/antdx/thought-chain/item/Index.svelte index aa44e6e3..2a5cad23 100644 --- a/frontend/antdx/thought-chain/item/Index.svelte +++ b/frontend/antdx/thought-chain/item/Index.svelte @@ -1,89 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedThoughtChainItem then ThoughtChainItem} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/welcome/Index.svelte b/frontend/antdx/welcome/Index.svelte index 0102f7e6..6a768bbf 100644 --- a/frontend/antdx/welcome/Index.svelte +++ b/frontend/antdx/welcome/Index.svelte @@ -1,74 +1,69 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedWelcome then Welcome} - + {@render children()} {/await} {/if} diff --git a/frontend/antdx/x-provider/Index.svelte b/frontend/antdx/x-provider/Index.svelte index f3f7f3af..9a86a426 100644 --- a/frontend/antdx/x-provider/Index.svelte +++ b/frontend/antdx/x-provider/Index.svelte @@ -1,32 +1,15 @@ - - {#await AwaitedXProvider then XProvider} - - + + {#snippet children()} + {@render props.children?.()} + {/snippet} {/await} diff --git a/frontend/antdx/x-provider/XProvider.svelte b/frontend/antdx/x-provider/XProvider.svelte index bec9ac81..6afe5a5e 100644 --- a/frontend/antdx/x-provider/XProvider.svelte +++ b/frontend/antdx/x-provider/XProvider.svelte @@ -1,76 +1,86 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedXProvider then XProvider} { + slotParamsFn = params; + }} > - + {@render children()} {/await} {/if} diff --git a/frontend/base/application/Application.svelte b/frontend/base/application/Application.svelte index 8276709e..fd249128 100644 --- a/frontend/base/application/Application.svelte +++ b/frontend/base/application/Application.svelte @@ -1,5 +1,3 @@ - - -{#await awaitedApplication then Application} +{#await AwaitedApplication then Application} - {@render children()} + {@render children?.()} {/await} diff --git a/frontend/base/application/gradio.config.js b/frontend/base/application/gradio.config.js index 3cf1a1f7..7377f13f 100644 --- a/frontend/base/application/gradio.config.js +++ b/frontend/base/application/gradio.config.js @@ -1,3 +1,3 @@ -import config from '../../defineConfig.js'; +// import config from '../../defineConfig.js'; -export default config({ external: false }); +export default {}; diff --git a/frontend/base/div/Index.svelte b/frontend/base/div/Index.svelte index 59668735..edc60688 100644 --- a/frontend/base/div/Index.svelte +++ b/frontend/base/div/Index.svelte @@ -4,6 +4,7 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; + import type React from 'react'; import cls from 'classnames'; const AwaitedDiv = importComponent(() => import('./div')); @@ -11,6 +12,7 @@ const { getComponentProps, getAdditionalProps, children } = getProps<{ value: string; + elem_style: React.CSSProperties; additional_props?: Record; _internal: { layout?: boolean; diff --git a/frontend/base/each/EachItem.svelte b/frontend/base/each/EachItem.svelte index 71db8507..ee9cce7b 100644 --- a/frontend/base/each/EachItem.svelte +++ b/frontend/base/each/EachItem.svelte @@ -1,10 +1,9 @@ {#if show} - - + + {@render children?.()} {:else} - + {@render children?.()} {/if} diff --git a/frontend/package.json b/frontend/package.json index 535e7f6e..10e82a6d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,25 +6,25 @@ "license": "Apache-2.0", "type": "module", "dependencies": { - "@ant-design/cssinjs": "^2.1.0", + "@ant-design/cssinjs": "^2.1.2", "@ant-design/icons": "^6.1.0", - "@ant-design/x": "^2.2.2", + "@ant-design/x": "^2.3.0", "@babel/standalone": "^7.29.1", - "@gradio/client": "^2.0.4", + "@gradio/client": "2.0.4", "@gradio/preview": "0.15.2", - "@gradio/statustracker": "^0.12.4", + "@gradio/statustracker": "^0.12.5", "@gradio/utils": "0.11.3", "@monaco-editor/react": "^4.7.0", "amuchina": "^1.0.12", - "antd": "^6.3.1", + "antd": "^6.3.2", "classnames": "^2.5.1", "dayjs": "^1.11.19", "dequal": "^2.0.2", "github-slugger": "^2.0.0", "immer": "^11.1.4", - "katex": "^0.16.33", + "katex": "^0.16.38", "lodash-es": "^4.17.23", - "marked": "^17.0.3", + "marked": "^17.0.4", "marked-gfm-heading-id": "^4.1.3", "marked-highlight": "^2.2.3", "mermaid": "^11.12.3", @@ -33,7 +33,7 @@ "prismjs": "^1.30.0", "react": "^19.2.4", "react-dom": "^19.2.4", - "svelte": "5.53.5", + "svelte": "5.48.0", "svelte-i18n": "^4.0.1", "wavesurfer.js": "^7.12.1" }, @@ -46,9 +46,8 @@ "@types/prismjs": "^1.26.6", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@types/sanitize-html": "^2.16.0", + "@types/sanitize-html": "^2.16.1", "@vitejs/plugin-react-swc": "^4.2.3", - "fast-glob": "^3.3.3", "less": "^4.5.1", "typescript-json-schema": "^0.67.1", "vite": "^7.3.1" diff --git a/frontend/plugin.js b/frontend/plugin.js index b4e9d278..bc39e833 100644 --- a/frontend/plugin.js +++ b/frontend/plugin.js @@ -1,5 +1,4 @@ import { parse, transformFromAstSync, traverse, types as t } from '@babel/core'; -import fg from 'fast-glob'; import path from 'node:path'; import url from 'node:url'; @@ -28,19 +27,7 @@ function generateSveltePreprocessReactAliases() { '@svelte-preprocess-react': path.resolve(dirname, baseDir), }; - const files = fg.sync([`${baseDir}/*.ts`, `${baseDir}/*.tsx`], { - cwd: dirname, - absolute: false, - }); - - const moduleAliases = files.reduce((aliases, file) => { - const fileName = path.basename(file, path.extname(file)); - aliases[`@svelte-preprocess-react/${fileName}`] = path.resolve( - dirname, - file - ); - return aliases; - }, {}); + const moduleAliases = {}; return { ...baseAlias, diff --git a/frontend/pro/chatbot/Index.svelte b/frontend/pro/chatbot/Index.svelte index 30f9b64c..ed2ead2e 100644 --- a/frontend/pro/chatbot/Index.svelte +++ b/frontend/pro/chatbot/Index.svelte @@ -1,88 +1,89 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedChatbot then Chatbot} { - value = v; + updateProps({ + value: v, + }); }} - urlRoot={root} - urlProxyUrl={proxy_url} - themeMode={gradio.theme} - slots={$slots} + urlRoot={proceedProps.gradio.shared.root} + urlProxyUrl={proceedProps.gradio.shared.proxy_url} + themeMode={proceedProps.additionalProps.gradio?.theme} + slots={slots.value} > - + {@render children()} {/await} {/if} diff --git a/frontend/pro/monaco-editor/Index.svelte b/frontend/pro/monaco-editor/Index.svelte index 175a0c78..48437d2d 100644 --- a/frontend/pro/monaco-editor/Index.svelte +++ b/frontend/pro/monaco-editor/Index.svelte @@ -1,99 +1,94 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await awaitedLoader then} {#await AwaitedMonacoEditor then MonacoEditor} - + {@render children()} {/await} {/await} diff --git a/frontend/pro/monaco-editor/diff-editor/Index.svelte b/frontend/pro/monaco-editor/diff-editor/Index.svelte index 6a89c150..fbddea6e 100644 --- a/frontend/pro/monaco-editor/diff-editor/Index.svelte +++ b/frontend/pro/monaco-editor/diff-editor/Index.svelte @@ -1,102 +1,65 @@ - - -{#if $mergedProps.visible} - {#await awaitedLoader then} - {#await AwaitedMonacoDiffEditor then MonacoDiffEditor} - - - - {/await} +{#if proceedProps.visible} + {#await AwaitedDiffEditor then DiffEditor} + + {@render children()} + {/await} {/if} diff --git a/frontend/pro/multimodal-input/Index.svelte b/frontend/pro/multimodal-input/Index.svelte index 83075b74..bde131d4 100644 --- a/frontend/pro/multimodal-input/Index.svelte +++ b/frontend/pro/multimodal-input/Index.svelte @@ -1,20 +1,12 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedMultimodalInput then MultimodalInput} { - value = v; + updateProps({ + value: v, + }); }} {upload} > - + {@render children()} {/await} {/if} diff --git a/frontend/pro/multimodal-input/multimodal-input.tsx b/frontend/pro/multimodal-input/multimodal-input.tsx index 3c59e189..46bc85ec 100644 --- a/frontend/pro/multimodal-input/multimodal-input.tsx +++ b/frontend/pro/multimodal-input/multimodal-input.tsx @@ -1,7 +1,6 @@ import { sveltify } from '@svelte-preprocess-react'; import { useSuggestionOpenContext } from '@svelte-preprocess-react/react-contexts'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import { CloudUploadOutlined, LinkOutlined } from '@ant-design/icons'; import { @@ -75,7 +74,6 @@ export const MultimodalInput = sveltify< 'onPasteFile' | 'value' | 'onSubmit' > & { children?: React.ReactNode; - setSlotParams: SetSlotParams; value?: MultimodalInputValue; mode?: 'inline' | 'block'; upload: (files: File[]) => Promise; diff --git a/frontend/pro/web-sandbox/Index.svelte b/frontend/pro/web-sandbox/Index.svelte index 71f481a7..3d1555d7 100644 --- a/frontend/pro/web-sandbox/Index.svelte +++ b/frontend/pro/web-sandbox/Index.svelte @@ -1,87 +1,78 @@ - - -{#if $mergedProps.visible} +{#if proceedProps.visible} {#await AwaitedWebSandbox then WebSandbox} - + {@render children()} {/await} {/if} diff --git a/frontend/pro/web-sandbox/web-sandbox.tsx b/frontend/pro/web-sandbox/web-sandbox.tsx index 9ad1be37..b72cb8b1 100644 --- a/frontend/pro/web-sandbox/web-sandbox.tsx +++ b/frontend/pro/web-sandbox/web-sandbox.tsx @@ -1,6 +1,5 @@ import reactIframeTemplate from './react-iframe-template.html?raw'; import { sveltify } from '@svelte-preprocess-react'; -import type { SetSlotParams } from '@svelte-preprocess-react/slot'; import React, { useEffect, useMemo, useState } from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { useMemoizedFn } from '@utils/hooks/useMemoizedFn'; @@ -31,7 +30,6 @@ export interface WebSandboxProps { onCustom?: (...args: any[]) => void; height?: string | number; themeMode: string; - setSlotParams: SetSlotParams; compileErrorRender?: (message: string) => React.ReactNode; children?: React.ReactNode; } @@ -42,7 +40,6 @@ export const WebSandbox = sveltify( value, imports, slots, - setSlotParams, template = 'react', themeMode, showRenderError, @@ -323,7 +320,6 @@ export const WebSandbox = sveltify(
{children}
{renderParamsSlot({ slots, - setSlotParams, key: 'compileErrorRender', })?.(compileError)} diff --git a/frontend/svelte-preprocess-react/component/props.svelte.ts b/frontend/svelte-preprocess-react/component/props.svelte.ts index 5ec1ea48..94e8ef1c 100644 --- a/frontend/svelte-preprocess-react/component/props.svelte.ts +++ b/frontend/svelte-preprocess-react/component/props.svelte.ts @@ -215,14 +215,13 @@ export function processEvents< ), }; } - export function processProps< T extends { as_item: string | undefined; _internal: Record; additionalProps?: Record; restProps: Record; - gradio?: Gradio>; + gradio: Gradio>; }, >( getPlainProps: () => T, @@ -232,15 +231,17 @@ export function processProps< shouldResetSlotKey?: boolean; } ) { - const props = $derived(getPlainProps()); + const props = $derived.by(() => getPlainProps()); const shouldResetSlotKey = options?.shouldResetSlotKey ?? true; const shouldSetLoadingStatus = options?.shouldSetLoadingStatus ?? true; // throw error once if the property keys are not exist - if (!Reflect.has(props, 'as_item') || !Reflect.has(props, '_internal')) { - throw new Error('`as_item` and `_internal` is required'); - } - + const assertProps = () => { + if (!Reflect.has(props, 'as_item') || !Reflect.has(props, '_internal')) { + throw new Error('`as_item` and `_internal` is required'); + } + }; + assertProps(); const slotKey = getSlotKey(); // get slotParamsMapping for slot const slotParamsMapping = getSlotParamsMapping(); @@ -276,7 +277,9 @@ export function processProps< return subIndex?.value; }); - const proceedEvents = $derived(processEvents(props, restPropsMapping)); + const proceedEvents = $derived.by(() => + processEvents(props, restPropsMapping) + ); const processRestProps = ( restProps?: Record, @@ -323,15 +326,13 @@ export function getProps< P extends Record, E extends Record = Record, >(getSvelteProps: () => any) { - const { - children, - ...restProps - }: { + const props: { children: Snippet; props: P; shared_props: SharedProps; } = getSvelteProps(); - const gradio = new Gradio(restProps); + const gradio = new Gradio(props); + const updateProps = (updatedProps: Partial

) => { gradio.update(updatedProps); }; @@ -356,7 +357,10 @@ export function getProps< ); let additionalProps = $state( - (() => $state.snapshot(gradio.props.additional_props) || {})() + (() => $state.snapshot(gradio.props.additional_props) || {})() as Record< + PropertyKey, + any + > ); $effect(() => { @@ -372,6 +376,6 @@ export function getProps< getComponentProps, getAdditionalProps, updateProps, - children, + children: props.children, }; } diff --git a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts index c1cefaf9..ea1d2386 100644 --- a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts +++ b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts @@ -10,6 +10,7 @@ import React, { useRef, useState, } from 'react'; +import { createFunction } from '@utils/createFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { patchProps } from '@utils/patchProps'; @@ -109,8 +110,15 @@ function BridgeInternal({ const autoCompleteContext = useAutoCompleteContext(); const suggestionContext = useSuggestionContext(); const props: typeof nodeProps = useMemo(() => { + const styles = createFunction(nodeProps.styles, true) || nodeProps.styles; + const classNames = + createFunction(nodeProps.classNames, true) || nodeProps.classNames; + return omitUndefinedProps({ ...nodeProps, + ...(styles ? { styles } : {}), + ...(classNames ? { classNames } : {}), + // convert styles & classNames // If the component is ignore, then its value should ignore the influence of the context. ...(node.ignore ? {} : formItemContext || {}), ...(node.ignore ? {} : autoCompleteContext || {}), diff --git a/frontend/svelte-preprocess-react/sveltify.svelte.ts b/frontend/svelte-preprocess-react/sveltify.svelte.ts index b6a4b671..5db46e3f 100644 --- a/frontend/svelte-preprocess-react/sveltify.svelte.ts +++ b/frontend/svelte-preprocess-react/sveltify.svelte.ts @@ -39,7 +39,7 @@ export function sveltify( | Sveltified, 'children'> & { children?: any }> { // svelte components options function Sveltified(internals: any, $$props: any) { - const wrapperProps = $derived({ + const wrapperProps = { componentProps: $$props, svelteInit: (init: SvelteInit) => { window.ms_globals.autokey += 1; @@ -63,8 +63,15 @@ export function sveltify( const rootEl = document.createElement('react-root'); const root = ReactDOM.createRoot(rootEl); portalTarget = document.createElement('bridge-root'); - document.head.appendChild(rootEl); - document.head.appendChild(portalTarget); + + $effect(() => { + document.head.appendChild(rootEl); + document.head.appendChild(portalTarget); + return () => { + document.head.removeChild(rootEl); + document.head.removeChild(portalTarget); + }; + }); rootNode.rerender = () => { root.render( React.createElement(Bridge, { @@ -91,7 +98,7 @@ export function sveltify( parent.rerender?.(); return node; }, - }); + }; (ReactWrapper as any)(internals, wrapperProps); } diff --git a/frontend/utils/hooks/useMemoizedEqualValue.ts b/frontend/utils/hooks/useMemoizedEqualValue.ts index a892d705..85d7e4ec 100644 --- a/frontend/utils/hooks/useMemoizedEqualValue.ts +++ b/frontend/utils/hooks/useMemoizedEqualValue.ts @@ -2,7 +2,7 @@ import { useMemo, useRef } from 'react'; import { isEqual } from 'lodash-es'; export function useMemoizedEqualValue(prop: T): T { - const propRef = useRef(); + const propRef = useRef(undefined); return useMemo(() => { if (isEqual(prop, propRef.current)) { diff --git a/package.json b/package.json index 3f8b76de..da15be83 100644 --- a/package.json +++ b/package.json @@ -27,24 +27,25 @@ "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/github": "^9.0.0", - "@changesets/cli": "^2.29.8", - "@commitlint/cli": "^20.4.2", - "@commitlint/config-conventional": "^20.4.2", + "@changesets/cli": "^2.30.0", + "@commitlint/cli": "^20.4.3", + "@commitlint/config-conventional": "^20.4.3", "@manypkg/get-packages": "^3.1.0", "@modelscope-studio/changelog": "workspace:*", "@modelscope-studio/lint-config": "workspace:*", + "@types/node": "^25.3.5", "eslint": "^9.39.3", "husky": "^9.1.7", - "lint-staged": "^16.2.7", + "lint-staged": "^16.3.2", "node-fetch": "^3.3.2", "npm-run-all": "^4.1.5", "prettier": "^3.8.1", - "prettier-plugin-packagejson": "^3.0.0", - "prettier-plugin-svelte": "^3.5.0", + "prettier-plugin-packagejson": "^3.0.2", + "prettier-plugin-svelte": "^3.5.1", "rimraf": "^6.1.3", "stylelint": "^17.4.0", - "svelte": "^5.53.5", - "svelte-check": "^4.4.3", + "svelte": "5.48.0", + "svelte-check": "^4.4.5", "tslib": "^2.8.1", "tsx": "^4.21.0", "typescript": "^5.9.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e8d88ea..551c1d5a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,14 +18,14 @@ importers: specifier: ^9.0.0 version: 9.0.0 '@changesets/cli': - specifier: ^2.29.8 - version: 2.29.8(@types/node@25.3.1) + specifier: ^2.30.0 + version: 2.30.0(@types/node@25.3.5) '@commitlint/cli': - specifier: ^20.4.2 - version: 20.4.2(@types/node@25.3.1)(typescript@5.9.3) + specifier: ^20.4.3 + version: 20.4.3(@types/node@25.3.5)(typescript@5.9.3) '@commitlint/config-conventional': - specifier: ^20.4.2 - version: 20.4.2 + specifier: ^20.4.3 + version: 20.4.3 '@manypkg/get-packages': specifier: ^3.1.0 version: 3.1.0 @@ -35,6 +35,9 @@ importers: '@modelscope-studio/lint-config': specifier: workspace:* version: link:config/lint-config + '@types/node': + specifier: ^25.3.5 + version: 25.3.5 eslint: specifier: ^9.39.3 version: 9.39.3(jiti@2.6.1) @@ -42,8 +45,8 @@ importers: specifier: ^9.1.7 version: 9.1.7 lint-staged: - specifier: ^16.2.7 - version: 16.2.7 + specifier: ^16.3.2 + version: 16.3.2 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -54,11 +57,11 @@ importers: specifier: ^3.8.1 version: 3.8.1 prettier-plugin-packagejson: - specifier: ^3.0.0 - version: 3.0.0(prettier@3.8.1) + specifier: ^3.0.2 + version: 3.0.2(prettier@3.8.1) prettier-plugin-svelte: - specifier: ^3.5.0 - version: 3.5.0(prettier@3.8.1)(svelte@5.53.5) + specifier: ^3.5.1 + version: 3.5.1(prettier@3.8.1)(svelte@5.48.0) rimraf: specifier: ^6.1.3 version: 6.1.3 @@ -66,11 +69,11 @@ importers: specifier: ^17.4.0 version: 17.4.0(typescript@5.9.3) svelte: - specifier: ^5.53.5 - version: 5.53.5 + specifier: 5.48.0 + version: 5.48.0 svelte-check: - specifier: ^4.4.3 - version: 4.4.3(picomatch@4.0.3)(svelte@5.53.5)(typescript@5.9.3) + specifier: ^4.4.5 + version: 4.4.5(picomatch@4.0.3)(svelte@5.48.0)(typescript@5.9.3) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -84,8 +87,8 @@ importers: config/changelog: dependencies: '@changesets/get-github-info': - specifier: ^0.7.0 - version: 0.7.0 + specifier: ^0.8.0 + version: 0.8.0 '@manypkg/get-packages': specifier: ^3.1.0 version: 3.1.0 @@ -97,17 +100,17 @@ importers: specifier: ^6.1.0 version: 6.1.0 '@types/node': - specifier: ^25.3.1 - version: 25.3.1 + specifier: ^25.3.5 + version: 25.3.5 tsup: specifier: ^8.5.1 - version: 8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.3.1))(@swc/core@1.15.11)(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.1) + version: 8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.3.5))(@swc/core@1.15.11)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) config/lint-config: dependencies: '@eslint/compat': - specifier: ^2.0.2 - version: 2.0.2(eslint@9.39.3(jiti@2.6.1)) + specifier: ^2.0.3 + version: 2.0.3(eslint@9.39.3(jiti@2.6.1)) '@eslint/js': specifier: ^10.0.1 version: 10.0.1(eslint@9.39.3(jiti@2.6.1)) @@ -142,17 +145,17 @@ importers: specifier: ^12.1.0 version: 12.1.1(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-svelte: - specifier: ^3.15.0 - version: 3.15.0(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.5)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.1)(typescript@5.9.3)) + specifier: ^3.15.1 + version: 3.15.1(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.7)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.5)(typescript@5.9.3)) globals: - specifier: ^17.3.0 - version: 17.3.0 + specifier: ^17.4.0 + version: 17.4.0 postcss: - specifier: ^8.5.6 - version: 8.5.6 + specifier: ^8.5.8 + version: 8.5.8 postcss-less: specifier: ^6.0.0 - version: 6.0.0(postcss@8.5.6) + version: 6.0.0(postcss@8.5.8) stylelint-config-rational-order: specifier: ^0.1.2 version: 0.1.2 @@ -169,8 +172,8 @@ importers: specifier: ^5.0.3 version: 5.0.3(prettier@3.8.1)(stylelint@17.4.0(typescript@5.9.3)) svelte-eslint-parser: - specifier: ^1.5.1 - version: 1.5.1(svelte@5.53.5) + specifier: ^1.6.0 + version: 1.6.0(svelte@5.53.7) typescript-eslint: specifier: ^8.56.1 version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) @@ -185,29 +188,29 @@ importers: frontend: dependencies: '@ant-design/cssinjs': - specifier: ^2.1.0 - version: 2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^2.1.2 + version: 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/icons': specifier: ^6.1.0 version: 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/x': - specifier: ^2.2.2 - version: 2.2.2(antd@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^2.3.0 + version: 2.3.0(antd@6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/standalone': specifier: ^7.29.1 version: 7.29.1 '@gradio/client': - specifier: ^2.0.4 + specifier: 2.0.4 version: 2.0.4 '@gradio/preview': specifier: 0.15.2 - version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1))(postcss@8.5.6)(rollup@4.57.1)(svelte@5.53.5)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.48.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@gradio/statustracker': - specifier: ^0.12.4 - version: 0.12.4(svelte@5.53.5) + specifier: ^0.12.5 + version: 0.12.5(svelte@5.48.0) '@gradio/utils': specifier: 0.11.3 - version: 0.11.3(svelte@5.53.5) + version: 0.11.3(svelte@5.48.0) '@monaco-editor/react': specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -215,8 +218,8 @@ importers: specifier: ^1.0.12 version: 1.0.12 antd: - specifier: ^6.3.1 - version: 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^6.3.2 + version: 6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) classnames: specifier: ^2.5.1 version: 2.5.1 @@ -233,20 +236,20 @@ importers: specifier: ^11.1.4 version: 11.1.4 katex: - specifier: ^0.16.33 - version: 0.16.33 + specifier: ^0.16.38 + version: 0.16.38 lodash-es: specifier: ^4.17.23 version: 4.17.23 marked: - specifier: ^17.0.3 - version: 17.0.3 + specifier: ^17.0.4 + version: 17.0.4 marked-gfm-heading-id: specifier: ^4.1.3 - version: 4.1.3(marked@17.0.3) + version: 4.1.3(marked@17.0.4) marked-highlight: specifier: ^2.2.3 - version: 2.2.3(marked@17.0.3) + version: 2.2.3(marked@17.0.4) mermaid: specifier: ^11.12.3 version: 11.12.3 @@ -266,11 +269,11 @@ importers: specifier: ^19.2.4 version: 19.2.4(react@19.2.4) svelte: - specifier: 5.53.5 - version: 5.53.5 + specifier: 5.48.0 + version: 5.48.0 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.53.5) + version: 4.0.1(svelte@5.48.0) wavesurfer.js: specifier: ^7.12.1 version: 7.12.1 @@ -300,14 +303,11 @@ importers: specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.14) '@types/sanitize-html': - specifier: ^2.16.0 - version: 2.16.0 + specifier: ^2.16.1 + version: 2.16.1 '@vitejs/plugin-react-swc': specifier: ^4.2.3 - version: 4.2.3(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) - fast-glob: - specifier: ^3.3.3 - version: 3.3.3 + version: 4.2.3(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) less: specifier: ^4.5.1 version: 4.5.1 @@ -316,7 +316,7 @@ importers: version: 0.67.1(@swc/core@1.15.11) vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + version: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) frontend/antd: {} @@ -355,14 +355,14 @@ packages: '@ant-design/colors@8.0.1': resolution: {integrity: sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==} - '@ant-design/cssinjs-utils@2.1.1': - resolution: {integrity: sha512-RKxkj5pGFB+FkPJ5NGhoX3DK3xsv0pMltha7Ei1AnY3tILeq38L7tuhaWDPQI/5nlPxOog44wvqpNyyGcUsNMg==} + '@ant-design/cssinjs-utils@2.1.2': + resolution: {integrity: sha512-5fTHQ158jJJ5dC/ECeyIdZUzKxE/mpEMRZxthyG1sw/AKRHKgJBg00Yi6ACVXgycdje7KahRNvNET/uBccwCnA==} peerDependencies: react: '>=18' react-dom: '>=18' - '@ant-design/cssinjs@2.1.0': - resolution: {integrity: sha512-eZFrPCnrYrF3XtL7qA4L75P0qA3TtZta8H3Yggy7UYFh8gZgu5bSMNF+v4UVCzGxzYmx8ZvPdgOce0BJ6PsW9g==} + '@ant-design/cssinjs@2.1.2': + resolution: {integrity: sha512-2Hy8BnCEH31xPeSLbhhB2ctCPXE2ZnASdi+KbSeS79BNbUhL9hAEe20SkUk+BR8aKTmqb6+FKFruk7w8z0VoRQ==} peerDependencies: react: '>=16.0.0' react-dom: '>=16.0.0' @@ -391,8 +391,8 @@ packages: react: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@ant-design/x@2.2.2': - resolution: {integrity: sha512-fNXMfCKBT3goPUHgm3DE863IgWlFe233EAeR4CZKChVVc/oUdj19uRURNMV6LL1l535FToNZAiaCz7BXSxxZZg==} + '@ant-design/x@2.3.0': + resolution: {integrity: sha512-kH711bo0PIizzYlhkGVD0/oNtEehP0AUktX55gtTFCM3cRbXIKTLwcxlragLWaCXPtT1O/T8F6SAYCxLtg76IA==} peerDependencies: antd: ^6.1.1 react: '>=18.0.0' @@ -566,8 +566,8 @@ packages: '@cacheable/utils@2.3.4': resolution: {integrity: sha512-knwKUJEYgIfwShABS1BX6JyJJTglAFcEU7EXqzTdiGCXur4voqkiJkdgZIQtWNFhynzDWERcTYv/sETMu3uJWA==} - '@changesets/apply-release-plan@7.0.14': - resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} + '@changesets/apply-release-plan@7.1.0': + resolution: {integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==} '@changesets/assemble-release-plan@6.0.9': resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} @@ -575,12 +575,12 @@ packages: '@changesets/changelog-git@0.2.1': resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@changesets/cli@2.29.8': - resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==} + '@changesets/cli@2.30.0': + resolution: {integrity: sha512-5D3Nk2JPqMI1wK25pEymeWRSlSMdo5QOGlyfrKg0AOufrUcjEE3RQgaCpHoBiM31CSNrtSgdJ0U6zL1rLDDfBA==} hasBin: true - '@changesets/config@3.1.2': - resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==} + '@changesets/config@3.1.3': + resolution: {integrity: sha512-vnXjcey8YgBn2L1OPWd3ORs0bGC4LoYcK/ubpgvzNVr53JXV5GiTVj7fWdMRsoKUH7hhhMAQnsJUqLr21EncNw==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} @@ -588,11 +588,11 @@ packages: '@changesets/get-dependents-graph@2.1.3': resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} - '@changesets/get-github-info@0.7.0': - resolution: {integrity: sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==} + '@changesets/get-github-info@0.8.0': + resolution: {integrity: sha512-cRnC+xdF0JIik7coko3iUP9qbnfi1iJQ3sAa6dE+Tx3+ET8bjFEm63PA4WEohgjYcmsOikPHWzPsMWWiZmntOQ==} - '@changesets/get-release-plan@4.0.14': - resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==} + '@changesets/get-release-plan@4.0.15': + resolution: {integrity: sha512-Q04ZaRPuEVZtA+auOYgFaVQQSA98dXiVe/yFaZfY7hoSmQICHGvP0TF4u3EDNHWmmCS4ekA/XSpKlSM2PyTS2g==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} @@ -603,14 +603,14 @@ packages: '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - '@changesets/parse@0.4.2': - resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==} + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} '@changesets/pre@2.0.2': resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - '@changesets/read@0.6.6': - resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==} + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} '@changesets/should-skip-package@0.1.2': resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} @@ -639,73 +639,73 @@ packages: '@chevrotain/utils@11.1.1': resolution: {integrity: sha512-71eTYMzYXYSFPrbg/ZwftSaSDld7UYlS8OQa3lNnn9jzNtpFbaReRRyghzqS7rI3CDaorqpPJJcXGHK+FE1TVQ==} - '@commitlint/cli@20.4.2': - resolution: {integrity: sha512-YjYSX2yj/WsVoxh9mNiymfFS2ADbg2EK4+1WAsMuckwKMCqJ5PDG0CJU/8GvmHWcv4VRB2V02KqSiecRksWqZQ==} + '@commitlint/cli@20.4.3': + resolution: {integrity: sha512-Z37EMoDT7+Upg500vlr/vZrgRsb6Xc5JAA3Tv7BYbobnN/ZpqUeZnSLggBg2+1O+NptRDtyujr2DD1CPV2qwhA==} engines: {node: '>=v18'} hasBin: true - '@commitlint/config-conventional@20.4.2': - resolution: {integrity: sha512-rwkTF55q7Q+6dpSKUmJoScV0f3EpDlWKw2UPzklkLS4o5krMN1tPWAVOgHRtyUTMneIapLeQwaCjn44Td6OzBQ==} + '@commitlint/config-conventional@20.4.3': + resolution: {integrity: sha512-9RtLySbYQAs8yEqWEqhSZo9nYhbm57jx7qHXtgRmv/nmeQIjjMcwf6Dl+y5UZcGWgWx435TAYBURONaJIuCjWg==} engines: {node: '>=v18'} - '@commitlint/config-validator@20.4.0': - resolution: {integrity: sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w==} + '@commitlint/config-validator@20.4.3': + resolution: {integrity: sha512-jCZpZFkcSL3ZEdL5zgUzFRdytv3xPo8iukTe9VA+QGus/BGhpp1xXSVu2B006GLLb2gYUAEGEqv64kTlpZNgmA==} engines: {node: '>=v18'} - '@commitlint/ensure@20.4.1': - resolution: {integrity: sha512-WLQqaFx1pBooiVvBrA1YfJNFqZF8wS/YGOtr5RzApDbV9tQ52qT5VkTsY65hFTnXhW8PcDfZLaknfJTmPejmlw==} + '@commitlint/ensure@20.4.3': + resolution: {integrity: sha512-WcXGKBNn0wBKpX8VlXgxqedyrLxedIlLBCMvdamLnJFEbUGJ9JZmBVx4vhLV3ZyA8uONGOb+CzW0Y9HDbQ+ONQ==} engines: {node: '>=v18'} '@commitlint/execute-rule@20.0.0': resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} engines: {node: '>=v18'} - '@commitlint/format@20.4.0': - resolution: {integrity: sha512-i3ki3WR0rgolFVX6r64poBHXM1t8qlFel1G1eCBvVgntE3fCJitmzSvH5JD/KVJN/snz6TfaX2CLdON7+s4WVQ==} + '@commitlint/format@20.4.3': + resolution: {integrity: sha512-UDJVErjLbNghop6j111rsHJYGw6MjCKAi95K0GT2yf4eeiDHy3JDRLWYWEjIaFgO+r+dQSkuqgJ1CdMTtrvHsA==} engines: {node: '>=v18'} - '@commitlint/is-ignored@20.4.1': - resolution: {integrity: sha512-In5EO4JR1lNsAv1oOBBO24V9ND1IqdAJDKZiEpdfjDl2HMasAcT7oA+5BKONv1pRoLG380DGPE2W2RIcUwdgLA==} + '@commitlint/is-ignored@20.4.3': + resolution: {integrity: sha512-W5VQKZ7fdJ1X3Tko+h87YZaqRMGN1KvQKXyCM8xFdxzMIf1KCZgN4uLz3osLB1zsFcVS4ZswHY64LI26/9ACag==} engines: {node: '>=v18'} - '@commitlint/lint@20.4.2': - resolution: {integrity: sha512-buquzNRtFng6xjXvBU1abY/WPEEjCgUipNQrNmIWe8QuJ6LWLtei/LDBAzEe5ASm45+Q9L2Xi3/GVvlj50GAug==} + '@commitlint/lint@20.4.3': + resolution: {integrity: sha512-CYOXL23e+nRKij81+d0+dymtIi7Owl9QzvblJYbEfInON/4MaETNSLFDI74LDu+YJ0ML5HZyw9Vhp9QpckwQ0A==} engines: {node: '>=v18'} - '@commitlint/load@20.4.0': - resolution: {integrity: sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A==} + '@commitlint/load@20.4.3': + resolution: {integrity: sha512-3cdJOUVP+VcgHa7bhJoWS+Z8mBNXB5aLWMBu7Q7uX8PSeWDzdbrBlR33J1MGGf7r1PZDp+mPPiFktk031PgdRw==} engines: {node: '>=v18'} - '@commitlint/message@20.4.0': - resolution: {integrity: sha512-B5lGtvHgiLAIsK5nLINzVW0bN5hXv+EW35sKhYHE8F7V9Uz1fR4tx3wt7mobA5UNhZKUNgB/+ldVMQE6IHZRyA==} + '@commitlint/message@20.4.3': + resolution: {integrity: sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==} engines: {node: '>=v18'} - '@commitlint/parse@20.4.1': - resolution: {integrity: sha512-XNtZjeRcFuAfUnhYrCY02+mpxwY4OmnvD3ETbVPs25xJFFz1nRo/25nHj+5eM+zTeRFvWFwD4GXWU2JEtoK1/w==} + '@commitlint/parse@20.4.3': + resolution: {integrity: sha512-hzC3JCo3zs3VkQ833KnGVuWjWIzR72BWZWjQM7tY/7dfKreKAm7fEsy71tIFCRtxf2RtMP2d3RLF1U9yhFSccA==} engines: {node: '>=v18'} - '@commitlint/read@20.4.0': - resolution: {integrity: sha512-QfpFn6/I240ySEGv7YWqho4vxqtPpx40FS7kZZDjUJ+eHxu3azfhy7fFb5XzfTqVNp1hNoI3tEmiEPbDB44+cg==} + '@commitlint/read@20.4.3': + resolution: {integrity: sha512-j42OWv3L31WfnP8WquVjHZRt03w50Y/gEE8FAyih7GQTrIv2+pZ6VZ6pWLD/ml/3PO+RV2SPtRtTp/MvlTb8rQ==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@20.4.0': - resolution: {integrity: sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g==} + '@commitlint/resolve-extends@20.4.3': + resolution: {integrity: sha512-QucxcOy+00FhS9s4Uy0OyS5HeUV+hbC6OLqkTSIm6fwMdKva+OEavaCDuLtgd9akZZlsUo//XzSmPP3sLKBPog==} engines: {node: '>=v18'} - '@commitlint/rules@20.4.2': - resolution: {integrity: sha512-oz83pnp5Yq6uwwTAabuVQPNlPfeD2Y5ZjMb7Wx8FSUlu4sLYJjbBWt8031Z0osCFPfHzAwSYrjnfDFKtuSMdKg==} + '@commitlint/rules@20.4.3': + resolution: {integrity: sha512-Yuosd7Grn5qiT7FovngXLyRXTMUbj9PYiSkvUgWK1B5a7+ZvrbWDS7epeUapYNYatCy/KTpPFPbgLUdE+MUrBg==} engines: {node: '>=v18'} '@commitlint/to-lines@20.0.0': resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==} engines: {node: '>=v18'} - '@commitlint/top-level@20.4.0': - resolution: {integrity: sha512-NDzq8Q6jmFaIIBC/GG6n1OQEaHdmaAAYdrZRlMgW6glYWGZ+IeuXmiymDvQNXPc82mVxq2KiE3RVpcs+1OeDeA==} + '@commitlint/top-level@20.4.3': + resolution: {integrity: sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==} engines: {node: '>=v18'} - '@commitlint/types@20.4.0': - resolution: {integrity: sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==} + '@commitlint/types@20.4.3': + resolution: {integrity: sha512-51OWa1Gi6ODOasPmfJPq6js4pZoomima4XLZZCrkldaH2V5Nb3bVhNXPeT6XV0gubbainSpTw4zi68NqAeCNCg==} engines: {node: '>=v18'} '@cspotcode/source-map-support@0.8.1': @@ -1232,8 +1232,8 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@2.0.2': - resolution: {integrity: sha512-pR1DoD0h3HfF675QZx0xsyrsU8q70Z/plx7880NOhS02NuWLgBCOMDL787nUeQ7EWLkxv3bPQJaarjcPQb2Dwg==} + '@eslint/compat@2.0.3': + resolution: {integrity: sha512-SjIJhGigp8hmd1YGIBwh7Ovri7Kisl42GYFjrOyHhtfYGGoLW6teYi/5p8W50KSsawUPpuLOSmsq1bD0NGQLBw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: ^8.40 || 9 || 10 @@ -1253,8 +1253,8 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@1.1.0': - resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==} + '@eslint/core@1.1.1': + resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/eslintrc@3.3.4': @@ -1297,8 +1297,8 @@ packages: '@formatjs/intl-localematcher@0.6.1': resolution: {integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==} - '@gradio/atoms@0.22.0': - resolution: {integrity: sha512-t/3ZuwiaGZrffYRN3diX6nv6XG2bXQUINNoniMjOlYnT9Ili751Q1BUwOgwZ3UgRdkiG9B8N1Xoe+d29lUVwRQ==} + '@gradio/atoms@0.22.2': + resolution: {integrity: sha512-rafZ8f1PO6EIOE9SSjuzBRAThwNZvU+2sYCwUU35I1rhYq/4JEFV4Yaq3SlIyh3x3UHgnWEqny6LkBvfltPFIw==} peerDependencies: svelte: ^5.48.0 @@ -1325,8 +1325,8 @@ packages: '@gradio/sanitize@0.3.0': resolution: {integrity: sha512-NYw9HZaI12UKOitYToRibOsD4KaMRbdaBeGszB0wKTtknk02qry6RbQi6mkBSv8ynl0/mSsGFmAQoKpVju1W/A==} - '@gradio/statustracker@0.12.4': - resolution: {integrity: sha512-nrygjZBob7X803ILZmvLpWo/8tUXdXEihUMSUSNZ9jPELAG8tLqHeBg2XfDyfwcDVm715GLDUnaNHdwCDr770Q==} + '@gradio/statustracker@0.12.5': + resolution: {integrity: sha512-TcDDjFo/0zOMNWkvMcS9k6Fo+2dEaC7vXcFYgFR+yes038z/D4zfp+m+3+l8aexe+Zz8QlZhRcpSsAtZdJA0HA==} peerDependencies: svelte: ^5.48.0 @@ -1338,6 +1338,9 @@ packages: '@gradio/utils@0.11.3': resolution: {integrity: sha512-k1X6HXcoOycvBHsXamCyiN21v40I88FjTgz1TsVF5Hb/vJoA1InHjT+Uo6vnt+aJ8UGtxjUMTBVFR/GOcgXB/Q==} + '@gradio/utils@0.12.0': + resolution: {integrity: sha512-twy9fxEikjqxgtP3fk8voIDdey3nYFpJfmayDU7/IGn3C35nk+kL4dsJfEPbQ99BXmRgBecurSJEduOFptOCCQ==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1642,8 +1645,8 @@ packages: react: '>=18.0.0' react-dom: '>=18.0.0' - '@rc-component/color-picker@3.1.0': - resolution: {integrity: sha512-o7Vavj7yyfVxFmeynXf0fCHVlC0UTE9al74c6nYuLck+gjuVdQNWSVXR8Efq/mmWFy7891SCOsfaPq6Eqe1s/g==} + '@rc-component/color-picker@3.1.1': + resolution: {integrity: sha512-OHaCHLHszCegdXmIq2ZRIZBN/EtpT6Wm8SG/gpzLATHbVKc/avvuKi+zlOuk05FTWvgaMmpxAko44uRJ3M+2pg==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -1672,8 +1675,8 @@ packages: react: '>=16.11.0' react-dom: '>=16.11.0' - '@rc-component/form@1.6.2': - resolution: {integrity: sha512-OgIn2RAoaSBqaIgzJf/X6iflIa9LpTozci1lagLBdURDFhGA370v0+T0tXxOi8YShMjTha531sFhwtnrv+EJaQ==} + '@rc-component/form@1.7.1': + resolution: {integrity: sha512-Uhw0FPvJ+Ko4xBxhvziqmqzIuO0YvVBzVyFGNAI9fMCz4r4DfrYK6PRIN6CkFqM0vdAX9sr4JGA1/h/VzpA1cA==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' @@ -1804,8 +1807,8 @@ packages: react: '>=16.0.0' react-dom: '>=16.0.0' - '@rc-component/select@1.6.12': - resolution: {integrity: sha512-jYXAglYdOb54BrpWAcjjhdBP16NyCv/HbEaWFMbEHZQAJVmGHPAtmBqbFuPPuvInAVsIwLbCj4Agag9udOamiQ==} + '@rc-component/select@1.6.14': + resolution: {integrity: sha512-T1IWeLlSas7Z/igZtPtJ/bweCxMMkXIGKQBtnigK+I/n1AVNjCs+ZdL3Fj42mq3uqm4sd1uzeQLZkdCqR26ADw==} engines: {node: '>=8.x'} peerDependencies: react: '*' @@ -1912,8 +1915,8 @@ packages: '@rolldown/pluginutils@1.0.0-rc.2': resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} - '@rollup/plugin-sucrase@5.0.2': - resolution: {integrity: sha512-4MhIVH9Dy2Hwose1/x5QMs0XF7yn9jDd/yozHqzdIrMWIolgFpGnrnVhQkqTaK1RALY/fpyrEKmwH/04vr1THA==} + '@rollup/plugin-sucrase@5.1.0': + resolution: {integrity: sha512-/S4cJnfnjmaH0RqjvZtKOCx8WRnL14f3+tIieL5Ty0YkRpUPW2S/tgHCplWsHEmuZAWYoPJ4KN5eIxWtQw95Qw==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.53.1||^3.0.0||^4.0.0 @@ -1949,6 +1952,11 @@ packages: cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.53.3': resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} cpu: [arm64] @@ -1959,6 +1967,11 @@ packages: cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.53.3': resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} cpu: [arm64] @@ -1969,6 +1982,11 @@ packages: cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.53.3': resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} cpu: [x64] @@ -1979,6 +1997,11 @@ packages: cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + '@rollup/rollup-freebsd-arm64@4.53.3': resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} cpu: [arm64] @@ -1989,6 +2012,11 @@ packages: cpu: [arm64] os: [freebsd] + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.53.3': resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} cpu: [x64] @@ -1999,6 +2027,11 @@ packages: cpu: [x64] os: [freebsd] + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} cpu: [arm] @@ -2011,6 +2044,12 @@ packages: os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm-musleabihf@4.53.3': resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} cpu: [arm] @@ -2023,6 +2062,12 @@ packages: os: [linux] libc: [musl] + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-arm64-gnu@4.53.3': resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} cpu: [arm64] @@ -2035,6 +2080,12 @@ packages: os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm64-musl@4.53.3': resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} cpu: [arm64] @@ -2047,6 +2098,12 @@ packages: os: [linux] libc: [musl] + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-loong64-gnu@4.53.3': resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} cpu: [loong64] @@ -2059,12 +2116,24 @@ packages: os: [linux] libc: [glibc] + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-loong64-musl@4.57.1': resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} cpu: [loong64] os: [linux] libc: [musl] + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-ppc64-gnu@4.53.3': resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} cpu: [ppc64] @@ -2077,12 +2146,24 @@ packages: os: [linux] libc: [glibc] + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-ppc64-musl@4.57.1': resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} cpu: [ppc64] os: [linux] libc: [musl] + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-riscv64-gnu@4.53.3': resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} cpu: [riscv64] @@ -2095,6 +2176,12 @@ packages: os: [linux] libc: [glibc] + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-riscv64-musl@4.53.3': resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} cpu: [riscv64] @@ -2107,6 +2194,12 @@ packages: os: [linux] libc: [musl] + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-s390x-gnu@4.53.3': resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} cpu: [s390x] @@ -2119,6 +2212,12 @@ packages: os: [linux] libc: [glibc] + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.53.3': resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} cpu: [x64] @@ -2131,6 +2230,12 @@ packages: os: [linux] libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-musl@4.53.3': resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} cpu: [x64] @@ -2143,11 +2248,22 @@ packages: os: [linux] libc: [musl] + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + libc: [musl] + '@rollup/rollup-openbsd-x64@4.57.1': resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} cpu: [x64] os: [openbsd] + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + '@rollup/rollup-openharmony-arm64@4.53.3': resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} cpu: [arm64] @@ -2158,6 +2274,11 @@ packages: cpu: [arm64] os: [openharmony] + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.53.3': resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} cpu: [arm64] @@ -2168,6 +2289,11 @@ packages: cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.53.3': resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} cpu: [ia32] @@ -2178,6 +2304,11 @@ packages: cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-gnu@4.53.3': resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} cpu: [x64] @@ -2188,6 +2319,11 @@ packages: cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.53.3': resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} cpu: [x64] @@ -2198,6 +2334,11 @@ packages: cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -2223,6 +2364,10 @@ packages: '@rushstack/ts-command-line@5.0.2': resolution: {integrity: sha512-+AkJDbu1GFMPIU8Sb7TLVXDv/Q7Mkvx+wAjEl8XiXVVq+p1FmWW6M3LYpJMmoHNckSofeMecgWg5lfMwNAAsEQ==} + '@simple-libs/stream-utils@1.2.0': + resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} + engines: {node: '>=18'} + '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} @@ -2498,8 +2643,8 @@ packages: '@types/node@18.19.130': resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} - '@types/node@25.3.1': - resolution: {integrity: sha512-hj9YIJimBCipHVfHKRMnvmHg+wfhKc0o4mTtXh9pKBjC8TLJzz0nzGmLi5UJsYAUgSvXFHgb0V2oY10DUFtImw==} + '@types/node@25.3.5': + resolution: {integrity: sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==} '@types/prismjs@1.26.5': resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} @@ -2515,8 +2660,8 @@ packages: '@types/react@19.2.14': resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} - '@types/sanitize-html@2.16.0': - resolution: {integrity: sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==} + '@types/sanitize-html@2.16.1': + resolution: {integrity: sha512-n9wjs8bCOTyN/ynwD8s/nTcTreIHB1vf31vhLMGqUPNHaweKC4/fAl4Dj+hUlCTKYgm4P3k83fmiFfzkZ6sgMA==} '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -2767,8 +2912,8 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - ansi-escapes@7.2.0: - resolution: {integrity: sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==} + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} engines: {node: '>=18'} ansi-regex@4.1.1: @@ -2795,8 +2940,8 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - antd@6.3.1: - resolution: {integrity: sha512-8pRjvxitZFyrYAtgwml93Km7fCXjw9IeqlmzpIsusRsmO3eWFVrOMum6+0TsGCtR/WrXVnPwfsgrFg3ChzGCeA==} + antd@6.3.2: + resolution: {integrity: sha512-IlMoqaXlq5Bgxi0ANERhAzmDREYyGwr/U7MCVihaUQbE/ZOB3r4ArakUxjA1ULYNDA6K00dawSrB8aalGnZlLA==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' @@ -3126,10 +3271,6 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - class-utils@0.3.6: resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} engines: {node: '>=0.10.0'} @@ -3145,8 +3286,8 @@ packages: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} - cli-truncate@5.1.1: - resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==} + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} engines: {node: '>=20'} cliui@8.0.1: @@ -3195,8 +3336,8 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@14.0.2: - resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} commander@2.20.3: @@ -3236,16 +3377,16 @@ packages: constantinople@4.0.1: resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} - conventional-changelog-angular@8.1.0: - resolution: {integrity: sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==} + conventional-changelog-angular@8.3.0: + resolution: {integrity: sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==} engines: {node: '>=18'} - conventional-changelog-conventionalcommits@9.1.0: - resolution: {integrity: sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA==} + conventional-changelog-conventionalcommits@9.3.0: + resolution: {integrity: sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==} engines: {node: '>=18'} - conventional-commits-parser@6.2.1: - resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} + conventional-commits-parser@6.3.0: + resolution: {integrity: sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==} engines: {node: '>=18'} hasBin: true @@ -3286,6 +3427,15 @@ packages: typescript: optional: true + cosmiconfig@9.0.1: + resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -3716,6 +3866,10 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -4040,8 +4194,8 @@ packages: peerDependencies: eslint: '>=5.0.0' - eslint-plugin-svelte@3.15.0: - resolution: {integrity: sha512-QKB7zqfuB8aChOfBTComgDptMf2yxiJx7FE04nneCmtQzgTHvY8UJkuh8J2Rz7KB9FFV9aTHX6r7rdYGvG8T9Q==} + eslint-plugin-svelte@3.15.1: + resolution: {integrity: sha512-Ao/LGKPFzz8jbLEqa7OMK6LUX/mJRcJbVbIaHKjdheirkwjA/cDLdY1NcIZYscRxrK4FDIOX6IepmXFnhQlDlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 @@ -4117,8 +4271,8 @@ packages: event-emitter@0.3.5: resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} execall@1.0.0: resolution: {integrity: sha512-/J0Q8CvOvlAdpvhfkD/WnTQ4H1eU0exze2nFGPj/RSC7jpQ0NkKe2r28T5eMkhEEs+fzepMZNy1kVRKNlC04nQ==} @@ -4284,8 +4438,8 @@ packages: resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} engines: {node: '>=0.10.0'} - fs-extra@11.3.3: - resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -4322,10 +4476,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.4.0: - resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} - engines: {node: '>=18'} - get-east-asian-width@1.5.0: resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} @@ -4362,6 +4512,7 @@ packages: git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} engines: {node: '>=16'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true github-slugger@2.0.0: @@ -4414,8 +4565,8 @@ packages: resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} - globals@17.3.0: - resolution: {integrity: sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==} + globals@17.4.0: + resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} engines: {node: '>=18'} globalthis@1.0.4: @@ -4545,6 +4696,9 @@ packages: resolution: {integrity: sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==} engines: {node: '>=20.10'} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + htmlparser2@3.10.1: resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} @@ -4588,8 +4742,8 @@ packages: immer@11.1.4: resolution: {integrity: sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==} - immutable@5.1.4: - resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} import-fresh@2.0.0: resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} @@ -4908,9 +5062,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isexe@3.1.2: - resolution: {integrity: sha512-mIcis6w+JiQf3P7t7mg/35GKB4T1FQsBOtMIvuKw4YErj5RjtbhcTd5/I30fmkmGMwvI0WlzSNN+27K0QCMkAw==} - engines: {node: '>=20'} + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} isobject@2.1.0: resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} @@ -5008,8 +5162,8 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} - katex@0.16.33: - resolution: {integrity: sha512-q3N5u+1sY9Bu7T4nlXoiRBXWfwSefNGoKeOwekV+gw0cAXQlz2Ww6BLcmBxVDeXBMUDQv6fK5bcNaJLxob3ZQA==} + katex@0.16.38: + resolution: {integrity: sha512-cjHooZUmIAUmDsHBN+1n8LaZdpmbj03LtYeYPyuYB7OuloiaeaV6N4LcfjcnHVzGWjVQmKrxxTrpDcmSzEZQwQ==} hasBin: true keyv@4.5.4: @@ -5154,8 +5308,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@16.2.7: - resolution: {integrity: sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==} + lint-staged@16.3.2: + resolution: {integrity: sha512-xKqhC2AeXLwiAHXguxBjuChoTTWFC6Pees0SHPwOpwlvI3BH7ZADFPddAdN3pgo3aiKgPUx/bxE78JfUnxQnlg==} engines: {node: '>=20.17'} hasBin: true @@ -5323,8 +5477,8 @@ packages: engines: {node: '>= 20'} hasBin: true - marked@17.0.3: - resolution: {integrity: sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A==} + marked@17.0.4: + resolution: {integrity: sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==} engines: {node: '>= 20'} hasBin: true @@ -5406,8 +5560,8 @@ packages: minimatch@3.1.4: resolution: {integrity: sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist-options@3.0.2: @@ -5417,10 +5571,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} @@ -5452,10 +5602,6 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nano-spawn@2.0.0: - resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==} - engines: {node: '>=20.17'} - nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -5753,11 +5899,6 @@ packages: engines: {node: '>=0.10'} hasBin: true - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} @@ -5926,8 +6067,8 @@ packages: resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} engines: {node: '>=6.0.0'} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -5942,16 +6083,16 @@ packages: resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} engines: {node: '>=6.0.0'} - prettier-plugin-packagejson@3.0.0: - resolution: {integrity: sha512-z8/QmPSqx/ANvvQMWJSkSq1+ihBXeuwDEYdjX3ZjRJ5Ty1k7vGbFQfhzk2eDe0rwS/TNyRjWK/qnjJEStAOtDw==} + prettier-plugin-packagejson@3.0.2: + resolution: {integrity: sha512-kmoj3hEynXwoHDo8ZhmWAIjRBoQWCDUVackiWfSDWdgD0rS3LGB61T9zoVbume/cotYdCoadUh4sqViAmXvpBQ==} peerDependencies: prettier: ^3 peerDependenciesMeta: prettier: optional: true - prettier-plugin-svelte@3.5.0: - resolution: {integrity: sha512-2lLO/7EupnjO/95t+XZesXs8Bf3nYLIDfCo270h5QWbj/vjLqmrQ1LiRk9LPggxSDsnVYfehamZNf+rgQYApZg==} + prettier-plugin-svelte@3.5.1: + resolution: {integrity: sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==} peerDependencies: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 @@ -6050,8 +6191,8 @@ packages: react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react-syntax-highlighter@16.1.0: - resolution: {integrity: sha512-E40/hBiP5rCNwkeBN1vRP+xow1X0pndinO+z3h7HLsHyjztbyjfzNWNKuAsJj+7DLam9iT4AaaOZnueCU+Nplg==} + react-syntax-highlighter@16.1.1: + resolution: {integrity: sha512-PjVawBGy80C6YbC5DDZJeUjBmC7skaoEUdvfFQediQHgCL7aKyVHe57SaJGfQsloGDac+gCpTfRdtxzWWKmCXA==} engines: {node: '>= 16.20.2'} peerDependencies: react: '>= 0.14.0' @@ -6199,6 +6340,11 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + roughjs@4.6.6: resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} @@ -6364,8 +6510,13 @@ packages: resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} - smob@1.5.0: - resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + + smob@1.6.1: + resolution: {integrity: sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==} + engines: {node: '>=20.0.0'} snapdragon-node@2.1.1: resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} @@ -6382,8 +6533,8 @@ packages: sort-object-keys@2.1.0: resolution: {integrity: sha512-SOiEnthkJKPv2L6ec6HMwhUcN0/lppkeYuN1x63PbyPRrgSPIuBJCiYxYyvWRTtjMlOi14vQUCGUJqS6PLVm8g==} - sort-package-json@3.6.0: - resolution: {integrity: sha512-fyJsPLhWvY7u2KsKPZn1PixbXp+1m7V8NWqU8CvgFRbMEX41Ffw1kD8n0CfJiGoaSfoAvbrqRRl/DcHO8omQOQ==} + sort-package-json@3.6.1: + resolution: {integrity: sha512-Chgejw1+10p2D0U2tB7au1lHtz6TkFnxmvZktyBCRyV0GgmF6nl1IxXxAsPtJVsUyg/fo+BfCMAVVFUVRkAHrQ==} engines: {node: '>=20'} hasBin: true @@ -6488,10 +6639,6 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string-width@8.1.0: - resolution: {integrity: sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==} - engines: {node: '>=20'} - string-width@8.2.0: resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} engines: {node: '>=20'} @@ -6541,6 +6688,10 @@ packages: resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -6652,17 +6803,17 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.4.3: - resolution: {integrity: sha512-4HtdEv2hOoLCEsSXI+RDELk9okP/4sImWa7X02OjMFFOWeSdFF3NFy3vqpw0z+eH9C88J9vxZfUXz/Uv2A1ANw==} + svelte-check@4.4.5: + resolution: {integrity: sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' - svelte-eslint-parser@1.5.1: - resolution: {integrity: sha512-UbY7DYoDg+x4AKLUcX5xWuEWylgmm8ZD2Z89YT/AK6Wm/ckeMTnOMwr6AVC99znXbRC26xzWEPhSgmB62E07Gg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.30.2} + svelte-eslint-parser@1.6.0: + resolution: {integrity: sha512-qoB1ehychT6OxEtQAqc/guSqLS20SlA53Uijl7x375s8nlUT0lb9ol/gzraEEatQwsyPTJo87s2CmKL9Xab+Uw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.30.3} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: @@ -6713,8 +6864,12 @@ packages: typescript: optional: true - svelte@5.53.5: - resolution: {integrity: sha512-YkqERnF05g8KLdDZwZrF8/i1eSbj6Eoat8Jjr2IfruZz9StLuBqo8sfCSzjosNKd+ZrQ8DkKZDjpO5y3ht1Pow==} + svelte@5.48.0: + resolution: {integrity: sha512-+NUe82VoFP1RQViZI/esojx70eazGF4u0O/9ucqZ4rPcOZD+n5EVp17uYsqwdzjUjZyTpGKunHbDziW6AIAVkQ==} + engines: {node: '>=18'} + + svelte@5.53.7: + resolution: {integrity: sha512-uxck1KI7JWtlfP3H6HOWi/94soAl23jsGJkBzN2BAWcQng0+lTrRNhxActFqORgnO9BHVd1hKJhG+ljRuIUWfQ==} engines: {node: '>=18'} svg-tags@1.0.0: @@ -7091,10 +7246,10 @@ packages: yaml: optional: true - vitefu@1.1.1: - resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + vitefu@1.1.2: + resolution: {integrity: sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==} peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0 peerDependenciesMeta: vite: optional: true @@ -7223,8 +7378,8 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} hasBin: true @@ -7305,15 +7460,15 @@ snapshots: dependencies: '@ant-design/fast-color': 3.0.1 - '@ant-design/cssinjs-utils@2.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ant-design/cssinjs-utils@2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@ant-design/cssinjs': 2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/runtime': 7.28.6 '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@ant-design/cssinjs@2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ant-design/cssinjs@2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.28.6 '@emotion/hash': 0.8.0 @@ -7349,24 +7504,24 @@ snapshots: react-dom: 19.2.4(react@19.2.4) throttle-debounce: 5.0.2 - '@ant-design/x@2.2.2(antd@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ant-design/x@2.3.0(antd@6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/colors': 8.0.1 - '@ant-design/cssinjs': 2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@ant-design/cssinjs-utils': 2.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ant-design/cssinjs-utils': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/fast-color': 3.0.1 '@ant-design/icons': 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/runtime': 7.28.6 '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - antd: 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + antd: 6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 lodash.throttle: 4.1.1 mermaid: 11.12.3 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-syntax-highlighter: 16.1.0(react@19.2.4) + react-syntax-highlighter: 16.1.1(react@19.2.4) '@antfu/install-pkg@1.1.0': dependencies: @@ -7607,9 +7762,9 @@ snapshots: hashery: 1.5.0 keyv: 5.6.0 - '@changesets/apply-release-plan@7.0.14': + '@changesets/apply-release-plan@7.1.0': dependencies: - '@changesets/config': 3.1.2 + '@changesets/config': 3.1.3 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.4 '@changesets/should-skip-package': 0.1.2 @@ -7636,30 +7791,28 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.29.8(@types/node@25.3.1)': + '@changesets/cli@2.30.0(@types/node@25.3.5)': dependencies: - '@changesets/apply-release-plan': 7.0.14 + '@changesets/apply-release-plan': 7.1.0 '@changesets/assemble-release-plan': 6.0.9 '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.2 + '@changesets/config': 3.1.3 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.14 + '@changesets/get-release-plan': 4.0.15 '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.6 + '@changesets/read': 0.6.7 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.3.1) + '@inquirer/external-editor': 1.0.3(@types/node@25.3.5) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 - ci-info: 3.9.0 enquirer: 2.4.1 fs-extra: 7.0.1 mri: 1.2.0 - p-limit: 2.3.0 package-manager-detector: 0.2.11 picocolors: 1.1.1 resolve-from: 5.0.0 @@ -7669,11 +7822,12 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@changesets/config@3.1.2': + '@changesets/config@3.1.3': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 @@ -7690,19 +7844,19 @@ snapshots: picocolors: 1.1.1 semver: 7.7.4 - '@changesets/get-github-info@0.7.0': + '@changesets/get-github-info@0.8.0': dependencies: dataloader: 1.4.0 node-fetch: 2.7.0 transitivePeerDependencies: - encoding - '@changesets/get-release-plan@4.0.14': + '@changesets/get-release-plan@4.0.15': dependencies: '@changesets/assemble-release-plan': 6.0.9 - '@changesets/config': 3.1.2 + '@changesets/config': 3.1.3 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.6 + '@changesets/read': 0.6.7 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 @@ -7720,7 +7874,7 @@ snapshots: dependencies: picocolors: 1.1.1 - '@changesets/parse@0.4.2': + '@changesets/parse@0.4.3': dependencies: '@changesets/types': 6.1.0 js-yaml: 4.1.1 @@ -7732,11 +7886,11 @@ snapshots: '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.6': + '@changesets/read@0.6.7': dependencies: '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.2 + '@changesets/parse': 0.4.3 '@changesets/types': 6.1.0 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -7775,32 +7929,32 @@ snapshots: '@chevrotain/utils@11.1.1': {} - '@commitlint/cli@20.4.2(@types/node@25.3.1)(typescript@5.9.3)': + '@commitlint/cli@20.4.3(@types/node@25.3.5)(typescript@5.9.3)': dependencies: - '@commitlint/format': 20.4.0 - '@commitlint/lint': 20.4.2 - '@commitlint/load': 20.4.0(@types/node@25.3.1)(typescript@5.9.3) - '@commitlint/read': 20.4.0 - '@commitlint/types': 20.4.0 + '@commitlint/format': 20.4.3 + '@commitlint/lint': 20.4.3 + '@commitlint/load': 20.4.3(@types/node@25.3.5)(typescript@5.9.3) + '@commitlint/read': 20.4.3 + '@commitlint/types': 20.4.3 tinyexec: 1.0.2 yargs: 17.7.2 transitivePeerDependencies: - '@types/node' - typescript - '@commitlint/config-conventional@20.4.2': + '@commitlint/config-conventional@20.4.3': dependencies: - '@commitlint/types': 20.4.0 - conventional-changelog-conventionalcommits: 9.1.0 + '@commitlint/types': 20.4.3 + conventional-changelog-conventionalcommits: 9.3.0 - '@commitlint/config-validator@20.4.0': + '@commitlint/config-validator@20.4.3': dependencies: - '@commitlint/types': 20.4.0 + '@commitlint/types': 20.4.3 ajv: 8.18.0 - '@commitlint/ensure@20.4.1': + '@commitlint/ensure@20.4.3': dependencies: - '@commitlint/types': 20.4.0 + '@commitlint/types': 20.4.3 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 @@ -7809,31 +7963,31 @@ snapshots: '@commitlint/execute-rule@20.0.0': {} - '@commitlint/format@20.4.0': + '@commitlint/format@20.4.3': dependencies: - '@commitlint/types': 20.4.0 + '@commitlint/types': 20.4.3 picocolors: 1.1.1 - '@commitlint/is-ignored@20.4.1': + '@commitlint/is-ignored@20.4.3': dependencies: - '@commitlint/types': 20.4.0 + '@commitlint/types': 20.4.3 semver: 7.7.4 - '@commitlint/lint@20.4.2': + '@commitlint/lint@20.4.3': dependencies: - '@commitlint/is-ignored': 20.4.1 - '@commitlint/parse': 20.4.1 - '@commitlint/rules': 20.4.2 - '@commitlint/types': 20.4.0 + '@commitlint/is-ignored': 20.4.3 + '@commitlint/parse': 20.4.3 + '@commitlint/rules': 20.4.3 + '@commitlint/types': 20.4.3 - '@commitlint/load@20.4.0(@types/node@25.3.1)(typescript@5.9.3)': + '@commitlint/load@20.4.3(@types/node@25.3.5)(typescript@5.9.3)': dependencies: - '@commitlint/config-validator': 20.4.0 + '@commitlint/config-validator': 20.4.3 '@commitlint/execute-rule': 20.0.0 - '@commitlint/resolve-extends': 20.4.0 - '@commitlint/types': 20.4.0 - cosmiconfig: 9.0.0(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.2.0(@types/node@25.3.1)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) + '@commitlint/resolve-extends': 20.4.3 + '@commitlint/types': 20.4.3 + cosmiconfig: 9.0.1(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.2.0(@types/node@25.3.5)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) is-plain-obj: 4.1.0 lodash.mergewith: 4.6.2 picocolors: 1.1.1 @@ -7841,47 +7995,47 @@ snapshots: - '@types/node' - typescript - '@commitlint/message@20.4.0': {} + '@commitlint/message@20.4.3': {} - '@commitlint/parse@20.4.1': + '@commitlint/parse@20.4.3': dependencies: - '@commitlint/types': 20.4.0 - conventional-changelog-angular: 8.1.0 - conventional-commits-parser: 6.2.1 + '@commitlint/types': 20.4.3 + conventional-changelog-angular: 8.3.0 + conventional-commits-parser: 6.3.0 - '@commitlint/read@20.4.0': + '@commitlint/read@20.4.3': dependencies: - '@commitlint/top-level': 20.4.0 - '@commitlint/types': 20.4.0 + '@commitlint/top-level': 20.4.3 + '@commitlint/types': 20.4.3 git-raw-commits: 4.0.0 minimist: 1.2.8 tinyexec: 1.0.2 - '@commitlint/resolve-extends@20.4.0': + '@commitlint/resolve-extends@20.4.3': dependencies: - '@commitlint/config-validator': 20.4.0 - '@commitlint/types': 20.4.0 + '@commitlint/config-validator': 20.4.3 + '@commitlint/types': 20.4.3 global-directory: 4.0.1 import-meta-resolve: 4.2.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - '@commitlint/rules@20.4.2': + '@commitlint/rules@20.4.3': dependencies: - '@commitlint/ensure': 20.4.1 - '@commitlint/message': 20.4.0 + '@commitlint/ensure': 20.4.3 + '@commitlint/message': 20.4.3 '@commitlint/to-lines': 20.0.0 - '@commitlint/types': 20.4.0 + '@commitlint/types': 20.4.3 '@commitlint/to-lines@20.0.0': {} - '@commitlint/top-level@20.4.0': + '@commitlint/top-level@20.4.3': dependencies: escalade: 3.2.0 - '@commitlint/types@20.4.0': + '@commitlint/types@20.4.3': dependencies: - conventional-commits-parser: 6.2.1 + conventional-commits-parser: 6.3.0 picocolors: 1.1.1 '@cspotcode/source-map-support@0.8.1': @@ -8169,9 +8323,9 @@ snapshots: '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.0.2(eslint@9.39.3(jiti@2.6.1))': + '@eslint/compat@2.0.3(eslint@9.39.3(jiti@2.6.1))': dependencies: - '@eslint/core': 1.1.0 + '@eslint/core': 1.1.1 optionalDependencies: eslint: 9.39.3(jiti@2.6.1) @@ -8191,7 +8345,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@1.1.0': + '@eslint/core@1.1.1': dependencies: '@types/json-schema': 7.0.15 @@ -8248,41 +8402,41 @@ snapshots: dependencies: tslib: 2.8.1 - '@gradio/atoms@0.22.0(svelte@5.53.5)': + '@gradio/atoms@0.22.2(svelte@5.48.0)': dependencies: - '@gradio/icons': 0.15.1(svelte@5.53.5) - '@gradio/markdown-code': 0.6.1(svelte@5.53.5) - '@gradio/utils': 0.11.3(svelte@5.53.5) - svelte: 5.53.5 + '@gradio/icons': 0.15.1(svelte@5.48.0) + '@gradio/markdown-code': 0.6.1(svelte@5.48.0) + '@gradio/utils': 0.12.0(svelte@5.48.0) + svelte: 5.48.0 '@gradio/client@2.0.4': dependencies: fetch-event-stream: 0.1.6 - '@gradio/icons@0.15.1(svelte@5.53.5)': + '@gradio/icons@0.15.1(svelte@5.48.0)': dependencies: - svelte: 5.53.5 + svelte: 5.48.0 - '@gradio/markdown-code@0.6.1(svelte@5.53.5)': + '@gradio/markdown-code@0.6.1(svelte@5.48.0)': dependencies: '@gradio/sanitize': 0.3.0 '@types/katex': 0.16.8 '@types/prismjs': 1.26.5 github-slugger: 2.0.0 - katex: 0.16.33 + katex: 0.16.38 marked: 12.0.2 marked-gfm-heading-id: 3.2.0(marked@12.0.2) marked-highlight: 2.2.3(marked@12.0.2) mermaid: 11.12.3 prismjs: 1.30.0 - svelte: 5.53.5 + svelte: 5.48.0 - '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1))(postcss@8.5.6)(rollup@4.57.1)(svelte@5.53.5)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)': + '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.48.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': dependencies: '@originjs/vite-plugin-commonjs': 1.0.3 - '@rollup/plugin-sucrase': 5.0.2(rollup@4.57.1) - '@rollup/plugin-terser': 0.4.4(rollup@4.57.1) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.5)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) + '@rollup/plugin-sucrase': 5.1.0(rollup@4.59.0) + '@rollup/plugin-terser': 0.4.4(rollup@4.59.0) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@types/which': 3.0.4 coffeescript: 2.7.0 lightningcss: 1.31.1 @@ -8290,10 +8444,10 @@ snapshots: sass: 1.97.3 stylus: 0.64.0 sucrase: 3.35.1 - sugarss: 5.0.1(postcss@8.5.6) - svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1))(postcss@8.5.6)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(svelte@5.53.5)(typescript@5.9.3) + sugarss: 5.0.1(postcss@8.5.8) + svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.48.0)(typescript@5.9.3) typescript: 5.9.3 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) which: 5.0.0 yootils: 0.3.1 transitivePeerDependencies: @@ -8321,21 +8475,28 @@ snapshots: amuchina: 1.0.12 sanitize-html: 2.17.1 - '@gradio/statustracker@0.12.4(svelte@5.53.5)': + '@gradio/statustracker@0.12.5(svelte@5.48.0)': dependencies: - '@gradio/atoms': 0.22.0(svelte@5.53.5) - '@gradio/icons': 0.15.1(svelte@5.53.5) + '@gradio/atoms': 0.22.2(svelte@5.48.0) + '@gradio/icons': 0.15.1(svelte@5.48.0) '@gradio/sanitize': 0.2.0 - '@gradio/utils': 0.11.3(svelte@5.53.5) - svelte: 5.53.5 + '@gradio/utils': 0.12.0(svelte@5.48.0) + svelte: 5.48.0 - '@gradio/theme@0.6.1(svelte@5.53.5)': + '@gradio/theme@0.6.1(svelte@5.48.0)': dependencies: - svelte: 5.53.5 + svelte: 5.48.0 - '@gradio/utils@0.11.3(svelte@5.53.5)': + '@gradio/utils@0.11.3(svelte@5.48.0)': dependencies: - '@gradio/theme': 0.6.1(svelte@5.53.5) + '@gradio/theme': 0.6.1(svelte@5.48.0) + transitivePeerDependencies: + - svelte + + '@gradio/utils@0.12.0(svelte@5.48.0)': + dependencies: + '@gradio/theme': 0.6.1(svelte@5.48.0) + svelte-i18n: 4.0.1(svelte@5.48.0) transitivePeerDependencies: - svelte @@ -8358,12 +8519,12 @@ snapshots: '@iconify/types': 2.0.0 mlly: 1.8.0 - '@inquirer/external-editor@1.0.3(@types/node@25.3.1)': + '@inquirer/external-editor@1.0.3(@types/node@25.3.5)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 25.3.1 + '@types/node': 25.3.5 '@isaacs/balanced-match@4.0.1': optional: true @@ -8377,7 +8538,7 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 @@ -8454,24 +8615,24 @@ snapshots: dependencies: langium: 4.2.1 - '@microsoft/api-extractor-model@7.30.7(@types/node@25.3.1)': + '@microsoft/api-extractor-model@7.30.7(@types/node@25.3.5)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@25.3.1) + '@rushstack/node-core-library': 5.14.0(@types/node@25.3.5) transitivePeerDependencies: - '@types/node' optional: true - '@microsoft/api-extractor@7.52.10(@types/node@25.3.1)': + '@microsoft/api-extractor@7.52.10(@types/node@25.3.5)': dependencies: - '@microsoft/api-extractor-model': 7.30.7(@types/node@25.3.1) + '@microsoft/api-extractor-model': 7.30.7(@types/node@25.3.5) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@25.3.1) + '@rushstack/node-core-library': 5.14.0(@types/node@25.3.5) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.4(@types/node@25.3.1) - '@rushstack/ts-command-line': 5.0.2(@types/node@25.3.1) + '@rushstack/terminal': 0.15.4(@types/node@25.3.5) + '@rushstack/ts-command-line': 5.0.2(@types/node@25.3.5) lodash: 4.17.23 minimatch: 10.0.3 resolve: 1.22.11 @@ -8657,7 +8818,7 @@ snapshots: '@rc-component/cascader@1.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/select': 1.6.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/select': 1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/tree': 1.2.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -8680,7 +8841,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/color-picker@3.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/color-picker@3.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/fast-color': 3.0.1 '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -8720,7 +8881,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/form@1.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/form@1.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/async-validator': 5.1.0 '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -8868,7 +9029,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/select@1.6.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/select@1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -8948,7 +9109,7 @@ snapshots: '@rc-component/tree-select@1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/select': 1.6.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/select': 1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/tree': 1.2.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -9006,28 +9167,28 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.2': {} - '@rollup/plugin-sucrase@5.0.2(rollup@4.57.1)': + '@rollup/plugin-sucrase@5.1.0(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) sucrase: 3.35.1 optionalDependencies: - rollup: 4.57.1 + rollup: 4.59.0 - '@rollup/plugin-terser@0.4.4(rollup@4.57.1)': + '@rollup/plugin-terser@0.4.4(rollup@4.59.0)': dependencies: serialize-javascript: 6.0.2 - smob: 1.5.0 + smob: 1.6.1 terser: 5.46.0 optionalDependencies: - rollup: 4.57.1 + rollup: 4.59.0 - '@rollup/pluginutils@5.3.0(rollup@4.57.1)': + '@rollup/pluginutils@5.3.0(rollup@4.59.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.57.1 + rollup: 4.59.0 '@rollup/rollup-android-arm-eabi@4.53.3': optional: true @@ -9035,155 +9196,230 @@ snapshots: '@rollup/rollup-android-arm-eabi@4.57.1': optional: true + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + '@rollup/rollup-android-arm64@4.53.3': optional: true '@rollup/rollup-android-arm64@4.57.1': optional: true + '@rollup/rollup-android-arm64@4.59.0': + optional: true + '@rollup/rollup-darwin-arm64@4.53.3': optional: true '@rollup/rollup-darwin-arm64@4.57.1': optional: true + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + '@rollup/rollup-darwin-x64@4.53.3': optional: true '@rollup/rollup-darwin-x64@4.57.1': optional: true + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + '@rollup/rollup-freebsd-arm64@4.53.3': optional: true '@rollup/rollup-freebsd-arm64@4.57.1': optional: true + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + '@rollup/rollup-freebsd-x64@4.53.3': optional: true '@rollup/rollup-freebsd-x64@4.57.1': optional: true + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.57.1': optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.53.3': optional: true '@rollup/rollup-linux-arm-musleabihf@4.57.1': optional: true + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.53.3': optional: true '@rollup/rollup-linux-arm64-gnu@4.57.1': optional: true + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-arm64-musl@4.53.3': optional: true '@rollup/rollup-linux-arm64-musl@4.57.1': optional: true + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + '@rollup/rollup-linux-loong64-gnu@4.53.3': optional: true '@rollup/rollup-linux-loong64-gnu@4.57.1': optional: true + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-loong64-musl@4.57.1': optional: true + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + '@rollup/rollup-linux-ppc64-gnu@4.53.3': optional: true '@rollup/rollup-linux-ppc64-gnu@4.57.1': optional: true + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-ppc64-musl@4.57.1': optional: true + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.53.3': optional: true '@rollup/rollup-linux-riscv64-gnu@4.57.1': optional: true + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-riscv64-musl@4.53.3': optional: true '@rollup/rollup-linux-riscv64-musl@4.57.1': optional: true + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.53.3': optional: true '@rollup/rollup-linux-s390x-gnu@4.57.1': optional: true + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-x64-gnu@4.53.3': optional: true '@rollup/rollup-linux-x64-gnu@4.57.1': optional: true + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-x64-musl@4.53.3': optional: true '@rollup/rollup-linux-x64-musl@4.57.1': optional: true + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + '@rollup/rollup-openbsd-x64@4.57.1': optional: true + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + '@rollup/rollup-openharmony-arm64@4.53.3': optional: true '@rollup/rollup-openharmony-arm64@4.57.1': optional: true + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.53.3': optional: true '@rollup/rollup-win32-arm64-msvc@4.57.1': optional: true + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.53.3': optional: true '@rollup/rollup-win32-ia32-msvc@4.57.1': optional: true + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + '@rollup/rollup-win32-x64-gnu@4.53.3': optional: true '@rollup/rollup-win32-x64-gnu@4.57.1': optional: true + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true '@rollup/rollup-win32-x64-msvc@4.57.1': optional: true + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + '@rtsao/scc@1.1.0': {} - '@rushstack/node-core-library@5.14.0(@types/node@25.3.1)': + '@rushstack/node-core-library@5.14.0(@types/node@25.3.5)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) ajv-formats: 3.0.1(ajv@8.13.0) - fs-extra: 11.3.3 + fs-extra: 11.3.4 import-lazy: 4.0.0 jju: 1.4.0 resolve: 1.22.11 semver: 7.5.4 optionalDependencies: - '@types/node': 25.3.1 + '@types/node': 25.3.5 optional: true '@rushstack/rig-package@0.5.3': @@ -9192,17 +9428,17 @@ snapshots: strip-json-comments: 3.1.1 optional: true - '@rushstack/terminal@0.15.4(@types/node@25.3.1)': + '@rushstack/terminal@0.15.4(@types/node@25.3.5)': dependencies: - '@rushstack/node-core-library': 5.14.0(@types/node@25.3.1) + '@rushstack/node-core-library': 5.14.0(@types/node@25.3.5) supports-color: 8.1.1 optionalDependencies: - '@types/node': 25.3.1 + '@types/node': 25.3.5 optional: true - '@rushstack/ts-command-line@5.0.2(@types/node@25.3.1)': + '@rushstack/ts-command-line@5.0.2(@types/node@25.3.5)': dependencies: - '@rushstack/terminal': 0.15.4(@types/node@25.3.1) + '@rushstack/terminal': 0.15.4(@types/node@25.3.5) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -9210,28 +9446,30 @@ snapshots: - '@types/node' optional: true + '@simple-libs/stream-utils@1.2.0': {} + '@sindresorhus/merge-streams@4.0.0': {} '@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0)': dependencies: acorn: 8.16.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.5)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)))(svelte@5.53.5)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.5)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) obug: 2.1.1 - svelte: 5.53.5 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + svelte: 5.48.0 + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.5)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.5)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)))(svelte@5.53.5)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.53.5 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) - vitefu: 1.1.1(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) + svelte: 5.48.0 + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@swc/core-darwin-arm64@1.15.11': optional: true @@ -9468,7 +9706,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 25.3.1 + '@types/node': 25.3.5 '@types/hast@3.0.4': dependencies: @@ -9494,7 +9732,7 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@25.3.1': + '@types/node@25.3.5': dependencies: undici-types: 7.18.2 @@ -9510,11 +9748,12 @@ snapshots: dependencies: csstype: 3.2.3 - '@types/sanitize-html@2.16.0': + '@types/sanitize-html@2.16.1': dependencies: - htmlparser2: 8.0.2 + htmlparser2: 10.1.0 - '@types/trusted-types@2.0.7': {} + '@types/trusted-types@2.0.7': + optional: true '@types/unist@2.0.11': {} @@ -9526,7 +9765,7 @@ snapshots: '@types/vfile@3.0.2': dependencies: - '@types/node': 25.3.1 + '@types/node': 25.3.5 '@types/unist': 2.0.11 '@types/vfile-message': 2.0.0 @@ -9682,11 +9921,11 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.9.2': optional: true - '@vitejs/plugin-react-swc@4.2.3(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': + '@vitejs/plugin-react-swc@4.2.3(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.2 '@swc/core': 1.15.11 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@swc/helpers' @@ -9755,7 +9994,7 @@ snapshots: ansi-colors@4.1.3: {} - ansi-escapes@7.2.0: + ansi-escapes@7.3.0: dependencies: environment: 1.1.0 @@ -9775,11 +10014,11 @@ snapshots: ansi-styles@6.2.3: {} - antd@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + antd@6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@ant-design/colors': 8.0.1 - '@ant-design/cssinjs': 2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@ant-design/cssinjs-utils': 2.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ant-design/cssinjs-utils': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/fast-color': 3.0.1 '@ant-design/icons': 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/react-slick': 2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -9787,11 +10026,11 @@ snapshots: '@rc-component/cascader': 1.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/checkbox': 2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/collapse': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/color-picker': 3.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/color-picker': 3.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/dialog': 1.8.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/drawer': 1.4.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/dropdown': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/form': 1.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/form': 1.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/image': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/input': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/input-number': 1.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -9807,7 +10046,7 @@ snapshots: '@rc-component/rate': 1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/segmented': 1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/select': 1.6.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/select': 1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/slider': 1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/steps': 1.2.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/switch': 1.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -9842,7 +10081,8 @@ snapshots: argparse@2.0.1: {} - aria-query@5.3.1: {} + aria-query@5.3.1: + optional: true aria-query@5.3.2: {} @@ -10188,8 +10428,6 @@ snapshots: dependencies: readdirp: 4.1.2 - ci-info@3.9.0: {} - class-utils@0.3.6: dependencies: arr-union: 3.1.0 @@ -10211,10 +10449,10 @@ snapshots: dependencies: restore-cursor: 5.1.0 - cli-truncate@5.1.1: + cli-truncate@5.2.0: dependencies: - slice-ansi: 7.1.2 - string-width: 8.1.0 + slice-ansi: 8.0.0 + string-width: 8.2.0 cliui@8.0.1: dependencies: @@ -10256,7 +10494,7 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@14.0.2: {} + commander@14.0.3: {} commander@2.20.3: {} @@ -10286,16 +10524,17 @@ snapshots: '@babel/parser': 7.29.0 '@babel/types': 7.29.0 - conventional-changelog-angular@8.1.0: + conventional-changelog-angular@8.3.0: dependencies: compare-func: 2.0.0 - conventional-changelog-conventionalcommits@9.1.0: + conventional-changelog-conventionalcommits@9.3.0: dependencies: compare-func: 2.0.0 - conventional-commits-parser@6.2.1: + conventional-commits-parser@6.3.0: dependencies: + '@simple-libs/stream-utils': 1.2.0 meow: 13.2.0 convert-source-map@2.0.0: {} @@ -10314,10 +10553,10 @@ snapshots: dependencies: layout-base: 2.0.1 - cosmiconfig-typescript-loader@6.2.0(@types/node@25.3.1)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.2.0(@types/node@25.3.5)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 25.3.1 - cosmiconfig: 9.0.0(typescript@5.9.3) + '@types/node': 25.3.5 + cosmiconfig: 9.0.1(typescript@5.9.3) jiti: 2.6.1 typescript: 5.9.3 @@ -10337,6 +10576,15 @@ snapshots: optionalDependencies: typescript: 5.9.3 + cosmiconfig@9.0.1(typescript@5.9.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.9.3 + create-require@1.1.1: {} cross-spawn@6.0.6: @@ -10760,6 +11008,8 @@ snapshots: entities@4.5.0: {} + entities@7.0.1: {} + env-paths@2.2.1: {} environment@1.1.0: {} @@ -11275,7 +11525,7 @@ snapshots: dependencies: eslint: 9.39.3(jiti@2.6.1) - eslint-plugin-svelte@3.15.0(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.5)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.1)(typescript@5.9.3)): + eslint-plugin-svelte@3.15.1(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.7)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.5)(typescript@5.9.3)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) '@jridgewell/sourcemap-codec': 1.5.5 @@ -11283,13 +11533,13 @@ snapshots: esutils: 2.0.3 globals: 16.5.0 known-css-properties: 0.37.0 - postcss: 8.5.6 - postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.1)(typescript@5.9.3)) - postcss-safe-parser: 7.0.1(postcss@8.5.6) + postcss: 8.5.8 + postcss-load-config: 3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.5)(typescript@5.9.3)) + postcss-safe-parser: 7.0.1(postcss@8.5.8) semver: 7.7.4 - svelte-eslint-parser: 1.5.1(svelte@5.53.5) + svelte-eslint-parser: 1.6.0(svelte@5.53.7) optionalDependencies: - svelte: 5.53.5 + svelte: 5.53.7 transitivePeerDependencies: - ts-node @@ -11385,7 +11635,7 @@ snapshots: d: 1.0.2 es5-ext: 0.10.64 - eventemitter3@5.0.1: {} + eventemitter3@5.0.4: {} execall@1.0.0: dependencies: @@ -11574,7 +11824,7 @@ snapshots: dependencies: map-cache: 0.2.2 - fs-extra@11.3.3: + fs-extra@11.3.4: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 @@ -11615,8 +11865,6 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.4.0: {} - get-east-asian-width@1.5.0: {} get-intrinsic@1.3.0: @@ -11684,8 +11932,8 @@ snapshots: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 + minimatch: 9.0.9 + minipass: 7.1.3 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 @@ -11722,7 +11970,7 @@ snapshots: globals@16.5.0: {} - globals@17.3.0: {} + globals@17.4.0: {} globalthis@1.0.4: dependencies: @@ -11855,6 +12103,13 @@ snapshots: html-tags@5.1.0: {} + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + htmlparser2@3.10.1: dependencies: domelementtype: 1.3.1 @@ -11894,7 +12149,7 @@ snapshots: immer@11.1.4: {} - immutable@5.1.4: {} + immutable@5.1.5: {} import-fresh@2.0.0: dependencies: @@ -12060,7 +12315,7 @@ snapshots: is-fullwidth-code-point@5.1.0: dependencies: - get-east-asian-width: 1.4.0 + get-east-asian-width: 1.5.0 is-generator-function@1.1.0: dependencies: @@ -12179,7 +12434,7 @@ snapshots: isexe@2.0.0: {} - isexe@3.1.2: {} + isexe@3.1.5: {} isobject@2.1.0: dependencies: @@ -12277,7 +12532,7 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 - katex@0.16.33: + katex@0.16.38: dependencies: commander: 8.3.0 @@ -12399,21 +12654,20 @@ snapshots: lines-and-columns@1.2.4: {} - lint-staged@16.2.7: + lint-staged@16.3.2: dependencies: - commander: 14.0.2 + commander: 14.0.3 listr2: 9.0.5 micromatch: 4.0.8 - nano-spawn: 2.0.0 - pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.8.1 + tinyexec: 1.0.2 + yaml: 2.8.2 listr2@9.0.5: dependencies: - cli-truncate: 5.1.1 + cli-truncate: 5.2.0 colorette: 2.0.20 - eventemitter3: 5.0.1 + eventemitter3: 5.0.4 log-update: 6.1.0 rfdc: 1.4.1 wrap-ansi: 9.0.2 @@ -12473,10 +12727,10 @@ snapshots: log-update@6.1.0: dependencies: - ansi-escapes: 7.2.0 + ansi-escapes: 7.3.0 cli-cursor: 5.0.0 slice-ansi: 7.1.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi: 9.0.2 longest-streak@2.0.4: {} @@ -12543,18 +12797,18 @@ snapshots: github-slugger: 2.0.0 marked: 12.0.2 - marked-gfm-heading-id@4.1.3(marked@17.0.3): + marked-gfm-heading-id@4.1.3(marked@17.0.4): dependencies: github-slugger: 2.0.0 - marked: 17.0.3 + marked: 17.0.4 marked-highlight@2.2.3(marked@12.0.2): dependencies: marked: 12.0.2 - marked-highlight@2.2.3(marked@17.0.3): + marked-highlight@2.2.3(marked@17.0.4): dependencies: - marked: 17.0.3 + marked: 17.0.4 marked@12.0.2: {} @@ -12562,7 +12816,7 @@ snapshots: marked@16.4.2: {} - marked@17.0.3: {} + marked@17.0.4: {} math-intrinsics@1.1.0: {} @@ -12623,7 +12877,7 @@ snapshots: dagre-d3-es: 7.0.13 dayjs: 1.11.19 dompurify: 3.3.1 - katex: 0.16.33 + katex: 0.16.38 khroma: 2.1.0 lodash-es: 4.17.23 marked: 16.4.2 @@ -12677,7 +12931,7 @@ snapshots: dependencies: brace-expansion: 1.1.11 - minimatch@9.0.5: + minimatch@9.0.9: dependencies: brace-expansion: 2.0.2 @@ -12688,8 +12942,6 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} - minipass@7.1.3: {} mixin-deep@1.3.2: @@ -12725,8 +12977,6 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nano-spawn@2.0.0: {} - nanoid@3.3.11: {} nanomatch@1.2.13: @@ -12994,7 +13244,7 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 - minipass: 7.1.2 + minipass: 7.1.3 path-scurry@2.0.2: dependencies: @@ -13021,8 +13271,6 @@ snapshots: pidtree@0.3.1: {} - pidtree@0.6.0: {} - pify@3.0.0: {} pify@4.0.1: {} @@ -13046,17 +13294,17 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39): + postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): dependencies: htmlparser2: 3.10.1 postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) - postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39): + postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): dependencies: '@babel/core': 7.29.0 postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) transitivePeerDependencies: - supports-color @@ -13064,31 +13312,31 @@ snapshots: dependencies: postcss: 7.0.39 - postcss-less@6.0.0(postcss@8.5.6): + postcss-less@6.0.0(postcss@8.5.8): dependencies: - postcss: 8.5.6 + postcss: 8.5.8 - postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.1)(typescript@5.9.3)): + postcss-load-config@3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.5)(typescript@5.9.3)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.15.11)(@types/node@25.3.1)(typescript@5.9.3) + postcss: 8.5.8 + ts-node: 10.9.2(@swc/core@1.15.11)(@types/node@25.3.5)(typescript@5.9.3) - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1): + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.6.1 - postcss: 8.5.6 + postcss: 8.5.8 tsx: 4.21.0 - yaml: 2.8.1 + yaml: 2.8.2 - postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39): + postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): dependencies: postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) remark: 10.0.1 unist-util-find-all-after: 1.0.5 @@ -13107,9 +13355,9 @@ snapshots: dependencies: postcss: 7.0.39 - postcss-safe-parser@7.0.1(postcss@8.5.6): + postcss-safe-parser@7.0.1(postcss@8.5.8): dependencies: - postcss: 8.5.6 + postcss: 8.5.8 postcss-sass@0.3.5: dependencies: @@ -13120,9 +13368,9 @@ snapshots: dependencies: postcss: 7.0.39 - postcss-scss@4.0.9(postcss@8.5.6): + postcss-scss@4.0.9(postcss@8.5.8): dependencies: - postcss: 8.5.6 + postcss: 8.5.8 postcss-selector-parser@3.1.2: dependencies: @@ -13140,18 +13388,18 @@ snapshots: lodash: 4.17.21 postcss: 7.0.39 - postcss-sorting@9.1.0(postcss@8.5.6): + postcss-sorting@9.1.0(postcss@8.5.8): dependencies: - postcss: 8.5.6 + postcss: 8.5.8 - postcss-syntax@0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39): + postcss-syntax@0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39): dependencies: postcss: 7.0.39 optionalDependencies: - postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39) - postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39) + postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) + postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) postcss-less: 3.1.4 - postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39) + postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) postcss-scss: 2.1.1 postcss-value-parser@3.3.1: {} @@ -13163,7 +13411,7 @@ snapshots: picocolors: 0.2.1 source-map: 0.6.1 - postcss@8.5.6: + postcss@8.5.8: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -13179,16 +13427,16 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier-plugin-packagejson@3.0.0(prettier@3.8.1): + prettier-plugin-packagejson@3.0.2(prettier@3.8.1): dependencies: - sort-package-json: 3.6.0 + sort-package-json: 3.6.1 optionalDependencies: prettier: 3.8.1 - prettier-plugin-svelte@3.5.0(prettier@3.8.1)(svelte@5.53.5): + prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.48.0): dependencies: prettier: 3.8.1 - svelte: 5.53.5 + svelte: 5.48.0 prettier@2.8.8: {} @@ -13303,7 +13551,7 @@ snapshots: react-is@18.3.1: {} - react-syntax-highlighter@16.1.0(react@19.2.4): + react-syntax-highlighter@16.1.1(react@19.2.4): dependencies: '@babel/runtime': 7.28.6 highlight.js: 10.7.3 @@ -13538,6 +13786,38 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.57.1 fsevents: 2.3.3 + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + optional: true + roughjs@4.6.6: dependencies: hachure-fill: 0.5.2 @@ -13591,12 +13871,12 @@ snapshots: htmlparser2: 8.0.2 is-plain-object: 5.0.0 parse-srcset: 1.0.2 - postcss: 8.5.6 + postcss: 8.5.8 sass@1.97.3: dependencies: chokidar: 4.0.3 - immutable: 5.1.4 + immutable: 5.1.5 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.6 @@ -13724,7 +14004,12 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 - smob@1.5.0: {} + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + smob@1.6.1: {} snapdragon-node@2.1.1: dependencies: @@ -13751,7 +14036,7 @@ snapshots: sort-object-keys@2.1.0: {} - sort-package-json@3.6.0: + sort-package-json@3.6.1: dependencies: detect-indent: 7.0.2 detect-newline: 4.0.1 @@ -13851,18 +14136,13 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.2 - - string-width@8.1.0: - dependencies: - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 string-width@8.2.0: dependencies: @@ -13949,6 +14229,10 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + strip-bom@3.0.0: {} strip-indent@2.0.0: {} @@ -13986,8 +14270,8 @@ snapshots: stylelint-order@7.0.1(stylelint@17.4.0(typescript@5.9.3)): dependencies: - postcss: 8.5.6 - postcss-sorting: 9.1.0(postcss@8.5.6) + postcss: 8.5.8 + postcss-sorting: 9.1.0(postcss@8.5.8) stylelint: 17.4.0(typescript@5.9.3) stylelint-prettier@5.0.3(prettier@3.8.1)(stylelint@17.4.0(typescript@5.9.3)): @@ -14026,8 +14310,8 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.6 - postcss-safe-parser: 7.0.1(postcss@8.5.6) + postcss: 8.5.8 + postcss-safe-parser: 7.0.1(postcss@8.5.8) postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 string-width: 8.2.0 @@ -14066,10 +14350,10 @@ snapshots: normalize-selector: 0.2.0 pify: 4.0.1 postcss: 7.0.39 - postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39) - postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39) + postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) + postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) postcss-less: 3.1.4 - postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39) + postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) postcss-media-query-parser: 0.2.3 postcss-reporter: 6.0.1 postcss-resolve-nested-selector: 0.1.6 @@ -14077,7 +14361,7 @@ snapshots: postcss-sass: 0.3.5 postcss-scss: 2.1.1 postcss-selector-parser: 3.1.2 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.6))(postcss@8.5.6))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) postcss-value-parser: 3.3.1 resolve-from: 4.0.0 signal-exit: 3.0.7 @@ -14117,9 +14401,9 @@ snapshots: dependencies: postcss: 7.0.39 - sugarss@5.0.1(postcss@8.5.6): + sugarss@5.0.1(postcss@8.5.8): dependencies: - postcss: 8.5.6 + postcss: 8.5.8 supports-color@10.2.2: {} @@ -14143,31 +14427,31 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.4.3(picomatch@4.0.3)(svelte@5.53.5)(typescript@5.9.3): + svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.48.0)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.53.5 + svelte: 5.48.0 typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.5.1(svelte@5.53.5): + svelte-eslint-parser@1.6.0(svelte@5.53.7): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - postcss: 8.5.6 - postcss-scss: 4.0.9(postcss@8.5.6) + postcss: 8.5.8 + postcss-scss: 4.0.9(postcss@8.5.8) postcss-selector-parser: 7.1.1 semver: 7.7.4 optionalDependencies: - svelte: 5.53.5 + svelte: 5.53.7 - svelte-i18n@4.0.1(svelte@5.53.5): + svelte-i18n@4.0.1(svelte@5.48.0): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -14175,25 +14459,43 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.16 sade: 1.8.1 - svelte: 5.53.5 + svelte: 5.48.0 tiny-glob: 0.2.9 - svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1))(postcss@8.5.6)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(svelte@5.53.5)(typescript@5.9.3): + svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.48.0)(typescript@5.9.3): dependencies: - svelte: 5.53.5 + svelte: 5.48.0 optionalDependencies: '@babel/core': 7.29.0 coffeescript: 2.7.0 less: 4.5.1 - postcss: 8.5.6 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1) + postcss: 8.5.8 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) pug: 3.0.3 sass: 1.97.3 stylus: 0.64.0 - sugarss: 5.0.1(postcss@8.5.6) + sugarss: 5.0.1(postcss@8.5.8) typescript: 5.9.3 - svelte@5.53.5: + svelte@5.48.0: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@types/estree': 1.0.8 + acorn: 8.16.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.3 + esm-env: 1.2.2 + esrap: 2.2.3 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + + svelte@5.53.7: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -14211,6 +14513,7 @@ snapshots: locate-character: 3.0.0 magic-string: 0.30.21 zimmerframe: 1.1.4 + optional: true svg-tags@1.0.0: {} @@ -14238,7 +14541,7 @@ snapshots: terser@5.46.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.15.0 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -14338,14 +14641,14 @@ snapshots: optionalDependencies: '@swc/core': 1.15.11 - ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.1)(typescript@5.9.3): + ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.3.5)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 25.3.1 + '@types/node': 25.3.5 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -14368,7 +14671,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.3.1))(@swc/core@1.15.11)(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.1): + tsup@8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.3.5))(@swc/core@1.15.11)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): dependencies: bundle-require: 5.1.0(esbuild@0.27.0) cac: 6.7.14 @@ -14379,7 +14682,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1) + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) resolve-from: 5.0.0 rollup: 4.53.3 source-map: 0.7.6 @@ -14388,9 +14691,9 @@ snapshots: tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: - '@microsoft/api-extractor': 7.52.10(@types/node@25.3.1) + '@microsoft/api-extractor': 7.52.10(@types/node@25.3.5) '@swc/core': 1.15.11 - postcss: 8.5.6 + postcss: 8.5.8 typescript: 5.9.3 transitivePeerDependencies: - jiti @@ -14636,12 +14939,12 @@ snapshots: unist-util-stringify-position: 1.1.2 vfile-message: 1.1.1 - vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1): + vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - postcss: 8.5.6 + postcss: 8.5.8 rollup: 4.57.1 tinyglobby: 0.2.15 optionalDependencies: @@ -14652,14 +14955,14 @@ snapshots: lightningcss: 1.31.1 sass: 1.97.3 stylus: 0.64.0 - sugarss: 5.0.1(postcss@8.5.6) + sugarss: 5.0.1(postcss@8.5.8) terser: 5.46.0 tsx: 4.21.0 - yaml: 2.8.1 + yaml: 2.8.2 - vitefu@1.1.1(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)): + vitefu@1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): optionalDependencies: - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vm2@3.10.4: dependencies: @@ -14747,7 +15050,7 @@ snapshots: which@5.0.0: dependencies: - isexe: 3.1.2 + isexe: 3.1.5 with@7.0.2: dependencies: @@ -14768,13 +15071,13 @@ snapshots: dependencies: ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi@9.0.2: dependencies: ansi-styles: 6.2.3 string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrappy@1.0.2: {} @@ -14800,7 +15103,7 @@ snapshots: yaml@1.10.2: {} - yaml@2.8.1: {} + yaml@2.8.2: {} yargs-parser@10.1.0: dependencies: diff --git a/scripts/create-tag-n-release.ts b/scripts/create-tag-n-release.ts index aa6dc491..eb4066b2 100644 --- a/scripts/create-tag-n-release.ts +++ b/scripts/create-tag-n-release.ts @@ -1,8 +1,8 @@ import { exec } from '@actions/exec'; import { getOctokit } from '@actions/github'; import { getPackagesSync } from '@manypkg/get-packages'; -import fs from 'fs'; -import path from 'path'; +import fs from 'node:fs'; +import path from 'node:path'; const githubToken = process.env.GITHUB_TOKEN as string; const repo = process.env.REPO as string; diff --git a/tsconfig.json b/tsconfig.json index a639cbf7..39d8d478 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,10 @@ "baseUrl": "./frontend", "paths": { "@svelte-preprocess-react": ["svelte-preprocess-react/index.ts"], - "@svelte-preprocess-react/*": ["svelte-preprocess-react/*"], + "@svelte-preprocess-react/*": [ + "svelte-preprocess-react/*/index.ts", + "svelte-preprocess-react/*" + ], "@utils/*": ["utils/*"], "@globals/*": ["globals/*"] } From d9b3b6294b9cb79abbbcc3cd083f17bbbc985387 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Mon, 9 Mar 2026 20:10:13 +0800 Subject: [PATCH 05/31] refactor(wip): fix event handler --- frontend/antd/affix/Index.svelte | 5 +++-- frontend/antd/alert/Index.svelte | 3 ++- frontend/antd/alert/error-boundary/Index.svelte | 3 ++- frontend/antd/anchor/Index.svelte | 6 +++--- frontend/antd/anchor/item/Index.svelte | 9 +++++---- frontend/antd/auto-complete/Index.svelte | 7 ++++--- frontend/antd/auto-complete/option/Index.svelte | 7 ++++--- frontend/antd/avatar/Index.svelte | 5 +++-- frontend/antd/avatar/group/Index.svelte | 5 +++-- frontend/antd/badge/Index.svelte | 5 +++-- frontend/antd/badge/ribbon/Index.svelte | 5 +++-- frontend/antd/breadcrumb/Index.svelte | 7 ++++--- frontend/antd/breadcrumb/item/Index.svelte | 5 +++-- frontend/antd/button/Index.svelte | 4 ++-- frontend/antd/button/group/Index.svelte | 5 +++-- frontend/antd/calendar/Index.svelte | 7 ++++--- frontend/antd/card/Index.svelte | 7 ++++--- frontend/antd/card/grid/Index.svelte | 3 ++- frontend/antd/card/meta/Index.svelte | 3 ++- frontend/antd/carousel/Index.svelte | 5 +++-- frontend/antd/cascader/Index.svelte | 7 ++++--- frontend/antd/cascader/option/Index.svelte | 10 +++++++--- frontend/antd/cascader/panel/Index.svelte | 7 ++++--- frontend/antd/checkbox/Index.svelte | 5 +++-- frontend/antd/checkbox/group/Index.svelte | 5 +++-- frontend/antd/checkbox/group/option/Index.svelte | 3 ++- frontend/antd/collapse/Index.svelte | 5 +++-- frontend/antd/collapse/item/Index.svelte | 9 +++++---- frontend/antd/color-picker/Index.svelte | 7 ++++--- frontend/antd/color-picker/preset/Index.svelte | 7 ++++--- frontend/antd/config-provider/Index.svelte | 4 ++-- frontend/antd/date-picker/Index.svelte | 7 ++++--- frontend/antd/date-picker/preset/Index.svelte | 7 ++++--- frontend/antd/date-picker/range-picker/Index.svelte | 7 ++++--- frontend/antd/descriptions/Index.svelte | 5 +++-- frontend/antd/descriptions/item/Index.svelte | 7 ++++--- frontend/antd/divider/Index.svelte | 5 +++-- frontend/antd/drawer/Index.svelte | 5 +++-- frontend/antd/dropdown/Index.svelte | 5 +++-- frontend/antd/dropdown/button/Index.svelte | 7 ++++--- frontend/antd/empty/Index.svelte | 5 +++-- frontend/antd/flex/Index.svelte | 5 +++-- frontend/antd/float-button/Index.svelte | 7 ++++--- frontend/antd/float-button/back-top/Index.svelte | 7 ++++--- frontend/antd/float-button/group/Index.svelte | 7 ++++--- frontend/antd/form/Index.svelte | 7 ++++--- frontend/antd/form/item/Index.svelte | 5 +++-- frontend/antd/form/item/rule/Index.svelte | 3 ++- frontend/antd/form/provider/Index.svelte | 5 +++-- frontend/antd/grid/col/Index.svelte | 5 +++-- frontend/antd/grid/row/Index.svelte | 5 +++-- frontend/antd/icon/Index.svelte | 5 +++-- frontend/antd/icon/iconfont-provider/Index.svelte | 5 +++-- frontend/antd/image/Index.svelte | 7 ++++--- frontend/antd/image/preview-group/Index.svelte | 7 ++++--- frontend/antd/input-number/Index.svelte | 7 ++++--- frontend/antd/input/Index.svelte | 7 ++++--- frontend/antd/input/otp/Index.svelte | 5 +++-- frontend/antd/input/password/Index.svelte | 7 ++++--- frontend/antd/input/search/Index.svelte | 7 ++++--- frontend/antd/input/textarea/Index.svelte | 7 ++++--- frontend/antd/layout/Base.svelte | 5 +++-- frontend/antd/layout/Index.svelte | 2 +- frontend/antd/layout/sider/Index.svelte | 5 +++-- frontend/antd/list/Index.svelte | 7 ++++--- frontend/antd/list/item/Index.svelte | 5 +++-- frontend/antd/list/item/meta/Index.svelte | 5 +++-- frontend/antd/mentions/Index.svelte | 7 ++++--- frontend/antd/mentions/option/Index.svelte | 7 ++++--- frontend/antd/menu/Index.svelte | 7 ++++--- frontend/antd/menu/item/Index.svelte | 9 +++++---- frontend/antd/message/Index.svelte | 5 +++-- frontend/antd/modal/Index.svelte | 5 +++-- frontend/antd/modal/static/Index.svelte | 5 +++-- frontend/antd/notification/Index.svelte | 5 +++-- frontend/antd/pagination/Index.svelte | 7 ++++--- frontend/antd/popconfirm/Index.svelte | 7 ++++--- frontend/antd/popover/Index.svelte | 7 ++++--- frontend/antd/progress/Index.svelte | 3 ++- frontend/antd/qr-code/Index.svelte | 3 ++- frontend/antd/radio/Index.svelte | 7 ++++--- frontend/antd/radio/button/Index.svelte | 7 ++++--- frontend/antd/radio/group/Index.svelte | 7 ++++--- frontend/antd/radio/group/option/Index.svelte | 3 ++- frontend/antd/rate/Index.svelte | 7 ++++--- frontend/antd/result/Index.svelte | 5 +++-- frontend/antd/segmented/Index.svelte | 8 +++++--- frontend/antd/segmented/option/Index.svelte | 7 ++++--- frontend/antd/select/Index.svelte | 7 ++++--- frontend/antd/select/option/Index.svelte | 10 +++++++--- frontend/antd/skeleton/Index.svelte | 5 +++-- frontend/antd/skeleton/avatar/Index.svelte | 5 +++-- frontend/antd/skeleton/button/Index.svelte | 5 +++-- frontend/antd/skeleton/image/Index.svelte | 5 +++-- frontend/antd/skeleton/input/Index.svelte | 5 +++-- frontend/antd/skeleton/node/Index.svelte | 5 +++-- frontend/antd/slider/Index.svelte | 7 ++++--- frontend/antd/slider/mark/Index.svelte | 7 ++++--- frontend/antd/space/Index.svelte | 5 +++-- frontend/antd/space/compact/Index.svelte | 5 +++-- frontend/antd/spin/Index.svelte | 5 +++-- frontend/antd/splitter/Index.svelte | 7 ++++--- frontend/antd/splitter/panel/Index.svelte | 5 +++-- frontend/antd/statistic/Index.svelte | 5 +++-- frontend/antd/statistic/countdown/Index.svelte | 5 +++-- frontend/antd/statistic/timer/Index.svelte | 6 ++++-- frontend/antd/steps/Index.svelte | 5 +++-- frontend/antd/steps/item/Index.svelte | 7 ++++--- frontend/antd/switch/Index.svelte | 5 +++-- frontend/antd/table/Index.svelte | 5 +++-- frontend/antd/table/column-group/Index.svelte | 7 ++++--- frontend/antd/table/column/Index.svelte | 10 ++++++---- frontend/antd/table/expandable/Index.svelte | 7 ++++--- frontend/antd/table/row-selection/Index.svelte | 5 +++-- .../antd/table/row-selection/selection/Index.svelte | 7 ++++--- frontend/antd/tabs/Index.svelte | 7 ++++--- frontend/antd/tabs/item/Index.svelte | 7 ++++--- frontend/antd/tag/Index.svelte | 5 +++-- frontend/antd/tag/checkable-tag/Index.svelte | 5 +++-- frontend/antd/time-picker/Index.svelte | 7 ++++--- frontend/antd/time-picker/range-picker/Index.svelte | 7 ++++--- frontend/antd/timeline/Index.svelte | 5 +++-- frontend/antd/timeline/item/Index.svelte | 7 ++++--- frontend/antd/tooltip/Index.svelte | 7 ++++--- frontend/antd/tour/Index.svelte | 5 +++-- frontend/antd/tour/step/Index.svelte | 9 +++++---- frontend/antd/transfer/Index.svelte | 7 ++++--- frontend/antd/tree-select/Index.svelte | 7 ++++--- frontend/antd/tree-select/tree-node/Index.svelte | 7 ++++--- frontend/antd/tree/Index.svelte | 7 ++++--- frontend/antd/tree/directory-tree/Index.svelte | 7 ++++--- frontend/antd/tree/tree-node/Index.svelte | 7 ++++--- frontend/antd/typography/Base.svelte | 7 ++++--- frontend/antd/upload/Index.svelte | 2 +- frontend/antd/upload/dragger/Index.svelte | 4 ++-- frontend/antd/watermark/Index.svelte | 5 +++-- frontend/antdx/actions/Index.svelte | 5 +++-- frontend/antdx/actions/item/Index.svelte | 10 +++++++--- frontend/antdx/attachments/Index.svelte | 7 ++++--- frontend/antdx/attachments/file-card/Index.svelte | 10 +++++++--- frontend/antdx/bubble/Index.svelte | 7 ++++--- frontend/antdx/bubble/list/Index.svelte | 5 +++-- frontend/antdx/bubble/list/item/Item.svelte | 10 +++++++--- frontend/antdx/bubble/list/role/Role.svelte | 5 +++-- frontend/antdx/conversations/Index.svelte | 7 ++++--- frontend/antdx/conversations/item/Index.svelte | 10 +++++++--- frontend/antdx/prompts/Index.svelte | 7 ++++--- frontend/antdx/prompts/item/Index.svelte | 10 +++++++--- frontend/antdx/sender/Index.svelte | 7 ++++--- frontend/antdx/sender/header/Index.svelte | 5 +++-- frontend/antdx/suggestion/Index.svelte | 7 ++++--- frontend/antdx/suggestion/item/Index.svelte | 10 +++++++--- frontend/antdx/thought-chain/Index.svelte | 5 +++-- frontend/antdx/thought-chain/item/Index.svelte | 10 +++++++--- frontend/antdx/welcome/Index.svelte | 5 +++-- frontend/antdx/x-provider/XProvider.svelte | 4 ++-- frontend/base/auto-loading/Index.svelte | 11 ++++++----- frontend/base/div/Index.svelte | 5 +++-- frontend/base/each/EachItem.svelte | 2 +- frontend/base/each/Index.svelte | 4 ++-- frontend/base/filter/Index.svelte | 5 +++-- frontend/base/fragment/Index.svelte | 5 +++-- frontend/base/markdown/Index.svelte | 3 ++- frontend/base/slot/Index.svelte | 5 +++-- frontend/base/span/Index.svelte | 5 +++-- frontend/base/text/Index.svelte | 3 ++- frontend/pro/chatbot/Index.svelte | 2 +- frontend/pro/monaco-editor/Index.svelte | 5 +++-- frontend/pro/monaco-editor/diff-editor/Index.svelte | 5 +++-- frontend/pro/multimodal-input/Index.svelte | 7 ++++--- frontend/pro/web-sandbox/Index.svelte | 7 ++++--- .../svelte-preprocess-react/component/props.svelte.ts | 2 +- .../internal/ReactWrapper.svelte | 2 +- 173 files changed, 610 insertions(+), 419 deletions(-) diff --git a/frontend/antd/affix/Index.svelte b/frontend/antd/affix/Index.svelte index c4ec63b1..1597e2eb 100644 --- a/frontend/antd/affix/Index.svelte +++ b/frontend/antd/affix/Index.svelte @@ -10,7 +10,7 @@ const AwaitedAffix = importComponent(() => import('./affix')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -32,6 +32,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -61,7 +62,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/alert/Index.svelte b/frontend/antd/alert/Index.svelte index 3edf75bc..5ebe4440 100644 --- a/frontend/antd/alert/Index.svelte +++ b/frontend/antd/alert/Index.svelte @@ -10,7 +10,7 @@ const AwaitedAlert = importComponent(() => import('./alert')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/alert/error-boundary/Index.svelte b/frontend/antd/alert/error-boundary/Index.svelte index 583d7c29..95482aaf 100644 --- a/frontend/antd/alert/error-boundary/Index.svelte +++ b/frontend/antd/alert/error-boundary/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string; _internal: { @@ -31,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/anchor/Index.svelte b/frontend/antd/anchor/Index.svelte index 08ea2538..ba3bae81 100644 --- a/frontend/antd/anchor/Index.svelte +++ b/frontend/antd/anchor/Index.svelte @@ -5,13 +5,12 @@ processProps, } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; - import type React from 'react'; import cls from 'classnames'; const AwaitedAnchor = importComponent(() => import('./anchor')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -31,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -56,7 +56,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/anchor/item/Index.svelte b/frontend/antd/anchor/item/Index.svelte index 2fad045d..09008e8e 100644 --- a/frontend/antd/anchor/item/Index.svelte +++ b/frontend/antd/anchor/item/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedAnchorItem = importComponent(() => import('./anchor.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -67,7 +68,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/auto-complete/Index.svelte b/frontend/antd/auto-complete/Index.svelte index 8104b26b..3f6c44e1 100644 --- a/frontend/antd/auto-complete/Index.svelte +++ b/frontend/antd/auto-complete/Index.svelte @@ -11,7 +11,7 @@ const AwaitedAutoComplete = importComponent(() => import('./auto-complete')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; value: string; @@ -37,7 +37,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -74,7 +75,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/auto-complete/option/Index.svelte b/frontend/antd/auto-complete/option/Index.svelte index f5aeb09c..c1fba290 100644 --- a/frontend/antd/auto-complete/option/Index.svelte +++ b/frontend/antd/auto-complete/option/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -35,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -66,7 +67,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/avatar/Index.svelte b/frontend/antd/avatar/Index.svelte index 6473517f..1b3b1afa 100644 --- a/frontend/antd/avatar/Index.svelte +++ b/frontend/antd/avatar/Index.svelte @@ -12,7 +12,7 @@ const AwaitedAvatar = importComponent(() => import('./avatar')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; value: string | FileData; @@ -34,6 +34,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -69,7 +70,7 @@ slots={slots.value} src={proceedProps.additionalProps.src || src} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/avatar/group/Index.svelte b/frontend/antd/avatar/group/Index.svelte index b4b9546c..32ab4d65 100644 --- a/frontend/antd/avatar/group/Index.svelte +++ b/frontend/antd/avatar/group/Index.svelte @@ -10,7 +10,7 @@ const AwaitedAvatarGroup = importComponent(() => import('./avatar.group')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/badge/Index.svelte b/frontend/antd/badge/Index.svelte index 007c1114..1fdd2a2f 100644 --- a/frontend/antd/badge/Index.svelte +++ b/frontend/antd/badge/Index.svelte @@ -11,7 +11,7 @@ const AwaitedBadge = importComponent(() => import('./badge')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -31,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -58,7 +59,7 @@ {#await AwaitedBadge then Badge} {#if proceedProps._internal.layout} - {@render children()} + {@render children?.()} {:else} diff --git a/frontend/antd/badge/ribbon/Index.svelte b/frontend/antd/badge/ribbon/Index.svelte index 2eb16501..6635dc9a 100644 --- a/frontend/antd/badge/ribbon/Index.svelte +++ b/frontend/antd/badge/ribbon/Index.svelte @@ -10,7 +10,7 @@ const AwaitedBadgeRibbon = importComponent(() => import('./badge.ribbon')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/breadcrumb/Index.svelte b/frontend/antd/breadcrumb/Index.svelte index 2f692a5e..e6bebc56 100644 --- a/frontend/antd/breadcrumb/Index.svelte +++ b/frontend/antd/breadcrumb/Index.svelte @@ -10,7 +10,7 @@ const AwaitedBreadcrumb = importComponent(() => import('./breadcrumb')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -70,7 +71,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/breadcrumb/item/Index.svelte b/frontend/antd/breadcrumb/item/Index.svelte index 7576a855..19f21328 100644 --- a/frontend/antd/breadcrumb/item/Index.svelte +++ b/frontend/antd/breadcrumb/item/Index.svelte @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -35,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -64,7 +65,7 @@ itemSlots={slots.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/button/Index.svelte b/frontend/antd/button/Index.svelte index 9d9df552..b400ede0 100644 --- a/frontend/antd/button/Index.svelte +++ b/frontend/antd/button/Index.svelte @@ -34,6 +34,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -43,7 +44,6 @@ elem_id, elem_classes, elem_style, - gradio, }; }, { @@ -67,7 +67,7 @@ slots={slots.value} value={proceedProps.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/button/group/Index.svelte b/frontend/antd/button/group/Index.svelte index 6f4e3aba..473faa03 100644 --- a/frontend/antd/button/group/Index.svelte +++ b/frontend/antd/button/group/Index.svelte @@ -10,7 +10,7 @@ const AwaitedButtonGroup = importComponent(() => import('./button.group')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/calendar/Index.svelte b/frontend/antd/calendar/Index.svelte index 2bc15a85..c55e0d1f 100644 --- a/frontend/antd/calendar/Index.svelte +++ b/frontend/antd/calendar/Index.svelte @@ -11,7 +11,7 @@ const AwaitedCalender = importComponent(() => import('./calendar')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, value, @@ -72,7 +73,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/card/Index.svelte b/frontend/antd/card/Index.svelte index 0e259c11..5069c705 100644 --- a/frontend/antd/card/Index.svelte +++ b/frontend/antd/card/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCard = importComponent(() => import('./card')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,7 +30,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -60,7 +61,7 @@ containsGrid={proceedProps._internal.contains_grid} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/card/grid/Index.svelte b/frontend/antd/card/grid/Index.svelte index 96d82298..2438f197 100644 --- a/frontend/antd/card/grid/Index.svelte +++ b/frontend/antd/card/grid/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCardGrid = importComponent(() => import('./card.grid')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string; _internal: Record; @@ -27,6 +27,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/card/meta/Index.svelte b/frontend/antd/card/meta/Index.svelte index 636947ad..43cf0a64 100644 --- a/frontend/antd/card/meta/Index.svelte +++ b/frontend/antd/card/meta/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCardMeta = importComponent(() => import('./card.meta')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string; _internal: Record; @@ -27,6 +27,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/carousel/Index.svelte b/frontend/antd/carousel/Index.svelte index 6e0e15f4..e350c50f 100644 --- a/frontend/antd/carousel/Index.svelte +++ b/frontend/antd/carousel/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCarousel = importComponent(() => import('./carousel')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/cascader/Index.svelte b/frontend/antd/cascader/Index.svelte index 47b786ba..15ee9aa2 100644 --- a/frontend/antd/cascader/Index.svelte +++ b/frontend/antd/cascader/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCascader = importComponent(() => import('./cascader')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ value?: string[] | number[]; additional_props?: Record; @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -71,7 +72,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/cascader/option/Index.svelte b/frontend/antd/cascader/option/Index.svelte index 50682dc8..6a3b2fcc 100644 --- a/frontend/antd/cascader/option/Index.svelte +++ b/frontend/antd/cascader/option/Index.svelte @@ -4,7 +4,10 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import {Keys + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedCascaderOption = importComponent( @@ -12,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -32,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -60,7 +64,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/cascader/panel/Index.svelte b/frontend/antd/cascader/panel/Index.svelte index ff201257..e3a872c5 100644 --- a/frontend/antd/cascader/panel/Index.svelte +++ b/frontend/antd/cascader/panel/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -69,7 +70,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/checkbox/Index.svelte b/frontend/antd/checkbox/Index.svelte index f5a6972a..1691058d 100644 --- a/frontend/antd/checkbox/Index.svelte +++ b/frontend/antd/checkbox/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCheckbox = importComponent(() => import('./checkbox')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ value?: boolean; additional_props?: Record; @@ -33,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -65,7 +66,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/checkbox/group/Index.svelte b/frontend/antd/checkbox/group/Index.svelte index 042351bf..196717e2 100644 --- a/frontend/antd/checkbox/group/Index.svelte +++ b/frontend/antd/checkbox/group/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -33,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +64,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/checkbox/group/option/Index.svelte b/frontend/antd/checkbox/group/option/Index.svelte index 5b108184..4e276a64 100644 --- a/frontend/antd/checkbox/group/option/Index.svelte +++ b/frontend/antd/checkbox/group/option/Index.svelte @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; value?: string; label?: string; @@ -41,6 +41,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/collapse/Index.svelte b/frontend/antd/collapse/Index.svelte index 5100376a..2373e63d 100644 --- a/frontend/antd/collapse/Index.svelte +++ b/frontend/antd/collapse/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCollapse = importComponent(() => import('./collapse')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -55,7 +56,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/collapse/item/Index.svelte b/frontend/antd/collapse/item/Index.svelte index 9643ca7f..2ce7e44c 100644 --- a/frontend/antd/collapse/item/Index.svelte +++ b/frontend/antd/collapse/item/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedCollapseItem = importComponent(() => import('./collapse.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -34,7 +34,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -80,7 +81,7 @@ > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} diff --git a/frontend/antd/color-picker/Index.svelte b/frontend/antd/color-picker/Index.svelte index 7f18eec2..c94db0c2 100644 --- a/frontend/antd/color-picker/Index.svelte +++ b/frontend/antd/color-picker/Index.svelte @@ -10,7 +10,7 @@ const AwaitedColorPicker = importComponent(() => import('./color-picker')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -40,7 +40,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -84,7 +85,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/color-picker/preset/Index.svelte b/frontend/antd/color-picker/preset/Index.svelte index fd49553a..432cc5aa 100644 --- a/frontend/antd/color-picker/preset/Index.svelte +++ b/frontend/antd/color-picker/preset/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -34,6 +34,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -62,7 +63,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/config-provider/Index.svelte b/frontend/antd/config-provider/Index.svelte index f5c5ebd2..8a72a121 100644 --- a/frontend/antd/config-provider/Index.svelte +++ b/frontend/antd/config-provider/Index.svelte @@ -30,8 +30,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -58,7 +58,7 @@ slots={slots.value} themeMode={proceedProps.gradio.shared.theme || 'light'} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/date-picker/Index.svelte b/frontend/antd/date-picker/Index.svelte index 441eeabc..28ba22ae 100644 --- a/frontend/antd/date-picker/Index.svelte +++ b/frontend/antd/date-picker/Index.svelte @@ -10,7 +10,7 @@ const AwaitedDatePicker = importComponent(() => import('./date-picker')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -73,7 +74,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/date-picker/preset/Index.svelte b/frontend/antd/date-picker/preset/Index.svelte index 8084f315..f3c22908 100644 --- a/frontend/antd/date-picker/preset/Index.svelte +++ b/frontend/antd/date-picker/preset/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; value?: string | number; _internal: { @@ -36,6 +36,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -66,7 +67,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/date-picker/range-picker/Index.svelte b/frontend/antd/date-picker/range-picker/Index.svelte index 5f38aa53..725107b4 100644 --- a/frontend/antd/date-picker/range-picker/Index.svelte +++ b/frontend/antd/date-picker/range-picker/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; value?: [string | number | null, string | number | null]; @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -72,7 +73,7 @@ updateProps({ value: val }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/descriptions/Index.svelte b/frontend/antd/descriptions/Index.svelte index a343a096..abe48880 100644 --- a/frontend/antd/descriptions/Index.svelte +++ b/frontend/antd/descriptions/Index.svelte @@ -10,7 +10,7 @@ const AwaitedDescriptions = importComponent(() => import('./descriptions')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -57,7 +58,7 @@ slots={slots.value} title={proceedProps.additionalProps.title || proceedProps.title} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/descriptions/item/Index.svelte b/frontend/antd/descriptions/item/Index.svelte index d2526838..64e04f4f 100644 --- a/frontend/antd/descriptions/item/Index.svelte +++ b/frontend/antd/descriptions/item/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -35,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -68,7 +69,7 @@ > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} diff --git a/frontend/antd/divider/Index.svelte b/frontend/antd/divider/Index.svelte index a74d528e..88839889 100644 --- a/frontend/antd/divider/Index.svelte +++ b/frontend/antd/divider/Index.svelte @@ -10,7 +10,7 @@ const AwaitedDivider = importComponent(() => import('./divider')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -32,6 +32,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -60,7 +61,7 @@ {#await AwaitedDivider then Divider} {#if proceedProps._internal.layout} - {@render children()} + {@render children?.()} {:else if proceedProps.value} diff --git a/frontend/antd/drawer/Index.svelte b/frontend/antd/drawer/Index.svelte index 86b7cea9..cc950b51 100644 --- a/frontend/antd/drawer/Index.svelte +++ b/frontend/antd/drawer/Index.svelte @@ -10,7 +10,7 @@ const AwaitedDrawer = importComponent(() => import('./drawer')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/dropdown/Index.svelte b/frontend/antd/dropdown/Index.svelte index 24c5e862..6e95314d 100644 --- a/frontend/antd/dropdown/Index.svelte +++ b/frontend/antd/dropdown/Index.svelte @@ -10,7 +10,7 @@ const AwaitedDropdown = importComponent(() => import('./dropdown')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string; _internal: { @@ -32,7 +32,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/dropdown/button/Index.svelte b/frontend/antd/dropdown/button/Index.svelte index a25e8af9..a2b7039f 100644 --- a/frontend/antd/dropdown/button/Index.svelte +++ b/frontend/antd/dropdown/button/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -33,7 +33,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -63,7 +64,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/empty/Index.svelte b/frontend/antd/empty/Index.svelte index 86c8850f..67c55700 100644 --- a/frontend/antd/empty/Index.svelte +++ b/frontend/antd/empty/Index.svelte @@ -10,7 +10,7 @@ const AwaitedEmpty = importComponent(() => import('./empty')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/flex/Index.svelte b/frontend/antd/flex/Index.svelte index 716e20f6..65b85826 100644 --- a/frontend/antd/flex/Index.svelte +++ b/frontend/antd/flex/Index.svelte @@ -10,7 +10,7 @@ const AwaitedFlex = importComponent(() => import('./flex')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/float-button/Index.svelte b/frontend/antd/float-button/Index.svelte index eef824a5..1be05eab 100644 --- a/frontend/antd/float-button/Index.svelte +++ b/frontend/antd/float-button/Index.svelte @@ -10,7 +10,7 @@ const AwaitedFloatButton = importComponent(() => import('./float-button')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { @@ -32,7 +32,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -62,7 +63,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/float-button/back-top/Index.svelte b/frontend/antd/float-button/back-top/Index.svelte index 6627b3fb..500a5022 100644 --- a/frontend/antd/float-button/back-top/Index.svelte +++ b/frontend/antd/float-button/back-top/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -33,7 +33,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -65,7 +66,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/float-button/group/Index.svelte b/frontend/antd/float-button/group/Index.svelte index 29f71f6a..1e6d7a71 100644 --- a/frontend/antd/float-button/group/Index.svelte +++ b/frontend/antd/float-button/group/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; href_target?: string; _internal: { @@ -32,7 +32,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -64,7 +65,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/form/Index.svelte b/frontend/antd/form/Index.svelte index 8d9ed0a7..6ea30aa3 100644 --- a/frontend/antd/form/Index.svelte +++ b/frontend/antd/form/Index.svelte @@ -12,7 +12,7 @@ const AwaitedForm = importComponent(() => import('./form')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; _internal: { @@ -40,7 +40,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -86,7 +87,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/form/item/Index.svelte b/frontend/antd/form/item/Index.svelte index 947baf1e..22495224 100644 --- a/frontend/antd/form/item/Index.svelte +++ b/frontend/antd/form/item/Index.svelte @@ -10,7 +10,7 @@ const AwaitedFormItem = importComponent(() => import('./form.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -30,7 +30,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/form/item/rule/Index.svelte b/frontend/antd/form/item/rule/Index.svelte index 12e6a9d0..0424670f 100644 --- a/frontend/antd/form/item/rule/Index.svelte +++ b/frontend/antd/form/item/rule/Index.svelte @@ -9,7 +9,7 @@ const AwaitedFormItemRule = importComponent(() => import('./form.item.rule')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/form/provider/Index.svelte b/frontend/antd/form/provider/Index.svelte index d6a7bb80..29b3aaee 100644 --- a/frontend/antd/form/provider/Index.svelte +++ b/frontend/antd/form/provider/Index.svelte @@ -9,7 +9,7 @@ const AwaitedFormProvider = importComponent(() => import('./form.provider')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: Record; form_change?: any; @@ -28,7 +28,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/grid/col/Index.svelte b/frontend/antd/grid/col/Index.svelte index de3b95af..b756f3d1 100644 --- a/frontend/antd/grid/col/Index.svelte +++ b/frontend/antd/grid/col/Index.svelte @@ -10,7 +10,7 @@ const AwaitedCol = importComponent(() => import('./col')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -33,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -62,7 +63,7 @@ > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} diff --git a/frontend/antd/grid/row/Index.svelte b/frontend/antd/grid/row/Index.svelte index 4af3e6c6..f006b78e 100644 --- a/frontend/antd/grid/row/Index.svelte +++ b/frontend/antd/grid/row/Index.svelte @@ -10,7 +10,7 @@ const AwaitedRow = importComponent(() => import('./row')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -28,6 +28,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -53,7 +54,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/icon/Index.svelte b/frontend/antd/icon/Index.svelte index 34431024..54e2293a 100644 --- a/frontend/antd/icon/Index.svelte +++ b/frontend/antd/icon/Index.svelte @@ -10,7 +10,7 @@ const AwaitedIcon = importComponent(() => import('./icon')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -59,7 +60,7 @@ {value} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/icon/iconfont-provider/Index.svelte b/frontend/antd/icon/iconfont-provider/Index.svelte index bb644a9e..595e02a2 100644 --- a/frontend/antd/icon/iconfont-provider/Index.svelte +++ b/frontend/antd/icon/iconfont-provider/Index.svelte @@ -9,7 +9,7 @@ () => import('./iconfont-provider') ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additionalProps: Record; }>(() => props); @@ -24,6 +24,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -45,7 +46,7 @@ {...proceedProps.additionalProps} slots={{}} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/image/Index.svelte b/frontend/antd/image/Index.svelte index 49ceb00c..454ed15e 100644 --- a/frontend/antd/image/Index.svelte +++ b/frontend/antd/image/Index.svelte @@ -11,7 +11,7 @@ const AwaitedImage = importComponent(() => import('./image')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -75,7 +76,7 @@ slots={slots.value} src={proceedProps.additionalProps.src || src} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/image/preview-group/Index.svelte b/frontend/antd/image/preview-group/Index.svelte index 215109a5..bd53a2a9 100644 --- a/frontend/antd/image/preview-group/Index.svelte +++ b/frontend/antd/image/preview-group/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -32,7 +32,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -64,7 +65,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/input-number/Index.svelte b/frontend/antd/input-number/Index.svelte index b0cc3226..19809cb8 100644 --- a/frontend/antd/input-number/Index.svelte +++ b/frontend/antd/input-number/Index.svelte @@ -10,7 +10,7 @@ const AwaitedInputNumber = importComponent(() => import('./input-number')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -72,7 +73,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/input/Index.svelte b/frontend/antd/input/Index.svelte index 4354dfd8..ff28b80b 100644 --- a/frontend/antd/input/Index.svelte +++ b/frontend/antd/input/Index.svelte @@ -10,7 +10,7 @@ const AwaitedInput = importComponent(() => import('./input')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -71,7 +72,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/input/otp/Index.svelte b/frontend/antd/input/otp/Index.svelte index 10f39c39..bcd582cd 100644 --- a/frontend/antd/input/otp/Index.svelte +++ b/frontend/antd/input/otp/Index.svelte @@ -10,7 +10,7 @@ const AwaitedInputOTP = importComponent(() => import('./input.otp')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -31,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -61,7 +62,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/input/password/Index.svelte b/frontend/antd/input/password/Index.svelte index d546726e..02f4f72c 100644 --- a/frontend/antd/input/password/Index.svelte +++ b/frontend/antd/input/password/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; _internal: { @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -70,7 +71,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/input/search/Index.svelte b/frontend/antd/input/search/Index.svelte index 8be16daa..96446d57 100644 --- a/frontend/antd/input/search/Index.svelte +++ b/frontend/antd/input/search/Index.svelte @@ -10,7 +10,7 @@ const AwaitedInputSearch = importComponent(() => import('./input.search')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; _internal: { @@ -32,7 +32,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -66,7 +67,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/input/textarea/Index.svelte b/frontend/antd/input/textarea/Index.svelte index fbe93556..298d8bd7 100644 --- a/frontend/antd/input/textarea/Index.svelte +++ b/frontend/antd/input/textarea/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTextArea = importComponent(() => import('./input.textarea')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; value?: string; @@ -32,7 +32,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -66,7 +67,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/layout/Base.svelte b/frontend/antd/layout/Base.svelte index ee5e4698..ac4d558c 100644 --- a/frontend/antd/layout/Base.svelte +++ b/frontend/antd/layout/Base.svelte @@ -14,7 +14,7 @@ component: 'header' | 'footer' | 'content' | 'layout'; children?: Snippet; } = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; component: 'header' | 'footer' | 'content' | 'layout'; @@ -36,6 +36,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +64,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/layout/Index.svelte b/frontend/antd/layout/Index.svelte index 1758c9d3..9d6a02c1 100644 --- a/frontend/antd/layout/Index.svelte +++ b/frontend/antd/layout/Index.svelte @@ -11,7 +11,7 @@ } = $props(); -{@render children()} +{@render children?.()} diff --git a/frontend/antd/layout/sider/Index.svelte b/frontend/antd/layout/sider/Index.svelte index 93793e9b..b9906f6e 100644 --- a/frontend/antd/layout/sider/Index.svelte +++ b/frontend/antd/layout/sider/Index.svelte @@ -10,7 +10,7 @@ const AwaitedLayoutSider = importComponent(() => import('./layout.sider')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/list/Index.svelte b/frontend/antd/list/Index.svelte index 055e7eb8..ce1b1cd3 100644 --- a/frontend/antd/list/Index.svelte +++ b/frontend/antd/list/Index.svelte @@ -10,7 +10,7 @@ const AwaitedList = importComponent(() => import('./list')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -31,7 +31,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -61,7 +62,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/list/item/Index.svelte b/frontend/antd/list/item/Index.svelte index 02cdf615..ab22752c 100644 --- a/frontend/antd/list/item/Index.svelte +++ b/frontend/antd/list/item/Index.svelte @@ -10,7 +10,7 @@ const AwaitedListItem = importComponent(() => import('./list.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: {}; @@ -27,6 +27,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -52,7 +53,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/list/item/meta/Index.svelte b/frontend/antd/list/item/meta/Index.svelte index 7dbb7071..dd0a35d7 100644 --- a/frontend/antd/list/item/meta/Index.svelte +++ b/frontend/antd/list/item/meta/Index.svelte @@ -10,7 +10,7 @@ const AwaitedListItemMeta = importComponent(() => import('./list.item.meta')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; }>(() => props); @@ -26,6 +26,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -51,7 +52,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/mentions/Index.svelte b/frontend/antd/mentions/Index.svelte index 58227c27..25a8dca1 100644 --- a/frontend/antd/mentions/Index.svelte +++ b/frontend/antd/mentions/Index.svelte @@ -10,7 +10,7 @@ const AwaitedMentions = importComponent(() => import('./mentions')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -72,7 +73,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/mentions/option/Index.svelte b/frontend/antd/mentions/option/Index.svelte index 8f6d981b..c755a867 100644 --- a/frontend/antd/mentions/option/Index.svelte +++ b/frontend/antd/mentions/option/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; value?: string; @@ -36,6 +36,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -64,7 +65,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/menu/Index.svelte b/frontend/antd/menu/Index.svelte index 33064588..5bc91307 100644 --- a/frontend/antd/menu/Index.svelte +++ b/frontend/antd/menu/Index.svelte @@ -10,7 +10,7 @@ const AwaitedMenu = importComponent(() => import('./menu')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { @@ -32,7 +32,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -61,7 +62,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/menu/item/Index.svelte b/frontend/antd/menu/item/Index.svelte index 163b3aac..1f765ca4 100644 --- a/frontend/antd/menu/item/Index.svelte +++ b/frontend/antd/menu/item/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedMenuItem = importComponent(() => import('./menu.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -34,7 +34,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -72,7 +73,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/message/Index.svelte b/frontend/antd/message/Index.svelte index 6abc2364..c1219ddb 100644 --- a/frontend/antd/message/Index.svelte +++ b/frontend/antd/message/Index.svelte @@ -10,7 +10,7 @@ const AwaitedMessage = importComponent(() => import('./message')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -33,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -66,6 +67,6 @@ }); }} > - {@render children()} + {@render children?.()} {/await} diff --git a/frontend/antd/modal/Index.svelte b/frontend/antd/modal/Index.svelte index faea1288..17c7f0de 100644 --- a/frontend/antd/modal/Index.svelte +++ b/frontend/antd/modal/Index.svelte @@ -10,7 +10,7 @@ const AwaitedModal = importComponent(() => import('./modal')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -55,7 +56,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/modal/static/Index.svelte b/frontend/antd/modal/static/Index.svelte index 94f0b10c..7ee953d0 100644 --- a/frontend/antd/modal/static/Index.svelte +++ b/frontend/antd/modal/static/Index.svelte @@ -10,7 +10,7 @@ const AwaitedModalStatic = importComponent(() => import('./modal.static')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -58,6 +59,6 @@ updateProps({ visible: v }); }} > - {@render children()} + {@render children?.()} {/await} diff --git a/frontend/antd/notification/Index.svelte b/frontend/antd/notification/Index.svelte index 2370aed3..0f129917 100644 --- a/frontend/antd/notification/Index.svelte +++ b/frontend/antd/notification/Index.svelte @@ -10,7 +10,7 @@ const AwaitedNotification = importComponent(() => import('./notification')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -34,6 +34,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -68,6 +69,6 @@ }); }} > - {@render children()} + {@render children?.()} {/await} diff --git a/frontend/antd/pagination/Index.svelte b/frontend/antd/pagination/Index.svelte index b8405fe4..be1bb255 100644 --- a/frontend/antd/pagination/Index.svelte +++ b/frontend/antd/pagination/Index.svelte @@ -10,7 +10,7 @@ const AwaitedPagination = importComponent(() => import('./pagination')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -31,7 +31,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -60,7 +61,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/popconfirm/Index.svelte b/frontend/antd/popconfirm/Index.svelte index e4c01ec9..8139433c 100644 --- a/frontend/antd/popconfirm/Index.svelte +++ b/frontend/antd/popconfirm/Index.svelte @@ -10,7 +10,7 @@ const AwaitedPopconfirm = importComponent(() => import('./popconfirm')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -68,7 +69,7 @@ slots={slots.value} title={proceedProps.additionalProps.title || proceedProps.title} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/popover/Index.svelte b/frontend/antd/popover/Index.svelte index 0608b933..669f2bf1 100644 --- a/frontend/antd/popover/Index.svelte +++ b/frontend/antd/popover/Index.svelte @@ -10,7 +10,7 @@ const AwaitedPopover = importComponent(() => import('./popover')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { @@ -34,7 +34,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -65,7 +66,7 @@ slots={slots.value} content={proceedProps.additionalProps.content || proceedProps.content} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/progress/Index.svelte b/frontend/antd/progress/Index.svelte index a07f5109..c1887f5c 100644 --- a/frontend/antd/progress/Index.svelte +++ b/frontend/antd/progress/Index.svelte @@ -10,7 +10,7 @@ const AwaitedProgress = importComponent(() => import('./progress')); const props = $props(); - const { getComponentProps, getAdditionalProps } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps } = getProps<{ additional_props?: Record; _internal: { @@ -31,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/qr-code/Index.svelte b/frontend/antd/qr-code/Index.svelte index 38b8448d..217e2cd9 100644 --- a/frontend/antd/qr-code/Index.svelte +++ b/frontend/antd/qr-code/Index.svelte @@ -10,7 +10,7 @@ const AwaitedQRCode = importComponent(() => import('./qr-code')); const props = $props(); - const { getComponentProps, getAdditionalProps } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps } = getProps<{ additional_props?: Record; _internal: { @@ -31,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/radio/Index.svelte b/frontend/antd/radio/Index.svelte index 34cd81d1..ba174341 100644 --- a/frontend/antd/radio/Index.svelte +++ b/frontend/antd/radio/Index.svelte @@ -10,7 +10,7 @@ const AwaitedRadio = importComponent(() => import('./radio')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -34,7 +34,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -70,7 +71,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/radio/button/Index.svelte b/frontend/antd/radio/button/Index.svelte index 3f4014bd..f47d8474 100644 --- a/frontend/antd/radio/button/Index.svelte +++ b/frontend/antd/radio/button/Index.svelte @@ -10,7 +10,7 @@ const AwaitedRadioButton = importComponent(() => import('./radio.button')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -71,7 +72,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/radio/group/Index.svelte b/frontend/antd/radio/group/Index.svelte index f19f4501..117ecda2 100644 --- a/frontend/antd/radio/group/Index.svelte +++ b/frontend/antd/radio/group/Index.svelte @@ -10,7 +10,7 @@ const AwaitedRadioGroup = importComponent(() => import('./radio.group')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -33,7 +33,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -67,7 +68,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/radio/group/option/Index.svelte b/frontend/antd/radio/group/option/Index.svelte index 707ee92c..c9b5bee1 100644 --- a/frontend/antd/radio/group/option/Index.svelte +++ b/frontend/antd/radio/group/option/Index.svelte @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; value?: string; label?: string; @@ -45,6 +45,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, diff --git a/frontend/antd/rate/Index.svelte b/frontend/antd/rate/Index.svelte index eb6775a3..475a8d55 100644 --- a/frontend/antd/rate/Index.svelte +++ b/frontend/antd/rate/Index.svelte @@ -10,7 +10,7 @@ const AwaitedRate = importComponent(() => import('./rate')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -37,7 +37,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -74,7 +75,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/result/Index.svelte b/frontend/antd/result/Index.svelte index 8aacd506..d71c4bb4 100644 --- a/frontend/antd/result/Index.svelte +++ b/frontend/antd/result/Index.svelte @@ -10,7 +10,7 @@ const AwaitedResult = importComponent(() => import('./result')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -28,6 +28,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -53,7 +54,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/segmented/Index.svelte b/frontend/antd/segmented/Index.svelte index b091b066..21a82787 100644 --- a/frontend/antd/segmented/Index.svelte +++ b/frontend/antd/segmented/Index.svelte @@ -6,12 +6,13 @@ } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; + import type { SegmentedProps } from './segmented'; const AwaitedSegmented = importComponent(() => import('./segmented')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -36,7 +37,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -76,7 +78,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/segmented/option/Index.svelte b/frontend/antd/segmented/option/Index.svelte index 6906a3f5..96d1b54f 100644 --- a/frontend/antd/segmented/option/Index.svelte +++ b/frontend/antd/segmented/option/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { layout?: boolean; @@ -35,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +64,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/select/Index.svelte b/frontend/antd/select/Index.svelte index 2a28e83e..3bf721dd 100644 --- a/frontend/antd/select/Index.svelte +++ b/frontend/antd/select/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSelect = importComponent(() => import('./select')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -37,7 +37,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -75,7 +76,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/select/option/Index.svelte b/frontend/antd/select/option/Index.svelte index 5e7dc86c..212d3e9c 100644 --- a/frontend/antd/select/option/Index.svelte +++ b/frontend/antd/select/option/Index.svelte @@ -4,13 +4,16 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import {Keys + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedSelectOption = importComponent(() => import('./select.option')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -30,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -58,7 +62,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/skeleton/Index.svelte b/frontend/antd/skeleton/Index.svelte index cec8af90..70645c9c 100644 --- a/frontend/antd/skeleton/Index.svelte +++ b/frontend/antd/skeleton/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSkeleton = importComponent(() => import('./skeleton')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -28,6 +28,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -53,7 +54,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/skeleton/avatar/Index.svelte b/frontend/antd/skeleton/avatar/Index.svelte index 7d1bb6e7..b0ec9109 100644 --- a/frontend/antd/skeleton/avatar/Index.svelte +++ b/frontend/antd/skeleton/avatar/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: Record; @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/skeleton/button/Index.svelte b/frontend/antd/skeleton/button/Index.svelte index b5fc22de..8c861f2b 100644 --- a/frontend/antd/skeleton/button/Index.svelte +++ b/frontend/antd/skeleton/button/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: Record; @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/skeleton/image/Index.svelte b/frontend/antd/skeleton/image/Index.svelte index 63f67abd..831d3c68 100644 --- a/frontend/antd/skeleton/image/Index.svelte +++ b/frontend/antd/skeleton/image/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: Record; @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/skeleton/input/Index.svelte b/frontend/antd/skeleton/input/Index.svelte index 0c45ab3d..c78fff7e 100644 --- a/frontend/antd/skeleton/input/Index.svelte +++ b/frontend/antd/skeleton/input/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: Record; @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/skeleton/node/Index.svelte b/frontend/antd/skeleton/node/Index.svelte index c3467e75..1d119166 100644 --- a/frontend/antd/skeleton/node/Index.svelte +++ b/frontend/antd/skeleton/node/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSkeletonNode = importComponent(() => import('./skeleton.node')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: Record; @@ -27,6 +27,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -52,7 +53,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/slider/Index.svelte b/frontend/antd/slider/Index.svelte index 854b2124..716d6085 100644 --- a/frontend/antd/slider/Index.svelte +++ b/frontend/antd/slider/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSlider = importComponent(() => import('./slider')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -72,7 +73,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/slider/mark/Index.svelte b/frontend/antd/slider/mark/Index.svelte index 73ae2695..762c0257 100644 --- a/frontend/antd/slider/mark/Index.svelte +++ b/frontend/antd/slider/mark/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedSliderMark = importComponent(() => import('./slider.mark')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -33,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -66,7 +67,7 @@ > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} diff --git a/frontend/antd/space/Index.svelte b/frontend/antd/space/Index.svelte index 6fe9c072..448af26e 100644 --- a/frontend/antd/space/Index.svelte +++ b/frontend/antd/space/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSpace = importComponent(() => import('./space')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -28,6 +28,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -53,7 +54,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/space/compact/Index.svelte b/frontend/antd/space/compact/Index.svelte index 84a86644..6307e85c 100644 --- a/frontend/antd/space/compact/Index.svelte +++ b/frontend/antd/space/compact/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSpaceCompact = importComponent(() => import('./space.compact')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: {}; @@ -27,6 +27,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -52,7 +53,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/spin/Index.svelte b/frontend/antd/spin/Index.svelte index 2d2e7b40..73a6daf1 100644 --- a/frontend/antd/spin/Index.svelte +++ b/frontend/antd/spin/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSpin = importComponent(() => import('./spin')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/splitter/Index.svelte b/frontend/antd/splitter/Index.svelte index 2e426aec..b83a4403 100644 --- a/frontend/antd/splitter/Index.svelte +++ b/frontend/antd/splitter/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSplitter = importComponent(() => import('./splitter')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -34,7 +34,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -63,7 +64,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/splitter/panel/Index.svelte b/frontend/antd/splitter/panel/Index.svelte index 46ed4ca8..cd8cb622 100644 --- a/frontend/antd/splitter/panel/Index.svelte +++ b/frontend/antd/splitter/panel/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -32,6 +32,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +64,7 @@ > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} diff --git a/frontend/antd/statistic/Index.svelte b/frontend/antd/statistic/Index.svelte index e95a9b40..f756d0fc 100644 --- a/frontend/antd/statistic/Index.svelte +++ b/frontend/antd/statistic/Index.svelte @@ -10,7 +10,7 @@ const AwaitedStatistic = importComponent(() => import('./statistic')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -57,7 +58,7 @@ slots={slots.value} value={proceedProps.additionalProps.value ?? proceedProps.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/statistic/countdown/Index.svelte b/frontend/antd/statistic/countdown/Index.svelte index 7362cd4b..db8fc89a 100644 --- a/frontend/antd/statistic/countdown/Index.svelte +++ b/frontend/antd/statistic/countdown/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: {}; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -58,7 +59,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/statistic/timer/Index.svelte b/frontend/antd/statistic/timer/Index.svelte index 171c9bb3..1bb88f77 100644 --- a/frontend/antd/statistic/timer/Index.svelte +++ b/frontend/antd/statistic/timer/Index.svelte @@ -6,12 +6,13 @@ } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; + import type StatisticTimer from './statistic.timer'; const AwaitedTimer = importComponent(() => import('./statistic.timer')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: {}; @@ -30,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -62,7 +64,7 @@ {type} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/steps/Index.svelte b/frontend/antd/steps/Index.svelte index 05540f83..0c101271 100644 --- a/frontend/antd/steps/Index.svelte +++ b/frontend/antd/steps/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSteps = importComponent(() => import('./steps')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -55,7 +56,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/steps/item/Index.svelte b/frontend/antd/steps/item/Index.svelte index 646ff4af..4fc98787 100644 --- a/frontend/antd/steps/item/Index.svelte +++ b/frontend/antd/steps/item/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedStepsItem = importComponent(() => import('./steps.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; }>(() => props); @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -57,7 +58,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/switch/Index.svelte b/frontend/antd/switch/Index.svelte index e48cb582..56dfaa81 100644 --- a/frontend/antd/switch/Index.svelte +++ b/frontend/antd/switch/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSwitch = importComponent(() => import('./switch')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -31,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +64,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/table/Index.svelte b/frontend/antd/table/Index.svelte index ccb39198..63633840 100644 --- a/frontend/antd/table/Index.svelte +++ b/frontend/antd/table/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTable = importComponent(() => import('./table')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -28,6 +28,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -53,7 +54,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/table/column-group/Index.svelte b/frontend/antd/table/column-group/Index.svelte index 58dda65d..58bbab4b 100644 --- a/frontend/antd/table/column-group/Index.svelte +++ b/frontend/antd/table/column-group/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: {}; @@ -32,6 +32,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -60,7 +61,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/table/column/Index.svelte b/frontend/antd/table/column/Index.svelte index 8c0c5f0e..9e6c2abb 100644 --- a/frontend/antd/table/column/Index.svelte +++ b/frontend/antd/table/column/Index.svelte @@ -5,17 +5,18 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import { createFunction } from '@utils/createFunction'; import cls from 'classnames'; + import type { TableColumnProps } from './table.column'; const AwaitedTableColumn = importComponent(() => import('./table.column')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: {}; @@ -57,7 +58,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -195,7 +197,7 @@ itemBuiltIn={proceedProps.built_in_column} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/table/expandable/Index.svelte b/frontend/antd/table/expandable/Index.svelte index 778b7c9b..8b5261ff 100644 --- a/frontend/antd/table/expandable/Index.svelte +++ b/frontend/antd/table/expandable/Index.svelte @@ -14,7 +14,7 @@ const AwaitedExpandable = importComponent(() => import('./table.expandable')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -46,7 +46,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -116,7 +117,7 @@ itemIndex={proceedProps._internal.index || 0} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/table/row-selection/Index.svelte b/frontend/antd/table/row-selection/Index.svelte index 58a79030..4648dd22 100644 --- a/frontend/antd/table/row-selection/Index.svelte +++ b/frontend/antd/table/row-selection/Index.svelte @@ -16,7 +16,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -41,6 +41,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -108,7 +109,7 @@ itemIndex={proceedProps._internal.index || 0} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/table/row-selection/selection/Index.svelte b/frontend/antd/table/row-selection/selection/Index.svelte index 07a0a111..abef3f4b 100644 --- a/frontend/antd/table/row-selection/selection/Index.svelte +++ b/frontend/antd/table/row-selection/selection/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -38,6 +38,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -71,7 +72,7 @@ itemBuiltIn={proceedProps.built_in_selection} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/tabs/Index.svelte b/frontend/antd/tabs/Index.svelte index 6820b639..4b7cfa64 100644 --- a/frontend/antd/tabs/Index.svelte +++ b/frontend/antd/tabs/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTabs = importComponent(() => import('./tabs')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; @@ -31,7 +31,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -61,7 +62,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tabs/item/Index.svelte b/frontend/antd/tabs/item/Index.svelte index d06673cd..73030d17 100644 --- a/frontend/antd/tabs/item/Index.svelte +++ b/frontend/antd/tabs/item/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedTabsItem = importComponent(() => import('./tabs.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; }>(() => props); @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -70,7 +71,7 @@ > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} diff --git a/frontend/antd/tag/Index.svelte b/frontend/antd/tag/Index.svelte index 8b04bad9..ea735bae 100644 --- a/frontend/antd/tag/Index.svelte +++ b/frontend/antd/tag/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTag = importComponent(() => import('./tag')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -32,6 +32,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -59,7 +60,7 @@ slots={slots.value} value={proceedProps.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tag/checkable-tag/Index.svelte b/frontend/antd/tag/checkable-tag/Index.svelte index 31fad660..20faa50f 100644 --- a/frontend/antd/tag/checkable-tag/Index.svelte +++ b/frontend/antd/tag/checkable-tag/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -34,6 +34,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -64,7 +65,7 @@ updateProps({ value: checked }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/time-picker/Index.svelte b/frontend/antd/time-picker/Index.svelte index d9a2f192..19ee576b 100644 --- a/frontend/antd/time-picker/Index.svelte +++ b/frontend/antd/time-picker/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTimePicker = importComponent(() => import('./time-picker')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -37,7 +37,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -74,7 +75,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/time-picker/range-picker/Index.svelte b/frontend/antd/time-picker/range-picker/Index.svelte index 26a9a985..283135a8 100644 --- a/frontend/antd/time-picker/range-picker/Index.svelte +++ b/frontend/antd/time-picker/range-picker/Index.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -73,7 +74,7 @@ updateProps({ value: val }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/timeline/Index.svelte b/frontend/antd/timeline/Index.svelte index 660cd8d4..c595a2e1 100644 --- a/frontend/antd/timeline/Index.svelte +++ b/frontend/antd/timeline/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTimeline = importComponent(() => import('./timeline')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; @@ -27,6 +27,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -52,7 +53,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/timeline/item/Index.svelte b/frontend/antd/timeline/item/Index.svelte index 05c0e250..d4ec998c 100644 --- a/frontend/antd/timeline/item/Index.svelte +++ b/frontend/antd/timeline/item/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedTimelineItem = importComponent(() => import('./timeline.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; }>(() => props); @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +64,7 @@ > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} diff --git a/frontend/antd/tooltip/Index.svelte b/frontend/antd/tooltip/Index.svelte index a84b2e0e..d82defc9 100644 --- a/frontend/antd/tooltip/Index.svelte +++ b/frontend/antd/tooltip/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTooltip = importComponent(() => import('./tooltip')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -33,7 +33,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -62,7 +63,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tour/Index.svelte b/frontend/antd/tour/Index.svelte index bde4506f..1b2df794 100644 --- a/frontend/antd/tour/Index.svelte +++ b/frontend/antd/tour/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTour = importComponent(() => import('./tour')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; @@ -27,6 +27,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -52,7 +53,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tour/step/Index.svelte b/frontend/antd/tour/step/Index.svelte index 2d2268e9..0b3715c4 100644 --- a/frontend/antd/tour/step/Index.svelte +++ b/frontend/antd/tour/step/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import { createFunction } from '@utils/createFunction'; import cls from 'classnames'; @@ -14,7 +14,7 @@ const AwaitedTourStep = importComponent(() => import('./tour.step')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; _internal: {}; get_target?: string; @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -74,7 +75,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/transfer/Index.svelte b/frontend/antd/transfer/Index.svelte index 42698c9a..68d087a7 100644 --- a/frontend/antd/transfer/Index.svelte +++ b/frontend/antd/transfer/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTransfer = importComponent(() => import('./transfer')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -37,7 +37,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -74,7 +75,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tree-select/Index.svelte b/frontend/antd/tree-select/Index.svelte index 9962a528..5b8b8b03 100644 --- a/frontend/antd/tree-select/Index.svelte +++ b/frontend/antd/tree-select/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTreeSelect = importComponent(() => import('./tree-select')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -40,7 +40,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -79,7 +80,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tree-select/tree-node/Index.svelte b/frontend/antd/tree-select/tree-node/Index.svelte index 1e889875..009d91df 100644 --- a/frontend/antd/tree-select/tree-node/Index.svelte +++ b/frontend/antd/tree-select/tree-node/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -15,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -35,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -72,7 +73,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tree/Index.svelte b/frontend/antd/tree/Index.svelte index 763fdab4..2e11d85d 100644 --- a/frontend/antd/tree/Index.svelte +++ b/frontend/antd/tree/Index.svelte @@ -10,7 +10,7 @@ const AwaitedTree = importComponent(() => import('./tree')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -37,7 +37,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -72,7 +73,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tree/directory-tree/Index.svelte b/frontend/antd/tree/directory-tree/Index.svelte index c74d04f2..84d238b5 100644 --- a/frontend/antd/tree/directory-tree/Index.svelte +++ b/frontend/antd/tree/directory-tree/Index.svelte @@ -10,7 +10,7 @@ const AwaitedDirectoryTree = importComponent(() => import('../tree')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: {}; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -75,7 +76,7 @@ slots={slots.value} directory > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/tree/tree-node/Index.svelte b/frontend/antd/tree/tree-node/Index.svelte index b4245c2d..cd3543ca 100644 --- a/frontend/antd/tree/tree-node/Index.svelte +++ b/frontend/antd/tree/tree-node/Index.svelte @@ -5,15 +5,15 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedTreeNode = importComponent(() => import('./tree.tree-node')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -33,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -67,7 +68,7 @@ itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - {@render children()} + {@render children?.()} {/if} {/await} diff --git a/frontend/antd/typography/Base.svelte b/frontend/antd/typography/Base.svelte index 4ae564db..ce94968a 100644 --- a/frontend/antd/typography/Base.svelte +++ b/frontend/antd/typography/Base.svelte @@ -16,7 +16,7 @@ component: 'text' | 'title' | 'paragraph' | 'link'; children?: Snippet; } = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; component: 'text' | 'title' | 'paragraph' | 'link'; @@ -42,7 +42,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -77,7 +78,7 @@ slots={slots.value} > {#if proceedProps._internal.layout} - {@render children()} + {@render children?.()} {:else} {proceedProps.value} {/if} diff --git a/frontend/antd/upload/Index.svelte b/frontend/antd/upload/Index.svelte index 0a8d70c5..596e1b99 100644 --- a/frontend/antd/upload/Index.svelte +++ b/frontend/antd/upload/Index.svelte @@ -91,7 +91,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/upload/dragger/Index.svelte b/frontend/antd/upload/dragger/Index.svelte index 83f2e0f1..1536755a 100644 --- a/frontend/antd/upload/dragger/Index.svelte +++ b/frontend/antd/upload/dragger/Index.svelte @@ -40,6 +40,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -49,7 +50,6 @@ elem_classes, elem_style, value, - gradio, }; }, { @@ -93,7 +93,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antd/watermark/Index.svelte b/frontend/antd/watermark/Index.svelte index 6c5b7485..ee8b5433 100644 --- a/frontend/antd/watermark/Index.svelte +++ b/frontend/antd/watermark/Index.svelte @@ -10,7 +10,7 @@ const AwaitedWatermark = importComponent(() => import('./watermark')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -57,7 +58,7 @@ slots={slots.value} content={proceedProps.additionalProps.content ?? proceedProps.content} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/actions/Index.svelte b/frontend/antdx/actions/Index.svelte index ee9bf7a6..8b85b16a 100644 --- a/frontend/antdx/actions/Index.svelte +++ b/frontend/antdx/actions/Index.svelte @@ -10,7 +10,7 @@ const AwaitedActions = importComponent(() => import('./actions')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -55,7 +56,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/actions/item/Index.svelte b/frontend/antdx/actions/item/Index.svelte index 9245d4f8..c444e509 100644 --- a/frontend/antdx/actions/item/Index.svelte +++ b/frontend/antdx/actions/item/Index.svelte @@ -4,13 +4,16 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import {Keys + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedActionsItem = importComponent(() => import('./actions.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -30,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -58,7 +62,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/attachments/Index.svelte b/frontend/antdx/attachments/Index.svelte index edcc2bae..92c5e923 100644 --- a/frontend/antdx/attachments/Index.svelte +++ b/frontend/antdx/attachments/Index.svelte @@ -11,7 +11,7 @@ const AwaitedAttachments = importComponent(() => import('./attachments')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -35,7 +35,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -88,7 +89,7 @@ }); }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/attachments/file-card/Index.svelte b/frontend/antdx/attachments/file-card/Index.svelte index f42fe8f1..094be650 100644 --- a/frontend/antdx/attachments/file-card/Index.svelte +++ b/frontend/antdx/attachments/file-card/Index.svelte @@ -4,7 +4,10 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import {Keys + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedFileCard = importComponent( @@ -12,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -32,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +67,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/bubble/Index.svelte b/frontend/antdx/bubble/Index.svelte index 53df6394..da7b37db 100644 --- a/frontend/antdx/bubble/Index.svelte +++ b/frontend/antdx/bubble/Index.svelte @@ -10,7 +10,7 @@ const AwaitedBubble = importComponent(() => import('./bubble')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -33,7 +33,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -62,7 +63,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/bubble/list/Index.svelte b/frontend/antdx/bubble/list/Index.svelte index 23c63608..1fca25ab 100644 --- a/frontend/antdx/bubble/list/Index.svelte +++ b/frontend/antdx/bubble/list/Index.svelte @@ -10,7 +10,7 @@ const AwaitedBubbleList = importComponent(() => import('./bubble.list')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/bubble/list/item/Item.svelte b/frontend/antdx/bubble/list/item/Item.svelte index 478a1e2d..02699713 100644 --- a/frontend/antdx/bubble/list/item/Item.svelte +++ b/frontend/antdx/bubble/list/item/Item.svelte @@ -4,7 +4,10 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import {Keys + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedBubbleListItem = importComponent( @@ -12,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -32,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -60,7 +64,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/bubble/list/role/Role.svelte b/frontend/antdx/bubble/list/role/Role.svelte index 167bc7c5..34ed9a35 100644 --- a/frontend/antdx/bubble/list/role/Role.svelte +++ b/frontend/antdx/bubble/list/role/Role.svelte @@ -12,7 +12,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -31,6 +31,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -56,7 +57,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/conversations/Index.svelte b/frontend/antdx/conversations/Index.svelte index 7c4dde82..d6def25c 100644 --- a/frontend/antdx/conversations/Index.svelte +++ b/frontend/antdx/conversations/Index.svelte @@ -10,7 +10,7 @@ const AwaitedConversations = importComponent(() => import('./conversations')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -33,7 +33,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -62,7 +63,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/conversations/item/Index.svelte b/frontend/antdx/conversations/item/Index.svelte index bbb12c6b..5b063bd8 100644 --- a/frontend/antdx/conversations/item/Index.svelte +++ b/frontend/antdx/conversations/item/Index.svelte @@ -4,7 +4,10 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import {Keys + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedConversationsItem = importComponent( @@ -12,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -32,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +67,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/prompts/Index.svelte b/frontend/antdx/prompts/Index.svelte index f57a72ec..3abbff6e 100644 --- a/frontend/antdx/prompts/Index.svelte +++ b/frontend/antdx/prompts/Index.svelte @@ -10,7 +10,7 @@ const AwaitedPrompts = importComponent(() => import('./prompts')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -33,7 +33,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -62,7 +63,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/prompts/item/Index.svelte b/frontend/antdx/prompts/item/Index.svelte index 0c74f774..2fab88a4 100644 --- a/frontend/antdx/prompts/item/Index.svelte +++ b/frontend/antdx/prompts/item/Index.svelte @@ -4,13 +4,16 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedPromptsItem = importComponent(() => import('./prompts.item')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -30,6 +33,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -58,7 +62,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/sender/Index.svelte b/frontend/antdx/sender/Index.svelte index 238adca2..e95a9331 100644 --- a/frontend/antdx/sender/Index.svelte +++ b/frontend/antdx/sender/Index.svelte @@ -11,7 +11,7 @@ const AwaitedSender = importComponent(() => import('./sender')); const props = $props(); - const { getComponentProps, getAdditionalProps, children, updateProps } = + const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = getProps<{ additional_props?: Record; @@ -42,7 +42,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -92,7 +93,7 @@ }} {upload} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/sender/header/Index.svelte b/frontend/antdx/sender/header/Index.svelte index 858896f5..f5ad18f1 100644 --- a/frontend/antdx/sender/header/Index.svelte +++ b/frontend/antdx/sender/header/Index.svelte @@ -10,7 +10,7 @@ const AwaitedSenderHeader = importComponent(() => import('./sender.header')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -29,6 +29,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -54,7 +55,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/suggestion/Index.svelte b/frontend/antdx/suggestion/Index.svelte index d1e7491b..c0f30c76 100644 --- a/frontend/antdx/suggestion/Index.svelte +++ b/frontend/antdx/suggestion/Index.svelte @@ -11,7 +11,7 @@ const AwaitedSuggestion = importComponent(() => import('./suggestion')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -36,7 +36,8 @@ ...restProps } = getComponentProps(); return { - additionalProps: getAdditionalProps(), + gradio, + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -67,7 +68,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/suggestion/item/Index.svelte b/frontend/antdx/suggestion/item/Index.svelte index 8f1c2c85..5ffc1d0d 100644 --- a/frontend/antdx/suggestion/item/Index.svelte +++ b/frontend/antdx/suggestion/item/Index.svelte @@ -4,7 +4,10 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedSuggestionItem = importComponent( @@ -12,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -32,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -60,7 +64,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/thought-chain/Index.svelte b/frontend/antdx/thought-chain/Index.svelte index 2a6b642a..d185b697 100644 --- a/frontend/antdx/thought-chain/Index.svelte +++ b/frontend/antdx/thought-chain/Index.svelte @@ -10,7 +10,7 @@ const AwaitedThoughtChain = importComponent(() => import('./thought-chain')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -30,6 +30,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -55,7 +56,7 @@ {...proceedProps.additionalProps} slots={slots.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/thought-chain/item/Index.svelte b/frontend/antdx/thought-chain/item/Index.svelte index 2a5cad23..f92ccd3f 100644 --- a/frontend/antdx/thought-chain/item/Index.svelte +++ b/frontend/antdx/thought-chain/item/Index.svelte @@ -4,7 +4,10 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots, getSlotKey } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { + getSlots, + getSlotKey, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedThoughtChainItem = importComponent( @@ -12,7 +15,7 @@ ); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; _internal: { @@ -32,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +67,7 @@ itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/welcome/Index.svelte b/frontend/antdx/welcome/Index.svelte index 6a768bbf..210dfa6c 100644 --- a/frontend/antdx/welcome/Index.svelte +++ b/frontend/antdx/welcome/Index.svelte @@ -10,7 +10,7 @@ const AwaitedWelcome = importComponent(() => import('./welcome')); const props = $props(); - const { getComponentProps, getAdditionalProps, children } = getProps<{ + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; @@ -34,6 +34,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -63,7 +64,7 @@ urlRoot={proceedProps.root} urlProxyUrl={proceedProps.proxy_url} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/antdx/x-provider/XProvider.svelte b/frontend/antdx/x-provider/XProvider.svelte index 6afe5a5e..78204317 100644 --- a/frontend/antdx/x-provider/XProvider.svelte +++ b/frontend/antdx/x-provider/XProvider.svelte @@ -35,6 +35,7 @@ ...restProps } = getComponentProps(); return { + gradio, additionalProps: getAdditionalProps(), _internal, as_item, @@ -43,7 +44,6 @@ elem_id, elem_classes, elem_style, - gradio, }; }); const proceedProps = $derived(getProceedProps()); @@ -80,7 +80,7 @@ slotParamsFn = params; }} > - {@render children()} + {@render children?.()} {/await} {/if} diff --git a/frontend/base/auto-loading/Index.svelte b/frontend/base/auto-loading/Index.svelte index 50760a1b..eacbb25e 100644 --- a/frontend/base/auto-loading/Index.svelte +++ b/frontend/base/auto-loading/Index.svelte @@ -1,18 +1,18 @@ {#await AwaitedAnchorItem then AnchorItem} diff --git a/frontend/antd/auto-complete/option/Index.svelte b/frontend/antd/auto-complete/option/Index.svelte index c1fba290..24bdd53e 100644 --- a/frontend/antd/auto-complete/option/Index.svelte +++ b/frontend/antd/auto-complete/option/Index.svelte @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,7 +50,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} diff --git a/frontend/antd/breadcrumb/item/Index.svelte b/frontend/antd/breadcrumb/item/Index.svelte index 19f21328..519c10e7 100644 --- a/frontend/antd/breadcrumb/item/Index.svelte +++ b/frontend/antd/breadcrumb/item/Index.svelte @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,7 +50,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedBreadcrumbItem then BreadcrumbItem} diff --git a/frontend/antd/breadcrumb/item/breadcrumb.item.tsx b/frontend/antd/breadcrumb/item/breadcrumb.item.tsx index a593ce4e..01ebbcbb 100644 --- a/frontend/antd/breadcrumb/item/breadcrumb.item.tsx +++ b/frontend/antd/breadcrumb/item/breadcrumb.item.tsx @@ -15,7 +15,20 @@ import { ItemHandler, type ItemHandlerProps } from '../context'; export const BreadcrumbItem = sveltify< BreadcrumbItemProps & ItemHandlerProps & { - itemSlots: Record; + itemSlots: Record< + [ + 'title', + 'menu.expandIcon', + 'menu.overflowedIndicator', + 'menu.items', + 'dropdownProps.dropdownRender', + 'dropdownProps.popupRender', + 'dropdownProps.menu.expandIcon', + 'dropdownProps.menu.overflowedIndicator', + 'dropdownProps.menu.items', + ][number], + HTMLElement + >; } >( withMenuItemsContextProvider( @@ -34,7 +47,7 @@ export const BreadcrumbItem = sveltify< const menu = { ...(itemProps.menu || {}), items: - itemProps.menu?.items || menuItems.length > 0 + itemProps.menu?.items || menuItems?.length > 0 ? renderItems(menuItems, { clone: true, }) @@ -57,7 +70,7 @@ export const BreadcrumbItem = sveltify< ...(itemProps.dropdownProps?.menu || {}), items: itemProps.dropdownProps?.menu?.items || - dropdownMenuItems.length > 0 + dropdownMenuItems?.length > 0 ? renderItems(dropdownMenuItems, { clone: true, }) @@ -106,8 +119,10 @@ export const BreadcrumbItem = sveltify< ? dropdownMenu : undefined, }; + return { ...itemProps, + title: renderSlot(slots.title) || itemProps.title, menu: Object.values(menu).filter(Boolean).length > 0 ? menu diff --git a/frontend/antd/cascader/option/Index.svelte b/frontend/antd/cascader/option/Index.svelte index 6a3b2fcc..21792567 100644 --- a/frontend/antd/cascader/option/Index.svelte +++ b/frontend/antd/cascader/option/Index.svelte @@ -4,9 +4,9 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import {Keys - getSlots, + import { getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,7 +50,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} diff --git a/frontend/antd/checkbox/group/option/Index.svelte b/frontend/antd/checkbox/group/option/Index.svelte index 4e276a64..d1673c87 100644 --- a/frontend/antd/checkbox/group/option/Index.svelte +++ b/frontend/antd/checkbox/group/option/Index.svelte @@ -26,6 +26,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -57,7 +58,6 @@ }); const proceedProps = $derived(getProceedProps()); - const slotKey = getSlotKey(); const slots = getSlots(); const itemProps = $derived({ diff --git a/frontend/antd/collapse/item/Index.svelte b/frontend/antd/collapse/item/Index.svelte index 2ce7e44c..37757eee 100644 --- a/frontend/antd/collapse/item/Index.svelte +++ b/frontend/antd/collapse/item/Index.svelte @@ -21,6 +21,7 @@ }; item_click?: any; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps( () => { @@ -35,7 +36,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -54,7 +55,6 @@ let slot = $state(); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedCollapseItem then CollapseItem} diff --git a/frontend/antd/color-picker/preset/Index.svelte b/frontend/antd/color-picker/preset/Index.svelte index 432cc5aa..ab0d40cd 100644 --- a/frontend/antd/color-picker/preset/Index.svelte +++ b/frontend/antd/color-picker/preset/Index.svelte @@ -22,6 +22,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -48,7 +49,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedColorPickerPreset then ColorPickerPreset} diff --git a/frontend/antd/date-picker/preset/Index.svelte b/frontend/antd/date-picker/preset/Index.svelte index f3c22908..f2f90125 100644 --- a/frontend/antd/date-picker/preset/Index.svelte +++ b/frontend/antd/date-picker/preset/Index.svelte @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -51,7 +52,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedDatePickerPreset then DatePickerPreset} diff --git a/frontend/antd/descriptions/item/Index.svelte b/frontend/antd/descriptions/item/Index.svelte index 64e04f4f..d5823146 100644 --- a/frontend/antd/descriptions/item/Index.svelte +++ b/frontend/antd/descriptions/item/Index.svelte @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -50,7 +51,6 @@ let slot = $state(); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedDescriptionsItem then DescriptionsItem} diff --git a/frontend/antd/form/item/rule/Index.svelte b/frontend/antd/form/item/rule/Index.svelte index 0424670f..7da2dedd 100644 --- a/frontend/antd/form/item/rule/Index.svelte +++ b/frontend/antd/form/item/rule/Index.svelte @@ -17,6 +17,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -42,8 +43,6 @@ }); const proceedProps = $derived(getProceedProps()); - const slotKey = getSlotKey(); - const itemProps = $derived({ props: { ...proceedProps.restProps, diff --git a/frontend/antd/layout/Base.svelte b/frontend/antd/layout/Base.svelte index ac4d558c..82d0c8e2 100644 --- a/frontend/antd/layout/Base.svelte +++ b/frontend/antd/layout/Base.svelte @@ -17,7 +17,6 @@ const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; - component: 'header' | 'footer' | 'content' | 'layout'; as_item?: string | undefined; _internal: { layout?: boolean; @@ -32,7 +31,6 @@ elem_classes, elem_id, elem_style, - component, ...restProps } = getComponentProps(); return { @@ -45,7 +43,6 @@ elem_id, elem_classes, elem_style, - component, }; }); const proceedProps = $derived(getProceedProps()); @@ -56,7 +53,7 @@ {#if proceedProps.visible} {#await AwaitedLayoutBase then LayoutBase} (() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -50,7 +51,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedMentionsOption then MentionsOption} diff --git a/frontend/antd/menu/item/Index.svelte b/frontend/antd/menu/item/Index.svelte index 1f765ca4..889702c4 100644 --- a/frontend/antd/menu/item/Index.svelte +++ b/frontend/antd/menu/item/Index.svelte @@ -21,6 +21,7 @@ }; title_click?: any; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps( () => { @@ -35,7 +36,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -52,7 +53,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedMenuItem then MenuItem} diff --git a/frontend/antd/radio/group/option/Index.svelte b/frontend/antd/radio/group/option/Index.svelte index c9b5bee1..d3cb4aba 100644 --- a/frontend/antd/radio/group/option/Index.svelte +++ b/frontend/antd/radio/group/option/Index.svelte @@ -28,6 +28,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -63,7 +64,6 @@ }); const proceedProps = $derived(getProceedProps()); - const slotKey = getSlotKey(); const slots = getSlots(); const itemProps = $derived({ diff --git a/frontend/antd/segmented/option/Index.svelte b/frontend/antd/segmented/option/Index.svelte index 96d1b54f..f21b996b 100644 --- a/frontend/antd/segmented/option/Index.svelte +++ b/frontend/antd/segmented/option/Index.svelte @@ -23,6 +23,7 @@ }; value: string | number; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,7 +50,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedSegmentedOption then SegmentedOption} diff --git a/frontend/antd/select/option/Index.svelte b/frontend/antd/select/option/Index.svelte index 212d3e9c..c29dbc70 100644 --- a/frontend/antd/select/option/Index.svelte +++ b/frontend/antd/select/option/Index.svelte @@ -4,9 +4,9 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import {Keys - getSlots, + import { getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -21,6 +21,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -47,7 +48,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} diff --git a/frontend/antd/slider/mark/Index.svelte b/frontend/antd/slider/mark/Index.svelte index 762c0257..af213aec 100644 --- a/frontend/antd/slider/mark/Index.svelte +++ b/frontend/antd/slider/mark/Index.svelte @@ -21,6 +21,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -47,7 +48,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); let slot = $state(); diff --git a/frontend/antd/splitter/panel/Index.svelte b/frontend/antd/splitter/panel/Index.svelte index cd8cb622..f3a8249e 100644 --- a/frontend/antd/splitter/panel/Index.svelte +++ b/frontend/antd/splitter/panel/Index.svelte @@ -20,6 +20,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -45,8 +46,6 @@ }); const proceedProps = $derived(getProceedProps()); - const slotKey = getSlotKey(); - let slot = $state(); diff --git a/frontend/antd/steps/item/Index.svelte b/frontend/antd/steps/item/Index.svelte index 4fc98787..a2b6a9c8 100644 --- a/frontend/antd/steps/item/Index.svelte +++ b/frontend/antd/steps/item/Index.svelte @@ -17,6 +17,7 @@ additional_props?: Record; _internal: {}; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -43,7 +44,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} diff --git a/frontend/antd/table/column-group/Index.svelte b/frontend/antd/table/column-group/Index.svelte index 58bbab4b..7fb818f1 100644 --- a/frontend/antd/table/column-group/Index.svelte +++ b/frontend/antd/table/column-group/Index.svelte @@ -20,6 +20,7 @@ as_item?: string | undefined; _internal: {}; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -46,7 +47,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedColumnGroup then ColumnGroup} diff --git a/frontend/antd/table/column/Index.svelte b/frontend/antd/table/column/Index.svelte index 9e6c2abb..1a01775f 100644 --- a/frontend/antd/table/column/Index.svelte +++ b/frontend/antd/table/column/Index.svelte @@ -34,6 +34,7 @@ filter_icon?: TableColumnProps['filterIcon']; filter_dropdown?: TableColumnProps['filterDropdown']; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps( () => { @@ -59,7 +60,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -88,7 +89,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); const itemProps = $derived.by(() => { { const showSorterTooltip = @@ -163,22 +163,27 @@ ...slots.value, filterIcon: { el: slots.value.filterIcon, + withParams: true, clone: true, }, filterDropdown: { el: slots.value.filterDropdown, + withParams: true, clone: true, }, sortIcon: { el: slots.value.sortIcon, + withParams: true, clone: true, }, title: { el: slots.value.title, + withParams: true, clone: true, }, render: { el: slots.value.render, + withParams: true, clone: true, }, }, diff --git a/frontend/antd/table/column/table.column.tsx b/frontend/antd/table/column/table.column.tsx index 3bbf30da..aa7f87d7 100644 --- a/frontend/antd/table/column/table.column.tsx +++ b/frontend/antd/table/column/table.column.tsx @@ -32,7 +32,7 @@ export const TableColumn = sveltify( ...(itemProps.filterDropdownProps?.menu || {}), items: itemProps.filterDropdownProps?.menu?.items || - dropdownMenuItems.length > 0 + dropdownMenuItems?.length > 0 ? renderItems(dropdownMenuItems, { clone: true, }) diff --git a/frontend/antd/table/expandable/Index.svelte b/frontend/antd/table/expandable/Index.svelte index 8b5261ff..ad63c347 100644 --- a/frontend/antd/table/expandable/Index.svelte +++ b/frontend/antd/table/expandable/Index.svelte @@ -28,6 +28,7 @@ expand_icon?: string; column_title?: string; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps( () => { @@ -47,7 +48,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -69,7 +70,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); const itemProps = $derived({ props: { style: proceedProps.elem_style, @@ -99,10 +99,12 @@ ...slots.value, expandIcon: { el: slots.value['expandIcon'], + withParams: true, clone: true, }, expandedRowRender: { el: slots.value['expandedRowRender'], + withParams: true, clone: true, }, }, diff --git a/frontend/antd/table/row-selection/Index.svelte b/frontend/antd/table/row-selection/Index.svelte index 4648dd22..c6078bf6 100644 --- a/frontend/antd/table/row-selection/Index.svelte +++ b/frontend/antd/table/row-selection/Index.svelte @@ -29,6 +29,7 @@ renderCell?: string; columnTitle?: string; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -55,7 +56,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); const itemProps = $derived({ props: { @@ -91,10 +91,12 @@ selections: undefined, columnTitle: { el: slots.value.columnTitle, + withParams: true, clone: true, }, renderCell: { el: slots.value.renderCell, + withParams: true, clone: true, }, }, diff --git a/frontend/antd/table/row-selection/selection/Index.svelte b/frontend/antd/table/row-selection/selection/Index.svelte index abef3f4b..89f13ef0 100644 --- a/frontend/antd/table/row-selection/selection/Index.svelte +++ b/frontend/antd/table/row-selection/selection/Index.svelte @@ -25,6 +25,7 @@ built_in_selection?: string; text?: string; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -53,7 +54,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedSelection then Selection} diff --git a/frontend/antd/table/row-selection/table.row-selection.tsx b/frontend/antd/table/row-selection/table.row-selection.tsx index 18d4f6cd..1b3acd75 100644 --- a/frontend/antd/table/row-selection/table.row-selection.tsx +++ b/frontend/antd/table/row-selection/table.row-selection.tsx @@ -24,7 +24,7 @@ export const TableRowSelection = sveltify< return { ...itemProps, selections: - selectionsItems.length > 0 + selectionsItems?.length > 0 ? renderItems(selectionsItems) : itemProps.selections, }; diff --git a/frontend/antd/tabs/item/Index.svelte b/frontend/antd/tabs/item/Index.svelte index 73030d17..601c3a51 100644 --- a/frontend/antd/tabs/item/Index.svelte +++ b/frontend/antd/tabs/item/Index.svelte @@ -17,6 +17,7 @@ additional_props?: Record; _internal: {}; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -43,7 +44,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); let slot = $state(); diff --git a/frontend/antd/timeline/item/Index.svelte b/frontend/antd/timeline/item/Index.svelte index d4ec998c..89603c17 100644 --- a/frontend/antd/timeline/item/Index.svelte +++ b/frontend/antd/timeline/item/Index.svelte @@ -17,6 +17,7 @@ additional_props?: Record; _internal: {}; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -43,7 +44,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); let slot = $state(); diff --git a/frontend/antd/tour/step/Index.svelte b/frontend/antd/tour/step/Index.svelte index 0b3715c4..bffa61af 100644 --- a/frontend/antd/tour/step/Index.svelte +++ b/frontend/antd/tour/step/Index.svelte @@ -21,6 +21,7 @@ next_button_click?: any; prev_button_click?: any; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps( () => { @@ -36,7 +37,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -55,7 +56,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedTourStep then TourStep} diff --git a/frontend/antd/tree-select/tree-node/Index.svelte b/frontend/antd/tree-select/tree-node/Index.svelte index 009d91df..5ebfb091 100644 --- a/frontend/antd/tree-select/tree-node/Index.svelte +++ b/frontend/antd/tree-select/tree-node/Index.svelte @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,7 +50,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} @@ -67,6 +67,7 @@ ...slots.value, icon: { el: slots.value.icon, + withParams: true, clone: true, }, }} diff --git a/frontend/antd/tree/tree-node/Index.svelte b/frontend/antd/tree/tree-node/Index.svelte index cd3543ca..81c73a80 100644 --- a/frontend/antd/tree/tree-node/Index.svelte +++ b/frontend/antd/tree/tree-node/Index.svelte @@ -21,6 +21,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -47,7 +48,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#await AwaitedTreeNode then TreeNode} @@ -61,6 +61,7 @@ ...slots.value, icon: { el: slots.value.icon, + withParams: true, clone: true, }, }} diff --git a/frontend/antd/typography/Base.svelte b/frontend/antd/typography/Base.svelte index ce94968a..9ec03130 100644 --- a/frontend/antd/typography/Base.svelte +++ b/frontend/antd/typography/Base.svelte @@ -19,7 +19,6 @@ const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; - component: 'text' | 'title' | 'paragraph' | 'link'; _internal: { layout?: boolean; }; @@ -38,12 +37,11 @@ elem_id, elem_style, value, - component, ...restProps } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -52,7 +50,6 @@ elem_classes, elem_style, value, - component, }; }, { @@ -68,7 +65,7 @@ {#if proceedProps.visible} {#await AwaitedTypographyBase then TypographyBase} import type { Snippet } from 'svelte'; + import Base from '../Base.svelte'; - let { children, ...restProps }: { children?: Snippet } = $props(); + const { children, ...restProps }: { children?: Snippet } = $props(); diff --git a/frontend/antdx/actions/Index.svelte b/frontend/antdx/actions/Index.svelte index 8b85b16a..8d8bb15a 100644 --- a/frontend/antdx/actions/Index.svelte +++ b/frontend/antdx/actions/Index.svelte @@ -17,30 +17,44 @@ _internal: { layout?: boolean; }; + dropdown_open_change?: any; + dropdown_menu_click?: any; + dropdown_menu_deselect?: any; + dropdown_menu_open_change?: any; + dropdown_menu_select?: any; }>(() => props); - const getProceedProps = processProps(() => { - const { - visible, - _internal, - as_item, - elem_classes, - elem_id, - elem_style, - ...restProps - } = getComponentProps(); - return { - gradio, - additionalProps: getAdditionalProps(), - _internal, - as_item, - restProps, - visible, - elem_id, - elem_classes, - elem_style, - }; - }, {}); + const getProceedProps = processProps( + () => { + const { + visible, + _internal, + as_item, + elem_classes, + elem_id, + elem_style, + ...restProps + } = getComponentProps(); + return { + gradio, + additionalProps: getAdditionalProps(), + _internal, + as_item, + restProps, + visible, + elem_id, + elem_classes, + elem_style, + }; + }, + { + dropdown_open_change: 'dropdownProps_openChange', + dropdown_menu_click: 'dropdownProps_menu_click', + dropdown_menu_deselect: 'dropdownProps_menu_deselect', + dropdown_menu_open_change: 'dropdownProps_menu_openChange', + dropdown_menu_select: 'dropdownProps_menu_select', + } + ); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); diff --git a/frontend/antdx/actions/action-item/Index.svelte b/frontend/antdx/actions/action-item/Index.svelte new file mode 100644 index 00000000..e66bf489 --- /dev/null +++ b/frontend/antdx/actions/action-item/Index.svelte @@ -0,0 +1,98 @@ + + +{#if proceedProps.visible} + {#await AwaitedActionsActionItem then ActionsActionItem} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/actions/action-item/actions.action-item.tsx b/frontend/antdx/actions/action-item/actions.action-item.tsx new file mode 100644 index 00000000..321c2610 --- /dev/null +++ b/frontend/antdx/actions/action-item/actions.action-item.tsx @@ -0,0 +1,21 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import type { ActionsProps } from '@ant-design/x'; + +import { ItemHandler, type ItemHandlerProps } from '../context'; + +export const ActionsActionItem = sveltify< + Partial[number]> & ItemHandlerProps +>((props) => { + return ( + + {...props} + allowedSlots={['default']} + itemChildren={(items) => { + return items.default.length > 0 ? items.default : undefined; + }} + /> + ); +}); + +export default ActionsActionItem; diff --git a/frontend/antdx/attachments/file-card/gradio.config.js b/frontend/antdx/actions/action-item/gradio.config.js similarity index 100% rename from frontend/antdx/attachments/file-card/gradio.config.js rename to frontend/antdx/actions/action-item/gradio.config.js diff --git a/frontend/antdx/actions/action-item/package.json b/frontend/antdx/actions/action-item/package.json new file mode 100644 index 00000000..0be1840a --- /dev/null +++ b/frontend/antdx/actions/action-item/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-actions.action-item", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/actions/actions.tsx b/frontend/antdx/actions/actions.tsx index 3c11bfef..51f34010 100644 --- a/frontend/antdx/actions/actions.tsx +++ b/frontend/antdx/actions/actions.tsx @@ -2,38 +2,119 @@ import { sveltify } from '@svelte-preprocess-react'; import React, { useMemo } from 'react'; import { Actions as XActions, type ActionsProps } from '@ant-design/x'; import type { ItemType } from '@ant-design/x/es/actions/interface'; +import { createFunction } from '@utils/createFunction'; import { renderItems } from '@utils/renderItems'; -import classNames from 'classnames'; +import { renderParamsSlot } from '@utils/renderParamsSlot'; +import { renderSlot } from '@utils/renderSlot'; + +import { + useItems as useMenuItems, + withItemsContextProvider as withMenuItemsContextProvider, +} from '../../antd/menu/context'; import { useItems, withItemsContextProvider } from './context'; -export const Actions = sveltify>( - withItemsContextProvider( - ['default', 'items'], - ({ children, items, className, ...props }) => { - const { items: slotItems } = useItems<['default', 'items']>(); - const resolvedSlotItems = - slotItems.items.length > 0 ? slotItems.items : slotItems.default; - - return ( - <> -

{children}
- { - return ( - items || - renderItems(resolvedSlotItems, { +export const Actions = sveltify< + Partial, + [ + 'dropdownProps.dropdownRender', + 'dropdownProps.popupRender', + 'dropdownProps.menu.expandIcon', + 'dropdownProps.menu.overflowedIndicator', + 'dropdownProps.menu.items', + ] +>( + withMenuItemsContextProvider( + ['dropdownProps.menu.items'], + withItemsContextProvider( + ['default', 'items'], + ({ children, items, dropdownProps, slots, ...props }) => { + const { items: slotItems } = useItems<['default', 'items']>(); + const resolvedSlotItems = + slotItems.items.length > 0 ? slotItems.items : slotItems.default; + const { + items: { 'dropdownProps.menu.items': dropdownMenuItems }, + } = useMenuItems<['dropdownProps.menu.items']>(); + + const modifiedDropdownProps = useMemo(() => { + const dropdownMenu = { + ...(dropdownProps?.menu || {}), + items: + dropdownProps?.menu?.items || dropdownMenuItems?.length > 0 + ? renderItems(dropdownMenuItems, { + clone: true, + }) + : undefined, + expandIcon: + renderParamsSlot( + { + slots: slots, + key: 'dropdownProps.menu.expandIcon', + }, + { clone: true, - }) || - [] - ); - }, [items, resolvedSlotItems])} - /> - - ); - } + } + ) || dropdownProps?.menu?.expandIcon, + overflowedIndicator: + renderSlot(slots['dropdownProps.menu.overflowedIndicator']) || + dropdownProps?.menu?.overflowedIndicator, + }; + + const modifiedProps = { + ...(dropdownProps || {}), + dropdownRender: slots['dropdownProps.dropdownRender'] + ? renderParamsSlot( + { + slots: slots, + key: 'dropdownProps.dropdownRender', + }, + { + clone: true, + } + ) + : createFunction(dropdownProps?.dropdownRender), + popupRender: slots['dropdownProps.popupRender'] + ? renderParamsSlot( + { + slots: slots, + key: 'dropdownProps.popupRender', + }, + { + clone: true, + } + ) + : createFunction(dropdownProps?.popupRender), + menu: + Object.values(dropdownMenu).filter(Boolean).length > 0 + ? dropdownMenu + : undefined, + } as NonNullable; + + return Object.values(modifiedProps).filter(Boolean).length > 0 + ? dropdownProps + : undefined; + }, [dropdownMenuItems, dropdownProps, slots]); + + return ( + <> +
{children}
+ { + return ( + items || + renderItems(resolvedSlotItems, { + clone: true, + }) || + [] + ); + }, [items, resolvedSlotItems])} + /> + + ); + } + ) ) ); diff --git a/frontend/antdx/actions/audio/Index.svelte b/frontend/antdx/actions/audio/Index.svelte new file mode 100644 index 00000000..e048e4b1 --- /dev/null +++ b/frontend/antdx/actions/audio/Index.svelte @@ -0,0 +1,59 @@ + + +{#if proceedProps.visible} + {#await AwaitedActionsAudio then ActionsAudio} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/actions/audio/actions.audio.tsx b/frontend/antdx/actions/audio/actions.audio.tsx new file mode 100644 index 00000000..5f1394a9 --- /dev/null +++ b/frontend/antdx/actions/audio/actions.audio.tsx @@ -0,0 +1,16 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import { Actions } from '@ant-design/x'; +import type { ActionsAudioProps } from '@ant-design/x/es/actions/ActionsAudio'; + +export const ActionsAudio = sveltify( + ({ slots: _slots, ...props }) => { + return ( + <> + + + ); + } +); + +export default ActionsAudio; diff --git a/frontend/antdx/actions/audio/gradio.config.js b/frontend/antdx/actions/audio/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/actions/audio/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/actions/audio/package.json b/frontend/antdx/actions/audio/package.json new file mode 100644 index 00000000..20f5e568 --- /dev/null +++ b/frontend/antdx/actions/audio/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-actions.audio", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/actions/copy/Index.svelte b/frontend/antdx/actions/copy/Index.svelte new file mode 100644 index 00000000..217fca66 --- /dev/null +++ b/frontend/antdx/actions/copy/Index.svelte @@ -0,0 +1,59 @@ + + +{#if proceedProps.visible} + {#await AwaitedActionsCopy then ActionsCopy} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/actions/copy/actions.copy.tsx b/frontend/antdx/actions/copy/actions.copy.tsx new file mode 100644 index 00000000..bdaf5424 --- /dev/null +++ b/frontend/antdx/actions/copy/actions.copy.tsx @@ -0,0 +1,21 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React from 'react'; +import { Actions } from '@ant-design/x'; +import type { ActionsCopyProps } from '@ant-design/x/es/actions/ActionsCopy'; + +export const ActionsCopy = sveltify( + ({ slots, children, ...props }) => { + return ( + <> +
{children}
+ : props.icon} + /> + + ); + } +); + +export default ActionsCopy; diff --git a/frontend/antdx/actions/copy/gradio.config.js b/frontend/antdx/actions/copy/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/actions/copy/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/actions/copy/package.json b/frontend/antdx/actions/copy/package.json new file mode 100644 index 00000000..ff0a5be8 --- /dev/null +++ b/frontend/antdx/actions/copy/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-actions.copy", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/actions/feedback/Index.svelte b/frontend/antdx/actions/feedback/Index.svelte new file mode 100644 index 00000000..9560d322 --- /dev/null +++ b/frontend/antdx/actions/feedback/Index.svelte @@ -0,0 +1,61 @@ + + +{#if proceedProps.visible} + {#await AwaitedActionsFeedback then ActionsFeedback} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/actions/feedback/actions.feedback.tsx b/frontend/antdx/actions/feedback/actions.feedback.tsx new file mode 100644 index 00000000..f73b9b9c --- /dev/null +++ b/frontend/antdx/actions/feedback/actions.feedback.tsx @@ -0,0 +1,15 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import { Actions, type ActionsFeedbackProps } from '@ant-design/x'; + +export const ActionsFeedback = sveltify( + ({ slots: _slots, ...props }) => { + return ( + <> + + + ); + } +); + +export default ActionsFeedback; diff --git a/frontend/antdx/actions/feedback/gradio.config.js b/frontend/antdx/actions/feedback/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/actions/feedback/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/actions/feedback/package.json b/frontend/antdx/actions/feedback/package.json new file mode 100644 index 00000000..98a8a294 --- /dev/null +++ b/frontend/antdx/actions/feedback/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-actions.feedback", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/actions/item/Index.svelte b/frontend/antdx/actions/item/Index.svelte index c444e509..e5213674 100644 --- a/frontend/antdx/actions/item/Index.svelte +++ b/frontend/antdx/actions/item/Index.svelte @@ -4,10 +4,7 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import {Keys - getSlots, - getSlotKey, - } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedActionsItem = importComponent(() => import('./actions.item')); @@ -16,10 +13,7 @@ const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; - _internal: { - layout?: boolean; - index?: number; - }; + _internal: {}; }>(() => props); const getProceedProps = processProps(() => { @@ -47,7 +41,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} @@ -59,8 +52,6 @@ {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} - itemIndex={proceedProps._internal.index || 0} - itemSlotKey={slotKey?.value} > {@render children?.()} diff --git a/frontend/antdx/actions/item/actions.item.tsx b/frontend/antdx/actions/item/actions.item.tsx index 78757dc0..49193511 100644 --- a/frontend/antdx/actions/item/actions.item.tsx +++ b/frontend/antdx/actions/item/actions.item.tsx @@ -1,20 +1,33 @@ import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React from 'react'; -import type { ActionsProps } from '@ant-design/x'; - -import { ItemHandler, type ItemHandlerProps } from '../context'; +import { Actions, type ActionsItemProps } from '@ant-design/x'; export const ActionsItem = sveltify< - Partial[number]> & ItemHandlerProps ->((props) => { + Partial, + ['defaultIcon', 'runningIcon'] +>(({ slots, children, ...props }) => { return ( - - {...props} - allowedSlots={['default']} - itemChildren={(items) => { - return items.default.length > 0 ? items.default : undefined; - }} - /> + <> +
{children}
+ + ) : ( + props.defaultIcon + ) + } + runningIcon={ + slots.runningIcon ? ( + + ) : ( + props.runningIcon + ) + } + /> + ); }); diff --git a/frontend/antdx/actions/item/package.json b/frontend/antdx/actions/item/package.json index 2a72966d..1cb4abea 100644 --- a/frontend/antdx/actions/item/package.json +++ b/frontend/antdx/actions/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/attachments/Index.svelte b/frontend/antdx/attachments/Index.svelte index 92c5e923..40553817 100644 --- a/frontend/antdx/attachments/Index.svelte +++ b/frontend/antdx/attachments/Index.svelte @@ -11,15 +11,19 @@ const AwaitedAttachments = importComponent(() => import('./attachments')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - - as_item?: string | undefined; - _internal: Record; - root: string; - value?: FileData[]; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + _internal: Record; + form_name?: string; + value?: FileData[]; + }>(() => props); const getProceedProps = processProps( () => { @@ -31,12 +35,11 @@ elem_id, elem_style, value, - root, ...restProps } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -45,7 +48,6 @@ elem_classes, elem_style, value, - root, }; }, { @@ -63,7 +65,7 @@ style={proceedProps.elem_style} className={cls(proceedProps.elem_classes, 'ms-gr-antdx-attachments')} id={proceedProps.elem_id} - items={proceedProps.value} + items={proceedProps.value || []} {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} @@ -74,9 +76,9 @@ }} upload={async (files) => { return ( - (await proceedProps.additionalProps.gradio.client.upload( + (await proceedProps.gradio.shared.client.upload( await prepare_files(files), - proceedProps.root + proceedProps.gradio.shared.root )) || [] ).map((file, i) => { if (!file) { diff --git a/frontend/antdx/attachments/attachments.tsx b/frontend/antdx/attachments/attachments.tsx index 520bff9e..c74d44bb 100644 --- a/frontend/antdx/attachments/attachments.tsx +++ b/frontend/antdx/attachments/attachments.tsx @@ -10,11 +10,11 @@ import { useFunction } from '@utils/hooks/useFunction'; import { useTargets } from '@utils/hooks/useTargets'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { renderParamsSlot } from '@utils/renderParamsSlot'; -import { type UploadFile } from 'antd'; +import { type ImageProps, type UploadFile } from 'antd'; import type { RcFile } from 'antd/es/upload'; import { noop } from 'lodash-es'; -import type { FileCardProps } from './file-card/file-card'; +import type { BaseFileCardProps } from '../file-card/base'; const isUploadFile = (file: FileData | UploadFile): file is UploadFile => { return !!(file as UploadFile).name; @@ -27,6 +27,12 @@ function getConfig(value: T): Partial> { return {} as any; } +declare module '@ant-design/x' { + export interface AttachmentsProps { + imageProps?: ImageProps; + } +} + export const Attachments = sveltify< Omit & { onValueChange?: (value: FileData[]) => void; @@ -203,7 +209,7 @@ export const Attachments = sveltify< ) : ( previewConfig.closeIcon ), - }) as NonNullable['preview']) + }) as NonNullable['preview']) : false, placeholder: slots['imageProps.placeholder'] ? ( diff --git a/frontend/antdx/attachments/file-card/file-card.tsx b/frontend/antdx/attachments/file-card/file-card.tsx deleted file mode 100644 index 177eea73..00000000 --- a/frontend/antdx/attachments/file-card/file-card.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { useMemo } from 'react'; -import { Attachments as XAttachments } from '@ant-design/x'; -import type { Attachment } from '@ant-design/x/es/attachments'; -import type { FileListCardProps } from '@ant-design/x/es/attachments/FileList/FileListCard'; -import type { FileData } from '@gradio/client'; -import { get_fetchable_url_or_file } from '@utils/upload'; -// import { theme } from 'antd'; - -export type FileCardProps = Omit & { - urlRoot: string; - urlProxyUrl: string; - item?: string | (Attachment & FileData); -}; - -export const FileCard: React.FC = ({ - item, - urlRoot, - urlProxyUrl, - ...props -}) => { - // const { token } = theme.useToken(); - const resolvedItem = useMemo(() => { - if (!item) { - return {}; - } - if (typeof item === 'string') { - return { - url: item.startsWith('http') - ? item - : get_fetchable_url_or_file(item, urlRoot, urlProxyUrl), - uid: item, - name: item.split('/').pop(), - }; - } - return { - ...item, - uid: item.uid || item.path || item.url, - name: - item.name || item.orig_name || (item.url || item.path).split('/').pop(), - url: - item.url || get_fetchable_url_or_file(item.path, urlRoot, urlProxyUrl), - }; - }, [item, urlProxyUrl, urlRoot]); - return ( - - ); -}; - -export default FileCard; diff --git a/frontend/antdx/attachments/file-card/package.json b/frontend/antdx/attachments/file-card/package.json deleted file mode 100644 index 50df06ec..00000000 --- a/frontend/antdx/attachments/file-card/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "@modelscope-studio/antdx-attachments.file-card", - "type": "module", - "exports": { - ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" - }, - "./package.json": { - "default": "./package.json", - "gradio": "./package.json" - } - } -} diff --git a/frontend/antdx/bubble/Index.svelte b/frontend/antdx/bubble/Index.svelte index da7b37db..b89a03aa 100644 --- a/frontend/antdx/bubble/Index.svelte +++ b/frontend/antdx/bubble/Index.svelte @@ -19,6 +19,9 @@ }; typing_complete?: any; + edit_confirm?: any; + edit_cancel?: any; + content?: string; }>(() => props); const getProceedProps = processProps( @@ -34,7 +37,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -46,6 +49,8 @@ }, { typing_complete: 'typingComplete', + edit_confirm: 'editConfirm', + edit_cancel: 'editCancel', } ); const proceedProps = $derived(getProceedProps()); @@ -61,6 +66,9 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} + content={proceedProps.additionalProps.content || + proceedProps.restProps.content || + ''} slots={slots.value} > {@render children?.()} diff --git a/frontend/antdx/bubble/bubble.tsx b/frontend/antdx/bubble/bubble.tsx index 41cda5c0..772c4a58 100644 --- a/frontend/antdx/bubble/bubble.tsx +++ b/frontend/antdx/bubble/bubble.tsx @@ -1,110 +1,118 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; -import React, { useMemo } from 'react'; +import React from 'react'; import { Bubble as XBubble, type BubbleProps } from '@ant-design/x'; import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; -import type { AvatarProps } from 'antd'; -import { isObject } from 'lodash-es'; +function getConfig(value: T): Partial> { + if (typeof value === 'object' && value !== null) { + return value as any; + } + return {} as any; +} export const Bubble = sveltify< - BubbleProps & { - }, + BubbleProps & {}, [ 'avatar', - 'avatar.icon', - 'avatar.src', - 'typing.suffix', + 'editable.okText', + 'editable.cancelText', 'content', 'footer', 'header', + 'extra', 'loadingRender', - 'messageRender', + 'contentRender', ] ->( - ({ - loadingRender, - messageRender, - slots, - children, - ...props - }) => { - const loadingRenderFunction = useFunction(loadingRender); - const messageRenderFunction = useFunction(messageRender); - const headerFunction = useFunction(props.header, true); - const footerFunction = useFunction(props.footer, true); - const avatar = useMemo(() => { - if (slots.avatar) { - return ; - } - if (slots['avatar.icon'] || slots['avatar.src']) { - return { - ...(props.avatar || {}), - icon: slots['avatar.icon'] ? ( - +>(({ loadingRender, contentRender, slots, children, ...props }) => { + const loadingRenderFunction = useFunction(loadingRender); + const contentRenderFunction = useFunction(contentRender); + const headerFunction = useFunction(props.header, true); + const footerFunction = useFunction(props.footer, true); + const avatarFunction = useFunction(props.avatar, true); + const extraFunction = useFunction(props.extra, true); + const typingFunction = useFunction(props.typing); + const editableConfig = getConfig(props.editable); + const supportEdit = + props.editable || slots['editable.cancelText'] || slots['editable.okText']; + return ( + <> +
{children}
+ + ) : ( + editableConfig.cancelText + ), + okText: slots['editable.okText'] ? ( + + ) : ( + editableConfig.okText + ), + } + : props.editable + } + typing={typingFunction || props.typing} + content={ + slots.content ? : props.content + } + avatar={ + slots.avatar ? ( + ) : ( - (props.avatar as AvatarProps)?.icon - ), - src: slots['avatar.src'] ? ( - + avatarFunction || props.avatar + ) + } + extra={ + slots.extra ? ( + ) : ( - (props.avatar as AvatarProps)?.src - ), - }; - } - return props.avatar; - }, [props.avatar, slots]); - return ( - <> -
{children}
- , - } - : props.typing - } - content={ - slots.content ? : props.content - } - footer={ - slots.footer ? ( - - ) : ( - footerFunction || props.footer - ) - } - header={ - slots.header ? ( - - ) : ( - headerFunction || props.header - ) - } - loadingRender={ - slots.loadingRender - ? renderParamsSlot({ - slots, - key: 'loadingRender', - }) - : loadingRenderFunction - } - messageRender={ - slots.messageRender - ? renderParamsSlot({ - slots, - key: 'messageRender', - }) - : messageRenderFunction - } - /> - - ); - } -); + extraFunction || props.extra + ) + } + footer={ + slots.footer ? ( + + ) : ( + footerFunction || props.footer + ) + } + header={ + slots.header ? ( + + ) : ( + headerFunction || props.header + ) + } + loadingRender={ + slots.loadingRender + ? renderParamsSlot({ + slots, + key: 'loadingRender', + }) + : loadingRenderFunction + } + contentRender={ + slots.contentRender + ? renderParamsSlot({ + slots, + key: 'contentRender', + }) + : contentRenderFunction + } + /> + + ); +}); export default Bubble; diff --git a/frontend/antdx/bubble/divider/Index.svelte b/frontend/antdx/bubble/divider/Index.svelte new file mode 100644 index 00000000..aa6d30b4 --- /dev/null +++ b/frontend/antdx/bubble/divider/Index.svelte @@ -0,0 +1,65 @@ + + +{#if proceedProps.visible} + {#await AwaitedBubbleDivider then BubbleDivider} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/bubble/divider/bubble.divider.tsx b/frontend/antdx/bubble/divider/bubble.divider.tsx new file mode 100644 index 00000000..5ad501ec --- /dev/null +++ b/frontend/antdx/bubble/divider/bubble.divider.tsx @@ -0,0 +1,26 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React from 'react'; +import { Bubble as XBubble } from '@ant-design/x'; +import type { DividerBubbleProps } from '@ant-design/x/es/bubble/interface'; + +export const BubbleDivider = sveltify< + DividerBubbleProps & { + children?: React.ReactNode; + }, + ['content'] +>(({ slots, children, ...props }) => { + return ( + <> +
{children}
+ : props.content + } + /> + + ); +}); + +export default BubbleDivider; diff --git a/frontend/antdx/bubble/divider/gradio.config.js b/frontend/antdx/bubble/divider/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/bubble/divider/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/bubble/divider/package.json b/frontend/antdx/bubble/divider/package.json new file mode 100644 index 00000000..2bf56fa4 --- /dev/null +++ b/frontend/antdx/bubble/divider/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-bubble.divider", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/bubble/list/bubble.list.tsx b/frontend/antdx/bubble/list/bubble.list.tsx index 60a445f3..c3adbaa0 100644 --- a/frontend/antdx/bubble/list/bubble.list.tsx +++ b/frontend/antdx/bubble/list/bubble.list.tsx @@ -1,7 +1,6 @@ import { sveltify } from '@svelte-preprocess-react'; import React, { useMemo } from 'react'; -import { Bubble as XBubble } from '@ant-design/x'; -import type { BubbleListProps } from '@ant-design/x/es/bubble/BubbleList'; +import { Bubble as XBubble, type BubbleListProps } from '@ant-design/x'; import { renderItems } from '@utils/renderItems'; import { @@ -9,38 +8,35 @@ import { withItemsContextProvider, withRoleItemsContextProvider, } from './context'; -import { useRolesRender } from './utils'; +import { useRole } from './utils'; export const BubbleList = sveltify( withRoleItemsContextProvider( - ['roles'], + ['role'], withItemsContextProvider( ['items', 'default'], - ({ items, roles, children, ...props }) => { + ({ items, role, children, ...props }) => { const { items: slotItems } = useItems<['items', 'default']>(); - const rolesRender = useRolesRender({ - roles, - }); - - const resolvedSlotItems = - slotItems.items.length > 0 ? slotItems.items : slotItems.default; - + const resolvedRole = useRole({ role }); + const resolvedSlotItems = slotItems.items?.length + ? slotItems.items + : slotItems.default; return ( <>
{children}
{ const resolvedItems = items || renderItems[number]>( - resolvedSlotItems + resolvedSlotItems || [] ); return resolvedItems; }, [items, resolvedSlotItems])} - roles={rolesRender} /> ); diff --git a/frontend/antdx/bubble/list/context.ts b/frontend/antdx/bubble/list/context.ts index 28caae1f..8dffd601 100644 --- a/frontend/antdx/bubble/list/context.ts +++ b/frontend/antdx/bubble/list/context.ts @@ -7,6 +7,6 @@ export const { useItems: useRoleItems, withItemsContextProvider: withRoleItemsContextProvider, ItemHandler: RoleItemHandler, -} = createItemsContext('antdx-bubble.list-roles'); +} = createItemsContext('antdx-bubble.list-role'); export * from '@utils/createItemsContext'; diff --git a/frontend/antdx/bubble/list/item/Index.svelte b/frontend/antdx/bubble/list/item/Index.svelte index dfa33c9a..9ff16b93 100644 --- a/frontend/antdx/bubble/list/item/Index.svelte +++ b/frontend/antdx/bubble/list/item/Index.svelte @@ -1,13 +1,19 @@ {#await AwaitedBubbleListItem then BubbleListItem} - {@render props.children?.()} + {@render children?.()} {/await} diff --git a/frontend/antdx/bubble/list/item/Item.svelte b/frontend/antdx/bubble/list/item/Item.svelte index 02699713..7f808e41 100644 --- a/frontend/antdx/bubble/list/item/Item.svelte +++ b/frontend/antdx/bubble/list/item/Item.svelte @@ -4,10 +4,11 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import {Keys - getSlots, + import { getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { createFunction } from '@utils/createFunction'; import cls from 'classnames'; const AwaitedBubbleListItem = importComponent( @@ -19,52 +20,130 @@ additional_props?: Record; as_item?: string | undefined; _internal: { - layout?: boolean; index?: number; }; + content?: string; + avatar?: string; + editable?: any; + loadingRender?: string; + contentRender?: string; + typing_complete?: any; + edit_confirm?: any; + edit_cancel?: any; }>(() => props); + const slotKey = getSlotKey(); - const getProceedProps = processProps(() => { - const { - visible, - _internal, - as_item, - elem_classes, - elem_id, - elem_style, - ...restProps - } = getComponentProps(); - return { - gradio, - additionalProps: getAdditionalProps(), - _internal, - as_item, - restProps, - visible, - elem_id, - elem_classes, - elem_style, - }; - }); + const getProceedProps = processProps( + () => { + const { + visible, + _internal, + as_item, + elem_classes, + elem_id, + elem_style, + ...restProps + } = getComponentProps(); + return { + gradio, + additionalProps: getAdditionalProps(), + _internal, + as_item, + restProps, + visible, + elem_id, + elem_classes, + elem_style, + }; + }, + { + typing_complete: 'typingComplete', + edit_confirm: 'editConfirm', + edit_cancel: 'editCancel', + } + ); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); + + const itemProps = $derived.by(() => { + const editable = + proceedProps.additionalProps.editable || proceedProps.restProps.editable; + return { + props: { + style: proceedProps.elem_style, + className: cls( + proceedProps.elem_classes, + 'ms-gr-antdx-bubble-list-item' + ), + id: proceedProps.elem_id, + ...proceedProps.restProps, + ...proceedProps.additionalProps, + editable: + typeof editable === 'boolean' + ? { + editing: editable, + } + : editable, + content: + proceedProps.additionalProps.content || + proceedProps.restProps.content || + '', + loadingRender: createFunction( + proceedProps.additionalProps.loadingRender || + proceedProps.restProps.loadingRender + ), + contentRender: createFunction( + proceedProps.additionalProps.contentRender || + proceedProps.restProps.contentRender + ), + }, + slots: { + ...slots.value, + loadingRender: { + el: slots.value.loadingRender, + clone: true, + withParams: true, + }, + avatar: { + el: slots.value.avatar, + clone: true, + withParams: true, + }, + header: { + el: slots.value.header, + clone: true, + withParams: true, + }, + footer: { + el: slots.value.footer, + clone: true, + withParams: true, + }, + extra: { + el: slots.value.extra, + clone: true, + withParams: true, + }, + contentRender: { + el: slots.value.messageRender, + clone: true, + withParams: true, + }, + }, + }; + }); -{#if proceedProps.visible} - {#await AwaitedBubbleListItem then BubbleListItem} - +{#await AwaitedBubbleListItem then BubbleListItem} + + {#if proceedProps.visible} {@render children?.()} - - {/await} -{/if} + {/if} + +{/await} diff --git a/frontend/antdx/bubble/list/role/Index.svelte b/frontend/antdx/bubble/list/role/Index.svelte index 554093bc..c101b3a8 100644 --- a/frontend/antdx/bubble/list/role/Index.svelte +++ b/frontend/antdx/bubble/list/role/Index.svelte @@ -1,13 +1,19 @@ {#await AwaitedBubbleListRole then BubbleListRole} - {@render props.children?.()} + {@render children?.()} {/await} diff --git a/frontend/antdx/bubble/list/role/Role.svelte b/frontend/antdx/bubble/list/role/Role.svelte index 34ed9a35..550ea553 100644 --- a/frontend/antdx/bubble/list/role/Role.svelte +++ b/frontend/antdx/bubble/list/role/Role.svelte @@ -4,7 +4,11 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { + getSlotKey, + getSlots, + } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { createFunction } from '@utils/createFunction'; import cls from 'classnames'; const AwaitedBubbleListRole = importComponent( @@ -16,48 +20,128 @@ additional_props?: Record; as_item?: string | undefined; _internal: { - layout?: boolean; + index?: boolean; }; + typing_complete?: any; + edit_confirm?: any; + edit_cancel?: any; + editable?: any; + content?: string; + loadingRender?: string; + contentRender?: string; }>(() => props); + const slotKey = getSlotKey(); - const getProceedProps = processProps(() => { - const { - visible, - _internal, - as_item, - elem_classes, - elem_id, - elem_style, - ...restProps - } = getComponentProps(); - return { - gradio, - additionalProps: getAdditionalProps(), - _internal, - as_item, - restProps, - visible, - elem_id, - elem_classes, - elem_style, - }; - }); + const getProceedProps = processProps( + () => { + const { + visible, + _internal, + as_item, + elem_classes, + elem_id, + elem_style, + ...restProps + } = getComponentProps(); + return { + gradio, + additionalProps: getAdditionalProps(), + _internal, + as_item, + restProps, + visible, + elem_id, + elem_classes, + elem_style, + }; + }, + { + typing_complete: 'typingComplete', + edit_confirm: 'editConfirm', + edit_cancel: 'editCancel', + } + ); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); + const itemProps = $derived.by(() => { + const editable = + proceedProps.additionalProps.editable || proceedProps.restProps.editable; + return { + props: { + style: proceedProps.elem_style, + className: cls( + proceedProps.elem_classes, + 'ms-gr-antdx-bubble-list-role' + ), + id: proceedProps.elem_id, + ...proceedProps.restProps, + ...proceedProps.additionalProps, + editable: + typeof editable === 'boolean' + ? { + editing: editable, + } + : editable, + content: + proceedProps.additionalProps.content || + proceedProps.restProps.content || + '', + loadingRender: createFunction( + proceedProps.additionalProps.loadingRender || + proceedProps.restProps.loadingRender + ), + contentRender: createFunction( + proceedProps.additionalProps.contentRender || + proceedProps.restProps.contentRender + ), + }, + slots: { + ...slots.value, + loadingRender: { + el: slots.value.loadingRender, + clone: true, + withParams: true, + }, + avatar: { + el: slots.value.avatar, + clone: true, + withParams: true, + }, + header: { + el: slots.value.header, + clone: true, + withParams: true, + }, + footer: { + el: slots.value.footer, + clone: true, + withParams: true, + }, + extra: { + el: slots.value.extra, + clone: true, + withParams: true, + }, + contentRender: { + el: slots.value.messageRender, + clone: true, + withParams: true, + }, + }, + }; + }); -{#if proceedProps.visible} - {#await AwaitedBubbleListRole then BubbleListRole} - +{#await AwaitedBubbleListRole then BubbleListRole} + + {#if proceedProps.visible} {@render children?.()} - - {/await} -{/if} + {/if} + +{/await} diff --git a/frontend/antdx/bubble/list/utils.tsx b/frontend/antdx/bubble/list/utils.tsx index 9d0df5d6..80fbbe15 100644 --- a/frontend/antdx/bubble/list/utils.tsx +++ b/frontend/antdx/bubble/list/utils.tsx @@ -1,108 +1,151 @@ import { useMemo } from 'react'; import type { - BubbleDataType, - RolesType, + BubbleItemType, + RoleProps, RoleType, -} from '@ant-design/x/es/bubble/BubbleList'; -import { useFunction } from '@utils/hooks/useFunction'; +} from '@ant-design/x/es/bubble/interface'; +import { createFunction } from '@utils/createFunction'; +import { useMemoizedEqualValue } from '@utils/hooks/useMemoizedEqualValue'; import { useMemoizedFn } from '@utils/hooks/useMemoizedFn'; import { patchSlots } from '@utils/patchSlots'; import { renderItems } from '@utils/renderItems'; -import type { AvatarProps } from 'antd'; import { isFunction, isObject } from 'lodash-es'; import { useRoleItems } from './context'; export const messageIndexSymbol = Symbol(); -function patchBubbleSlots(role: RoleType, params: any[]) { +function patchBubbleSlots(role: RoleProps, params: any[]) { return patchSlots(params, (patchSlotRender) => { return { ...role, - avatar: isFunction(role.avatar) - ? patchSlotRender(role.avatar) - : isObject(role.avatar) - ? { - ...role.avatar, - icon: patchSlotRender((role.avatar as AvatarProps)?.icon), - src: patchSlotRender((role.avatar as AvatarProps)?.src), - } - : role.avatar, + avatar: patchSlotRender(role.avatar, { + unshift: true, + }), + extra: patchSlotRender(role.extra, { + unshift: true, + }), footer: patchSlotRender(role.footer, { unshift: true, }), header: patchSlotRender(role.header, { unshift: true, }), - loadingRender: patchSlotRender(role.loadingRender, true), - messageRender: patchSlotRender(role.messageRender, true), + loadingRender: patchSlotRender(role.loadingRender, { + unshift: true, + }), + contentRender: patchSlotRender(role.contentRender, { + unshift: true, + }), }; }); } -export interface UseRolesRenderOptions { - roles?: RolesType; - preProcess?: (bubbleProps: T, index: number) => RoleType; - postProcess?: (bubbleProps: T, index: number) => RoleType | void; +export interface UseRoleOptions { + role?: RoleType; + defaultRoleKeys?: string[]; + preProcess?: (bubbleProps: T, index: number) => RoleProps; + defaultRolePostProcess?: (bubbleProps: T, index: number) => RoleProps | void; } -export function useRolesRender( - { roles: rolesProp, preProcess, postProcess }: UseRolesRenderOptions, +export function useRole( + { + role: roleProp, + defaultRoleKeys, + preProcess, + defaultRolePostProcess, + }: UseRoleOptions, deps: React.DependencyList = [] ) { - const rolesFunction = useFunction(rolesProp); const memoizedPreProcess = useMemoizedFn(preProcess); - const memoizedPostProcess = useMemoizedFn(postProcess); + const memoizedDefaultRolePostProcess = useMemoizedFn(defaultRolePostProcess); + const memoizedDefaultRoleKeys = useMemoizedEqualValue(defaultRoleKeys); const { - items: { roles: roleItems }, - } = useRoleItems<['roles']>(); - - const roles = useMemo(() => { + items: { role: roleItems }, + } = useRoleItems<['role']>(); + const role = useMemo(() => { return ( - rolesProp || - renderItems< - RoleType & { - role?: string; - } - >(roleItems, { - clone: true, - forceClone: true, - })?.reduce( - (acc, v) => { - if (v.role !== undefined) { - acc[v.role] = v; + roleProp || + (roleItems?.length + ? renderItems< + RoleProps & { + role?: string; + } + >(roleItems || [], { + clone: true, + forceClone: true, + })?.reduce( + (acc, v) => { + if (v.role !== undefined) { + acc[v.role] = v; + } + return acc; + }, + {} as Record + ) + : {}) || + {} + ); + }, [roleItems, roleProp]); + const resolvedRole = useMemo(() => { + const roleKeys = [ + ...new Set([ + ...(memoizedDefaultRoleKeys || []), + ...Object.keys(role || {}), + ]), + ]; + if (roleKeys.length > 0) { + return Object.keys(role).reduce( + (acc, key) => { + if (typeof role[key] === 'string') { + const functionRole = createFunction(role[key]); + if (functionRole) { + acc[key] = functionRole; + } + } else { + acc[key] = (data) => { + const index = data[messageIndexSymbol]; + const preProcessResult = + memoizedPreProcess(data as T, index) || data; + if (role[key]) { + return patchBubbleSlots( + isFunction(role[key]) + ? role[key](preProcessResult as BubbleItemType) + : role[key], + [preProcessResult, index] + ); + } + const postProcessResult = memoizedDefaultRolePostProcess( + preProcessResult as T, + index + ); + if (postProcessResult) { + return postProcessResult; + } + return { + contentRender(content) { + return ( + <>{isObject(content) ? JSON.stringify(content) : content} + ); + }, + }; + }; } return acc; }, - {} as Record - ) - ); - }, [roleItems, rolesProp]); - const rolesRender = useMemo(() => { - return (originalBubbleProps: BubbleDataType, i: number): RoleType => { - const index = i ?? originalBubbleProps[messageIndexSymbol]; - const bubbleProps = - memoizedPreProcess(originalBubbleProps as T, index) || - originalBubbleProps; - if (bubbleProps.role && (roles || {})[bubbleProps.role]) { - return patchBubbleSlots((roles || {})[bubbleProps.role], [ - bubbleProps, - index, - ]) as RoleType; - } - let postProcessResult: RoleType | void = undefined; - postProcessResult = memoizedPostProcess(bubbleProps as T, index); - if (postProcessResult) { - return postProcessResult; - } - return { - messageRender(content) { - return <>{isObject(content) ? JSON.stringify(content) : content}; - }, - }; - }; + {} as typeof role + ); + } + return role; + }, [ + memoizedDefaultRoleKeys, + role, + memoizedPreProcess, + memoizedDefaultRolePostProcess, // eslint-disable-next-line react-hooks/exhaustive-deps - }, [roles, memoizedPostProcess, memoizedPreProcess, ...deps]); - return rolesFunction || rolesRender; + ...deps, + ]); + + return resolvedRole; } diff --git a/frontend/antdx/bubble/system/Index.svelte b/frontend/antdx/bubble/system/Index.svelte new file mode 100644 index 00000000..6ce6c9b5 --- /dev/null +++ b/frontend/antdx/bubble/system/Index.svelte @@ -0,0 +1,63 @@ + + +{#if proceedProps.visible} + {#await AwaitedBubbleSystem then BubbleSystem} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/bubble/system/bubble.system.tsx b/frontend/antdx/bubble/system/bubble.system.tsx new file mode 100644 index 00000000..121fc934 --- /dev/null +++ b/frontend/antdx/bubble/system/bubble.system.tsx @@ -0,0 +1,26 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React from 'react'; +import { Bubble as XBubble } from '@ant-design/x'; +import type { SystemBubbleProps } from '@ant-design/x/es/bubble/interface'; + +export const BubbleSystem = sveltify< + SystemBubbleProps & { + children?: React.ReactNode; + }, + ['content'] +>(({ slots, children, ...props }) => { + return ( + <> +
{children}
+ : props.content + } + /> + + ); +}); + +export default BubbleSystem; diff --git a/frontend/antdx/bubble/system/gradio.config.js b/frontend/antdx/bubble/system/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/bubble/system/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/bubble/system/package.json b/frontend/antdx/bubble/system/package.json new file mode 100644 index 00000000..286973a2 --- /dev/null +++ b/frontend/antdx/bubble/system/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-bubble.system", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/conversations/item/Index.svelte b/frontend/antdx/conversations/item/Index.svelte index 5b063bd8..849dbd57 100644 --- a/frontend/antdx/conversations/item/Index.svelte +++ b/frontend/antdx/conversations/item/Index.svelte @@ -4,9 +4,9 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import {Keys - getSlots, + import { getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,7 +50,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} diff --git a/frontend/antdx/attachments/file-card/Index.svelte b/frontend/antdx/file-card/Index.svelte similarity index 70% rename from frontend/antdx/attachments/file-card/Index.svelte rename to frontend/antdx/file-card/Index.svelte index 094be650..2a194595 100644 --- a/frontend/antdx/attachments/file-card/Index.svelte +++ b/frontend/antdx/file-card/Index.svelte @@ -4,24 +4,17 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import {Keys - getSlots, - getSlotKey, - } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; - const AwaitedFileCard = importComponent( - () => import('./attachments.file-card') - ); + const AwaitedFileCard = importComponent(() => import('./file-card')); const props = $props(); const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; as_item?: string | undefined; - _internal: { - layout?: boolean; - index?: number; - }; + _internal: {}; + filename?: string; }>(() => props); const getProceedProps = processProps(() => { @@ -32,6 +25,7 @@ elem_classes, elem_id, elem_style, + filename, ...restProps } = getComponentProps(); return { @@ -44,28 +38,26 @@ elem_id, elem_classes, elem_style, + name: filename, }; }); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} {#await AwaitedFileCard then FileCard} {@render children?.()} diff --git a/frontend/antdx/file-card/base.tsx b/frontend/antdx/file-card/base.tsx new file mode 100644 index 00000000..bc69bb87 --- /dev/null +++ b/frontend/antdx/file-card/base.tsx @@ -0,0 +1,35 @@ +import React, { useMemo } from 'react'; +import { + FileCard as XFileCard, + type FileCardProps as XFileCardProps, +} from '@ant-design/x'; +import type { FileData } from '@gradio/client'; +import { getFetchableUrl } from '@utils/upload'; + +export type BaseFileCardProps = Omit & { + rootUrl: string; + apiPrefix: string; + src?: string | FileData; +}; + +export const BaseFileCard: React.FC = ({ + src, + rootUrl, + apiPrefix, + ...props +}) => { + const resolvedSrc = useMemo(() => { + if (!src) { + return src; + } + if (typeof src === 'string') { + return src.startsWith('http') + ? src + : getFetchableUrl(src, rootUrl, apiPrefix); + } + return src.url || getFetchableUrl(src.path, rootUrl, apiPrefix); + }, [src, apiPrefix, rootUrl]); + return ; +}; + +export default BaseFileCard; diff --git a/frontend/antdx/attachments/file-card/attachments.file-card.tsx b/frontend/antdx/file-card/file-card.tsx similarity index 71% rename from frontend/antdx/attachments/file-card/attachments.file-card.tsx rename to frontend/antdx/file-card/file-card.tsx index 266e0ef6..63409623 100644 --- a/frontend/antdx/attachments/file-card/attachments.file-card.tsx +++ b/frontend/antdx/file-card/file-card.tsx @@ -4,7 +4,7 @@ import { useFunction } from '@utils/hooks/useFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { renderParamsSlot } from '@utils/renderParamsSlot'; -import { FileCard, type FileCardProps } from './file-card'; +import { BaseFileCard, type BaseFileCardProps } from './base'; function getConfig(value: T): Partial> { if (typeof value === 'object' && value !== null) { @@ -12,8 +12,10 @@ function getConfig(value: T): Partial> { } return {} as any; } -export const AttachmentsFileCard = sveltify< - FileCardProps & { + +// sync with FileCardListItem +export const FileCard = sveltify< + BaseFileCardProps & { children?: React.ReactNode; }, [ @@ -22,7 +24,12 @@ export const AttachmentsFileCard = sveltify< 'imageProps.preview.closeIcon', 'imageProps.preview.toolbarRender', 'imageProps.preview.imageRender', + 'description', 'icon', + 'mask', + 'spinProps.icon', + 'spinProps.description', + 'spinProps.indicator', ] >(({ imageProps, slots, children, ...props }) => { const previewConfig = getConfig(imageProps?.preview); @@ -39,9 +46,35 @@ export const AttachmentsFileCard = sveltify< return ( <>
{children}
- : props.icon} + description={ + slots.description ? ( + + ) : ( + props.description + ) + } + mask={slots.mask ? : props.mask} + spinProps={{ + ...props.spinProps, + icon: slots['spinProps.icon'] ? ( + + ) : ( + props.spinProps?.icon + ), + description: slots['spinProps.description'] ? ( + + ) : ( + props.spinProps?.description + ), + indicator: slots['spinProps.indicator'] ? ( + + ) : ( + props.spinProps?.indicator + ), + }} imageProps={{ ...imageProps, preview: supportPreview @@ -76,7 +109,7 @@ export const AttachmentsFileCard = sveltify< ) : ( previewConfig.closeIcon ), - }) as NonNullable['preview']) + }) as NonNullable['preview']) : false, placeholder: slots['imageProps.placeholder'] ? ( @@ -89,4 +122,4 @@ export const AttachmentsFileCard = sveltify< ); }); -export default AttachmentsFileCard; +export default FileCard; diff --git a/frontend/antdx/file-card/gradio.config.js b/frontend/antdx/file-card/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antdx/file-card/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/file-card/list/Index.svelte b/frontend/antdx/file-card/list/Index.svelte new file mode 100644 index 00000000..d25348ad --- /dev/null +++ b/frontend/antdx/file-card/list/Index.svelte @@ -0,0 +1,65 @@ + + +{#if proceedProps.visible} + {#await AwaitedFileCardList then FileCardList} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/file-card/list/context.ts b/frontend/antdx/file-card/list/context.ts new file mode 100644 index 00000000..ed2b891d --- /dev/null +++ b/frontend/antdx/file-card/list/context.ts @@ -0,0 +1,6 @@ +import { createItemsContext } from '@utils/createItemsContext'; + +export const { useItems, withItemsContextProvider, ItemHandler } = + createItemsContext('antdx-file-card-list-items'); + +export * from '@utils/createItemsContext'; diff --git a/frontend/antdx/file-card/list/file-card.list.tsx b/frontend/antdx/file-card/list/file-card.list.tsx new file mode 100644 index 00000000..712fa17a --- /dev/null +++ b/frontend/antdx/file-card/list/file-card.list.tsx @@ -0,0 +1,51 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React, { useMemo } from 'react'; +import { FileCard as XFileCard, type FileCardListProps } from '@ant-design/x'; +import { useFunction } from '@utils/hooks/useFunction'; +import { omitUndefinedProps } from '@utils/omitUndefinedProps'; +import { renderItems } from '@utils/renderItems'; +import type { ItemType } from 'antd/es/menu/interface'; + +import { useItems, withItemsContextProvider } from './context'; + +export const FileCardList = sveltify< + FileCardListProps & { + children?: React.ReactNode; + }, + ['extension'] +>( + withItemsContextProvider( + ['default', 'items'], + ({ slots, items, children, extension, removable, ...props }) => { + const { items: slotItems } = useItems<['default', 'items']>(); + const resolvedSlotItems = slotItems.items?.length + ? slotItems.items + : slotItems.default; + const removableFunction = useFunction(removable); + return ( + <> +
{children}
+ : extension + } + removable={removableFunction || removable} + items={useMemo(() => { + // ['label','icon',"title"] + return ( + items || + renderItems(resolvedSlotItems || [], { + clone: true, + }) + ); + }, [items, resolvedSlotItems])} + /> + + ); + } + ) +); + +export default FileCardList; diff --git a/frontend/antdx/file-card/list/gradio.config.js b/frontend/antdx/file-card/list/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/file-card/list/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/file-card/list/item/Index.svelte b/frontend/antdx/file-card/list/item/Index.svelte new file mode 100644 index 00000000..a88dec5e --- /dev/null +++ b/frontend/antdx/file-card/list/item/Index.svelte @@ -0,0 +1,75 @@ + + +{#await AwaitedFileCardListItem then FileCardListItem} + + {#if proceedProps.visible} + {@render children?.()} + {/if} + +{/await} diff --git a/frontend/antdx/file-card/list/item/file-card.list.item.tsx b/frontend/antdx/file-card/list/item/file-card.list.item.tsx new file mode 100644 index 00000000..450ca176 --- /dev/null +++ b/frontend/antdx/file-card/list/item/file-card.list.item.tsx @@ -0,0 +1,82 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import { useFunction } from '@utils/hooks/useFunction'; +import { omitUndefinedProps } from '@utils/omitUndefinedProps'; + +import type { BaseFileCardProps } from '../../../file-card/base'; +import { ItemHandler, type ItemHandlerProps } from '../context'; + +function getConfig(value: T): Partial> { + if (typeof value === 'object' && value !== null) { + return value as any; + } + return {} as any; +} + +export const FileCardListItem = sveltify< + BaseFileCardProps & ItemHandlerProps, + [ + 'imageProps.placeholder', + 'imageProps.preview.mask', + 'imageProps.preview.closeIcon', + 'imageProps.preview.toolbarRender', + 'imageProps.preview.imageRender', + 'description', + 'icon', + 'mask', + 'spinProps.icon', + 'spinProps.description', + 'spinProps.indicator', + ] +>(({ imageProps, slots, ...props }) => { + const previewConfig = getConfig(imageProps?.preview); + const supportPreview = + slots['imageProps.preview.mask'] || + slots['imageProps.preview.closeIcon'] || + slots['imageProps.preview.toolbarRender'] || + slots['imageProps.preview.imageRender'] || + imageProps?.preview !== false; + const getContainerFunction = useFunction(previewConfig.getContainer); + const previewToolbarRenderFunction = useFunction(previewConfig.toolbarRender); + const previewImageRenderFunction = useFunction(previewConfig.imageRender); + return ( + + {...props} + slots={{ + ...slots, + 'imageProps.preview.toolbarRender': { + el: slots['imageProps.preview.toolbarRender'], + clone: true, + withParams: true, + }, + 'imageProps.preview.imageRender': { + el: slots['imageProps.preview.imageRender'], + clone: true, + withParams: true, + }, + }} + allowedSlots={['default']} + itemProps={(itemProps) => { + return { + ...itemProps, + imageProps: { + ...(itemProps?.imageProps || {}), + preview: supportPreview + ? (omitUndefinedProps({ + ...previewConfig, + getContainer: getContainerFunction, + toolbarRender: previewToolbarRenderFunction, + imageRender: previewImageRenderFunction, + }) as NonNullable['preview']) + : false, + }, + }; + }} + itemChildren={(items) => { + return items.default.length > 0 ? items.default : undefined; + }} + /> + ); +}); + +export default FileCardListItem; diff --git a/frontend/antdx/file-card/list/item/gradio.config.js b/frontend/antdx/file-card/list/item/gradio.config.js new file mode 100644 index 00000000..7b2fe8dd --- /dev/null +++ b/frontend/antdx/file-card/list/item/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/file-card/list/item/package.json b/frontend/antdx/file-card/list/item/package.json new file mode 100644 index 00000000..4d1f4f3f --- /dev/null +++ b/frontend/antdx/file-card/list/item/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antd-file-card.list.item", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/file-card/list/package.json b/frontend/antdx/file-card/list/package.json new file mode 100644 index 00000000..c349ad7f --- /dev/null +++ b/frontend/antdx/file-card/list/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-file-card.list", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/file-card/package.json b/frontend/antdx/file-card/package.json new file mode 100644 index 00000000..e08adccb --- /dev/null +++ b/frontend/antdx/file-card/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-file-card", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/prompts/item/Index.svelte b/frontend/antdx/prompts/item/Index.svelte index 2fab88a4..21117068 100644 --- a/frontend/antdx/prompts/item/Index.svelte +++ b/frontend/antdx/prompts/item/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -21,6 +21,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -47,7 +48,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} diff --git a/frontend/antdx/suggestion/item/Index.svelte b/frontend/antdx/suggestion/item/Index.svelte index 5ffc1d0d..1c849863 100644 --- a/frontend/antdx/suggestion/item/Index.svelte +++ b/frontend/antdx/suggestion/item/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,18 +50,40 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); + const itemProps = $derived({ + props: { + style: proceedProps.elem_style, + className: cls(proceedProps.elem_classes, 'ms-gr-antd-suggestion-item'), + id: proceedProps.elem_id, + ...proceedProps.restProps, + ...proceedProps.additionalProps, + }, + slots: { + ...slots.value, + extra: { + el: slots.value.extra, + clone: true, + withParams: true, + }, + icon: { + el: slots.value.icon, + clone: true, + withParams: true, + }, + label: { + el: slots.value.label, + clone: true, + withParams: true, + }, + }, + }); {#if proceedProps.visible} {#await AwaitedSuggestionItem then SuggestionItem} diff --git a/frontend/antdx/thought-chain/item/Index.svelte b/frontend/antdx/thought-chain/item/Index.svelte index f92ccd3f..aac70757 100644 --- a/frontend/antdx/thought-chain/item/Index.svelte +++ b/frontend/antdx/thought-chain/item/Index.svelte @@ -5,8 +5,8 @@ processProps, } from '@svelte-preprocess-react/component'; import { - getSlots, getSlotKey, + getSlots, } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; @@ -23,6 +23,7 @@ index?: number; }; }>(() => props); + const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -49,7 +50,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - const slotKey = getSlotKey(); {#if proceedProps.visible} diff --git a/frontend/antdx/welcome/Index.svelte b/frontend/antdx/welcome/Index.svelte index 210dfa6c..dc96d668 100644 --- a/frontend/antdx/welcome/Index.svelte +++ b/frontend/antdx/welcome/Index.svelte @@ -61,8 +61,8 @@ {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} - urlRoot={proceedProps.root} - urlProxyUrl={proceedProps.proxy_url} + rootUrl={proceedProps.root} + apiPrefix={proceedProps.proxy_url} > {@render children?.()} diff --git a/frontend/antdx/welcome/welcome.tsx b/frontend/antdx/welcome/welcome.tsx index ee239539..d83d46af 100644 --- a/frontend/antdx/welcome/welcome.tsx +++ b/frontend/antdx/welcome/welcome.tsx @@ -7,13 +7,13 @@ import { getFileUrl } from '@utils/upload'; export const Welcome = sveltify< Omit & { - urlRoot: string; - urlProxyUrl: string; + rootUrl: string; + apiPrefix: string; icon?: WelcomeProps['icon'] | FileData; children?: React.ReactNode; }, ['description', 'icon', 'extra', 'title'] ->(({ slots, children, urlProxyUrl, urlRoot, ...props }) => { +>(({ slots, children, apiPrefix, rootUrl, ...props }) => { return ( <>
{children}
@@ -24,7 +24,7 @@ export const Welcome = sveltify< slots.icon ? ( ) : ( - getFileUrl(props.icon, urlRoot, urlProxyUrl) + getFileUrl(props.icon, rootUrl, apiPrefix) ) } title={slots.title ? : props.title} diff --git a/frontend/antdx/x-provider/Index.svelte b/frontend/antdx/x-provider/Index.svelte index 9a86a426..5dbff0ff 100644 --- a/frontend/antdx/x-provider/Index.svelte +++ b/frontend/antdx/x-provider/Index.svelte @@ -1,15 +1,19 @@ {#await AwaitedXProvider then XProvider} - {#snippet children()} - {@render props.children?.()} - {/snippet} + {@render children?.()} {/await} diff --git a/frontend/antdx/x-provider/XProvider.svelte b/frontend/antdx/x-provider/XProvider.svelte index 78204317..75a95dac 100644 --- a/frontend/antdx/x-provider/XProvider.svelte +++ b/frontend/antdx/x-provider/XProvider.svelte @@ -5,11 +5,7 @@ processProps, } from '@svelte-preprocess-react/component'; import { setConfigType } from '@svelte-preprocess-react/svelte-contexts/config.svelte'; - import { - getSlots, - setComponentSlotValue, - setSlotParamsMapping, - } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import { XProvider as XXProvider } from '@ant-design/x'; import cls from 'classnames'; @@ -48,18 +44,6 @@ }); const proceedProps = $derived(getProceedProps()); - let slotParamsFn = $state<((...args: any[]) => any) | undefined>(undefined); - - setSlotParamsMapping(() => slotParamsFn); - - setComponentSlotValue(() => { - return { - slot: undefined, - index: proceedProps._internal.index, - subIndex: proceedProps._internal.subIndex, - }; - }); - const slots = getSlots(); setConfigType(() => 'antd'); @@ -75,10 +59,7 @@ {...proceedProps.additionalProps} slots={slots.value} component={XXProvider} - themeMode={proceedProps.gradio.shared.theme} - setSlotParams={(params) => { - slotParamsFn = params; - }} + themeMode={proceedProps.gradio.shared.theme || 'light'} > {@render children?.()}
diff --git a/frontend/base/markdown/Index.svelte b/frontend/base/markdown/Index.svelte index b5c04168..db6f3348 100644 --- a/frontend/base/markdown/Index.svelte +++ b/frontend/base/markdown/Index.svelte @@ -52,8 +52,8 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} - urlRoot={gradio.shared.root} - themeMode={gradio.shared.theme} + rootUrl={proceedProps.gradio.shared.root} + themeMode={proceedProps.gradio.shared.theme || 'light'} value={proceedProps.value} slots={slots.value} > diff --git a/frontend/globals/components/markdown/index.tsx b/frontend/globals/components/markdown/index.tsx index 9be65344..915d48c9 100644 --- a/frontend/globals/components/markdown/index.tsx +++ b/frontend/globals/components/markdown/index.tsx @@ -40,7 +40,7 @@ export interface MarkdownProps extends Omit< showCopyButton?: boolean; rtl?: boolean; themeMode: string; - urlRoot: string; + rootUrl: string; allowTags?: string[] | boolean; onCopy?: (options: { value: string }) => void; onChange?: () => void; @@ -70,7 +70,7 @@ export const Markdown: React.FC = ({ rtl, themeMode, showCopyButton, - urlRoot, + rootUrl, onChange, onCopy, copyButtons, @@ -131,7 +131,7 @@ export const Markdown: React.FC = ({ ); if (sanitize_html) { - parsedValue = sanitize(parsedValue, urlRoot); + parsedValue = sanitize(parsedValue, rootUrl); } return parsedValue; diff --git a/frontend/pro/chatbot/Index.svelte b/frontend/pro/chatbot/Index.svelte index 5edc94d2..f269f5da 100644 --- a/frontend/pro/chatbot/Index.svelte +++ b/frontend/pro/chatbot/Index.svelte @@ -78,8 +78,8 @@ value: v, }); }} - urlRoot={proceedProps.gradio.shared.root} - urlProxyUrl={proceedProps.gradio.shared.proxy_url} + rootUrl={proceedProps.gradio.shared.root} + apiPrefix={proceedProps.gradio.shared.proxy_url} themeMode={proceedProps.additionalProps.gradio?.theme} slots={slots.value} > diff --git a/frontend/pro/chatbot/chatbot-footer.tsx b/frontend/pro/chatbot/chatbot-footer.tsx index d9ac1561..ee5bdf9f 100644 --- a/frontend/pro/chatbot/chatbot-footer.tsx +++ b/frontend/pro/chatbot/chatbot-footer.tsx @@ -46,8 +46,8 @@ export interface ChatbotFooterProps { extra?: string; onRetry?: (data: RetryData) => void; onLike?: (data: LikeData) => void; - urlRoot: string; - urlProxyUrl: string; + rootUrl: string; + apiPrefix: string; } export const CopyButton: React.FC<{ @@ -56,20 +56,12 @@ export const CopyButton: React.FC<{ style?: React.CSSProperties; className?: string; disabled?: boolean; - urlRoot: string; - urlProxyUrl: string; -}> = ({ - content, - className, - style, - disabled, - urlRoot, - urlProxyUrl, - onCopy, -}) => { + rootUrl: string; + apiPrefix: string; +}> = ({ content, className, style, disabled, rootUrl, apiPrefix, onCopy }) => { const text = useMemo( - () => getCopyText(content, urlRoot, urlProxyUrl), - [content, urlProxyUrl, urlRoot] + () => getCopyText(content, rootUrl, apiPrefix), + [content, apiPrefix, rootUrl] ); const copyButtonRef = useRef(null); @@ -119,8 +111,8 @@ const Action: React.FC<{ onEdit: () => void; onLike: (liked: boolean) => void; onRetry: () => void; - urlRoot: string; - urlProxyUrl: string; + rootUrl: string; + apiPrefix: string; }> = ({ action: actionOrActionObject, disabledActions, @@ -130,8 +122,8 @@ const Action: React.FC<{ onEdit, onLike, onRetry, - urlRoot, - urlProxyUrl, + rootUrl, + apiPrefix, }) => { const handleActionRef = useRef<() => void>(); const getActionProps = () => { @@ -159,8 +151,8 @@ const Action: React.FC<{ disabled={disabled} content={message.content} onCopy={onCopy} - urlRoot={urlRoot} - urlProxyUrl={urlProxyUrl} + rootUrl={rootUrl} + apiPrefix={apiPrefix} /> ); case 'like': @@ -277,8 +269,8 @@ export const ChatbotFooter: React.FC = ({ index, actions, disabledActions, - urlRoot, - urlProxyUrl, + rootUrl, + apiPrefix, }) => { if (isEditing) { return ( @@ -333,8 +325,8 @@ export const ChatbotFooter: React.FC = ({ return ( void; }>( withRoleItemsContextProvider( - ['roles'], + ['role'], ({ id, className, @@ -87,9 +87,9 @@ export const Chatbot = sveltify<{ minHeight, maxHeight, value, - roles, - urlRoot, - urlProxyUrl, + role, + rootUrl, + apiPrefix, themeMode, autoScroll = true, showScrollToBottomButton = true, @@ -122,10 +122,10 @@ export const Chatbot = sveltify<{ lineBreaks: true, renderMarkdown: true, ...convertObjectKeyToCamelCase(markdownConfig), - urlRoot, + rootUrl, themeMode, }), - [markdownConfig, themeMode, urlRoot] + [markdownConfig, themeMode, rootUrl] ); const resolvedUserConfig = useMemo(() => { return ( @@ -302,8 +302,8 @@ export const Chatbot = sveltify<{ messageRender() { return ( @@ -361,8 +361,8 @@ export const Chatbot = sveltify<{ ? resolvedUserConfig?.footer : resolvedBotConfig?.footer) as string) } - urlRoot={urlRoot} - urlProxyUrl={urlProxyUrl} + rootUrl={rootUrl} + apiPrefix={apiPrefix} editValues={editValues} index={index} actions={ @@ -390,8 +390,8 @@ export const Chatbot = sveltify<{ return ( void; onSuggestionSelect: (value: SuggestionData) => void; } @@ -44,8 +44,8 @@ export const Message: React.FC = ({ markdownConfig, onEdit, onSuggestionSelect, - urlProxyUrl, - urlRoot, + apiPrefix, + rootUrl, }) => { const containerRef = useRef(null); @@ -114,8 +114,8 @@ export const Message: React.FC = ({ return ( { if (!item) { return {} as Attachment; @@ -32,7 +32,7 @@ const resolveItem = ( return { url: item.startsWith('http') ? item - : get_fetchable_url_or_file(item, urlRoot, urlProxyUrl), + : getFetchableUrl(item, rootUrl, apiPrefix), uid: item, name: item.split('/').pop(), } as Attachment; @@ -42,7 +42,7 @@ const resolveItem = ( uid: item.uid || item.path || item.url, name: item.name || item.orig_name || (item.url || item.path).split('/').pop(), - url: item.url || get_fetchable_url_or_file(item.path, urlRoot, urlProxyUrl), + url: item.url || getFetchableUrl(item.path, rootUrl, apiPrefix), } as Attachment; }; @@ -96,8 +96,8 @@ const FileContainer: React.FC<{ export const FileMessage: React.FC = ({ value, - urlProxyUrl, - urlRoot, + apiPrefix, + rootUrl, options, }) => { const { imageProps } = options; @@ -109,14 +109,14 @@ export const FileMessage: React.FC = ({ className="ms-gr-pro-chatbot-message-file-message" > {value?.map((file, index) => { - const item = resolveItem(file, urlRoot, urlProxyUrl); + const item = resolveItem(file, rootUrl, apiPrefix); return ( diff --git a/frontend/pro/chatbot/messages/welcome.tsx b/frontend/pro/chatbot/messages/welcome.tsx index 253c71e6..0cd4a1ae 100644 --- a/frontend/pro/chatbot/messages/welcome.tsx +++ b/frontend/pro/chatbot/messages/welcome.tsx @@ -10,15 +10,15 @@ import type { ChatbotWelcomeConfig, WelcomePromptData } from '../type'; export interface WelcomeMessageProps { options: ChatbotWelcomeConfig; - urlRoot: string; - urlProxyUrl: string; + rootUrl: string; + apiPrefix: string; onWelcomePromptSelect: (value: WelcomePromptData) => void; } export const WelcomeMessage: React.FC = ({ options, - urlProxyUrl, - urlRoot, + apiPrefix, + rootUrl, onWelcomePromptSelect, }) => { const { prompts, ...welcome } = options; @@ -29,7 +29,7 @@ export const WelcomeMessage: React.FC = ({ { if (typeof content === 'string') { return content; @@ -113,7 +113,7 @@ export const getCopyText = ( if (Array.isArray(content)) { return content .map((item) => { - return getCopyText(item, root, urlProxyUrl); + return getCopyText(item, root, apiPrefix); }) .filter(Boolean) .join('\n'); @@ -129,7 +129,7 @@ export const getCopyText = ( if (content.type === 'file') { return JSON.stringify( (content.content as ChatbotFileContent).map((item) => - getFileUrl(item, root, urlProxyUrl) + getFileUrl(item, root, apiPrefix) ) ); } diff --git a/frontend/svelte-preprocess-react/component/props.svelte.ts b/frontend/svelte-preprocess-react/component/props.svelte.ts index b2841bc1..7721f2db 100644 --- a/frontend/svelte-preprocess-react/component/props.svelte.ts +++ b/frontend/svelte-preprocess-react/component/props.svelte.ts @@ -332,7 +332,6 @@ export function getProps< shared_props: SharedProps; } = getSvelteProps(); const gradio = new Gradio(props); - const updateProps = (updatedProps: Partial

) => { gradio.update(updatedProps); }; diff --git a/frontend/utils/createItemsContext.tsx b/frontend/utils/createItemsContext.tsx index 260ed8c3..48f8805a 100644 --- a/frontend/utils/createItemsContext.tsx +++ b/frontend/utils/createItemsContext.tsx @@ -25,10 +25,9 @@ export type Item = | HTMLElement | { el?: HTMLElement; - // slot key, render args - callback?: (key: string, params: any[]) => void; clone?: boolean; forceClone?: boolean; + withParams?: boolean; } >; el?: HTMLElement; @@ -65,10 +64,9 @@ export interface ItemHandlerProps< | undefined | { el?: HTMLElement; - // slot key, render args - callback?: (key: string, params: any[]) => void; clone?: boolean; - ß?: boolean; + forceClone?: boolean; + withParams?: boolean; } >; children?: React.ReactNode; diff --git a/frontend/utils/renderItems.tsx b/frontend/utils/renderItems.tsx index 0cb8ba76..c85c3772 100644 --- a/frontend/utils/renderItems.tsx +++ b/frontend/utils/renderItems.tsx @@ -48,7 +48,7 @@ export function renderItems( const splits = slotKey.split('.'); splits.forEach((split, index) => { - if (!current[split]) { + if (!current[split] || typeof current[split] !== 'object') { current[split] = {}; } if (index !== splits.length - 1) { @@ -58,24 +58,22 @@ export function renderItems( const elOrObject = item.slots[slotKey]; let el: HTMLElement | undefined; - let callback: ((key: string, params: any[]) => void) | undefined; + let withParams: boolean | undefined; let clone = options?.clone ?? false; let forceClone = options?.forceClone; if (elOrObject instanceof Element) { el = elOrObject; } else { el = elOrObject.el; - callback = elOrObject.callback; + withParams = elOrObject.withParams; clone = elOrObject.clone ?? clone; forceClone = elOrObject.forceClone ?? forceClone; } - forceClone = forceClone ?? (callback ? true : false); + forceClone = forceClone ?? (withParams ? true : false); current[splits[splits.length - 1]] = el - ? callback + ? withParams ? (...args: any[]) => { - callback(splits[splits.length - 1], args); - return ( = 5 ? 'gradio_api/' : ''; - - if (path == null) { - return proxy_url - ? `/proxy=${proxy_url}${prefix}file=` - : `${server_url}${prefix}file=`; - } - if (is_url(path)) { + if (isUrl(path)) { return path; } - return proxy_url - ? `/proxy=${proxy_url}${prefix}file=${path}` - : `${server_url}/${prefix}file=${path}`; -} - -// for <= gradio 4.19.1 -export async function upload( - file_data: FileData[], - root: string, - upload_fn: typeof upload_files = upload_files -): Promise<(FileData | null)[] | null> { - const files = (Array.isArray(file_data) ? file_data : [file_data]).map( - (file) => file.blob! - ); - - return await Promise.all( - await (upload_fn as any)(root, files, undefined, undefined).then( - (response: { - files?: string[]; - error?: string; - modelscope_upload_error?: boolean; - }) => { - if (response.modelscope_upload_error) { - return []; - } - if (response.error) { - throw new Error(response.error); - } else { - if (response.files) { - return response.files.map((f, i) => { - const file = new FileData({ - ...file_data[i], - path: f, - url: root + '/file=' + f, - }); - return file; - }); - } - - return []; - } - } - ) - ); + return `${rootUrl}${apiPrefix}/file=${path}`; } const isFileData = (v: FileData | any): v is FileData => { @@ -146,8 +26,8 @@ const isFileData = (v: FileData | any): v is FileData => { export function getFileUrl( file: T, - urlRoot: string, - urlProxyUrl: string + rootUrl: string, + apiPrefix: string ): string | Exclude | undefined { if (!file) { return; @@ -158,7 +38,7 @@ export function getFileUrl( if (typeof file === 'string') { return file.startsWith('http') ? file - : get_fetchable_url_or_file(file, urlRoot, urlProxyUrl); + : getFetchableUrl(file, rootUrl, apiPrefix); } return file as Exclude; } From 1cd2ed1b743d54a0b99a4ce458a86d7745cc5bb3 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 18 Mar 2026 15:24:43 +0800 Subject: [PATCH 09/31] refactor(antdx): components migration --- frontend/base/auto-loading/Index.svelte | 2 +- frontend/base/fragment/Index.svelte | 5 ++-- frontend/pro/chatbot/type.ts | 12 +++++--- frontend/pro/monaco-editor/Index.svelte | 31 +++++++++++--------- frontend/pro/multimodal-input/Index.svelte | 33 +++++++++++++--------- frontend/pro/web-sandbox/Index.svelte | 2 +- 6 files changed, 49 insertions(+), 36 deletions(-) diff --git a/frontend/base/auto-loading/Index.svelte b/frontend/base/auto-loading/Index.svelte index eacbb25e..114f5d23 100644 --- a/frontend/base/auto-loading/Index.svelte +++ b/frontend/base/auto-loading/Index.svelte @@ -33,7 +33,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), restProps, _internal, as_item, diff --git a/frontend/base/fragment/Index.svelte b/frontend/base/fragment/Index.svelte index 747f08a0..fe1c6063 100644 --- a/frontend/base/fragment/Index.svelte +++ b/frontend/base/fragment/Index.svelte @@ -9,9 +9,8 @@ const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{}>( - () => props - ); + const { gradio, getComponentProps, getAdditionalProps, children } = + getProps<{}>(() => props); const getProceedProps = processProps( () => { diff --git a/frontend/pro/chatbot/type.ts b/frontend/pro/chatbot/type.ts index 89582111..eb2c2cf1 100644 --- a/frontend/pro/chatbot/type.ts +++ b/frontend/pro/chatbot/type.ts @@ -74,8 +74,10 @@ export interface ChatbotUserActionObject { popconfirm?: string | PopconfirmProps; } -export interface ChatbotUserConfig - extends Omit { +export interface ChatbotUserConfig extends Omit< + BubbleProps, + 'avatar' | 'content' +> { actions?: (ChatbotUserAction | ChatbotUserActionObject)[]; disabled_actions?: ChatbotUserAction[]; avatar?: ChatbotAvatar; @@ -94,8 +96,10 @@ export interface ChatbotBotActionObject { popconfirm?: string | PopconfirmProps; } -export interface ChatbotBotConfig - extends Omit { +export interface ChatbotBotConfig extends Omit< + BubbleProps, + 'avatar' | 'content' +> { actions?: (ChatbotBotAction | ChatbotBotActionObject)[]; disabled_actions?: ChatbotBotAction[]; avatar?: ChatbotAvatar; diff --git a/frontend/pro/monaco-editor/Index.svelte b/frontend/pro/monaco-editor/Index.svelte index 54709c7a..145df6c0 100644 --- a/frontend/pro/monaco-editor/Index.svelte +++ b/frontend/pro/monaco-editor/Index.svelte @@ -12,20 +12,25 @@ const AwaitedMonacoEditor = importComponent(() => import('./monaco-editor')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: string | undefined; - _loader?: { - mode?: 'cdn' | 'local'; - cdn_url?: string; - }; - }>(() => props); + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: string | undefined; + _loader?: { + mode?: 'cdn' | 'local'; + cdn_url?: string; + }; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/pro/multimodal-input/Index.svelte b/frontend/pro/multimodal-input/Index.svelte index a57f8be5..e7610797 100644 --- a/frontend/pro/multimodal-input/Index.svelte +++ b/frontend/pro/multimodal-input/Index.svelte @@ -15,20 +15,25 @@ ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: MultimodalInputValue; - root?: string; - key_press?: any; - paste_file?: any; - key_down?: any; - }>(() => props); + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: MultimodalInputValue; + root?: string; + key_press?: any; + paste_file?: any; + key_down?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -45,7 +50,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/pro/web-sandbox/Index.svelte b/frontend/pro/web-sandbox/Index.svelte index ae346966..06f8e685 100644 --- a/frontend/pro/web-sandbox/Index.svelte +++ b/frontend/pro/web-sandbox/Index.svelte @@ -39,7 +39,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, From 8ce80635def6cbc49333fc970dd51abc0326a5ed Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 18 Mar 2026 15:33:08 +0800 Subject: [PATCH 10/31] refactor(antdx): components migration --- .../components/antdx/__init__.py | 2 + .../components/antdx/components.py | 2 + .../antdx/conversations/__init__.py | 16 ++- .../antdx/conversations/item/__init__.py | 10 +- .../components/antdx/prompts/__init__.py | 10 +- .../components/antdx/prompts/item/__init__.py | 2 +- .../components/antdx/sender/__init__.py | 31 +++-- .../antdx/sender/header/__init__.py | 6 +- .../antdx/sender/switch/__init__.py | 80 +++++++++++++ .../antdx/thought_chain/__init__.py | 22 ++-- .../antdx/thought_chain/item/__init__.py | 26 ++-- .../thought_chain_item/__init__.py | 80 +++++++++++++ frontend/antd/affix/package.json | 8 +- .../antd/alert/error-boundary/package.json | 8 +- frontend/antd/alert/package.json | 8 +- frontend/antd/anchor/item/package.json | 8 +- frontend/antd/anchor/package.json | 8 +- frontend/antd/auto-complete/Index.svelte | 29 +++-- .../antd/auto-complete/option/package.json | 8 +- frontend/antd/auto-complete/package.json | 8 +- frontend/antd/avatar/group/package.json | 8 +- frontend/antd/avatar/package.json | 8 +- frontend/antd/badge/package.json | 8 +- frontend/antd/badge/ribbon/package.json | 8 +- frontend/antd/breadcrumb/Index.svelte | 2 +- frontend/antd/breadcrumb/item/package.json | 8 +- frontend/antd/breadcrumb/package.json | 8 +- frontend/antd/button/group/package.json | 8 +- frontend/antd/button/package.json | 8 +- frontend/antd/calendar/Index.svelte | 27 +++-- frontend/antd/calendar/package.json | 8 +- frontend/antd/card/Index.svelte | 2 +- frontend/antd/card/card.tsx | 9 +- frontend/antd/card/grid/package.json | 8 +- frontend/antd/card/meta/package.json | 8 +- frontend/antd/card/package.json | 8 +- frontend/antd/carousel/package.json | 8 +- frontend/antd/cascader/Index.svelte | 31 +++-- frontend/antd/cascader/option/package.json | 8 +- frontend/antd/cascader/package.json | 8 +- frontend/antd/cascader/panel/Index.svelte | 27 +++-- frontend/antd/cascader/panel/package.json | 8 +- frontend/antd/checkbox/Index.svelte | 23 ++-- frontend/antd/checkbox/group/Index.svelte | 23 ++-- .../antd/checkbox/group/option/package.json | 8 +- frontend/antd/checkbox/group/package.json | 8 +- frontend/antd/checkbox/package.json | 8 +- frontend/antd/collapse/collapse.tsx | 15 +-- frontend/antd/collapse/item/package.json | 8 +- frontend/antd/collapse/package.json | 8 +- frontend/antd/color-picker/Index.svelte | 33 +++--- frontend/antd/color-picker/package.json | 8 +- .../antd/color-picker/preset/package.json | 8 +- frontend/antd/config-provider/package.json | 8 +- frontend/antd/date-picker/Index.svelte | 29 +++-- frontend/antd/date-picker/package.json | 8 +- frontend/antd/date-picker/preset/package.json | 8 +- .../date-picker/range-picker/Index.svelte | 25 ++-- .../date-picker/range-picker/package.json | 8 +- frontend/antd/descriptions/item/package.json | 8 +- frontend/antd/descriptions/package.json | 8 +- frontend/antd/divider/package.json | 8 +- frontend/antd/drawer/package.json | 8 +- frontend/antd/dropdown/Index.svelte | 2 +- frontend/antd/dropdown/button/Index.svelte | 2 +- frontend/antd/dropdown/button/package.json | 8 +- frontend/antd/dropdown/package.json | 8 +- frontend/antd/empty/package.json | 8 +- frontend/antd/flex/package.json | 8 +- frontend/antd/float-button/Index.svelte | 2 +- .../antd/float-button/back-top/Index.svelte | 2 +- .../antd/float-button/back-top/package.json | 8 +- frontend/antd/float-button/group/Index.svelte | 2 +- frontend/antd/float-button/group/package.json | 8 +- frontend/antd/float-button/package.json | 8 +- frontend/antd/form/Index.svelte | 33 +++--- frontend/antd/form/item/Index.svelte | 2 +- frontend/antd/form/item/package.json | 8 +- frontend/antd/form/item/rule/package.json | 8 +- frontend/antd/form/package.json | 8 +- frontend/antd/form/provider/Index.svelte | 2 +- frontend/antd/form/provider/package.json | 8 +- frontend/antd/grid/col/package.json | 8 +- frontend/antd/grid/row/package.json | 8 +- .../antd/icon/iconfont-provider/package.json | 8 +- frontend/antd/icon/package.json | 8 +- frontend/antd/image/Index.svelte | 2 +- frontend/antd/image/image.tsx | 3 +- frontend/antd/image/package.json | 8 +- .../antd/image/preview-group/Index.svelte | 2 +- .../antd/image/preview-group/package.json | 8 +- frontend/antd/input-number/Index.svelte | 27 +++-- frontend/antd/input-number/package.json | 8 +- frontend/antd/input/Index.svelte | 25 ++-- frontend/antd/input/otp/Index.svelte | 23 ++-- frontend/antd/input/otp/package.json | 8 +- frontend/antd/input/package.json | 8 +- frontend/antd/input/password/Index.svelte | 27 +++-- frontend/antd/input/password/package.json | 8 +- frontend/antd/input/search/Index.svelte | 25 ++-- frontend/antd/input/search/package.json | 8 +- frontend/antd/input/textarea/Index.svelte | 25 ++-- frontend/antd/input/textarea/package.json | 8 +- frontend/antd/layout/content/package.json | 8 +- frontend/antd/layout/footer/package.json | 8 +- frontend/antd/layout/header/package.json | 8 +- frontend/antd/layout/package.json | 8 +- frontend/antd/layout/sider/package.json | 8 +- frontend/antd/list/Index.svelte | 2 +- frontend/antd/list/item/meta/package.json | 8 +- frontend/antd/list/item/package.json | 8 +- frontend/antd/list/list.tsx | 3 +- frontend/antd/list/package.json | 8 +- frontend/antd/mentions/Index.svelte | 27 +++-- frontend/antd/mentions/option/package.json | 8 +- frontend/antd/mentions/package.json | 8 +- frontend/antd/menu/Index.svelte | 2 +- frontend/antd/menu/item/package.json | 8 +- frontend/antd/menu/menu.tsx | 3 +- frontend/antd/menu/package.json | 8 +- frontend/antd/message/Index.svelte | 23 ++-- frontend/antd/message/package.json | 8 +- frontend/antd/modal/package.json | 8 +- frontend/antd/modal/static/Index.svelte | 21 ++-- frontend/antd/modal/static/package.json | 8 +- frontend/antd/notification/Index.svelte | 25 ++-- frontend/antd/notification/package.json | 8 +- frontend/antd/pagination/Index.svelte | 2 +- frontend/antd/pagination/package.json | 8 +- frontend/antd/pagination/pagination.tsx | 5 +- frontend/antd/popconfirm/Index.svelte | 2 +- frontend/antd/popconfirm/package.json | 8 +- frontend/antd/popover/Index.svelte | 2 +- frontend/antd/popover/package.json | 8 +- frontend/antd/progress/package.json | 8 +- frontend/antd/qr-code/package.json | 8 +- frontend/antd/qr-code/qr-code.tsx | 32 +++-- frontend/antd/radio/Index.svelte | 25 ++-- frontend/antd/radio/button/Index.svelte | 29 +++-- frontend/antd/radio/button/package.json | 8 +- frontend/antd/radio/group/Index.svelte | 27 +++-- frontend/antd/radio/group/option/package.json | 8 +- frontend/antd/radio/group/package.json | 8 +- frontend/antd/radio/package.json | 8 +- frontend/antd/rate/Index.svelte | 29 +++-- frontend/antd/rate/package.json | 8 +- frontend/antd/result/package.json | 8 +- frontend/antd/segmented/Index.svelte | 27 +++-- frontend/antd/segmented/option/package.json | 8 +- frontend/antd/segmented/package.json | 8 +- frontend/antd/select/Index.svelte | 29 +++-- frontend/antd/select/option/package.json | 8 +- frontend/antd/select/package.json | 8 +- frontend/antd/skeleton/avatar/package.json | 8 +- frontend/antd/skeleton/button/package.json | 8 +- frontend/antd/skeleton/image/package.json | 8 +- frontend/antd/skeleton/input/package.json | 8 +- frontend/antd/skeleton/node/package.json | 8 +- frontend/antd/skeleton/package.json | 8 +- frontend/antd/slider/Index.svelte | 27 +++-- frontend/antd/slider/mark/package.json | 8 +- frontend/antd/slider/package.json | 8 +- frontend/antd/space/compact/package.json | 8 +- frontend/antd/space/package.json | 8 +- frontend/antd/spin/package.json | 8 +- frontend/antd/splitter/Index.svelte | 2 +- frontend/antd/splitter/package.json | 8 +- frontend/antd/splitter/panel/package.json | 8 +- .../antd/statistic/countdown/package.json | 8 +- frontend/antd/statistic/package.json | 8 +- frontend/antd/statistic/timer/package.json | 8 +- frontend/antd/steps/item/package.json | 8 +- frontend/antd/steps/package.json | 8 +- frontend/antd/switch/Index.svelte | 19 +-- frontend/antd/switch/package.json | 8 +- frontend/antd/table/column-group/package.json | 8 +- frontend/antd/table/column/package.json | 8 +- frontend/antd/table/expandable/package.json | 8 +- frontend/antd/table/package.json | 8 +- .../antd/table/row-selection/package.json | 8 +- .../row-selection/selection/package.json | 8 +- frontend/antd/table/table.tsx | 3 +- frontend/antd/tabs/Index.svelte | 2 +- frontend/antd/tabs/item/package.json | 8 +- frontend/antd/tabs/package.json | 8 +- frontend/antd/tabs/tabs.tsx | 3 +- frontend/antd/tag/checkable-tag/Index.svelte | 23 ++-- frontend/antd/tag/checkable-tag/package.json | 8 +- frontend/antd/tag/package.json | 8 +- frontend/antd/time-picker/Index.svelte | 29 +++-- frontend/antd/time-picker/package.json | 8 +- .../time-picker/range-picker/Index.svelte | 27 +++-- .../time-picker/range-picker/package.json | 8 +- frontend/antd/timeline/item/package.json | 8 +- frontend/antd/timeline/package.json | 8 +- frontend/antd/tooltip/Index.svelte | 2 +- frontend/antd/tooltip/package.json | 8 +- frontend/antd/tour/package.json | 8 +- frontend/antd/tour/step/package.json | 8 +- frontend/antd/transfer/Index.svelte | 29 +++-- frontend/antd/transfer/package.json | 8 +- frontend/antd/tree-select/Index.svelte | 35 +++--- frontend/antd/tree-select/package.json | 8 +- .../antd/tree-select/tree-node/package.json | 8 +- frontend/antd/tree/Index.svelte | 2 +- .../antd/tree/directory-tree/Index.svelte | 2 +- .../antd/tree/directory-tree/package.json | 8 +- frontend/antd/tree/package.json | 8 +- frontend/antd/tree/tree-node/package.json | 8 +- frontend/antd/typography/link/package.json | 8 +- .../antd/typography/paragraph/package.json | 8 +- frontend/antd/typography/text/package.json | 8 +- frontend/antd/typography/title/package.json | 8 +- frontend/antd/upload/dragger/package.json | 8 +- frontend/antd/upload/package.json | 8 +- frontend/antd/watermark/package.json | 8 +- frontend/antdx/actions/package.json | 8 +- frontend/antdx/attachments/attachments.tsx | 1 - frontend/antdx/attachments/package.json | 8 +- frontend/antdx/bubble/list/Index.svelte | 4 + frontend/antdx/bubble/list/item/package.json | 8 +- frontend/antdx/bubble/list/package.json | 8 +- frontend/antdx/bubble/list/role/package.json | 8 +- frontend/antdx/bubble/package.json | 8 +- frontend/antdx/conversations/Index.svelte | 5 +- .../antdx/conversations/conversations.tsx | 28 +++-- .../antdx/conversations/item/Index.svelte | 1 - .../antdx/conversations/item/package.json | 8 +- frontend/antdx/conversations/package.json | 8 +- frontend/antdx/file-card/base.tsx | 26 ++-- frontend/antdx/file-card/list/Index.svelte | 8 +- .../antdx/file-card/list/file-card.list.tsx | 22 +++- frontend/antdx/prompts/Index.svelte | 2 +- frontend/antdx/prompts/item/package.json | 8 +- frontend/antdx/prompts/package.json | 8 +- frontend/antdx/prompts/prompts.tsx | 4 +- frontend/antdx/sender/Index.svelte | 35 +++--- frontend/antdx/sender/header/Index.svelte | 50 ++++---- frontend/antdx/sender/header/package.json | 8 +- .../antdx/sender/header/sender.header.tsx | 17 +-- frontend/antdx/sender/package.json | 8 +- frontend/antdx/sender/sender.tsx | 111 ++++++++++++++++-- frontend/antdx/sender/switch/Index.svelte | 61 ++++++++++ frontend/antdx/sender/switch/gradio.config.js | 3 + frontend/antdx/sender/switch/package.json | 14 +++ .../antdx/sender/switch/sender.switch.tsx | 33 ++++++ frontend/antdx/suggestion/Index.svelte | 2 +- frontend/antdx/suggestion/item/package.json | 8 +- frontend/antdx/suggestion/package.json | 8 +- frontend/antdx/suggestion/suggestion.tsx | 11 +- .../antdx/thought-chain/item/Index.svelte | 8 +- .../antdx/thought-chain/item/package.json | 8 +- .../thought-chain/item/thought-chain.item.tsx | 31 ++++- frontend/antdx/thought-chain/package.json | 8 +- .../thought-chain-item/Index.svelte | 73 ++++++++++++ .../thought-chain-item/gradio.config.js | 3 + .../thought-chain-item/package.json | 14 +++ .../thought-chain.thought-chain-item.tsx | 13 ++ frontend/antdx/welcome/package.json | 8 +- frontend/antdx/x-provider/package.json | 8 +- frontend/base/auto-loading/package.json | 8 +- frontend/base/div/package.json | 8 +- frontend/base/each/package.json | 8 +- frontend/base/filter/package.json | 8 +- frontend/base/fragment/package.json | 8 +- frontend/base/markdown/package.json | 8 +- frontend/base/slot/package.json | 8 +- frontend/base/span/package.json | 8 +- frontend/base/text/package.json | 8 +- frontend/pro/chatbot/chatbot.tsx | 2 +- frontend/pro/chatbot/package.json | 8 +- .../monaco-editor/diff-editor/package.json | 8 +- frontend/pro/monaco-editor/loader.ts | 18 +-- frontend/pro/monaco-editor/package.json | 8 +- frontend/pro/multimodal-input/package.json | 8 +- frontend/pro/web-sandbox/package.json | 8 +- .../internal/Bridge.svelte.ts | 8 +- .../svelte-preprocess-react/react-slot.tsx | 1 + 278 files changed, 1990 insertions(+), 1291 deletions(-) create mode 100644 backend/modelscope_studio/components/antdx/sender/switch/__init__.py create mode 100644 backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py create mode 100644 frontend/antdx/sender/switch/Index.svelte create mode 100644 frontend/antdx/sender/switch/gradio.config.js create mode 100644 frontend/antdx/sender/switch/package.json create mode 100644 frontend/antdx/sender/switch/sender.switch.tsx create mode 100644 frontend/antdx/thought-chain/thought-chain-item/Index.svelte create mode 100644 frontend/antdx/thought-chain/thought-chain-item/gradio.config.js create mode 100644 frontend/antdx/thought-chain/thought-chain-item/package.json create mode 100644 frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx diff --git a/backend/modelscope_studio/components/antdx/__init__.py b/backend/modelscope_studio/components/antdx/__init__.py index 5f17f99c..12199009 100644 --- a/backend/modelscope_studio/components/antdx/__init__.py +++ b/backend/modelscope_studio/components/antdx/__init__.py @@ -21,9 +21,11 @@ from .prompts.item import AntdXPromptsItem as PromptsItem from .sender import AntdXSender as Sender from .sender.header import AntdXSenderHeader as SenderHeader +from .sender.switch import AntdXSenderSwitch as SenderSwitch from .suggestion import AntdXSuggestion as Suggestion from .suggestion.item import AntdXSuggestionItem as SuggestionItem from .thought_chain import AntdXThoughtChain as ThoughtChain from .thought_chain.item import AntdXThoughtChainItem as ThoughtChainItem +from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem as ThoughtChainThoughtChainItem from .welcome import AntdXWelcome as Welcome from .x_provider import AntdXXProvider as XProvider diff --git a/backend/modelscope_studio/components/antdx/components.py b/backend/modelscope_studio/components/antdx/components.py index b239e815..80fe1bcc 100644 --- a/backend/modelscope_studio/components/antdx/components.py +++ b/backend/modelscope_studio/components/antdx/components.py @@ -20,9 +20,11 @@ from .prompts.item import AntdXPromptsItem from .sender import AntdXSender from .sender.header import AntdXSenderHeader +from .sender.switch import AntdXSenderSwitch from .suggestion import AntdXSuggestion from .suggestion.item import AntdXSuggestionItem from .thought_chain import AntdXThoughtChain from .thought_chain.item import AntdXThoughtChainItem +from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem from .welcome import AntdXWelcome from .x_provider import AntdXXProvider diff --git a/backend/modelscope_studio/components/antdx/conversations/__init__.py b/backend/modelscope_studio/components/antdx/conversations/__init__.py index 928ad0fc..64ad5088 100644 --- a/backend/modelscope_studio/components/antdx/conversations/__init__.py +++ b/backend/modelscope_studio/components/antdx/conversations/__init__.py @@ -32,12 +32,18 @@ class AntdXConversations(ModelScopeLayoutComponent): EventListener("menu_select", callback=lambda block: block._internal.update( bind_menu_select_event=True)), + EventListener("groupable_expand", + callback=lambda block: block._internal.update( + bind_groupable_expand_event=True)), + EventListener("creation_click", + callback=lambda block: block._internal.update( + bind_creation_click_event=True)), ] # supported slots SLOTS = [ 'menu.expandIcon', 'menu.overflowedIndicator', 'menu.trigger', - 'groupable.title', 'items' + 'groupable.label', 'items', 'creation.icon', 'creation.label' ] def __init__( @@ -49,8 +55,10 @@ def __init__( items: list[dict] | None = None, menu: str | dict | None = None, groupable: bool | dict | None = None, - styles: dict | str | None= None, - class_names: dict | str | None= None, + shortcut_keys: dict | None = None, + creation: dict | None = None, + styles: dict | str | None = None, + class_names: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, @@ -74,6 +82,8 @@ def __init__( self.items = items self.menu = menu self.groupable = groupable + self.shortcut_keys = shortcut_keys + self.creation = creation self.styles = styles self.class_names = class_names self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antdx/conversations/item/__init__.py b/backend/modelscope_studio/components/antdx/conversations/item/__init__.py index 9a24a69e..74a63d4a 100644 --- a/backend/modelscope_studio/components/antdx/conversations/item/__init__.py +++ b/backend/modelscope_studio/components/antdx/conversations/item/__init__.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any +from typing import Any, Literal from .....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir @@ -21,13 +21,14 @@ class AntdXConversationsItem(ModelScopeLayoutComponent): def __init__( self, label: str | None = None, - additional_props: dict | None = None, *, key: str | None = None, - timestamp: int | float | None = None, + type: Literal['divider'] | None = None, group: str | None = None, icon: str | None = None, disabled: bool | None = None, + dashed: bool | None = None, + additional_props: dict | None = None, as_item: str | None = None, _internal: None = None, # gradio properties @@ -46,7 +47,8 @@ def __init__( **kwargs) self.additional_props = additional_props self.label = label - self.timestamp = timestamp + self.type = type + self.dashed = dashed self.group = group self.icon = icon self.disabled = disabled diff --git a/backend/modelscope_studio/components/antdx/prompts/__init__.py b/backend/modelscope_studio/components/antdx/prompts/__init__.py index 8bee4b3e..fbbd57ac 100644 --- a/backend/modelscope_studio/components/antdx/prompts/__init__.py +++ b/backend/modelscope_studio/components/antdx/prompts/__init__.py @@ -27,16 +27,18 @@ class AntdXPrompts(ModelScopeLayoutComponent): def __init__( self, - additional_props: dict | None = None, *, items: list[dict] | None = None, prefix_cls: str | None = None, title: str | None = None, vertical: bool | None = None, + fade_in: bool | None = None, + fade_in_left: bool | None = None, wrap: bool | None = None, - styles: dict | str | None= None, - class_names: dict | str | None= None, + styles: dict | str | None = None, + class_names: dict | str | None = None, root_class_name: str | None = None, + additional_props: dict | None = None, as_item: str | None = None, _internal: None = None, # gradio properties @@ -58,6 +60,8 @@ def __init__( self.prefix_cls = prefix_cls self.title = title self.vertical = vertical + self.fade_in = fade_in + self.fade_in_left = fade_in_left self.wrap = wrap self.styles = styles self.class_names = class_names diff --git a/backend/modelscope_studio/components/antdx/prompts/item/__init__.py b/backend/modelscope_studio/components/antdx/prompts/item/__init__.py index 866c5617..0f4365bf 100644 --- a/backend/modelscope_studio/components/antdx/prompts/item/__init__.py +++ b/backend/modelscope_studio/components/antdx/prompts/item/__init__.py @@ -18,12 +18,12 @@ class AntdXPromptsItem(ModelScopeLayoutComponent): def __init__( self, label: str | None = None, - additional_props: dict | None = None, *, key: str | None = None, description: str | None = None, icon: str | None = None, disabled: bool | None = None, + additional_props: dict | None = None, as_item: str | None = None, _internal: None = None, # gradio properties diff --git a/backend/modelscope_studio/components/antdx/sender/__init__.py b/backend/modelscope_studio/components/antdx/sender/__init__.py index 64f77f78..47d4943e 100644 --- a/backend/modelscope_studio/components/antdx/sender/__init__.py +++ b/backend/modelscope_studio/components/antdx/sender/__init__.py @@ -7,6 +7,7 @@ from ....utils.dev import ModelScopeDataLayoutComponent, resolve_frontend_dir from .header import AntdXSenderHeader +from .switch import AntdXSenderSwitch # as inputs, outputs @@ -15,6 +16,7 @@ class AntdXSender(ModelScopeDataLayoutComponent): Ant Design X: https://x.ant.design/components/sender """ Header = AntdXSenderHeader + Switch = AntdXSenderSwitch EVENTS = [ EventListener("change", @@ -51,32 +53,41 @@ class AntdXSender(ModelScopeDataLayoutComponent): EventListener("paste_file", callback=lambda block: block._internal.update( bind_pasteFile_event=True)), + EventListener("skill_closable_close", + callback=lambda block: block._internal.update( + bind_skill_closable_close_event=True)), ] # supported slots - SLOTS = ['actions', 'header', 'prefix', 'footer'] + SLOTS = [ + 'suffix', 'header', 'prefix', 'footer', 'skill.title', + 'skill.toolTip.title' + 'skill.closable.closeIcon' + ] def __init__( self, value: str | None = None, - additional_props: dict | None = None, *, - auto_size: bool | dict | None = None, - footer: str | None = None, - actions: str | bool | None = None, allow_speech: bool | dict | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, components: dict | None = None, default_value: str | None = None, - loading: bool | None = None, disabled: bool | None = None, + auto_size: bool | dict | None = None, + loading: bool | None = None, + suffix: str | bool | None = None, + footer: str | None = None, header: str | None = None, prefix: str | None = None, read_only: bool | None = None, - styles: dict | str | None= None, + styles: dict | str | None = None, submit_type: Literal['enter', 'shiftEnter'] | None = None, placeholder: str | None = None, + slot_config: list[dict] | None = None, + skill: dict | None = None, root_class_name: str | None = None, + additional_props: dict | None = None, as_item: str | None = None, _internal: None = None, # gradio properties @@ -108,7 +119,9 @@ def __init__( self.read_only = read_only self.loading = loading self.header = header - self.actions = actions + self.suffix = suffix + self.slot_config = slot_config + self.skill = skill self.placeholder = placeholder self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antdx/sender/header/__init__.py b/backend/modelscope_studio/components/antdx/sender/header/__init__.py index c0b93360..3b7c9cf4 100644 --- a/backend/modelscope_studio/components/antdx/sender/header/__init__.py +++ b/backend/modelscope_studio/components/antdx/sender/header/__init__.py @@ -21,14 +21,14 @@ class AntdXSenderHeader(ModelScopeLayoutComponent): def __init__( self, - additional_props: dict | None = None, *, closable: bool | None = None, force_render: bool | None = None, - styles: dict | str | None= None, - class_names: dict | str | None= None, + styles: dict | str | None = None, + class_names: dict | str | None = None, open: bool | None = None, title: str | None = None, + additional_props: dict | None = None, as_item: str | None = None, _internal: None = None, # gradio properties diff --git a/backend/modelscope_studio/components/antdx/sender/switch/__init__.py b/backend/modelscope_studio/components/antdx/sender/switch/__init__.py new file mode 100644 index 00000000..146d5d95 --- /dev/null +++ b/backend/modelscope_studio/components/antdx/sender/switch/__init__.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +from gradio.events import EventListener + +from .....utils.dev import ModelScopeDataLayoutComponent, resolve_frontend_dir + + +class AntdXSenderSwitch(ModelScopeDataLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/sender + """ + EVENTS = [ + EventListener("change", + callback=lambda block: block._internal.update( + bind_change_event=True)), + ] + + # supported slots + SLOTS = ['checkedChildren', 'unCheckedChildren', 'icon'] + + def __init__( + self, + value: bool | None = None, + *, + checked_children: str | None = None, + un_checked_children: str | None = None, + icon: str | None = None, + disabled: bool | None = None, + loading: bool | None = None, + default_value: bool | None = None, + styles: dict | str | None = None, + class_names: dict | str | None = None, + root_class_name: str | None = None, + additional_props: dict | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(value=value, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.styles = styles + self.class_names = class_names + self.root_class_name = root_class_name + self.checked_children = checked_children + self.un_checked_children = un_checked_children + self.icon = icon + self.disabled = disabled + self.loading = loading + self.default_value = default_value + + FRONTEND_DIR = resolve_frontend_dir("sender", 'switch', type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> None: + return None + + def example_value(self) -> None: + return None diff --git a/backend/modelscope_studio/components/antdx/thought_chain/__init__.py b/backend/modelscope_studio/components/antdx/thought_chain/__init__.py index 1b4765bb..d5d18fc4 100644 --- a/backend/modelscope_studio/components/antdx/thought_chain/__init__.py +++ b/backend/modelscope_studio/components/antdx/thought_chain/__init__.py @@ -6,6 +6,7 @@ from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir from .item import AntdXThoughtChainItem +from .thought_chain_item import AntdXThoughtChainThoughtChainItem class AntdXThoughtChain(ModelScopeLayoutComponent): @@ -14,11 +15,12 @@ class AntdXThoughtChain(ModelScopeLayoutComponent): """ Item = AntdXThoughtChainItem + ThoughtChainItem = AntdXThoughtChainThoughtChainItem EVENTS = [ - EventListener("collapsible_expand", + EventListener("expand", callback=lambda block: block._internal.update( - bind_collapsible_expand_event=True), + bind_expand_event=True), doc="Callback function when expanded keys change."), ] @@ -27,14 +29,15 @@ class AntdXThoughtChain(ModelScopeLayoutComponent): def __init__( self, - additional_props: dict | None = None, *, - collapsible: bool | dict | None = None, + expanded_keys: list[str] | None = None, + default_expanded_keys: list[str] | None = None, items: list[dict] | None = None, - size: Literal['small', 'middle', 'large'] | None = None, + line: bool | Literal['solid', 'dashed', "dotted"] | None = None, prefix_cls: str | None = None, - styles: dict | str | None= None, - class_names: dict | str | None= None, + additional_props: dict | None = None, + styles: dict | str | None = None, + class_names: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, @@ -53,9 +56,10 @@ def __init__( elem_style=elem_style, **kwargs) self.additional_props = additional_props - self.collapsible = collapsible self.items = items - self.size = size + self.expanded_keys = expanded_keys + self.default_expanded_keys = default_expanded_keys + self.line = line self.prefix_cls = prefix_cls self.styles = styles self.class_names = class_names diff --git a/backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py b/backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py index 3cc95e57..06663386 100644 --- a/backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py +++ b/backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py @@ -13,20 +13,23 @@ class AntdXThoughtChainItem(ModelScopeLayoutComponent): EVENTS = [] # supported slots - SLOTS = ['content', 'description', 'extra', 'footer', 'icon', 'title'] + SLOTS = ['description', 'icon', 'title'] def __init__( self, - content: str | None = None, - additional_props: dict | None = None, *, - key: str | None = None, description: str | None = None, - extra: str | None = None, - footer: str | None = None, icon: str | None = None, title: str | None = None, - status: Literal['pending', 'success', 'error'] | None = None, + status: Literal['pending', 'success', 'error', 'abort'] + | None = None, + variant: Literal['solid', 'outlined', 'text'] + | None = None, + blink: bool | None = None, + additional_props: dict | None = None, + prefix_cls: str | None = None, + class_names: dict | str | None = None, + styles: dict | str | None = None, as_item: str | None = None, _internal: None = None, # gradio properties @@ -44,14 +47,15 @@ def __init__( elem_style=elem_style, **kwargs) self.additional_props = additional_props - self.content = content self.description = description - self.extra = extra - self.footer = footer self.icon = icon self.title = title self.status = status - self.key = key + self.variant = variant + self.blink = blink + self.prefix_cls = prefix_cls + self.class_names = class_names + self.styles = styles FRONTEND_DIR = resolve_frontend_dir("thought-chain", "item", type="antdx") diff --git a/backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py b/backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py new file mode 100644 index 00000000..3e50fd7c --- /dev/null +++ b/backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +from typing import Any, Literal + +from .....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXThoughtChainThoughtChainItem(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/thought-chain + """ + + EVENTS = [] + + # supported slots + SLOTS = ['content', 'description', 'footer', 'icon', 'title'] + + def __init__( + self, + content: str | None = None, + additional_props: dict | None = None, + *, + key: str | None = None, + description: str | None = None, + extra: str | None = None, + footer: str | None = None, + icon: str | None = None, + title: str | None = None, + status: Literal['pending', 'success', 'error', 'abort'] + | None = None, + collapsible: bool | None = None, + blink: bool | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.content = content + self.description = description + self.extra = extra + self.footer = footer + self.icon = icon + self.title = title + self.status = status + self.key = key + self.collapsible = collapsible + self.blink = blink + + FRONTEND_DIR = resolve_frontend_dir("thought-chain", + "thought-chain-item", + type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/frontend/antd/affix/package.json b/frontend/antd/affix/package.json index 97da442b..567eca5b 100644 --- a/frontend/antd/affix/package.json +++ b/frontend/antd/affix/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/alert/error-boundary/package.json b/frontend/antd/alert/error-boundary/package.json index 81358d1f..1f06e225 100644 --- a/frontend/antd/alert/error-boundary/package.json +++ b/frontend/antd/alert/error-boundary/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/alert/package.json b/frontend/antd/alert/package.json index 08fb77c3..4cbf0891 100644 --- a/frontend/antd/alert/package.json +++ b/frontend/antd/alert/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/anchor/item/package.json b/frontend/antd/anchor/item/package.json index 8a407e76..0f8defe1 100644 --- a/frontend/antd/anchor/item/package.json +++ b/frontend/antd/anchor/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/anchor/package.json b/frontend/antd/anchor/package.json index 40ee8290..7b9f83f5 100644 --- a/frontend/antd/anchor/package.json +++ b/frontend/antd/anchor/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/auto-complete/Index.svelte b/frontend/antd/auto-complete/Index.svelte index 3f6c44e1..150cc4b8 100644 --- a/frontend/antd/auto-complete/Index.svelte +++ b/frontend/antd/auto-complete/Index.svelte @@ -11,18 +11,23 @@ const AwaitedAutoComplete = importComponent(() => import('./auto-complete')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - value: string; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + value: string; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - dropdown_visible_change?: any; - popup_visible_change?: any; - }>(() => props); + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + dropdown_visible_change?: any; + popup_visible_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -38,7 +43,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/auto-complete/option/package.json b/frontend/antd/auto-complete/option/package.json index cc09764f..593db2ec 100644 --- a/frontend/antd/auto-complete/option/package.json +++ b/frontend/antd/auto-complete/option/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/auto-complete/package.json b/frontend/antd/auto-complete/package.json index 511f48a1..4e15dfd0 100644 --- a/frontend/antd/auto-complete/package.json +++ b/frontend/antd/auto-complete/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/avatar/group/package.json b/frontend/antd/avatar/group/package.json index 9353d3bd..28ee1871 100644 --- a/frontend/antd/avatar/group/package.json +++ b/frontend/antd/avatar/group/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/avatar/package.json b/frontend/antd/avatar/package.json index 433e0199..20ea887c 100644 --- a/frontend/antd/avatar/package.json +++ b/frontend/antd/avatar/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/badge/package.json b/frontend/antd/badge/package.json index 5ff82104..1fe094e7 100644 --- a/frontend/antd/badge/package.json +++ b/frontend/antd/badge/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/badge/ribbon/package.json b/frontend/antd/badge/ribbon/package.json index 2ca52113..ad384563 100644 --- a/frontend/antd/badge/ribbon/package.json +++ b/frontend/antd/badge/ribbon/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/breadcrumb/Index.svelte b/frontend/antd/breadcrumb/Index.svelte index e6bebc56..d4210350 100644 --- a/frontend/antd/breadcrumb/Index.svelte +++ b/frontend/antd/breadcrumb/Index.svelte @@ -37,7 +37,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/breadcrumb/item/package.json b/frontend/antd/breadcrumb/item/package.json index 5bc17e02..9352277f 100644 --- a/frontend/antd/breadcrumb/item/package.json +++ b/frontend/antd/breadcrumb/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/breadcrumb/package.json b/frontend/antd/breadcrumb/package.json index 79d543ea..b3938a9f 100644 --- a/frontend/antd/breadcrumb/package.json +++ b/frontend/antd/breadcrumb/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/button/group/package.json b/frontend/antd/button/group/package.json index 2a274c55..26eba872 100644 --- a/frontend/antd/button/group/package.json +++ b/frontend/antd/button/group/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/button/package.json b/frontend/antd/button/package.json index 7c409d28..dd5a6047 100644 --- a/frontend/antd/button/package.json +++ b/frontend/antd/button/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/calendar/Index.svelte b/frontend/antd/calendar/Index.svelte index c55e0d1f..9fe94853 100644 --- a/frontend/antd/calendar/Index.svelte +++ b/frontend/antd/calendar/Index.svelte @@ -11,17 +11,22 @@ const AwaitedCalender = importComponent(() => import('./calendar')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - value?: string | number; - _internal: { - layout?: boolean; - }; - panel_change?: any; - }>(() => props); + as_item?: string | undefined; + value?: string | number; + _internal: { + layout?: boolean; + }; + panel_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -37,7 +42,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, value, diff --git a/frontend/antd/calendar/package.json b/frontend/antd/calendar/package.json index 08c25085..4f970df6 100644 --- a/frontend/antd/calendar/package.json +++ b/frontend/antd/calendar/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/card/Index.svelte b/frontend/antd/card/Index.svelte index 5069c705..ebeeed23 100644 --- a/frontend/antd/card/Index.svelte +++ b/frontend/antd/card/Index.svelte @@ -31,7 +31,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/card/card.tsx b/frontend/antd/card/card.tsx index 1f973869..8aa6caaa 100644 --- a/frontend/antd/card/card.tsx +++ b/frontend/antd/card/card.tsx @@ -36,14 +36,7 @@ export const Card = sveltify< >( withTabsItemsContextProvider( ['tabList'], - ({ - children, - containsGrid, - slots, - tabList, - tabProps, - ...props - }) => { + ({ children, containsGrid, slots, tabList, tabProps, ...props }) => { const targets = useTargets(children, 'actions'); const { items: { tabList: tabListItems }, diff --git a/frontend/antd/card/grid/package.json b/frontend/antd/card/grid/package.json index 3289638e..e3b4a347 100644 --- a/frontend/antd/card/grid/package.json +++ b/frontend/antd/card/grid/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/card/meta/package.json b/frontend/antd/card/meta/package.json index ccd84493..55ac3d74 100644 --- a/frontend/antd/card/meta/package.json +++ b/frontend/antd/card/meta/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/card/package.json b/frontend/antd/card/package.json index e4606ae9..23692a8d 100644 --- a/frontend/antd/card/package.json +++ b/frontend/antd/card/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/carousel/package.json b/frontend/antd/carousel/package.json index 90bdf99f..3752adc0 100644 --- a/frontend/antd/carousel/package.json +++ b/frontend/antd/carousel/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/cascader/Index.svelte b/frontend/antd/cascader/Index.svelte index 15ee9aa2..a9ec309f 100644 --- a/frontend/antd/cascader/Index.svelte +++ b/frontend/antd/cascader/Index.svelte @@ -10,18 +10,23 @@ const AwaitedCascader = importComponent(() => import('./cascader')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - value?: string[] | number[]; - additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - dropdown_visible_change?: any; - popup_visible_change?: any; - load_data?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + value?: string[] | number[]; + additional_props?: Record; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + dropdown_visible_change?: any; + popup_visible_change?: any; + load_data?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -36,7 +41,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/cascader/option/package.json b/frontend/antd/cascader/option/package.json index 34248320..4deea527 100644 --- a/frontend/antd/cascader/option/package.json +++ b/frontend/antd/cascader/option/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/cascader/package.json b/frontend/antd/cascader/package.json index da29c32a..47946d6d 100644 --- a/frontend/antd/cascader/package.json +++ b/frontend/antd/cascader/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/cascader/panel/Index.svelte b/frontend/antd/cascader/panel/Index.svelte index e3a872c5..5c9bb290 100644 --- a/frontend/antd/cascader/panel/Index.svelte +++ b/frontend/antd/cascader/panel/Index.svelte @@ -12,16 +12,21 @@ ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - value?: string[] | number[]; - _internal: { - layout?: boolean; - }; - load_data?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + value?: string[] | number[]; + _internal: { + layout?: boolean; + }; + load_data?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -36,7 +41,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/cascader/panel/package.json b/frontend/antd/cascader/panel/package.json index 9bb1a881..27954b79 100644 --- a/frontend/antd/cascader/panel/package.json +++ b/frontend/antd/cascader/panel/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/checkbox/Index.svelte b/frontend/antd/checkbox/Index.svelte index 1691058d..ec76fdf3 100644 --- a/frontend/antd/checkbox/Index.svelte +++ b/frontend/antd/checkbox/Index.svelte @@ -10,16 +10,21 @@ const AwaitedCheckbox = importComponent(() => import('./checkbox')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - value?: boolean; - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + value?: boolean; + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - }>(() => props); + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/checkbox/group/Index.svelte b/frontend/antd/checkbox/group/Index.svelte index 196717e2..b4f72419 100644 --- a/frontend/antd/checkbox/group/Index.svelte +++ b/frontend/antd/checkbox/group/Index.svelte @@ -12,15 +12,20 @@ ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - value?: (string | number | boolean)[]; - _internal: { - layout?: boolean; - }; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + value?: (string | number | boolean)[]; + _internal: { + layout?: boolean; + }; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/checkbox/group/option/package.json b/frontend/antd/checkbox/group/option/package.json index 2518ecef..18793283 100644 --- a/frontend/antd/checkbox/group/option/package.json +++ b/frontend/antd/checkbox/group/option/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/checkbox/group/package.json b/frontend/antd/checkbox/group/package.json index caca02f0..bee77759 100644 --- a/frontend/antd/checkbox/group/package.json +++ b/frontend/antd/checkbox/group/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/checkbox/package.json b/frontend/antd/checkbox/package.json index aad1d284..2fa1c247 100644 --- a/frontend/antd/checkbox/package.json +++ b/frontend/antd/checkbox/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/collapse/collapse.tsx b/frontend/antd/collapse/collapse.tsx index 64ff9027..564bb8fe 100644 --- a/frontend/antd/collapse/collapse.tsx +++ b/frontend/antd/collapse/collapse.tsx @@ -8,21 +8,10 @@ import { Collapse as ACollapse, type GetProps } from 'antd'; import { useItems, withItemsContextProvider } from './context'; type CollapseProps = GetProps; -export const Collapse = sveltify< - CollapseProps & { - }, - ['expandIcon'] ->( +export const Collapse = sveltify( withItemsContextProvider( ['default', 'items'], - ({ - slots, - items, - children, - onChange, - expandIcon, - ...props - }) => { + ({ slots, items, children, onChange, expandIcon, ...props }) => { const { items: slotItems } = useItems<['default', 'items']>(); const resolvedSlotItems = slotItems.items.length > 0 ? slotItems.items : slotItems.default; diff --git a/frontend/antd/collapse/item/package.json b/frontend/antd/collapse/item/package.json index 0da9d083..66e6d58b 100644 --- a/frontend/antd/collapse/item/package.json +++ b/frontend/antd/collapse/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/collapse/package.json b/frontend/antd/collapse/package.json index bd26edfa..3f058691 100644 --- a/frontend/antd/collapse/package.json +++ b/frontend/antd/collapse/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/color-picker/Index.svelte b/frontend/antd/color-picker/Index.svelte index c94db0c2..f529f402 100644 --- a/frontend/antd/color-picker/Index.svelte +++ b/frontend/antd/color-picker/Index.svelte @@ -10,21 +10,26 @@ const AwaitedColorPicker = importComponent(() => import('./color-picker')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: string | { color: string; percent: number }[]; - value_format?: 'rgb' | 'hex' | 'hsb'; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: string | { color: string; percent: number }[]; + value_format?: 'rgb' | 'hex' | 'hsb'; - change_complete?: any; - open_change?: any; - format_change?: any; - }>(() => props); + change_complete?: any; + open_change?: any; + format_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -41,7 +46,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/color-picker/package.json b/frontend/antd/color-picker/package.json index f725b70b..d3e1d16b 100644 --- a/frontend/antd/color-picker/package.json +++ b/frontend/antd/color-picker/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/color-picker/preset/package.json b/frontend/antd/color-picker/preset/package.json index 742ac13e..d956e272 100644 --- a/frontend/antd/color-picker/preset/package.json +++ b/frontend/antd/color-picker/preset/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/config-provider/package.json b/frontend/antd/config-provider/package.json index b5b1a6fc..2e7d0170 100644 --- a/frontend/antd/config-provider/package.json +++ b/frontend/antd/config-provider/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/date-picker/Index.svelte b/frontend/antd/date-picker/Index.svelte index 28ba22ae..7baff9b9 100644 --- a/frontend/antd/date-picker/Index.svelte +++ b/frontend/antd/date-picker/Index.svelte @@ -10,18 +10,23 @@ const AwaitedDatePicker = importComponent(() => import('./date-picker')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: string | number | (string | number | null)[] | null; - panel_change?: any; - open_change?: any; - }>(() => props); + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: string | number | (string | number | null)[] | null; + panel_change?: any; + open_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -37,7 +42,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/date-picker/package.json b/frontend/antd/date-picker/package.json index 255df8a9..7f2ee5f0 100644 --- a/frontend/antd/date-picker/package.json +++ b/frontend/antd/date-picker/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/date-picker/preset/package.json b/frontend/antd/date-picker/preset/package.json index 645a8c87..8397fff5 100644 --- a/frontend/antd/date-picker/preset/package.json +++ b/frontend/antd/date-picker/preset/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/date-picker/range-picker/Index.svelte b/frontend/antd/date-picker/range-picker/Index.svelte index 725107b4..5a75550a 100644 --- a/frontend/antd/date-picker/range-picker/Index.svelte +++ b/frontend/antd/date-picker/range-picker/Index.svelte @@ -12,15 +12,20 @@ ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - value?: [string | number | null, string | number | null]; - _internal: { - layout?: boolean; - }; - calendar_change?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + value?: [string | number | null, string | number | null]; + _internal: { + layout?: boolean; + }; + calendar_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -36,7 +41,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/date-picker/range-picker/package.json b/frontend/antd/date-picker/range-picker/package.json index cf035a9e..c0d96786 100644 --- a/frontend/antd/date-picker/range-picker/package.json +++ b/frontend/antd/date-picker/range-picker/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/descriptions/item/package.json b/frontend/antd/descriptions/item/package.json index dec14896..1b0a1805 100644 --- a/frontend/antd/descriptions/item/package.json +++ b/frontend/antd/descriptions/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/descriptions/package.json b/frontend/antd/descriptions/package.json index 0b4c4628..c8af7f60 100644 --- a/frontend/antd/descriptions/package.json +++ b/frontend/antd/descriptions/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/divider/package.json b/frontend/antd/divider/package.json index 1d726c4d..177a4bd1 100644 --- a/frontend/antd/divider/package.json +++ b/frontend/antd/divider/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/drawer/package.json b/frontend/antd/drawer/package.json index b0bd9ab3..28d2f707 100644 --- a/frontend/antd/drawer/package.json +++ b/frontend/antd/drawer/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/dropdown/Index.svelte b/frontend/antd/dropdown/Index.svelte index 6e95314d..6490f7a2 100644 --- a/frontend/antd/dropdown/Index.svelte +++ b/frontend/antd/dropdown/Index.svelte @@ -33,7 +33,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/dropdown/button/Index.svelte b/frontend/antd/dropdown/button/Index.svelte index a2b7039f..681ad8fa 100644 --- a/frontend/antd/dropdown/button/Index.svelte +++ b/frontend/antd/dropdown/button/Index.svelte @@ -34,7 +34,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/dropdown/button/package.json b/frontend/antd/dropdown/button/package.json index f104ebef..8d5ed01a 100644 --- a/frontend/antd/dropdown/button/package.json +++ b/frontend/antd/dropdown/button/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/dropdown/package.json b/frontend/antd/dropdown/package.json index 5cbe4a0f..38103f22 100644 --- a/frontend/antd/dropdown/package.json +++ b/frontend/antd/dropdown/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/empty/package.json b/frontend/antd/empty/package.json index 968ab06e..e53e4385 100644 --- a/frontend/antd/empty/package.json +++ b/frontend/antd/empty/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/flex/package.json b/frontend/antd/flex/package.json index 968ab06e..e53e4385 100644 --- a/frontend/antd/flex/package.json +++ b/frontend/antd/flex/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/float-button/Index.svelte b/frontend/antd/float-button/Index.svelte index 1be05eab..b2df0aed 100644 --- a/frontend/antd/float-button/Index.svelte +++ b/frontend/antd/float-button/Index.svelte @@ -33,7 +33,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/float-button/back-top/Index.svelte b/frontend/antd/float-button/back-top/Index.svelte index 500a5022..ec533104 100644 --- a/frontend/antd/float-button/back-top/Index.svelte +++ b/frontend/antd/float-button/back-top/Index.svelte @@ -34,7 +34,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/float-button/back-top/package.json b/frontend/antd/float-button/back-top/package.json index 6ec6d243..71c83ba9 100644 --- a/frontend/antd/float-button/back-top/package.json +++ b/frontend/antd/float-button/back-top/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/float-button/group/Index.svelte b/frontend/antd/float-button/group/Index.svelte index 1e6d7a71..26740971 100644 --- a/frontend/antd/float-button/group/Index.svelte +++ b/frontend/antd/float-button/group/Index.svelte @@ -33,7 +33,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/float-button/group/package.json b/frontend/antd/float-button/group/package.json index 934ecfe7..caa70ed5 100644 --- a/frontend/antd/float-button/group/package.json +++ b/frontend/antd/float-button/group/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/float-button/package.json b/frontend/antd/float-button/package.json index 942fb12d..331ea99c 100644 --- a/frontend/antd/float-button/package.json +++ b/frontend/antd/float-button/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/form/Index.svelte b/frontend/antd/form/Index.svelte index 6ea30aa3..9bdd42b1 100644 --- a/frontend/antd/form/Index.svelte +++ b/frontend/antd/form/Index.svelte @@ -12,19 +12,24 @@ const AwaitedForm = importComponent(() => import('./form')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - _internal: { - layout?: boolean; - }; - value?: Record; - form_action?: FormProps['formAction'] | null; - form_name?: string; - fields_change?: any; - finish_failed?: any; - values_change?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + _internal: { + layout?: boolean; + }; + value?: Record; + form_action?: FormProps['formAction'] | null; + form_name?: string; + fields_change?: any; + finish_failed?: any; + values_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -41,7 +46,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/form/item/Index.svelte b/frontend/antd/form/item/Index.svelte index 22495224..9ab6aa33 100644 --- a/frontend/antd/form/item/Index.svelte +++ b/frontend/antd/form/item/Index.svelte @@ -31,7 +31,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/form/item/package.json b/frontend/antd/form/item/package.json index 70a0a7e5..ea17d06e 100644 --- a/frontend/antd/form/item/package.json +++ b/frontend/antd/form/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/form/item/rule/package.json b/frontend/antd/form/item/rule/package.json index 496f775d..65e2a47b 100644 --- a/frontend/antd/form/item/rule/package.json +++ b/frontend/antd/form/item/rule/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/form/package.json b/frontend/antd/form/package.json index f0cd1c5d..8ba4721e 100644 --- a/frontend/antd/form/package.json +++ b/frontend/antd/form/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/form/provider/Index.svelte b/frontend/antd/form/provider/Index.svelte index 29b3aaee..cbfb622c 100644 --- a/frontend/antd/form/provider/Index.svelte +++ b/frontend/antd/form/provider/Index.svelte @@ -29,7 +29,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/form/provider/package.json b/frontend/antd/form/provider/package.json index 33496ee6..bb973215 100644 --- a/frontend/antd/form/provider/package.json +++ b/frontend/antd/form/provider/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/grid/col/package.json b/frontend/antd/grid/col/package.json index 7fcfeb0b..4106636b 100644 --- a/frontend/antd/grid/col/package.json +++ b/frontend/antd/grid/col/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/grid/row/package.json b/frontend/antd/grid/row/package.json index 72bab38d..6d91b7c2 100644 --- a/frontend/antd/grid/row/package.json +++ b/frontend/antd/grid/row/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/icon/iconfont-provider/package.json b/frontend/antd/icon/iconfont-provider/package.json index 4005caa8..77c7e136 100644 --- a/frontend/antd/icon/iconfont-provider/package.json +++ b/frontend/antd/icon/iconfont-provider/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/icon/package.json b/frontend/antd/icon/package.json index 2cfbc4d0..1c313730 100644 --- a/frontend/antd/icon/package.json +++ b/frontend/antd/icon/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/image/Index.svelte b/frontend/antd/image/Index.svelte index 454ed15e..5a597c96 100644 --- a/frontend/antd/image/Index.svelte +++ b/frontend/antd/image/Index.svelte @@ -37,7 +37,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/image/image.tsx b/frontend/antd/image/image.tsx index ed5e184a..35c50274 100644 --- a/frontend/antd/image/image.tsx +++ b/frontend/antd/image/image.tsx @@ -13,8 +13,7 @@ function getConfig(value: T): Partial> { } type ImageProps = GetProps; export const Image = sveltify< - ImageProps & { - }, + ImageProps & {}, [ 'placeholder', 'preview.mask', diff --git a/frontend/antd/image/package.json b/frontend/antd/image/package.json index e7ba95d7..ef0a35a1 100644 --- a/frontend/antd/image/package.json +++ b/frontend/antd/image/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/image/preview-group/Index.svelte b/frontend/antd/image/preview-group/Index.svelte index bd53a2a9..10980e58 100644 --- a/frontend/antd/image/preview-group/Index.svelte +++ b/frontend/antd/image/preview-group/Index.svelte @@ -33,7 +33,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/image/preview-group/package.json b/frontend/antd/image/preview-group/package.json index 5925e7d8..1112ef29 100644 --- a/frontend/antd/image/preview-group/package.json +++ b/frontend/antd/image/preview-group/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/input-number/Index.svelte b/frontend/antd/input-number/Index.svelte index 19809cb8..b0d9a196 100644 --- a/frontend/antd/input-number/Index.svelte +++ b/frontend/antd/input-number/Index.svelte @@ -10,18 +10,23 @@ const AwaitedInputNumber = importComponent(() => import('./input-number')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: number | string | null; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: number | string | null; - press_enter?: any; - }>(() => props); + press_enter?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -37,7 +42,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/input-number/package.json b/frontend/antd/input-number/package.json index 38779fc3..d5b6196c 100644 --- a/frontend/antd/input-number/package.json +++ b/frontend/antd/input-number/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/input/Index.svelte b/frontend/antd/input/Index.svelte index ff28b80b..a2d914b4 100644 --- a/frontend/antd/input/Index.svelte +++ b/frontend/antd/input/Index.svelte @@ -10,17 +10,22 @@ const AwaitedInput = importComponent(() => import('./input')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - _internal: { - layout?: boolean; - }; - value?: string; + _internal: { + layout?: boolean; + }; + value?: string; - press_enter?: any; - }>(() => props); + press_enter?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -36,7 +41,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/input/otp/Index.svelte b/frontend/antd/input/otp/Index.svelte index bcd582cd..0e5e6c12 100644 --- a/frontend/antd/input/otp/Index.svelte +++ b/frontend/antd/input/otp/Index.svelte @@ -10,15 +10,20 @@ const AwaitedInputOTP = importComponent(() => import('./input.otp')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: string; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: string; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/input/otp/package.json b/frontend/antd/input/otp/package.json index 4d7e5a6d..6ca6c979 100644 --- a/frontend/antd/input/otp/package.json +++ b/frontend/antd/input/otp/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/input/package.json b/frontend/antd/input/package.json index 1e06b44d..b05ca714 100644 --- a/frontend/antd/input/package.json +++ b/frontend/antd/input/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/input/password/Index.svelte b/frontend/antd/input/password/Index.svelte index 02f4f72c..34e7bd9e 100644 --- a/frontend/antd/input/password/Index.svelte +++ b/frontend/antd/input/password/Index.svelte @@ -12,16 +12,21 @@ ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - _internal: { - layout?: boolean; - }; - value?: string; - press_enter?: any; - visibility_toggle_visible_change?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + _internal: { + layout?: boolean; + }; + value?: string; + press_enter?: any; + visibility_toggle_visible_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -36,7 +41,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/input/password/package.json b/frontend/antd/input/password/package.json index a1d844ab..7e1212ab 100644 --- a/frontend/antd/input/password/package.json +++ b/frontend/antd/input/password/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/input/search/Index.svelte b/frontend/antd/input/search/Index.svelte index 96446d57..dedfa308 100644 --- a/frontend/antd/input/search/Index.svelte +++ b/frontend/antd/input/search/Index.svelte @@ -10,15 +10,20 @@ const AwaitedInputSearch = importComponent(() => import('./input.search')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - _internal: { - layout?: boolean; - }; - value?: string; - press_enter?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + _internal: { + layout?: boolean; + }; + value?: string; + press_enter?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -33,7 +38,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/input/search/package.json b/frontend/antd/input/search/package.json index 199e28ca..4df8bcdc 100644 --- a/frontend/antd/input/search/package.json +++ b/frontend/antd/input/search/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/input/textarea/Index.svelte b/frontend/antd/input/textarea/Index.svelte index 298d8bd7..2bd90ff2 100644 --- a/frontend/antd/input/textarea/Index.svelte +++ b/frontend/antd/input/textarea/Index.svelte @@ -10,15 +10,20 @@ const AwaitedTextArea = importComponent(() => import('./input.textarea')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - value?: string; - _internal: { - layout?: boolean; - }; - press_enter?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + value?: string; + _internal: { + layout?: boolean; + }; + press_enter?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -33,7 +38,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/input/textarea/package.json b/frontend/antd/input/textarea/package.json index cbf45dda..fa271510 100644 --- a/frontend/antd/input/textarea/package.json +++ b/frontend/antd/input/textarea/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/layout/content/package.json b/frontend/antd/layout/content/package.json index d1d8802b..4c90fd14 100644 --- a/frontend/antd/layout/content/package.json +++ b/frontend/antd/layout/content/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/layout/footer/package.json b/frontend/antd/layout/footer/package.json index 081f6f0d..dab12318 100644 --- a/frontend/antd/layout/footer/package.json +++ b/frontend/antd/layout/footer/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/layout/header/package.json b/frontend/antd/layout/header/package.json index 3a473715..3de1b402 100644 --- a/frontend/antd/layout/header/package.json +++ b/frontend/antd/layout/header/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/layout/package.json b/frontend/antd/layout/package.json index fb548851..af70f7b0 100644 --- a/frontend/antd/layout/package.json +++ b/frontend/antd/layout/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/layout/sider/package.json b/frontend/antd/layout/sider/package.json index e93c644e..9d9ca886 100644 --- a/frontend/antd/layout/sider/package.json +++ b/frontend/antd/layout/sider/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/list/Index.svelte b/frontend/antd/list/Index.svelte index ce1b1cd3..ed326726 100644 --- a/frontend/antd/list/Index.svelte +++ b/frontend/antd/list/Index.svelte @@ -32,7 +32,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/list/item/meta/package.json b/frontend/antd/list/item/meta/package.json index 1cf251bb..d83eddc6 100644 --- a/frontend/antd/list/item/meta/package.json +++ b/frontend/antd/list/item/meta/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/list/item/package.json b/frontend/antd/list/item/package.json index 729c77ae..413ad191 100644 --- a/frontend/antd/list/item/package.json +++ b/frontend/antd/list/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/list/list.tsx b/frontend/antd/list/list.tsx index 6405aacc..9086950c 100644 --- a/frontend/antd/list/list.tsx +++ b/frontend/antd/list/list.tsx @@ -6,8 +6,7 @@ import { renderParamsSlot } from '@utils/renderParamsSlot'; import { type GetProps, List as AList } from 'antd'; export const List = sveltify< - GetProps & { - }, + GetProps & {}, ['footer', 'header', 'loadMore', 'renderItem'] >(({ slots, renderItem, ...props }) => { const renderItemFunction = useFunction(renderItem); diff --git a/frontend/antd/list/package.json b/frontend/antd/list/package.json index c6f617dd..f89b32d3 100644 --- a/frontend/antd/list/package.json +++ b/frontend/antd/list/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/mentions/Index.svelte b/frontend/antd/mentions/Index.svelte index 25a8dca1..bd93a1a6 100644 --- a/frontend/antd/mentions/Index.svelte +++ b/frontend/antd/mentions/Index.svelte @@ -10,18 +10,23 @@ const AwaitedMentions = importComponent(() => import('./mentions')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: string; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: string; - popup_scroll?: any; - }>(() => props); + popup_scroll?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -37,7 +42,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/mentions/option/package.json b/frontend/antd/mentions/option/package.json index 295cd4af..743957d8 100644 --- a/frontend/antd/mentions/option/package.json +++ b/frontend/antd/mentions/option/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/mentions/package.json b/frontend/antd/mentions/package.json index 4b99168f..8eaf25c4 100644 --- a/frontend/antd/mentions/package.json +++ b/frontend/antd/mentions/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/menu/Index.svelte b/frontend/antd/menu/Index.svelte index 5bc91307..f191c3c5 100644 --- a/frontend/antd/menu/Index.svelte +++ b/frontend/antd/menu/Index.svelte @@ -33,7 +33,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/menu/item/package.json b/frontend/antd/menu/item/package.json index f078a35d..a7b645bd 100644 --- a/frontend/antd/menu/item/package.json +++ b/frontend/antd/menu/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/menu/menu.tsx b/frontend/antd/menu/menu.tsx index a82ffdac..9adacefa 100644 --- a/frontend/antd/menu/menu.tsx +++ b/frontend/antd/menu/menu.tsx @@ -12,8 +12,7 @@ import { useItems, withItemsContextProvider } from './context'; import './menu.less'; export const Menu = sveltify< - GetProps & { - }, + GetProps & {}, ['expandIcon', 'overflowedIndicator'] >( withItemsContextProvider( diff --git a/frontend/antd/menu/package.json b/frontend/antd/menu/package.json index 21d1e57c..ffd62229 100644 --- a/frontend/antd/menu/package.json +++ b/frontend/antd/menu/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/message/Index.svelte b/frontend/antd/message/Index.svelte index c1219ddb..1f5bd996 100644 --- a/frontend/antd/message/Index.svelte +++ b/frontend/antd/message/Index.svelte @@ -10,16 +10,21 @@ const AwaitedMessage = importComponent(() => import('./message')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - _internal: { - layout?: boolean; - }; - key?: string; - content?: string; - }>(() => props); + _internal: { + layout?: boolean; + }; + key?: string; + content?: string; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/message/package.json b/frontend/antd/message/package.json index 6690b00d..c2d8089f 100644 --- a/frontend/antd/message/package.json +++ b/frontend/antd/message/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/modal/package.json b/frontend/antd/modal/package.json index b12ba527..4c2c32f4 100644 --- a/frontend/antd/modal/package.json +++ b/frontend/antd/modal/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/modal/static/Index.svelte b/frontend/antd/modal/static/Index.svelte index 7ee953d0..fed5c7f8 100644 --- a/frontend/antd/modal/static/Index.svelte +++ b/frontend/antd/modal/static/Index.svelte @@ -10,14 +10,19 @@ const AwaitedModalStatic = importComponent(() => import('./modal.static')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/modal/static/package.json b/frontend/antd/modal/static/package.json index 80b28455..2518d8e3 100644 --- a/frontend/antd/modal/static/package.json +++ b/frontend/antd/modal/static/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/notification/Index.svelte b/frontend/antd/notification/Index.svelte index 0f129917..8ed86c6e 100644 --- a/frontend/antd/notification/Index.svelte +++ b/frontend/antd/notification/Index.svelte @@ -10,17 +10,22 @@ const AwaitedNotification = importComponent(() => import('./notification')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - key?: string; - message?: string; - }>(() => props); + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + key?: string; + message?: string; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/notification/package.json b/frontend/antd/notification/package.json index 70926955..ef9e8918 100644 --- a/frontend/antd/notification/package.json +++ b/frontend/antd/notification/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/pagination/Index.svelte b/frontend/antd/pagination/Index.svelte index be1bb255..064be5d0 100644 --- a/frontend/antd/pagination/Index.svelte +++ b/frontend/antd/pagination/Index.svelte @@ -32,7 +32,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/pagination/package.json b/frontend/antd/pagination/package.json index e4670065..acb44162 100644 --- a/frontend/antd/pagination/package.json +++ b/frontend/antd/pagination/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/pagination/pagination.tsx b/frontend/antd/pagination/pagination.tsx index 42154a78..5d83e653 100644 --- a/frontend/antd/pagination/pagination.tsx +++ b/frontend/antd/pagination/pagination.tsx @@ -30,10 +30,7 @@ export const Pagination = sveltify< showTotal={showTotal ? showTotalFunction : undefined} itemRender={ slots.itemRender - ? renderParamsSlot( - { slots, key: 'itemRender' }, - { clone: true } - ) + ? renderParamsSlot({ slots, key: 'itemRender' }, { clone: true }) : itemRenderFunction } onChange={(page, pageSize) => { diff --git a/frontend/antd/popconfirm/Index.svelte b/frontend/antd/popconfirm/Index.svelte index 8139433c..76e5abf3 100644 --- a/frontend/antd/popconfirm/Index.svelte +++ b/frontend/antd/popconfirm/Index.svelte @@ -37,7 +37,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/popconfirm/package.json b/frontend/antd/popconfirm/package.json index fe5fff9e..05002b32 100644 --- a/frontend/antd/popconfirm/package.json +++ b/frontend/antd/popconfirm/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/popover/Index.svelte b/frontend/antd/popover/Index.svelte index 669f2bf1..38f3395f 100644 --- a/frontend/antd/popover/Index.svelte +++ b/frontend/antd/popover/Index.svelte @@ -35,7 +35,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/popover/package.json b/frontend/antd/popover/package.json index 597b1773..801effd1 100644 --- a/frontend/antd/popover/package.json +++ b/frontend/antd/popover/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/progress/package.json b/frontend/antd/progress/package.json index ae96d020..649c102e 100644 --- a/frontend/antd/progress/package.json +++ b/frontend/antd/progress/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/qr-code/package.json b/frontend/antd/qr-code/package.json index f1d43ad8..fa9777e9 100644 --- a/frontend/antd/qr-code/package.json +++ b/frontend/antd/qr-code/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/qr-code/qr-code.tsx b/frontend/antd/qr-code/qr-code.tsx index 687ba7c9..bef1a96e 100644 --- a/frontend/antd/qr-code/qr-code.tsx +++ b/frontend/antd/qr-code/qr-code.tsx @@ -3,22 +3,20 @@ import { useFunction } from '@utils/hooks/useFunction'; import { renderParamsSlot } from '@utils/renderParamsSlot'; import { type GetProps, QRCode as AQRCode } from 'antd'; -export const QRCode = sveltify< - GetProps & { - }, - ['statusRender'] ->(({ slots, statusRender, ...props }) => { - const statusRenderFunction = useFunction(statusRender); - return ( - - ); -}); +export const QRCode = sveltify & {}, ['statusRender']>( + ({ slots, statusRender, ...props }) => { + const statusRenderFunction = useFunction(statusRender); + return ( + + ); + } +); export default QRCode; diff --git a/frontend/antd/radio/Index.svelte b/frontend/antd/radio/Index.svelte index ba174341..ced347c2 100644 --- a/frontend/antd/radio/Index.svelte +++ b/frontend/antd/radio/Index.svelte @@ -10,16 +10,21 @@ const AwaitedRadio = importComponent(() => import('./radio')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - group_value?: any; - _internal: { - layout?: boolean; - }; - value?: boolean; - }>(() => props); + group_value?: any; + _internal: { + layout?: boolean; + }; + value?: boolean; + }>(() => props); const getProceedProps = processProps( () => { @@ -35,7 +40,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/radio/button/Index.svelte b/frontend/antd/radio/button/Index.svelte index f47d8474..e5d9fa08 100644 --- a/frontend/antd/radio/button/Index.svelte +++ b/frontend/antd/radio/button/Index.svelte @@ -10,17 +10,22 @@ const AwaitedRadioButton = importComponent(() => import('./radio.button')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - index?: number; - }; - value?: boolean; - group_value?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + _internal: { + layout?: boolean; + index?: number; + }; + value?: boolean; + group_value?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -36,7 +41,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/radio/button/package.json b/frontend/antd/radio/button/package.json index ec80da14..18580565 100644 --- a/frontend/antd/radio/button/package.json +++ b/frontend/antd/radio/button/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/radio/group/Index.svelte b/frontend/antd/radio/group/Index.svelte index 117ecda2..278ce547 100644 --- a/frontend/antd/radio/group/Index.svelte +++ b/frontend/antd/radio/group/Index.svelte @@ -10,16 +10,21 @@ const AwaitedRadioGroup = importComponent(() => import('./radio.group')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - form_name?: string; - value?: any; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + form_name?: string; + value?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -34,7 +39,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/radio/group/option/package.json b/frontend/antd/radio/group/option/package.json index c93c2d0d..263f4e46 100644 --- a/frontend/antd/radio/group/option/package.json +++ b/frontend/antd/radio/group/option/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/radio/group/package.json b/frontend/antd/radio/group/package.json index bc2654c9..daff9e8a 100644 --- a/frontend/antd/radio/group/package.json +++ b/frontend/antd/radio/group/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/radio/package.json b/frontend/antd/radio/package.json index 23aef293..a195a2ed 100644 --- a/frontend/antd/radio/package.json +++ b/frontend/antd/radio/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/rate/Index.svelte b/frontend/antd/rate/Index.svelte index 475a8d55..d6c95512 100644 --- a/frontend/antd/rate/Index.svelte +++ b/frontend/antd/rate/Index.svelte @@ -10,19 +10,24 @@ const AwaitedRate = importComponent(() => import('./rate')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: number; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: number; - hover_change?: any; - key_down?: any; - }>(() => props); + hover_change?: any; + key_down?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -38,7 +43,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/rate/package.json b/frontend/antd/rate/package.json index fae33ef2..bb78d41e 100644 --- a/frontend/antd/rate/package.json +++ b/frontend/antd/rate/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/result/package.json b/frontend/antd/result/package.json index 7f3d2a90..9aa37eb1 100644 --- a/frontend/antd/result/package.json +++ b/frontend/antd/result/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/segmented/Index.svelte b/frontend/antd/segmented/Index.svelte index 21a82787..345203cd 100644 --- a/frontend/antd/segmented/Index.svelte +++ b/frontend/antd/segmented/Index.svelte @@ -12,17 +12,22 @@ const AwaitedSegmented = importComponent(() => import('./segmented')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - _internal: { - layout?: boolean; - }; - value?: number | string; - form_name?: string; - options?: SegmentedProps['options']; - }>(() => props); + _internal: { + layout?: boolean; + }; + value?: number | string; + form_name?: string; + options?: SegmentedProps['options']; + }>(() => props); const getProceedProps = processProps( () => { @@ -38,7 +43,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/segmented/option/package.json b/frontend/antd/segmented/option/package.json index e9e9c7ee..7f9d8348 100644 --- a/frontend/antd/segmented/option/package.json +++ b/frontend/antd/segmented/option/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/segmented/package.json b/frontend/antd/segmented/package.json index f1d43ad8..fa9777e9 100644 --- a/frontend/antd/segmented/package.json +++ b/frontend/antd/segmented/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/select/Index.svelte b/frontend/antd/select/Index.svelte index 3bf721dd..e584d31b 100644 --- a/frontend/antd/select/Index.svelte +++ b/frontend/antd/select/Index.svelte @@ -10,19 +10,24 @@ const AwaitedSelect = importComponent(() => import('./select')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - _internal: { - layout?: boolean; - }; - value?: string | number | (string | number)[]; + _internal: { + layout?: boolean; + }; + value?: string | number | (string | number)[]; - popup_scroll?: any; - dropdown_visible_change?: any; - popup_visible_change?: any; - }>(() => props); + popup_scroll?: any; + dropdown_visible_change?: any; + popup_visible_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -38,7 +43,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/select/option/package.json b/frontend/antd/select/option/package.json index 527c382d..91f06aca 100644 --- a/frontend/antd/select/option/package.json +++ b/frontend/antd/select/option/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/select/package.json b/frontend/antd/select/package.json index 03094c7a..5b17e4a2 100644 --- a/frontend/antd/select/package.json +++ b/frontend/antd/select/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/skeleton/avatar/package.json b/frontend/antd/skeleton/avatar/package.json index 35aa5482..94e36420 100644 --- a/frontend/antd/skeleton/avatar/package.json +++ b/frontend/antd/skeleton/avatar/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/skeleton/button/package.json b/frontend/antd/skeleton/button/package.json index 415a6d95..b30a59d4 100644 --- a/frontend/antd/skeleton/button/package.json +++ b/frontend/antd/skeleton/button/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/skeleton/image/package.json b/frontend/antd/skeleton/image/package.json index 6467b271..00e30e54 100644 --- a/frontend/antd/skeleton/image/package.json +++ b/frontend/antd/skeleton/image/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/skeleton/input/package.json b/frontend/antd/skeleton/input/package.json index 011e2611..104f9b5d 100644 --- a/frontend/antd/skeleton/input/package.json +++ b/frontend/antd/skeleton/input/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/skeleton/node/package.json b/frontend/antd/skeleton/node/package.json index a4a7b24c..7ed2bc2e 100644 --- a/frontend/antd/skeleton/node/package.json +++ b/frontend/antd/skeleton/node/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/skeleton/package.json b/frontend/antd/skeleton/package.json index a8848a90..93eba12a 100644 --- a/frontend/antd/skeleton/package.json +++ b/frontend/antd/skeleton/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/slider/Index.svelte b/frontend/antd/slider/Index.svelte index 716d6085..e8801608 100644 --- a/frontend/antd/slider/Index.svelte +++ b/frontend/antd/slider/Index.svelte @@ -10,18 +10,23 @@ const AwaitedSlider = importComponent(() => import('./slider')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: number | number[]; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: number | number[]; - change_complete?: any; - }>(() => props); + change_complete?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -37,7 +42,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/slider/mark/package.json b/frontend/antd/slider/mark/package.json index f7302d2a..9c6c59d8 100644 --- a/frontend/antd/slider/mark/package.json +++ b/frontend/antd/slider/mark/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/slider/package.json b/frontend/antd/slider/package.json index 7cb4695d..15a52e8c 100644 --- a/frontend/antd/slider/package.json +++ b/frontend/antd/slider/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/space/compact/package.json b/frontend/antd/space/compact/package.json index c6865718..b874ec55 100644 --- a/frontend/antd/space/compact/package.json +++ b/frontend/antd/space/compact/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/space/package.json b/frontend/antd/space/package.json index 2f2bb790..c7177363 100644 --- a/frontend/antd/space/package.json +++ b/frontend/antd/space/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/spin/package.json b/frontend/antd/spin/package.json index ae3028cc..e1a9d8bc 100644 --- a/frontend/antd/spin/package.json +++ b/frontend/antd/spin/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/splitter/Index.svelte b/frontend/antd/splitter/Index.svelte index b83a4403..a9773939 100644 --- a/frontend/antd/splitter/Index.svelte +++ b/frontend/antd/splitter/Index.svelte @@ -35,7 +35,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/splitter/package.json b/frontend/antd/splitter/package.json index f81675f0..26bf437d 100644 --- a/frontend/antd/splitter/package.json +++ b/frontend/antd/splitter/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/splitter/panel/package.json b/frontend/antd/splitter/panel/package.json index 79840404..03b83b8e 100644 --- a/frontend/antd/splitter/panel/package.json +++ b/frontend/antd/splitter/panel/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/statistic/countdown/package.json b/frontend/antd/statistic/countdown/package.json index 8e94d069..b45af8d9 100644 --- a/frontend/antd/statistic/countdown/package.json +++ b/frontend/antd/statistic/countdown/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/statistic/package.json b/frontend/antd/statistic/package.json index 6e457ec3..71849740 100644 --- a/frontend/antd/statistic/package.json +++ b/frontend/antd/statistic/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/statistic/timer/package.json b/frontend/antd/statistic/timer/package.json index 7ef22ab1..f05ffff8 100644 --- a/frontend/antd/statistic/timer/package.json +++ b/frontend/antd/statistic/timer/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/steps/item/package.json b/frontend/antd/steps/item/package.json index 533045f0..ca8b4ada 100644 --- a/frontend/antd/steps/item/package.json +++ b/frontend/antd/steps/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/steps/package.json b/frontend/antd/steps/package.json index c6cbdd10..4cd95aad 100644 --- a/frontend/antd/steps/package.json +++ b/frontend/antd/steps/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/switch/Index.svelte b/frontend/antd/switch/Index.svelte index 56dfaa81..5136fb3a 100644 --- a/frontend/antd/switch/Index.svelte +++ b/frontend/antd/switch/Index.svelte @@ -10,14 +10,19 @@ const AwaitedSwitch = importComponent(() => import('./switch')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: {}; - value?: boolean; - }>(() => props); + as_item?: string | undefined; + _internal: {}; + value?: boolean; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/switch/package.json b/frontend/antd/switch/package.json index 3a81efa0..420b2865 100644 --- a/frontend/antd/switch/package.json +++ b/frontend/antd/switch/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/table/column-group/package.json b/frontend/antd/table/column-group/package.json index 0b211b78..d01a7cf9 100644 --- a/frontend/antd/table/column-group/package.json +++ b/frontend/antd/table/column-group/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/table/column/package.json b/frontend/antd/table/column/package.json index 4d346167..41f90e4e 100644 --- a/frontend/antd/table/column/package.json +++ b/frontend/antd/table/column/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/table/expandable/package.json b/frontend/antd/table/expandable/package.json index 7903774c..49fcbeb9 100644 --- a/frontend/antd/table/expandable/package.json +++ b/frontend/antd/table/expandable/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/table/package.json b/frontend/antd/table/package.json index 30aa7610..d7b65337 100644 --- a/frontend/antd/table/package.json +++ b/frontend/antd/table/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/table/row-selection/package.json b/frontend/antd/table/row-selection/package.json index bf1eafd4..f2dbb877 100644 --- a/frontend/antd/table/row-selection/package.json +++ b/frontend/antd/table/row-selection/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/table/row-selection/selection/package.json b/frontend/antd/table/row-selection/selection/package.json index 975c06b9..af88e2e9 100644 --- a/frontend/antd/table/row-selection/selection/package.json +++ b/frontend/antd/table/row-selection/selection/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/table/table.tsx b/frontend/antd/table/table.tsx index 60003301..ae55eb9a 100644 --- a/frontend/antd/table/table.tsx +++ b/frontend/antd/table/table.tsx @@ -26,8 +26,7 @@ function getConfig(value: T): Partial> { type TableProps = GetProps; export const Table = sveltify< - TableProps & { - }, + TableProps & {}, [ 'footer', 'title', diff --git a/frontend/antd/tabs/Index.svelte b/frontend/antd/tabs/Index.svelte index 4b7cfa64..5a594eab 100644 --- a/frontend/antd/tabs/Index.svelte +++ b/frontend/antd/tabs/Index.svelte @@ -32,7 +32,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/tabs/item/package.json b/frontend/antd/tabs/item/package.json index cefe2bfb..24f8d65c 100644 --- a/frontend/antd/tabs/item/package.json +++ b/frontend/antd/tabs/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tabs/package.json b/frontend/antd/tabs/package.json index c52cec1f..d3d5cb53 100644 --- a/frontend/antd/tabs/package.json +++ b/frontend/antd/tabs/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tabs/tabs.tsx b/frontend/antd/tabs/tabs.tsx index 37067933..82db68ad 100644 --- a/frontend/antd/tabs/tabs.tsx +++ b/frontend/antd/tabs/tabs.tsx @@ -10,8 +10,7 @@ import { type GetProps, Tabs as ATabs } from 'antd'; import { useItems, withItemsContextProvider } from './context'; export const Tabs = sveltify< - GetProps & { - }, + GetProps & {}, [ 'addIcon', 'removeIcon', diff --git a/frontend/antd/tag/checkable-tag/Index.svelte b/frontend/antd/tag/checkable-tag/Index.svelte index 20faa50f..3279bd06 100644 --- a/frontend/antd/tag/checkable-tag/Index.svelte +++ b/frontend/antd/tag/checkable-tag/Index.svelte @@ -12,15 +12,20 @@ ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: boolean; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: boolean; + }>(() => props); const getProceedProps = processProps(() => { const { diff --git a/frontend/antd/tag/checkable-tag/package.json b/frontend/antd/tag/checkable-tag/package.json index ce1b1c46..bcbdd76c 100644 --- a/frontend/antd/tag/checkable-tag/package.json +++ b/frontend/antd/tag/checkable-tag/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tag/package.json b/frontend/antd/tag/package.json index 72f0afe1..331cee34 100644 --- a/frontend/antd/tag/package.json +++ b/frontend/antd/tag/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/time-picker/Index.svelte b/frontend/antd/time-picker/Index.svelte index 19ee576b..e6a67cb8 100644 --- a/frontend/antd/time-picker/Index.svelte +++ b/frontend/antd/time-picker/Index.svelte @@ -10,19 +10,24 @@ const AwaitedTimePicker = importComponent(() => import('./time-picker')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: string | number; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: string | number; - open_change?: any; - calendar_change?: any; - }>(() => props); + open_change?: any; + calendar_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -38,7 +43,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/time-picker/package.json b/frontend/antd/time-picker/package.json index 32687b6b..0cf763a6 100644 --- a/frontend/antd/time-picker/package.json +++ b/frontend/antd/time-picker/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/time-picker/range-picker/Index.svelte b/frontend/antd/time-picker/range-picker/Index.svelte index 283135a8..792a4f51 100644 --- a/frontend/antd/time-picker/range-picker/Index.svelte +++ b/frontend/antd/time-picker/range-picker/Index.svelte @@ -12,16 +12,21 @@ ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - calendar_change?: any; - value?: [string | number | null, string | number | null]; - }>(() => props); + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + calendar_change?: any; + value?: [string | number | null, string | number | null]; + }>(() => props); const getProceedProps = processProps( () => { @@ -37,7 +42,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/time-picker/range-picker/package.json b/frontend/antd/time-picker/range-picker/package.json index 60da7ac4..a78d72d7 100644 --- a/frontend/antd/time-picker/range-picker/package.json +++ b/frontend/antd/time-picker/range-picker/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/timeline/item/package.json b/frontend/antd/timeline/item/package.json index 397ceb79..08b81e46 100644 --- a/frontend/antd/timeline/item/package.json +++ b/frontend/antd/timeline/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/timeline/package.json b/frontend/antd/timeline/package.json index 401e27e8..5c4452b9 100644 --- a/frontend/antd/timeline/package.json +++ b/frontend/antd/timeline/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tooltip/Index.svelte b/frontend/antd/tooltip/Index.svelte index d82defc9..2fd12464 100644 --- a/frontend/antd/tooltip/Index.svelte +++ b/frontend/antd/tooltip/Index.svelte @@ -34,7 +34,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/tooltip/package.json b/frontend/antd/tooltip/package.json index 11f0309f..301a67ea 100644 --- a/frontend/antd/tooltip/package.json +++ b/frontend/antd/tooltip/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tour/package.json b/frontend/antd/tour/package.json index c3510ef4..4a377592 100644 --- a/frontend/antd/tour/package.json +++ b/frontend/antd/tour/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tour/step/package.json b/frontend/antd/tour/step/package.json index c2f358e2..16110e29 100644 --- a/frontend/antd/tour/step/package.json +++ b/frontend/antd/tour/step/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/transfer/Index.svelte b/frontend/antd/transfer/Index.svelte index 68d087a7..844d3c63 100644 --- a/frontend/antd/transfer/Index.svelte +++ b/frontend/antd/transfer/Index.svelte @@ -10,19 +10,24 @@ const AwaitedTransfer = importComponent(() => import('./transfer')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: (string | number)[]; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: (string | number)[]; - select_change?: any; - item_render?: any; - }>(() => props); + select_change?: any; + item_render?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -38,7 +43,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/transfer/package.json b/frontend/antd/transfer/package.json index 7bdd6254..25357c9d 100644 --- a/frontend/antd/transfer/package.json +++ b/frontend/antd/transfer/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tree-select/Index.svelte b/frontend/antd/tree-select/Index.svelte index 5b8b8b03..5c26682d 100644 --- a/frontend/antd/tree-select/Index.svelte +++ b/frontend/antd/tree-select/Index.svelte @@ -10,22 +10,27 @@ const AwaitedTreeSelect = importComponent(() => import('./tree-select')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - value?: string | string[]; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + value?: string | string[]; - tree_expand?: any; - popup_scroll?: any; - dropdown_visible_change?: any; - popup_visible_change?: any; - load_data?: any; - }>(() => props); + tree_expand?: any; + popup_scroll?: any; + dropdown_visible_change?: any; + popup_visible_change?: any; + load_data?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -41,7 +46,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/tree-select/package.json b/frontend/antd/tree-select/package.json index 00b433f7..01858a39 100644 --- a/frontend/antd/tree-select/package.json +++ b/frontend/antd/tree-select/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tree-select/tree-node/package.json b/frontend/antd/tree-select/tree-node/package.json index b2b3e659..df2b9838 100644 --- a/frontend/antd/tree-select/tree-node/package.json +++ b/frontend/antd/tree-select/tree-node/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tree/Index.svelte b/frontend/antd/tree/Index.svelte index 2e11d85d..57218ec7 100644 --- a/frontend/antd/tree/Index.svelte +++ b/frontend/antd/tree/Index.svelte @@ -38,7 +38,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/tree/directory-tree/Index.svelte b/frontend/antd/tree/directory-tree/Index.svelte index 84d238b5..bc19f31c 100644 --- a/frontend/antd/tree/directory-tree/Index.svelte +++ b/frontend/antd/tree/directory-tree/Index.svelte @@ -37,7 +37,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antd/tree/directory-tree/package.json b/frontend/antd/tree/directory-tree/package.json index bd4c7e70..3ced8353 100644 --- a/frontend/antd/tree/directory-tree/package.json +++ b/frontend/antd/tree/directory-tree/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tree/package.json b/frontend/antd/tree/package.json index e4245db8..3317c75c 100644 --- a/frontend/antd/tree/package.json +++ b/frontend/antd/tree/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/tree/tree-node/package.json b/frontend/antd/tree/tree-node/package.json index c6843cfa..bed2681d 100644 --- a/frontend/antd/tree/tree-node/package.json +++ b/frontend/antd/tree/tree-node/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/typography/link/package.json b/frontend/antd/typography/link/package.json index 20f412c9..58a506b9 100644 --- a/frontend/antd/typography/link/package.json +++ b/frontend/antd/typography/link/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/typography/paragraph/package.json b/frontend/antd/typography/paragraph/package.json index 7e2a86e1..332ab8d8 100644 --- a/frontend/antd/typography/paragraph/package.json +++ b/frontend/antd/typography/paragraph/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/typography/text/package.json b/frontend/antd/typography/text/package.json index f35ede67..a41a7fff 100644 --- a/frontend/antd/typography/text/package.json +++ b/frontend/antd/typography/text/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/typography/title/package.json b/frontend/antd/typography/title/package.json index 221fd14d..af867672 100644 --- a/frontend/antd/typography/title/package.json +++ b/frontend/antd/typography/title/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/upload/dragger/package.json b/frontend/antd/upload/dragger/package.json index b68a119d..a2b1ff9e 100644 --- a/frontend/antd/upload/dragger/package.json +++ b/frontend/antd/upload/dragger/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/upload/package.json b/frontend/antd/upload/package.json index d07c445d..276fa140 100644 --- a/frontend/antd/upload/package.json +++ b/frontend/antd/upload/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antd/watermark/package.json b/frontend/antd/watermark/package.json index 26c38a1e..77b9c5ff 100644 --- a/frontend/antd/watermark/package.json +++ b/frontend/antd/watermark/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/actions/package.json b/frontend/antdx/actions/package.json index 95a09b63..f4782591 100644 --- a/frontend/antdx/actions/package.json +++ b/frontend/antdx/actions/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/attachments/attachments.tsx b/frontend/antdx/attachments/attachments.tsx index c74d44bb..a85f7e22 100644 --- a/frontend/antdx/attachments/attachments.tsx +++ b/frontend/antdx/attachments/attachments.tsx @@ -166,7 +166,6 @@ export const Attachments = sveltify< }, [fileList]); const targets = useTargets(children); const uploadDisabled = props.disabled || uploading; - return ( <>

diff --git a/frontend/antdx/attachments/package.json b/frontend/antdx/attachments/package.json index 817ad823..b5a69e53 100644 --- a/frontend/antdx/attachments/package.json +++ b/frontend/antdx/attachments/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/bubble/list/Index.svelte b/frontend/antdx/bubble/list/Index.svelte index 1fca25ab..d509868e 100644 --- a/frontend/antdx/bubble/list/Index.svelte +++ b/frontend/antdx/bubble/list/Index.svelte @@ -16,6 +16,7 @@ _internal: { layout?: boolean; }; + items?: any[]; }>(() => props); const getProceedProps = processProps(() => { @@ -53,6 +54,9 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} + items={proceedProps.additionalProps.items || + proceedProps.restProps.items || + []} slots={slots.value} > {@render children?.()} diff --git a/frontend/antdx/bubble/list/item/package.json b/frontend/antdx/bubble/list/item/package.json index dde2617a..c30fa47d 100644 --- a/frontend/antdx/bubble/list/item/package.json +++ b/frontend/antdx/bubble/list/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/bubble/list/package.json b/frontend/antdx/bubble/list/package.json index 660d47fd..08853ba9 100644 --- a/frontend/antdx/bubble/list/package.json +++ b/frontend/antdx/bubble/list/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/bubble/list/role/package.json b/frontend/antdx/bubble/list/role/package.json index db20b488..fa78ac3b 100644 --- a/frontend/antdx/bubble/list/role/package.json +++ b/frontend/antdx/bubble/list/role/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/bubble/package.json b/frontend/antdx/bubble/package.json index 629d8f65..2b2bfc8f 100644 --- a/frontend/antdx/bubble/package.json +++ b/frontend/antdx/bubble/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/conversations/Index.svelte b/frontend/antdx/conversations/Index.svelte index d6def25c..57c35bf5 100644 --- a/frontend/antdx/conversations/Index.svelte +++ b/frontend/antdx/conversations/Index.svelte @@ -17,7 +17,7 @@ _internal: { layout?: boolean; }; - + menu_open_change?: any; active_change?: any; }>(() => props); @@ -34,7 +34,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, @@ -46,6 +46,7 @@ }, { active_change: 'activeChange', + menu_open_change: 'menu_openChange', } ); const proceedProps = $derived(getProceedProps()); diff --git a/frontend/antdx/conversations/conversations.tsx b/frontend/antdx/conversations/conversations.tsx index 550d5a69..70910574 100644 --- a/frontend/antdx/conversations/conversations.tsx +++ b/frontend/antdx/conversations/conversations.tsx @@ -2,10 +2,10 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React, { useMemo } from 'react'; import { + type ConversationItemType, Conversations as XConversations, type ConversationsProps, } from '@ant-design/x'; -import type { Conversation } from '@ant-design/x/es/conversations'; import type { ConversationsItemProps } from '@ant-design/x/es/conversations/Item'; import { createFunction } from '@utils/createFunction'; import { useFunction } from '@utils/hooks/useFunction'; @@ -32,7 +32,10 @@ function getConfig(value: T): Partial> { return {} as any; } -function patchMenuEvents(menuProps: MenuProps, conversation: Conversation) { +function patchMenuEvents( + menuProps: MenuProps, + conversation: ConversationItemType +) { return Object.keys(menuProps).reduce((acc, key) => { if (key.startsWith('on') && isFunction(menuProps[key])) { const originalEvent = menuProps[key]; @@ -54,13 +57,12 @@ function patchMenuEvents(menuProps: MenuProps, conversation: Conversation) { } export const Conversations = sveltify< - ConversationsProps & { - }, + ConversationsProps & {}, [ 'menu.expandIcon', 'menu.overflowedIndicator', 'menu.trigger', - 'groupable.title', + 'groupable.label', ] >( withMenuItemsContextProvider( @@ -73,9 +75,11 @@ export const Conversations = sveltify< } = useMenuItems<['menu.items']>(); const menuFunction = useFunction(props.menu); const supportGroupableConfig = - typeof props.groupable === 'object' || slots['groupable.title']; + typeof props.groupable === 'object' || slots['groupable.label']; const groupableConfig = getConfig(props.groupable); - const groupableSortFunction = useFunction(props.groupable); + const groupableCollapsibleFunction = useFunction( + groupableConfig.collapsible + ); const menu: ConversationsProps['menu'] = useMemo(() => { if (typeof props.menu === 'string') { return menuFunction; @@ -150,13 +154,15 @@ export const Conversations = sveltify< supportGroupableConfig ? { ...groupableConfig, - title: slots['groupable.title'] + label: slots['groupable.label'] ? renderParamsSlot({ slots, - key: 'groupable.title', + key: 'groupable.label', }) - : groupableConfig.title, - sort: groupableSortFunction || groupableConfig.sort, + : groupableConfig.label, + collapsible: + groupableCollapsibleFunction || + groupableConfig.collapsible, } : props.groupable } diff --git a/frontend/antdx/conversations/item/Index.svelte b/frontend/antdx/conversations/item/Index.svelte index 849dbd57..2b1b998f 100644 --- a/frontend/antdx/conversations/item/Index.svelte +++ b/frontend/antdx/conversations/item/Index.svelte @@ -19,7 +19,6 @@ additional_props?: Record; as_item?: string | undefined; _internal: { - layout?: boolean; index?: number; }; }>(() => props); diff --git a/frontend/antdx/conversations/item/package.json b/frontend/antdx/conversations/item/package.json index eb55d393..1eacab80 100644 --- a/frontend/antdx/conversations/item/package.json +++ b/frontend/antdx/conversations/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/conversations/package.json b/frontend/antdx/conversations/package.json index 4d50df15..93bd739f 100644 --- a/frontend/antdx/conversations/package.json +++ b/frontend/antdx/conversations/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/file-card/base.tsx b/frontend/antdx/file-card/base.tsx index bc69bb87..a244ef56 100644 --- a/frontend/antdx/file-card/base.tsx +++ b/frontend/antdx/file-card/base.tsx @@ -12,6 +12,22 @@ export type BaseFileCardProps = Omit & { src?: string | FileData; }; +export function resolveFileSrc( + src: string | FileData | undefined, + rootUrl: string, + apiPrefix: string +) { + if (!src) { + return src; + } + if (typeof src === 'string') { + return src.startsWith('http') + ? src + : getFetchableUrl(src, rootUrl, apiPrefix); + } + return src.url || getFetchableUrl(src.path, rootUrl, apiPrefix); +} + export const BaseFileCard: React.FC = ({ src, rootUrl, @@ -19,15 +35,7 @@ export const BaseFileCard: React.FC = ({ ...props }) => { const resolvedSrc = useMemo(() => { - if (!src) { - return src; - } - if (typeof src === 'string') { - return src.startsWith('http') - ? src - : getFetchableUrl(src, rootUrl, apiPrefix); - } - return src.url || getFetchableUrl(src.path, rootUrl, apiPrefix); + return resolveFileSrc(src, rootUrl, apiPrefix); }, [src, apiPrefix, rootUrl]); return ; }; diff --git a/frontend/antdx/file-card/list/Index.svelte b/frontend/antdx/file-card/list/Index.svelte index d25348ad..4a11491d 100644 --- a/frontend/antdx/file-card/list/Index.svelte +++ b/frontend/antdx/file-card/list/Index.svelte @@ -14,7 +14,7 @@ additional_props?: Record; as_item?: string | undefined; _internal: {}; - filename?: string; + items?: any[]; }>(() => props); const getProceedProps = processProps(() => { @@ -25,7 +25,6 @@ elem_classes, elem_id, elem_style, - filename, ...restProps } = getComponentProps(); return { @@ -38,7 +37,6 @@ elem_id, elem_classes, elem_style, - name: filename, }; }); const proceedProps = $derived(getProceedProps()); @@ -54,7 +52,9 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} - name={proceedProps.additionalProps.name || proceedProps.name || ''} + items={proceedProps.additionalProps.items || + proceedProps.restProps.items || + []} rootUrl={proceedProps.gradio.shared.root} apiPrefix={proceedProps.gradio.shared.api_prefix} slots={slots.value} diff --git a/frontend/antdx/file-card/list/file-card.list.tsx b/frontend/antdx/file-card/list/file-card.list.tsx index 712fa17a..f0ba2643 100644 --- a/frontend/antdx/file-card/list/file-card.list.tsx +++ b/frontend/antdx/file-card/list/file-card.list.tsx @@ -7,17 +7,30 @@ import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { renderItems } from '@utils/renderItems'; import type { ItemType } from 'antd/es/menu/interface'; +import { resolveFileSrc } from '../base'; + import { useItems, withItemsContextProvider } from './context'; export const FileCardList = sveltify< FileCardListProps & { children?: React.ReactNode; + rootUrl: string; + apiPrefix: string; }, ['extension'] >( withItemsContextProvider( ['default', 'items'], - ({ slots, items, children, extension, removable, ...props }) => { + ({ + slots, + items, + children, + extension, + removable, + rootUrl, + apiPrefix, + ...props + }) => { const { items: slotItems } = useItems<['default', 'items']>(); const resolvedSlotItems = slotItems.items?.length ? slotItems.items @@ -39,8 +52,11 @@ export const FileCardList = sveltify< renderItems(resolvedSlotItems || [], { clone: true, }) - ); - }, [items, resolvedSlotItems])} + ).map((item) => ({ + ...item, + src: resolveFileSrc(item.src, rootUrl, apiPrefix), + })); + }, [apiPrefix, items, resolvedSlotItems, rootUrl])} /> ); diff --git a/frontend/antdx/prompts/Index.svelte b/frontend/antdx/prompts/Index.svelte index 3abbff6e..72f226aa 100644 --- a/frontend/antdx/prompts/Index.svelte +++ b/frontend/antdx/prompts/Index.svelte @@ -34,7 +34,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antdx/prompts/item/package.json b/frontend/antdx/prompts/item/package.json index 84c74cd9..f803e7e4 100644 --- a/frontend/antdx/prompts/item/package.json +++ b/frontend/antdx/prompts/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/prompts/package.json b/frontend/antdx/prompts/package.json index 8c046bcb..437bbe23 100644 --- a/frontend/antdx/prompts/package.json +++ b/frontend/antdx/prompts/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/prompts/prompts.tsx b/frontend/antdx/prompts/prompts.tsx index 94fc9877..eaf5ea8c 100644 --- a/frontend/antdx/prompts/prompts.tsx +++ b/frontend/antdx/prompts/prompts.tsx @@ -2,8 +2,8 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React, { useMemo } from 'react'; import { - type PromptProps, Prompts as XPrompts, + type PromptsItemType, type PromptsProps, } from '@ant-design/x'; import { renderItems } from '@utils/renderItems'; @@ -27,7 +27,7 @@ export const Prompts = sveltify( items={useMemo(() => { return ( items || - renderItems(resolvedSlotItems, { + renderItems(resolvedSlotItems, { clone: true, }) ); diff --git a/frontend/antdx/sender/Index.svelte b/frontend/antdx/sender/Index.svelte index e95a9331..30f7d4d6 100644 --- a/frontend/antdx/sender/Index.svelte +++ b/frontend/antdx/sender/Index.svelte @@ -11,22 +11,27 @@ const AwaitedSender = importComponent(() => import('./sender')); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children, updateProps } = - getProps<{ - additional_props?: Record; + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ + additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; - root: string; - value?: string; + as_item?: string | undefined; + _internal: { + layout?: boolean; + }; + root: string; + value?: string; - key_press?: any; - paste_file?: any; - key_down?: any; - allow_speech_recording_change?: any; - }>(() => props); + key_press?: any; + paste_file?: any; + key_down?: any; + allow_speech_recording_change?: any; + }>(() => props); const getProceedProps = processProps( () => { @@ -43,7 +48,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antdx/sender/header/Index.svelte b/frontend/antdx/sender/header/Index.svelte index f5ad18f1..ff12d2fc 100644 --- a/frontend/antdx/sender/header/Index.svelte +++ b/frontend/antdx/sender/header/Index.svelte @@ -16,30 +16,36 @@ _internal: { layout?: boolean; }; + open_change?: any; }>(() => props); - const getProceedProps = processProps(() => { - const { - visible, - _internal, - as_item, - elem_classes, - elem_id, - elem_style, - ...restProps - } = getComponentProps(); - return { - gradio, - additionalProps: getAdditionalProps(), - _internal, - as_item, - restProps, - visible, - elem_id, - elem_classes, - elem_style, - }; - }); + const getProceedProps = processProps( + () => { + const { + visible, + _internal, + as_item, + elem_classes, + elem_id, + elem_style, + ...restProps + } = getComponentProps(); + return { + gradio, + additionalProps: getAdditionalProps(), + _internal, + as_item, + restProps, + visible, + elem_id, + elem_classes, + elem_style, + }; + }, + { + open_change: 'openChange', + } + ); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); diff --git a/frontend/antdx/sender/header/package.json b/frontend/antdx/sender/header/package.json index 062764d3..cd1beac0 100644 --- a/frontend/antdx/sender/header/package.json +++ b/frontend/antdx/sender/header/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/sender/header/sender.header.tsx b/frontend/antdx/sender/header/sender.header.tsx index ef17a585..73ae5679 100644 --- a/frontend/antdx/sender/header/sender.header.tsx +++ b/frontend/antdx/sender/header/sender.header.tsx @@ -1,25 +1,18 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React from 'react'; -import XSenderHeader from '@ant-design/x/es/sender/SenderHeader'; -import { - type SenderHeaderProps, - SendHeaderContext, -} from '@ant-design/x/es/sender/SenderHeader'; -import { ConfigProvider } from 'antd'; +import { Sender as XSender } from '@ant-design/x'; +import { type SenderHeaderProps } from '@ant-design/x/es/sender/SenderHeader'; export const SenderHeader = sveltify( ({ slots, ...props }) => { - const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext); - - // fix style return ( - - + : props.title} /> - + ); } ); diff --git a/frontend/antdx/sender/package.json b/frontend/antdx/sender/package.json index 4a3c8b43..48ea83d5 100644 --- a/frontend/antdx/sender/package.json +++ b/frontend/antdx/sender/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/sender/sender.tsx b/frontend/antdx/sender/sender.tsx index 9068554c..49752beb 100644 --- a/frontend/antdx/sender/sender.tsx +++ b/frontend/antdx/sender/sender.tsx @@ -4,9 +4,17 @@ import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React from 'react'; import { Sender as XSender, type SenderProps } from '@ant-design/x'; import type { FileData } from '@gradio/client'; +import { createFunction } from '@utils/createFunction'; import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; +function getConfig(value: T): Partial> { + if (typeof value === 'object' && value !== null) { + return value as any; + } + return {} as any; +} + export const Sender = sveltify< Omit & { children?: React.ReactNode; @@ -14,7 +22,15 @@ export const Sender = sveltify< onPasteFile?: (value: string[]) => void; onValueChange: (value: string) => void; }, - ['actions', 'header', 'prefix', 'footer'] + [ + 'suffix', + 'header', + 'prefix', + 'footer', + 'skill.title', + 'skill.toolTip.title', + 'skill.closable.closeIcon', + ] >( ({ slots, @@ -23,11 +39,32 @@ export const Sender = sveltify< onChange, onPasteFile, upload, + slotConfig, elRef, ...props }) => { - const actionsFunction = useFunction(props.actions, true); + const suffixFunction = useFunction(props.suffix, true); + const headerFunction = useFunction(props.header, true); + const prefixFunction = useFunction(props.prefix, true); const footerFunction = useFunction(props.footer, true); + const supportSkill = + props.skill || + slots['skill.title'] || + slots['skill.toolTip.title'] || + slots['skill.closable.closeIcon']; + const supportSkillTooltip = + slots['skill.toolTip.title'] || typeof props.skill?.toolTip === 'object'; + const skillTooltipConfig = getConfig(props.skill?.toolTip); + const supportSkillClosable = + slots['skill.closable.closeIcon'] || props.skill?.closable; + const skillClosableConfig = getConfig(props.skill?.closable); + + const skillTooltipAfterOpenChangeFunction = useFunction( + skillTooltipConfig.afterOpenChange + ); + const skillTooltipGetPopupContainerFunction = useFunction( + skillTooltipConfig.getPopupContainer + ); const [value, setValue] = useValueChange({ onValueChange, value: props.value, @@ -40,6 +77,52 @@ export const Sender = sveltify< {...props} value={value} ref={elRef} + skill={ + supportSkill + ? { + ...(props.skill || {}), + title: slots['skill.title'] ? ( + + ) : ( + props.skill?.title + ), + value: props.skill?.value || '', + toolTip: supportSkillTooltip + ? { + ...skillTooltipConfig, + afterOpenChange: skillTooltipAfterOpenChangeFunction, + getPopupContainer: + skillTooltipGetPopupContainerFunction, + title: slots['showSorterTooltip.title'] ? ( + + ) : ( + skillTooltipConfig.title + ), + } + : props.skill?.toolTip, + closable: supportSkillClosable + ? { + ...skillClosableConfig, + closeIcon: slots['skill.closable.closeIcon'] ? ( + + ) : ( + skillClosableConfig.closeIcon + ), + } + : props.skill?.closable, + } + : undefined + } + slotConfig={slotConfig?.map((c) => { + return { + ...c, + formatResult: createFunction(c.formatResult), + customRender: + c.type === 'custom' + ? createFunction(c.customRender) + : undefined, + }; + })} onSubmit={(...args) => { if (!open) { props.onSubmit?.(...args); @@ -49,21 +132,29 @@ export const Sender = sveltify< onChange?.(v); setValue(v); }} - onPasteFile={async (_file, files) => { + onPasteFile={async (files) => { const urls = await upload(Array.from(files)); onPasteFile?.(urls.map((url) => url.path)); }} + suffix={ + slots.suffix ? ( + + ) : ( + suffixFunction || props.suffix + ) + } header={ - slots.header ? : props.header + slots.header ? ( + + ) : ( + headerFunction || props.header + ) } prefix={ - slots.prefix ? : props.prefix - } - actions={ - slots.actions ? ( - + slots.prefix ? ( + ) : ( - actionsFunction || props.actions + prefixFunction || props.prefix ) } footer={ diff --git a/frontend/antdx/sender/switch/Index.svelte b/frontend/antdx/sender/switch/Index.svelte new file mode 100644 index 00000000..ea28db69 --- /dev/null +++ b/frontend/antdx/sender/switch/Index.svelte @@ -0,0 +1,61 @@ + + +{#if proceedProps.visible} + {#await AwaitedSenderSwitch then SenderSwitch} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/sender/switch/gradio.config.js b/frontend/antdx/sender/switch/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/sender/switch/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/sender/switch/package.json b/frontend/antdx/sender/switch/package.json new file mode 100644 index 00000000..fc88cacb --- /dev/null +++ b/frontend/antdx/sender/switch/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-sender.switch", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/sender/switch/sender.switch.tsx b/frontend/antdx/sender/switch/sender.switch.tsx new file mode 100644 index 00000000..961e8f1b --- /dev/null +++ b/frontend/antdx/sender/switch/sender.switch.tsx @@ -0,0 +1,33 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React from 'react'; +import { Sender } from '@ant-design/x'; +import type { SenderSwitchProps } from '@ant-design/x/es/sender/SenderSwitch'; + +export const SenderSwitch = sveltify< + SenderSwitchProps, + ['checkedChildren', 'unCheckedChildren', 'icon'] +>(({ slots, ...props }) => { + return ( + + ) : ( + props.checkedChildren + ) + } + unCheckedChildren={ + slots.unCheckedChildren ? ( + + ) : ( + props.unCheckedChildren + ) + } + icon={slots.icon ? : props.icon} + /> + ); +}); + +export default SenderSwitch; diff --git a/frontend/antdx/suggestion/Index.svelte b/frontend/antdx/suggestion/Index.svelte index c0f30c76..32256111 100644 --- a/frontend/antdx/suggestion/Index.svelte +++ b/frontend/antdx/suggestion/Index.svelte @@ -37,7 +37,7 @@ } = getComponentProps(); return { gradio, - additionalProps: getAdditionalProps(), + additionalProps: getAdditionalProps(), _internal, as_item, restProps, diff --git a/frontend/antdx/suggestion/item/package.json b/frontend/antdx/suggestion/item/package.json index 743ca68b..06ac1b13 100644 --- a/frontend/antdx/suggestion/item/package.json +++ b/frontend/antdx/suggestion/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/suggestion/package.json b/frontend/antdx/suggestion/package.json index f58d076e..a9144112 100644 --- a/frontend/antdx/suggestion/package.json +++ b/frontend/antdx/suggestion/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/suggestion/suggestion.tsx b/frontend/antdx/suggestion/suggestion.tsx index 063a379e..2ab4655c 100644 --- a/frontend/antdx/suggestion/suggestion.tsx +++ b/frontend/antdx/suggestion/suggestion.tsx @@ -76,13 +76,21 @@ export const Suggestion = sveltify< >( withItemsContextProvider( ['default', 'items'], - ({ children, items, shouldTrigger, slots, ...props }) => { + ({ + children, + items, + shouldTrigger, + getPopupContainer, + slots, + ...props + }) => { const [open, setOpen] = useState(() => props.open ?? false); const { items: slotItems } = useItems<['default', 'items']>(); const resolvedSlotItems = slotItems.items.length > 0 ? slotItems.items : slotItems.default; const itemsFunction = useFunction(items); const shouldTriggerFunction = useFunction(shouldTrigger); + const getPopupContainerFunction = useFunction(getPopupContainer); const resolvedItems = useMemo(() => { return (items || renderItems(resolvedSlotItems, { @@ -122,6 +130,7 @@ export const Suggestion = sveltify< { if (isUndefined(props.open)) { setOpen(suggestionOpen); diff --git a/frontend/antdx/thought-chain/item/Index.svelte b/frontend/antdx/thought-chain/item/Index.svelte index aac70757..4306f02b 100644 --- a/frontend/antdx/thought-chain/item/Index.svelte +++ b/frontend/antdx/thought-chain/item/Index.svelte @@ -4,10 +4,7 @@ importComponent, processProps, } from '@svelte-preprocess-react/component'; - import { - getSlotKey, - getSlots, - } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; + import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; const AwaitedThoughtChainItem = importComponent( @@ -23,7 +20,6 @@ index?: number; }; }>(() => props); - const slotKey = getSlotKey(); const getProceedProps = processProps(() => { const { @@ -64,8 +60,6 @@ {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} - itemIndex={proceedProps._internal.index || 0} - itemSlotKey={slotKey?.value} > {@render children?.()} diff --git a/frontend/antdx/thought-chain/item/package.json b/frontend/antdx/thought-chain/item/package.json index 7bdf2426..ed9edbbe 100644 --- a/frontend/antdx/thought-chain/item/package.json +++ b/frontend/antdx/thought-chain/item/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/thought-chain/item/thought-chain.item.tsx b/frontend/antdx/thought-chain/item/thought-chain.item.tsx index 0d03ed6e..a3dbbe77 100644 --- a/frontend/antdx/thought-chain/item/thought-chain.item.tsx +++ b/frontend/antdx/thought-chain/item/thought-chain.item.tsx @@ -1,13 +1,32 @@ import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React from 'react'; -import type { ThoughtChainProps } from '@ant-design/x'; - -import { ItemHandler, type ItemHandlerProps } from '../context'; +import { + ThoughtChain as XThoughtChain, + type ThoughtChainItemProps, +} from '@ant-design/x'; export const ThoughtChainItem = sveltify< - Partial[number]> & ItemHandlerProps ->((props) => { - return ; + ThoughtChainItemProps, + ['description', 'icon', 'title'] +>(({ children, slots, ...props }) => { + return ( + <> +
{children}
+ + ) : ( + props.description + ) + } + icon={slots.icon ? : props.icon} + title={slots.title ? : props.title} + /> + + ); }); export default ThoughtChainItem; diff --git a/frontend/antdx/thought-chain/package.json b/frontend/antdx/thought-chain/package.json index 2aeef739..ce4a62f8 100644 --- a/frontend/antdx/thought-chain/package.json +++ b/frontend/antdx/thought-chain/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/thought-chain/thought-chain-item/Index.svelte b/frontend/antdx/thought-chain/thought-chain-item/Index.svelte new file mode 100644 index 00000000..11cd8b5b --- /dev/null +++ b/frontend/antdx/thought-chain/thought-chain-item/Index.svelte @@ -0,0 +1,73 @@ + + +{#await AwaitedThoughtChainItem then ThoughtChainItem} + + {#if proceedProps.visible} + {@render children?.()} + {/if} + +{/await} diff --git a/frontend/antdx/thought-chain/thought-chain-item/gradio.config.js b/frontend/antdx/thought-chain/thought-chain-item/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/thought-chain/thought-chain-item/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/thought-chain/thought-chain-item/package.json b/frontend/antdx/thought-chain/thought-chain-item/package.json new file mode 100644 index 00000000..54226056 --- /dev/null +++ b/frontend/antdx/thought-chain/thought-chain-item/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-thought-chain.thought-chain-item", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx b/frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx new file mode 100644 index 00000000..0d03ed6e --- /dev/null +++ b/frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx @@ -0,0 +1,13 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import type { ThoughtChainProps } from '@ant-design/x'; + +import { ItemHandler, type ItemHandlerProps } from '../context'; + +export const ThoughtChainItem = sveltify< + Partial[number]> & ItemHandlerProps +>((props) => { + return ; +}); + +export default ThoughtChainItem; diff --git a/frontend/antdx/welcome/package.json b/frontend/antdx/welcome/package.json index a5fc2750..39458515 100644 --- a/frontend/antdx/welcome/package.json +++ b/frontend/antdx/welcome/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/antdx/x-provider/package.json b/frontend/antdx/x-provider/package.json index 19288f0b..0b66f83e 100644 --- a/frontend/antdx/x-provider/package.json +++ b/frontend/antdx/x-provider/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/auto-loading/package.json b/frontend/base/auto-loading/package.json index 2833ec7c..f88519a5 100644 --- a/frontend/base/auto-loading/package.json +++ b/frontend/base/auto-loading/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/div/package.json b/frontend/base/div/package.json index 15bab76a..a08fb139 100644 --- a/frontend/base/div/package.json +++ b/frontend/base/div/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/each/package.json b/frontend/base/each/package.json index 39cb4c78..0e17a09c 100644 --- a/frontend/base/each/package.json +++ b/frontend/base/each/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/filter/package.json b/frontend/base/filter/package.json index 8148d2d6..adfe27d2 100644 --- a/frontend/base/filter/package.json +++ b/frontend/base/filter/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/fragment/package.json b/frontend/base/fragment/package.json index fcded91f..4355f935 100644 --- a/frontend/base/fragment/package.json +++ b/frontend/base/fragment/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" }, "./ShowFragment": "./ShowFragment.svelte" } diff --git a/frontend/base/markdown/package.json b/frontend/base/markdown/package.json index 3bbc98d5..b078cf30 100644 --- a/frontend/base/markdown/package.json +++ b/frontend/base/markdown/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/slot/package.json b/frontend/base/slot/package.json index bc3acdd4..5c30f014 100644 --- a/frontend/base/slot/package.json +++ b/frontend/base/slot/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/span/package.json b/frontend/base/span/package.json index 63379a2b..bf32c014 100644 --- a/frontend/base/span/package.json +++ b/frontend/base/span/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/base/text/package.json b/frontend/base/text/package.json index ec491487..f7ab16ac 100644 --- a/frontend/base/text/package.json +++ b/frontend/base/text/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/pro/chatbot/chatbot.tsx b/frontend/pro/chatbot/chatbot.tsx index e5ee2e0f..4487ee40 100644 --- a/frontend/pro/chatbot/chatbot.tsx +++ b/frontend/pro/chatbot/chatbot.tsx @@ -165,7 +165,7 @@ export const Chatbot = sveltify<{ const chatbotRef = useRef(null); const [editIndex, setEditIndex] = useState(-1); const [editValues, setEditValues] = useState>({}); - const oldValueRef = useRef(); + const oldValueRef = useRef(undefined); const handleEditValue = useMemoizedFn((itemIndex: number, v: string) => { setEditValues((prev) => ({ ...prev, [itemIndex]: v })); diff --git a/frontend/pro/chatbot/package.json b/frontend/pro/chatbot/package.json index 6d1566cc..423124b0 100644 --- a/frontend/pro/chatbot/package.json +++ b/frontend/pro/chatbot/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/pro/monaco-editor/diff-editor/package.json b/frontend/pro/monaco-editor/diff-editor/package.json index e84e2125..0e947829 100644 --- a/frontend/pro/monaco-editor/diff-editor/package.json +++ b/frontend/pro/monaco-editor/diff-editor/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/pro/monaco-editor/loader.ts b/frontend/pro/monaco-editor/loader.ts index f07bf23d..a66b4942 100644 --- a/frontend/pro/monaco-editor/loader.ts +++ b/frontend/pro/monaco-editor/loader.ts @@ -39,15 +39,15 @@ export async function initLocalLoader() { import('monaco-editor/esm/vs/language/css/css.worker?worker&inline').then( (m) => m.default ), - import( - 'monaco-editor/esm/vs/language/html/html.worker?worker&inline' - ).then((m) => m.default), - import( - 'monaco-editor/esm/vs/language/json/json.worker?worker&inline' - ).then((m) => m.default), - import( - 'monaco-editor/esm/vs/language/typescript/ts.worker?worker&inline' - ).then((m) => m.default), + import('monaco-editor/esm/vs/language/html/html.worker?worker&inline').then( + (m) => m.default + ), + import('monaco-editor/esm/vs/language/json/json.worker?worker&inline').then( + (m) => m.default + ), + import('monaco-editor/esm/vs/language/typescript/ts.worker?worker&inline').then( + (m) => m.default + ), ]); window.MonacoEnvironment = { diff --git a/frontend/pro/monaco-editor/package.json b/frontend/pro/monaco-editor/package.json index 2729d500..84ec3d99 100644 --- a/frontend/pro/monaco-editor/package.json +++ b/frontend/pro/monaco-editor/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/pro/multimodal-input/package.json b/frontend/pro/multimodal-input/package.json index eb709a8d..cd9bcc60 100644 --- a/frontend/pro/multimodal-input/package.json +++ b/frontend/pro/multimodal-input/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/pro/web-sandbox/package.json b/frontend/pro/web-sandbox/package.json index c891a9e3..b06e3a2c 100644 --- a/frontend/pro/web-sandbox/package.json +++ b/frontend/pro/web-sandbox/package.json @@ -3,12 +3,12 @@ "type": "module", "exports": { ".": { - "default": "./Index.svelte", - "gradio": "./Index.svelte" + "gradio": "./Index.svelte", + "default": "./Index.svelte" }, "./package.json": { - "default": "./package.json", - "gradio": "./package.json" + "gradio": "./package.json", + "default": "./package.json" } } } diff --git a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts index ea1d2386..49c17b48 100644 --- a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts +++ b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts @@ -97,10 +97,6 @@ function BridgeInternal({ return patchProps(omitNodeProps(originalNodeProps)); }, [originalNodeProps]); - const subSlotKeys = useMemo( - () => node.nodes.map((subnode) => subnode.slotKey), - [node.nodes] - ); let formItemContext = useFormItemContext(); const slotKey = node.slotKey; if (slotKey) { @@ -175,13 +171,13 @@ function BridgeInternal({ if (node.nodes.length !== 0) { children = [ children, - ...node.nodes.map((subnode, i) => { + ...node.nodes.map((subnode) => { return createElement(Bridge, { key: `bridge${subnode.key}`, createPortal, node: subnode, // slotKey - nodeSlotKey: subSlotKeys[i], + nodeSlotKey: subnode.slotKey, }); }), ]; diff --git a/frontend/svelte-preprocess-react/react-slot.tsx b/frontend/svelte-preprocess-react/react-slot.tsx index fc4e1bb7..07a70d06 100644 --- a/frontend/svelte-preprocess-react/react-slot.tsx +++ b/frontend/svelte-preprocess-react/react-slot.tsx @@ -112,6 +112,7 @@ export const ReactSlot = forwardRef( if (!ref.current || !slot) { return; } + // the cloned component cannot handle the eventListener let cloned = slot; function mountElementProps() { From 0b74709b5decdac9dfd9e7ec5ff0db82fb16bf5a Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 18 Mar 2026 20:23:04 +0800 Subject: [PATCH 11/31] refactor(antdx): new components notification & think --- .../components/antdx/__init__.py | 2 + .../components/antdx/components.py | 2 + .../components/antdx/notification/__init__.py | 94 ++ .../components/antdx/think/__init__.py | 78 ++ config/changelog/package.json | 2 +- config/lint-config/package.json | 8 +- frontend/antdx/notification/Index.svelte | 74 ++ frontend/antdx/notification/gradio.config.js | 3 + frontend/antdx/notification/notification.tsx | 50 + frontend/antdx/notification/package.json | 14 + frontend/antdx/think/Index.svelte | 68 + frontend/antdx/think/gradio.config.js | 3 + frontend/antdx/think/package.json | 14 + frontend/antdx/think/think.tsx | 23 + frontend/package.json | 14 +- frontend/utils/hooks/useTargets.ts | 7 +- package.json | 8 +- pnpm-lock.yaml | 1175 +++++++---------- 18 files changed, 933 insertions(+), 706 deletions(-) create mode 100644 backend/modelscope_studio/components/antdx/notification/__init__.py create mode 100644 backend/modelscope_studio/components/antdx/think/__init__.py create mode 100644 frontend/antdx/notification/Index.svelte create mode 100644 frontend/antdx/notification/gradio.config.js create mode 100644 frontend/antdx/notification/notification.tsx create mode 100644 frontend/antdx/notification/package.json create mode 100644 frontend/antdx/think/Index.svelte create mode 100644 frontend/antdx/think/gradio.config.js create mode 100644 frontend/antdx/think/package.json create mode 100644 frontend/antdx/think/think.tsx diff --git a/backend/modelscope_studio/components/antdx/__init__.py b/backend/modelscope_studio/components/antdx/__init__.py index 12199009..7004b5ef 100644 --- a/backend/modelscope_studio/components/antdx/__init__.py +++ b/backend/modelscope_studio/components/antdx/__init__.py @@ -27,5 +27,7 @@ from .thought_chain import AntdXThoughtChain as ThoughtChain from .thought_chain.item import AntdXThoughtChainItem as ThoughtChainItem from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem as ThoughtChainThoughtChainItem +from .think import AntdXThink as Think from .welcome import AntdXWelcome as Welcome +from .notification import AntdXNotification as Notification from .x_provider import AntdXXProvider as XProvider diff --git a/backend/modelscope_studio/components/antdx/components.py b/backend/modelscope_studio/components/antdx/components.py index 80fe1bcc..a608ede0 100644 --- a/backend/modelscope_studio/components/antdx/components.py +++ b/backend/modelscope_studio/components/antdx/components.py @@ -26,5 +26,7 @@ from .thought_chain import AntdXThoughtChain from .thought_chain.item import AntdXThoughtChainItem from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem +from .think import AntdXThink from .welcome import AntdXWelcome +from .notification import AntdXNotification from .x_provider import AntdXXProvider diff --git a/backend/modelscope_studio/components/antdx/notification/__init__.py b/backend/modelscope_studio/components/antdx/notification/__init__.py new file mode 100644 index 00000000..7b51c7b3 --- /dev/null +++ b/backend/modelscope_studio/components/antdx/notification/__init__.py @@ -0,0 +1,94 @@ +from __future__ import annotations + +from gradio.events import EventListener +from typing import Any, Literal +from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXNotification(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/notification + """ + EVENTS = [ + EventListener("permission", + callback=lambda block: block._internal.update( + bind_permission_event=True)), + EventListener("click", + callback=lambda block: block._internal.update( + bind_click_event=True)), + EventListener("close", + callback=lambda block: block._internal.update( + bind_close_event=True)), + EventListener("error", + callback=lambda block: block._internal.update( + bind_error_event=True)), + EventListener("show", + callback=lambda block: block._internal.update( + bind_show_event=True)) + ] + + # supported slots + SLOTS = [] + + def __init__( + self, + *, + title: str | None = None, + duration: int | float | None = None, + badge: str | None = None, + body: str | None = None, + data: Any | None = None, + dir: Literal['auto', 'ltr', 'rtl'] | None = None, + icon: str | None = None, + lang: str | None = None, + require_interaction: bool | None = None, + silent: bool | None = None, + tag: str | None = None, + additional_props: dict | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool | None = None, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.title = title + self.duration = duration + self.badge = badge + self.body = body + self.data = data + self.dir = dir + self.icon = icon + self.lang = lang + self.require_interaction = require_interaction + self.silent = silent + self.tag = tag + + FRONTEND_DIR = resolve_frontend_dir("notification", type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> None: + return None + + def example_value(self) -> None: + return None diff --git a/backend/modelscope_studio/components/antdx/think/__init__.py b/backend/modelscope_studio/components/antdx/think/__init__.py new file mode 100644 index 00000000..25ad92cf --- /dev/null +++ b/backend/modelscope_studio/components/antdx/think/__init__.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from gradio.events import EventListener + +from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXThink(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/think + """ + EVENTS = [ + EventListener("expand", + callback=lambda block: block._internal.update( + bind_expand_event=True)), + ] + + # supported slots + SLOTS = ['loading', 'icon', 'title'] + + def __init__( + self, + additional_props: dict | None = None, + *, + icon: str | None = None, + styles: dict | str | None = None, + class_names: dict | str | None = None, + loading: str | bool = None, + title: str | None = None, + root_class_name: str | None = None, + default_expanded: bool | None = None, + expanded: bool | None = None, + blink: bool | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.icon = icon + self.styles = styles + self.class_names = class_names + self.loading = loading + self.default_expanded = default_expanded + self.expanded = expanded + self.blink = blink + self.title = title + self.root_class_name = root_class_name + + FRONTEND_DIR = resolve_frontend_dir("think", type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> None: + return None + + def example_value(self) -> None: + return None diff --git a/config/changelog/package.json b/config/changelog/package.json index 57edaaa4..66b46c3c 100644 --- a/config/changelog/package.json +++ b/config/changelog/package.json @@ -25,7 +25,7 @@ }, "devDependencies": { "@changesets/types": "^6.1.0", - "@types/node": "^25.4.0", + "@types/node": "^25.5.0", "tsup": "^8.5.1" } } diff --git a/config/lint-config/package.json b/config/lint-config/package.json index 109b3c78..e3bf9085 100644 --- a/config/lint-config/package.json +++ b/config/lint-config/package.json @@ -18,7 +18,7 @@ "dependencies": { "@eslint/compat": "^2.0.3", "@eslint/js": "^10.0.1", - "@typescript-eslint/parser": "^8.57.0", + "@typescript-eslint/parser": "^8.57.1", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", @@ -28,17 +28,17 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-svelte": "^3.15.1", + "eslint-plugin-svelte": "^3.15.2", "globals": "^17.4.0", "postcss": "^8.5.8", "postcss-less": "^6.0.0", "stylelint-config-rational-order": "^0.1.2", "stylelint-config-standard": "^40.0.0", "stylelint-declaration-block-no-ignored-properties": "^3.0.0", - "stylelint-order": "^8.0.0", + "stylelint-order": "^8.1.1", "stylelint-prettier": "^5.0.3", "svelte-eslint-parser": "^1.6.0", - "typescript-eslint": "^8.57.0" + "typescript-eslint": "^8.57.1" }, "devDependencies": { "@types/eslint": "^9.6.1", diff --git a/frontend/antdx/notification/Index.svelte b/frontend/antdx/notification/Index.svelte new file mode 100644 index 00000000..0bb5646e --- /dev/null +++ b/frontend/antdx/notification/Index.svelte @@ -0,0 +1,74 @@ + + +{#await AwaitedNotification then Notification} + { + updateProps({ + visible: v, + }); + }} + > + {@render children?.()} + +{/await} diff --git a/frontend/antdx/notification/gradio.config.js b/frontend/antdx/notification/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antdx/notification/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/notification/notification.tsx b/frontend/antdx/notification/notification.tsx new file mode 100644 index 00000000..00eeb640 --- /dev/null +++ b/frontend/antdx/notification/notification.tsx @@ -0,0 +1,50 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { useEffect } from 'react'; +import { notification, type XNotificationOpenArgs } from '@ant-design/x'; +import { useMemoizedFn } from '@utils/hooks/useMemoizedFn'; + +export const Notification = sveltify< + XNotificationOpenArgs & { + visible: boolean; + onVisible: (visible: boolean) => void; + onPermission?: (permission: NotificationPermission) => void; + } +>(({ slots, onClose, visible, onVisible, tag, onPermission, ...props }) => { + const [{ permission }, { open, close, requestPermission }] = + notification.useNotification(); + const onPermissionMemoized = useMemoizedFn(onPermission); + + useEffect(() => { + onPermissionMemoized(permission); + }, [permission, onPermissionMemoized]); + useEffect(() => { + if (visible) { + const run = async () => { + let result = permission; + if (result !== 'granted') { + result = await requestPermission(); + } + if (result === 'granted') { + open({ + ...props, + tag, + onClose(...args) { + onVisible?.(false); + onClose?.(...args); + }, + }); + } + }; + run(); + } else { + close(tag ? [tag] : undefined); + } + + return () => { + close(tag ? [tag] : undefined); + }; + }, [visible, tag]); + return null; +}); + +export default Notification; diff --git a/frontend/antdx/notification/package.json b/frontend/antdx/notification/package.json new file mode 100644 index 00000000..ef9e8918 --- /dev/null +++ b/frontend/antdx/notification/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antd-notification", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/think/Index.svelte b/frontend/antdx/think/Index.svelte new file mode 100644 index 00000000..c29e6e7b --- /dev/null +++ b/frontend/antdx/think/Index.svelte @@ -0,0 +1,68 @@ + + +{#if proceedProps.visible} + {#await AwaitedThink then Think} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/think/gradio.config.js b/frontend/antdx/think/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antdx/think/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/think/package.json b/frontend/antdx/think/package.json new file mode 100644 index 00000000..200d99d0 --- /dev/null +++ b/frontend/antdx/think/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-think", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/think/think.tsx b/frontend/antdx/think/think.tsx new file mode 100644 index 00000000..c7c2cd0a --- /dev/null +++ b/frontend/antdx/think/think.tsx @@ -0,0 +1,23 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React from 'react'; +import { Think as XThink, type ThinkProps } from '@ant-design/x'; + +export const Think = sveltify( + ({ slots, ...props }) => { + return ( + <> + : props.loading + } + icon={slots.icon ? : props.icon} + title={slots.title ? : props.title} + /> + + ); + } +); + +export default Think; diff --git a/frontend/package.json b/frontend/package.json index c848c436..6a4507be 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,17 +8,17 @@ "dependencies": { "@ant-design/cssinjs": "^2.1.2", "@ant-design/icons": "^6.1.0", - "@ant-design/x": "^2.3.0", - "@babel/standalone": "^7.29.1", + "@ant-design/x": "^2.4.0", + "@babel/standalone": "^7.29.2", "@gradio/client": "2.1.0", "@gradio/preview": "0.15.2", "@gradio/statustracker": "^0.12.5", "@gradio/utils": "0.11.3", "@monaco-editor/react": "^4.7.0", "amuchina": "^1.0.12", - "antd": "^6.3.2", + "antd": "^6.3.3", "classnames": "^2.5.1", - "dayjs": "^1.11.19", + "dayjs": "^1.11.20", "dequal": "^2.0.2", "github-slugger": "^2.0.0", "immer": "^11.1.4", @@ -35,7 +35,7 @@ "react-dom": "^19.2.4", "svelte": "5.53.9", "svelte-i18n": "^4.0.1", - "wavesurfer.js": "^7.12.1" + "wavesurfer.js": "^7.12.4" }, "devDependencies": { "@babel/core": "^7.29.0", @@ -47,8 +47,8 @@ "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "@types/sanitize-html": "^2.16.1", - "@vitejs/plugin-react-swc": "^4.2.3", - "less": "^4.5.1", + "@vitejs/plugin-react-swc": "^4.3.0", + "less": "^4.6.4", "typescript-json-schema": "^0.67.1", "vite": "^7.3.1" }, diff --git a/frontend/utils/hooks/useTargets.ts b/frontend/utils/hooks/useTargets.ts index a755679c..60ab1f0e 100644 --- a/frontend/utils/hooks/useTargets.ts +++ b/frontend/utils/hooks/useTargets.ts @@ -1,5 +1,6 @@ import { type TreeNode } from '@svelte-preprocess-react'; import React, { useMemo } from 'react'; +import { isNumber } from 'lodash-es'; export function useTargets(children: React.ReactNode, slotKey?: string) { const targets = useMemo(() => { @@ -22,7 +23,10 @@ export function useTargets(children: React.ReactNode, slotKey?: string) { ); }) .sort((a, b) => { - if (a.props.node.slotIndex && b.props.node.slotIndex) { + if ( + isNumber(a.props.node.slotIndex) && + isNumber(b.props.node.slotIndex) + ) { const slotIndexA = a.props.node.slotIndex || 0; const slotIndexB = b.props.node.slotIndex || 0; if ( @@ -43,6 +47,5 @@ export function useTargets(children: React.ReactNode, slotKey?: string) { return child.props.node.portalTarget; }) as HTMLElement[]; }, [children, slotKey]); - return targets; } diff --git a/package.json b/package.json index 7be613b1..584418f9 100644 --- a/package.json +++ b/package.json @@ -28,15 +28,15 @@ "@actions/exec": "^3.0.0", "@actions/github": "^9.0.0", "@changesets/cli": "^2.30.0", - "@commitlint/cli": "^20.4.3", - "@commitlint/config-conventional": "^20.4.3", + "@commitlint/cli": "^20.5.0", + "@commitlint/config-conventional": "^20.5.0", "@manypkg/get-packages": "^3.1.0", "@modelscope-studio/changelog": "workspace:*", "@modelscope-studio/lint-config": "workspace:*", - "@types/node": "^25.4.0", + "@types/node": "^25.5.0", "eslint": "^9.39.3", "husky": "^9.1.7", - "lint-staged": "^16.3.2", + "lint-staged": "^16.4.0", "node-fetch": "^3.3.2", "npm-run-all": "^4.1.5", "prettier": "^3.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ba4c5c3..96c1977c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,13 +19,13 @@ importers: version: 9.0.0 '@changesets/cli': specifier: ^2.30.0 - version: 2.30.0(@types/node@25.4.0) + version: 2.30.0(@types/node@25.5.0) '@commitlint/cli': - specifier: ^20.4.3 - version: 20.4.3(@types/node@25.4.0)(typescript@5.9.3) + specifier: ^20.5.0 + version: 20.5.0(@types/node@25.5.0)(conventional-commits-parser@6.3.0)(typescript@5.9.3) '@commitlint/config-conventional': - specifier: ^20.4.3 - version: 20.4.3 + specifier: ^20.5.0 + version: 20.5.0 '@manypkg/get-packages': specifier: ^3.1.0 version: 3.1.0 @@ -36,8 +36,8 @@ importers: specifier: workspace:* version: link:config/lint-config '@types/node': - specifier: ^25.4.0 - version: 25.4.0 + specifier: ^25.5.0 + version: 25.5.0 eslint: specifier: ^9.39.3 version: 9.39.3(jiti@2.6.1) @@ -45,8 +45,8 @@ importers: specifier: ^9.1.7 version: 9.1.7 lint-staged: - specifier: ^16.3.2 - version: 16.3.2 + specifier: ^16.4.0 + version: 16.4.0 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -100,11 +100,11 @@ importers: specifier: ^6.1.0 version: 6.1.0 '@types/node': - specifier: ^25.4.0 - version: 25.4.0 + specifier: ^25.5.0 + version: 25.5.0 tsup: specifier: ^8.5.1 - version: 8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.4.0))(@swc/core@1.15.11)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.5.0))(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) config/lint-config: dependencies: @@ -115,8 +115,8 @@ importers: specifier: ^10.0.1 version: 10.0.1(eslint@9.39.3(jiti@2.6.1)) '@typescript-eslint/parser': - specifier: ^8.57.0 - version: 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.57.1 + version: 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint-config-prettier: specifier: ^10.1.8 version: 10.1.8(eslint@9.39.3(jiti@2.6.1)) @@ -125,7 +125,7 @@ importers: version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) + version: 2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-jsx-a11y: specifier: ^6.10.2 version: 6.10.2(eslint@9.39.3(jiti@2.6.1)) @@ -145,8 +145,8 @@ importers: specifier: ^12.1.0 version: 12.1.1(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-svelte: - specifier: ^3.15.1 - version: 3.15.1(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.9)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.4.0)(typescript@5.9.3)) + specifier: ^3.15.2 + version: 3.15.2(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.9)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)) globals: specifier: ^17.4.0 version: 17.4.0 @@ -166,8 +166,8 @@ importers: specifier: ^3.0.0 version: 3.0.0(stylelint@17.4.0(typescript@5.9.3)) stylelint-order: - specifier: ^8.0.0 - version: 8.0.0(stylelint@17.4.0(typescript@5.9.3)) + specifier: ^8.1.1 + version: 8.1.1(stylelint@17.4.0(typescript@5.9.3)) stylelint-prettier: specifier: ^5.0.3 version: 5.0.3(prettier@3.8.1)(stylelint@17.4.0(typescript@5.9.3)) @@ -175,8 +175,8 @@ importers: specifier: ^1.6.0 version: 1.6.0(svelte@5.53.9) typescript-eslint: - specifier: ^8.57.0 - version: 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.57.1 + version: 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) devDependencies: '@types/eslint': specifier: ^9.6.1 @@ -194,17 +194,17 @@ importers: specifier: ^6.1.0 version: 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/x': - specifier: ^2.3.0 - version: 2.3.0(antd@6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^2.4.0 + version: 2.4.0(antd@6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/standalone': - specifier: ^7.29.1 - version: 7.29.1 + specifier: ^7.29.2 + version: 7.29.2 '@gradio/client': specifier: 2.1.0 version: 2.1.0 '@gradio/preview': specifier: 0.15.2 - version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.53.9)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.53.9)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@gradio/statustracker': specifier: ^0.12.5 version: 0.12.5(svelte@5.53.9) @@ -218,14 +218,14 @@ importers: specifier: ^1.0.12 version: 1.0.12 antd: - specifier: ^6.3.2 - version: 6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^6.3.3 + version: 6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) classnames: specifier: ^2.5.1 version: 2.5.1 dayjs: - specifier: ^1.11.19 - version: 1.11.19 + specifier: ^1.11.20 + version: 1.11.20 dequal: specifier: ^2.0.2 version: 2.0.3 @@ -275,8 +275,8 @@ importers: specifier: ^4.0.1 version: 4.0.1(svelte@5.53.9) wavesurfer.js: - specifier: ^7.12.1 - version: 7.12.1 + specifier: ^7.12.4 + version: 7.12.4 devDependencies: '@babel/core': specifier: ^7.29.0 @@ -306,17 +306,17 @@ importers: specifier: ^2.16.1 version: 2.16.1 '@vitejs/plugin-react-swc': - specifier: ^4.2.3 - version: 4.2.3(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + specifier: ^4.3.0 + version: 4.3.0(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) less: - specifier: ^4.5.1 - version: 4.5.1 + specifier: ^4.6.4 + version: 4.6.4 typescript-json-schema: specifier: ^0.67.1 - version: 0.67.1(@swc/core@1.15.11) + version: 0.67.1(@swc/core@1.15.18) vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) frontend/antd: {} @@ -391,8 +391,8 @@ packages: react: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@ant-design/x@2.3.0': - resolution: {integrity: sha512-kH711bo0PIizzYlhkGVD0/oNtEehP0AUktX55gtTFCM3cRbXIKTLwcxlragLWaCXPtT1O/T8F6SAYCxLtg76IA==} + '@ant-design/x@2.4.0': + resolution: {integrity: sha512-2J+S6V2RuR1ZKOOTtY6/XUA+T/S690j25uTx2HTKC3q8S9wi8BUuJBEMNPkPHUf9V+3Y8KgChyB5JnZkKP5J6Q==} peerDependencies: antd: ^6.1.1 react: '>=18.0.0' @@ -521,8 +521,12 @@ packages: resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} - '@babel/standalone@7.29.1': - resolution: {integrity: sha512-z42abD0C6fiHfgLyCWw8PYv6FCJ0IGVtSCxXk/NPykWO5LNIEGfdLDJ3HdYqlPcAhwtQ3oKH1PvNj2JGpTxQKg==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/standalone@7.29.2': + resolution: {integrity: sha512-VSuvywmVRS8efooKrvJzs6BlVSxRvAdLeGrAKUrWoBx1fFBSeE/oBpUZCQ5BcprLyXy04W8skzz7JT8GqlNRJg==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': @@ -639,61 +643,61 @@ packages: '@chevrotain/utils@11.1.2': resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} - '@commitlint/cli@20.4.3': - resolution: {integrity: sha512-Z37EMoDT7+Upg500vlr/vZrgRsb6Xc5JAA3Tv7BYbobnN/ZpqUeZnSLggBg2+1O+NptRDtyujr2DD1CPV2qwhA==} + '@commitlint/cli@20.5.0': + resolution: {integrity: sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ==} engines: {node: '>=v18'} hasBin: true - '@commitlint/config-conventional@20.4.3': - resolution: {integrity: sha512-9RtLySbYQAs8yEqWEqhSZo9nYhbm57jx7qHXtgRmv/nmeQIjjMcwf6Dl+y5UZcGWgWx435TAYBURONaJIuCjWg==} + '@commitlint/config-conventional@20.5.0': + resolution: {integrity: sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA==} engines: {node: '>=v18'} - '@commitlint/config-validator@20.4.3': - resolution: {integrity: sha512-jCZpZFkcSL3ZEdL5zgUzFRdytv3xPo8iukTe9VA+QGus/BGhpp1xXSVu2B006GLLb2gYUAEGEqv64kTlpZNgmA==} + '@commitlint/config-validator@20.5.0': + resolution: {integrity: sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==} engines: {node: '>=v18'} - '@commitlint/ensure@20.4.3': - resolution: {integrity: sha512-WcXGKBNn0wBKpX8VlXgxqedyrLxedIlLBCMvdamLnJFEbUGJ9JZmBVx4vhLV3ZyA8uONGOb+CzW0Y9HDbQ+ONQ==} + '@commitlint/ensure@20.5.0': + resolution: {integrity: sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw==} engines: {node: '>=v18'} '@commitlint/execute-rule@20.0.0': resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} engines: {node: '>=v18'} - '@commitlint/format@20.4.3': - resolution: {integrity: sha512-UDJVErjLbNghop6j111rsHJYGw6MjCKAi95K0GT2yf4eeiDHy3JDRLWYWEjIaFgO+r+dQSkuqgJ1CdMTtrvHsA==} + '@commitlint/format@20.5.0': + resolution: {integrity: sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==} engines: {node: '>=v18'} - '@commitlint/is-ignored@20.4.3': - resolution: {integrity: sha512-W5VQKZ7fdJ1X3Tko+h87YZaqRMGN1KvQKXyCM8xFdxzMIf1KCZgN4uLz3osLB1zsFcVS4ZswHY64LI26/9ACag==} + '@commitlint/is-ignored@20.5.0': + resolution: {integrity: sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==} engines: {node: '>=v18'} - '@commitlint/lint@20.4.3': - resolution: {integrity: sha512-CYOXL23e+nRKij81+d0+dymtIi7Owl9QzvblJYbEfInON/4MaETNSLFDI74LDu+YJ0ML5HZyw9Vhp9QpckwQ0A==} + '@commitlint/lint@20.5.0': + resolution: {integrity: sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA==} engines: {node: '>=v18'} - '@commitlint/load@20.4.3': - resolution: {integrity: sha512-3cdJOUVP+VcgHa7bhJoWS+Z8mBNXB5aLWMBu7Q7uX8PSeWDzdbrBlR33J1MGGf7r1PZDp+mPPiFktk031PgdRw==} + '@commitlint/load@20.5.0': + resolution: {integrity: sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==} engines: {node: '>=v18'} '@commitlint/message@20.4.3': resolution: {integrity: sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==} engines: {node: '>=v18'} - '@commitlint/parse@20.4.3': - resolution: {integrity: sha512-hzC3JCo3zs3VkQ833KnGVuWjWIzR72BWZWjQM7tY/7dfKreKAm7fEsy71tIFCRtxf2RtMP2d3RLF1U9yhFSccA==} + '@commitlint/parse@20.5.0': + resolution: {integrity: sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==} engines: {node: '>=v18'} - '@commitlint/read@20.4.3': - resolution: {integrity: sha512-j42OWv3L31WfnP8WquVjHZRt03w50Y/gEE8FAyih7GQTrIv2+pZ6VZ6pWLD/ml/3PO+RV2SPtRtTp/MvlTb8rQ==} + '@commitlint/read@20.5.0': + resolution: {integrity: sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@20.4.3': - resolution: {integrity: sha512-QucxcOy+00FhS9s4Uy0OyS5HeUV+hbC6OLqkTSIm6fwMdKva+OEavaCDuLtgd9akZZlsUo//XzSmPP3sLKBPog==} + '@commitlint/resolve-extends@20.5.0': + resolution: {integrity: sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==} engines: {node: '>=v18'} - '@commitlint/rules@20.4.3': - resolution: {integrity: sha512-Yuosd7Grn5qiT7FovngXLyRXTMUbj9PYiSkvUgWK1B5a7+ZvrbWDS7epeUapYNYatCy/KTpPFPbgLUdE+MUrBg==} + '@commitlint/rules@20.5.0': + resolution: {integrity: sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ==} engines: {node: '>=v18'} '@commitlint/to-lines@20.0.0': @@ -704,10 +708,22 @@ packages: resolution: {integrity: sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==} engines: {node: '>=v18'} - '@commitlint/types@20.4.3': - resolution: {integrity: sha512-51OWa1Gi6ODOasPmfJPq6js4pZoomima4XLZZCrkldaH2V5Nb3bVhNXPeT6XV0gubbainSpTw4zi68NqAeCNCg==} + '@commitlint/types@20.5.0': + resolution: {integrity: sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==} engines: {node: '>=v18'} + '@conventional-changelog/git-client@2.6.0': + resolution: {integrity: sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==} + engines: {node: '>=18'} + peerDependencies: + conventional-commits-filter: ^5.0.0 + conventional-commits-parser: ^6.3.0 + peerDependenciesMeta: + conventional-commits-filter: + optional: true + conventional-commits-parser: + optional: true + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1675,8 +1691,8 @@ packages: react: '>=16.11.0' react-dom: '>=16.11.0' - '@rc-component/form@1.7.1': - resolution: {integrity: sha512-Uhw0FPvJ+Ko4xBxhvziqmqzIuO0YvVBzVyFGNAI9fMCz4r4DfrYK6PRIN6CkFqM0vdAX9sr4JGA1/h/VzpA1cA==} + '@rc-component/form@1.7.2': + resolution: {integrity: sha512-5C90rXH7aZvvvxB4M5ew+QxROvimdL/lqhSshR8NsyiR7HKOoGQYSitxdfENnH6/0KNFxEy2ranVe2LrTnHZIw==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' @@ -1712,8 +1728,8 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@rc-component/mini-decimal@1.1.0': - resolution: {integrity: sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==} + '@rc-component/mini-decimal@1.1.3': + resolution: {integrity: sha512-bk/FJ09fLf+NLODMAFll6CfYrHPBioTedhW6lxDBuuWucJEqFUd4l/D/5JgIi3dina6sYahB8iuPAZTNz2pMxw==} engines: {node: '>=8.x'} '@rc-component/motion@1.3.1': @@ -1748,8 +1764,8 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@rc-component/picker@1.9.0': - resolution: {integrity: sha512-OLisdk8AWVCG9goBU1dWzuH5QlBQk8jktmQ6p0/IyBFwdKGwyIZOSjnBYo8hooHiTdl0lU+wGf/OfMtVBw02KQ==} + '@rc-component/picker@1.9.1': + resolution: {integrity: sha512-9FBYYsvH3HMLICaPDA/1Th5FLaDkFa7qAtangIdlhKb3ZALaR745e9PsOhheJb6asS4QXc12ffiAcjdkZ4C5/g==} engines: {node: '>=12.x'} peerDependencies: date-fns: '>= 2.x' @@ -1807,8 +1823,8 @@ packages: react: '>=16.0.0' react-dom: '>=16.0.0' - '@rc-component/select@1.6.14': - resolution: {integrity: sha512-T1IWeLlSas7Z/igZtPtJ/bweCxMMkXIGKQBtnigK+I/n1AVNjCs+ZdL3Fj42mq3uqm4sd1uzeQLZkdCqR26ADw==} + '@rc-component/select@1.6.15': + resolution: {integrity: sha512-SyVCWnqxCQZZcQvQJ/CxSjx2bGma6ds/HtnpkIfZVnt6RoEgbqUmHgD6vrzNarNXwbLXerwVzWwq8F3d1sst7g==} engines: {node: '>=8.x'} peerDependencies: react: '*' @@ -1873,8 +1889,8 @@ packages: react: '*' react-dom: '*' - '@rc-component/tree@1.2.3': - resolution: {integrity: sha512-mG8hF2ogQcKaEpfyxzPvMWqqkptofd7Sf+YiXOpPzuXLTLwNKfLDJtysc1/oybopbnzxNqWh2Vgwi+GYwNIb7w==} + '@rc-component/tree@1.2.4': + resolution: {integrity: sha512-5Gli43+m4R7NhpYYz3Z61I6LOw9yI6CNChxgVtvrO6xB1qML7iE6QMLVMB3+FTjo2yF6uFdAHtqWPECz/zbX5w==} engines: {node: '>=10.x'} peerDependencies: react: '*' @@ -1893,6 +1909,12 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' + '@rc-component/util@1.10.0': + resolution: {integrity: sha512-aY9GLBuiUdpyfIUpAWSYer4Tu3mVaZCo5A0q9NtXcazT3MRiI3/WNHCR+DUn5VAtR6iRRf0ynCqQUcHli5UdYw==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + '@rc-component/util@1.3.0': resolution: {integrity: sha512-hfXE04CVsxI/slmWKeSh6du7sSKpbvVdVEZCa8A+2QWDlL97EsCYme2c3ZWLn1uC9FR21JoewlrhUPWO4QgO8w==} peerDependencies: @@ -1912,8 +1934,8 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@rolldown/pluginutils@1.0.0-rc.2': - resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} '@rollup/plugin-sucrase@5.1.0': resolution: {integrity: sha512-/S4cJnfnjmaH0RqjvZtKOCx8WRnL14f3+tIieL5Ty0YkRpUPW2S/tgHCplWsHEmuZAWYoPJ4KN5eIxWtQw95Qw==} @@ -1947,11 +1969,6 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.57.1': - resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} - cpu: [arm] - os: [android] - '@rollup/rollup-android-arm-eabi@4.59.0': resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] @@ -1962,11 +1979,6 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.57.1': - resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} - cpu: [arm64] - os: [android] - '@rollup/rollup-android-arm64@4.59.0': resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] @@ -1977,11 +1989,6 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.57.1': - resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} - cpu: [arm64] - os: [darwin] - '@rollup/rollup-darwin-arm64@4.59.0': resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] @@ -1992,11 +1999,6 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.57.1': - resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} - cpu: [x64] - os: [darwin] - '@rollup/rollup-darwin-x64@4.59.0': resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] @@ -2007,11 +2009,6 @@ packages: cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-arm64@4.57.1': - resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} - cpu: [arm64] - os: [freebsd] - '@rollup/rollup-freebsd-arm64@4.59.0': resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} cpu: [arm64] @@ -2022,11 +2019,6 @@ packages: cpu: [x64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.57.1': - resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} - cpu: [x64] - os: [freebsd] - '@rollup/rollup-freebsd-x64@4.59.0': resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} cpu: [x64] @@ -2038,12 +2030,6 @@ packages: os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-gnueabihf@4.57.1': - resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} - cpu: [arm] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] @@ -2056,12 +2042,6 @@ packages: os: [linux] libc: [musl] - '@rollup/rollup-linux-arm-musleabihf@4.57.1': - resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} - cpu: [arm] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] @@ -2074,12 +2054,6 @@ packages: os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-gnu@4.57.1': - resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} - cpu: [arm64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] @@ -2092,12 +2066,6 @@ packages: os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-musl@4.57.1': - resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} - cpu: [arm64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] @@ -2110,24 +2078,12 @@ packages: os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-gnu@4.57.1': - resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} - cpu: [loong64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.57.1': - resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} - cpu: [loong64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] @@ -2140,24 +2096,12 @@ packages: os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-gnu@4.57.1': - resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.57.1': - resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} - cpu: [ppc64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] @@ -2170,12 +2114,6 @@ packages: os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.57.1': - resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] @@ -2188,12 +2126,6 @@ packages: os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-musl@4.57.1': - resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} - cpu: [riscv64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] @@ -2206,12 +2138,6 @@ packages: os: [linux] libc: [glibc] - '@rollup/rollup-linux-s390x-gnu@4.57.1': - resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} - cpu: [s390x] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] @@ -2224,12 +2150,6 @@ packages: os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.57.1': - resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} - cpu: [x64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] @@ -2242,23 +2162,12 @@ packages: os: [linux] libc: [musl] - '@rollup/rollup-linux-x64-musl@4.57.1': - resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} - cpu: [x64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.57.1': - resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} - cpu: [x64] - os: [openbsd] - '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} cpu: [x64] @@ -2269,11 +2178,6 @@ packages: cpu: [arm64] os: [openharmony] - '@rollup/rollup-openharmony-arm64@4.57.1': - resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} - cpu: [arm64] - os: [openharmony] - '@rollup/rollup-openharmony-arm64@4.59.0': resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} cpu: [arm64] @@ -2284,11 +2188,6 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.57.1': - resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.59.0': resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] @@ -2299,11 +2198,6 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.57.1': - resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.59.0': resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] @@ -2314,11 +2208,6 @@ packages: cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.57.1': - resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-gnu@4.59.0': resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} cpu: [x64] @@ -2329,11 +2218,6 @@ packages: cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.57.1': - resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.59.0': resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] @@ -2364,6 +2248,10 @@ packages: '@rushstack/ts-command-line@5.0.2': resolution: {integrity: sha512-+AkJDbu1GFMPIU8Sb7TLVXDv/Q7Mkvx+wAjEl8XiXVVq+p1FmWW6M3LYpJMmoHNckSofeMecgWg5lfMwNAAsEQ==} + '@simple-libs/child-process-utils@1.0.2': + resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==} + engines: {node: '>=18'} + '@simple-libs/stream-utils@1.2.0': resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} engines: {node: '>=18'} @@ -2392,72 +2280,72 @@ packages: svelte: ^5.0.0 vite: ^6.3.0 || ^7.0.0 - '@swc/core-darwin-arm64@1.15.11': - resolution: {integrity: sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==} + '@swc/core-darwin-arm64@1.15.18': + resolution: {integrity: sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.11': - resolution: {integrity: sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==} + '@swc/core-darwin-x64@1.15.18': + resolution: {integrity: sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.11': - resolution: {integrity: sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==} + '@swc/core-linux-arm-gnueabihf@1.15.18': + resolution: {integrity: sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.11': - resolution: {integrity: sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==} + '@swc/core-linux-arm64-gnu@1.15.18': + resolution: {integrity: sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] libc: [glibc] - '@swc/core-linux-arm64-musl@1.15.11': - resolution: {integrity: sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==} + '@swc/core-linux-arm64-musl@1.15.18': + resolution: {integrity: sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] libc: [musl] - '@swc/core-linux-x64-gnu@1.15.11': - resolution: {integrity: sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==} + '@swc/core-linux-x64-gnu@1.15.18': + resolution: {integrity: sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==} engines: {node: '>=10'} cpu: [x64] os: [linux] libc: [glibc] - '@swc/core-linux-x64-musl@1.15.11': - resolution: {integrity: sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==} + '@swc/core-linux-x64-musl@1.15.18': + resolution: {integrity: sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==} engines: {node: '>=10'} cpu: [x64] os: [linux] libc: [musl] - '@swc/core-win32-arm64-msvc@1.15.11': - resolution: {integrity: sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==} + '@swc/core-win32-arm64-msvc@1.15.18': + resolution: {integrity: sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.11': - resolution: {integrity: sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==} + '@swc/core-win32-ia32-msvc@1.15.18': + resolution: {integrity: sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.11': - resolution: {integrity: sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==} + '@swc/core-win32-x64-msvc@1.15.18': + resolution: {integrity: sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.15.11': - resolution: {integrity: sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==} + '@swc/core@1.15.18': + resolution: {integrity: sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -2643,8 +2531,8 @@ packages: '@types/node@18.19.130': resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} - '@types/node@25.4.0': - resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} + '@types/node@25.5.0': + resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} '@types/prismjs@1.26.5': resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} @@ -2682,63 +2570,63 @@ packages: '@types/which@3.0.4': resolution: {integrity: sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==} - '@typescript-eslint/eslint-plugin@8.57.0': - resolution: {integrity: sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==} + '@typescript-eslint/eslint-plugin@8.57.1': + resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.0 + '@typescript-eslint/parser': ^8.57.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.57.0': - resolution: {integrity: sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==} + '@typescript-eslint/parser@8.57.1': + resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.57.0': - resolution: {integrity: sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==} + '@typescript-eslint/project-service@8.57.1': + resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.57.0': - resolution: {integrity: sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==} + '@typescript-eslint/scope-manager@8.57.1': + resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.57.0': - resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} + '@typescript-eslint/tsconfig-utils@8.57.1': + resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.57.0': - resolution: {integrity: sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==} + '@typescript-eslint/type-utils@8.57.1': + resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.57.0': - resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} + '@typescript-eslint/types@8.57.1': + resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.57.0': - resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} + '@typescript-eslint/typescript-estree@8.57.1': + resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.57.0': - resolution: {integrity: sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==} + '@typescript-eslint/utils@8.57.1': + resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.57.0': - resolution: {integrity: sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==} + '@typescript-eslint/visitor-keys@8.57.1': + resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.9.2': @@ -2847,11 +2735,11 @@ packages: '@upsetjs/venn.js@2.0.0': resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} - '@vitejs/plugin-react-swc@4.2.3': - resolution: {integrity: sha512-QIluDil2prhY1gdA3GGwxZzTAmLdi8cQ2CcuMW4PB/Wu4e/1pzqrwhYWVd09LInCRlDUidQjd0B70QWbjWtLxA==} + '@vitejs/plugin-react-swc@4.3.0': + resolution: {integrity: sha512-mOkXCII839dHyAt/gpoSlm28JIVDwhZ6tnG6wJxUy2bmOx7UaPjvOyIDf3SFv5s7Eo7HVaq6kRcu6YMEzt5Z7w==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^4 || ^5 || ^6 || ^7 + vite: ^4 || ^5 || ^6 || ^7 || ^8 acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -2943,8 +2831,8 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - antd@6.3.2: - resolution: {integrity: sha512-IlMoqaXlq5Bgxi0ANERhAzmDREYyGwr/U7MCVihaUQbE/ZOB3r4ArakUxjA1ULYNDA6K00dawSrB8aalGnZlLA==} + antd@6.3.3: + resolution: {integrity: sha512-T8FAQelw36zS96cZw2U/qEjpYny5yFc7hg+1W7DvVr8xMoSXWvyB8WvmiDVH0nS0LPYV4y2sxetsJoGZt7rhhw==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' @@ -3400,8 +3288,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - copy-anything@2.0.6: - resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} copy-descriptor@0.1.1: resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} @@ -3637,10 +3526,6 @@ packages: damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dargs@8.1.0: - resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} - engines: {node: '>=12'} - data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -3660,8 +3545,8 @@ packages: dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} - dayjs@1.11.19: - resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} @@ -4202,8 +4087,8 @@ packages: peerDependencies: eslint: '>=5.0.0' - eslint-plugin-svelte@3.15.1: - resolution: {integrity: sha512-Ao/LGKPFzz8jbLEqa7OMK6LUX/mJRcJbVbIaHKjdheirkwjA/cDLdY1NcIZYscRxrK4FDIOX6IepmXFnhQlDlw==} + eslint-plugin-svelte@3.15.2: + resolution: {integrity: sha512-k4Nsjs3bHujeEnnckoTM4mFYR1e8Mb9l2rTwNdmYiamA+Tjzn8X+2F+fuSP2w4VbXYhn2bmySyACQYdmUDW2Cg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 @@ -4517,10 +4402,9 @@ packages: git-hooks-list@4.2.1: resolution: {integrity: sha512-WNvqJjOxxs/8ZP9+DWdwWJ7cDsd60NHf39XnD82pDVrKO5q7xfPqpkK6hwEAmBa/ZSEE4IOoR75EzbbIuwGlMw==} - git-raw-commits@4.0.0: - resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} - engines: {node: '>=16'} - deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. + git-raw-commits@5.0.1: + resolution: {integrity: sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==} + engines: {node: '>=18'} hasBin: true github-slugger@2.0.0: @@ -5048,8 +4932,9 @@ packages: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} - is-what@3.14.1: - resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} is-whitespace-character@1.0.4: resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} @@ -5218,9 +5103,9 @@ packages: layout-base@2.0.1: resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} - less@4.5.1: - resolution: {integrity: sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw==} - engines: {node: '>=14'} + less@4.6.4: + resolution: {integrity: sha512-OJmO5+HxZLLw0RLzkqaNHzcgEAQG7C0y3aMbwtCzIUFZsLMNNq/1IdAdHEycQ58CwUO3jPTHmoN+tE5I7FQxNg==} + engines: {node: '>=18'} hasBin: true leven@2.1.0: @@ -5316,8 +5201,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@16.3.2: - resolution: {integrity: sha512-xKqhC2AeXLwiAHXguxBjuChoTTWFC6Pees0SHPwOpwlvI3BH7ZADFPddAdN3pgo3aiKgPUx/bxE78JfUnxQnlg==} + lint-staged@16.4.0: + resolution: {integrity: sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==} engines: {node: '>=20.17'} hasBin: true @@ -5514,10 +5399,6 @@ packages: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - meow@12.1.1: - resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} - engines: {node: '>=16.10'} - meow@13.2.0: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} @@ -5634,8 +5515,8 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - needle@3.3.1: - resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} + needle@3.5.0: + resolution: {integrity: sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==} engines: {node: '>= 4.4.x'} hasBin: true @@ -6350,11 +6231,6 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rollup@4.57.1: - resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - rollup@4.59.0: resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -6410,6 +6286,10 @@ packages: resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} engines: {node: '>=11.0.0'} + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -6606,10 +6486,6 @@ packages: resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} engines: {node: '>=0.10.0'} - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -6749,8 +6625,8 @@ packages: peerDependencies: stylelint: ^9.10.1 || ^10.0.0 - stylelint-order@8.0.0: - resolution: {integrity: sha512-1oAwPRz6Ba8u9LPjgvdbeMjZszHhjY6DBBK+xMlS3IC89GdTsvAPpGYvW+dkn6pxc4ZaI1S959g4c8CftZbhIg==} + stylelint-order@8.1.1: + resolution: {integrity: sha512-LqsEB6VggJuu5v10RtkrQsBObcdwBE7GuAOlwfc/LR3VL/w8UqKX2BOLIjhyGt0Gne/njo7gRNGiJAKhfmPMNw==} engines: {node: '>=20.19.0'} peerDependencies: stylelint: ^16.18.0 || ^17.0.0 @@ -6932,6 +6808,10 @@ packages: resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} engines: {node: '>=18'} + tinyexec@1.0.4: + resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} + engines: {node: '>=18'} + tinyglobby@0.2.14: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} @@ -7064,8 +6944,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.57.0: - resolution: {integrity: sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==} + typescript-eslint@8.57.1: + resolution: {integrity: sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -7297,8 +7177,8 @@ packages: vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - wavesurfer.js@7.12.1: - resolution: {integrity: sha512-NswPjVHxk0Q1F/VMRemCPUzSojjuHHisQrBqQiRXg7MVbe3f5vQ6r0rTTXA/a/neC/4hnOEC4YpXca4LpH0SUg==} + wavesurfer.js@7.12.4: + resolution: {integrity: sha512-b/+XnWfJejNdvNUmtm4M5QzQepHhUbTo+62wYybwdV1B/Sn9vHhgb1xckRm0rGY2ZefJwLkE7lYcKnLfIia4cQ==} web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} @@ -7477,8 +7357,8 @@ snapshots: '@ant-design/cssinjs-utils@2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@babel/runtime': 7.28.6 - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@babel/runtime': 7.29.2 + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -7511,25 +7391,25 @@ snapshots: '@ant-design/react-slick@2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 clsx: 2.1.1 json2mq: 0.2.0 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) throttle-debounce: 5.0.2 - '@ant-design/x@2.3.0(antd@6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ant-design/x@2.4.0(antd@6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/colors': 8.0.1 '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/cssinjs-utils': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/fast-color': 3.0.1 '@ant-design/icons': 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - antd: 6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + antd: 6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 lodash.throttle: 4.1.1 mermaid: 11.13.0 @@ -7704,7 +7584,9 @@ snapshots: '@babel/runtime@7.28.6': {} - '@babel/standalone@7.29.1': {} + '@babel/runtime@7.29.2': {} + + '@babel/standalone@7.29.2': {} '@babel/template@7.27.2': dependencies: @@ -7805,7 +7687,7 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.30.0(@types/node@25.4.0)': + '@changesets/cli@2.30.0(@types/node@25.5.0)': dependencies: '@changesets/apply-release-plan': 7.1.0 '@changesets/assemble-release-plan': 6.0.9 @@ -7821,7 +7703,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.4.0) + '@inquirer/external-editor': 1.0.3(@types/node@25.5.0) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 enquirer: 2.4.1 @@ -7943,32 +7825,34 @@ snapshots: '@chevrotain/utils@11.1.2': {} - '@commitlint/cli@20.4.3(@types/node@25.4.0)(typescript@5.9.3)': + '@commitlint/cli@20.5.0(@types/node@25.5.0)(conventional-commits-parser@6.3.0)(typescript@5.9.3)': dependencies: - '@commitlint/format': 20.4.3 - '@commitlint/lint': 20.4.3 - '@commitlint/load': 20.4.3(@types/node@25.4.0)(typescript@5.9.3) - '@commitlint/read': 20.4.3 - '@commitlint/types': 20.4.3 - tinyexec: 1.0.2 + '@commitlint/format': 20.5.0 + '@commitlint/lint': 20.5.0 + '@commitlint/load': 20.5.0(@types/node@25.5.0)(typescript@5.9.3) + '@commitlint/read': 20.5.0(conventional-commits-parser@6.3.0) + '@commitlint/types': 20.5.0 + tinyexec: 1.0.4 yargs: 17.7.2 transitivePeerDependencies: - '@types/node' + - conventional-commits-filter + - conventional-commits-parser - typescript - '@commitlint/config-conventional@20.4.3': + '@commitlint/config-conventional@20.5.0': dependencies: - '@commitlint/types': 20.4.3 + '@commitlint/types': 20.5.0 conventional-changelog-conventionalcommits: 9.3.0 - '@commitlint/config-validator@20.4.3': + '@commitlint/config-validator@20.5.0': dependencies: - '@commitlint/types': 20.4.3 + '@commitlint/types': 20.5.0 ajv: 8.18.0 - '@commitlint/ensure@20.4.3': + '@commitlint/ensure@20.5.0': dependencies: - '@commitlint/types': 20.4.3 + '@commitlint/types': 20.5.0 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 @@ -7977,31 +7861,31 @@ snapshots: '@commitlint/execute-rule@20.0.0': {} - '@commitlint/format@20.4.3': + '@commitlint/format@20.5.0': dependencies: - '@commitlint/types': 20.4.3 + '@commitlint/types': 20.5.0 picocolors: 1.1.1 - '@commitlint/is-ignored@20.4.3': + '@commitlint/is-ignored@20.5.0': dependencies: - '@commitlint/types': 20.4.3 + '@commitlint/types': 20.5.0 semver: 7.7.4 - '@commitlint/lint@20.4.3': + '@commitlint/lint@20.5.0': dependencies: - '@commitlint/is-ignored': 20.4.3 - '@commitlint/parse': 20.4.3 - '@commitlint/rules': 20.4.3 - '@commitlint/types': 20.4.3 + '@commitlint/is-ignored': 20.5.0 + '@commitlint/parse': 20.5.0 + '@commitlint/rules': 20.5.0 + '@commitlint/types': 20.5.0 - '@commitlint/load@20.4.3(@types/node@25.4.0)(typescript@5.9.3)': + '@commitlint/load@20.5.0(@types/node@25.5.0)(typescript@5.9.3)': dependencies: - '@commitlint/config-validator': 20.4.3 + '@commitlint/config-validator': 20.5.0 '@commitlint/execute-rule': 20.0.0 - '@commitlint/resolve-extends': 20.4.3 - '@commitlint/types': 20.4.3 + '@commitlint/resolve-extends': 20.5.0 + '@commitlint/types': 20.5.0 cosmiconfig: 9.0.1(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.2.0(@types/node@25.4.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.2.0(@types/node@25.5.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) is-plain-obj: 4.1.0 lodash.mergewith: 4.6.2 picocolors: 1.1.1 @@ -8011,35 +7895,38 @@ snapshots: '@commitlint/message@20.4.3': {} - '@commitlint/parse@20.4.3': + '@commitlint/parse@20.5.0': dependencies: - '@commitlint/types': 20.4.3 + '@commitlint/types': 20.5.0 conventional-changelog-angular: 8.3.0 conventional-commits-parser: 6.3.0 - '@commitlint/read@20.4.3': + '@commitlint/read@20.5.0(conventional-commits-parser@6.3.0)': dependencies: '@commitlint/top-level': 20.4.3 - '@commitlint/types': 20.4.3 - git-raw-commits: 4.0.0 + '@commitlint/types': 20.5.0 + git-raw-commits: 5.0.1(conventional-commits-parser@6.3.0) minimist: 1.2.8 - tinyexec: 1.0.2 + tinyexec: 1.0.4 + transitivePeerDependencies: + - conventional-commits-filter + - conventional-commits-parser - '@commitlint/resolve-extends@20.4.3': + '@commitlint/resolve-extends@20.5.0': dependencies: - '@commitlint/config-validator': 20.4.3 - '@commitlint/types': 20.4.3 + '@commitlint/config-validator': 20.5.0 + '@commitlint/types': 20.5.0 global-directory: 4.0.1 import-meta-resolve: 4.2.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - '@commitlint/rules@20.4.3': + '@commitlint/rules@20.5.0': dependencies: - '@commitlint/ensure': 20.4.3 + '@commitlint/ensure': 20.5.0 '@commitlint/message': 20.4.3 '@commitlint/to-lines': 20.0.0 - '@commitlint/types': 20.4.3 + '@commitlint/types': 20.5.0 '@commitlint/to-lines@20.0.0': {} @@ -8047,11 +7934,19 @@ snapshots: dependencies: escalade: 3.2.0 - '@commitlint/types@20.4.3': + '@commitlint/types@20.5.0': dependencies: conventional-commits-parser: 6.3.0 picocolors: 1.1.1 + '@conventional-changelog/git-client@2.6.0(conventional-commits-parser@6.3.0)': + dependencies: + '@simple-libs/child-process-utils': 1.0.2 + '@simple-libs/stream-utils': 1.2.0 + semver: 7.7.4 + optionalDependencies: + conventional-commits-parser: 6.3.0 + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -8445,12 +8340,12 @@ snapshots: prismjs: 1.30.0 svelte: 5.53.9 - '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.53.9)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': + '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.53.9)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': dependencies: '@originjs/vite-plugin-commonjs': 1.0.3 '@rollup/plugin-sucrase': 5.1.0(rollup@4.59.0) '@rollup/plugin-terser': 0.4.4(rollup@4.59.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@types/which': 3.0.4 coffeescript: 2.7.0 lightningcss: 1.31.1 @@ -8459,9 +8354,9 @@ snapshots: stylus: 0.64.0 sucrase: 3.35.1 sugarss: 5.0.1(postcss@8.5.8) - svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.53.9)(typescript@5.9.3) + svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.53.9)(typescript@5.9.3) typescript: 5.9.3 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) which: 5.0.0 yootils: 0.3.1 transitivePeerDependencies: @@ -8533,12 +8428,12 @@ snapshots: '@iconify/types': 2.0.0 mlly: 1.8.1 - '@inquirer/external-editor@1.0.3(@types/node@25.4.0)': + '@inquirer/external-editor@1.0.3(@types/node@25.5.0)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 25.4.0 + '@types/node': 25.5.0 '@isaacs/balanced-match@4.0.1': optional: true @@ -8629,24 +8524,24 @@ snapshots: dependencies: langium: 4.2.1 - '@microsoft/api-extractor-model@7.30.7(@types/node@25.4.0)': + '@microsoft/api-extractor-model@7.30.7(@types/node@25.5.0)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@25.4.0) + '@rushstack/node-core-library': 5.14.0(@types/node@25.5.0) transitivePeerDependencies: - '@types/node' optional: true - '@microsoft/api-extractor@7.52.10(@types/node@25.4.0)': + '@microsoft/api-extractor@7.52.10(@types/node@25.5.0)': dependencies: - '@microsoft/api-extractor-model': 7.30.7(@types/node@25.4.0) + '@microsoft/api-extractor-model': 7.30.7(@types/node@25.5.0) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@25.4.0) + '@rushstack/node-core-library': 5.14.0(@types/node@25.5.0) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.4(@types/node@25.4.0) - '@rushstack/ts-command-line': 5.0.2(@types/node@25.4.0) + '@rushstack/terminal': 0.15.4(@types/node@25.5.0) + '@rushstack/ts-command-line': 5.0.2(@types/node@25.5.0) lodash: 4.17.23 minimatch: 10.0.3 resolve: 1.22.11 @@ -8828,29 +8723,29 @@ snapshots: '@rc-component/async-validator@5.1.0': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/cascader@1.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/select': 1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/tree': 1.2.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/select': 1.6.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/tree': 1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/checkbox@2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/collapse@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8858,14 +8753,14 @@ snapshots: '@rc-component/color-picker@3.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/fast-color': 3.0.1 - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/context@2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8873,7 +8768,7 @@ snapshots: dependencies: '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8882,7 +8777,7 @@ snapshots: dependencies: '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8890,15 +8785,15 @@ snapshots: '@rc-component/dropdown@1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/form@1.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/form@1.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/async-validator': 5.1.0 - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8907,22 +8802,22 @@ snapshots: dependencies: '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/input-number@1.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/mini-decimal': 1.1.0 - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/mini-decimal': 1.1.3 + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/input@1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8933,7 +8828,7 @@ snapshots: '@rc-component/menu': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/textarea': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8943,111 +8838,111 @@ snapshots: '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/mini-decimal@1.1.0': + '@rc-component/mini-decimal@1.1.3': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/motion@1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/mutate-observer@2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/notification@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/overflow@1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/pagination@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/picker@1.9.0(dayjs@1.11.19)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/picker@1.9.1(dayjs@1.11.20)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - dayjs: 1.11.19 + dayjs: 1.11.20 '@rc-component/portal@2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/progress@1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/qrcode@1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/rate@1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/resize-observer@1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/segmented@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/select@1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/select@1.6.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9055,21 +8950,21 @@ snapshots: '@rc-component/slider@1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/steps@1.2.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/switch@1.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9078,7 +8973,7 @@ snapshots: dependencies: '@rc-component/context': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9090,7 +8985,7 @@ snapshots: '@rc-component/menu': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9099,7 +8994,7 @@ snapshots: dependencies: '@rc-component/input': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9107,7 +9002,7 @@ snapshots: '@rc-component/tooltip@1.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9116,24 +9011,24 @@ snapshots: dependencies: '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/tree-select@1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/select': 1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/tree': 1.2.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/select': 1.6.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/tree': 1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/tree@1.2.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/tree@1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9144,18 +9039,25 @@ snapshots: '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/upload@1.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + '@rc-component/util@1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + is-mobile: 5.0.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-is: 18.3.1 + '@rc-component/util@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: is-mobile: 5.0.0 @@ -9172,14 +9074,14 @@ snapshots: '@rc-component/virtual-list@1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rolldown/pluginutils@1.0.0-rc.2': {} + '@rolldown/pluginutils@1.0.0-rc.7': {} '@rollup/plugin-sucrase@5.1.0(rollup@4.59.0)': dependencies: @@ -9207,222 +9109,147 @@ snapshots: '@rollup/rollup-android-arm-eabi@4.53.3': optional: true - '@rollup/rollup-android-arm-eabi@4.57.1': - optional: true - '@rollup/rollup-android-arm-eabi@4.59.0': optional: true '@rollup/rollup-android-arm64@4.53.3': optional: true - '@rollup/rollup-android-arm64@4.57.1': - optional: true - '@rollup/rollup-android-arm64@4.59.0': optional: true '@rollup/rollup-darwin-arm64@4.53.3': optional: true - '@rollup/rollup-darwin-arm64@4.57.1': - optional: true - '@rollup/rollup-darwin-arm64@4.59.0': optional: true '@rollup/rollup-darwin-x64@4.53.3': optional: true - '@rollup/rollup-darwin-x64@4.57.1': - optional: true - '@rollup/rollup-darwin-x64@4.59.0': optional: true '@rollup/rollup-freebsd-arm64@4.53.3': optional: true - '@rollup/rollup-freebsd-arm64@4.57.1': - optional: true - '@rollup/rollup-freebsd-arm64@4.59.0': optional: true '@rollup/rollup-freebsd-x64@4.53.3': optional: true - '@rollup/rollup-freebsd-x64@4.57.1': - optional: true - '@rollup/rollup-freebsd-x64@4.59.0': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.57.1': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true '@rollup/rollup-linux-arm-musleabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.57.1': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true '@rollup/rollup-linux-arm64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-arm64-gnu@4.57.1': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true '@rollup/rollup-linux-arm64-musl@4.53.3': optional: true - '@rollup/rollup-linux-arm64-musl@4.57.1': - optional: true - '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true '@rollup/rollup-linux-loong64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-loong64-gnu@4.57.1': - optional: true - '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-loong64-musl@4.57.1': - optional: true - '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true '@rollup/rollup-linux-ppc64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.57.1': - optional: true - '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-ppc64-musl@4.57.1': - optional: true - '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true '@rollup/rollup-linux-riscv64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.57.1': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true '@rollup/rollup-linux-riscv64-musl@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-musl@4.57.1': - optional: true - '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true '@rollup/rollup-linux-s390x-gnu@4.53.3': optional: true - '@rollup/rollup-linux-s390x-gnu@4.57.1': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true '@rollup/rollup-linux-x64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-gnu@4.57.1': - optional: true - '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true '@rollup/rollup-linux-x64-musl@4.53.3': optional: true - '@rollup/rollup-linux-x64-musl@4.57.1': - optional: true - '@rollup/rollup-linux-x64-musl@4.59.0': optional: true - '@rollup/rollup-openbsd-x64@4.57.1': - optional: true - '@rollup/rollup-openbsd-x64@4.59.0': optional: true '@rollup/rollup-openharmony-arm64@4.53.3': optional: true - '@rollup/rollup-openharmony-arm64@4.57.1': - optional: true - '@rollup/rollup-openharmony-arm64@4.59.0': optional: true '@rollup/rollup-win32-arm64-msvc@4.53.3': optional: true - '@rollup/rollup-win32-arm64-msvc@4.57.1': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.59.0': optional: true '@rollup/rollup-win32-ia32-msvc@4.53.3': optional: true - '@rollup/rollup-win32-ia32-msvc@4.57.1': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.59.0': optional: true '@rollup/rollup-win32-x64-gnu@4.53.3': optional: true - '@rollup/rollup-win32-x64-gnu@4.57.1': - optional: true - '@rollup/rollup-win32-x64-gnu@4.59.0': optional: true '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true - '@rollup/rollup-win32-x64-msvc@4.57.1': - optional: true - '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true '@rtsao/scc@1.1.0': {} - '@rushstack/node-core-library@5.14.0(@types/node@25.4.0)': + '@rushstack/node-core-library@5.14.0(@types/node@25.5.0)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -9433,7 +9260,7 @@ snapshots: resolve: 1.22.11 semver: 7.5.4 optionalDependencies: - '@types/node': 25.4.0 + '@types/node': 25.5.0 optional: true '@rushstack/rig-package@0.5.3': @@ -9442,17 +9269,17 @@ snapshots: strip-json-comments: 3.1.1 optional: true - '@rushstack/terminal@0.15.4(@types/node@25.4.0)': + '@rushstack/terminal@0.15.4(@types/node@25.5.0)': dependencies: - '@rushstack/node-core-library': 5.14.0(@types/node@25.4.0) + '@rushstack/node-core-library': 5.14.0(@types/node@25.5.0) supports-color: 8.1.1 optionalDependencies: - '@types/node': 25.4.0 + '@types/node': 25.5.0 optional: true - '@rushstack/ts-command-line@5.0.2(@types/node@25.4.0)': + '@rushstack/ts-command-line@5.0.2(@types/node@25.5.0)': dependencies: - '@rushstack/terminal': 0.15.4(@types/node@25.4.0) + '@rushstack/terminal': 0.15.4(@types/node@25.5.0) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -9460,6 +9287,10 @@ snapshots: - '@types/node' optional: true + '@simple-libs/child-process-utils@1.0.2': + dependencies: + '@simple-libs/stream-utils': 1.2.0 + '@simple-libs/stream-utils@1.2.0': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -9468,68 +9299,68 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) obug: 2.1.1 svelte: 5.53.9 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 svelte: 5.53.9 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vitefu: 1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) - '@swc/core-darwin-arm64@1.15.11': + '@swc/core-darwin-arm64@1.15.18': optional: true - '@swc/core-darwin-x64@1.15.11': + '@swc/core-darwin-x64@1.15.18': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.11': + '@swc/core-linux-arm-gnueabihf@1.15.18': optional: true - '@swc/core-linux-arm64-gnu@1.15.11': + '@swc/core-linux-arm64-gnu@1.15.18': optional: true - '@swc/core-linux-arm64-musl@1.15.11': + '@swc/core-linux-arm64-musl@1.15.18': optional: true - '@swc/core-linux-x64-gnu@1.15.11': + '@swc/core-linux-x64-gnu@1.15.18': optional: true - '@swc/core-linux-x64-musl@1.15.11': + '@swc/core-linux-x64-musl@1.15.18': optional: true - '@swc/core-win32-arm64-msvc@1.15.11': + '@swc/core-win32-arm64-msvc@1.15.18': optional: true - '@swc/core-win32-ia32-msvc@1.15.11': + '@swc/core-win32-ia32-msvc@1.15.18': optional: true - '@swc/core-win32-x64-msvc@1.15.11': + '@swc/core-win32-x64-msvc@1.15.18': optional: true - '@swc/core@1.15.11': + '@swc/core@1.15.18': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.25 optionalDependencies: - '@swc/core-darwin-arm64': 1.15.11 - '@swc/core-darwin-x64': 1.15.11 - '@swc/core-linux-arm-gnueabihf': 1.15.11 - '@swc/core-linux-arm64-gnu': 1.15.11 - '@swc/core-linux-arm64-musl': 1.15.11 - '@swc/core-linux-x64-gnu': 1.15.11 - '@swc/core-linux-x64-musl': 1.15.11 - '@swc/core-win32-arm64-msvc': 1.15.11 - '@swc/core-win32-ia32-msvc': 1.15.11 - '@swc/core-win32-x64-msvc': 1.15.11 + '@swc/core-darwin-arm64': 1.15.18 + '@swc/core-darwin-x64': 1.15.18 + '@swc/core-linux-arm-gnueabihf': 1.15.18 + '@swc/core-linux-arm64-gnu': 1.15.18 + '@swc/core-linux-arm64-musl': 1.15.18 + '@swc/core-linux-x64-gnu': 1.15.18 + '@swc/core-linux-x64-musl': 1.15.18 + '@swc/core-win32-arm64-msvc': 1.15.18 + '@swc/core-win32-ia32-msvc': 1.15.18 + '@swc/core-win32-x64-msvc': 1.15.18 '@swc/counter@0.1.3': {} @@ -9720,7 +9551,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 25.4.0 + '@types/node': 25.5.0 '@types/hast@3.0.4': dependencies: @@ -9746,7 +9577,7 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@25.4.0': + '@types/node@25.5.0': dependencies: undici-types: 7.18.2 @@ -9778,20 +9609,20 @@ snapshots: '@types/vfile@3.0.2': dependencies: - '@types/node': 25.4.0 + '@types/node': 25.5.0 '@types/unist': 2.0.11 '@types/vfile-message': 2.0.0 '@types/which@3.0.4': {} - '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/type-utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/type-utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 eslint: 9.39.3(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -9800,41 +9631,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3 eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) - '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.57.0': + '@typescript-eslint/scope-manager@8.57.1': dependencies: - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 - '@typescript-eslint/tsconfig-utils@8.57.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.3(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) @@ -9842,14 +9673,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.57.0': {} + '@typescript-eslint/types@8.57.1': {} - '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.57.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.4 @@ -9859,20 +9690,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.57.0': + '@typescript-eslint/visitor-keys@8.57.1': dependencies: - '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/types': 8.57.1 eslint-visitor-keys: 5.0.1 '@unrs/resolver-binding-android-arm-eabi@1.9.2': @@ -9939,11 +9770,11 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@vitejs/plugin-react-swc@4.2.3(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react-swc@4.3.0(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@rolldown/pluginutils': 1.0.0-rc.2 - '@swc/core': 1.15.11 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + '@rolldown/pluginutils': 1.0.0-rc.7 + '@swc/core': 1.15.18 + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@swc/helpers' @@ -10032,7 +9863,7 @@ snapshots: ansi-styles@6.2.3: {} - antd@6.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + antd@6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@ant-design/colors': 8.0.1 '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -10040,7 +9871,7 @@ snapshots: '@ant-design/fast-color': 3.0.1 '@ant-design/icons': 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/react-slick': 2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/cascader': 1.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/checkbox': 2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/collapse': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -10048,7 +9879,7 @@ snapshots: '@rc-component/dialog': 1.8.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/drawer': 1.4.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/dropdown': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/form': 1.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/form': 1.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/image': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/input': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/input-number': 1.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -10058,13 +9889,13 @@ snapshots: '@rc-component/mutate-observer': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/notification': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/pagination': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/picker': 1.9.0(dayjs@1.11.19)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/picker': 1.9.1(dayjs@1.11.20)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/progress': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/qrcode': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/rate': 1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/segmented': 1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/select': 1.6.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/select': 1.6.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/slider': 1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/steps': 1.2.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/switch': 1.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -10073,13 +9904,13 @@ snapshots: '@rc-component/textarea': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/tooltip': 1.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/tour': 2.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/tree': 1.2.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/tree': 1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/tree-select': 1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/upload': 1.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 - dayjs: 1.11.19 + dayjs: 1.11.20 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) scroll-into-view-if-needed: 3.1.0 @@ -10560,9 +10391,9 @@ snapshots: convert-source-map@2.0.0: {} - copy-anything@2.0.6: + copy-anything@3.0.5: dependencies: - is-what: 3.14.1 + is-what: 4.1.16 copy-descriptor@0.1.1: {} @@ -10574,9 +10405,9 @@ snapshots: dependencies: layout-base: 2.0.1 - cosmiconfig-typescript-loader@6.2.0(@types/node@25.4.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.2.0(@types/node@25.5.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 25.4.0 + '@types/node': 25.5.0 cosmiconfig: 9.0.1(typescript@5.9.3) jiti: 2.6.1 typescript: 5.9.3 @@ -10828,8 +10659,6 @@ snapshots: damerau-levenshtein@1.0.8: {} - dargs@8.1.0: {} - data-uri-to-buffer@4.0.1: {} data-view-buffer@1.0.2: @@ -10852,7 +10681,7 @@ snapshots: dataloader@1.4.0: {} - dayjs@1.11.19: {} + dayjs@1.11.20: {} debug@2.6.9: dependencies: @@ -11432,22 +11261,22 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -11458,7 +11287,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.3(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11470,7 +11299,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -11546,7 +11375,7 @@ snapshots: dependencies: eslint: 9.39.3(jiti@2.6.1) - eslint-plugin-svelte@3.15.1(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.9)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.4.0)(typescript@5.9.3)): + eslint-plugin-svelte@3.15.2(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.9)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) '@jridgewell/sourcemap-codec': 1.5.5 @@ -11555,7 +11384,7 @@ snapshots: globals: 16.5.0 known-css-properties: 0.37.0 postcss: 8.5.8 - postcss-load-config: 3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.4.0)(typescript@5.9.3)) + postcss-load-config: 3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)) postcss-safe-parser: 7.0.1(postcss@8.5.8) semver: 7.7.4 svelte-eslint-parser: 1.6.0(svelte@5.53.9) @@ -11926,11 +11755,13 @@ snapshots: git-hooks-list@4.2.1: {} - git-raw-commits@4.0.0: + git-raw-commits@5.0.1(conventional-commits-parser@6.3.0): dependencies: - dargs: 8.1.0 - meow: 12.1.1 - split2: 4.2.0 + '@conventional-changelog/git-client': 2.6.0(conventional-commits-parser@6.3.0) + meow: 13.2.0 + transitivePeerDependencies: + - conventional-commits-filter + - conventional-commits-parser github-slugger@2.0.0: {} @@ -12441,7 +12272,7 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 - is-what@3.14.1: {} + is-what@4.1.16: {} is-whitespace-character@1.0.4: {} @@ -12599,18 +12430,17 @@ snapshots: layout-base@2.0.1: {} - less@4.5.1: + less@4.6.4: dependencies: - copy-anything: 2.0.6 + copy-anything: 3.0.5 parse-node-version: 1.0.1 - tslib: 2.8.1 optionalDependencies: errno: 0.1.8 graceful-fs: 4.2.11 image-size: 0.5.5 make-dir: 2.1.0 mime: 1.6.0 - needle: 3.3.1 + needle: 3.5.0 source-map: 0.6.1 leven@2.1.0: {} @@ -12675,13 +12505,13 @@ snapshots: lines-and-columns@1.2.4: {} - lint-staged@16.3.2: + lint-staged@16.4.0: dependencies: commander: 14.0.3 listr2: 9.0.5 - micromatch: 4.0.8 + picomatch: 4.0.3 string-argv: 0.3.2 - tinyexec: 1.0.2 + tinyexec: 1.0.4 yaml: 2.8.2 listr2@9.0.5: @@ -12864,8 +12694,6 @@ snapshots: memorystream@0.3.1: {} - meow@12.1.1: {} - meow@13.2.0: {} meow@14.1.0: {} @@ -12897,7 +12725,7 @@ snapshots: d3: 7.9.0 d3-sankey: 0.12.3 dagre-d3-es: 7.0.14 - dayjs: 1.11.19 + dayjs: 1.11.20 dompurify: 3.3.2 katex: 0.16.38 khroma: 2.1.0 @@ -13032,10 +12860,10 @@ snapshots: natural-compare@1.4.0: {} - needle@3.3.1: + needle@3.5.0: dependencies: iconv-lite: 0.6.3 - sax: 1.4.4 + sax: 1.6.0 optional: true next-tick@1.1.0: {} @@ -13331,13 +13159,13 @@ snapshots: dependencies: htmlparser2: 3.10.1 postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): dependencies: '@babel/core': 7.29.0 postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) transitivePeerDependencies: - supports-color @@ -13349,13 +13177,13 @@ snapshots: dependencies: postcss: 8.5.8 - postcss-load-config@3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.4.0)(typescript@5.9.3)): + postcss-load-config@3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.5.8 - ts-node: 10.9.2(@swc/core@1.15.11)(@types/node@25.4.0)(typescript@5.9.3) + ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3) postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2): dependencies: @@ -13369,7 +13197,7 @@ snapshots: postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): dependencies: postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) remark: 10.0.1 unist-util-find-all-after: 1.0.5 @@ -13425,7 +13253,7 @@ snapshots: lodash: 4.17.21 postcss: 7.0.39 - postcss-syntax@0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39): + postcss-syntax@0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39): dependencies: postcss: 7.0.39 optionalDependencies: @@ -13586,7 +13414,7 @@ snapshots: react-syntax-highlighter@16.1.1(react@19.2.4): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 highlight.js: 10.7.3 highlightjs-vue: 1.0.0 lowlight: 1.20.0 @@ -13788,37 +13616,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.53.3 fsevents: 2.3.3 - rollup@4.57.1: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.57.1 - '@rollup/rollup-android-arm64': 4.57.1 - '@rollup/rollup-darwin-arm64': 4.57.1 - '@rollup/rollup-darwin-x64': 4.57.1 - '@rollup/rollup-freebsd-arm64': 4.57.1 - '@rollup/rollup-freebsd-x64': 4.57.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 - '@rollup/rollup-linux-arm-musleabihf': 4.57.1 - '@rollup/rollup-linux-arm64-gnu': 4.57.1 - '@rollup/rollup-linux-arm64-musl': 4.57.1 - '@rollup/rollup-linux-loong64-gnu': 4.57.1 - '@rollup/rollup-linux-loong64-musl': 4.57.1 - '@rollup/rollup-linux-ppc64-gnu': 4.57.1 - '@rollup/rollup-linux-ppc64-musl': 4.57.1 - '@rollup/rollup-linux-riscv64-gnu': 4.57.1 - '@rollup/rollup-linux-riscv64-musl': 4.57.1 - '@rollup/rollup-linux-s390x-gnu': 4.57.1 - '@rollup/rollup-linux-x64-gnu': 4.57.1 - '@rollup/rollup-linux-x64-musl': 4.57.1 - '@rollup/rollup-openbsd-x64': 4.57.1 - '@rollup/rollup-openharmony-arm64': 4.57.1 - '@rollup/rollup-win32-arm64-msvc': 4.57.1 - '@rollup/rollup-win32-ia32-msvc': 4.57.1 - '@rollup/rollup-win32-x64-gnu': 4.57.1 - '@rollup/rollup-win32-x64-msvc': 4.57.1 - fsevents: 2.3.3 - rollup@4.59.0: dependencies: '@types/estree': 1.0.8 @@ -13849,7 +13646,6 @@ snapshots: '@rollup/rollup-win32-x64-gnu': 4.59.0 '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 - optional: true roughjs@4.6.6: dependencies: @@ -13916,6 +13712,9 @@ snapshots: sax@1.4.4: {} + sax@1.6.0: + optional: true + scheduler@0.27.0: {} scroll-into-view-if-needed@3.1.0: @@ -14129,8 +13928,6 @@ snapshots: dependencies: extend-shallow: 3.0.2 - split2@4.2.0: {} - sprintf-js@1.0.3: {} stable-hash-x@0.2.0: {} @@ -14301,7 +14098,7 @@ snapshots: postcss-sorting: 4.1.0 stylelint: 9.10.1 - stylelint-order@8.0.0(stylelint@17.4.0(typescript@5.9.3)): + stylelint-order@8.1.1(stylelint@17.4.0(typescript@5.9.3)): dependencies: postcss: 8.5.8 postcss-sorting: 10.0.0(postcss@8.5.8) @@ -14394,7 +14191,7 @@ snapshots: postcss-sass: 0.3.5 postcss-scss: 2.1.1 postcss-selector-parser: 3.1.2 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) postcss-value-parser: 3.3.1 resolve-from: 4.0.0 signal-exit: 3.0.7 @@ -14495,13 +14292,13 @@ snapshots: svelte: 5.53.9 tiny-glob: 0.2.9 - svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.5.1)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.53.9)(typescript@5.9.3): + svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.53.9)(typescript@5.9.3): dependencies: svelte: 5.53.9 optionalDependencies: '@babel/core': 7.29.0 coffeescript: 2.7.0 - less: 4.5.1 + less: 4.6.4 postcss: 8.5.8 postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) pug: 3.0.3 @@ -14583,6 +14380,8 @@ snapshots: tinyexec@1.0.2: {} + tinyexec@1.0.4: {} + tinyglobby@0.2.14: dependencies: fdir: 6.4.4(picomatch@4.0.2) @@ -14635,7 +14434,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@swc/core@1.15.11)(@types/node@18.19.130)(typescript@5.5.4): + ts-node@10.9.2(@swc/core@1.15.18)(@types/node@18.19.130)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -14653,16 +14452,16 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.15.11 + '@swc/core': 1.15.18 - ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.4.0)(typescript@5.9.3): + ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 25.4.0 + '@types/node': 25.5.0 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -14673,7 +14472,7 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.15.11 + '@swc/core': 1.15.18 optional: true tsconfig-paths@3.15.0: @@ -14685,7 +14484,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.4.0))(@swc/core@1.15.11)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): + tsup@8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.5.0))(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): dependencies: bundle-require: 5.1.0(esbuild@0.27.0) cac: 6.7.14 @@ -14705,8 +14504,8 @@ snapshots: tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: - '@microsoft/api-extractor': 7.52.10(@types/node@25.4.0) - '@swc/core': 1.15.11 + '@microsoft/api-extractor': 7.52.10(@types/node@25.5.0) + '@swc/core': 1.15.18 postcss: 8.5.8 typescript: 5.9.3 transitivePeerDependencies: @@ -14763,25 +14562,25 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript-json-schema@0.67.1(@swc/core@1.15.11): + typescript-json-schema@0.67.1(@swc/core@1.15.18): dependencies: '@types/json-schema': 7.0.15 '@types/node': 18.19.130 glob: 7.2.3 path-equal: 1.2.5 safe-stable-stringify: 2.5.0 - ts-node: 10.9.2(@swc/core@1.15.11)(@types/node@18.19.130)(typescript@5.5.4) + ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@18.19.130)(typescript@5.5.4) typescript: 5.5.4 vm2: 3.10.4 yargs: 17.7.2 @@ -14955,19 +14754,19 @@ snapshots: unist-util-stringify-position: 1.1.2 vfile-message: 1.1.1 - vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.8 - rollup: 4.57.1 + rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 18.19.130 fsevents: 2.3.3 jiti: 2.6.1 - less: 4.5.1 + less: 4.6.4 lightningcss: 1.31.1 sass: 1.97.3 stylus: 0.64.0 @@ -14976,9 +14775,9 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitefu@1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vitefu@1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): optionalDependencies: - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vm2@3.10.4: dependencies: @@ -15004,7 +14803,7 @@ snapshots: vscode-uri@3.1.0: {} - wavesurfer.js@7.12.1: {} + wavesurfer.js@7.12.4: {} web-streams-polyfill@3.3.3: {} From d659bffc3c7590064144ed54fd6f55c357d3e505 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Thu, 19 Mar 2026 19:41:19 +0800 Subject: [PATCH 12/31] refactor(antdx): new components folder & code-highlighter --- .../components/antdx/__init__.py | 4 + .../antdx/code_highlighter/__init__.py | 70 ++++++++++ .../components/antdx/components.py | 4 + .../components/antdx/folder/__init__.py | 113 ++++++++++++++++ .../antdx/folder/directory_icon/__init__.py | 60 +++++++++ .../antdx/folder/tree_node/__init__.py | 62 +++++++++ frontend/antdx/code-highlighter/Index.svelte | 64 +++++++++ .../code-highlighter/code-highlighter.tsx | 53 ++++++++ .../antdx/code-highlighter/gradio.config.js | 3 + frontend/antdx/code-highlighter/package.json | 14 ++ frontend/antdx/folder/Index.svelte | 82 ++++++++++++ frontend/antdx/folder/context.ts | 15 +++ .../antdx/folder/directory-icon/Index.svelte | 78 +++++++++++ .../directory-icon/folder.directory-icon.tsx | 13 ++ .../folder/directory-icon/gradio.config.js | 3 + .../antdx/folder/directory-icon/package.json | 14 ++ frontend/antdx/folder/folder.tsx | 122 ++++++++++++++++++ frontend/antdx/folder/gradio.config.js | 3 + frontend/antdx/folder/package.json | 14 ++ frontend/antdx/folder/tree-node/Index.svelte | 70 ++++++++++ .../folder/tree-node/folder.tree-node.tsx | 21 +++ .../antdx/folder/tree-node/gradio.config.js | 3 + frontend/antdx/folder/tree-node/package.json | 14 ++ frontend/antdx/sender/Index.svelte | 5 +- frontend/antdx/welcome/Index.svelte | 10 +- frontend/fixtures.d.ts | 2 + frontend/package.json | 2 + frontend/pro/multimodal-input/Index.svelte | 2 +- .../internal/Bridge.svelte.ts | 26 +++- .../svelte-preprocess-react/react-slot.tsx | 20 +-- pnpm-lock.yaml | 13 ++ 31 files changed, 955 insertions(+), 24 deletions(-) create mode 100644 backend/modelscope_studio/components/antdx/code_highlighter/__init__.py create mode 100644 backend/modelscope_studio/components/antdx/folder/__init__.py create mode 100644 backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py create mode 100644 backend/modelscope_studio/components/antdx/folder/tree_node/__init__.py create mode 100644 frontend/antdx/code-highlighter/Index.svelte create mode 100644 frontend/antdx/code-highlighter/code-highlighter.tsx create mode 100644 frontend/antdx/code-highlighter/gradio.config.js create mode 100644 frontend/antdx/code-highlighter/package.json create mode 100644 frontend/antdx/folder/Index.svelte create mode 100644 frontend/antdx/folder/context.ts create mode 100644 frontend/antdx/folder/directory-icon/Index.svelte create mode 100644 frontend/antdx/folder/directory-icon/folder.directory-icon.tsx create mode 100644 frontend/antdx/folder/directory-icon/gradio.config.js create mode 100644 frontend/antdx/folder/directory-icon/package.json create mode 100644 frontend/antdx/folder/folder.tsx create mode 100644 frontend/antdx/folder/gradio.config.js create mode 100644 frontend/antdx/folder/package.json create mode 100644 frontend/antdx/folder/tree-node/Index.svelte create mode 100644 frontend/antdx/folder/tree-node/folder.tree-node.tsx create mode 100644 frontend/antdx/folder/tree-node/gradio.config.js create mode 100644 frontend/antdx/folder/tree-node/package.json diff --git a/backend/modelscope_studio/components/antdx/__init__.py b/backend/modelscope_studio/components/antdx/__init__.py index 7004b5ef..49c169b7 100644 --- a/backend/modelscope_studio/components/antdx/__init__.py +++ b/backend/modelscope_studio/components/antdx/__init__.py @@ -15,8 +15,12 @@ from .bubble.list.role import AntdXBubbleListRole as BubbleListRole from .bubble.divider import AntdXBubbleDivider as BubbleDivider from .bubble.system import AntdXBubbleSystem as BubbleSystem +from .code_highlighter import AntdXCodeHighlighter as CodeHighlighter from .conversations import AntdXConversations as Conversations from .conversations.item import AntdXConversationsItem as ConversationsItem +from .folder import AntdXFolder as Folder +from .folder.tree_node import AntdXFolderTreeNode as FolderTreeNode +from .folder.directory_icon import AntdXFolderDirectoryIcon as FolderDirectoryIcon from .prompts import AntdXPrompts as Prompts from .prompts.item import AntdXPromptsItem as PromptsItem from .sender import AntdXSender as Sender diff --git a/backend/modelscope_studio/components/antdx/code_highlighter/__init__.py b/backend/modelscope_studio/components/antdx/code_highlighter/__init__.py new file mode 100644 index 00000000..ad1f354f --- /dev/null +++ b/backend/modelscope_studio/components/antdx/code_highlighter/__init__.py @@ -0,0 +1,70 @@ +from __future__ import annotations + +from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXCodeHighlighter(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/code-highlighter + """ + EVENTS = [] + + # supported slots + SLOTS = ['header'] + + def __init__( + self, + value: str | None = None, + *, + lang: str | None = None, + header: str | bool | None = None, + highlight_props: dict | None = None, + prism_light_mode: bool | None = None, + styles: dict | str | None = None, + class_names: dict | str | None = None, + additional_props: dict | None = None, + root_class_name: str | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.styles = styles + self.class_names = class_names + self.root_class_name = root_class_name + self.value = value + self.lang = lang + self.header = header + self.highlight_props = highlight_props + self.prism_light_mode = prism_light_mode + + FRONTEND_DIR = resolve_frontend_dir("code-highlighter", type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> None: + return None + + def example_value(self) -> None: + return None diff --git a/backend/modelscope_studio/components/antdx/components.py b/backend/modelscope_studio/components/antdx/components.py index a608ede0..411529a7 100644 --- a/backend/modelscope_studio/components/antdx/components.py +++ b/backend/modelscope_studio/components/antdx/components.py @@ -14,8 +14,12 @@ from .bubble.list.role import AntdXBubbleListRole from .bubble.divider import AntdXBubbleDivider from .bubble.system import AntdXBubbleSystem +from .code_highlighter import AntdXCodeHighlighter from .conversations import AntdXConversations from .conversations.item import AntdXConversationsItem +from .folder import AntdXFolder +from .folder.tree_node import AntdXFolderTreeNode +from .folder.directory_icon import AntdXFolderDirectoryIcon from .prompts import AntdXPrompts from .prompts.item import AntdXPromptsItem from .sender import AntdXSender diff --git a/backend/modelscope_studio/components/antdx/folder/__init__.py b/backend/modelscope_studio/components/antdx/folder/__init__.py new file mode 100644 index 00000000..c9397f0b --- /dev/null +++ b/backend/modelscope_studio/components/antdx/folder/__init__.py @@ -0,0 +1,113 @@ +from __future__ import annotations + +from typing import Any + +from gradio.events import EventListener + +from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir +from .tree_node import AntdXFolderTreeNode +from .directory_icon import AntdXFolderDirectoryIcon + + +class AntdXFolder(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/folder + """ + TreeNode = AntdXFolderTreeNode + DirectoryIcon = AntdXFolderDirectoryIcon + + EVENTS = [ + EventListener("file_click", + callback=lambda block: block._internal.update( + bind_fileClick_event=True)), + EventListener("folder_click", + callback=lambda block: block._internal.update( + bind_folderClick_event=True)), + EventListener("selected_file_change", + callback=lambda block: block._internal.update( + bind_selectedFileChange_event=True)), + EventListener("expanded_paths_change", + callback=lambda block: block._internal.update( + bind_expandedPathsChange_event=True)), + EventListener("file_content_service_load_file_content", + callback=lambda block: block._internal.update( + bind_fileContentService_loadFileContent_event=True)), + ] + + # supported slots + SLOTS = [ + 'emptyRender', 'previewRender', 'directoryTitle', 'previewTitle', + 'treeData', 'directoryIcons' + ] + + def __init__( + self, + additional_props: dict | None = None, + *, + tree_data: list[dict] | None = None, + selectable: bool | None = None, + selected_file: list[str] | None = None, + default_selected_file: list[str] | None = None, + directory_tree_width: int | float | str | None = None, + empty_render: str | None = None, + preview_render: str | None = None, + expanded_paths: list[str] | None = None, + default_expanded_paths: list[str] | None = None, + default_expand_all: bool | None = None, + directory_title: str | None = None, + preview_title: str | None = None, + directory_icons: dict | None = None, + root_class_name: str | None = None, + class_names: dict | str | None = None, + styles: dict | str | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.class_names = class_names + self.styles = styles + self.additional_props = additional_props + self.root_class_name = root_class_name + self.tree_data = tree_data + self.selectable = selectable + self.selected_file = selected_file + self.default_selected_file = default_selected_file + self.directory_tree_width = directory_tree_width + self.empty_render = empty_render + self.preview_render = preview_render + self.expanded_paths = expanded_paths + self.default_expanded_paths = default_expanded_paths + self.default_expand_all = default_expand_all + self.directory_title = directory_title + self.preview_title = preview_title + self.directory_icons = directory_icons + + FRONTEND_DIR = resolve_frontend_dir("folder", type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None | None) -> None: + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py b/backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py new file mode 100644 index 00000000..011fd216 --- /dev/null +++ b/backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +from typing import Any, Literal + +from .....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXFolderDirectoryIcon(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/folder + """ + + EVENTS = [] + + # supported slots + SLOTS = [] + + def __init__( + self, + extension: str | Literal['directory'], + *, + additional_props: dict | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.extension = extension + self.additional_props = additional_props + + FRONTEND_DIR = resolve_frontend_dir("folder", + "directory-icon", + type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/backend/modelscope_studio/components/antdx/folder/tree_node/__init__.py b/backend/modelscope_studio/components/antdx/folder/tree_node/__init__.py new file mode 100644 index 00000000..d95c2a04 --- /dev/null +++ b/backend/modelscope_studio/components/antdx/folder/tree_node/__init__.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +from typing import Any + +from .....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXFolderTreeNode(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/folder + """ + + EVENTS = [] + + # supported slots + SLOTS = [] + + def __init__( + self, + *, + title: str | None = None, + path: str | None = None, + content: str | None = None, + additional_props: dict | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.title = title + self.additional_props = additional_props + self.path = path + self.content = content + + FRONTEND_DIR = resolve_frontend_dir("folder", "tree-node", type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/frontend/antdx/code-highlighter/Index.svelte b/frontend/antdx/code-highlighter/Index.svelte new file mode 100644 index 00000000..ad63df6d --- /dev/null +++ b/frontend/antdx/code-highlighter/Index.svelte @@ -0,0 +1,64 @@ + + +{#if proceedProps.visible} + {#await AwaitedCodeHighlighter then CodeHighlighter} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/code-highlighter/code-highlighter.tsx b/frontend/antdx/code-highlighter/code-highlighter.tsx new file mode 100644 index 00000000..dfaa74d4 --- /dev/null +++ b/frontend/antdx/code-highlighter/code-highlighter.tsx @@ -0,0 +1,53 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import { + CodeHighlighter as XCodeHighlighter, + type CodeHighlighterProps, +} from '@ant-design/x'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import { + materialDark, + materialLight, +} from 'react-syntax-highlighter/dist/esm/styles/prism'; + +const customDarkStyle = { + ...materialDark, + 'pre[class*="language-"]': { + ...materialDark['pre[class*="language-"]'], + margin: 0, + }, +}; + +const customLightStyle = { + ...materialLight, + 'pre[class*="language-"]': { + ...materialLight['pre[class*="language-"]'], + margin: 0, + }, +}; + +export const CodeHighlighter = sveltify< + CodeHighlighterProps & { + value?: string; + themeMode: string; + }, + ['header'] +>(({ slots, children, value, themeMode, ...props }) => { + return ( + <> +
{children}
+ : props.header} + > + {value || ''} + + + ); +}); + +export default CodeHighlighter; diff --git a/frontend/antdx/code-highlighter/gradio.config.js b/frontend/antdx/code-highlighter/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antdx/code-highlighter/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/code-highlighter/package.json b/frontend/antdx/code-highlighter/package.json new file mode 100644 index 00000000..ff09a35a --- /dev/null +++ b/frontend/antdx/code-highlighter/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-code-highlighter", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/folder/Index.svelte b/frontend/antdx/folder/Index.svelte new file mode 100644 index 00000000..1fcd9a76 --- /dev/null +++ b/frontend/antdx/folder/Index.svelte @@ -0,0 +1,82 @@ + + +{#if proceedProps.visible} + {#await AwaitedFolder then Folder} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/folder/context.ts b/frontend/antdx/folder/context.ts new file mode 100644 index 00000000..bda4c01b --- /dev/null +++ b/frontend/antdx/folder/context.ts @@ -0,0 +1,15 @@ +import { createItemsContext } from '@utils/createItemsContext'; + +export const { + withItemsContextProvider: withTreeNodeItemsContextProvider, + useItems: useTreeNodeItems, + ItemHandler: TreeNodeItemHandler, +} = createItemsContext('antdx-folder-tree-nodes'); + +export const { + withItemsContextProvider: withDirectoryIconItemsContextProvider, + useItems: useDirectoryIconItems, + ItemHandler: DirectoryIconItemHandler, +} = createItemsContext('antdx-folder-directory-icons'); + +export * from '@utils/createItemsContext'; diff --git a/frontend/antdx/folder/directory-icon/Index.svelte b/frontend/antdx/folder/directory-icon/Index.svelte new file mode 100644 index 00000000..4fccd463 --- /dev/null +++ b/frontend/antdx/folder/directory-icon/Index.svelte @@ -0,0 +1,78 @@ + + +{#await AwaitedFolderDirectoryIcon then FolderDirectoryIcon} + + {#if proceedProps.visible} + + {@render children?.()} + + {/if} + +{/await} diff --git a/frontend/antdx/folder/directory-icon/folder.directory-icon.tsx b/frontend/antdx/folder/directory-icon/folder.directory-icon.tsx new file mode 100644 index 00000000..15ad47ff --- /dev/null +++ b/frontend/antdx/folder/directory-icon/folder.directory-icon.tsx @@ -0,0 +1,13 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import type { TreeNodeProps } from 'antd'; + +import { DirectoryIconItemHandler, type ItemHandlerProps } from '../context'; + +export const FolderDirectoryIcon = sveltify( + (props) => { + return ; + } +); + +export default FolderDirectoryIcon; diff --git a/frontend/antdx/folder/directory-icon/gradio.config.js b/frontend/antdx/folder/directory-icon/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/folder/directory-icon/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/folder/directory-icon/package.json b/frontend/antdx/folder/directory-icon/package.json new file mode 100644 index 00000000..46a2777d --- /dev/null +++ b/frontend/antdx/folder/directory-icon/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-folder.directory-icon", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/folder/folder.tsx b/frontend/antdx/folder/folder.tsx new file mode 100644 index 00000000..3fa9a688 --- /dev/null +++ b/frontend/antdx/folder/folder.tsx @@ -0,0 +1,122 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React, { useMemo } from 'react'; +import { Folder as XFolder, type FolderProps } from '@ant-design/x'; +import { useFunction } from '@utils/hooks/useFunction'; +import { renderItems } from '@utils/renderItems'; +import { renderParamsSlot } from '@utils/renderParamsSlot'; + +import { + useDirectoryIconItems, + useTreeNodeItems, + withDirectoryIconItemsContextProvider, + withTreeNodeItemsContextProvider, +} from './context'; + +export const Folder = sveltify< + FolderProps & { + children?: React.ReactNode; + fileContentService?: { + onLoadFileContent?: (filePath: string) => Promise; + }; + }, + ['emptyRender', 'previewRender', 'directoryTitle', 'previewTitle'] +>( + withTreeNodeItemsContextProvider( + ['default', 'treeData'], + withDirectoryIconItemsContextProvider( + ['directoryIcons'], + ({ + slots, + children, + previewRender, + previewTitle, + fileContentService, + ...props + }) => { + const { items: treeNodeItems } = + useTreeNodeItems<['default', 'treeData']>(); + const resolvedTreeNodeItems = + treeNodeItems.treeData.length > 0 + ? treeNodeItems.treeData + : treeNodeItems.default; + const { items: directoryIconItems } = + useDirectoryIconItems<['directoryIcons']>(); + const previewRenderFunction = useFunction(previewRender, true); + const previewTitleFunction = useFunction(previewTitle, true); + + return ( + <> +
{children}
+ { + return ( + props.treeData || + renderItems[number]>( + resolvedTreeNodeItems, + { + clone: true, + } + ) + ); + }, [props.treeData, resolvedTreeNodeItems])} + directoryIcons={useMemo(() => { + return ( + props.directoryIcons || + renderItems<{ + extension: string; + children: React.ReactNode; + }>(directoryIconItems.directoryIcons, { + clone: true, + })?.reduce( + (acc, cur) => { + acc[cur.extension] = cur.children; + return acc; + }, + {} as Record + ) + ); + }, [directoryIconItems.directoryIcons, props.directoryIcons])} + emptyRender={ + slots.emptyRender ? ( + + ) : ( + props.emptyRender + ) + } + directoryTitle={ + slots.directoryTitle ? ( + + ) : ( + props.directoryTitle + ) + } + previewTitle={ + slots.previewTitle ? ( + + ) : ( + previewTitleFunction || previewTitle + ) + } + previewRender={ + slots.previewRender + ? renderParamsSlot({ slots, key: 'previewRender' }) + : previewRenderFunction || previewRender + } + /> + + ); + } + ) + ) +); + +export default Folder; diff --git a/frontend/antdx/folder/gradio.config.js b/frontend/antdx/folder/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antdx/folder/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/folder/package.json b/frontend/antdx/folder/package.json new file mode 100644 index 00000000..9de2c53d --- /dev/null +++ b/frontend/antdx/folder/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-folder", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/folder/tree-node/Index.svelte b/frontend/antdx/folder/tree-node/Index.svelte new file mode 100644 index 00000000..50675f91 --- /dev/null +++ b/frontend/antdx/folder/tree-node/Index.svelte @@ -0,0 +1,70 @@ + + +{#await AwaitedFolderTreeNode then FolderTreeNode} + + {#if proceedProps.visible} + {@render children?.()} + {/if} + +{/await} diff --git a/frontend/antdx/folder/tree-node/folder.tree-node.tsx b/frontend/antdx/folder/tree-node/folder.tree-node.tsx new file mode 100644 index 00000000..64f469a0 --- /dev/null +++ b/frontend/antdx/folder/tree-node/folder.tree-node.tsx @@ -0,0 +1,21 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import type { TreeNodeProps } from 'antd'; + +import { type ItemHandlerProps, TreeNodeItemHandler } from '../context'; + +export const FolderTreeNode = sveltify( + (props) => { + return ( + + {...props} + allowedSlots={['default']} + itemChildren={(items) => { + return items.default.length > 0 ? items.default : undefined; + }} + /> + ); + } +); + +export default FolderTreeNode; diff --git a/frontend/antdx/folder/tree-node/gradio.config.js b/frontend/antdx/folder/tree-node/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/folder/tree-node/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/folder/tree-node/package.json b/frontend/antdx/folder/tree-node/package.json new file mode 100644 index 00000000..f0fa2e9d --- /dev/null +++ b/frontend/antdx/folder/tree-node/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-folder.tree-node", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/sender/Index.svelte b/frontend/antdx/sender/Index.svelte index 30f7d4d6..8b9df304 100644 --- a/frontend/antdx/sender/Index.svelte +++ b/frontend/antdx/sender/Index.svelte @@ -24,7 +24,6 @@ _internal: { layout?: boolean; }; - root: string; value?: string; key_press?: any; @@ -43,7 +42,6 @@ elem_id, elem_style, value, - root, ...restProps } = getComponentProps(); return { @@ -57,7 +55,6 @@ elem_classes, elem_style, value, - root, }; }, { @@ -75,7 +72,7 @@ return ( ((await proceedProps.additionalProps.gradio.client.upload( await prepare_files(files), - proceedProps.root + proceedProps.gradio.shared.root )) as FileData[]) || [] ); }; diff --git a/frontend/antdx/welcome/Index.svelte b/frontend/antdx/welcome/Index.svelte index dc96d668..9a4cd503 100644 --- a/frontend/antdx/welcome/Index.svelte +++ b/frontend/antdx/welcome/Index.svelte @@ -17,8 +17,6 @@ _internal: { layout?: boolean; }; - root: string; - proxy_url: string; }>(() => props); const getProceedProps = processProps(() => { @@ -29,8 +27,6 @@ elem_classes, elem_id, elem_style, - root, - proxy_url, ...restProps } = getComponentProps(); return { @@ -43,8 +39,6 @@ elem_id, elem_classes, elem_style, - root, - proxy_url, }; }, {}); const proceedProps = $derived(getProceedProps()); @@ -61,8 +55,8 @@ {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} - rootUrl={proceedProps.root} - apiPrefix={proceedProps.proxy_url} + rootUrl={proceedProps.gradio.shared.root} + apiPrefix={proceedProps.gradio.shared.api_prefix} > {@render children?.()} diff --git a/frontend/fixtures.d.ts b/frontend/fixtures.d.ts index 76dbc766..88da115c 100644 --- a/frontend/fixtures.d.ts +++ b/frontend/fixtures.d.ts @@ -36,6 +36,8 @@ interface Element { _reactElement: React.ReactElement & { props: Record; }; + _effects: (() => void)[]; + _registerEffect: (cb: () => void) => () => void; } declare module '*.svelte' { diff --git a/frontend/package.json b/frontend/package.json index 6a4507be..eb08a248 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,6 +33,7 @@ "prismjs": "^1.30.0", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-syntax-highlighter": "^16.1.1", "svelte": "5.53.9", "svelte-i18n": "^4.0.1", "wavesurfer.js": "^7.12.4" @@ -46,6 +47,7 @@ "@types/prismjs": "^1.26.6", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", + "@types/react-syntax-highlighter": "^15.5.13", "@types/sanitize-html": "^2.16.1", "@vitejs/plugin-react-swc": "^4.3.0", "less": "^4.6.4", diff --git a/frontend/pro/multimodal-input/Index.svelte b/frontend/pro/multimodal-input/Index.svelte index e7610797..ec0f51c8 100644 --- a/frontend/pro/multimodal-input/Index.svelte +++ b/frontend/pro/multimodal-input/Index.svelte @@ -76,7 +76,7 @@ return ( ((await proceedProps.additionalProps.gradio.client.upload( await prepare_files(files), - proceedProps.root + proceedProps.gradio.shared.root )) as FileData[]) || [] ); }; diff --git a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts index 49c17b48..47c16809 100644 --- a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts +++ b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts @@ -54,11 +54,11 @@ const Bridge: React.FC = ({ node, createPortal }) => { $effect.root(() => { $effect(() => { fresh.current = true; - setResult( React.createElement(BridgeInternal, { // read the object when the property of node changes node: $state.snapshot(node) as TreeNode, + createPortal, }) ); @@ -94,7 +94,7 @@ function BridgeInternal({ props: originalNodeProps, } = node; const nodeProps = useMemo(() => { - return patchProps(omitNodeProps(originalNodeProps)); + return $state.snapshot(patchProps(omitNodeProps(originalNodeProps))); }, [originalNodeProps]); let formItemContext = useFormItemContext(); @@ -182,7 +182,6 @@ function BridgeInternal({ }), ]; } - // eslint-disable-next-line react/no-children-prop const element = createElement(BridgeContext, { props, @@ -193,8 +192,29 @@ function BridgeInternal({ if (portalTarget) { // eslint-disable-next-line react-hooks/immutability portalTarget._reactElement = element; + // eslint-disable-next-line react-hooks/immutability + portalTarget._effects = portalTarget._effects || []; + // eslint-disable-next-line react-hooks/immutability + portalTarget._registerEffect = (cb) => { + portalTarget._effects.push(cb); + return () => { + portalTarget._effects = portalTarget._effects.filter((e) => e !== cb); + }; + }; + } + + useEffect(() => { + if (portalTarget) { + portalTarget._effects.forEach((cb) => { + cb(); + }); + } + }, [portalTarget, props]); + + if (portalTarget) { return createPortal(element, portalTarget); } + return null; } export default Bridge; diff --git a/frontend/svelte-preprocess-react/react-slot.tsx b/frontend/svelte-preprocess-react/react-slot.tsx index 07a70d06..ecaff66f 100644 --- a/frontend/svelte-preprocess-react/react-slot.tsx +++ b/frontend/svelte-preprocess-react/react-slot.tsx @@ -12,10 +12,14 @@ export interface ReactSlotProps { className?: string; } -function cloneElementWithEvents(element: HTMLElement) { +function cloneElementWithEvents(element: HTMLElement, render: () => void) { const portals: React.ReactPortal[] = []; const clonedElement = element.cloneNode(false) as HTMLElement; if (element._reactElement) { + const unregister = element._registerEffect(() => { + render(); + unregister(); + }); const resolvedChildren: Array & { originalChildren: React.ReactNode; } = React.Children.toArray(element._reactElement.props.children).map( @@ -30,8 +34,7 @@ function cloneElementWithEvents(element: HTMLElement) { child.props.__slot__ ) { const { portals: childPortals, clonedElement: childClonedElement } = - cloneElementWithEvents(child.props.el); - + cloneElementWithEvents(child.props.el, render); // Child Component return React.cloneElement(child, { ...child.props, @@ -75,7 +78,7 @@ function cloneElementWithEvents(element: HTMLElement) { // element if (child.nodeType === 1) { const { clonedElement: clonedChild, portals: portalsChildren } = - cloneElementWithEvents(child as HTMLElement); + cloneElementWithEvents(child as HTMLElement, render); portals.push(...portalsChildren); clonedElement.appendChild(clonedChild); // clonedElement.replaceChild(clonedChild, clonedElement.children[i]); @@ -112,9 +115,8 @@ export const ReactSlot = forwardRef( if (!ref.current || !slot) { return; } - // the cloned component cannot handle the eventListener + // the cloned component change props let cloned = slot; - function mountElementProps() { let child = cloned as Element; if ( @@ -150,8 +152,10 @@ export const ReactSlot = forwardRef( if (ref.current?.contains(cloned)) { ref.current?.removeChild(cloned); } - - const { portals, clonedElement } = cloneElementWithEvents(slot); + const { portals, clonedElement } = cloneElementWithEvents( + slot, + render + ); cloned = clonedElement; setChildren(portals); cloned.style.display = 'contents'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96c1977c..53194041 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -268,6 +268,9 @@ importers: react-dom: specifier: ^19.2.4 version: 19.2.4(react@19.2.4) + react-syntax-highlighter: + specifier: ^16.1.1 + version: 16.1.1(react@19.2.4) svelte: specifier: 5.53.9 version: 5.53.9 @@ -302,6 +305,9 @@ importers: '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.14) + '@types/react-syntax-highlighter': + specifier: ^15.5.13 + version: 15.5.13 '@types/sanitize-html': specifier: ^2.16.1 version: 2.16.1 @@ -2545,6 +2551,9 @@ packages: peerDependencies: '@types/react': ^19.2.0 + '@types/react-syntax-highlighter@15.5.13': + resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==} + '@types/react@19.2.14': resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} @@ -9589,6 +9598,10 @@ snapshots: dependencies: '@types/react': 19.2.14 + '@types/react-syntax-highlighter@15.5.13': + dependencies: + '@types/react': 19.2.14 + '@types/react@19.2.14': dependencies: csstype: 3.2.3 From ef84796b68a9e60cdc4c9d481eb7cec4f21de078 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Thu, 19 Mar 2026 20:23:11 +0800 Subject: [PATCH 13/31] refactor(antdx): new components mermaid & sources --- .../components/antdx/__init__.py | 3 + .../components/antdx/components.py | 3 + .../components/antdx/mermaid/__init__.py | 74 +++++++++++++++ .../components/antdx/sources/__init__.py | 91 +++++++++++++++++++ .../components/antdx/sources/item/__init__.py | 69 ++++++++++++++ frontend/antdx/mermaid/Index.svelte | 68 ++++++++++++++ frontend/antdx/mermaid/gradio.config.js | 3 + frontend/antdx/mermaid/mermaid.tsx | 86 ++++++++++++++++++ frontend/antdx/mermaid/package.json | 14 +++ frontend/antdx/sources/Index.svelte | 62 +++++++++++++ frontend/antdx/sources/context.ts | 6 ++ frontend/antdx/sources/gradio.config.js | 3 + frontend/antdx/sources/item/Index.svelte | 68 ++++++++++++++ frontend/antdx/sources/item/gradio.config.js | 3 + frontend/antdx/sources/item/package.json | 14 +++ frontend/antdx/sources/item/sources.item.tsx | 13 +++ frontend/antdx/sources/package.json | 14 +++ frontend/antdx/sources/sources.tsx | 41 +++++++++ 18 files changed, 635 insertions(+) create mode 100644 backend/modelscope_studio/components/antdx/mermaid/__init__.py create mode 100644 backend/modelscope_studio/components/antdx/sources/__init__.py create mode 100644 backend/modelscope_studio/components/antdx/sources/item/__init__.py create mode 100644 frontend/antdx/mermaid/Index.svelte create mode 100644 frontend/antdx/mermaid/gradio.config.js create mode 100644 frontend/antdx/mermaid/mermaid.tsx create mode 100644 frontend/antdx/mermaid/package.json create mode 100644 frontend/antdx/sources/Index.svelte create mode 100644 frontend/antdx/sources/context.ts create mode 100644 frontend/antdx/sources/gradio.config.js create mode 100644 frontend/antdx/sources/item/Index.svelte create mode 100644 frontend/antdx/sources/item/gradio.config.js create mode 100644 frontend/antdx/sources/item/package.json create mode 100644 frontend/antdx/sources/item/sources.item.tsx create mode 100644 frontend/antdx/sources/package.json create mode 100644 frontend/antdx/sources/sources.tsx diff --git a/backend/modelscope_studio/components/antdx/__init__.py b/backend/modelscope_studio/components/antdx/__init__.py index 49c169b7..561c3d80 100644 --- a/backend/modelscope_studio/components/antdx/__init__.py +++ b/backend/modelscope_studio/components/antdx/__init__.py @@ -28,10 +28,13 @@ from .sender.switch import AntdXSenderSwitch as SenderSwitch from .suggestion import AntdXSuggestion as Suggestion from .suggestion.item import AntdXSuggestionItem as SuggestionItem +from .sources import AntdXSources as Sources +from .sources.item import AntdXSourcesItem as SourcesItem from .thought_chain import AntdXThoughtChain as ThoughtChain from .thought_chain.item import AntdXThoughtChainItem as ThoughtChainItem from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem as ThoughtChainThoughtChainItem from .think import AntdXThink as Think from .welcome import AntdXWelcome as Welcome +from .mermaid import AntdXMermaid as Mermaid from .notification import AntdXNotification as Notification from .x_provider import AntdXXProvider as XProvider diff --git a/backend/modelscope_studio/components/antdx/components.py b/backend/modelscope_studio/components/antdx/components.py index 411529a7..72aa3bc2 100644 --- a/backend/modelscope_studio/components/antdx/components.py +++ b/backend/modelscope_studio/components/antdx/components.py @@ -25,6 +25,8 @@ from .sender import AntdXSender from .sender.header import AntdXSenderHeader from .sender.switch import AntdXSenderSwitch +from .sources import AntdXSources +from .sources.item import AntdXSourcesItem from .suggestion import AntdXSuggestion from .suggestion.item import AntdXSuggestionItem from .thought_chain import AntdXThoughtChain @@ -32,5 +34,6 @@ from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem from .think import AntdXThink from .welcome import AntdXWelcome +from .mermaid import AntdXMermaid from .notification import AntdXNotification from .x_provider import AntdXXProvider diff --git a/backend/modelscope_studio/components/antdx/mermaid/__init__.py b/backend/modelscope_studio/components/antdx/mermaid/__init__.py new file mode 100644 index 00000000..832ddd79 --- /dev/null +++ b/backend/modelscope_studio/components/antdx/mermaid/__init__.py @@ -0,0 +1,74 @@ +from __future__ import annotations +from gradio.events import EventListener +from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXMermaid(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/mermaid + """ + EVENTS = [ + EventListener("render_type_change", + callback=lambda block: block._internal.update( + bind_renderTypeChange_event=True)), + ] + + # supported slots + SLOTS = ['header', 'actions.customActions'] + + def __init__( + self, + value: str | None = None, + *, + highlight_props: dict | None = None, + config: dict | None = None, + actions: dict | None = None, + prefix_cls: str | None = None, + styles: dict | str | None = None, + class_names: dict | str | None = None, + additional_props: dict | None = None, + root_class_name: str | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.styles = styles + self.class_names = class_names + self.root_class_name = root_class_name + self.value = value + self.highlight_props = highlight_props + self.config = config + self.actions = actions + self.prefix_cls = prefix_cls + + FRONTEND_DIR = resolve_frontend_dir("mermaid", type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> None: + return None + + def example_value(self) -> None: + return None diff --git a/backend/modelscope_studio/components/antdx/sources/__init__.py b/backend/modelscope_studio/components/antdx/sources/__init__.py new file mode 100644 index 00000000..5bcf4f84 --- /dev/null +++ b/backend/modelscope_studio/components/antdx/sources/__init__.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +from typing import Any, Literal + +from gradio.events import EventListener + +from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir +from .item import AntdXSourcesItem + + +class AntdXSources(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/sources + """ + + Item = AntdXSourcesItem + + EVENTS = [ + EventListener("expand", + callback=lambda block: block._internal.update( + bind_expand_event=True)), + EventListener("click", + callback=lambda block: block._internal.update( + bind_click_event=True)), + ] + + # supported slots + SLOTS = ['items'] + + def __init__( + self, + *, + title: str | None = None, + items: list[dict] | None = None, + expand_icon_position: Literal['start', 'end'] | None = None, + default_expanded: bool | None = None, + expanded: bool | None = None, + inline: bool | None = None, + active_key: str | None = None, + popover_overlay_width: str | int | float | None = None, + additional_props: dict | None = None, + styles: dict | str | None = None, + class_names: dict | str | None = None, + root_class_name: str | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.items = items + self.styles = styles + self.class_names = class_names + self.root_class_name = root_class_name + self.title = title + self.expand_icon_position = expand_icon_position + self.default_expanded = default_expanded + self.expanded = expanded + self.inline = inline + self.active_key = active_key + self.popover_overlay_width = popover_overlay_width + + FRONTEND_DIR = resolve_frontend_dir("sources", type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/backend/modelscope_studio/components/antdx/sources/item/__init__.py b/backend/modelscope_studio/components/antdx/sources/item/__init__.py new file mode 100644 index 00000000..c6b35329 --- /dev/null +++ b/backend/modelscope_studio/components/antdx/sources/item/__init__.py @@ -0,0 +1,69 @@ +from __future__ import annotations + +from typing import Any + +from .....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdXSourcesItem(ModelScopeLayoutComponent): + """ + Ant Design X: https://x.ant.design/components/sources + """ + + EVENTS = [] + + # supported slots + SLOTS = ['title', 'icon', 'description'] + + def __init__( + self, + key: str | None = None, + *, + description: str | None = None, + icon: str | None = None, + title: str | None = None, + url: str | None = None, + additional_props: dict | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.description = description + self.icon = icon + self.title = title + self.key = key + self.url = url + + FRONTEND_DIR = resolve_frontend_dir("sources", + "sources-item", + type="antdx") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/frontend/antdx/mermaid/Index.svelte b/frontend/antdx/mermaid/Index.svelte new file mode 100644 index 00000000..8782778e --- /dev/null +++ b/frontend/antdx/mermaid/Index.svelte @@ -0,0 +1,68 @@ + + +{#if proceedProps.visible} + {#await AwaitedMermaid then Mermaid} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/mermaid/gradio.config.js b/frontend/antdx/mermaid/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antdx/mermaid/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/mermaid/mermaid.tsx b/frontend/antdx/mermaid/mermaid.tsx new file mode 100644 index 00000000..a25c5f7c --- /dev/null +++ b/frontend/antdx/mermaid/mermaid.tsx @@ -0,0 +1,86 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React, { useMemo } from 'react'; +import { + materialDark, + materialLight, +} from 'react-syntax-highlighter/dist/esm/styles/prism'; +import { Mermaid as XMermaid, type MermaidProps } from '@ant-design/x'; +import type { ItemType } from '@ant-design/x/es/actions/interface'; +import { renderItems } from '@utils/renderItems'; + +import { + useItems as useActionItems, + withItemsContextProvider as withActionItemsContextProvider, +} from '../actions/context'; + +const customDarkStyle = { + ...materialDark, + 'pre[class*="language-"]': { + ...materialDark['pre[class*="language-"]'], + margin: 0, + }, +}; + +const customLightStyle = { + ...materialLight, + 'pre[class*="language-"]': { + ...materialLight['pre[class*="language-"]'], + margin: 0, + }, +}; + +export const Mermaid = sveltify< + MermaidProps & { + value?: string; + themeMode: string; + }, + ['header', 'actions.customActions'] +>( + withActionItemsContextProvider( + ['actions.customActions'], + ({ slots, children, value, themeMode, actions, config, ...props }) => { + const { + items: { 'actions.customActions': actionItems }, + } = useActionItems<['actions.customActions']>(); + + return ( + <> +
{children}
+ { + return { + theme: themeMode === 'dark' ? 'dark' : 'base', + ...config, + }; + }, [config, themeMode])} + actions={{ + ...actions, + customActions: useMemo(() => { + return ( + actions?.customActions || + renderItems(actionItems, { + clone: true, + }) || + [] + ); + }, [actions?.customActions, actionItems]), + }} + header={ + slots.header ? : props.header + } + > + {value || ''} + + + ); + } + ) +); + +export default Mermaid; diff --git a/frontend/antdx/mermaid/package.json b/frontend/antdx/mermaid/package.json new file mode 100644 index 00000000..78a12373 --- /dev/null +++ b/frontend/antdx/mermaid/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-mermaid", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/sources/Index.svelte b/frontend/antdx/sources/Index.svelte new file mode 100644 index 00000000..1ca15b1e --- /dev/null +++ b/frontend/antdx/sources/Index.svelte @@ -0,0 +1,62 @@ + + +{#if proceedProps.visible} + {#await AwaitedSources then Sources} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antdx/sources/context.ts b/frontend/antdx/sources/context.ts new file mode 100644 index 00000000..61e7fcd9 --- /dev/null +++ b/frontend/antdx/sources/context.ts @@ -0,0 +1,6 @@ +import { createItemsContext } from '@utils/createItemsContext'; + +export const { useItems, withItemsContextProvider, ItemHandler } = + createItemsContext('antdx-sources-items'); + +export * from '@utils/createItemsContext'; diff --git a/frontend/antdx/sources/gradio.config.js b/frontend/antdx/sources/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antdx/sources/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/sources/item/Index.svelte b/frontend/antdx/sources/item/Index.svelte new file mode 100644 index 00000000..cbf2cdff --- /dev/null +++ b/frontend/antdx/sources/item/Index.svelte @@ -0,0 +1,68 @@ + + +{#await AwaitedSourcesItem then SourcesItem} + + {#if proceedProps.visible} + {@render children?.()} + {/if} + +{/await} diff --git a/frontend/antdx/sources/item/gradio.config.js b/frontend/antdx/sources/item/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antdx/sources/item/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antdx/sources/item/package.json b/frontend/antdx/sources/item/package.json new file mode 100644 index 00000000..3e8cadbb --- /dev/null +++ b/frontend/antdx/sources/item/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-sources.item", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/sources/item/sources.item.tsx b/frontend/antdx/sources/item/sources.item.tsx new file mode 100644 index 00000000..0a0ae8ae --- /dev/null +++ b/frontend/antdx/sources/item/sources.item.tsx @@ -0,0 +1,13 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import type { SourcesProps } from '@ant-design/x'; + +import { ItemHandler, type ItemHandlerProps } from '../context'; + +export const SourcesItem = sveltify< + Partial[number]> & ItemHandlerProps +>((props) => { + return ; +}); + +export default SourcesItem; diff --git a/frontend/antdx/sources/package.json b/frontend/antdx/sources/package.json new file mode 100644 index 00000000..3d299de0 --- /dev/null +++ b/frontend/antdx/sources/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antdx-sources", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/sources/sources.tsx b/frontend/antdx/sources/sources.tsx new file mode 100644 index 00000000..d8426a11 --- /dev/null +++ b/frontend/antdx/sources/sources.tsx @@ -0,0 +1,41 @@ +import { sveltify } from '@svelte-preprocess-react'; +import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React, { useMemo } from 'react'; +import { Sources as XSources, type SourcesProps } from '@ant-design/x'; +import { renderItems } from '@utils/renderItems'; + +import { useItems, withItemsContextProvider } from './context'; + +export const Sources = sveltify( + withItemsContextProvider( + ['default', 'items'], + ({ children, items, slots, ...props }) => { + const { items: slotItems } = useItems<['default', 'items']>(); + const resolvedSlotItems = + slotItems.items.length > 0 ? slotItems.items : slotItems.default; + + return ( + <> +
{children}
+ : slots.title} + items={useMemo(() => { + return ( + items || + renderItems[number]>( + resolvedSlotItems, + { + clone: true, + } + ) + ); + }, [items, resolvedSlotItems])} + /> + + ); + } + ) +); + +export default Sources; From 5d4c703fbc1e63d55a9a7bcbee1deb22f7417ca6 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Tue, 24 Mar 2026 17:19:26 +0800 Subject: [PATCH 14/31] refactor(pro): migration --- .../components/antd/auto_complete/__init__.py | 4 +- .../components/antd/badge/__init__.py | 4 +- .../components/antd/card/__init__.py | 4 +- .../components/antd/cascader/__init__.py | 4 +- .../antd/config_provider/__init__.py | 7 + .../components/antd/drawer/__init__.py | 4 +- .../components/antd/dropdown/__init__.py | 4 +- .../antd/dropdown/button/__init__.py | 4 +- .../components/antd/empty/__init__.py | 4 +- .../components/antd/input/__init__.py | 4 +- .../antd/input/password/__init__.py | 4 +- .../components/antd/input/search/__init__.py | 4 +- .../antd/input/textarea/__init__.py | 4 +- .../components/antd/layout/sider/__init__.py | 7 + .../components/antd/menu/__init__.py | 7 + .../components/antd/menu/item/__init__.py | 7 + .../components/antd/modal/__init__.py | 4 +- .../components/antd/modal/static/__init__.py | 4 +- .../components/antd/select/__init__.py | 4 +- .../components/antd/slider/__init__.py | 4 +- .../components/antd/space/__init__.py | 4 +- .../components/antd/tree_select/__init__.py | 4 +- .../components/antdx/__init__.py | 27 +- .../components/antdx/actions/__init__.py | 6 +- .../components/antdx/bubble/__init__.py | 2 +- .../components/antdx/components.py | 22 +- .../components/antdx/folder/__init__.py | 2 +- .../components/antdx/mermaid/__init__.py | 2 + .../components/antdx/notification/__init__.py | 4 +- .../components/antdx/sources/item/__init__.py | 4 +- .../components/antdx/welcome/__init__.py | 4 +- .../components/antdx/x_provider/__init__.py | 9 +- .../components/pro/chatbot/__init__.py | 5 +- .../pro/multimodal_input/__init__.py | 21 +- .../modelscope_studio/utils/dev/component.py | 3 +- config/lint-config/package.json | 6 +- frontend/antd/checkbox/checkbox.tsx | 2 +- .../antd/checkbox/group/checkbox.group.tsx | 3 +- frontend/antd/color-picker/color-picker.tsx | 4 +- frontend/antd/config-provider/Index.svelte | 9 +- frontend/antd/date-picker/date-picker.tsx | 2 +- .../range-picker/date-picker.range-picker.tsx | 2 +- frontend/antd/menu/Index.svelte | 5 +- frontend/antd/menu/item/Index.svelte | 4 + frontend/antd/menu/item/menu.item.tsx | 5 +- frontend/antd/popconfirm/popconfirm.tsx | 4 +- frontend/antd/popover/popover.tsx | 10 +- frontend/antd/radio/button/radio.button.tsx | 2 +- frontend/antd/radio/group/radio.group.tsx | 2 +- frontend/antd/radio/radio.tsx | 2 +- frontend/antd/rate/rate.tsx | 2 +- frontend/antd/segmented/segmented.tsx | 2 +- frontend/antd/select/select.tsx | 2 +- frontend/antd/slider/slider.tsx | 2 +- .../tag/checkable-tag/tag.checkable-tag.tsx | 2 +- .../range-picker/time-picker.range-picker.tsx | 2 +- frontend/antd/time-picker/time-picker.tsx | 2 +- frontend/antd/tooltip/tooltip.tsx | 4 +- frontend/antd/transfer/transfer.tsx | 2 +- frontend/antd/tree-select/tree-select.tsx | 2 +- frontend/antd/typography/link/Index.svelte | 3 +- frontend/antd/typography/text/Index.svelte | 3 +- frontend/antd/typography/title/Index.svelte | 3 +- frontend/antdx/bubble/list/utils.tsx | 2 +- .../code-highlighter/code-highlighter.tsx | 10 +- frontend/antdx/file-card/file-card.tsx | 1 + frontend/antdx/folder/folder.tsx | 2 +- frontend/antdx/sender/Index.svelte | 2 +- frontend/antdx/suggestion/suggestion.tsx | 1 + frontend/antdx/x-provider/XProvider.svelte | 7 + frontend/fixtures.d.ts | 4 +- frontend/package.json | 8 +- frontend/pro/chatbot/Index.svelte | 9 +- frontend/pro/chatbot/chatbot-footer.tsx | 7 +- frontend/pro/chatbot/chatbot.less | 29 +- frontend/pro/chatbot/chatbot.tsx | 111 +-- frontend/pro/chatbot/hooks/useScroll.ts | 15 +- frontend/pro/chatbot/messages/file.tsx | 131 ++-- frontend/pro/chatbot/type.ts | 37 +- frontend/pro/monaco-editor/Index.svelte | 21 +- .../monaco-editor/diff-editor/Index.svelte | 74 +- frontend/pro/multimodal-input/Index.svelte | 13 +- .../pro/multimodal-input/multimodal-input.tsx | 117 +++- frontend/pro/web-sandbox/Index.svelte | 8 +- .../component/props.svelte.ts | 36 +- .../internal/Bridge.svelte.ts | 36 +- frontend/utils/patchProps.tsx | 2 +- package.json | 4 +- pnpm-lock.yaml | 657 +++++++++--------- 89 files changed, 916 insertions(+), 732 deletions(-) diff --git a/backend/modelscope_studio/components/antd/auto_complete/__init__.py b/backend/modelscope_studio/components/antd/auto_complete/__init__.py index 43b36120..f37f03f9 100644 --- a/backend/modelscope_studio/components/antd/auto_complete/__init__.py +++ b/backend/modelscope_studio/components/antd/auto_complete/__init__.py @@ -76,8 +76,8 @@ def __init__( status: Literal['error', 'warning'] | None = None, variant: Literal['outlined', 'borderless', 'filled'] | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antd/badge/__init__.py b/backend/modelscope_studio/components/antd/badge/__init__.py index c0c7f843..3129a490 100644 --- a/backend/modelscope_studio/components/antd/badge/__init__.py +++ b/backend/modelscope_studio/components/antd/badge/__init__.py @@ -23,7 +23,7 @@ def __init__( additional_props: dict | None = None, *, color: str | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, dot: bool | None = None, offset: tuple[int | float, int | float] | None = None, overflow_count: int = 99, @@ -33,7 +33,7 @@ def __init__( 'warning'] | None = None, text: str | None = None, title: str | None = None, - styles: dict | str | None= None, + styles: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antd/card/__init__.py b/backend/modelscope_studio/components/antd/card/__init__.py index ff5ee081..e0398148 100644 --- a/backend/modelscope_studio/components/antd/card/__init__.py +++ b/backend/modelscope_studio/components/antd/card/__init__.py @@ -72,8 +72,8 @@ def __init__( tab_props: dict | None = None, title: str | None = None, type: str | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antd/cascader/__init__.py b/backend/modelscope_studio/components/antd/cascader/__init__.py index b1305781..afd26e35 100644 --- a/backend/modelscope_studio/components/antd/cascader/__init__.py +++ b/backend/modelscope_studio/components/antd/cascader/__init__.py @@ -95,8 +95,8 @@ def __init__( dropdown_menu_column_style: dict | None = None, option_render: str | None = None, root_class_name: str | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, as_item: str | None = None, _internal: None = None, # gradio properties diff --git a/backend/modelscope_studio/components/antd/config_provider/__init__.py b/backend/modelscope_studio/components/antd/config_provider/__init__.py index 90cca397..936c3711 100644 --- a/backend/modelscope_studio/components/antd/config_provider/__init__.py +++ b/backend/modelscope_studio/components/antd/config_provider/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import Any, Literal from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir @@ -44,6 +45,7 @@ def __init__(self, prefix_cls: str | None = None, render_empty: str | None = None, theme: dict | None = None, + theme_config: dict | None = None, variant: Literal['outlined', 'filled', 'borderless'] | None = None, virtual: bool | None = None, @@ -81,6 +83,11 @@ def __init__(self, self.prefix_cls = prefix_cls self.render_empty = render_empty self.theme = theme + if theme: + warnings.warn( + """[antd.ConfigProvider]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_config` instead.""" + ) + self.theme_config = theme_config self.variant = variant self.virtual = virtual self.warning = warning diff --git a/backend/modelscope_studio/components/antd/drawer/__init__.py b/backend/modelscope_studio/components/antd/drawer/__init__.py index 617cec7a..60893a4c 100644 --- a/backend/modelscope_studio/components/antd/drawer/__init__.py +++ b/backend/modelscope_studio/components/antd/drawer/__init__.py @@ -31,7 +31,7 @@ def __init__( auto_focus: bool | None = None, body_style: dict | None = None, close_icon: str | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, closable: bool | dict | None = None, destroy_on_close: bool | None = None, destroy_on_hidden: bool | None = None, @@ -46,7 +46,7 @@ def __init__( placement: Literal['left', 'right', 'top', 'bottom'] | None = None, push: bool | dict | None = None, size: Literal['default', 'large'] | None = None, - styles: dict | str | None= None, + styles: dict | str | None = None, title: str | None = None, loading: bool | None = None, open: bool | None = None, diff --git a/backend/modelscope_studio/components/antd/dropdown/__init__.py b/backend/modelscope_studio/components/antd/dropdown/__init__.py index f901f571..8e4fb6fb 100644 --- a/backend/modelscope_studio/components/antd/dropdown/__init__.py +++ b/backend/modelscope_studio/components/antd/dropdown/__init__.py @@ -59,8 +59,8 @@ def __init__( 'contextMenu']] = ['hover'], open: bool | None = None, inner_elem_style: dict | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antd/dropdown/button/__init__.py b/backend/modelscope_studio/components/antd/dropdown/button/__init__.py index 82cd07e0..50a26f02 100644 --- a/backend/modelscope_studio/components/antd/dropdown/button/__init__.py +++ b/backend/modelscope_studio/components/antd/dropdown/button/__init__.py @@ -68,8 +68,8 @@ def __init__( size: Literal["large", "middle", "small"] | None = None, type: Literal["primary", "dashed", "link", "text", "default"] | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antd/empty/__init__.py b/backend/modelscope_studio/components/antd/empty/__init__.py index d9bf8b66..f5aed97c 100644 --- a/backend/modelscope_studio/components/antd/empty/__init__.py +++ b/backend/modelscope_studio/components/antd/empty/__init__.py @@ -25,8 +25,8 @@ def __init__( | None = None, image_style: dict | None = None, root_class_name: str | None = None, - styles: dict | str | None= None, - class_names: dict | str | None= None, + styles: dict | str | None = None, + class_names: dict | str | None = None, as_item: str | None = None, _internal: None = None, # gradio properties diff --git a/backend/modelscope_studio/components/antd/input/__init__.py b/backend/modelscope_studio/components/antd/input/__init__.py index a82ff839..987df056 100644 --- a/backend/modelscope_studio/components/antd/input/__init__.py +++ b/backend/modelscope_studio/components/antd/input/__init__.py @@ -48,7 +48,7 @@ def __init__( addon_after: str | None = None, addon_before: str | None = None, allow_clear: bool | dict | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, count: dict | None = None, default_value: str | None = None, read_only: bool | None = None, @@ -58,7 +58,7 @@ def __init__( show_count: bool | dict = None, size: Literal['large', 'middle', 'small'] | None = None, status: Literal['error', 'warning'] | None = None, - styles: dict | str | None= None, + styles: dict | str | None = None, suffix: str | None = None, type: str | None = None, placeholder: str | None = None, diff --git a/backend/modelscope_studio/components/antd/input/password/__init__.py b/backend/modelscope_studio/components/antd/input/password/__init__.py index 51fb3a92..0f6a4665 100644 --- a/backend/modelscope_studio/components/antd/input/password/__init__.py +++ b/backend/modelscope_studio/components/antd/input/password/__init__.py @@ -43,7 +43,7 @@ def __init__( addon_after: str | None = None, addon_before: str | None = None, allow_clear: bool | dict | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, count: dict | None = None, default_value: str | None = None, read_only: bool | None = None, @@ -53,7 +53,7 @@ def __init__( show_count: bool | dict = None, size: Literal['large', 'middle', 'small'] | None = None, status: Literal['error', 'warning'] | None = None, - styles: dict | str | None= None, + styles: dict | str | None = None, suffix: str | None = None, type: str | None = None, placeholder: str | None = None, diff --git a/backend/modelscope_studio/components/antd/input/search/__init__.py b/backend/modelscope_studio/components/antd/input/search/__init__.py index 79dd5e47..15fa9f5f 100644 --- a/backend/modelscope_studio/components/antd/input/search/__init__.py +++ b/backend/modelscope_studio/components/antd/input/search/__init__.py @@ -43,7 +43,7 @@ def __init__( addon_after: str | None = None, addon_before: str | None = None, allow_clear: bool | dict | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, count: dict | None = None, default_value: str | None = None, read_only: bool | None = None, @@ -53,7 +53,7 @@ def __init__( show_count: bool | dict = None, size: Literal['large', 'middle', 'small'] | None = None, status: Literal['error', 'warning'] | None = None, - styles: dict | str | None= None, + styles: dict | str | None = None, suffix: str | None = None, type: str | None = None, placeholder: str | None = None, diff --git a/backend/modelscope_studio/components/antd/input/textarea/__init__.py b/backend/modelscope_studio/components/antd/input/textarea/__init__.py index 5b821f1f..0ba71624 100644 --- a/backend/modelscope_studio/components/antd/input/textarea/__init__.py +++ b/backend/modelscope_studio/components/antd/input/textarea/__init__.py @@ -34,7 +34,7 @@ def __init__( *, auto_size: bool | dict | None = None, allow_clear: bool | dict | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, count: dict | None = None, default_value: str | None = None, read_only: bool | None = None, @@ -43,7 +43,7 @@ def __init__( show_count: bool | dict = None, size: Literal['large', 'middle', 'small'] | None = None, status: Literal['error', 'warning'] | None = None, - styles: dict | str | None= None, + styles: dict | str | None = None, type: str | None = None, placeholder: str | None = None, variant: Literal['outlined', 'borderless', 'filled', 'underlined'] diff --git a/backend/modelscope_studio/components/antd/layout/sider/__init__.py b/backend/modelscope_studio/components/antd/layout/sider/__init__.py index 870e60ed..dd4fb41a 100644 --- a/backend/modelscope_studio/components/antd/layout/sider/__init__.py +++ b/backend/modelscope_studio/components/antd/layout/sider/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import Any, Literal from gradio.events import EventListener @@ -52,6 +53,7 @@ def __init__( default_collapsed: bool | None = None, reverse_arrow: bool | None = None, theme: Literal['light', 'dark'] | None = None, + theme_value: Literal['light', 'dark'] | None = None, trigger: str | None = 'default', width: int | float | str = 200, zero_width_trigger_style: dict | None = None, @@ -96,6 +98,11 @@ def __init__( self.default_collapsed = default_collapsed self.reverse_arrow = reverse_arrow self.theme = theme + if theme: + warnings.warn( + """[antd.Layout.Sider]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_value` instead.""" + ) + self.theme_value = theme_value self.trigger = trigger self.width = width self.zero_width_trigger_style = zero_width_trigger_style diff --git a/backend/modelscope_studio/components/antd/menu/__init__.py b/backend/modelscope_studio/components/antd/menu/__init__.py index 179e8fc3..dfc639ad 100644 --- a/backend/modelscope_studio/components/antd/menu/__init__.py +++ b/backend/modelscope_studio/components/antd/menu/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import Any, Literal from gradio.events import EventListener @@ -53,6 +54,7 @@ def __init__( sub_menu_close_delay: int | float = 0.1, sub_menu_open_delay: int | float = 0, theme: Literal['light', 'dark'] | None = None, + theme_value: Literal['light', 'dark'] | None = None, trigger_sub_menu_action: Literal['click', 'hover'] = 'hover', root_class_name: str | None = None, class_names: dict | str | None = None, @@ -92,6 +94,11 @@ def __init__( self.sub_menu_close_delay = sub_menu_close_delay self.sub_menu_open_delay = sub_menu_open_delay self.theme = theme + if theme: + warnings.warn( + """[antd.Menu.Item]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_value` instead.""" + ) + self.theme_value = theme_value self.trigger_sub_menu_action = trigger_sub_menu_action self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/menu/item/__init__.py b/backend/modelscope_studio/components/antd/menu/item/__init__.py index 74ffccc8..2af492fd 100644 --- a/backend/modelscope_studio/components/antd/menu/item/__init__.py +++ b/backend/modelscope_studio/components/antd/menu/item/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import Any, Literal from gradio.events import EventListener @@ -32,6 +33,7 @@ def __init__( icon: str | None = None, key: str | None = None, theme: Literal['dark', 'light'] = None, + theme_value: Literal['dark', 'light'] = None, type: Literal['group'] | None = None, popup_class_name: str | None = None, popup_offset: tuple[int | float, int | float] | None = None, @@ -60,6 +62,11 @@ def __init__( self.icon = icon self.key = key self.theme = theme + if theme: + warnings.warn( + """[antd.Menu.Item]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_value` instead.""" + ) + self.theme_value = theme_value self.type = type self.popup_class_name = popup_class_name self.popup_offset = popup_offset diff --git a/backend/modelscope_studio/components/antd/modal/__init__.py b/backend/modelscope_studio/components/antd/modal/__init__.py index 4ae067fa..cdcca0ff 100644 --- a/backend/modelscope_studio/components/antd/modal/__init__.py +++ b/backend/modelscope_studio/components/antd/modal/__init__.py @@ -36,8 +36,8 @@ def __init__( additional_props: dict | None = None, *, after_close: str | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, cancel_button_props: dict | None = None, cancel_text: str | None = None, centered: bool | None = None, diff --git a/backend/modelscope_studio/components/antd/modal/static/__init__.py b/backend/modelscope_studio/components/antd/modal/static/__init__.py index 7821f6f2..209d9eeb 100644 --- a/backend/modelscope_studio/components/antd/modal/static/__init__.py +++ b/backend/modelscope_studio/components/antd/modal/static/__init__.py @@ -35,8 +35,8 @@ def __init__( auto_focus_button: Literal['ok', 'cancel'] | None = 'ok', type: Literal['info', 'success', 'error', 'warning', 'confirm'] | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, cancel_button_props: dict | None = None, cancel_text: str | None = None, centered: bool | None = None, diff --git a/backend/modelscope_studio/components/antd/select/__init__.py b/backend/modelscope_studio/components/antd/select/__init__.py index 1cc9dbca..d5e58dc5 100644 --- a/backend/modelscope_studio/components/antd/select/__init__.py +++ b/backend/modelscope_studio/components/antd/select/__init__.py @@ -106,8 +106,8 @@ def __init__( variant: Literal['outlined', 'borderless', 'filled', 'underlined'] | None = None, virtual: bool | None = True, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antd/slider/__init__.py b/backend/modelscope_studio/components/antd/slider/__init__.py index bb8ffb6b..48200244 100644 --- a/backend/modelscope_studio/components/antd/slider/__init__.py +++ b/backend/modelscope_studio/components/antd/slider/__init__.py @@ -34,7 +34,7 @@ def __init__( additional_props: dict | None = None, *, auto_focus: bool | None = None, - class_names: dict | str | None= None, + class_names: dict | str | None = None, default_value: int | float | tuple[int | float, int | float] | list[int | float] | None = None, disabled: bool | None = None, @@ -47,7 +47,7 @@ def __init__( range: bool | dict | None = False, reverse: bool | None = None, step: int | float | None = 1, - styles: dict | str | None= None, + styles: dict | str | None = None, tooltip: dict | None = None, vertical: bool | None = None, root_class_name: str | None = None, diff --git a/backend/modelscope_studio/components/antd/space/__init__.py b/backend/modelscope_studio/components/antd/space/__init__.py index b76a4321..f7d9868c 100644 --- a/backend/modelscope_studio/components/antd/space/__init__.py +++ b/backend/modelscope_studio/components/antd/space/__init__.py @@ -32,8 +32,8 @@ def __init__( additional_props: dict | None = None, *, align: Literal['start', 'end', 'center', 'baseline'] | None = None, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, direction: Literal['vertical', 'horizontal'] | None = 'horizontal', size: Literal['small', 'middle', 'large'] | int | float | list[Literal['small', 'middle', 'large'] | int | float] diff --git a/backend/modelscope_studio/components/antd/tree_select/__init__.py b/backend/modelscope_studio/components/antd/tree_select/__init__.py index 6c550f0b..609ebf85 100644 --- a/backend/modelscope_studio/components/antd/tree_select/__init__.py +++ b/backend/modelscope_studio/components/antd/tree_select/__init__.py @@ -106,8 +106,8 @@ def __init__( variant: Literal['outlined', 'borderless', 'solid', 'underlined'] | None = None, virtual: bool | None = True, - class_names: dict | str | None= None, - styles: dict | str | None= None, + class_names: dict | str | None = None, + styles: dict | str | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, diff --git a/backend/modelscope_studio/components/antdx/__init__.py b/backend/modelscope_studio/components/antdx/__init__.py index 561c3d80..577f6a34 100644 --- a/backend/modelscope_studio/components/antdx/__init__.py +++ b/backend/modelscope_studio/components/antdx/__init__.py @@ -1,40 +1,41 @@ from .actions import AntdXActions as Actions from .actions.action_item import AntdXActionsActionItem as ActionsActionItem +from .actions.audio import AntdXActionsAudio as ActionsAudio from .actions.copy import AntdXActionsCopy as ActionsCopy from .actions.feedback import AntdXActionsFeedback as ActionsFeedback -from .actions.audio import AntdXActionsAudio as ActionsAudio from .actions.item import AntdXActionsItem as ActionsItem from .attachments import AntdXAttachments as Attachments -from .file_card import \ - AntdXFileCard as FileCard -from .file_card.list import AntdXFileCardList as FileCardList -from .file_card.list.item import AntdXFileCardListItem as FileCardListItem from .bubble import AntdXBubble as Bubble +from .bubble.divider import AntdXBubbleDivider as BubbleDivider from .bubble.list import AntdXBubbleList as BubbleList from .bubble.list.item import AntdXBubbleListItem as BubbleListItem from .bubble.list.role import AntdXBubbleListRole as BubbleListRole -from .bubble.divider import AntdXBubbleDivider as BubbleDivider from .bubble.system import AntdXBubbleSystem as BubbleSystem from .code_highlighter import AntdXCodeHighlighter as CodeHighlighter from .conversations import AntdXConversations as Conversations from .conversations.item import AntdXConversationsItem as ConversationsItem +from .file_card import AntdXFileCard as FileCard +from .file_card.list import AntdXFileCardList as FileCardList +from .file_card.list.item import AntdXFileCardListItem as FileCardListItem from .folder import AntdXFolder as Folder +from .folder.directory_icon import \ + AntdXFolderDirectoryIcon as FolderDirectoryIcon from .folder.tree_node import AntdXFolderTreeNode as FolderTreeNode -from .folder.directory_icon import AntdXFolderDirectoryIcon as FolderDirectoryIcon +from .mermaid import AntdXMermaid as Mermaid +from .notification import AntdXNotification as Notification from .prompts import AntdXPrompts as Prompts from .prompts.item import AntdXPromptsItem as PromptsItem from .sender import AntdXSender as Sender from .sender.header import AntdXSenderHeader as SenderHeader from .sender.switch import AntdXSenderSwitch as SenderSwitch -from .suggestion import AntdXSuggestion as Suggestion -from .suggestion.item import AntdXSuggestionItem as SuggestionItem from .sources import AntdXSources as Sources from .sources.item import AntdXSourcesItem as SourcesItem +from .suggestion import AntdXSuggestion as Suggestion +from .suggestion.item import AntdXSuggestionItem as SuggestionItem +from .think import AntdXThink as Think from .thought_chain import AntdXThoughtChain as ThoughtChain from .thought_chain.item import AntdXThoughtChainItem as ThoughtChainItem -from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem as ThoughtChainThoughtChainItem -from .think import AntdXThink as Think +from .thought_chain.thought_chain_item import \ + AntdXThoughtChainThoughtChainItem as ThoughtChainThoughtChainItem from .welcome import AntdXWelcome as Welcome -from .mermaid import AntdXMermaid as Mermaid -from .notification import AntdXNotification as Notification from .x_provider import AntdXXProvider as XProvider diff --git a/backend/modelscope_studio/components/antdx/actions/__init__.py b/backend/modelscope_studio/components/antdx/actions/__init__.py index 92e8cd8e..b4917a48 100644 --- a/backend/modelscope_studio/components/antdx/actions/__init__.py +++ b/backend/modelscope_studio/components/antdx/actions/__init__.py @@ -6,10 +6,10 @@ from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir from .action_item import AntdXActionsActionItem -from .item import AntdXActionsItem -from .feedback import AntdXActionsFeedback -from .copy import AntdXActionsCopy from .audio import AntdXActionsAudio +from .copy import AntdXActionsCopy +from .feedback import AntdXActionsFeedback +from .item import AntdXActionsItem class AntdXActions(ModelScopeLayoutComponent): diff --git a/backend/modelscope_studio/components/antdx/bubble/__init__.py b/backend/modelscope_studio/components/antdx/bubble/__init__.py index b2ca256e..46db363b 100644 --- a/backend/modelscope_studio/components/antdx/bubble/__init__.py +++ b/backend/modelscope_studio/components/antdx/bubble/__init__.py @@ -5,9 +5,9 @@ from gradio.events import EventListener from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir +from .divider import AntdXBubbleDivider from .list import AntdXBubbleList from .system import AntdXBubbleSystem -from .divider import AntdXBubbleDivider class AntdXBubble(ModelScopeLayoutComponent): diff --git a/backend/modelscope_studio/components/antdx/components.py b/backend/modelscope_studio/components/antdx/components.py index 72aa3bc2..d7e79be8 100644 --- a/backend/modelscope_studio/components/antdx/components.py +++ b/backend/modelscope_studio/components/antdx/components.py @@ -1,25 +1,27 @@ from .actions import AntdXActions -from .actions.item import AntdXActionsItem from .actions.action_item import AntdXActionsActionItem -from .actions.feedback import AntdXActionsFeedback -from .actions.copy import AntdXActionsCopy from .actions.audio import AntdXActionsAudio +from .actions.copy import AntdXActionsCopy +from .actions.feedback import AntdXActionsFeedback +from .actions.item import AntdXActionsItem from .attachments import AntdXAttachments -from .file_card import AntdXFileCard -from .file_card.list import AntdXFileCardList -from .file_card.list.item import AntdXFileCardListItem from .bubble import AntdXBubble +from .bubble.divider import AntdXBubbleDivider from .bubble.list import AntdXBubbleList from .bubble.list.item import AntdXBubbleListItem from .bubble.list.role import AntdXBubbleListRole -from .bubble.divider import AntdXBubbleDivider from .bubble.system import AntdXBubbleSystem from .code_highlighter import AntdXCodeHighlighter from .conversations import AntdXConversations from .conversations.item import AntdXConversationsItem +from .file_card import AntdXFileCard +from .file_card.list import AntdXFileCardList +from .file_card.list.item import AntdXFileCardListItem from .folder import AntdXFolder -from .folder.tree_node import AntdXFolderTreeNode from .folder.directory_icon import AntdXFolderDirectoryIcon +from .folder.tree_node import AntdXFolderTreeNode +from .mermaid import AntdXMermaid +from .notification import AntdXNotification from .prompts import AntdXPrompts from .prompts.item import AntdXPromptsItem from .sender import AntdXSender @@ -29,11 +31,9 @@ from .sources.item import AntdXSourcesItem from .suggestion import AntdXSuggestion from .suggestion.item import AntdXSuggestionItem +from .think import AntdXThink from .thought_chain import AntdXThoughtChain from .thought_chain.item import AntdXThoughtChainItem from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem -from .think import AntdXThink from .welcome import AntdXWelcome -from .mermaid import AntdXMermaid -from .notification import AntdXNotification from .x_provider import AntdXXProvider diff --git a/backend/modelscope_studio/components/antdx/folder/__init__.py b/backend/modelscope_studio/components/antdx/folder/__init__.py index c9397f0b..f36c59fd 100644 --- a/backend/modelscope_studio/components/antdx/folder/__init__.py +++ b/backend/modelscope_studio/components/antdx/folder/__init__.py @@ -5,8 +5,8 @@ from gradio.events import EventListener from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir -from .tree_node import AntdXFolderTreeNode from .directory_icon import AntdXFolderDirectoryIcon +from .tree_node import AntdXFolderTreeNode class AntdXFolder(ModelScopeLayoutComponent): diff --git a/backend/modelscope_studio/components/antdx/mermaid/__init__.py b/backend/modelscope_studio/components/antdx/mermaid/__init__.py index 832ddd79..5bf9c11c 100644 --- a/backend/modelscope_studio/components/antdx/mermaid/__init__.py +++ b/backend/modelscope_studio/components/antdx/mermaid/__init__.py @@ -1,5 +1,7 @@ from __future__ import annotations + from gradio.events import EventListener + from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir diff --git a/backend/modelscope_studio/components/antdx/notification/__init__.py b/backend/modelscope_studio/components/antdx/notification/__init__.py index 7b51c7b3..a5c1e2e2 100644 --- a/backend/modelscope_studio/components/antdx/notification/__init__.py +++ b/backend/modelscope_studio/components/antdx/notification/__init__.py @@ -1,7 +1,9 @@ from __future__ import annotations -from gradio.events import EventListener from typing import Any, Literal + +from gradio.events import EventListener + from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir diff --git a/backend/modelscope_studio/components/antdx/sources/item/__init__.py b/backend/modelscope_studio/components/antdx/sources/item/__init__.py index c6b35329..d8e7053e 100644 --- a/backend/modelscope_studio/components/antdx/sources/item/__init__.py +++ b/backend/modelscope_studio/components/antdx/sources/item/__init__.py @@ -47,9 +47,7 @@ def __init__( self.key = key self.url = url - FRONTEND_DIR = resolve_frontend_dir("sources", - "sources-item", - type="antdx") + FRONTEND_DIR = resolve_frontend_dir("sources", "item", type="antdx") @property def skip_api(self): diff --git a/backend/modelscope_studio/components/antdx/welcome/__init__.py b/backend/modelscope_studio/components/antdx/welcome/__init__.py index 840eb677..7e4429d6 100644 --- a/backend/modelscope_studio/components/antdx/welcome/__init__.py +++ b/backend/modelscope_studio/components/antdx/welcome/__init__.py @@ -20,8 +20,8 @@ def __init__( *, extra: str | None = None, icon: str | None = None, - styles: dict | str | None= None, - class_names: dict | str | None= None, + styles: dict | str | None = None, + class_names: dict | str | None = None, description: str | None = None, variant: Literal['filled', 'borderless'] | None = None, title: str | None = None, diff --git a/backend/modelscope_studio/components/antdx/x_provider/__init__.py b/backend/modelscope_studio/components/antdx/x_provider/__init__.py index cb933bb3..c7518c48 100644 --- a/backend/modelscope_studio/components/antdx/x_provider/__init__.py +++ b/backend/modelscope_studio/components/antdx/x_provider/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import Any, Literal from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir @@ -31,7 +32,8 @@ def __init__(self, popup_overflow: Literal['viewport', 'scroll'] | None = None, prefix_cls: str | None = None, render_empty: str | None = None, - theme: dict | None = None, + theme: str | None = None, + theme_config: dict | None = None, variant: Literal['outlined', 'filled', 'borderless'] | None = None, virtual: bool | None = None, @@ -69,6 +71,11 @@ def __init__(self, self.prefix_cls = prefix_cls self.render_empty = render_empty self.theme = theme + if theme: + warnings.warn( + """[antdx.XProvider]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_config` instead.""" + ) + self.theme_config = theme_config self.variant = variant self.virtual = virtual self.warning = warning diff --git a/backend/modelscope_studio/components/pro/chatbot/__init__.py b/backend/modelscope_studio/components/pro/chatbot/__init__.py index c45b4f39..46a9338d 100644 --- a/backend/modelscope_studio/components/pro/chatbot/__init__.py +++ b/backend/modelscope_studio/components/pro/chatbot/__init__.py @@ -208,6 +208,8 @@ class ChatbotDataFileContentOptions(GradioModel): gap: Optional[Union[Literal["small", "middle", "large"], str, int, float]] = "small" image_props: Optional[dict] = None + video_props: Optional[dict] = None + audio_props: Optional[dict] = None # Ant Design X prompts props: https://x.ant.design/components/prompts @@ -249,7 +251,8 @@ class ChatbotDataMessageContent(GradioModel): class ChatbotDataMessage(ChatbotBotConfig): - role: Union[Literal['user', 'assistant', 'system'], str] = None + role: Union[Literal['user', 'assistant', 'system', 'divider'], str] = None + divider_props: Optional[dict] = None key: Optional[Union[str, int, float]] = None # If status is 'pending', the message will not render the footer area (including 'actions' and 'footer'). status: Optional[Literal['pending', 'done']] = None diff --git a/backend/modelscope_studio/components/pro/multimodal_input/__init__.py b/backend/modelscope_studio/components/pro/multimodal_input/__init__.py index 3707ed17..01af5a4a 100644 --- a/backend/modelscope_studio/components/pro/multimodal_input/__init__.py +++ b/backend/modelscope_studio/components/pro/multimodal_input/__init__.py @@ -117,6 +117,9 @@ class ModelScopeProMultimodalInput(ModelScopeDataLayoutComponent): EventListener("paste_file", callback=lambda block: block._internal.update( bind_pasteFile_event=True)), + EventListener("skill_closable_close", + callback=lambda block: block._internal.update( + bind_skill_closable_close_event=True)), EventListener("drop", callback=lambda block: block._internal.update( bind_drop_event=True)), @@ -134,7 +137,11 @@ class ModelScopeProMultimodalInput(ModelScopeDataLayoutComponent): data_model = MultimodalInputValue # supported slots - SLOTS = ['actions', "prefix", 'footer', 'header'] + SLOTS = [ + 'suffix', 'header', 'prefix', 'footer', 'skill.title', + 'skill.toolTip.title' + 'skill.closable.closeIcon' + ] def __init__( self, @@ -144,7 +151,8 @@ def __init__( auto_size: bool | dict | None = None, footer: str | None = None, header: str | None = None, - actions: str | bool | None = None, + prefix: str | None = None, + suffix: str | bool | None = None, class_names: dict | None = None, styles: dict | None = None, loading: bool | None = None, @@ -153,6 +161,8 @@ def __init__( submit_type: Literal['enter', 'shiftEnter'] | None = None, placeholder: str | None = None, upload_config: MultimodalInputUploadConfig | dict | None = None, + slot_config: list[dict] | None = None, + skill: dict | None = None, root_class_name: str | None = None, as_item: str | None = None, _internal: None = None, @@ -175,12 +185,15 @@ def __init__( self.mode = mode self.footer = footer self.header = header - self.actions = actions - self.class_names = class_names + self.prefix = prefix + self.suffix = suffix self.disabled = disabled + self.class_names = class_names self.styles = styles self.submit_type = submit_type self.read_only = read_only + self.slot_config = slot_config + self.skill = skill self.loading = loading self.placeholder = placeholder self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/utils/dev/component.py b/backend/modelscope_studio/utils/dev/component.py index cd006003..ef63f866 100644 --- a/backend/modelscope_studio/utils/dev/component.py +++ b/backend/modelscope_studio/utils/dev/component.py @@ -1,8 +1,9 @@ from timeit import Timer from typing import Any, Callable, List, Set, Union + +from gradio.blocks import BlockContext from gradio.component_meta import ComponentMeta from gradio.components.base import Component -from gradio.blocks import BlockContext from .app_context import AppContext diff --git a/config/lint-config/package.json b/config/lint-config/package.json index e3bf9085..8ad9eb32 100644 --- a/config/lint-config/package.json +++ b/config/lint-config/package.json @@ -18,7 +18,7 @@ "dependencies": { "@eslint/compat": "^2.0.3", "@eslint/js": "^10.0.1", - "@typescript-eslint/parser": "^8.57.1", + "@typescript-eslint/parser": "^8.57.2", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", @@ -28,7 +28,7 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-svelte": "^3.15.2", + "eslint-plugin-svelte": "^3.16.0", "globals": "^17.4.0", "postcss": "^8.5.8", "postcss-less": "^6.0.0", @@ -38,7 +38,7 @@ "stylelint-order": "^8.1.1", "stylelint-prettier": "^5.0.3", "svelte-eslint-parser": "^1.6.0", - "typescript-eslint": "^8.57.1" + "typescript-eslint": "^8.57.2" }, "devDependencies": { "@types/eslint": "^9.6.1", diff --git a/frontend/antd/checkbox/checkbox.tsx b/frontend/antd/checkbox/checkbox.tsx index 9695d686..dc44385c 100644 --- a/frontend/antd/checkbox/checkbox.tsx +++ b/frontend/antd/checkbox/checkbox.tsx @@ -11,8 +11,8 @@ export const Checkbox = sveltify< {...props} ref={elRef} onChange={(e) => { - onChange?.(e); onValueChange(e.target.checked); + onChange?.(e); }} /> ); diff --git a/frontend/antd/checkbox/group/checkbox.group.tsx b/frontend/antd/checkbox/group/checkbox.group.tsx index 9c0fa970..c81651bd 100644 --- a/frontend/antd/checkbox/group/checkbox.group.tsx +++ b/frontend/antd/checkbox/group/checkbox.group.tsx @@ -16,7 +16,6 @@ export const CheckboxGroup = sveltify< const { items: slotItems } = useItems<['default', 'options']>(); const resolvedSlotItems = slotItems.options.length > 0 ? slotItems.options : slotItems.default; - return ( <>
{children}
@@ -34,8 +33,8 @@ export const CheckboxGroup = sveltify< ); }, [resolvedSlotItems, options])} onChange={(v: any[]) => { - onChange?.(v); onValueChange(v); + onChange?.(v); }} /> diff --git a/frontend/antd/color-picker/color-picker.tsx b/frontend/antd/color-picker/color-picker.tsx index ed5ed6f6..629992b0 100644 --- a/frontend/antd/color-picker/color-picker.tsx +++ b/frontend/antd/color-picker/color-picker.tsx @@ -81,8 +81,8 @@ export const ColorPicker = sveltify< color: colors[value_format], }; }); - onChange?.(gradientColors, ...args); onValueChange(gradientColors); + onChange?.(gradientColors, ...args); return; } const colors = { @@ -90,8 +90,8 @@ export const ColorPicker = sveltify< hex: v.toHexString(), hsb: v.toHsbString(), }; - onChange?.(colors[value_format], ...args); onValueChange(colors[value_format]); + onChange?.(colors[value_format], ...args); }} > {targets.length === 0 ? null : children} diff --git a/frontend/antd/config-provider/Index.svelte b/frontend/antd/config-provider/Index.svelte index 8a72a121..ae7b08c6 100644 --- a/frontend/antd/config-provider/Index.svelte +++ b/frontend/antd/config-provider/Index.svelte @@ -15,8 +15,9 @@ const props = $props(); const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; - as_item?: string | undefined; + theme_config?: any; + theme?: any; }>(() => props); const getProceedProps = processProps(() => { @@ -27,6 +28,7 @@ elem_classes, elem_id, elem_style, + theme_config, ...restProps } = getComponentProps(); return { @@ -39,11 +41,13 @@ elem_id, elem_classes, elem_style, + themeConfig: theme_config, }; }); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); + setConfigType(() => 'antd'); @@ -56,6 +60,9 @@ {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} + theme={proceedProps.additionalProps.theme || + proceedProps.restProps.theme || + proceedProps.themeConfig} themeMode={proceedProps.gradio.shared.theme || 'light'} > {@render children?.()} diff --git a/frontend/antd/date-picker/date-picker.tsx b/frontend/antd/date-picker/date-picker.tsx index b9cf7437..ae5e77cb 100644 --- a/frontend/antd/date-picker/date-picker.tsx +++ b/frontend/antd/date-picker/date-picker.tsx @@ -165,8 +165,8 @@ export const DatePicker = sveltify< }} onChange={(date, ...args) => { const formattedDate = formatDate(date); - onChange?.(formattedDate, ...args); onValueChange(formattedDate); + onChange?.(formattedDate, ...args); }} renderExtraFooter={ slots.renderExtraFooter diff --git a/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx b/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx index 4fc37f52..cda2d5fd 100644 --- a/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx +++ b/frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx @@ -168,8 +168,8 @@ export const DateRangePicker = sveltify< }} onChange={(dates, ...args) => { const formattedDates = formatDates(dates); - onChange?.(formattedDates, ...args); onValueChange(formattedDates); + onChange?.(formattedDates, ...args); }} onCalendarChange={(dates, ...args) => { const formattedDates = formatDates(dates); diff --git a/frontend/antd/menu/Index.svelte b/frontend/antd/menu/Index.svelte index f191c3c5..38dee2f9 100644 --- a/frontend/antd/menu/Index.svelte +++ b/frontend/antd/menu/Index.svelte @@ -16,7 +16,7 @@ _internal: { layout?: boolean; }; - + theme_value?: any; open_change?: any; }>(() => props); @@ -29,6 +29,7 @@ elem_classes, elem_id, elem_style, + theme_value, ...restProps } = getComponentProps(); return { @@ -41,6 +42,7 @@ elem_id, elem_classes, elem_style, + theme: theme_value, }; }, { @@ -60,6 +62,7 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} + theme={proceedProps.additionalProps.theme || proceedProps.theme} slots={slots.value} > {@render children?.()} diff --git a/frontend/antd/menu/item/Index.svelte b/frontend/antd/menu/item/Index.svelte index 889702c4..eaa353b9 100644 --- a/frontend/antd/menu/item/Index.svelte +++ b/frontend/antd/menu/item/Index.svelte @@ -20,6 +20,7 @@ index?: number; }; title_click?: any; + theme_value?: any; }>(() => props); const slotKey = getSlotKey(); @@ -32,6 +33,7 @@ elem_classes, elem_id, elem_style, + theme_value, ...restProps } = getComponentProps(); return { @@ -44,6 +46,7 @@ elem_id, elem_classes, elem_style, + theme: theme_value, }; }, { @@ -62,6 +65,7 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} + theme={proceedProps.additionalProps.theme || proceedProps.theme} slots={{ ...slots.value, icon: { diff --git a/frontend/antd/menu/item/menu.item.tsx b/frontend/antd/menu/item/menu.item.tsx index e86fb779..7d26d8ee 100644 --- a/frontend/antd/menu/item/menu.item.tsx +++ b/frontend/antd/menu/item/menu.item.tsx @@ -1,11 +1,14 @@ import { sveltify } from '@svelte-preprocess-react'; import React from 'react'; import { type MenuItemProps } from 'antd'; +import type { SubMenuProps } from 'antd/lib/menu'; import cls from 'classnames'; import { ItemHandler, type ItemHandlerProps } from '../context'; -export const MenuItem = sveltify((props) => { +export const MenuItem = sveltify< + MenuItemProps & SubMenuProps & ItemHandlerProps +>((props) => { return ( {...props} diff --git a/frontend/antd/popconfirm/popconfirm.tsx b/frontend/antd/popconfirm/popconfirm.tsx index a1708592..c01b288a 100644 --- a/frontend/antd/popconfirm/popconfirm.tsx +++ b/frontend/antd/popconfirm/popconfirm.tsx @@ -47,10 +47,10 @@ export const Popconfirm = sveltify< props.cancelButtonProps?.icon ), }} - title={slots.title ? : props.title} + title={slots.title ? : props.title} description={ slots.description ? ( - + ) : ( props.description ) diff --git a/frontend/antd/popover/popover.tsx b/frontend/antd/popover/popover.tsx index f9fb0341..c22a4ec9 100644 --- a/frontend/antd/popover/popover.tsx +++ b/frontend/antd/popover/popover.tsx @@ -16,9 +16,15 @@ export const Popover = sveltify< {...props} afterOpenChange={afterOpenChangeFunction} getPopupContainer={getPopupContainerFunction} - title={slots.title ? : props.title} + title={ + slots.title ? : props.title + } content={ - slots.content ? : props.content + slots.content ? ( + + ) : ( + props.content + ) } > {children} diff --git a/frontend/antd/radio/button/radio.button.tsx b/frontend/antd/radio/button/radio.button.tsx index d74e5e9a..ddf3993b 100644 --- a/frontend/antd/radio/button/radio.button.tsx +++ b/frontend/antd/radio/button/radio.button.tsx @@ -21,8 +21,8 @@ export const Radio = sveltify< } ref={elRef} onChange={(e) => { - onChange?.(e); onValueChange(e.target.checked); + onChange?.(e); }} /> ); diff --git a/frontend/antd/radio/group/radio.group.tsx b/frontend/antd/radio/group/radio.group.tsx index ea8cfa60..b6b5ef2a 100644 --- a/frontend/antd/radio/group/radio.group.tsx +++ b/frontend/antd/radio/group/radio.group.tsx @@ -31,8 +31,8 @@ export const RadioGroup = sveltify< ); }, [optionItems, options])} onChange={(e) => { - onChange?.(e); onValueChange(e.target.value); + onChange?.(e); }} > diff --git a/frontend/antd/radio/radio.tsx b/frontend/antd/radio/radio.tsx index d020d41b..4b29521b 100644 --- a/frontend/antd/radio/radio.tsx +++ b/frontend/antd/radio/radio.tsx @@ -21,8 +21,8 @@ export const Radio = sveltify< } ref={elRef} onChange={(e) => { - onChange?.(e); onValueChange(e.target.checked); + onChange?.(e); }} /> ); diff --git a/frontend/antd/rate/rate.tsx b/frontend/antd/rate/rate.tsx index b643902f..071060a9 100644 --- a/frontend/antd/rate/rate.tsx +++ b/frontend/antd/rate/rate.tsx @@ -27,8 +27,8 @@ export const Rate = sveltify< {...props} ref={elRef} onChange={(v) => { - onChange?.(v); onValueChange(v); + onChange?.(v); }} character={ slots.character diff --git a/frontend/antd/segmented/segmented.tsx b/frontend/antd/segmented/segmented.tsx index 9389dc58..fcc49d4d 100644 --- a/frontend/antd/segmented/segmented.tsx +++ b/frontend/antd/segmented/segmented.tsx @@ -24,8 +24,8 @@ export const Segmented = sveltify< { - onChange?.(v); onValueChange(v as string | number); + onChange?.(v); }} options={useMemo(() => { // ['label','icon'] diff --git a/frontend/antd/select/select.tsx b/frontend/antd/select/select.tsx index 8615f3a5..1e13fa4c 100644 --- a/frontend/antd/select/select.tsx +++ b/frontend/antd/select/select.tsx @@ -76,8 +76,8 @@ export const Select = sveltify< ); }, [resolvedSlotItems, options])} onChange={(v, ...args) => { - onChange?.(v, ...args); onValueChange(v as string); + onChange?.(v, ...args); }} allowClear={ slots['allowClear.clearIcon'] diff --git a/frontend/antd/slider/slider.tsx b/frontend/antd/slider/slider.tsx index 5b11bb16..ae1c413f 100644 --- a/frontend/antd/slider/slider.tsx +++ b/frontend/antd/slider/slider.tsx @@ -55,8 +55,8 @@ export const Slider = sveltify< ...props }) => { const onSliderChange = (v: number | number[]) => { - onChange?.(v as any); onValueChange(v); + onChange?.(v as any); }; const tooltipGetPopupContainerFunction = useFunction( tooltip?.getPopupContainer diff --git a/frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx b/frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx index b873f444..ffc5147a 100644 --- a/frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx +++ b/frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx @@ -21,8 +21,8 @@ export const CheckableTag = sveltify< {...props} icon={slots.icon ? : props.icon} onChange={(v) => { - onChange?.(v); onValueChange(v); + onChange?.(v); }} > {targets.length > 0 ? children : label} diff --git a/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx b/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx index bae15003..0e7aeb1e 100644 --- a/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx +++ b/frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx @@ -137,8 +137,8 @@ export const TimeRangePicker = sveltify< }} onChange={(dates, ...args) => { const formattedDates = formatDates(dates); - onChange?.(formattedDates, ...args); onValueChange(formattedDates); + onChange?.(formattedDates, ...args); }} onCalendarChange={(dates, ...args) => { const formattedDates = formatDates(dates); diff --git a/frontend/antd/time-picker/time-picker.tsx b/frontend/antd/time-picker/time-picker.tsx index a7e8b7e4..23b65645 100644 --- a/frontend/antd/time-picker/time-picker.tsx +++ b/frontend/antd/time-picker/time-picker.tsx @@ -134,8 +134,8 @@ export const TimePicker = sveltify< }} onChange={(date, ...args) => { const formattedDate = formatDate(date); - onChange?.(formattedDate, ...args); onValueChange(formattedDate as number); + onChange?.(formattedDate, ...args); }} onCalendarChange={(date, ...args) => { const formattedDate = formatDate(date); diff --git a/frontend/antd/tooltip/tooltip.tsx b/frontend/antd/tooltip/tooltip.tsx index b06d47b6..d236ced6 100644 --- a/frontend/antd/tooltip/tooltip.tsx +++ b/frontend/antd/tooltip/tooltip.tsx @@ -14,7 +14,9 @@ export const Tooltip = sveltify, ['title']>( {...props} afterOpenChange={afterOpenChangeFunction} getPopupContainer={getPopupContainerFunction} - title={slots.title ? : props.title} + title={ + slots.title ? : props.title + } > {children} diff --git a/frontend/antd/transfer/transfer.tsx b/frontend/antd/transfer/transfer.tsx index b55eabc4..45c01a8f 100644 --- a/frontend/antd/transfer/transfer.tsx +++ b/frontend/antd/transfer/transfer.tsx @@ -44,8 +44,8 @@ export const Transfer = sveltify< { - onChange?.(targetKeys, ...args); onValueChange(targetKeys as (string | number)[]); + onChange?.(targetKeys, ...args); }} selectionsIcon={ slots.selectionsIcon ? ( diff --git a/frontend/antd/tree-select/tree-select.tsx b/frontend/antd/tree-select/tree-select.tsx index f8aa25d2..8dbf1864 100644 --- a/frontend/antd/tree-select/tree-select.tsx +++ b/frontend/antd/tree-select/tree-select.tsx @@ -150,8 +150,8 @@ export const TreeSelect = sveltify< {...omitUndefinedProps(componentProps)} ref={elRef} onChange={(v, ...args) => { - onChange?.(v, ...args); onValueChange(v as string | string[]); + onChange?.(v, ...args); }} /> diff --git a/frontend/antd/typography/link/Index.svelte b/frontend/antd/typography/link/Index.svelte index 76b81ad1..62e0e04f 100644 --- a/frontend/antd/typography/link/Index.svelte +++ b/frontend/antd/typography/link/Index.svelte @@ -1,8 +1,9 @@ diff --git a/frontend/antd/typography/text/Index.svelte b/frontend/antd/typography/text/Index.svelte index 8b10e766..593be384 100644 --- a/frontend/antd/typography/text/Index.svelte +++ b/frontend/antd/typography/text/Index.svelte @@ -1,8 +1,9 @@ diff --git a/frontend/antd/typography/title/Index.svelte b/frontend/antd/typography/title/Index.svelte index fc54916e..446ca408 100644 --- a/frontend/antd/typography/title/Index.svelte +++ b/frontend/antd/typography/title/Index.svelte @@ -1,8 +1,9 @@ diff --git a/frontend/antdx/bubble/list/utils.tsx b/frontend/antdx/bubble/list/utils.tsx index 80fbbe15..9bbf639c 100644 --- a/frontend/antdx/bubble/list/utils.tsx +++ b/frontend/antdx/bubble/list/utils.tsx @@ -96,7 +96,7 @@ export function useRole( ]), ]; if (roleKeys.length > 0) { - return Object.keys(role).reduce( + return roleKeys.reduce( (acc, key) => { if (typeof role[key] === 'string') { const functionRole = createFunction(role[key]); diff --git a/frontend/antdx/code-highlighter/code-highlighter.tsx b/frontend/antdx/code-highlighter/code-highlighter.tsx index dfaa74d4..0bddc2e8 100644 --- a/frontend/antdx/code-highlighter/code-highlighter.tsx +++ b/frontend/antdx/code-highlighter/code-highlighter.tsx @@ -1,14 +1,14 @@ import { sveltify } from '@svelte-preprocess-react'; -import React from 'react'; -import { - CodeHighlighter as XCodeHighlighter, - type CodeHighlighterProps, -} from '@ant-design/x'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; +import React from 'react'; import { materialDark, materialLight, } from 'react-syntax-highlighter/dist/esm/styles/prism'; +import { + CodeHighlighter as XCodeHighlighter, + type CodeHighlighterProps, +} from '@ant-design/x'; const customDarkStyle = { ...materialDark, diff --git a/frontend/antdx/file-card/file-card.tsx b/frontend/antdx/file-card/file-card.tsx index 63409623..a2e8459e 100644 --- a/frontend/antdx/file-card/file-card.tsx +++ b/frontend/antdx/file-card/file-card.tsx @@ -59,6 +59,7 @@ export const FileCard = sveltify< mask={slots.mask ? : props.mask} spinProps={{ ...props.spinProps, + size: props.spinProps?.size || 'default', icon: slots['spinProps.icon'] ? ( ) : ( diff --git a/frontend/antdx/folder/folder.tsx b/frontend/antdx/folder/folder.tsx index 3fa9a688..31e6dcda 100644 --- a/frontend/antdx/folder/folder.tsx +++ b/frontend/antdx/folder/folder.tsx @@ -44,7 +44,7 @@ export const Folder = sveltify< useDirectoryIconItems<['directoryIcons']>(); const previewRenderFunction = useFunction(previewRender, true); const previewTitleFunction = useFunction(previewTitle, true); - + return ( <>
{children}
diff --git a/frontend/antdx/sender/Index.svelte b/frontend/antdx/sender/Index.svelte index 8b9df304..26798393 100644 --- a/frontend/antdx/sender/Index.svelte +++ b/frontend/antdx/sender/Index.svelte @@ -70,7 +70,7 @@ const upload = async (files: File[]) => { return ( - ((await proceedProps.additionalProps.gradio.client.upload( + ((await proceedProps.gradio.shared.client.upload( await prepare_files(files), proceedProps.gradio.shared.root )) as FileData[]) || [] diff --git a/frontend/antdx/suggestion/suggestion.tsx b/frontend/antdx/suggestion/suggestion.tsx index 2ab4655c..52d6001c 100644 --- a/frontend/antdx/suggestion/suggestion.tsx +++ b/frontend/antdx/suggestion/suggestion.tsx @@ -125,6 +125,7 @@ export const Suggestion = sveltify< setOpen(props.open); } }, [props.open]); + return ( <> ; as_item?: string | undefined; _internal: Record; + theme_config?: any; + theme?: any; }>(() => props); const getProceedProps = processProps(() => { @@ -28,6 +30,7 @@ elem_classes, elem_id, elem_style, + theme_config, ...restProps } = getComponentProps(); return { @@ -40,6 +43,7 @@ elem_id, elem_classes, elem_style, + themeConfig: theme_config, }; }); const proceedProps = $derived(getProceedProps()); @@ -59,6 +63,9 @@ {...proceedProps.additionalProps} slots={slots.value} component={XXProvider} + theme={proceedProps.additionalProps.theme || + proceedProps.restProps.theme || + proceedProps.themeConfig} themeMode={proceedProps.gradio.shared.theme || 'light'} > {@render children?.()} diff --git a/frontend/fixtures.d.ts b/frontend/fixtures.d.ts index 88da115c..1be6f19c 100644 --- a/frontend/fixtures.d.ts +++ b/frontend/fixtures.d.ts @@ -36,8 +36,8 @@ interface Element { _reactElement: React.ReactElement & { props: Record; }; - _effects: (() => void)[]; - _registerEffect: (cb: () => void) => () => void; + _effects: ((props: Record) => void)[]; + _registerEffect: (cb: (props: Record) => void) => () => void; } declare module '*.svelte' { diff --git a/frontend/package.json b/frontend/package.json index eb08a248..1d7c4b6b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,7 +13,7 @@ "@gradio/client": "2.1.0", "@gradio/preview": "0.15.2", "@gradio/statustracker": "^0.12.5", - "@gradio/utils": "0.11.3", + "@gradio/utils": "0.12.0", "@monaco-editor/react": "^4.7.0", "amuchina": "^1.0.12", "antd": "^6.3.3", @@ -22,9 +22,9 @@ "dequal": "^2.0.2", "github-slugger": "^2.0.0", "immer": "^11.1.4", - "katex": "^0.16.38", + "katex": "^0.16.40", "lodash-es": "^4.17.23", - "marked": "^17.0.4", + "marked": "^17.0.5", "marked-gfm-heading-id": "^4.1.3", "marked-highlight": "^2.2.3", "mermaid": "^11.13.0", @@ -34,7 +34,7 @@ "react": "^19.2.4", "react-dom": "^19.2.4", "react-syntax-highlighter": "^16.1.1", - "svelte": "5.53.9", + "svelte": "5.55.0", "svelte-i18n": "^4.0.1", "wavesurfer.js": "^7.12.4" }, diff --git a/frontend/pro/chatbot/Index.svelte b/frontend/pro/chatbot/Index.svelte index f269f5da..2d0ec8d2 100644 --- a/frontend/pro/chatbot/Index.svelte +++ b/frontend/pro/chatbot/Index.svelte @@ -72,21 +72,18 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} - value={proceedProps.value} + value={proceedProps.value || []} onValueChange={(v) => { updateProps({ value: v, }); }} rootUrl={proceedProps.gradio.shared.root} - apiPrefix={proceedProps.gradio.shared.proxy_url} - themeMode={proceedProps.additionalProps.gradio?.theme} + apiPrefix={proceedProps.gradio.shared.api_prefix} + themeMode={proceedProps.gradio.shared.theme || 'light'} slots={slots.value} > {@render children?.()} {/await} {/if} - - diff --git a/frontend/pro/chatbot/chatbot-footer.tsx b/frontend/pro/chatbot/chatbot-footer.tsx index ee5bdf9f..12443bc2 100644 --- a/frontend/pro/chatbot/chatbot-footer.tsx +++ b/frontend/pro/chatbot/chatbot-footer.tsx @@ -63,7 +63,6 @@ export const CopyButton: React.FC<{ () => getCopyText(content, rootUrl, apiPrefix), [content, apiPrefix, rootUrl] ); - const copyButtonRef = useRef(null); return ( { - const handleActionRef = useRef<() => void>(); + const handleActionRef = useRef<(() => void) | null>(null); const getActionProps = () => { return isObject(actionOrActionObject) ? { @@ -274,7 +272,7 @@ export const ChatbotFooter: React.FC = ({ }) => { if (isEditing) { return ( - +
- - )} -
- ); + } as ChatbotFileContentItem; }; export const FileMessage: React.FC = ({ @@ -100,10 +47,12 @@ export const FileMessage: React.FC = ({ rootUrl, options, }) => { - const { imageProps } = options; + const { imageProps, videoProps, audioProps } = options; + const { token } = theme.useToken(); return ( = ({ const item = resolveItem(file, rootUrl, apiPrefix); return ( - - - + } + style={{ color: token.colorWhite }} + variant="link" + color="default" + size="small" + href={item.url} + target="_blank" + rel="noopener noreferrer" + /> + } + rootUrl={rootUrl} + apiPrefix={apiPrefix} + imageProps={{ + styles: { + cover: { + borderRadius: token.borderRadius, + }, + image: { + height: 68, + width: 68, + borderRadius: token.borderRadius, + }, + ...imageProps?.styles, + }, + ...imageProps, + }} + videoProps={videoProps} + audioProps={{ + style: { + width: 268, + ...audioProps?.style, + }, + ...audioProps, + }} + /> ); })} diff --git a/frontend/pro/chatbot/type.ts b/frontend/pro/chatbot/type.ts index eb2c2cf1..e20a8801 100644 --- a/frontend/pro/chatbot/type.ts +++ b/frontend/pro/chatbot/type.ts @@ -1,16 +1,17 @@ import type { + BubbleItemType, BubbleProps, - PromptProps, + FileCardProps, + PromptsItemType, PromptsProps, WelcomeProps, } from '@ant-design/x'; import type { Attachment } from '@ant-design/x/es/attachments'; -import type { FileListProps } from '@ant-design/x/es/attachments/FileList'; -import type { BubbleDataType } from '@ant-design/x/es/bubble/BubbleList'; import type { MarkdownProps } from '@globals/components'; import type { FileData } from '@gradio/client'; import type { AvatarProps, + DividerProps, FlexProps, PopconfirmProps, TooltipProps, @@ -39,8 +40,14 @@ export interface ChatbotWelcomeConfig extends Omit { elem_classes?: string | string[]; } -export type ChatbotFileContent = (string | (Attachment & FileData))[]; -export type ChatbotSuggestionContent = PromptProps[]; +export type ChatbotFileContent = ( + | string + | (Attachment & + FileData & { + type?: FileCardProps['type']; + }) +)[]; +export type ChatbotSuggestionContent = PromptsItemType[]; export type ChatbotToolContent = string; export type ChatbotTextContent = string; @@ -53,7 +60,9 @@ export type ChatbotToolContentConfig = ChatbotMarkdownConfig & { title?: string; }; export type ChatbotFileContentConfig = FlexProps & { - imageProps?: FileListProps['imageProps']; + imageProps?: FileCardProps['imageProps']; + videoProps?: FileCardProps['videoProps']; + audioProps?: FileCardProps['audioProps']; }; export type ChatbotSuggestionContentConfig = ChatbotPromptsConfig; @@ -126,7 +135,13 @@ export interface ChatbotMessageContentObject { } export interface ChatbotMessage extends ChatbotBotConfig { - role: 'user' | 'assistant' | 'system' | 'chatbot-internal-welcome'; + role: + | 'user' + | 'assistant' + | 'system' + | 'divider' + | 'chatbot-internal-welcome'; + divider_props?: DividerProps; key?: string | number; [lastMessageSymbol]?: boolean; [messageHeaderSymbol]?: string; @@ -163,19 +178,19 @@ export interface EditData { export interface DeleteData { index: number; - value: BubbleDataType['content']; + value: BubbleItemType['content']; } export interface RetryData { index: number; - value: BubbleDataType['content']; + value: BubbleItemType['content']; } export interface SuggestionData { index: number; - value: PromptProps; + value: PromptsItemType; } export interface WelcomePromptData { - value: PromptProps; + value: PromptsItemType; } diff --git a/frontend/pro/monaco-editor/Index.svelte b/frontend/pro/monaco-editor/Index.svelte index 145df6c0..461f8021 100644 --- a/frontend/pro/monaco-editor/Index.svelte +++ b/frontend/pro/monaco-editor/Index.svelte @@ -20,11 +20,7 @@ updateProps, } = getProps<{ additional_props?: Record; - - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; + _internal: {}; value?: string | undefined; _loader?: { mode?: 'cdn' | 'local'; @@ -73,20 +69,23 @@ : undefined ); + // Define this method outside of the $ block to avoid re-rendering + const onValueChange = (v: string | undefined) => { + updateProps({ + value: v, + }); + }; + const editorProps = $derived({ style: proceedProps.elem_style, className: cls(proceedProps.elem_classes, 'ms-gr-pro-monaco-editor'), id: proceedProps.elem_id, ...proceedProps.restProps, ...proceedProps.additionalProps, - onValueChange: (v: string | undefined) => { - updateProps({ - value: v, - }); - }, + onValueChange, value: proceedProps.value, slots: slots.value, - themeMode: proceedProps.additionalProps.gradio?.theme, + themeMode: proceedProps.gradio.shared.theme, }); diff --git a/frontend/pro/monaco-editor/diff-editor/Index.svelte b/frontend/pro/monaco-editor/diff-editor/Index.svelte index d29e8d0d..5c22978a 100644 --- a/frontend/pro/monaco-editor/diff-editor/Index.svelte +++ b/frontend/pro/monaco-editor/diff-editor/Index.svelte @@ -7,16 +7,26 @@ import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; import cls from 'classnames'; - const AwaitedDiffEditor = importComponent( + import { initCDNLoader, initLocalLoader } from '../loader'; + + const AwaitedMonacoDiffEditor = importComponent( () => import('./monaco-editor.diff-editor') ); const props = $props(); - const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ + const { + gradio, + getComponentProps, + getAdditionalProps, + children, + updateProps, + } = getProps<{ additional_props?: Record; - as_item?: string | undefined; - _internal: { - layout?: boolean; + _internal: {}; + value?: string | undefined; + _loader?: { + mode?: 'cdn' | 'local'; + cdn_url?: string; }; }>(() => props); @@ -28,6 +38,8 @@ elem_classes, elem_id, elem_style, + value, + _loader, ...restProps } = getComponentProps(); return { @@ -40,27 +52,51 @@ elem_id, elem_classes, elem_style, + value, + _loader, }; }); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); + + const mode = $derived(proceedProps._loader?.mode); + const cdn_url = $derived(proceedProps._loader?.cdn_url); + + const awaitedLoader = $derived( + mode === 'local' + ? initLocalLoader() + : cdn_url + ? initCDNLoader(cdn_url) + : undefined + ); + + // Define this method outside of the $ block to avoid re-rendering + const onValueChange = (v: string | undefined) => { + updateProps({ + value: v, + }); + }; + + const editorProps = $derived({ + style: proceedProps.elem_style, + className: cls(proceedProps.elem_classes, 'ms-gr-pro-monaco-diff-editor'), + id: proceedProps.elem_id, + ...proceedProps.restProps, + ...proceedProps.additionalProps, + onValueChange, + value: proceedProps.value, + slots: slots.value, + themeMode: proceedProps.gradio.shared.theme, + }); {#if proceedProps.visible} - {#await AwaitedDiffEditor then DiffEditor} - - {@render children?.()} - + {#await awaitedLoader then} + {#await AwaitedMonacoDiffEditor then MonacoDiffEditor} + + {@render children?.()} + + {/await} {/await} {/if} diff --git a/frontend/pro/multimodal-input/Index.svelte b/frontend/pro/multimodal-input/Index.svelte index ec0f51c8..725ccba3 100644 --- a/frontend/pro/multimodal-input/Index.svelte +++ b/frontend/pro/multimodal-input/Index.svelte @@ -23,13 +23,8 @@ updateProps, } = getProps<{ additional_props?: Record; - - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; + _internal: {}; value?: MultimodalInputValue; - root?: string; key_press?: any; paste_file?: any; key_down?: any; @@ -45,7 +40,6 @@ elem_id, elem_style, value, - root, ...restProps } = getComponentProps(); return { @@ -59,7 +53,6 @@ elem_classes, elem_style, value, - root, }; }, { @@ -74,7 +67,7 @@ const upload = async (files: File[]) => { return ( - ((await proceedProps.additionalProps.gradio.client.upload( + ((await proceedProps.gradio.shared.client.upload( await prepare_files(files), proceedProps.gradio.shared.root )) as FileData[]) || [] @@ -91,7 +84,7 @@ {...proceedProps.restProps} {...proceedProps.additionalProps} slots={slots.value} - value={proceedProps.value} + value={proceedProps.additionalProps.value ?? proceedProps.value} onValueChange={(v) => { updateProps({ value: v, diff --git a/frontend/pro/multimodal-input/multimodal-input.tsx b/frontend/pro/multimodal-input/multimodal-input.tsx index 46bc85ec..7459f20b 100644 --- a/frontend/pro/multimodal-input/multimodal-input.tsx +++ b/frontend/pro/multimodal-input/multimodal-input.tsx @@ -11,6 +11,7 @@ import { } from '@ant-design/x'; import { type FileData } from '@gradio/client'; import { convertObjectKeyToCamelCase } from '@utils/convertToCamelCase'; +import { createFunction } from '@utils/createFunction'; import { useFunction } from '@utils/hooks/useFunction'; import { useMemoizedFn } from '@utils/hooks/useMemoizedFn'; import { useValueChange } from '@utils/hooks/useValueChange'; @@ -64,6 +65,13 @@ const formatChangedValue = ( }; }; +function getConfig(value: T): Partial> { + if (typeof value === 'object' && value !== null) { + return value as any; + } + return {} as any; +} + export const MultimodalInput = sveltify< Omit< SenderProps & @@ -84,7 +92,15 @@ export const MultimodalInput = sveltify< onSubmit?: (value: MultimodalInputChangedValue) => void; uploadConfig?: UploadConfig; }, - ['actions', 'header', 'prefix', 'footer'] + [ + 'suffix', + 'header', + 'prefix', + 'footer', + 'skill.title', + 'skill.toolTip.title', + 'skill.closable.closeIcon', + ] >( ({ onValueChange, @@ -106,7 +122,7 @@ export const MultimodalInput = sveltify< elRef, slots, mode, - // setSlotParams, + slotConfig, uploadConfig: uploadConfigProp, value: valueProp, ...senderProps @@ -115,8 +131,29 @@ export const MultimodalInput = sveltify< const suggestionOpen = useSuggestionOpenContext(); const recorderContainerRef = useRef(null); const [uploading, setUploading] = useState(false); - const actionsFunction = useFunction(senderProps.actions, true); + const suffixFunction = useFunction(senderProps.suffix, true); + const headerFunction = useFunction(senderProps.header, true); + const prefixFunction = useFunction(senderProps.prefix, true); const footerFunction = useFunction(senderProps.footer, true); + const supportSkill = + senderProps.skill || + slots['skill.title'] || + slots['skill.toolTip.title'] || + slots['skill.closable.closeIcon']; + const supportSkillTooltip = + slots['skill.toolTip.title'] || + typeof senderProps.skill?.toolTip === 'object'; + const skillTooltipConfig = getConfig(senderProps.skill?.toolTip); + const supportSkillClosable = + slots['skill.closable.closeIcon'] || senderProps.skill?.closable; + const skillClosableConfig = getConfig(senderProps.skill?.closable); + + const skillTooltipAfterOpenChangeFunction = useFunction( + skillTooltipConfig.afterOpenChange + ); + const skillTooltipGetPopupContainerFunction = useFunction( + skillTooltipConfig.getPopupContainer + ); const { start, stop, recording } = useRecorder({ container: recorderContainerRef.current, async onStop(blob) { @@ -312,7 +349,7 @@ export const MultimodalInput = sveltify< onChange?.(formatChangedValue(newValue)); setValue(newValue); }} - onPasteFile={async (_file, files) => { + onPasteFile={async (files) => { if (!(allowPasteFile ?? true)) { return; } @@ -321,24 +358,74 @@ export const MultimodalInput = sveltify< onPasteFile?.(filesData.map((url) => url.path)); } }} - prefix={ - <> - {allowUpload && mode !== 'block' ? uploadHandlerNode : null} - {slots.prefix ? : null} - + skill={ + supportSkill + ? { + ...(senderProps.skill || {}), + title: slots['skill.title'] ? ( + + ) : ( + senderProps.skill?.title + ), + value: senderProps.skill?.value || '', + toolTip: supportSkillTooltip + ? { + ...skillTooltipConfig, + afterOpenChange: skillTooltipAfterOpenChangeFunction, + getPopupContainer: + skillTooltipGetPopupContainerFunction, + title: slots['showSorterTooltip.title'] ? ( + + ) : ( + skillTooltipConfig.title + ), + } + : senderProps.skill?.toolTip, + closable: supportSkillClosable + ? { + ...skillClosableConfig, + closeIcon: slots['skill.closable.closeIcon'] ? ( + + ) : ( + skillClosableConfig.closeIcon + ), + } + : senderProps.skill?.closable, + } + : undefined } - actions={ + slotConfig={slotConfig?.map((c) => { + return { + ...c, + formatResult: createFunction(c.formatResult), + customRender: + c.type === 'custom' + ? createFunction(c.customRender) + : undefined, + }; + })} + suffix={ mode === 'block' ? ( false - ) : slots.actions ? ( - + ) : slots.suffix ? ( + ) : ( - actionsFunction || senderProps.actions + suffixFunction || senderProps.suffix ) } + prefix={ + <> + {allowUpload && mode !== 'block' ? uploadHandlerNode : null} + {slots.prefix ? ( + + ) : ( + prefixFunction || senderProps.prefix + )} + + } footer={ mode === 'block' ? ( - ({ components }) => { + (_oriNode, { components }) => { const { SendButton, SpeechButton, LoadingButton } = components; return ( @@ -519,7 +606,7 @@ export const MultimodalInput = sveltify< ) : slots.header ? ( ) : ( - senderProps.header + headerFunction || senderProps.header ) } /> diff --git a/frontend/pro/web-sandbox/Index.svelte b/frontend/pro/web-sandbox/Index.svelte index 06f8e685..8e952d66 100644 --- a/frontend/pro/web-sandbox/Index.svelte +++ b/frontend/pro/web-sandbox/Index.svelte @@ -14,11 +14,7 @@ const props = $props(); const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; - - as_item?: string | undefined; - _internal: { - layout?: boolean; - }; + _internal: {}; value?: WebSandboxProps['value']; compile_error?: any; compile_success?: any; @@ -71,7 +67,7 @@ {...proceedProps.additionalProps} value={proceedProps.value} slots={slots.value} - themeMode={proceedProps.additionalProps.gradio?.theme} + themeMode={proceedProps.gradio.shared.theme || 'light'} > {@render children?.()} diff --git a/frontend/svelte-preprocess-react/component/props.svelte.ts b/frontend/svelte-preprocess-react/component/props.svelte.ts index 7721f2db..5cc08109 100644 --- a/frontend/svelte-preprocess-react/component/props.svelte.ts +++ b/frontend/svelte-preprocess-react/component/props.svelte.ts @@ -13,6 +13,7 @@ import type React from 'react'; import { SvelteSet } from 'svelte/reactivity'; import { Gradio, type SharedProps } from '@gradio/utils'; import { convertToCamelCase } from '@utils/convertToCamelCase'; +import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { isPlainObject, mapKeys, omit } from 'lodash-es'; import { type Snippet, untrack } from 'svelte'; @@ -337,22 +338,25 @@ export function getProps< }; const getComponentProps = () => - omit( - { - elem_id: gradio.shared.elem_id as string | undefined, - elem_classes: gradio.shared.elem_classes as - | string - | string[] - | undefined, - elem_style: gradio.props.elem_style as React.CSSProperties, - visible: gradio.shared.visible, - attached_events: gradio.shared.attached_events, - as_item: gradio.props.as_item as string | undefined, - _internal: gradio.props._internal as {}, - loading_status: gradio.shared.loading_status, - ...gradio.props, - }, - ['i18n', 'api_url', 'name', 'additional_props'] + omitUndefinedProps( + omit( + { + elem_id: gradio.shared.elem_id as string | undefined, + elem_classes: gradio.shared.elem_classes as + | string + | string[] + | undefined, + elem_style: gradio.props.elem_style as React.CSSProperties, + visible: gradio.shared.visible, + attached_events: gradio.shared.attached_events, + as_item: gradio.props.as_item as string | undefined, + _internal: gradio.props._internal as {}, + loading_status: gradio.shared.loading_status, + ...gradio.props, + label: gradio.shared.label, + }, + ['i18n', 'api_url', 'name', 'additional_props'] + ) ); let additionalProps = $state( diff --git a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts index 47c16809..bb1e70f5 100644 --- a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts +++ b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts @@ -11,6 +11,7 @@ import React, { useState, } from 'react'; import { createFunction } from '@utils/createFunction'; +import { useMemoizedEqualValue } from '@utils/hooks/useMemoizedEqualValue'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { patchProps } from '@utils/patchProps'; @@ -41,37 +42,28 @@ export type BridgeProps = { ) => React.ReactPortal; }; +const watch = (_value: any) => {}; + const Bridge: React.FC = ({ node, createPortal }) => { const fresh = useRef(false); - const [result, setResult] = useState(() => { - return React.createElement(BridgeInternal, { - node, - createPortal, - }); - }); + const [, rerender] = useState({}); useEffect( () => $effect.root(() => { $effect(() => { - fresh.current = true; - setResult( - React.createElement(BridgeInternal, { - // read the object when the property of node changes - node: $state.snapshot(node) as TreeNode, - - createPortal, - }) - ); + watch(node.props); + if (!fresh.current) { + fresh.current = true; + return; + } + rerender({}); }); }), + // eslint-disable-next-line react-hooks/exhaustive-deps [] ); - if (fresh.current) { - fresh.current = false; - return result; - } return React.createElement(BridgeInternal, { node, createPortal, @@ -157,6 +149,7 @@ function BridgeInternal({ autoCompleteContext, suggestionContext, ]); + const memoizedProps = useMemoizedEqualValue(props); if (svelteChildren) { // console.log(childrenSource); @@ -182,6 +175,7 @@ function BridgeInternal({ }), ]; } + // eslint-disable-next-line react/no-children-prop const element = createElement(BridgeContext, { props, @@ -206,10 +200,10 @@ function BridgeInternal({ useEffect(() => { if (portalTarget) { portalTarget._effects.forEach((cb) => { - cb(); + cb(memoizedProps); }); } - }, [portalTarget, props]); + }, [portalTarget, memoizedProps]); if (portalTarget) { return createPortal(element, portalTarget); diff --git a/frontend/utils/patchProps.tsx b/frontend/utils/patchProps.tsx index d50a1f37..ad97757b 100644 --- a/frontend/utils/patchProps.tsx +++ b/frontend/utils/patchProps.tsx @@ -22,7 +22,7 @@ export function applyPatchToProps(props: Record) { } // ==== SLOT PROPS ==== -// eslint-disable-next-line react-refresh/only-export-components + const PatchSlotPropsWrapper: React.FC<{ children: (props: Record) => React.ReactNode; }> = ({ children, ...args }) => { diff --git a/package.json b/package.json index 584418f9..2b764a89 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,8 @@ "prettier-plugin-packagejson": "^3.0.2", "prettier-plugin-svelte": "^3.5.1", "rimraf": "^6.1.3", - "stylelint": "^17.4.0", - "svelte": "5.53.9", + "stylelint": "^17.5.0", + "svelte": "5.55.0", "svelte-check": "^4.4.5", "tslib": "^2.8.1", "tsx": "^4.21.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53194041..6bffa348 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,7 +40,7 @@ importers: version: 25.5.0 eslint: specifier: ^9.39.3 - version: 9.39.3(jiti@2.6.1) + version: 9.39.4(jiti@2.6.1) husky: specifier: ^9.1.7 version: 9.1.7 @@ -61,19 +61,19 @@ importers: version: 3.0.2(prettier@3.8.1) prettier-plugin-svelte: specifier: ^3.5.1 - version: 3.5.1(prettier@3.8.1)(svelte@5.53.9) + version: 3.5.1(prettier@3.8.1)(svelte@5.55.0) rimraf: specifier: ^6.1.3 version: 6.1.3 stylelint: - specifier: ^17.4.0 - version: 17.4.0(typescript@5.9.3) + specifier: ^17.5.0 + version: 17.5.0(typescript@5.9.3) svelte: - specifier: 5.53.9 - version: 5.53.9 + specifier: 5.55.0 + version: 5.55.0 svelte-check: specifier: ^4.4.5 - version: 4.4.5(picomatch@4.0.3)(svelte@5.53.9)(typescript@5.9.3) + version: 4.4.5(picomatch@4.0.3)(svelte@5.55.0)(typescript@5.9.3) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -110,43 +110,43 @@ importers: dependencies: '@eslint/compat': specifier: ^2.0.3 - version: 2.0.3(eslint@9.39.3(jiti@2.6.1)) + version: 2.0.3(eslint@9.39.4(jiti@2.6.1)) '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@9.39.3(jiti@2.6.1)) + version: 10.0.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/parser': - specifier: ^8.57.1 - version: 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.57.2 + version: 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.39.3(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.4(jiti@2.6.1)) eslint-import-resolver-typescript: specifier: ^4.4.4 - version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) + version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) + version: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-jsx-a11y: specifier: ^6.10.2 - version: 6.10.2(eslint@9.39.3(jiti@2.6.1)) + version: 6.10.2(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-prettier: specifier: 5.5.5 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.6.1)))(eslint@9.39.3(jiti@2.6.1))(prettier@3.8.1) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(prettier@3.8.1) eslint-plugin-react: specifier: ^7.37.5 - version: 7.37.5(eslint@9.39.3(jiti@2.6.1)) + version: 7.37.5(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-hooks: specifier: ^7.0.1 - version: 7.0.1(eslint@9.39.3(jiti@2.6.1)) + version: 7.0.1(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-refresh: specifier: ^0.5.2 - version: 0.5.2(eslint@9.39.3(jiti@2.6.1)) + version: 0.5.2(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-simple-import-sort: specifier: ^12.1.0 - version: 12.1.1(eslint@9.39.3(jiti@2.6.1)) + version: 12.1.1(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-svelte: - specifier: ^3.15.2 - version: 3.15.2(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.9)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)) + specifier: ^3.16.0 + version: 3.16.0(eslint@9.39.4(jiti@2.6.1))(svelte@5.55.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)) globals: specifier: ^17.4.0 version: 17.4.0 @@ -161,29 +161,29 @@ importers: version: 0.1.2 stylelint-config-standard: specifier: ^40.0.0 - version: 40.0.0(stylelint@17.4.0(typescript@5.9.3)) + version: 40.0.0(stylelint@17.5.0(typescript@5.9.3)) stylelint-declaration-block-no-ignored-properties: specifier: ^3.0.0 - version: 3.0.0(stylelint@17.4.0(typescript@5.9.3)) + version: 3.0.0(stylelint@17.5.0(typescript@5.9.3)) stylelint-order: specifier: ^8.1.1 - version: 8.1.1(stylelint@17.4.0(typescript@5.9.3)) + version: 8.1.1(stylelint@17.5.0(typescript@5.9.3)) stylelint-prettier: specifier: ^5.0.3 - version: 5.0.3(prettier@3.8.1)(stylelint@17.4.0(typescript@5.9.3)) + version: 5.0.3(prettier@3.8.1)(stylelint@17.5.0(typescript@5.9.3)) svelte-eslint-parser: specifier: ^1.6.0 - version: 1.6.0(svelte@5.53.9) + version: 1.6.0(svelte@5.55.0) typescript-eslint: - specifier: ^8.57.1 - version: 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.57.2 + version: 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) devDependencies: '@types/eslint': specifier: ^9.6.1 version: 9.6.1 '@types/eslint__js': specifier: ^9.14.0 - version: 9.14.0(eslint@9.39.3(jiti@2.6.1)) + version: 9.14.0(eslint@9.39.4(jiti@2.6.1)) frontend: dependencies: @@ -204,13 +204,13 @@ importers: version: 2.1.0 '@gradio/preview': specifier: 0.15.2 - version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.53.9)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.55.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@gradio/statustracker': specifier: ^0.12.5 - version: 0.12.5(svelte@5.53.9) + version: 0.12.5(svelte@5.55.0) '@gradio/utils': - specifier: 0.11.3 - version: 0.11.3(svelte@5.53.9) + specifier: 0.12.0 + version: 0.12.0(svelte@5.55.0) '@monaco-editor/react': specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -236,20 +236,20 @@ importers: specifier: ^11.1.4 version: 11.1.4 katex: - specifier: ^0.16.38 - version: 0.16.38 + specifier: ^0.16.40 + version: 0.16.40 lodash-es: specifier: ^4.17.23 version: 4.17.23 marked: - specifier: ^17.0.4 - version: 17.0.4 + specifier: ^17.0.5 + version: 17.0.5 marked-gfm-heading-id: specifier: ^4.1.3 - version: 4.1.3(marked@17.0.4) + version: 4.1.3(marked@17.0.5) marked-highlight: specifier: ^2.2.3 - version: 2.2.3(marked@17.0.4) + version: 2.2.3(marked@17.0.5) mermaid: specifier: ^11.13.0 version: 11.13.0 @@ -272,11 +272,11 @@ importers: specifier: ^16.1.1 version: 16.1.1(react@19.2.4) svelte: - specifier: 5.53.9 - version: 5.53.9 + specifier: 5.55.0 + version: 5.55.0 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.53.9) + version: 4.0.1(svelte@5.55.0) wavesurfer.js: specifier: ^7.12.4 version: 7.12.4 @@ -570,11 +570,11 @@ packages: '@braintree/sanitize-url@7.1.2': resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} - '@cacheable/memory@2.0.7': - resolution: {integrity: sha512-RbxnxAMf89Tp1dLhXMS7ceft/PGsDl1Ip7T20z5nZ+pwIAsQ1p2izPjVG69oCLv/jfQ7HDPHTWK0c9rcAWXN3A==} + '@cacheable/memory@2.0.8': + resolution: {integrity: sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==} - '@cacheable/utils@2.3.4': - resolution: {integrity: sha512-knwKUJEYgIfwShABS1BX6JyJJTglAFcEU7EXqzTdiGCXur4voqkiJkdgZIQtWNFhynzDWERcTYv/sETMu3uJWA==} + '@cacheable/utils@2.4.0': + resolution: {integrity: sha512-PeMMsqjVq+bF0WBsxFBxr/WozBJiZKY0rUojuaCoIaKnEl3Ju1wfEwS+SV1DU/cSe8fqHIPiYJFif8T3MVt4cQ==} '@changesets/apply-release-plan@7.1.0': resolution: {integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==} @@ -747,8 +747,13 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.0.28': - resolution: {integrity: sha512-1NRf1CUBjnr3K7hu8BLxjQrKCxEe8FP/xmPTenAxCRZWVLbmGotkFvG9mfNpjA6k7Bw1bw4BilZq9cu19RA5pg==} + '@csstools/css-syntax-patches-for-csstree@1.1.1': + resolution: {integrity: sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true '@csstools/css-tokenizer@4.0.0': resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} @@ -1263,8 +1268,8 @@ packages: eslint: optional: true - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/config-helpers@0.4.2': @@ -1279,8 +1284,8 @@ packages: resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/eslintrc@3.3.4': - resolution: {integrity: sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==} + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/js@10.0.1': @@ -1292,8 +1297,8 @@ packages: eslint: optional: true - '@eslint/js@9.39.3': - resolution: {integrity: sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==} + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.7': @@ -1357,9 +1362,6 @@ packages: peerDependencies: svelte: ^5.48.0 - '@gradio/utils@0.11.3': - resolution: {integrity: sha512-k1X6HXcoOycvBHsXamCyiN21v40I88FjTgz1TsVF5Hb/vJoA1InHjT+Uo6vnt+aJ8UGtxjUMTBVFR/GOcgXB/Q==} - '@gradio/utils@0.12.0': resolution: {integrity: sha512-twy9fxEikjqxgtP3fk8voIDdey3nYFpJfmayDU7/IGn3C35nk+kL4dsJfEPbQ99BXmRgBecurSJEduOFptOCCQ==} @@ -2579,63 +2581,63 @@ packages: '@types/which@3.0.4': resolution: {integrity: sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==} - '@typescript-eslint/eslint-plugin@8.57.1': - resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==} + '@typescript-eslint/eslint-plugin@8.57.2': + resolution: {integrity: sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.1 + '@typescript-eslint/parser': ^8.57.2 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.57.1': - resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==} + '@typescript-eslint/parser@8.57.2': + resolution: {integrity: sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.57.1': - resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==} + '@typescript-eslint/project-service@8.57.2': + resolution: {integrity: sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.57.1': - resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} + '@typescript-eslint/scope-manager@8.57.2': + resolution: {integrity: sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.57.1': - resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} + '@typescript-eslint/tsconfig-utils@8.57.2': + resolution: {integrity: sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.57.1': - resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==} + '@typescript-eslint/type-utils@8.57.2': + resolution: {integrity: sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.57.1': - resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} + '@typescript-eslint/types@8.57.2': + resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.57.1': - resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==} + '@typescript-eslint/typescript-estree@8.57.2': + resolution: {integrity: sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.57.1': - resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==} + '@typescript-eslint/utils@8.57.2': + resolution: {integrity: sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.57.1': - resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} + '@typescript-eslint/visitor-keys@8.57.2': + resolution: {integrity: sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.9.2': @@ -3074,8 +3076,8 @@ packages: resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} engines: {node: '>=0.10.0'} - cacheable@2.3.2: - resolution: {integrity: sha512-w+ZuRNmex9c1TR9RcsxbfTKCjSL0rh1WA5SABbrWprIHeNBdmyQLSYonlDy9gpD+63XT8DgZ/wNh1Smvc9WnJA==} + cacheable@2.3.4: + resolution: {integrity: sha512-djgxybDbw9fL/ZWMI3+CE8ZilNxcwFkVtDc1gJ+IlOSSWkSMPQabhV/XCHTQ6pwwN6aivXPZ43omTooZiX06Ew==} call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} @@ -3323,15 +3325,6 @@ packages: resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} engines: {node: '>=4'} - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - cosmiconfig@9.0.1: resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} engines: {node: '>=14'} @@ -3356,8 +3349,8 @@ packages: resolution: {integrity: sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==} engines: {node: '>=12'} - css-tree@3.1.0: - resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} cssesc@3.0.0: @@ -3668,8 +3661,8 @@ packages: resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - devalue@5.6.3: - resolution: {integrity: sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==} + devalue@5.6.4: + resolution: {integrity: sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==} diff@4.0.4: resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} @@ -4096,8 +4089,8 @@ packages: peerDependencies: eslint: '>=5.0.0' - eslint-plugin-svelte@3.15.2: - resolution: {integrity: sha512-k4Nsjs3bHujeEnnckoTM4mFYR1e8Mb9l2rTwNdmYiamA+Tjzn8X+2F+fuSP2w4VbXYhn2bmySyACQYdmUDW2Cg==} + eslint-plugin-svelte@3.16.0: + resolution: {integrity: sha512-DJXxqpYZUxcE0SfYo8EJzV2ZC+zAD7fJp1n1HwcEMRR1cOEUYvjT9GuzJeNghMjgb7uxuK3IJAzI+x6zzUxO5A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 @@ -4122,8 +4115,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@9.39.3: - resolution: {integrity: sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==} + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -4152,8 +4145,8 @@ packages: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} - esrap@2.2.3: - resolution: {integrity: sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==} + esrap@2.2.4: + resolution: {integrity: sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg==} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -4307,14 +4300,14 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flat-cache@6.1.20: - resolution: {integrity: sha512-AhHYqwvN62NVLp4lObVXGVluiABTHapoB57EyegZVmazN+hhGhLTn3uZbOofoTw4DSDvVCadzzyChXhOAvy8uQ==} + flat-cache@6.1.21: + resolution: {integrity: sha512-2u7cJfSf7Th7NxEk/VzQjnPoglok2YCsevS7TSbJjcDQWJPbqUUnSYtriHSvtnq+fRZHy1s0ugk4ApnQyhPGoQ==} flatted@2.0.2: resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} @@ -4557,8 +4550,8 @@ packages: resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} engines: {node: '>=0.10.0'} - hashery@1.5.0: - resolution: {integrity: sha512-nhQ6ExaOIqti2FDWoEMWARUqIKyjr2VcZzXShrI+A3zpeiuPWzx6iPftt44LhP74E5sW36B75N6VHbvRtpvO6Q==} + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} engines: {node: '>=20'} hasown@2.0.2: @@ -4586,6 +4579,9 @@ packages: hookified@1.15.1: resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} + hookified@2.1.0: + resolution: {integrity: sha512-ootKng4eaxNxa7rx6FJv2YKef3DuhqbEj3l70oGXwddPQEEnISm50TEZQclqiLTAtilT2nu7TErtCO523hHkyg==} + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -5064,8 +5060,8 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} - katex@0.16.38: - resolution: {integrity: sha512-cjHooZUmIAUmDsHBN+1n8LaZdpmbj03LtYeYPyuYB7OuloiaeaV6N4LcfjcnHVzGWjVQmKrxxTrpDcmSzEZQwQ==} + katex@0.16.40: + resolution: {integrity: sha512-1DJcK/L05k1Y9Gf7wMcyuqFOL6BiY3vY0CFcAM/LPRN04NALxcl6u7lOWNsp3f/bCHWxigzQl6FbR95XJ4R84Q==} hasBin: true keyv@4.5.4: @@ -5379,8 +5375,8 @@ packages: engines: {node: '>= 20'} hasBin: true - marked@17.0.4: - resolution: {integrity: sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==} + marked@17.0.5: + resolution: {integrity: sha512-6hLvc0/JEbRjRgzI6wnT2P1XuM1/RrrDEX0kPt0N7jGm1133g6X7DlxFasUIx+72aKAr904GTxhSLDrd5DIlZg==} engines: {node: '>= 20'} hasBin: true @@ -5397,8 +5393,8 @@ packages: mdast-util-compact@1.0.4: resolution: {integrity: sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==} - mdn-data@2.12.2: - resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} memoizee@0.4.17: resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==} @@ -5459,8 +5455,8 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@3.1.4: - resolution: {integrity: sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} minimatch@9.0.9: resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} @@ -6068,8 +6064,8 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qified@0.6.0: - resolution: {integrity: sha512-tsSGN1x3h569ZSU1u6diwhltLyfUWDp3YbFHedapTmpBl0B3P6U3+Qptg7xu+v+1io1EwhdPyyRHYbEw0KN2FA==} + qified@0.9.0: + resolution: {integrity: sha512-4q61YgkHbY6gmwkqm0BsxyLDO3UYdrdiJTJ7JiaZb3xpW1duxn135SB7KqUEkCiuu5O4W+TtwEWP2VjmSRanvA==} engines: {node: '>=20'} quansync@0.2.11: @@ -6647,8 +6643,8 @@ packages: prettier: '>=3.0.0' stylelint: '>=16.0.0' - stylelint@17.4.0: - resolution: {integrity: sha512-3kQ2/cHv3Zt8OBg+h2B8XCx9evEABQIrv4hh3uXahGz/ZEHrTR80zxBiK2NfXNaSoyBzxO1pjsz1Vhdzwn5XSw==} + stylelint@17.5.0: + resolution: {integrity: sha512-o/NS6zhsPZFmgUm5tXX4pVNg1XDOZSlucLdf2qow/lVn4JIyzZIQ5b3kad1ugqUj3GSIgr2u5lQw7X8rjqw33g==} engines: {node: '>=20.19.0'} hasBin: true @@ -6764,8 +6760,8 @@ packages: typescript: optional: true - svelte@5.53.9: - resolution: {integrity: sha512-MwDfWsN8qZzeP0jlQsWF4k/4B3csb3IbzCRggF+L/QqY7T8bbKvnChEo1cPZztF51HJQhilDbevWYl2LvXbquA==} + svelte@5.55.0: + resolution: {integrity: sha512-SThllKq6TRMBwPtat7ASnm/9CDXnIhBR0NPGw0ujn2DVYx9rVwsPZxDaDQcYGdUz/3BYVsCzdq7pZarRQoGvtw==} engines: {node: '>=18'} svg-tags@1.0.0: @@ -6869,8 +6865,8 @@ packages: trough@1.0.5: resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -6953,8 +6949,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.57.1: - resolution: {integrity: sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==} + typescript-eslint@8.57.2: + resolution: {integrity: sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -7252,8 +7248,8 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - write-file-atomic@7.0.0: - resolution: {integrity: sha512-YnlPC6JqnZl6aO4uRc+dx5PHguiR9S6WeoLtpxNT9wIG+BDya7ZNE1q7KOjVgaA73hKhKLpVPgJ5QA9THQ5BRg==} + write-file-atomic@7.0.1: + resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==} engines: {node: ^20.17.0 || >=22.9.0} write@1.0.3: @@ -7277,8 +7273,8 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} engines: {node: '>= 6'} yaml@2.8.2: @@ -7655,16 +7651,16 @@ snapshots: '@braintree/sanitize-url@7.1.2': {} - '@cacheable/memory@2.0.7': + '@cacheable/memory@2.0.8': dependencies: - '@cacheable/utils': 2.3.4 + '@cacheable/utils': 2.4.0 '@keyv/bigmap': 1.3.1(keyv@5.6.0) hookified: 1.15.1 keyv: 5.6.0 - '@cacheable/utils@2.3.4': + '@cacheable/utils@2.4.0': dependencies: - hashery: 1.5.0 + hashery: 1.5.1 keyv: 5.6.0 '@changesets/apply-release-plan@7.1.0': @@ -7969,7 +7965,9 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.0.28': {} + '@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 '@csstools/css-tokenizer@4.0.0': {} @@ -8234,24 +8232,24 @@ snapshots: '@esbuild/win32-x64@0.27.3': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.3(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': dependencies: - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.0.3(eslint@9.39.3(jiti@2.6.1))': + '@eslint/compat@2.0.3(eslint@9.39.4(jiti@2.6.1))': dependencies: '@eslint/core': 1.1.1 optionalDependencies: - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) - '@eslint/config-array@0.21.1': + '@eslint/config-array@0.21.2': dependencies: '@eslint/object-schema': 2.1.7 debug: 4.4.3 - minimatch: 3.1.2 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -8267,7 +8265,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.4': + '@eslint/eslintrc@3.3.5': dependencies: ajv: 6.14.0 debug: 4.4.3 @@ -8276,16 +8274,16 @@ snapshots: ignore: 5.3.2 import-fresh: 3.3.1 js-yaml: 4.1.1 - minimatch: 3.1.4 + minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@9.39.3(jiti@2.6.1))': + '@eslint/js@10.0.1(eslint@9.39.4(jiti@2.6.1))': optionalDependencies: - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) - '@eslint/js@9.39.3': {} + '@eslint/js@9.39.4': {} '@eslint/object-schema@2.1.7': {} @@ -8320,41 +8318,41 @@ snapshots: dependencies: tslib: 2.8.1 - '@gradio/atoms@0.22.2(svelte@5.53.9)': + '@gradio/atoms@0.22.2(svelte@5.55.0)': dependencies: - '@gradio/icons': 0.15.1(svelte@5.53.9) - '@gradio/markdown-code': 0.6.1(svelte@5.53.9) - '@gradio/utils': 0.12.0(svelte@5.53.9) - svelte: 5.53.9 + '@gradio/icons': 0.15.1(svelte@5.55.0) + '@gradio/markdown-code': 0.6.1(svelte@5.55.0) + '@gradio/utils': 0.12.0(svelte@5.55.0) + svelte: 5.55.0 '@gradio/client@2.1.0': dependencies: fetch-event-stream: 0.1.6 - '@gradio/icons@0.15.1(svelte@5.53.9)': + '@gradio/icons@0.15.1(svelte@5.55.0)': dependencies: - svelte: 5.53.9 + svelte: 5.55.0 - '@gradio/markdown-code@0.6.1(svelte@5.53.9)': + '@gradio/markdown-code@0.6.1(svelte@5.55.0)': dependencies: '@gradio/sanitize': 0.3.0 '@types/katex': 0.16.8 '@types/prismjs': 1.26.5 github-slugger: 2.0.0 - katex: 0.16.38 + katex: 0.16.40 marked: 12.0.2 marked-gfm-heading-id: 3.2.0(marked@12.0.2) marked-highlight: 2.2.3(marked@12.0.2) mermaid: 11.13.0 prismjs: 1.30.0 - svelte: 5.53.9 + svelte: 5.55.0 - '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.53.9)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': + '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.55.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': dependencies: '@originjs/vite-plugin-commonjs': 1.0.3 '@rollup/plugin-sucrase': 5.1.0(rollup@4.59.0) '@rollup/plugin-terser': 0.4.4(rollup@4.59.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@types/which': 3.0.4 coffeescript: 2.7.0 lightningcss: 1.31.1 @@ -8363,7 +8361,7 @@ snapshots: stylus: 0.64.0 sucrase: 3.35.1 sugarss: 5.0.1(postcss@8.5.8) - svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.53.9)(typescript@5.9.3) + svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.55.0)(typescript@5.9.3) typescript: 5.9.3 vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) which: 5.0.0 @@ -8393,28 +8391,22 @@ snapshots: amuchina: 1.0.12 sanitize-html: 2.17.1 - '@gradio/statustracker@0.12.5(svelte@5.53.9)': + '@gradio/statustracker@0.12.5(svelte@5.55.0)': dependencies: - '@gradio/atoms': 0.22.2(svelte@5.53.9) - '@gradio/icons': 0.15.1(svelte@5.53.9) + '@gradio/atoms': 0.22.2(svelte@5.55.0) + '@gradio/icons': 0.15.1(svelte@5.55.0) '@gradio/sanitize': 0.2.0 - '@gradio/utils': 0.12.0(svelte@5.53.9) - svelte: 5.53.9 - - '@gradio/theme@0.6.1(svelte@5.53.9)': - dependencies: - svelte: 5.53.9 + '@gradio/utils': 0.12.0(svelte@5.55.0) + svelte: 5.55.0 - '@gradio/utils@0.11.3(svelte@5.53.9)': + '@gradio/theme@0.6.1(svelte@5.55.0)': dependencies: - '@gradio/theme': 0.6.1(svelte@5.53.9) - transitivePeerDependencies: - - svelte + svelte: 5.55.0 - '@gradio/utils@0.12.0(svelte@5.53.9)': + '@gradio/utils@0.12.0(svelte@5.55.0)': dependencies: - '@gradio/theme': 0.6.1(svelte@5.53.9) - svelte-i18n: 4.0.1(svelte@5.53.9) + '@gradio/theme': 0.6.1(svelte@5.55.0) + svelte-i18n: 4.0.1(svelte@5.55.0) transitivePeerDependencies: - svelte @@ -8492,7 +8484,7 @@ snapshots: '@keyv/bigmap@1.3.1(keyv@5.6.0)': dependencies: - hashery: 1.5.0 + hashery: 1.5.1 hookified: 1.15.1 keyv: 5.6.0 @@ -9308,20 +9300,20 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) obug: 2.1.1 - svelte: 5.53.9 + svelte: 5.55.0 vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.53.9)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.53.9 + svelte: 5.55.0 vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitefu: 1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -9545,9 +9537,9 @@ snapshots: '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 - '@types/eslint__js@9.14.0(eslint@9.39.3(jiti@2.6.1))': + '@types/eslint__js@9.14.0(eslint@9.39.4(jiti@2.6.1))': dependencies: - '@eslint/js': 10.0.1(eslint@9.39.3(jiti@2.6.1)) + '@eslint/js': 10.0.1(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - eslint @@ -9628,95 +9620,95 @@ snapshots: '@types/which@3.0.4': {} - '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.1 - eslint: 9.39.3(jiti@2.6.1) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.2 + eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.1 + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.2 debug: 4.4.3 - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.57.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.57.1': + '@typescript-eslint/scope-manager@8.57.2': dependencies: - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/visitor-keys': 8.57.1 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/visitor-keys': 8.57.2 - '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.57.2(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.39.3(jiti@2.6.1) - ts-api-utils: 2.4.0(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.57.1': {} + '@typescript-eslint/types@8.57.2': {} - '@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/visitor-keys': 8.57.1 + '@typescript-eslint/project-service': 8.57.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/visitor-keys': 8.57.2 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - eslint: 9.39.3(jiti@2.6.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.57.1': + '@typescript-eslint/visitor-keys@8.57.2': dependencies: - '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/types': 8.57.2 eslint-visitor-keys: 5.0.1 '@unrs/resolver-binding-android-arm-eabi@1.9.2': @@ -10189,13 +10181,13 @@ snapshots: union-value: 1.0.1 unset-value: 1.0.0 - cacheable@2.3.2: + cacheable@2.3.4: dependencies: - '@cacheable/memory': 2.0.7 - '@cacheable/utils': 2.3.4 + '@cacheable/memory': 2.0.8 + '@cacheable/utils': 2.4.0 hookified: 1.15.1 keyv: 5.6.0 - qified: 0.6.0 + qified: 0.9.0 call-bind-apply-helpers@1.0.2: dependencies: @@ -10432,15 +10424,6 @@ snapshots: js-yaml: 3.14.1 parse-json: 4.0.0 - cosmiconfig@9.0.0(typescript@5.9.3): - dependencies: - env-paths: 2.2.1 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - parse-json: 5.2.0 - optionalDependencies: - typescript: 5.9.3 - cosmiconfig@9.0.1(typescript@5.9.3): dependencies: env-paths: 2.2.1 @@ -10468,9 +10451,9 @@ snapshots: css-functions-list@3.3.3: {} - css-tree@3.1.0: + css-tree@3.2.1: dependencies: - mdn-data: 2.12.2 + mdn-data: 2.27.1 source-map-js: 1.2.1 cssesc@3.0.0: {} @@ -10774,7 +10757,7 @@ snapshots: detect-newline@4.0.1: {} - devalue@5.6.3: {} + devalue@5.6.4: {} diff@4.0.4: {} @@ -11244,9 +11227,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-import-context@0.1.9(unrs-resolver@1.9.2): dependencies: @@ -11263,10 +11246,10 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)): + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 4.4.1 - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-import-context: 0.1.9(unrs-resolver@1.9.2) get-tsconfig: 4.10.1 is-bun-module: 2.0.0 @@ -11274,22 +11257,22 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.39.3(jiti@2.6.1) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) + eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -11298,9 +11281,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11312,13 +11295,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4(jiti@2.6.1)): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -11328,7 +11311,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -11337,32 +11320,32 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.6.1)))(eslint@9.39.3(jiti@2.6.1))(prettier@3.8.1): + eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1))(prettier@3.8.1): dependencies: - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) prettier: 3.8.1 prettier-linter-helpers: 1.0.1 synckit: 0.11.12 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@9.39.3(jiti@2.6.1)) + eslint-config-prettier: 10.1.8(eslint@9.39.4(jiti@2.6.1)) - eslint-plugin-react-hooks@7.0.1(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@babel/core': 7.28.5 '@babel/parser': 7.28.5 - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) hermes-parser: 0.25.1 zod: 4.1.12 zod-validation-error: 4.0.2(zod@4.1.12) transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.5.2(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-react-refresh@0.5.2(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-react@7.37.5(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.6.1)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -11370,7 +11353,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -11384,15 +11367,15 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-svelte@3.15.2(eslint@9.39.3(jiti@2.6.1))(svelte@5.53.9)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)): + eslint-plugin-svelte@3.16.0(eslint@9.39.4(jiti@2.6.1))(svelte@5.55.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@jridgewell/sourcemap-codec': 1.5.5 - eslint: 9.39.3(jiti@2.6.1) + eslint: 9.39.4(jiti@2.6.1) esutils: 2.0.3 globals: 16.5.0 known-css-properties: 0.37.0 @@ -11400,9 +11383,9 @@ snapshots: postcss-load-config: 3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)) postcss-safe-parser: 7.0.1(postcss@8.5.8) semver: 7.7.4 - svelte-eslint-parser: 1.6.0(svelte@5.53.9) + svelte-eslint-parser: 1.6.0(svelte@5.55.0) optionalDependencies: - svelte: 5.53.9 + svelte: 5.55.0 transitivePeerDependencies: - ts-node @@ -11417,15 +11400,15 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.3(jiti@2.6.1): + eslint@9.39.4(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 + '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.4 - '@eslint/js': 9.39.3 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 @@ -11450,7 +11433,7 @@ snapshots: is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -11479,9 +11462,10 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@2.2.3: + esrap@2.2.4: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + '@typescript-eslint/types': 8.57.2 esrecurse@4.3.0: dependencies: @@ -11604,7 +11588,7 @@ snapshots: file-entry-cache@11.1.2: dependencies: - flat-cache: 6.1.20 + flat-cache: 6.1.21 file-entry-cache@4.0.0: dependencies: @@ -11653,18 +11637,18 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 - flat-cache@6.1.20: + flat-cache@6.1.21: dependencies: - cacheable: 2.3.2 - flatted: 3.3.3 + cacheable: 2.3.4 + flatted: 3.4.2 hookified: 1.15.1 flatted@2.0.2: {} - flatted@3.3.3: {} + flatted@3.4.2: {} for-each@0.3.5: dependencies: @@ -11930,7 +11914,7 @@ snapshots: is-number: 3.0.0 kind-of: 4.0.0 - hashery@1.5.0: + hashery@1.5.1: dependencies: hookified: 1.15.1 @@ -11962,6 +11946,8 @@ snapshots: hookified@1.15.1: {} + hookified@2.1.0: {} + hosted-git-info@2.8.9: {} html-tags@2.0.0: {} @@ -12397,7 +12383,7 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 - katex@0.16.38: + katex@0.16.40: dependencies: commander: 8.3.0 @@ -12661,18 +12647,18 @@ snapshots: github-slugger: 2.0.0 marked: 12.0.2 - marked-gfm-heading-id@4.1.3(marked@17.0.4): + marked-gfm-heading-id@4.1.3(marked@17.0.5): dependencies: github-slugger: 2.0.0 - marked: 17.0.4 + marked: 17.0.5 marked-highlight@2.2.3(marked@12.0.2): dependencies: marked: 12.0.2 - marked-highlight@2.2.3(marked@17.0.4): + marked-highlight@2.2.3(marked@17.0.5): dependencies: - marked: 17.0.4 + marked: 17.0.5 marked@12.0.2: {} @@ -12680,7 +12666,7 @@ snapshots: marked@16.4.2: {} - marked@17.0.4: {} + marked@17.0.5: {} math-intrinsics@1.1.0: {} @@ -12692,7 +12678,7 @@ snapshots: dependencies: unist-util-visit: 1.4.1 - mdn-data@2.12.2: {} + mdn-data@2.27.1: {} memoizee@0.4.17: dependencies: @@ -12740,7 +12726,7 @@ snapshots: dagre-d3-es: 7.0.14 dayjs: 1.11.20 dompurify: 3.3.2 - katex: 0.16.38 + katex: 0.16.40 khroma: 2.1.0 lodash-es: 4.17.23 marked: 16.4.2 @@ -12794,7 +12780,7 @@ snapshots: dependencies: brace-expansion: 1.1.11 - minimatch@3.1.4: + minimatch@3.1.5: dependencies: brace-expansion: 1.1.11 @@ -13193,7 +13179,7 @@ snapshots: postcss-load-config@3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)): dependencies: lilconfig: 2.1.0 - yaml: 1.10.2 + yaml: 1.10.3 optionalDependencies: postcss: 8.5.8 ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3) @@ -13307,10 +13293,10 @@ snapshots: optionalDependencies: prettier: 3.8.1 - prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.53.9): + prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.55.0): dependencies: prettier: 3.8.1 - svelte: 5.53.9 + svelte: 5.55.0 prettier@2.8.8: {} @@ -13402,9 +13388,9 @@ snapshots: punycode@2.3.1: {} - qified@0.6.0: + qified@0.9.0: dependencies: - hookified: 1.15.1 + hookified: 2.1.0 quansync@0.2.11: {} @@ -14091,18 +14077,18 @@ snapshots: transitivePeerDependencies: - supports-color - stylelint-config-recommended@18.0.0(stylelint@17.4.0(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.5.0(typescript@5.9.3)): dependencies: - stylelint: 17.4.0(typescript@5.9.3) + stylelint: 17.5.0(typescript@5.9.3) - stylelint-config-standard@40.0.0(stylelint@17.4.0(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.5.0(typescript@5.9.3)): dependencies: - stylelint: 17.4.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.4.0(typescript@5.9.3)) + stylelint: 17.5.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.5.0(typescript@5.9.3)) - stylelint-declaration-block-no-ignored-properties@3.0.0(stylelint@17.4.0(typescript@5.9.3)): + stylelint-declaration-block-no-ignored-properties@3.0.0(stylelint@17.5.0(typescript@5.9.3)): dependencies: - stylelint: 17.4.0(typescript@5.9.3) + stylelint: 17.5.0(typescript@5.9.3) stylelint-order@2.2.1(stylelint@9.10.1): dependencies: @@ -14111,31 +14097,31 @@ snapshots: postcss-sorting: 4.1.0 stylelint: 9.10.1 - stylelint-order@8.1.1(stylelint@17.4.0(typescript@5.9.3)): + stylelint-order@8.1.1(stylelint@17.5.0(typescript@5.9.3)): dependencies: postcss: 8.5.8 postcss-sorting: 10.0.0(postcss@8.5.8) - stylelint: 17.4.0(typescript@5.9.3) + stylelint: 17.5.0(typescript@5.9.3) - stylelint-prettier@5.0.3(prettier@3.8.1)(stylelint@17.4.0(typescript@5.9.3)): + stylelint-prettier@5.0.3(prettier@3.8.1)(stylelint@17.5.0(typescript@5.9.3)): dependencies: prettier: 3.8.1 prettier-linter-helpers: 1.0.0 - stylelint: 17.4.0(typescript@5.9.3) + stylelint: 17.5.0(typescript@5.9.3) - stylelint@17.4.0(typescript@5.9.3): + stylelint@17.5.0(typescript@5.9.3): dependencies: '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-syntax-patches-for-csstree': 1.0.28 + '@csstools/css-syntax-patches-for-csstree': 1.1.1(css-tree@3.2.1) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.1) '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) colord: 2.9.3 - cosmiconfig: 9.0.0(typescript@5.9.3) + cosmiconfig: 9.0.1(typescript@5.9.3) css-functions-list: 3.3.3 - css-tree: 3.1.0 + css-tree: 3.2.1 debug: 4.4.3 fast-glob: 3.3.3 fastest-levenshtein: 1.0.16 @@ -14161,7 +14147,7 @@ snapshots: supports-hyperlinks: 4.4.0 svg-tags: 1.0.0 table: 6.9.0 - write-file-atomic: 7.0.0 + write-file-atomic: 7.0.1 transitivePeerDependencies: - supports-color - typescript @@ -14270,19 +14256,19 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.53.9)(typescript@5.9.3): + svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.55.0)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.53.9 + svelte: 5.55.0 typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.6.0(svelte@5.53.9): + svelte-eslint-parser@1.6.0(svelte@5.55.0): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -14292,9 +14278,9 @@ snapshots: postcss-selector-parser: 7.1.1 semver: 7.7.4 optionalDependencies: - svelte: 5.53.9 + svelte: 5.55.0 - svelte-i18n@4.0.1(svelte@5.53.9): + svelte-i18n@4.0.1(svelte@5.55.0): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -14302,12 +14288,12 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.16 sade: 1.8.1 - svelte: 5.53.9 + svelte: 5.55.0 tiny-glob: 0.2.9 - svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.53.9)(typescript@5.9.3): + svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.55.0)(typescript@5.9.3): dependencies: - svelte: 5.53.9 + svelte: 5.55.0 optionalDependencies: '@babel/core': 7.29.0 coffeescript: 2.7.0 @@ -14320,7 +14306,7 @@ snapshots: sugarss: 5.0.1(postcss@8.5.8) typescript: 5.9.3 - svelte@5.53.9: + svelte@5.55.0: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -14331,9 +14317,9 @@ snapshots: aria-query: 5.3.1 axobject-query: 4.1.0 clsx: 2.1.1 - devalue: 5.6.3 + devalue: 5.6.4 esm-env: 1.2.2 - esrap: 2.2.3 + esrap: 2.2.4 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.21 @@ -14439,7 +14425,7 @@ snapshots: trough@1.0.5: {} - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -14575,13 +14561,13 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.39.3(jiti@2.6.1) + '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -14909,9 +14895,8 @@ snapshots: wrappy@1.0.2: {} - write-file-atomic@7.0.0: + write-file-atomic@7.0.1: dependencies: - imurmurhash: 0.1.4 signal-exit: 4.1.0 write@1.0.3: @@ -14929,7 +14914,7 @@ snapshots: yallist@4.0.0: optional: true - yaml@1.10.2: {} + yaml@1.10.3: {} yaml@2.8.2: {} From 26ea2485990098ea60e95ff8b3e71dad713a3aba Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Tue, 24 Mar 2026 17:29:53 +0800 Subject: [PATCH 15/31] chore: enter prerelease mode and version packages --- .changeset/eleven-aliens-sell.md | 12 ++++++++++++ .changeset/pre.json | 15 +++++++++++++++ .github/workflows/publish.yaml | 1 + 3 files changed, 28 insertions(+) create mode 100644 .changeset/eleven-aliens-sell.md create mode 100644 .changeset/pre.json diff --git a/.changeset/eleven-aliens-sell.md b/.changeset/eleven-aliens-sell.md new file mode 100644 index 00000000..604e63b4 --- /dev/null +++ b/.changeset/eleven-aliens-sell.md @@ -0,0 +1,12 @@ +--- +'@modelscope-studio/lint-config': major +'@modelscope-studio/changelog': major +'@modelscope-studio/antdx': major +'@modelscope-studio/antd': major +'@modelscope-studio/base': major +'@modelscope-studio/pro': major +'@modelscope-studio/frontend': major +'modelscope_studio': major +--- + +refactor: migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0 diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000..458c8c07 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,15 @@ +{ + "mode": "pre", + "tag": "beta", + "initialVersions": { + "modelscope_studio": "1.6.1", + "@modelscope-studio/changelog": "1.6.1", + "@modelscope-studio/lint-config": "1.6.1", + "@modelscope-studio/frontend": "1.6.1", + "@modelscope-studio/antd": "1.6.1", + "@modelscope-studio/antdx": "1.6.1", + "@modelscope-studio/base": "1.6.1", + "@modelscope-studio/pro": "1.6.1" + }, + "changesets": [] +} diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index a99fcebe..5cf84952 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -4,6 +4,7 @@ on: push: branches: - main + - next env: CI: true From 2f28df532fa9781955676eed4a654e0e22235ad7 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Tue, 24 Mar 2026 19:13:45 +0800 Subject: [PATCH 16/31] chore: update versions --- .changeset/pre.json | 4 +- .github/workflows/publish.yaml | 2 +- CHANGELOG.md | 8 +- backend/modelscope_studio/version.py | 2 +- config/changelog/CHANGELOG.md | 8 +- config/changelog/package.json | 2 +- config/lint-config/CHANGELOG.md | 8 +- config/lint-config/package.json | 2 +- docs/requirements.txt | 2 +- docs/src/pyproject.toml | 2 +- frontend/CHANGELOG.md | 8 +- frontend/antd/CHANGELOG.md | 8 +- frontend/antd/package.json | 2 +- frontend/antdx/CHANGELOG.md | 8 +- frontend/antdx/package.json | 2 +- frontend/base/CHANGELOG.md | 8 +- frontend/base/package.json | 2 +- frontend/package.json | 6 +- frontend/pro/CHANGELOG.md | 8 +- frontend/pro/package.json | 2 +- package.json | 6 +- pnpm-lock.yaml | 132 +++++++++++------- pyproject.toml | 22 ++- ...publish-to-pypi.ts => publish-to-pypi.mts} | 0 24 files changed, 179 insertions(+), 75 deletions(-) rename scripts/{publish-to-pypi.ts => publish-to-pypi.mts} (100%) diff --git a/.changeset/pre.json b/.changeset/pre.json index 458c8c07..471b7fc2 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -11,5 +11,7 @@ "@modelscope-studio/base": "1.6.1", "@modelscope-studio/pro": "1.6.1" }, - "changesets": [] + "changesets": [ + "eleven-aliens-sell" + ] } diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 5cf84952..ad4c67a7 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -38,7 +38,7 @@ jobs: github.event.head_commit.message == 'chore: update versions' uses: actions/setup-node@v3 with: - node-version: 20 + node-version: 22 - name: Install Pnpm if: | github.event.head_commit.message == 'chore: update versions' diff --git a/CHANGELOG.md b/CHANGELOG.md index 998bcfb8..98269376 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # modelscope_studio +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 ### Features @@ -439,4 +445,4 @@ ### Features - [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`d1829d3`](https://github.com/modelscope/modelscope-studio/commit/d1829d34dd0bce8834d2e257b612d79705e57d6d) - update the timing of onMount call and new onUpdate lifecycle of custom component. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`96e1682`](https://github.com/modelscope/modelscope-studio/commit/96e1682b7cb63907aafba06afb820f55d7df8ff0) - add Flow component. Thanks [@Col0ring](https://github.com/Col0ring)! +- [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`96e1682`](https://github.com/modelscope/modelscope-studio/commit/96e1682b7cb63907aafba06afb820f55d7df8ff0) - add Flow component. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file diff --git a/backend/modelscope_studio/version.py b/backend/modelscope_studio/version.py index f49459c7..ce304548 100644 --- a/backend/modelscope_studio/version.py +++ b/backend/modelscope_studio/version.py @@ -1 +1 @@ -__version__ = "1.6.1" +__version__ = "2.0.0-beta.0" diff --git a/config/changelog/CHANGELOG.md b/config/changelog/CHANGELOG.md index 60d4881e..1312a3f8 100644 --- a/config/changelog/CHANGELOG.md +++ b/config/changelog/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/changelog +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 No significant changes to this package were made in this release. @@ -270,4 +276,4 @@ No significant changes to this package were made in this release. ## 0.2.0 -No significant changes to this package were made in this release. +No significant changes to this package were made in this release. \ No newline at end of file diff --git a/config/changelog/package.json b/config/changelog/package.json index 66b46c3c..cf0337be 100644 --- a/config/changelog/package.json +++ b/config/changelog/package.json @@ -1,6 +1,6 @@ { "name": "@modelscope-studio/changelog", - "version": "1.6.1", + "version": "2.0.0-beta.0", "private": false, "description": "ModelScope Studio Changelog", "repository": "git@github.com:modelscope/modelscope-studio.git", diff --git a/config/lint-config/CHANGELOG.md b/config/lint-config/CHANGELOG.md index 821da4eb..48228822 100644 --- a/config/lint-config/CHANGELOG.md +++ b/config/lint-config/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/lint-config +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 No significant changes to this package were made in this release. @@ -270,4 +276,4 @@ No significant changes to this package were made in this release. ## 0.2.0 -No significant changes to this package were made in this release. +No significant changes to this package were made in this release. \ No newline at end of file diff --git a/config/lint-config/package.json b/config/lint-config/package.json index 8ad9eb32..803cc156 100644 --- a/config/lint-config/package.json +++ b/config/lint-config/package.json @@ -1,6 +1,6 @@ { "name": "@modelscope-studio/lint-config", - "version": "1.6.1", + "version": "2.0.0-beta.0", "private": false, "description": "ModelScope Studio Lint Config", "repository": "git@github.com:modelscope/modelscope-studio.git", diff --git a/docs/requirements.txt b/docs/requirements.txt index ce3aef6b..9abd576a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ gradio==5.34.1 -modelscope_studio==1.6.1 +modelscope_studio==2.0.0-beta.0 openai diff --git a/docs/src/pyproject.toml b/docs/src/pyproject.toml index f21508f9..cf8711e2 100644 --- a/docs/src/pyproject.toml +++ b/docs/src/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "hatchling.build" [project] name = "modelscope_studio" -version = "1.6.1" +version = "2.0.0-beta.0" description = "A third-party component library based on Gradio." readme = "README.md" license = "Apache-2.0" diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index 0d0056cb..f56e6406 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/frontend +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 No significant changes to this package were made in this release. @@ -336,4 +342,4 @@ No significant changes to this package were made in this release. ### Features -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! +- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file diff --git a/frontend/antd/CHANGELOG.md b/frontend/antd/CHANGELOG.md index 65ec8e36..eb796740 100644 --- a/frontend/antd/CHANGELOG.md +++ b/frontend/antd/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/antd +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 No significant changes to this package were made in this release. @@ -265,4 +271,4 @@ No significant changes to this package were made in this release. ### Features -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! +- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file diff --git a/frontend/antd/package.json b/frontend/antd/package.json index 4d23b4ed..ce811551 100644 --- a/frontend/antd/package.json +++ b/frontend/antd/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/antd", - "version": "1.6.1", + "version": "2.0.0-beta.0", "type": "module" } diff --git a/frontend/antdx/CHANGELOG.md b/frontend/antdx/CHANGELOG.md index 247f0933..bad11d73 100644 --- a/frontend/antdx/CHANGELOG.md +++ b/frontend/antdx/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/antdx +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 No significant changes to this package were made in this release. @@ -148,4 +154,4 @@ No significant changes to this package were made in this release. ### Features -- [#48](https://github.com/modelscope/modelscope-studio/pull/48) [`b0197ef`](https://github.com/modelscope/modelscope-studio/commit/b0197ef7ede322e2c40b4e1dcc6480530a62490e) - integrate antdx. Thanks [@Col0ring](https://github.com/Col0ring)! +- [#48](https://github.com/modelscope/modelscope-studio/pull/48) [`b0197ef`](https://github.com/modelscope/modelscope-studio/commit/b0197ef7ede322e2c40b4e1dcc6480530a62490e) - integrate antdx. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file diff --git a/frontend/antdx/package.json b/frontend/antdx/package.json index 977e314d..b37fccb6 100644 --- a/frontend/antdx/package.json +++ b/frontend/antdx/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/antdx", - "version": "1.6.1", + "version": "2.0.0-beta.0", "type": "module" } diff --git a/frontend/base/CHANGELOG.md b/frontend/base/CHANGELOG.md index 0ec1a4e3..947392b1 100644 --- a/frontend/base/CHANGELOG.md +++ b/frontend/base/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/base +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 No significant changes to this package were made in this release. @@ -227,4 +233,4 @@ No significant changes to this package were made in this release. ### Features -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! +- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file diff --git a/frontend/base/package.json b/frontend/base/package.json index 5db984bd..9fc16323 100644 --- a/frontend/base/package.json +++ b/frontend/base/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/base", - "version": "1.6.1", + "version": "2.0.0-beta.0", "type": "module" } diff --git a/frontend/package.json b/frontend/package.json index 1d7c4b6b..dc8b47a3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@modelscope-studio/frontend", - "version": "1.6.1", + "version": "2.0.0-beta.0", "private": false, "description": "ModelScope Gradio Components", "license": "Apache-2.0", @@ -13,7 +13,7 @@ "@gradio/client": "2.1.0", "@gradio/preview": "0.15.2", "@gradio/statustracker": "^0.12.5", - "@gradio/utils": "0.12.0", + "@gradio/utils": "0.11.3", "@monaco-editor/react": "^4.7.0", "amuchina": "^1.0.12", "antd": "^6.3.3", @@ -34,7 +34,7 @@ "react": "^19.2.4", "react-dom": "^19.2.4", "react-syntax-highlighter": "^16.1.1", - "svelte": "5.55.0", + "svelte": "5.48.0", "svelte-i18n": "^4.0.1", "wavesurfer.js": "^7.12.4" }, diff --git a/frontend/pro/CHANGELOG.md b/frontend/pro/CHANGELOG.md index 1790d920..5e1565c1 100644 --- a/frontend/pro/CHANGELOG.md +++ b/frontend/pro/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/pro +## 2.0.0-beta.0 + +### Misc Changes + +- [`26ea248`](https://github.com/modelscope/modelscope-studio/commit/26ea2485990098ea60e95ff8b3e71dad713a3aba) - migrate to Gradio 6.0, Ant Design 6.0, Ant Design X 2.0. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 1.6.1 ### Features @@ -134,4 +140,4 @@ No significant changes to this package were made in this release. ### Fixes -- [#64](https://github.com/modelscope/modelscope-studio/pull/64) [`7bf9d74`](https://github.com/modelscope/modelscope-studio/commit/7bf9d741bc66e318d3c310e798b1a781d23a0abf) - the logic of uploading files. Thanks [@Col0ring](https://github.com/Col0ring)! +- [#64](https://github.com/modelscope/modelscope-studio/pull/64) [`7bf9d74`](https://github.com/modelscope/modelscope-studio/commit/7bf9d741bc66e318d3c310e798b1a781d23a0abf) - the logic of uploading files. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file diff --git a/frontend/pro/package.json b/frontend/pro/package.json index 9c030b9e..74ec97aa 100644 --- a/frontend/pro/package.json +++ b/frontend/pro/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/pro", - "version": "1.6.1", + "version": "2.0.0-beta.0", "type": "module" } diff --git a/package.json b/package.json index 2b764a89..5dd0f3c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "modelscope_studio", - "version": "1.6.1", + "version": "2.0.0-beta.0", "private": true, "description": "ModelScope Gradio Components", "repository": "git@github.com:modelscope/modelscope-studio.git", @@ -10,7 +10,7 @@ "changeset": "changeset", "check-encoding": "python ./scripts/check_encoding.py", "ci:create-tag-n-release": "tsx ./scripts/create-tag-n-release.ts", - "ci:publish": "tsx ./scripts/publish-to-pypi.ts", + "ci:publish": "tsx ./scripts/publish-to-pypi.mts", "ci:version": "pnpm run version", "dev": "gradio cc dev docs/app.py", "fix-changelog": "node ./config/changelog/dist/fix-changelog.mjs", @@ -44,7 +44,7 @@ "prettier-plugin-svelte": "^3.5.1", "rimraf": "^6.1.3", "stylelint": "^17.5.0", - "svelte": "5.55.0", + "svelte": "5.48.0", "svelte-check": "^4.4.5", "tslib": "^2.8.1", "tsx": "^4.21.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6bffa348..e5154a30 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,7 +61,7 @@ importers: version: 3.0.2(prettier@3.8.1) prettier-plugin-svelte: specifier: ^3.5.1 - version: 3.5.1(prettier@3.8.1)(svelte@5.55.0) + version: 3.5.1(prettier@3.8.1)(svelte@5.48.0) rimraf: specifier: ^6.1.3 version: 6.1.3 @@ -69,11 +69,11 @@ importers: specifier: ^17.5.0 version: 17.5.0(typescript@5.9.3) svelte: - specifier: 5.55.0 - version: 5.55.0 + specifier: 5.48.0 + version: 5.48.0 svelte-check: specifier: ^4.4.5 - version: 4.4.5(picomatch@4.0.3)(svelte@5.55.0)(typescript@5.9.3) + version: 4.4.5(picomatch@4.0.3)(svelte@5.48.0)(typescript@5.9.3) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -204,13 +204,13 @@ importers: version: 2.1.0 '@gradio/preview': specifier: 0.15.2 - version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.55.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.48.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@gradio/statustracker': specifier: ^0.12.5 - version: 0.12.5(svelte@5.55.0) + version: 0.12.5(svelte@5.48.0) '@gradio/utils': - specifier: 0.12.0 - version: 0.12.0(svelte@5.55.0) + specifier: 0.11.3 + version: 0.11.3(svelte@5.48.0) '@monaco-editor/react': specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -272,11 +272,11 @@ importers: specifier: ^16.1.1 version: 16.1.1(react@19.2.4) svelte: - specifier: 5.55.0 - version: 5.55.0 + specifier: 5.48.0 + version: 5.48.0 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.55.0) + version: 4.0.1(svelte@5.48.0) wavesurfer.js: specifier: ^7.12.4 version: 7.12.4 @@ -1362,6 +1362,9 @@ packages: peerDependencies: svelte: ^5.48.0 + '@gradio/utils@0.11.3': + resolution: {integrity: sha512-k1X6HXcoOycvBHsXamCyiN21v40I88FjTgz1TsVF5Hb/vJoA1InHjT+Uo6vnt+aJ8UGtxjUMTBVFR/GOcgXB/Q==} + '@gradio/utils@0.12.0': resolution: {integrity: sha512-twy9fxEikjqxgtP3fk8voIDdey3nYFpJfmayDU7/IGn3C35nk+kL4dsJfEPbQ99BXmRgBecurSJEduOFptOCCQ==} @@ -6760,6 +6763,10 @@ packages: typescript: optional: true + svelte@5.48.0: + resolution: {integrity: sha512-+NUe82VoFP1RQViZI/esojx70eazGF4u0O/9ucqZ4rPcOZD+n5EVp17uYsqwdzjUjZyTpGKunHbDziW6AIAVkQ==} + engines: {node: '>=18'} + svelte@5.55.0: resolution: {integrity: sha512-SThllKq6TRMBwPtat7ASnm/9CDXnIhBR0NPGw0ujn2DVYx9rVwsPZxDaDQcYGdUz/3BYVsCzdq7pZarRQoGvtw==} engines: {node: '>=18'} @@ -8318,22 +8325,22 @@ snapshots: dependencies: tslib: 2.8.1 - '@gradio/atoms@0.22.2(svelte@5.55.0)': + '@gradio/atoms@0.22.2(svelte@5.48.0)': dependencies: - '@gradio/icons': 0.15.1(svelte@5.55.0) - '@gradio/markdown-code': 0.6.1(svelte@5.55.0) - '@gradio/utils': 0.12.0(svelte@5.55.0) - svelte: 5.55.0 + '@gradio/icons': 0.15.1(svelte@5.48.0) + '@gradio/markdown-code': 0.6.1(svelte@5.48.0) + '@gradio/utils': 0.12.0(svelte@5.48.0) + svelte: 5.48.0 '@gradio/client@2.1.0': dependencies: fetch-event-stream: 0.1.6 - '@gradio/icons@0.15.1(svelte@5.55.0)': + '@gradio/icons@0.15.1(svelte@5.48.0)': dependencies: - svelte: 5.55.0 + svelte: 5.48.0 - '@gradio/markdown-code@0.6.1(svelte@5.55.0)': + '@gradio/markdown-code@0.6.1(svelte@5.48.0)': dependencies: '@gradio/sanitize': 0.3.0 '@types/katex': 0.16.8 @@ -8345,14 +8352,14 @@ snapshots: marked-highlight: 2.2.3(marked@12.0.2) mermaid: 11.13.0 prismjs: 1.30.0 - svelte: 5.55.0 + svelte: 5.48.0 - '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.55.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': + '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.48.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': dependencies: '@originjs/vite-plugin-commonjs': 1.0.3 '@rollup/plugin-sucrase': 5.1.0(rollup@4.59.0) '@rollup/plugin-terser': 0.4.4(rollup@4.59.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@types/which': 3.0.4 coffeescript: 2.7.0 lightningcss: 1.31.1 @@ -8361,7 +8368,7 @@ snapshots: stylus: 0.64.0 sucrase: 3.35.1 sugarss: 5.0.1(postcss@8.5.8) - svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.55.0)(typescript@5.9.3) + svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.48.0)(typescript@5.9.3) typescript: 5.9.3 vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) which: 5.0.0 @@ -8391,22 +8398,28 @@ snapshots: amuchina: 1.0.12 sanitize-html: 2.17.1 - '@gradio/statustracker@0.12.5(svelte@5.55.0)': + '@gradio/statustracker@0.12.5(svelte@5.48.0)': dependencies: - '@gradio/atoms': 0.22.2(svelte@5.55.0) - '@gradio/icons': 0.15.1(svelte@5.55.0) + '@gradio/atoms': 0.22.2(svelte@5.48.0) + '@gradio/icons': 0.15.1(svelte@5.48.0) '@gradio/sanitize': 0.2.0 - '@gradio/utils': 0.12.0(svelte@5.55.0) - svelte: 5.55.0 + '@gradio/utils': 0.12.0(svelte@5.48.0) + svelte: 5.48.0 - '@gradio/theme@0.6.1(svelte@5.55.0)': + '@gradio/theme@0.6.1(svelte@5.48.0)': dependencies: - svelte: 5.55.0 + svelte: 5.48.0 + + '@gradio/utils@0.11.3(svelte@5.48.0)': + dependencies: + '@gradio/theme': 0.6.1(svelte@5.48.0) + transitivePeerDependencies: + - svelte - '@gradio/utils@0.12.0(svelte@5.55.0)': + '@gradio/utils@0.12.0(svelte@5.48.0)': dependencies: - '@gradio/theme': 0.6.1(svelte@5.55.0) - svelte-i18n: 4.0.1(svelte@5.55.0) + '@gradio/theme': 0.6.1(svelte@5.48.0) + svelte-i18n: 4.0.1(svelte@5.48.0) transitivePeerDependencies: - svelte @@ -9300,20 +9313,20 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) obug: 2.1.1 - svelte: 5.55.0 + svelte: 5.48.0 vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.55.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.55.0 + svelte: 5.48.0 vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitefu: 1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -9602,7 +9615,8 @@ snapshots: dependencies: htmlparser2: 10.1.0 - '@types/trusted-types@2.0.7': {} + '@types/trusted-types@2.0.7': + optional: true '@types/unist@2.0.11': {} @@ -9935,7 +9949,8 @@ snapshots: argparse@2.0.1: {} - aria-query@5.3.1: {} + aria-query@5.3.1: + optional: true aria-query@5.3.2: {} @@ -13293,10 +13308,10 @@ snapshots: optionalDependencies: prettier: 3.8.1 - prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.55.0): + prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.48.0): dependencies: prettier: 3.8.1 - svelte: 5.55.0 + svelte: 5.48.0 prettier@2.8.8: {} @@ -14256,14 +14271,14 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.55.0)(typescript@5.9.3): + svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.48.0)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.55.0 + svelte: 5.48.0 typescript: 5.9.3 transitivePeerDependencies: - picomatch @@ -14280,7 +14295,7 @@ snapshots: optionalDependencies: svelte: 5.55.0 - svelte-i18n@4.0.1(svelte@5.55.0): + svelte-i18n@4.0.1(svelte@5.48.0): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -14288,12 +14303,12 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.16 sade: 1.8.1 - svelte: 5.55.0 + svelte: 5.48.0 tiny-glob: 0.2.9 - svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.55.0)(typescript@5.9.3): + svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.48.0)(typescript@5.9.3): dependencies: - svelte: 5.55.0 + svelte: 5.48.0 optionalDependencies: '@babel/core': 7.29.0 coffeescript: 2.7.0 @@ -14306,6 +14321,24 @@ snapshots: sugarss: 5.0.1(postcss@8.5.8) typescript: 5.9.3 + svelte@5.48.0: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@types/estree': 1.0.8 + acorn: 8.16.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.4 + esm-env: 1.2.2 + esrap: 2.2.4 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + svelte@5.55.0: dependencies: '@jridgewell/remapping': 2.3.5 @@ -14324,6 +14357,7 @@ snapshots: locate-character: 3.0.0 magic-string: 0.30.21 zimmerframe: 1.1.4 + optional: true svg-tags@1.0.0: {} diff --git a/pyproject.toml b/pyproject.toml index c4d13b86..2ca8bba0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "hatchling.build" [project] name = "modelscope_studio" -version = "1.6.1" +version = "2.0.0-beta.0" description = "A third-party component library based on Gradio." readme = "README.md" license = "Apache-2.0" @@ -221,6 +221,26 @@ artifacts = [ "/backend/modelscope_studio/components/antd/statistic/timer/templates", "/backend/modelscope_studio/components/pro/monaco_editor/templates", "/backend/modelscope_studio/components/pro/monaco_editor/diff_editor/templates", + "/backend/modelscope_studio/components/antdx/actions/action_item/templates", + "/backend/modelscope_studio/components/antdx/actions/audio/templates", + "/backend/modelscope_studio/components/antdx/actions/copy/templates", + "/backend/modelscope_studio/components/antdx/actions/feedback/templates", + "/backend/modelscope_studio/components/antdx/bubble/divider/templates", + "/backend/modelscope_studio/components/antdx/bubble/system/templates", + "/backend/modelscope_studio/components/antdx/code_highlighter/templates", + "/backend/modelscope_studio/components/antdx/file_card/templates", + "/backend/modelscope_studio/components/antdx/file_card/list/templates", + "/backend/modelscope_studio/components/antdx/file_card/list/item/templates", + "/backend/modelscope_studio/components/antdx/folder/templates", + "/backend/modelscope_studio/components/antdx/folder/directory_icon/templates", + "/backend/modelscope_studio/components/antdx/folder/tree_node/templates", + "/backend/modelscope_studio/components/antdx/mermaid/templates", + "/backend/modelscope_studio/components/antdx/notification/templates", + "/backend/modelscope_studio/components/antdx/sender/switch/templates", + "/backend/modelscope_studio/components/antdx/sources/templates", + "/backend/modelscope_studio/components/antdx/sources/item/templates", + "/backend/modelscope_studio/components/antdx/think/templates", + "/backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/templates", ] [tool.yapfignore] diff --git a/scripts/publish-to-pypi.ts b/scripts/publish-to-pypi.mts similarity index 100% rename from scripts/publish-to-pypi.ts rename to scripts/publish-to-pypi.mts From 2b6ba3dcdc23030532f2061cf520afff6c8a1152 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Tue, 24 Mar 2026 20:03:37 +0800 Subject: [PATCH 17/31] fix(ci): create github tag and release --- package.json | 2 +- scripts/{create-tag-n-release.ts => create-tag-n-release.mts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename scripts/{create-tag-n-release.ts => create-tag-n-release.mts} (100%) diff --git a/package.json b/package.json index 5dd0f3c5..1c4e3a68 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build": "rimraf dist && gradio cc build --no-generate-docs", "changeset": "changeset", "check-encoding": "python ./scripts/check_encoding.py", - "ci:create-tag-n-release": "tsx ./scripts/create-tag-n-release.ts", + "ci:create-tag-n-release": "tsx ./scripts/create-tag-n-release.mts", "ci:publish": "tsx ./scripts/publish-to-pypi.mts", "ci:version": "pnpm run version", "dev": "gradio cc dev docs/app.py", diff --git a/scripts/create-tag-n-release.ts b/scripts/create-tag-n-release.mts similarity index 100% rename from scripts/create-tag-n-release.ts rename to scripts/create-tag-n-release.mts From f9f2caea9dde666edcb0f2ba21d6048101b9f68c Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Fri, 27 Mar 2026 18:28:44 +0800 Subject: [PATCH 18/31] fix: cloned props --- .changeset/pre.json | 4 +- CHANGELOG.md | 2 +- .../antdx/actions/action_item/__init__.py | 2 +- .../pro/multimodal_input/__init__.py | 3 +- config/changelog/CHANGELOG.md | 2 +- config/lint-config/CHANGELOG.md | 2 +- docs/components/antdx/actions/demos/basic.py | 28 +-- docs/components/pro/chatbot/README-zh_CN.md | 7 +- docs/components/pro/chatbot/README.md | 7 +- .../pro/multimodal_input/README-zh_CN.md | 8 +- .../components/pro/multimodal_input/README.md | 30 ++- frontend/CHANGELOG.md | 2 +- frontend/antd/CHANGELOG.md | 2 +- .../antd/config-provider/config-provider.tsx | 1 + frontend/antdx/CHANGELOG.md | 2 +- .../action-item/actions.action-item.tsx | 7 +- frontend/antdx/actions/actions.tsx | 1 + frontend/base/CHANGELOG.md | 2 +- frontend/package.json | 8 +- frontend/pro/CHANGELOG.md | 2 +- .../svelte-preprocess-react/react-slot.tsx | 14 +- package.json | 2 +- pnpm-lock.yaml | 230 +++++++++--------- pyproject.toml | 2 +- 24 files changed, 196 insertions(+), 174 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 471b7fc2..c74b580b 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -11,7 +11,5 @@ "@modelscope-studio/base": "1.6.1", "@modelscope-studio/pro": "1.6.1" }, - "changesets": [ - "eleven-aliens-sell" - ] + "changesets": ["eleven-aliens-sell"] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 98269376..cd14c58d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -445,4 +445,4 @@ ### Features - [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`d1829d3`](https://github.com/modelscope/modelscope-studio/commit/d1829d34dd0bce8834d2e257b612d79705e57d6d) - update the timing of onMount call and new onUpdate lifecycle of custom component. Thanks [@Col0ring](https://github.com/Col0ring)! -- [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`96e1682`](https://github.com/modelscope/modelscope-studio/commit/96e1682b7cb63907aafba06afb820f55d7df8ff0) - add Flow component. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file +- [#16](https://github.com/modelscope/modelscope-studio/pull/16) [`96e1682`](https://github.com/modelscope/modelscope-studio/commit/96e1682b7cb63907aafba06afb820f55d7df8ff0) - add Flow component. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/backend/modelscope_studio/components/antdx/actions/action_item/__init__.py b/backend/modelscope_studio/components/antdx/actions/action_item/__init__.py index b2b0781e..08f12c1c 100644 --- a/backend/modelscope_studio/components/antdx/actions/action_item/__init__.py +++ b/backend/modelscope_studio/components/antdx/actions/action_item/__init__.py @@ -21,7 +21,7 @@ class AntdXActionsActionItem(ModelScopeLayoutComponent): ] # Supported slots - SLOTS = ['label', 'icon', 'actionRender'] + SLOTS = ['label', 'icon', 'actionRender', "subItems"] def __init__( self, diff --git a/backend/modelscope_studio/components/pro/multimodal_input/__init__.py b/backend/modelscope_studio/components/pro/multimodal_input/__init__.py index 01af5a4a..94da7e9f 100644 --- a/backend/modelscope_studio/components/pro/multimodal_input/__init__.py +++ b/backend/modelscope_studio/components/pro/multimodal_input/__init__.py @@ -139,8 +139,7 @@ class ModelScopeProMultimodalInput(ModelScopeDataLayoutComponent): # supported slots SLOTS = [ 'suffix', 'header', 'prefix', 'footer', 'skill.title', - 'skill.toolTip.title' - 'skill.closable.closeIcon' + 'skill.toolTip.title', 'skill.closable.closeIcon' ] def __init__( diff --git a/config/changelog/CHANGELOG.md b/config/changelog/CHANGELOG.md index 1312a3f8..f04a2edc 100644 --- a/config/changelog/CHANGELOG.md +++ b/config/changelog/CHANGELOG.md @@ -276,4 +276,4 @@ No significant changes to this package were made in this release. ## 0.2.0 -No significant changes to this package were made in this release. \ No newline at end of file +No significant changes to this package were made in this release. diff --git a/config/lint-config/CHANGELOG.md b/config/lint-config/CHANGELOG.md index 48228822..66c520ab 100644 --- a/config/lint-config/CHANGELOG.md +++ b/config/lint-config/CHANGELOG.md @@ -276,4 +276,4 @@ No significant changes to this package were made in this release. ## 0.2.0 -No significant changes to this package were made in this release. \ No newline at end of file +No significant changes to this package were made in this release. diff --git a/docs/components/antdx/actions/demos/basic.py b/docs/components/antdx/actions/demos/basic.py index 65d32bfd..6f154b00 100644 --- a/docs/components/antdx/actions/demos/basic.py +++ b/docs/components/antdx/actions/demos/basic.py @@ -22,8 +22,8 @@ def on_delete(): with ms.Slot("icon"): antd.Icon("RedoOutlined") with antdx.Actions.ActionItem(key="copy", label="Copy"): - with ms.Slot("icon"): - antd.Icon("CopyOutlined") + with ms.Slot("actionRender"): + antdx.Actions.Copy(text="Copy Text") antd.Divider("More Menu ActionItems") with antdx.Actions() as actions2: with antdx.Actions.ActionItem(key="retry", label="Retry"): @@ -33,24 +33,24 @@ def on_delete(): with ms.Slot("icon"): antd.Icon("CopyOutlined") with antdx.Actions.ActionItem(key="more"): - with antdx.Actions.ActionItem(key="share", label="Share"): - with ms.Slot("icon"): - antd.Icon("ShareAltOutlined") - antdx.Actions.ActionItem(key="qq", label="QQ") - antdx.Actions.ActionItem(key="wechat", label="WeChat") - antdx.Actions.ActionItem(key="import", label="Import") - with antdx.Actions.ActionItem( - key="delete", label="Delete", - danger=True) as actions_delete_ActionItem: - with ms.Slot("icon"): - antd.Icon("DeleteOutlined") + with ms.Slot("subItems"): + with antdx.Actions.ActionItem(key="share", + label="Share"): + with ms.Slot("icon"): + antd.Icon("ShareAltOutlined") + antdx.Actions.ActionItem(key="import", label="Import") + with antdx.Actions.ActionItem( + key="delete", label="Delete", + danger=True) as actions_delete_item: + with ms.Slot("icon"): + antd.Icon("DeleteOutlined") with antdx.Actions.ActionItem(key="clear", label="Clear"): with ms.Slot("icon"): antd.Icon("ClearOutlined") actions.click(fn=on_click) actions2.click(fn=on_click) - actions_delete_ActionItem.ActionItem_click(fn=on_delete) + actions_delete_item.item_click(fn=on_delete) if __name__ == "__main__": demo.queue().launch() diff --git a/docs/components/pro/chatbot/README-zh_CN.md b/docs/components/pro/chatbot/README-zh_CN.md index 0ce3b4a1..5856b10f 100644 --- a/docs/components/pro/chatbot/README-zh_CN.md +++ b/docs/components/pro/chatbot/README-zh_CN.md @@ -107,7 +107,7 @@ class ChatbotPromptsConfig(GradioModel): # Ant Design X welcome props: https://x.ant.design/components/welcome class ChatbotWelcomeConfig(GradioModel): variant: Optional[Literal['borderless', 'filled']] = 'borderless' - icon: Optional[Union[str, Path]] = None + icon: Optional[Union[str, Path, dict]] = None title: Optional[str] = None description: Optional[str] = None extra: Optional[str] = None @@ -277,6 +277,8 @@ class ChatbotDataFileContentOptions(GradioModel): gap: Optional[Union[Literal["small", "middle", "large"], str, int, float]] = "small" image_props: Optional[dict] = None + video_props: Optional[dict] = None + audio_props: Optional[dict] = None # Ant Design X prompts props: https://x.ant.design/components/prompts @@ -318,7 +320,8 @@ class ChatbotDataMessageContent(GradioModel): class ChatbotDataMessage(ChatbotBotConfig): - role: Union[Literal['user', 'assistant', 'system'], str] = None + role: Union[Literal['user', 'assistant', 'system', 'divider'], str] = None + divider_props: Optional[dict] = None key: Optional[Union[str, int, float]] = None # If status is 'pending', the message will not render the footer area (including 'actions' and 'footer'). status: Optional[Literal['pending', 'done']] = None diff --git a/docs/components/pro/chatbot/README.md b/docs/components/pro/chatbot/README.md index f4b41015..55763eb3 100644 --- a/docs/components/pro/chatbot/README.md +++ b/docs/components/pro/chatbot/README.md @@ -106,7 +106,7 @@ class ChatbotPromptsConfig(GradioModel): # Ant Design X welcome props: https://x.ant.design/components/welcome class ChatbotWelcomeConfig(GradioModel): variant: Optional[Literal['borderless', 'filled']] = 'borderless' - icon: Optional[Union[str, Path]] = None + icon: Optional[Union[str, Path, dict]] = None title: Optional[str] = None description: Optional[str] = None extra: Optional[str] = None @@ -276,6 +276,8 @@ class ChatbotDataFileContentOptions(GradioModel): gap: Optional[Union[Literal["small", "middle", "large"], str, int, float]] = "small" image_props: Optional[dict] = None + video_props: Optional[dict] = None + audio_props: Optional[dict] = None # Ant Design X prompts props: https://x.ant.design/components/prompts @@ -317,7 +319,8 @@ class ChatbotDataMessageContent(GradioModel): class ChatbotDataMessage(ChatbotBotConfig): - role: Union[Literal['user', 'assistant', 'system'], str] = None + role: Union[Literal['user', 'assistant', 'system', 'divider'], str] = None + divider_props: Optional[dict] = None key: Optional[Union[str, int, float]] = None # If status is 'pending', the message will not render the footer area (including 'actions' and 'footer'). status: Optional[Literal['pending', 'done']] = None diff --git a/docs/components/pro/multimodal_input/README-zh_CN.md b/docs/components/pro/multimodal_input/README-zh_CN.md index 95ae0d42..f966a55a 100644 --- a/docs/components/pro/multimodal_input/README-zh_CN.md +++ b/docs/components/pro/multimodal_input/README-zh_CN.md @@ -39,11 +39,16 @@ | placeholder | `str \| None` | None | 输入框的提示信息。 | | disabled | `bool \| None` | None | 是否禁用。 | | upload_config | `MultimodalInputUploadConfig \| dict \| None` | None | 文件上传配置。 | +| slot_config | `dict \| None` | None | 词槽配置,配置后输入框将变为词槽模式,支持结构化输入,此模式 value 配置将无效。 | +| skill | `dict \| None` | None | 技能配置,输入框将变为词槽模式,支持结构化输入,此模式 value 配置将无效。 | ### 插槽 ```python -SLOTS=['actions', "prefix", 'footer', 'header'] +SLOTS = [ + 'suffix', 'header', 'prefix', 'footer', 'skill.title', + 'skill.toolTip.title', 'skill.closable.closeIcon' +] ``` ### 类型 @@ -110,5 +115,4 @@ class MultimodalInputUploadConfig(GradioModel): class MultimodalInputValue(GradioModel): files: Optional[ListFiles] = None text: Optional[str] = None - ``` diff --git a/docs/components/pro/multimodal_input/README.md b/docs/components/pro/multimodal_input/README.md index f3ecec28..b7bbe126 100644 --- a/docs/components/pro/multimodal_input/README.md +++ b/docs/components/pro/multimodal_input/README.md @@ -28,22 +28,27 @@ A multimodal input component based on [Ant Design X](https://x.ant.design), supp ### Props -| Attribute | Type | Default Value | Description | -| ------------- | -------------------------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------- | -| value | `dict \| MultimodalInputValue \| None` | None | Default value to display, formatted as `{ "text":"", "files":[] }`. | -| loading | `bool \| None` | None | Whether the input is in a loading state, in which case the `cancel` event can be triggered. | -| mode | `inline \| block` | 'inline' | The rending mode of the input box. If `block`, the input box and the submit button will be rendered separately. | -| auto_size | `bool \| { minRows?: number; maxRows?: number } \| None` | { "maxRows": 8 } | Height auto size feature, can be set to True \| False or an object { "minRows": 2, "maxRows": 6 }. | -| read_only | `bool \| None` | None | Whether the input is read-only. | -| submit_type | `Literal['enter', 'shiftEnter'] \| None` | 'enter' | How the input box triggers the `submit` event. | -| placeholder | `str \| None` | None | Input placeholder text. | -| disabled | `bool \| None` | None | Whether to disable. | -| upload_config | `MultimodalInputUploadConfig \| dict \| None` | None | File upload configuration. | +| Attribute | Type | Default Value | Description | +| ------------- | -------------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| value | `dict \| MultimodalInputValue \| None` | None | Default value to display, formatted as `{ "text":"", "files":[] }`. | +| loading | `bool \| None` | None | Whether the input is in a loading state, in which case the `cancel` event can be triggered. | +| mode | `inline \| block` | 'inline' | The rending mode of the input box. If `block`, the input box and the submit button will be rendered separately. | +| auto_size | `bool \| { minRows?: number; maxRows?: number } \| None` | { "maxRows": 8 } | Height auto size feature, can be set to True \| False or an object { "minRows": 2, "maxRows": 6 }. | +| read_only | `bool \| None` | None | Whether the input is read-only. | +| submit_type | `Literal['enter', 'shiftEnter'] \| None` | 'enter' | How the input box triggers the `submit` event. | +| placeholder | `str \| None` | None | Input placeholder text. | +| disabled | `bool \| None` | None | Whether to disable. | +| upload_config | `MultimodalInputUploadConfig \| dict \| None` | None | File upload configuration. | +| slot_config | `dict \| None` | None | Slot configuration, after configuration the input box will switch to slot mode, supporting structured input. In this mode, value configurations will be invalid. | +| skill | `dict \| None` | None | Skill configuration, after configuration the input box will switch to slot mode, supporting structured input. In this mode, value configurations will be invalid. | ### Slots ```python -SLOTS=['actions', "prefix", 'footer', 'header'] +SLOTS = [ + 'suffix', 'header', 'prefix', 'footer', 'skill.title', + 'skill.toolTip.title', 'skill.closable.closeIcon' +] ``` ### Types @@ -106,6 +111,7 @@ class MultimodalInputUploadConfig(GradioModel): } }) + class MultimodalInputValue(GradioModel): files: Optional[ListFiles] = None text: Optional[str] = None diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index f56e6406..998130e7 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -342,4 +342,4 @@ No significant changes to this package were made in this release. ### Features -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file +- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/antd/CHANGELOG.md b/frontend/antd/CHANGELOG.md index eb796740..804f5c84 100644 --- a/frontend/antd/CHANGELOG.md +++ b/frontend/antd/CHANGELOG.md @@ -271,4 +271,4 @@ No significant changes to this package were made in this release. ### Features -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file +- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/antd/config-provider/config-provider.tsx b/frontend/antd/config-provider/config-provider.tsx index 71baf639..9ecc641a 100644 --- a/frontend/antd/config-provider/config-provider.tsx +++ b/frontend/antd/config-provider/config-provider.tsx @@ -104,6 +104,7 @@ export const ConfigProvider = sveltify< }); }, [localeProp]); const ProviderComponent = component || AConfigProvider; + return (
diff --git a/frontend/antdx/CHANGELOG.md b/frontend/antdx/CHANGELOG.md index bad11d73..eb3a6d74 100644 --- a/frontend/antdx/CHANGELOG.md +++ b/frontend/antdx/CHANGELOG.md @@ -154,4 +154,4 @@ No significant changes to this package were made in this release. ### Features -- [#48](https://github.com/modelscope/modelscope-studio/pull/48) [`b0197ef`](https://github.com/modelscope/modelscope-studio/commit/b0197ef7ede322e2c40b4e1dcc6480530a62490e) - integrate antdx. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file +- [#48](https://github.com/modelscope/modelscope-studio/pull/48) [`b0197ef`](https://github.com/modelscope/modelscope-studio/commit/b0197ef7ede322e2c40b4e1dcc6480530a62490e) - integrate antdx. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/antdx/actions/action-item/actions.action-item.tsx b/frontend/antdx/actions/action-item/actions.action-item.tsx index 321c2610..7e824d09 100644 --- a/frontend/antdx/actions/action-item/actions.action-item.tsx +++ b/frontend/antdx/actions/action-item/actions.action-item.tsx @@ -8,11 +8,12 @@ export const ActionsActionItem = sveltify< Partial[number]> & ItemHandlerProps >((props) => { return ( - + {...props} - allowedSlots={['default']} + allowedSlots={['default', 'subItems']} + itemChildrenKey="subItems" itemChildren={(items) => { - return items.default.length > 0 ? items.default : undefined; + return items.subItems.length > 0 ? items.subItems : items.default; }} /> ); diff --git a/frontend/antdx/actions/actions.tsx b/frontend/antdx/actions/actions.tsx index 51f34010..238799bd 100644 --- a/frontend/antdx/actions/actions.tsx +++ b/frontend/antdx/actions/actions.tsx @@ -106,6 +106,7 @@ export const Actions = sveltify< items || renderItems(resolvedSlotItems, { clone: true, + children: 'subItems', }) || [] ); diff --git a/frontend/base/CHANGELOG.md b/frontend/base/CHANGELOG.md index 947392b1..bab5c073 100644 --- a/frontend/base/CHANGELOG.md +++ b/frontend/base/CHANGELOG.md @@ -233,4 +233,4 @@ No significant changes to this package were made in this release. ### Features -- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file +- [`4a46970`](https://github.com/modelscope/modelscope-studio/commit/4a46970007452af606abe02cdfa54a4959b2f3db) - integrate ant design. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/package.json b/frontend/package.json index dc8b47a3..2b29874a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,7 @@ "type": "module", "dependencies": { "@ant-design/cssinjs": "^2.1.2", - "@ant-design/icons": "^6.1.0", + "@ant-design/icons": "^6.1.1", "@ant-design/x": "^2.4.0", "@babel/standalone": "^7.29.2", "@gradio/client": "2.1.0", @@ -16,13 +16,13 @@ "@gradio/utils": "0.11.3", "@monaco-editor/react": "^4.7.0", "amuchina": "^1.0.12", - "antd": "^6.3.3", + "antd": "^6.3.4", "classnames": "^2.5.1", "dayjs": "^1.11.20", "dequal": "^2.0.2", "github-slugger": "^2.0.0", "immer": "^11.1.4", - "katex": "^0.16.40", + "katex": "^0.16.43", "lodash-es": "^4.17.23", "marked": "^17.0.5", "marked-gfm-heading-id": "^4.1.3", @@ -36,7 +36,7 @@ "react-syntax-highlighter": "^16.1.1", "svelte": "5.48.0", "svelte-i18n": "^4.0.1", - "wavesurfer.js": "^7.12.4" + "wavesurfer.js": "^7.12.5" }, "devDependencies": { "@babel/core": "^7.29.0", diff --git a/frontend/pro/CHANGELOG.md b/frontend/pro/CHANGELOG.md index 5e1565c1..9fb60a12 100644 --- a/frontend/pro/CHANGELOG.md +++ b/frontend/pro/CHANGELOG.md @@ -140,4 +140,4 @@ No significant changes to this package were made in this release. ### Fixes -- [#64](https://github.com/modelscope/modelscope-studio/pull/64) [`7bf9d74`](https://github.com/modelscope/modelscope-studio/commit/7bf9d741bc66e318d3c310e798b1a781d23a0abf) - the logic of uploading files. Thanks [@Col0ring](https://github.com/Col0ring)! \ No newline at end of file +- [#64](https://github.com/modelscope/modelscope-studio/pull/64) [`7bf9d74`](https://github.com/modelscope/modelscope-studio/commit/7bf9d741bc66e318d3c310e798b1a781d23a0abf) - the logic of uploading files. Thanks [@Col0ring](https://github.com/Col0ring)! diff --git a/frontend/svelte-preprocess-react/react-slot.tsx b/frontend/svelte-preprocess-react/react-slot.tsx index ecaff66f..eff58909 100644 --- a/frontend/svelte-preprocess-react/react-slot.tsx +++ b/frontend/svelte-preprocess-react/react-slot.tsx @@ -1,6 +1,7 @@ import { useContextPropsContext } from '@svelte-preprocess-react/react-contexts'; import React, { forwardRef, useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; +import { useMemoizedEqualValue } from '@utils/hooks/useMemoizedEqualValue'; import { styleObject2HtmlStyle } from '@utils/style'; import { debounce } from 'lodash-es'; @@ -106,11 +107,15 @@ function mountElRef(elRef: React.ForwardedRef, el: HTMLElement) { // eslint-disable-next-line react/display-name export const ReactSlot = forwardRef( - ({ slot, clone: cloneProp, className, style, observeAttributes }, elRef) => { + ( + { slot, clone: cloneProp, className, style: styleProp, observeAttributes }, + elRef + ) => { const ref = useRef(null); const [children, setChildren] = useState([]); const { forceClone } = useContextPropsContext(); const clone = forceClone ? true : cloneProp; + const style = useMemoizedEqualValue(styleProp); useEffect(() => { if (!ref.current || !slot) { return; @@ -121,8 +126,11 @@ export const ReactSlot = forwardRef( let child = cloned as Element; if ( cloned.tagName.toLowerCase() === 'svelte-slot' && - cloned.children.length === 1 && - cloned.children[0] + ((cloned.children.length === 1 && cloned.children[0]) || + (cloned.children.length === 2 && + cloned.children[0].tagName.toLowerCase() === + 'react-portal-target' && + cloned.children[1].tagName.toLowerCase() === 'svelte-slot')) ) { child = cloned.children[0]; if ( diff --git a/package.json b/package.json index 1c4e3a68..70d98beb 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "prettier-plugin-packagejson": "^3.0.2", "prettier-plugin-svelte": "^3.5.1", "rimraf": "^6.1.3", - "stylelint": "^17.5.0", + "stylelint": "^17.6.0", "svelte": "5.48.0", "svelte-check": "^4.4.5", "tslib": "^2.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5154a30..16c1795c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,8 +66,8 @@ importers: specifier: ^6.1.3 version: 6.1.3 stylelint: - specifier: ^17.5.0 - version: 17.5.0(typescript@5.9.3) + specifier: ^17.6.0 + version: 17.6.0(typescript@5.9.3) svelte: specifier: 5.48.0 version: 5.48.0 @@ -161,16 +161,16 @@ importers: version: 0.1.2 stylelint-config-standard: specifier: ^40.0.0 - version: 40.0.0(stylelint@17.5.0(typescript@5.9.3)) + version: 40.0.0(stylelint@17.6.0(typescript@5.9.3)) stylelint-declaration-block-no-ignored-properties: specifier: ^3.0.0 - version: 3.0.0(stylelint@17.5.0(typescript@5.9.3)) + version: 3.0.0(stylelint@17.6.0(typescript@5.9.3)) stylelint-order: specifier: ^8.1.1 - version: 8.1.1(stylelint@17.5.0(typescript@5.9.3)) + version: 8.1.1(stylelint@17.6.0(typescript@5.9.3)) stylelint-prettier: specifier: ^5.0.3 - version: 5.0.3(prettier@3.8.1)(stylelint@17.5.0(typescript@5.9.3)) + version: 5.0.3(prettier@3.8.1)(stylelint@17.6.0(typescript@5.9.3)) svelte-eslint-parser: specifier: ^1.6.0 version: 1.6.0(svelte@5.55.0) @@ -191,11 +191,11 @@ importers: specifier: ^2.1.2 version: 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/icons': - specifier: ^6.1.0 - version: 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^6.1.1 + version: 6.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/x': specifier: ^2.4.0 - version: 2.4.0(antd@6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 2.4.0(antd@6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/standalone': specifier: ^7.29.2 version: 7.29.2 @@ -218,8 +218,8 @@ importers: specifier: ^1.0.12 version: 1.0.12 antd: - specifier: ^6.3.3 - version: 6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^6.3.4 + version: 6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) classnames: specifier: ^2.5.1 version: 2.5.1 @@ -236,8 +236,8 @@ importers: specifier: ^11.1.4 version: 11.1.4 katex: - specifier: ^0.16.40 - version: 0.16.40 + specifier: ^0.16.43 + version: 0.16.43 lodash-es: specifier: ^4.17.23 version: 4.17.23 @@ -278,8 +278,8 @@ importers: specifier: ^4.0.1 version: 4.0.1(svelte@5.48.0) wavesurfer.js: - specifier: ^7.12.4 - version: 7.12.4 + specifier: ^7.12.5 + version: 7.12.5 devDependencies: '@babel/core': specifier: ^7.29.0 @@ -355,9 +355,6 @@ packages: '@adobe/css-tools@4.3.3': resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} - '@ant-design/colors@8.0.0': - resolution: {integrity: sha512-6YzkKCw30EI/E9kHOIXsQDHmMvTllT8STzjMb4K2qzit33RW2pqCJP0sk+hidBntXxE+Vz4n1+RvCTfBw6OErw==} - '@ant-design/colors@8.0.1': resolution: {integrity: sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==} @@ -373,10 +370,6 @@ packages: react: '>=16.0.0' react-dom: '>=16.0.0' - '@ant-design/fast-color@3.0.0': - resolution: {integrity: sha512-eqvpP7xEDm2S7dUzl5srEQCBTXZMmY3ekf97zI+M2DHOYyKdJGH0qua0JACHTqbkRnD/KHFQP9J1uMJ/XWVzzA==} - engines: {node: '>=8.x'} - '@ant-design/fast-color@3.0.1': resolution: {integrity: sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==} engines: {node: '>=8.x'} @@ -384,8 +377,8 @@ packages: '@ant-design/icons-svg@4.4.2': resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} - '@ant-design/icons@6.1.0': - resolution: {integrity: sha512-KrWMu1fIg3w/1F2zfn+JlfNDU8dDqILfA5Tg85iqs1lf8ooyGlbkA+TkwfOKKgqpUmAiRY1PTFpuOU2DAIgSUg==} + '@ant-design/icons@6.1.1': + resolution: {integrity: sha512-AMT4N2y++TZETNHiM77fs4a0uPVCJGuL5MTonk13Pvv7UN7sID1cNEZOc1qNqx6zLKAOilTEFAdAoAFKa0U//Q==} engines: {node: '>=8'} peerDependencies: react: '>=16.0.0' @@ -573,8 +566,8 @@ packages: '@cacheable/memory@2.0.8': resolution: {integrity: sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==} - '@cacheable/utils@2.4.0': - resolution: {integrity: sha512-PeMMsqjVq+bF0WBsxFBxr/WozBJiZKY0rUojuaCoIaKnEl3Ju1wfEwS+SV1DU/cSe8fqHIPiYJFif8T3MVt4cQ==} + '@cacheable/utils@2.4.1': + resolution: {integrity: sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==} '@changesets/apply-release-plan@7.1.0': resolution: {integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==} @@ -747,8 +740,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.1': - resolution: {integrity: sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==} + '@csstools/css-syntax-patches-for-csstree@1.1.2': + resolution: {integrity: sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -1702,15 +1695,15 @@ packages: react: '>=16.11.0' react-dom: '>=16.11.0' - '@rc-component/form@1.7.2': - resolution: {integrity: sha512-5C90rXH7aZvvvxB4M5ew+QxROvimdL/lqhSshR8NsyiR7HKOoGQYSitxdfENnH6/0KNFxEy2ranVe2LrTnHZIw==} + '@rc-component/form@1.8.0': + resolution: {integrity: sha512-eUD5KKYnIZWmJwRA0vnyO/ovYUfHGU1svydY1OrqU5fw8Oz9Tdqvxvrlh0wl6xI/EW69dT7II49xpgOWzK3T5A==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' - '@rc-component/image@1.6.0': - resolution: {integrity: sha512-tSfn2ZE/oP082g4QIOxeehkmgnXB7R+5AFj/lIFr4k7pEuxHBdyGIq9axoCY9qea8NN0DY6p4IB/F07tLqaT5A==} + '@rc-component/image@1.8.0': + resolution: {integrity: sha512-Dr41bFevLB5NgVaJhEUmNvbEf+ynAhim6W98ZW2xvCsdFISc2TYP4ZvCVdie3eaZdum2kieVcvpNHu+UrzAAHA==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -1749,6 +1742,12 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' + '@rc-component/motion@1.3.2': + resolution: {integrity: sha512-itfd+GztzJYAb04Z4RkEub1TbJAfZc2Iuy8p44U44xD1F5+fNYFKI3897ijlbIyfvXkTmMm+KGcjkQQGMHywEQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + '@rc-component/mutate-observer@2.0.1': resolution: {integrity: sha512-AyarjoLU5YlxuValRi+w8JRH2Z84TBbFO2RoGWz9d8bSu0FqT8DtugH3xC3BV7mUwlmROFauyWuXFuq4IFbH+w==} engines: {node: '>=8.x'} @@ -1828,6 +1827,12 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' + '@rc-component/resize-observer@1.1.2': + resolution: {integrity: sha512-t/Bb0W8uvL4PYKAB3YcChC+DlHh0Wt5kM7q/J+0qpVEUMLe7Hk5zuvc9km0hMnTFPSx5Z7Wu/fzCLN6erVLE8Q==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + '@rc-component/segmented@1.3.0': resolution: {integrity: sha512-5J/bJ01mbDnoA6P/FW8SxUvKn+OgUSTZJPzCNnTBntG50tzoP7DydGhqxp7ggZXZls7me3mc2EQDXakU3iTVFg==} peerDependencies: @@ -1926,12 +1931,6 @@ packages: react: '>=18.0.0' react-dom: '>=18.0.0' - '@rc-component/util@1.3.0': - resolution: {integrity: sha512-hfXE04CVsxI/slmWKeSh6du7sSKpbvVdVEZCa8A+2QWDlL97EsCYme2c3ZWLn1uC9FR21JoewlrhUPWO4QgO8w==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - '@rc-component/util@1.9.0': resolution: {integrity: sha512-5uW6AfhIigCWeEQDthTozlxiT4Prn6xYQWeO0xokjcaa186OtwPRHBZJ2o0T0FhbjGhZ3vXdbkv0sx3gAYW7Vg==} peerDependencies: @@ -2845,8 +2844,8 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - antd@6.3.3: - resolution: {integrity: sha512-T8FAQelw36zS96cZw2U/qEjpYny5yFc7hg+1W7DvVr8xMoSXWvyB8WvmiDVH0nS0LPYV4y2sxetsJoGZt7rhhw==} + antd@6.3.4: + resolution: {integrity: sha512-Bu6JivPP7bFfYIdVj+61dxhwSOz+A3m0W7PlDasFGC3H3sNMYQ9gJXZoo11/rQh7pTlOQa351q5Ig/zjI98XYw==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' @@ -4303,8 +4302,8 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flat-cache@6.1.21: - resolution: {integrity: sha512-2u7cJfSf7Th7NxEk/VzQjnPoglok2YCsevS7TSbJjcDQWJPbqUUnSYtriHSvtnq+fRZHy1s0ugk4ApnQyhPGoQ==} + flat-cache@6.1.22: + resolution: {integrity: sha512-N2dnzVJIphnNsjHcrxGW7DePckJ6haPrSFqpsBUhHYgwtKGVq4JrBGielEGD2fCVnsGm1zlBVZ8wGhkyuetgug==} flatted@2.0.2: resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} @@ -5063,8 +5062,8 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} - katex@0.16.40: - resolution: {integrity: sha512-1DJcK/L05k1Y9Gf7wMcyuqFOL6BiY3vY0CFcAM/LPRN04NALxcl6u7lOWNsp3f/bCHWxigzQl6FbR95XJ4R84Q==} + katex@0.16.43: + resolution: {integrity: sha512-K7NL5JtGrFEglipOAjY4UYA69CnTuNmjArxeXF6+bw7h2OGySUPv6QWRjfb1gmutJ4Mw/qLeBqiROOEDULp4nA==} hasBin: true keyv@4.5.4: @@ -6646,8 +6645,8 @@ packages: prettier: '>=3.0.0' stylelint: '>=16.0.0' - stylelint@17.5.0: - resolution: {integrity: sha512-o/NS6zhsPZFmgUm5tXX4pVNg1XDOZSlucLdf2qow/lVn4JIyzZIQ5b3kad1ugqUj3GSIgr2u5lQw7X8rjqw33g==} + stylelint@17.6.0: + resolution: {integrity: sha512-tokrsMIVAR9vAQ/q3UVEr7S0dGXCi7zkCezPRnS2kqPUulvUh5Vgfwngrk4EoAoW7wnrThqTdnTFN5Ra7CaxIg==} engines: {node: '>=20.19.0'} hasBin: true @@ -7189,8 +7188,8 @@ packages: vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - wavesurfer.js@7.12.4: - resolution: {integrity: sha512-b/+XnWfJejNdvNUmtm4M5QzQepHhUbTo+62wYybwdV1B/Sn9vHhgb1xckRm0rGY2ZefJwLkE7lYcKnLfIia4cQ==} + wavesurfer.js@7.12.5: + resolution: {integrity: sha512-MSZcA13R9ZlxgYpzfakaSYf8dz5tCdZKYbjtN1qnKbCi+UoyfaTuhvjlXHrITi/fgeO3qWfsH7U3BP1AKnwRNg==} web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} @@ -7358,10 +7357,6 @@ snapshots: '@adobe/css-tools@4.3.3': {} - '@ant-design/colors@8.0.0': - dependencies: - '@ant-design/fast-color': 3.0.0 - '@ant-design/colors@8.0.1': dependencies: '@ant-design/fast-color': 3.0.1 @@ -7386,17 +7381,15 @@ snapshots: react-dom: 19.2.4(react@19.2.4) stylis: 4.3.6 - '@ant-design/fast-color@3.0.0': {} - '@ant-design/fast-color@3.0.1': {} '@ant-design/icons-svg@4.4.2': {} - '@ant-design/icons@6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ant-design/icons@6.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@ant-design/colors': 8.0.0 + '@ant-design/colors': 8.0.1 '@ant-design/icons-svg': 4.4.2 - '@rc-component/util': 1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -7410,18 +7403,18 @@ snapshots: react-dom: 19.2.4(react@19.2.4) throttle-debounce: 5.0.2 - '@ant-design/x@2.4.0(antd@6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ant-design/x@2.4.0(antd@6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/colors': 8.0.1 '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/cssinjs-utils': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/fast-color': 3.0.1 - '@ant-design/icons': 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ant-design/icons': 6.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/runtime': 7.29.2 '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - antd: 6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + antd: 6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 lodash.throttle: 4.1.1 mermaid: 11.13.0 @@ -7660,12 +7653,12 @@ snapshots: '@cacheable/memory@2.0.8': dependencies: - '@cacheable/utils': 2.4.0 + '@cacheable/utils': 2.4.1 '@keyv/bigmap': 1.3.1(keyv@5.6.0) hookified: 1.15.1 keyv: 5.6.0 - '@cacheable/utils@2.4.0': + '@cacheable/utils@2.4.1': dependencies: hashery: 1.5.1 keyv: 5.6.0 @@ -7972,7 +7965,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.2(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -8346,7 +8339,7 @@ snapshots: '@types/katex': 0.16.8 '@types/prismjs': 1.26.5 github-slugger: 2.0.0 - katex: 0.16.40 + katex: 0.16.43 marked: 12.0.2 marked-gfm-heading-id: 3.2.0(marked@12.0.2) marked-highlight: 2.2.3(marked@12.0.2) @@ -8758,7 +8751,7 @@ snapshots: '@rc-component/collapse@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.29.2 - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -8780,7 +8773,7 @@ snapshots: '@rc-component/dialog@1.8.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -8789,7 +8782,7 @@ snapshots: '@rc-component/drawer@1.4.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -8804,7 +8797,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/form@1.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/form@1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/async-validator': 5.1.0 '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -8812,9 +8805,9 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/image@1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@rc-component/image@1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -8849,7 +8842,7 @@ snapshots: '@rc-component/menu@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -8868,6 +8861,13 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + '@rc-component/motion@1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + clsx: 2.1.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + '@rc-component/mutate-observer@2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -8876,7 +8876,7 @@ snapshots: '@rc-component/notification@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -8885,7 +8885,7 @@ snapshots: '@rc-component/overflow@1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.29.2 - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -8901,7 +8901,7 @@ snapshots: '@rc-component/picker@1.9.1(dayjs@1.11.20)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -8943,10 +8943,16 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + '@rc-component/resize-observer@1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + '@rc-component/segmented@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.29.2 - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -8986,7 +8992,7 @@ snapshots: '@rc-component/table@1.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/context': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -8997,8 +9003,8 @@ snapshots: dependencies: '@rc-component/dropdown': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/menu': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9007,7 +9013,7 @@ snapshots: '@rc-component/textarea@1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/input': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9041,7 +9047,7 @@ snapshots: '@rc-component/tree@1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 @@ -9050,9 +9056,9 @@ snapshots: '@rc-component/trigger@3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9072,13 +9078,6 @@ snapshots: react-dom: 19.2.4(react@19.2.4) react-is: 18.3.1 - '@rc-component/util@1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - is-mobile: 5.0.0 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-is: 18.3.1 - '@rc-component/util@1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: is-mobile: 5.0.0 @@ -9089,7 +9088,7 @@ snapshots: '@rc-component/virtual-list@1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.29.2 - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9882,13 +9881,13 @@ snapshots: ansi-styles@6.2.3: {} - antd@6.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + antd@6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@ant-design/colors': 8.0.1 '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/cssinjs-utils': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/fast-color': 3.0.1 - '@ant-design/icons': 6.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ant-design/icons': 6.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/react-slick': 2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/runtime': 7.29.2 '@rc-component/cascader': 1.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -9898,13 +9897,13 @@ snapshots: '@rc-component/dialog': 1.8.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/drawer': 1.4.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/dropdown': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/form': 1.7.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/image': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/form': 1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/image': 1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/input': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/input-number': 1.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/mentions': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/menu': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/mutate-observer': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/notification': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/pagination': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -9912,7 +9911,7 @@ snapshots: '@rc-component/progress': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/qrcode': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/rate': 1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/segmented': 1.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/select': 1.6.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/slider': 1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -10199,7 +10198,7 @@ snapshots: cacheable@2.3.4: dependencies: '@cacheable/memory': 2.0.8 - '@cacheable/utils': 2.4.0 + '@cacheable/utils': 2.4.1 hookified: 1.15.1 keyv: 5.6.0 qified: 0.9.0 @@ -11603,7 +11602,7 @@ snapshots: file-entry-cache@11.1.2: dependencies: - flat-cache: 6.1.21 + flat-cache: 6.1.22 file-entry-cache@4.0.0: dependencies: @@ -11655,7 +11654,7 @@ snapshots: flatted: 3.4.2 keyv: 4.5.4 - flat-cache@6.1.21: + flat-cache@6.1.22: dependencies: cacheable: 2.3.4 flatted: 3.4.2 @@ -12398,7 +12397,7 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 - katex@0.16.40: + katex@0.16.43: dependencies: commander: 8.3.0 @@ -12741,7 +12740,7 @@ snapshots: dagre-d3-es: 7.0.14 dayjs: 1.11.20 dompurify: 3.3.2 - katex: 0.16.40 + katex: 0.16.43 khroma: 2.1.0 lodash-es: 4.17.23 marked: 16.4.2 @@ -14092,18 +14091,18 @@ snapshots: transitivePeerDependencies: - supports-color - stylelint-config-recommended@18.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.6.0(typescript@5.9.3)): dependencies: - stylelint: 17.5.0(typescript@5.9.3) + stylelint: 17.6.0(typescript@5.9.3) - stylelint-config-standard@40.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.6.0(typescript@5.9.3)): dependencies: - stylelint: 17.5.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.5.0(typescript@5.9.3)) + stylelint: 17.6.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.6.0(typescript@5.9.3)) - stylelint-declaration-block-no-ignored-properties@3.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-declaration-block-no-ignored-properties@3.0.0(stylelint@17.6.0(typescript@5.9.3)): dependencies: - stylelint: 17.5.0(typescript@5.9.3) + stylelint: 17.6.0(typescript@5.9.3) stylelint-order@2.2.1(stylelint@9.10.1): dependencies: @@ -14112,23 +14111,23 @@ snapshots: postcss-sorting: 4.1.0 stylelint: 9.10.1 - stylelint-order@8.1.1(stylelint@17.5.0(typescript@5.9.3)): + stylelint-order@8.1.1(stylelint@17.6.0(typescript@5.9.3)): dependencies: postcss: 8.5.8 postcss-sorting: 10.0.0(postcss@8.5.8) - stylelint: 17.5.0(typescript@5.9.3) + stylelint: 17.6.0(typescript@5.9.3) - stylelint-prettier@5.0.3(prettier@3.8.1)(stylelint@17.5.0(typescript@5.9.3)): + stylelint-prettier@5.0.3(prettier@3.8.1)(stylelint@17.6.0(typescript@5.9.3)): dependencies: prettier: 3.8.1 prettier-linter-helpers: 1.0.0 - stylelint: 17.5.0(typescript@5.9.3) + stylelint: 17.6.0(typescript@5.9.3) - stylelint@17.5.0(typescript@5.9.3): + stylelint@17.6.0(typescript@5.9.3): dependencies: '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-syntax-patches-for-csstree': 1.1.1(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.2(css-tree@3.2.1) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.1) @@ -14147,7 +14146,6 @@ snapshots: html-tags: 5.1.0 ignore: 7.0.5 import-meta-resolve: 4.2.0 - imurmurhash: 0.1.4 is-plain-object: 5.0.0 mathml-tag-names: 4.0.0 meow: 14.1.0 @@ -14836,7 +14834,7 @@ snapshots: vscode-uri@3.1.0: {} - wavesurfer.js@7.12.4: {} + wavesurfer.js@7.12.5: {} web-streams-polyfill@3.3.3: {} diff --git a/pyproject.toml b/pyproject.toml index 2ca8bba0..0439a695 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ keywords = [ 'gradio-antdx', ] # Add dependencies here -dependencies = ["gradio>=6.0"] +dependencies = ["6.0= Date: Wed, 8 Apr 2026 14:37:50 +0800 Subject: [PATCH 19/31] chore: update deps --- config/changelog/package.json | 2 +- config/lint-config/package.json | 12 +- frontend/package.json | 20 +- .../svelte-preprocess-react/react-slot.tsx | 4 +- package.json | 6 +- pnpm-lock.yaml | 1066 ++++++++--------- 6 files changed, 513 insertions(+), 597 deletions(-) diff --git a/config/changelog/package.json b/config/changelog/package.json index cf0337be..90b4da81 100644 --- a/config/changelog/package.json +++ b/config/changelog/package.json @@ -25,7 +25,7 @@ }, "devDependencies": { "@changesets/types": "^6.1.0", - "@types/node": "^25.5.0", + "@types/node": "^25.5.2", "tsup": "^8.5.1" } } diff --git a/config/lint-config/package.json b/config/lint-config/package.json index 803cc156..4947e2d8 100644 --- a/config/lint-config/package.json +++ b/config/lint-config/package.json @@ -16,9 +16,9 @@ } }, "dependencies": { - "@eslint/compat": "^2.0.3", + "@eslint/compat": "^2.0.4", "@eslint/js": "^10.0.1", - "@typescript-eslint/parser": "^8.57.2", + "@typescript-eslint/parser": "^8.58.1", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", @@ -27,10 +27,10 @@ "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", - "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-svelte": "^3.16.0", + "eslint-plugin-simple-import-sort": "^13.0.0", + "eslint-plugin-svelte": "^3.17.0", "globals": "^17.4.0", - "postcss": "^8.5.8", + "postcss": "^8.5.9", "postcss-less": "^6.0.0", "stylelint-config-rational-order": "^0.1.2", "stylelint-config-standard": "^40.0.0", @@ -38,7 +38,7 @@ "stylelint-order": "^8.1.1", "stylelint-prettier": "^5.0.3", "svelte-eslint-parser": "^1.6.0", - "typescript-eslint": "^8.57.2" + "typescript-eslint": "^8.58.1" }, "devDependencies": { "@types/eslint": "^9.6.1", diff --git a/frontend/package.json b/frontend/package.json index 2b29874a..b5f30c30 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,33 +8,33 @@ "dependencies": { "@ant-design/cssinjs": "^2.1.2", "@ant-design/icons": "^6.1.1", - "@ant-design/x": "^2.4.0", + "@ant-design/x": "^2.5.0", "@babel/standalone": "^7.29.2", "@gradio/client": "2.1.0", "@gradio/preview": "0.15.2", - "@gradio/statustracker": "^0.12.5", + "@gradio/statustracker": "^0.13.1", "@gradio/utils": "0.11.3", "@monaco-editor/react": "^4.7.0", "amuchina": "^1.0.12", - "antd": "^6.3.4", + "antd": "^6.3.5", "classnames": "^2.5.1", "dayjs": "^1.11.20", "dequal": "^2.0.2", "github-slugger": "^2.0.0", "immer": "^11.1.4", - "katex": "^0.16.43", - "lodash-es": "^4.17.23", - "marked": "^17.0.5", - "marked-gfm-heading-id": "^4.1.3", - "marked-highlight": "^2.2.3", - "mermaid": "^11.13.0", + "katex": "^0.16.45", + "lodash-es": "^4.18.1", + "marked": "^18.0.0", + "marked-gfm-heading-id": "^4.1.4", + "marked-highlight": "^2.2.4", + "mermaid": "^11.14.0", "monaco-editor": "^0.55.1", "path-browserify-esm": "^1.0.6", "prismjs": "^1.30.0", "react": "^19.2.4", "react-dom": "^19.2.4", "react-syntax-highlighter": "^16.1.1", - "svelte": "5.48.0", + "svelte": "5.55.2", "svelte-i18n": "^4.0.1", "wavesurfer.js": "^7.12.5" }, diff --git a/frontend/svelte-preprocess-react/react-slot.tsx b/frontend/svelte-preprocess-react/react-slot.tsx index eff58909..5e22fa9d 100644 --- a/frontend/svelte-preprocess-react/react-slot.tsx +++ b/frontend/svelte-preprocess-react/react-slot.tsx @@ -128,9 +128,9 @@ export const ReactSlot = forwardRef( cloned.tagName.toLowerCase() === 'svelte-slot' && ((cloned.children.length === 1 && cloned.children[0]) || (cloned.children.length === 2 && - cloned.children[0].tagName.toLowerCase() === + cloned.children[0]?.tagName?.toLowerCase() === 'react-portal-target' && - cloned.children[1].tagName.toLowerCase() === 'svelte-slot')) + cloned.children[1]?.tagName?.toLowerCase() === 'svelte-slot')) ) { child = cloned.children[0]; if ( diff --git a/package.json b/package.json index 70d98beb..897ca8f6 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@manypkg/get-packages": "^3.1.0", "@modelscope-studio/changelog": "workspace:*", "@modelscope-studio/lint-config": "workspace:*", - "@types/node": "^25.5.0", + "@types/node": "^25.5.2", "eslint": "^9.39.3", "husky": "^9.1.7", "lint-staged": "^16.4.0", @@ -44,8 +44,8 @@ "prettier-plugin-svelte": "^3.5.1", "rimraf": "^6.1.3", "stylelint": "^17.6.0", - "svelte": "5.48.0", - "svelte-check": "^4.4.5", + "svelte": "5.55.2", + "svelte-check": "^4.4.6", "tslib": "^2.8.1", "tsx": "^4.21.0", "typescript": "^5.9.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 16c1795c..8152b75e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,10 +19,10 @@ importers: version: 9.0.0 '@changesets/cli': specifier: ^2.30.0 - version: 2.30.0(@types/node@25.5.0) + version: 2.30.0(@types/node@25.5.2) '@commitlint/cli': specifier: ^20.5.0 - version: 20.5.0(@types/node@25.5.0)(conventional-commits-parser@6.3.0)(typescript@5.9.3) + version: 20.5.0(@types/node@25.5.2)(conventional-commits-parser@6.3.0)(typescript@5.9.3) '@commitlint/config-conventional': specifier: ^20.5.0 version: 20.5.0 @@ -36,8 +36,8 @@ importers: specifier: workspace:* version: link:config/lint-config '@types/node': - specifier: ^25.5.0 - version: 25.5.0 + specifier: ^25.5.2 + version: 25.5.2 eslint: specifier: ^9.39.3 version: 9.39.4(jiti@2.6.1) @@ -61,7 +61,7 @@ importers: version: 3.0.2(prettier@3.8.1) prettier-plugin-svelte: specifier: ^3.5.1 - version: 3.5.1(prettier@3.8.1)(svelte@5.48.0) + version: 3.5.1(prettier@3.8.1)(svelte@5.55.2) rimraf: specifier: ^6.1.3 version: 6.1.3 @@ -69,11 +69,11 @@ importers: specifier: ^17.6.0 version: 17.6.0(typescript@5.9.3) svelte: - specifier: 5.48.0 - version: 5.48.0 + specifier: 5.55.2 + version: 5.55.2 svelte-check: - specifier: ^4.4.5 - version: 4.4.5(picomatch@4.0.3)(svelte@5.48.0)(typescript@5.9.3) + specifier: ^4.4.6 + version: 4.4.6(picomatch@4.0.4)(svelte@5.55.2)(typescript@5.9.3) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -100,23 +100,23 @@ importers: specifier: ^6.1.0 version: 6.1.0 '@types/node': - specifier: ^25.5.0 - version: 25.5.0 + specifier: ^25.5.2 + version: 25.5.2 tsup: specifier: ^8.5.1 - version: 8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.5.0))(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.5.2))(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) config/lint-config: dependencies: '@eslint/compat': - specifier: ^2.0.3 - version: 2.0.3(eslint@9.39.4(jiti@2.6.1)) + specifier: ^2.0.4 + version: 2.0.4(eslint@9.39.4(jiti@2.6.1)) '@eslint/js': specifier: ^10.0.1 version: 10.0.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/parser': - specifier: ^8.57.2 - version: 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.58.1 + version: 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-config-prettier: specifier: ^10.1.8 version: 10.1.8(eslint@9.39.4(jiti@2.6.1)) @@ -125,7 +125,7 @@ importers: version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) + version: 2.32.0(@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-jsx-a11y: specifier: ^6.10.2 version: 6.10.2(eslint@9.39.4(jiti@2.6.1)) @@ -142,20 +142,20 @@ importers: specifier: ^0.5.2 version: 0.5.2(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-simple-import-sort: - specifier: ^12.1.0 - version: 12.1.1(eslint@9.39.4(jiti@2.6.1)) + specifier: ^13.0.0 + version: 13.0.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-svelte: - specifier: ^3.16.0 - version: 3.16.0(eslint@9.39.4(jiti@2.6.1))(svelte@5.55.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)) + specifier: ^3.17.0 + version: 3.17.0(eslint@9.39.4(jiti@2.6.1))(svelte@5.55.2)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.2)(typescript@5.9.3)) globals: specifier: ^17.4.0 version: 17.4.0 postcss: - specifier: ^8.5.8 - version: 8.5.8 + specifier: ^8.5.9 + version: 8.5.9 postcss-less: specifier: ^6.0.0 - version: 6.0.0(postcss@8.5.8) + version: 6.0.0(postcss@8.5.9) stylelint-config-rational-order: specifier: ^0.1.2 version: 0.1.2 @@ -173,10 +173,10 @@ importers: version: 5.0.3(prettier@3.8.1)(stylelint@17.6.0(typescript@5.9.3)) svelte-eslint-parser: specifier: ^1.6.0 - version: 1.6.0(svelte@5.55.0) + version: 1.6.0(svelte@5.55.2) typescript-eslint: - specifier: ^8.57.2 - version: 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.58.1 + version: 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) devDependencies: '@types/eslint': specifier: ^9.6.1 @@ -194,8 +194,8 @@ importers: specifier: ^6.1.1 version: 6.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@ant-design/x': - specifier: ^2.4.0 - version: 2.4.0(antd@6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^2.5.0 + version: 2.5.0(antd@6.3.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/standalone': specifier: ^7.29.2 version: 7.29.2 @@ -204,13 +204,13 @@ importers: version: 2.1.0 '@gradio/preview': specifier: 0.15.2 - version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.48.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.9)(rollup@4.59.0)(svelte@5.55.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@gradio/statustracker': - specifier: ^0.12.5 - version: 0.12.5(svelte@5.48.0) + specifier: ^0.13.1 + version: 0.13.1(svelte@5.55.2) '@gradio/utils': specifier: 0.11.3 - version: 0.11.3(svelte@5.48.0) + version: 0.11.3(svelte@5.55.2) '@monaco-editor/react': specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -218,8 +218,8 @@ importers: specifier: ^1.0.12 version: 1.0.12 antd: - specifier: ^6.3.4 - version: 6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^6.3.5 + version: 6.3.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) classnames: specifier: ^2.5.1 version: 2.5.1 @@ -236,23 +236,23 @@ importers: specifier: ^11.1.4 version: 11.1.4 katex: - specifier: ^0.16.43 - version: 0.16.43 + specifier: ^0.16.45 + version: 0.16.45 lodash-es: - specifier: ^4.17.23 - version: 4.17.23 + specifier: ^4.18.1 + version: 4.18.1 marked: - specifier: ^17.0.5 - version: 17.0.5 + specifier: ^18.0.0 + version: 18.0.0 marked-gfm-heading-id: - specifier: ^4.1.3 - version: 4.1.3(marked@17.0.5) + specifier: ^4.1.4 + version: 4.1.4(marked@18.0.0) marked-highlight: - specifier: ^2.2.3 - version: 2.2.3(marked@17.0.5) + specifier: ^2.2.4 + version: 2.2.4(marked@18.0.0) mermaid: - specifier: ^11.13.0 - version: 11.13.0 + specifier: ^11.14.0 + version: 11.14.0 monaco-editor: specifier: ^0.55.1 version: 0.55.1 @@ -272,11 +272,11 @@ importers: specifier: ^16.1.1 version: 16.1.1(react@19.2.4) svelte: - specifier: 5.48.0 - version: 5.48.0 + specifier: 5.55.2 + version: 5.55.2 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.48.0) + version: 4.0.1(svelte@5.55.2) wavesurfer.js: specifier: ^7.12.5 version: 7.12.5 @@ -313,7 +313,7 @@ importers: version: 2.16.1 '@vitejs/plugin-react-swc': specifier: ^4.3.0 - version: 4.3.0(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.3.0(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) less: specifier: ^4.6.4 version: 4.6.4 @@ -322,7 +322,7 @@ importers: version: 0.67.1(@swc/core@1.15.18) vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) frontend/antd: {} @@ -390,8 +390,8 @@ packages: react: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@ant-design/x@2.4.0': - resolution: {integrity: sha512-2J+S6V2RuR1ZKOOTtY6/XUA+T/S690j25uTx2HTKC3q8S9wi8BUuJBEMNPkPHUf9V+3Y8KgChyB5JnZkKP5J6Q==} + '@ant-design/x@2.5.0': + resolution: {integrity: sha512-B4FGlYz++MHelu5+PHbdKCXASAz7n+W8bzpIDzFbK45Dx9mL6uR3jOpCN2UcuWE0w2hQ8wtuKbRb/AfGS+KNeA==} peerDependencies: antd: ^6.1.1 react: '>=18.0.0' @@ -627,20 +627,20 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@chevrotain/cst-dts-gen@11.1.2': - resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==} + '@chevrotain/cst-dts-gen@12.0.0': + resolution: {integrity: sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg==} - '@chevrotain/gast@11.1.2': - resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==} + '@chevrotain/gast@12.0.0': + resolution: {integrity: sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ==} - '@chevrotain/regexp-to-ast@11.1.2': - resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==} + '@chevrotain/regexp-to-ast@12.0.0': + resolution: {integrity: sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA==} - '@chevrotain/types@11.1.2': - resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} + '@chevrotain/types@12.0.0': + resolution: {integrity: sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA==} - '@chevrotain/utils@11.1.2': - resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} + '@chevrotain/utils@12.0.0': + resolution: {integrity: sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA==} '@commitlint/cli@20.5.0': resolution: {integrity: sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ==} @@ -1252,8 +1252,8 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@2.0.3': - resolution: {integrity: sha512-SjIJhGigp8hmd1YGIBwh7Ovri7Kisl42GYFjrOyHhtfYGGoLW6teYi/5p8W50KSsawUPpuLOSmsq1bD0NGQLBw==} + '@eslint/compat@2.0.4': + resolution: {integrity: sha512-o598tCGstJv9Kk4XapwP+oDij9HD9Qr3V37ABzTfdzVvbFciV+sfg9zSW6olj6G/IXj7p89SwSzPnZ+JUEPIPg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: ^8.40 || 9 || 10 @@ -1273,8 +1273,8 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@1.1.1': - resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} + '@eslint/core@1.2.0': + resolution: {integrity: sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/eslintrc@3.3.5': @@ -1317,8 +1317,8 @@ packages: '@formatjs/intl-localematcher@0.6.1': resolution: {integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==} - '@gradio/atoms@0.22.2': - resolution: {integrity: sha512-rafZ8f1PO6EIOE9SSjuzBRAThwNZvU+2sYCwUU35I1rhYq/4JEFV4Yaq3SlIyh3x3UHgnWEqny6LkBvfltPFIw==} + '@gradio/atoms@0.23.0': + resolution: {integrity: sha512-aFqoxOI4TXd2Ob7tAZ49j6xiX7Ik4+Rofr/ACPW1/idkCGQgB+0m7NchZzZ3tFiKjxX4/3Kctd7F0VEFZ8ZcQQ==} peerDependencies: svelte: ^5.48.0 @@ -1331,22 +1331,14 @@ packages: peerDependencies: svelte: ^5.48.0 - '@gradio/markdown-code@0.6.1': - resolution: {integrity: sha512-kss4xXrAOdYXc9ESR6lqulbnCQWYjTIu0eYLUlwHQ/AqcOgICG1CO9dxc9LGTlAIftkFjZka22+36HwpNJpjNw==} - peerDependencies: - svelte: ^5.48.0 - '@gradio/preview@0.15.2': resolution: {integrity: sha512-3AbAUClTlxNCQgnus8n0T3zCyZJbWMY8Fkza5I9PK47bTBrY4WlvxktNsfXNJjol+Zqov/x7ksLfwqbhady8uQ==} '@gradio/sanitize@0.2.0': resolution: {integrity: sha512-fb8v4s/YHhCRF+4d3xTAtaW2z9G2xUJBlWpKwc0vAK7GL/eSKLtNKnWNjgkiRIHzpwT4PZEvWa7WxuTMoJgj+Q==} - '@gradio/sanitize@0.3.0': - resolution: {integrity: sha512-NYw9HZaI12UKOitYToRibOsD4KaMRbdaBeGszB0wKTtknk02qry6RbQi6mkBSv8ynl0/mSsGFmAQoKpVju1W/A==} - - '@gradio/statustracker@0.12.5': - resolution: {integrity: sha512-TcDDjFo/0zOMNWkvMcS9k6Fo+2dEaC7vXcFYgFR+yes038z/D4zfp+m+3+l8aexe+Zz8QlZhRcpSsAtZdJA0HA==} + '@gradio/statustracker@0.13.1': + resolution: {integrity: sha512-PgqNwODKA2iGqw9hF6xmzR8wFkijLzMhtF3SIVChQZ01xYrkOyDhiIzQ6mnMBzk9vpTj7/Ml56RNwTHQamhCOQ==} peerDependencies: svelte: ^5.48.0 @@ -1358,8 +1350,8 @@ packages: '@gradio/utils@0.11.3': resolution: {integrity: sha512-k1X6HXcoOycvBHsXamCyiN21v40I88FjTgz1TsVF5Hb/vJoA1InHjT+Uo6vnt+aJ8UGtxjUMTBVFR/GOcgXB/Q==} - '@gradio/utils@0.12.0': - resolution: {integrity: sha512-twy9fxEikjqxgtP3fk8voIDdey3nYFpJfmayDU7/IGn3C35nk+kL4dsJfEPbQ99BXmRgBecurSJEduOFptOCCQ==} + '@gradio/utils@0.12.2': + resolution: {integrity: sha512-kyYVAieI1z3pKoGB/SkEM8sE4Uja25NVOyFdJeTkPgeQneLckcs+IgJFd0px2K90vsBBY4c1nEGZ9HQyXn+ltA==} '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -1453,8 +1445,8 @@ packages: resolution: {integrity: sha512-0FOIepYR4ugPYaHwK7hDeHDkfPOBVvayt9QpvRbi2LT/h2b0GaE/gM9Gag7fsnyYyNaTZ2IGyOuVg07IYepvYQ==} engines: {node: '>=20.0.0'} - '@mermaid-js/parser@1.0.1': - resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==} + '@mermaid-js/parser@1.1.0': + resolution: {integrity: sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw==} '@microsoft/api-extractor-model@7.30.7': resolution: {integrity: sha512-TBbmSI2/BHpfR9YhQA7nH0nqVmGgJ0xH0Ex4D99/qBDAUpnhA2oikGmdXanbw9AWWY/ExBYIpkmY8dBHdla3YQ==} @@ -1736,12 +1728,6 @@ packages: resolution: {integrity: sha512-bk/FJ09fLf+NLODMAFll6CfYrHPBioTedhW6lxDBuuWucJEqFUd4l/D/5JgIi3dina6sYahB8iuPAZTNz2pMxw==} engines: {node: '>=8.x'} - '@rc-component/motion@1.3.1': - resolution: {integrity: sha512-Wo1mkd0tCcHtvYvpPOmlYJz546z16qlsiwaygmW7NPJpOZOF9GBjhGzdzZSsC2lEJ1IUkWLF4gMHlRA1aSA+Yw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - '@rc-component/motion@1.3.2': resolution: {integrity: sha512-itfd+GztzJYAb04Z4RkEub1TbJAfZc2Iuy8p44U44xD1F5+fNYFKI3897ijlbIyfvXkTmMm+KGcjkQQGMHywEQ==} peerDependencies: @@ -1821,12 +1807,6 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@rc-component/resize-observer@1.1.1': - resolution: {integrity: sha512-NfXXMmiR+SmUuKE1NwJESzEUYUFWIDUn2uXpxCTOLwiRUUakd62DRNFjRJArgzyFW8S5rsL4aX5XlyIXyC/vRA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - '@rc-component/resize-observer@1.1.2': resolution: {integrity: sha512-t/Bb0W8uvL4PYKAB3YcChC+DlHh0Wt5kM7q/J+0qpVEUMLe7Hk5zuvc9km0hMnTFPSx5Z7Wu/fzCLN6erVLE8Q==} peerDependencies: @@ -1931,6 +1911,12 @@ packages: react: '>=18.0.0' react-dom: '>=18.0.0' + '@rc-component/util@1.10.1': + resolution: {integrity: sha512-q++9S6rUa5Idb/xIBNz6jtvumw5+O5YV5V0g4iK9mn9jWs4oGJheE3ZN1kAnE723AXyaD8v95yeOASmdk8Jnng==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + '@rc-component/util@1.9.0': resolution: {integrity: sha512-5uW6AfhIigCWeEQDthTozlxiT4Prn6xYQWeO0xokjcaa186OtwPRHBZJ2o0T0FhbjGhZ3vXdbkv0sx3gAYW7Vg==} peerDependencies: @@ -2541,11 +2527,8 @@ packages: '@types/node@18.19.130': resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} - '@types/node@25.5.0': - resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} - - '@types/prismjs@1.26.5': - resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} + '@types/node@25.5.2': + resolution: {integrity: sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==} '@types/prismjs@1.26.6': resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==} @@ -2583,63 +2566,63 @@ packages: '@types/which@3.0.4': resolution: {integrity: sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==} - '@typescript-eslint/eslint-plugin@8.57.2': - resolution: {integrity: sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==} + '@typescript-eslint/eslint-plugin@8.58.1': + resolution: {integrity: sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.2 + '@typescript-eslint/parser': ^8.58.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.57.2': - resolution: {integrity: sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==} + '@typescript-eslint/parser@8.58.1': + resolution: {integrity: sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.57.2': - resolution: {integrity: sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==} + '@typescript-eslint/project-service@8.58.1': + resolution: {integrity: sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.57.2': - resolution: {integrity: sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==} + '@typescript-eslint/scope-manager@8.58.1': + resolution: {integrity: sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.57.2': - resolution: {integrity: sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==} + '@typescript-eslint/tsconfig-utils@8.58.1': + resolution: {integrity: sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.57.2': - resolution: {integrity: sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==} + '@typescript-eslint/type-utils@8.58.1': + resolution: {integrity: sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.57.2': - resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} + '@typescript-eslint/types@8.58.1': + resolution: {integrity: sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.57.2': - resolution: {integrity: sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==} + '@typescript-eslint/typescript-estree@8.58.1': + resolution: {integrity: sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.57.2': - resolution: {integrity: sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==} + '@typescript-eslint/utils@8.58.1': + resolution: {integrity: sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.57.2': - resolution: {integrity: sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==} + '@typescript-eslint/visitor-keys@8.58.1': + resolution: {integrity: sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.9.2': @@ -2844,8 +2827,8 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - antd@6.3.4: - resolution: {integrity: sha512-Bu6JivPP7bFfYIdVj+61dxhwSOz+A3m0W7PlDasFGC3H3sNMYQ9gJXZoo11/rQh7pTlOQa351q5Ig/zjI98XYw==} + antd@6.3.5: + resolution: {integrity: sha512-8BPz9lpZWQm42PTx7yL4KxWAotVuqINiKcoYRcLtdd5BFmAcAZicVyFTnBJyRDlzGZFZeRW3foGu6jXYFnej6Q==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' @@ -3034,8 +3017,8 @@ packages: resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==} engines: {node: 18 || 20 || >=22} - brace-expansion@5.0.4: - resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} braces@2.3.2: @@ -3167,13 +3150,14 @@ packages: chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - chevrotain-allstar@0.3.1: - resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + chevrotain-allstar@0.4.1: + resolution: {integrity: sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA==} peerDependencies: - chevrotain: ^11.0.0 + chevrotain: ^12.0.0 - chevrotain@11.1.2: - resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} + chevrotain@12.0.0: + resolution: {integrity: sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ==} + engines: {node: '>=22.0.0'} chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} @@ -3377,8 +3361,8 @@ packages: peerDependencies: cytoscape: ^3.2.0 - cytoscape@3.33.1: - resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} + cytoscape@3.33.2: + resolution: {integrity: sha512-sj4HXd3DokGhzZAdjDejGvTPLqlt84vNFN8m7bGsOzDY5DyVcxIb2ejIXat2Iy7HxWhdT/N1oKyheJ5YdpsGuw==} engines: {node: '>=0.10'} d3-array@2.12.1: @@ -3640,8 +3624,8 @@ packages: resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} engines: {node: '>=0.10.0'} - delaunator@5.0.1: - resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} @@ -3663,8 +3647,8 @@ packages: resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - devalue@5.6.4: - resolution: {integrity: sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==} + devalue@5.7.0: + resolution: {integrity: sha512-qCvc8m7cImp1QDCsiY+C2EdSBWSj7Ucfoq87scSdYboDiIKdvMtFbH1U2VReBls6WMhMaUOoK3ZJEDNG/7zm3w==} diff@4.0.4: resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} @@ -3707,9 +3691,8 @@ packages: dompurify@3.2.7: resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==} - dompurify@3.3.2: - resolution: {integrity: sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==} - engines: {node: '>=20'} + dompurify@3.3.3: + resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} domutils@1.7.0: resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} @@ -4086,13 +4069,13 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-simple-import-sort@12.1.1: - resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + eslint-plugin-simple-import-sort@13.0.0: + resolution: {integrity: sha512-McAc+/Nlvcg4byY/CABGH8kqnefWBj8s3JA2okEtz8ixbECQgU46p0HkTUKa4YS7wvgGceimlc34p1nXqbWqtA==} peerDependencies: eslint: '>=5.0.0' - eslint-plugin-svelte@3.16.0: - resolution: {integrity: sha512-DJXxqpYZUxcE0SfYo8EJzV2ZC+zAD7fJp1n1HwcEMRR1cOEUYvjT9GuzJeNghMjgb7uxuK3IJAzI+x6zzUxO5A==} + eslint-plugin-svelte@3.17.0: + resolution: {integrity: sha512-sF6wgd5FLS2P8CCaOy2HdYYYEcZ6TwL251dLHUkNmtLnWECk1Dwc+j6VeulmmnFxr7Xs0WNtjweOA+bJ0PnaFw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 @@ -4601,9 +4584,6 @@ packages: htmlparser2@3.10.1: resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} - htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - human-id@4.1.3: resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true @@ -5062,8 +5042,8 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} - katex@0.16.43: - resolution: {integrity: sha512-K7NL5JtGrFEglipOAjY4UYA69CnTuNmjArxeXF6+bw7h2OGySUPv6QWRjfb1gmutJ4Mw/qLeBqiROOEDULp4nA==} + katex@0.16.45: + resolution: {integrity: sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==} hasBin: true keyv@4.5.4: @@ -5093,8 +5073,8 @@ packages: known-css-properties@0.37.0: resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} - langium@4.2.1: - resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} + langium@4.2.2: + resolution: {integrity: sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} language-subtag-registry@0.3.23: @@ -5240,8 +5220,8 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.17.23: - resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -5347,25 +5327,15 @@ packages: markdown-table@1.1.3: resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} - marked-gfm-heading-id@3.2.0: - resolution: {integrity: sha512-Xfxpr5lXLDLY10XqzSCA9l2dDaiabQUgtYM9hw8yunyVsB/xYBRpiic6BOiY/EAJw1ik1eWr1ET1HKOAPZBhXg==} + marked-gfm-heading-id@4.1.4: + resolution: {integrity: sha512-CspnvVfHSkb/znqdPS4jUR8HtCjq3M/DnrsJCrfLBLvdrgbemmoINKpeWKQYkBiXAoBGejw0cV7xzqrPdup3WA==} peerDependencies: - marked: '>=4 <13' + marked: '>=13 <19' - marked-gfm-heading-id@4.1.3: - resolution: {integrity: sha512-aR0i63LmFbuxU/gAgrgz1Ir+8HK6zAIFXMlckeKHpV+qKbYaOP95L4Ux5Gi+sKmCZU5qnN2rdKpvpb7PnUBIWg==} + marked-highlight@2.2.4: + resolution: {integrity: sha512-PZxisNMJDduSjc0q6uvjsnqqHCXc9s0eyzxDO9sB1eNGJnd/H1/Fu+z6g/liC1dfJdFW4SftMwMlLvsBhUPrqQ==} peerDependencies: - marked: '>=13 <18' - - marked-highlight@2.2.3: - resolution: {integrity: sha512-FCfZRxW/msZAiasCML4isYpxyQWKEEx44vOgdn5Kloae+Qc3q4XR7WjpKKf8oMLk7JP9ZCRd2vhtclJFdwxlWQ==} - peerDependencies: - marked: '>=4 <18' - - marked@12.0.2: - resolution: {integrity: sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==} - engines: {node: '>= 18'} - hasBin: true + marked: '>=4 <19' marked@14.0.0: resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==} @@ -5377,8 +5347,8 @@ packages: engines: {node: '>= 20'} hasBin: true - marked@17.0.5: - resolution: {integrity: sha512-6hLvc0/JEbRjRgzI6wnT2P1XuM1/RrrDEX0kPt0N7jGm1133g6X7DlxFasUIx+72aKAr904GTxhSLDrd5DIlZg==} + marked@18.0.0: + resolution: {integrity: sha512-2e7Qiv/HJSXj8rDEpgTvGKsP8yYtI9xXHKDnrftrmnrJPaFNM7VRb2YCzWaX4BP1iCJ/XPduzDJZMFoqTCcIMA==} engines: {node: '>= 20'} hasBin: true @@ -5422,8 +5392,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - mermaid@11.13.0: - resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==} + mermaid@11.14.0: + resolution: {integrity: sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g==} micromatch@3.1.10: resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} @@ -5450,8 +5420,8 @@ packages: resolution: {integrity: sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==} engines: {node: 18 || 20 || >=22} - minimatch@10.2.4: - resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} minimatch@3.1.2: @@ -5486,8 +5456,8 @@ packages: mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} - mlly@1.8.1: - resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} monaco-editor@0.55.1: resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==} @@ -5797,6 +5767,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + pidtree@0.3.1: resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} engines: {node: '>=0.10'} @@ -5970,8 +5944,8 @@ packages: resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} engines: {node: '>=6.0.0'} - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + postcss@8.5.9: + resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -6230,8 +6204,8 @@ packages: engines: {node: 20 || >=22} hasBin: true - robust-predicates@3.0.2: - resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} rollup@4.53.3: resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} @@ -6281,8 +6255,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sanitize-html@2.17.1: - resolution: {integrity: sha512-ehFCW+q1a4CSOWRAdX97BX/6/PDEkCqw7/0JXZAGQV57FQB3YOkTa/rrzHPeJ+Aghy4vZAFfWMYyfxIiB7F/gw==} + sanitize-html@2.17.2: + resolution: {integrity: sha512-EnffJUl46VE9uvZ0XeWzObHLurClLlT12gsOk1cHyP2Ol1P0BnBnsXmShlBmWVJM+dKieQI68R0tsPY5m/B+Jg==} sass@1.97.3: resolution: {integrity: sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==} @@ -6701,8 +6675,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.4.5: - resolution: {integrity: sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==} + svelte-check@4.4.6: + resolution: {integrity: sha512-kP1zG81EWaFe9ZyTv4ZXv44Csi6Pkdpb7S3oj6m+K2ec/IcDg/a8LsFsnVLqm2nxtkSwsd5xPj/qFkTBgXHXjg==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: @@ -6762,12 +6736,8 @@ packages: typescript: optional: true - svelte@5.48.0: - resolution: {integrity: sha512-+NUe82VoFP1RQViZI/esojx70eazGF4u0O/9ucqZ4rPcOZD+n5EVp17uYsqwdzjUjZyTpGKunHbDziW6AIAVkQ==} - engines: {node: '>=18'} - - svelte@5.55.0: - resolution: {integrity: sha512-SThllKq6TRMBwPtat7ASnm/9CDXnIhBR0NPGw0ujn2DVYx9rVwsPZxDaDQcYGdUz/3BYVsCzdq7pZarRQoGvtw==} + svelte@5.55.2: + resolution: {integrity: sha512-z41M/hi0ZPTzrwVKLvB/R1/Oo08gL1uIib8HZ+FncqxxtY9MLb01emg2fqk+WLZ/lNrrtNDFh7BZLDxAHvMgLw==} engines: {node: '>=18'} svg-tags@1.0.0: @@ -6815,14 +6785,14 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} - tinyexec@1.0.4: resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} engines: {node: '>=18'} + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} + tinyglobby@0.2.14: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} @@ -6831,6 +6801,10 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + to-object-path@0.3.0: resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} engines: {node: '>=0.10.0'} @@ -6955,12 +6929,12 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.57.2: - resolution: {integrity: sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==} + typescript-eslint@8.58.1: + resolution: {integrity: sha512-gf6/oHChByg9HJvhMO1iBexJh12AqqTfnuxscMDOVqfJW3htsdRJI/GfPpHTTcyeB8cSTUY2JcZmVgoyPqcrDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' typescript-json-schema@0.67.1: resolution: {integrity: sha512-vKTZB/RoYTIBdVP7E7vrgHMCssBuhja91wQy498QIVhvfRimaOgjc98uwAXmZ7mbLUytJmOSbF11wPz+ByQeXg==} @@ -7365,7 +7339,7 @@ snapshots: dependencies: '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/runtime': 7.29.2 - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -7403,7 +7377,7 @@ snapshots: react-dom: 19.2.4(react@19.2.4) throttle-debounce: 5.0.2 - '@ant-design/x@2.4.0(antd@6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ant-design/x@2.5.0(antd@6.3.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/colors': 8.0.1 '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -7411,13 +7385,13 @@ snapshots: '@ant-design/fast-color': 3.0.1 '@ant-design/icons': 6.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@babel/runtime': 7.29.2 - '@rc-component/motion': 1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/resize-observer': 1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - antd: 6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + antd: 6.3.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 lodash.throttle: 4.1.1 - mermaid: 11.13.0 + mermaid: 11.14.0 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) react-syntax-highlighter: 16.1.1(react@19.2.4) @@ -7425,7 +7399,7 @@ snapshots: '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.6.0 - tinyexec: 1.0.2 + tinyexec: 1.1.1 '@babel/code-frame@7.27.1': dependencies: @@ -7692,7 +7666,7 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.30.0(@types/node@25.5.0)': + '@changesets/cli@2.30.0(@types/node@25.5.2)': dependencies: '@changesets/apply-release-plan': 7.1.0 '@changesets/assemble-release-plan': 6.0.9 @@ -7708,7 +7682,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.5.0) + '@inquirer/external-editor': 1.0.3(@types/node@25.5.2) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 enquirer: 2.4.1 @@ -7813,28 +7787,26 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 - '@chevrotain/cst-dts-gen@11.1.2': + '@chevrotain/cst-dts-gen@12.0.0': dependencies: - '@chevrotain/gast': 11.1.2 - '@chevrotain/types': 11.1.2 - lodash-es: 4.17.23 + '@chevrotain/gast': 12.0.0 + '@chevrotain/types': 12.0.0 - '@chevrotain/gast@11.1.2': + '@chevrotain/gast@12.0.0': dependencies: - '@chevrotain/types': 11.1.2 - lodash-es: 4.17.23 + '@chevrotain/types': 12.0.0 - '@chevrotain/regexp-to-ast@11.1.2': {} + '@chevrotain/regexp-to-ast@12.0.0': {} - '@chevrotain/types@11.1.2': {} + '@chevrotain/types@12.0.0': {} - '@chevrotain/utils@11.1.2': {} + '@chevrotain/utils@12.0.0': {} - '@commitlint/cli@20.5.0(@types/node@25.5.0)(conventional-commits-parser@6.3.0)(typescript@5.9.3)': + '@commitlint/cli@20.5.0(@types/node@25.5.2)(conventional-commits-parser@6.3.0)(typescript@5.9.3)': dependencies: '@commitlint/format': 20.5.0 '@commitlint/lint': 20.5.0 - '@commitlint/load': 20.5.0(@types/node@25.5.0)(typescript@5.9.3) + '@commitlint/load': 20.5.0(@types/node@25.5.2)(typescript@5.9.3) '@commitlint/read': 20.5.0(conventional-commits-parser@6.3.0) '@commitlint/types': 20.5.0 tinyexec: 1.0.4 @@ -7883,14 +7855,14 @@ snapshots: '@commitlint/rules': 20.5.0 '@commitlint/types': 20.5.0 - '@commitlint/load@20.5.0(@types/node@25.5.0)(typescript@5.9.3)': + '@commitlint/load@20.5.0(@types/node@25.5.2)(typescript@5.9.3)': dependencies: '@commitlint/config-validator': 20.5.0 '@commitlint/execute-rule': 20.0.0 '@commitlint/resolve-extends': 20.5.0 '@commitlint/types': 20.5.0 cosmiconfig: 9.0.1(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.2.0(@types/node@25.5.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.2.0(@types/node@25.5.2)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) is-plain-obj: 4.1.0 lodash.mergewith: 4.6.2 picocolors: 1.1.1 @@ -8239,9 +8211,9 @@ snapshots: '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.0.3(eslint@9.39.4(jiti@2.6.1))': + '@eslint/compat@2.0.4(eslint@9.39.4(jiti@2.6.1))': dependencies: - '@eslint/core': 1.1.1 + '@eslint/core': 1.2.0 optionalDependencies: eslint: 9.39.4(jiti@2.6.1) @@ -8261,7 +8233,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@1.1.1': + '@eslint/core@1.2.0': dependencies: '@types/json-schema': 7.0.15 @@ -8318,41 +8290,26 @@ snapshots: dependencies: tslib: 2.8.1 - '@gradio/atoms@0.22.2(svelte@5.48.0)': + '@gradio/atoms@0.23.0(svelte@5.55.2)': dependencies: - '@gradio/icons': 0.15.1(svelte@5.48.0) - '@gradio/markdown-code': 0.6.1(svelte@5.48.0) - '@gradio/utils': 0.12.0(svelte@5.48.0) - svelte: 5.48.0 + '@gradio/icons': 0.15.1(svelte@5.55.2) + '@gradio/utils': 0.12.2(svelte@5.55.2) + svelte: 5.55.2 '@gradio/client@2.1.0': dependencies: fetch-event-stream: 0.1.6 - '@gradio/icons@0.15.1(svelte@5.48.0)': - dependencies: - svelte: 5.48.0 - - '@gradio/markdown-code@0.6.1(svelte@5.48.0)': + '@gradio/icons@0.15.1(svelte@5.55.2)': dependencies: - '@gradio/sanitize': 0.3.0 - '@types/katex': 0.16.8 - '@types/prismjs': 1.26.5 - github-slugger: 2.0.0 - katex: 0.16.43 - marked: 12.0.2 - marked-gfm-heading-id: 3.2.0(marked@12.0.2) - marked-highlight: 2.2.3(marked@12.0.2) - mermaid: 11.13.0 - prismjs: 1.30.0 - svelte: 5.48.0 + svelte: 5.55.2 - '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(rollup@4.59.0)(svelte@5.48.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': + '@gradio/preview@0.15.2(@babel/core@7.29.0)(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.9)(rollup@4.59.0)(svelte@5.55.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)': dependencies: '@originjs/vite-plugin-commonjs': 1.0.3 '@rollup/plugin-sucrase': 5.1.0(rollup@4.59.0) '@rollup/plugin-terser': 0.4.4(rollup@4.59.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.2)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@types/which': 3.0.4 coffeescript: 2.7.0 lightningcss: 1.31.1 @@ -8360,10 +8317,10 @@ snapshots: sass: 1.97.3 stylus: 0.64.0 sucrase: 3.35.1 - sugarss: 5.0.1(postcss@8.5.8) - svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.48.0)(typescript@5.9.3) + sugarss: 5.0.1(postcss@8.5.9) + svelte-preprocess: 6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.9)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(svelte@5.55.2)(typescript@5.9.3) typescript: 5.9.3 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) which: 5.0.0 yootils: 0.3.1 transitivePeerDependencies: @@ -8384,35 +8341,30 @@ snapshots: '@gradio/sanitize@0.2.0': dependencies: amuchina: 1.0.12 - sanitize-html: 2.17.1 + sanitize-html: 2.17.2 - '@gradio/sanitize@0.3.0': + '@gradio/statustracker@0.13.1(svelte@5.55.2)': dependencies: - amuchina: 1.0.12 - sanitize-html: 2.17.1 - - '@gradio/statustracker@0.12.5(svelte@5.48.0)': - dependencies: - '@gradio/atoms': 0.22.2(svelte@5.48.0) - '@gradio/icons': 0.15.1(svelte@5.48.0) + '@gradio/atoms': 0.23.0(svelte@5.55.2) + '@gradio/icons': 0.15.1(svelte@5.55.2) '@gradio/sanitize': 0.2.0 - '@gradio/utils': 0.12.0(svelte@5.48.0) - svelte: 5.48.0 + '@gradio/utils': 0.12.2(svelte@5.55.2) + svelte: 5.55.2 - '@gradio/theme@0.6.1(svelte@5.48.0)': + '@gradio/theme@0.6.1(svelte@5.55.2)': dependencies: - svelte: 5.48.0 + svelte: 5.55.2 - '@gradio/utils@0.11.3(svelte@5.48.0)': + '@gradio/utils@0.11.3(svelte@5.55.2)': dependencies: - '@gradio/theme': 0.6.1(svelte@5.48.0) + '@gradio/theme': 0.6.1(svelte@5.55.2) transitivePeerDependencies: - svelte - '@gradio/utils@0.12.0(svelte@5.48.0)': + '@gradio/utils@0.12.2(svelte@5.55.2)': dependencies: - '@gradio/theme': 0.6.1(svelte@5.48.0) - svelte-i18n: 4.0.1(svelte@5.48.0) + '@gradio/theme': 0.6.1(svelte@5.55.2) + svelte-i18n: 4.0.1(svelte@5.55.2) transitivePeerDependencies: - svelte @@ -8433,14 +8385,14 @@ snapshots: dependencies: '@antfu/install-pkg': 1.1.0 '@iconify/types': 2.0.0 - mlly: 1.8.1 + mlly: 1.8.2 - '@inquirer/external-editor@1.0.3(@types/node@25.5.0)': + '@inquirer/external-editor@1.0.3(@types/node@25.5.2)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 25.5.0 + '@types/node': 25.5.2 '@isaacs/balanced-match@4.0.1': optional: true @@ -8527,28 +8479,28 @@ snapshots: js-yaml: 4.1.0 tinyglobby: 0.2.14 - '@mermaid-js/parser@1.0.1': + '@mermaid-js/parser@1.1.0': dependencies: - langium: 4.2.1 + langium: 4.2.2 - '@microsoft/api-extractor-model@7.30.7(@types/node@25.5.0)': + '@microsoft/api-extractor-model@7.30.7(@types/node@25.5.2)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@25.5.0) + '@rushstack/node-core-library': 5.14.0(@types/node@25.5.2) transitivePeerDependencies: - '@types/node' optional: true - '@microsoft/api-extractor@7.52.10(@types/node@25.5.0)': + '@microsoft/api-extractor@7.52.10(@types/node@25.5.2)': dependencies: - '@microsoft/api-extractor-model': 7.30.7(@types/node@25.5.0) + '@microsoft/api-extractor-model': 7.30.7(@types/node@25.5.2) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@25.5.0) + '@rushstack/node-core-library': 5.14.0(@types/node@25.5.2) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.4(@types/node@25.5.0) - '@rushstack/ts-command-line': 5.0.2(@types/node@25.5.0) + '@rushstack/terminal': 0.15.4(@types/node@25.5.2) + '@rushstack/ts-command-line': 5.0.2(@types/node@25.5.2) lodash: 4.17.23 minimatch: 10.0.3 resolve: 1.22.11 @@ -8736,14 +8688,14 @@ snapshots: dependencies: '@rc-component/select': 1.6.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/tree': 1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/checkbox@2.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8752,7 +8704,7 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8760,14 +8712,14 @@ snapshots: '@rc-component/color-picker@3.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ant-design/fast-color': 3.0.1 - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/context@2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8775,7 +8727,7 @@ snapshots: dependencies: '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8784,7 +8736,7 @@ snapshots: dependencies: '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8792,7 +8744,7 @@ snapshots: '@rc-component/dropdown@1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8800,7 +8752,7 @@ snapshots: '@rc-component/form@1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/async-validator': 5.1.0 - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8809,7 +8761,7 @@ snapshots: dependencies: '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8817,14 +8769,14 @@ snapshots: '@rc-component/input-number@1.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/mini-decimal': 1.1.3 - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/input@1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8835,7 +8787,7 @@ snapshots: '@rc-component/menu': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/textarea': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8845,7 +8797,7 @@ snapshots: '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8854,30 +8806,23 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 - '@rc-component/motion@1.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - clsx: 2.1.1 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - '@rc-component/motion@1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/mutate-observer@2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/notification@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8886,14 +8831,14 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/pagination@1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8903,7 +8848,7 @@ snapshots: '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8912,14 +8857,14 @@ snapshots: '@rc-component/portal@2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/progress@1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8932,20 +8877,14 @@ snapshots: '@rc-component/rate@1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@rc-component/resize-observer@1.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - '@rc-component/resize-observer@1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8953,7 +8892,7 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8962,7 +8901,7 @@ snapshots: dependencies: '@rc-component/overflow': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -8970,21 +8909,21 @@ snapshots: '@rc-component/slider@1.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/steps@1.2.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/switch@1.0.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -8993,7 +8932,7 @@ snapshots: dependencies: '@rc-component/context': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9005,7 +8944,7 @@ snapshots: '@rc-component/menu': 1.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9014,7 +8953,7 @@ snapshots: dependencies: '@rc-component/input': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9022,7 +8961,7 @@ snapshots: '@rc-component/tooltip@1.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9031,7 +8970,7 @@ snapshots: dependencies: '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9040,7 +8979,7 @@ snapshots: dependencies: '@rc-component/select': 1.6.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/tree': 1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9048,7 +8987,7 @@ snapshots: '@rc-component/tree@1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 @@ -9059,14 +8998,14 @@ snapshots: '@rc-component/motion': 1.3.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/portal': 2.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@rc-component/upload@1.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9078,6 +9017,13 @@ snapshots: react-dom: 19.2.4(react@19.2.4) react-is: 18.3.1 + '@rc-component/util@1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + is-mobile: 5.0.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-is: 18.3.1 + '@rc-component/util@1.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: is-mobile: 5.0.0 @@ -9089,7 +9035,7 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 '@rc-component/resize-observer': 1.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9262,7 +9208,7 @@ snapshots: '@rtsao/scc@1.1.0': {} - '@rushstack/node-core-library@5.14.0(@types/node@25.5.0)': + '@rushstack/node-core-library@5.14.0(@types/node@25.5.2)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -9273,7 +9219,7 @@ snapshots: resolve: 1.22.11 semver: 7.5.4 optionalDependencies: - '@types/node': 25.5.0 + '@types/node': 25.5.2 optional: true '@rushstack/rig-package@0.5.3': @@ -9282,17 +9228,17 @@ snapshots: strip-json-comments: 3.1.1 optional: true - '@rushstack/terminal@0.15.4(@types/node@25.5.0)': + '@rushstack/terminal@0.15.4(@types/node@25.5.2)': dependencies: - '@rushstack/node-core-library': 5.14.0(@types/node@25.5.0) + '@rushstack/node-core-library': 5.14.0(@types/node@25.5.2) supports-color: 8.1.1 optionalDependencies: - '@types/node': 25.5.0 + '@types/node': 25.5.2 optional: true - '@rushstack/ts-command-line@5.0.2(@types/node@25.5.0)': + '@rushstack/ts-command-line@5.0.2(@types/node@25.5.2)': dependencies: - '@rushstack/terminal': 0.15.4(@types/node@25.5.0) + '@rushstack/terminal': 0.15.4(@types/node@25.5.2) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -9312,22 +9258,22 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.2)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.55.2)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.2)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) obug: 2.1.1 - svelte: 5.48.0 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + svelte: 5.55.2 + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.2)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.48.0)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.2)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.55.2)(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.48.0 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vitefu: 1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + svelte: 5.55.2 + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@swc/core-darwin-arm64@1.15.18': optional: true @@ -9564,7 +9510,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 25.5.0 + '@types/node': 25.5.2 '@types/hast@3.0.4': dependencies: @@ -9590,12 +9536,10 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@25.5.0': + '@types/node@25.5.2': dependencies: undici-types: 7.18.2 - '@types/prismjs@1.26.5': {} - '@types/prismjs@1.26.6': {} '@types/react-dom@19.2.3(@types/react@19.2.14)': @@ -9614,8 +9558,7 @@ snapshots: dependencies: htmlparser2: 10.1.0 - '@types/trusted-types@2.0.7': - optional: true + '@types/trusted-types@2.0.7': {} '@types/unist@2.0.11': {} @@ -9627,20 +9570,20 @@ snapshots: '@types/vfile@3.0.2': dependencies: - '@types/node': 25.5.0 + '@types/node': 25.5.2 '@types/unist': 2.0.11 '@types/vfile-message': 2.0.0 '@types/which@3.0.4': {} - '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.58.1(@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/type-utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/parser': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/type-utils': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.58.1 eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -9649,41 +9592,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.58.1 debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.2(typescript@5.9.3)': + '@typescript-eslint/project-service@8.58.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) - '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/tsconfig-utils': 8.58.1(typescript@5.9.3) + '@typescript-eslint/types': 8.58.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.57.2': + '@typescript-eslint/scope-manager@8.58.1': dependencies: - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/visitor-keys': 8.58.1 - '@typescript-eslint/tsconfig-utils@8.57.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.58.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.5.0(typescript@5.9.3) @@ -9691,37 +9634,37 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.57.2': {} + '@typescript-eslint/types@8.58.1': {} - '@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.58.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.57.2(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/project-service': 8.58.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.58.1(typescript@5.9.3) + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/visitor-keys': 8.58.1 debug: 4.4.3 - minimatch: 10.2.4 + minimatch: 10.2.5 semver: 7.7.4 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.57.2': + '@typescript-eslint/visitor-keys@8.58.1': dependencies: - '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/types': 8.58.1 eslint-visitor-keys: 5.0.1 '@unrs/resolver-binding-android-arm-eabi@1.9.2': @@ -9788,11 +9731,11 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@vitejs/plugin-react-swc@4.3.0(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react-swc@4.3.0(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 '@swc/core': 1.15.18 - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@swc/helpers' @@ -9881,7 +9824,7 @@ snapshots: ansi-styles@6.2.3: {} - antd@6.3.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + antd@6.3.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@ant-design/colors': 8.0.1 '@ant-design/cssinjs': 2.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -9926,7 +9869,7 @@ snapshots: '@rc-component/tree-select': 1.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/trigger': 3.9.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@rc-component/upload': 1.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@rc-component/util': 1.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@rc-component/util': 1.10.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: 2.1.1 dayjs: 1.11.20 react: 19.2.4 @@ -9948,8 +9891,7 @@ snapshots: argparse@2.0.1: {} - aria-query@5.3.1: - optional: true + aria-query@5.3.1: {} aria-query@5.3.2: {} @@ -10128,7 +10070,7 @@ snapshots: dependencies: balanced-match: 4.0.4 - brace-expansion@5.0.4: + brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -10281,19 +10223,18 @@ snapshots: chardet@2.1.1: {} - chevrotain-allstar@0.3.1(chevrotain@11.1.2): + chevrotain-allstar@0.4.1(chevrotain@12.0.0): dependencies: - chevrotain: 11.1.2 - lodash-es: 4.17.23 + chevrotain: 12.0.0 + lodash-es: 4.18.1 - chevrotain@11.1.2: + chevrotain@12.0.0: dependencies: - '@chevrotain/cst-dts-gen': 11.1.2 - '@chevrotain/gast': 11.1.2 - '@chevrotain/regexp-to-ast': 11.1.2 - '@chevrotain/types': 11.1.2 - '@chevrotain/utils': 11.1.2 - lodash-es: 4.17.23 + '@chevrotain/cst-dts-gen': 12.0.0 + '@chevrotain/gast': 12.0.0 + '@chevrotain/regexp-to-ast': 12.0.0 + '@chevrotain/types': 12.0.0 + '@chevrotain/utils': 12.0.0 chokidar@4.0.3: dependencies: @@ -10424,9 +10365,9 @@ snapshots: dependencies: layout-base: 2.0.1 - cosmiconfig-typescript-loader@6.2.0(@types/node@25.5.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.2.0(@types/node@25.5.2)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 25.5.0 + '@types/node': 25.5.2 cosmiconfig: 9.0.1(typescript@5.9.3) jiti: 2.6.1 typescript: 5.9.3 @@ -10478,17 +10419,17 @@ snapshots: dependencies: array-find-index: 1.0.2 - cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.2): dependencies: cose-base: 1.0.3 - cytoscape: 3.33.1 + cytoscape: 3.33.2 - cytoscape-fcose@2.2.0(cytoscape@3.33.1): + cytoscape-fcose@2.2.0(cytoscape@3.33.2): dependencies: cose-base: 2.2.0 - cytoscape: 3.33.1 + cytoscape: 3.33.2 - cytoscape@3.33.1: {} + cytoscape@3.33.2: {} d3-array@2.12.1: dependencies: @@ -10520,7 +10461,7 @@ snapshots: d3-delaunay@6.0.4: dependencies: - delaunator: 5.0.1 + delaunator: 5.1.0 d3-dispatch@3.0.1: {} @@ -10665,7 +10606,7 @@ snapshots: dagre-d3-es@7.0.14: dependencies: d3: 7.9.0 - lodash-es: 4.17.23 + lodash-es: 4.18.1 damerau-levenshtein@1.0.8: {} @@ -10757,9 +10698,9 @@ snapshots: is-descriptor: 1.0.3 isobject: 3.0.1 - delaunator@5.0.1: + delaunator@5.1.0: dependencies: - robust-predicates: 3.0.2 + robust-predicates: 3.0.3 dequal@2.0.3: {} @@ -10771,7 +10712,7 @@ snapshots: detect-newline@4.0.1: {} - devalue@5.6.4: {} + devalue@5.7.0: {} diff@4.0.4: {} @@ -10816,7 +10757,7 @@ snapshots: optionalDependencies: '@types/trusted-types': 2.0.7 - dompurify@3.3.2: + dompurify@3.3.3: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -11271,22 +11212,22 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -11297,7 +11238,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11309,7 +11250,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -11381,11 +11322,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.4(jiti@2.6.1)): + eslint-plugin-simple-import-sort@13.0.0(eslint@9.39.4(jiti@2.6.1)): dependencies: eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-svelte@3.16.0(eslint@9.39.4(jiti@2.6.1))(svelte@5.55.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)): + eslint-plugin-svelte@3.17.0(eslint@9.39.4(jiti@2.6.1))(svelte@5.55.2)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.2)(typescript@5.9.3)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@jridgewell/sourcemap-codec': 1.5.5 @@ -11393,13 +11334,13 @@ snapshots: esutils: 2.0.3 globals: 16.5.0 known-css-properties: 0.37.0 - postcss: 8.5.8 - postcss-load-config: 3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)) - postcss-safe-parser: 7.0.1(postcss@8.5.8) + postcss: 8.5.9 + postcss-load-config: 3.1.4(postcss@8.5.9)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.2)(typescript@5.9.3)) + postcss-safe-parser: 7.0.1(postcss@8.5.9) semver: 7.7.4 - svelte-eslint-parser: 1.6.0(svelte@5.55.0) + svelte-eslint-parser: 1.6.0(svelte@5.55.2) optionalDependencies: - svelte: 5.55.0 + svelte: 5.55.2 transitivePeerDependencies: - ts-node @@ -11479,7 +11420,7 @@ snapshots: esrap@2.2.4: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/types': 8.58.1 esrecurse@4.3.0: dependencies: @@ -11593,6 +11534,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -11984,13 +11929,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - htmlparser2@8.0.2: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - entities: 4.5.0 - human-id@4.1.3: {} husky@9.1.7: {} @@ -12397,7 +12335,7 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 - katex@0.16.43: + katex@0.16.45: dependencies: commander: 8.3.0 @@ -12425,10 +12363,11 @@ snapshots: known-css-properties@0.37.0: {} - langium@4.2.1: + langium@4.2.2: dependencies: - chevrotain: 11.1.2 - chevrotain-allstar: 0.3.1(chevrotain@11.1.2) + '@chevrotain/regexp-to-ast': 12.0.0 + chevrotain: 12.0.0 + chevrotain-allstar: 0.4.1(chevrotain@12.0.0) vscode-languageserver: 9.0.1 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 @@ -12560,7 +12499,7 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash-es@4.17.23: {} + lodash-es@4.18.1: {} lodash.camelcase@4.3.0: {} @@ -12656,31 +12595,20 @@ snapshots: markdown-table@1.1.3: {} - marked-gfm-heading-id@3.2.0(marked@12.0.2): - dependencies: - github-slugger: 2.0.0 - marked: 12.0.2 - - marked-gfm-heading-id@4.1.3(marked@17.0.5): + marked-gfm-heading-id@4.1.4(marked@18.0.0): dependencies: github-slugger: 2.0.0 - marked: 17.0.5 + marked: 18.0.0 - marked-highlight@2.2.3(marked@12.0.2): + marked-highlight@2.2.4(marked@18.0.0): dependencies: - marked: 12.0.2 - - marked-highlight@2.2.3(marked@17.0.5): - dependencies: - marked: 17.0.5 - - marked@12.0.2: {} + marked: 18.0.0 marked@14.0.0: {} marked@16.4.2: {} - marked@17.0.5: {} + marked@18.0.0: {} math-intrinsics@1.1.0: {} @@ -12725,24 +12653,24 @@ snapshots: merge2@1.4.1: {} - mermaid@11.13.0: + mermaid@11.14.0: dependencies: '@braintree/sanitize-url': 7.1.2 '@iconify/utils': 3.1.0 - '@mermaid-js/parser': 1.0.1 + '@mermaid-js/parser': 1.1.0 '@types/d3': 7.4.3 '@upsetjs/venn.js': 2.0.0 - cytoscape: 3.33.1 - cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) - cytoscape-fcose: 2.2.0(cytoscape@3.33.1) + cytoscape: 3.33.2 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.2) + cytoscape-fcose: 2.2.0(cytoscape@3.33.2) d3: 7.9.0 d3-sankey: 0.12.3 dagre-d3-es: 7.0.14 dayjs: 1.11.20 - dompurify: 3.3.2 - katex: 0.16.43 + dompurify: 3.3.3 + katex: 0.16.45 khroma: 2.1.0 - lodash-es: 4.17.23 + lodash-es: 4.18.1 marked: 16.4.2 roughjs: 4.6.6 stylis: 4.3.6 @@ -12786,9 +12714,9 @@ snapshots: dependencies: brace-expansion: 5.0.3 - minimatch@10.2.4: + minimatch@10.2.5: dependencies: - brace-expansion: 5.0.4 + brace-expansion: 5.0.5 minimatch@3.1.2: dependencies: @@ -12827,7 +12755,7 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.1 - mlly@1.8.1: + mlly@1.8.2: dependencies: acorn: 8.16.0 pathe: 2.0.3 @@ -13143,6 +13071,8 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.4: {} + pidtree@0.3.1: {} pify@3.0.0: {} @@ -13168,17 +13098,17 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): + postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39): dependencies: htmlparser2: 3.10.1 postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0)(postcss-jsx@0.36.4)(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) - postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): + postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39): dependencies: '@babel/core': 7.29.0 postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0)(postcss-jsx@0.36.4)(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) transitivePeerDependencies: - supports-color @@ -13186,31 +13116,31 @@ snapshots: dependencies: postcss: 7.0.39 - postcss-less@6.0.0(postcss@8.5.8): + postcss-less@6.0.0(postcss@8.5.9): dependencies: - postcss: 8.5.8 + postcss: 8.5.9 - postcss-load-config@3.1.4(postcss@8.5.8)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3)): + postcss-load-config@3.1.4(postcss@8.5.9)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.2)(typescript@5.9.3)): dependencies: lilconfig: 2.1.0 yaml: 1.10.3 optionalDependencies: - postcss: 8.5.8 - ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3) + postcss: 8.5.9 + ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@25.5.2)(typescript@5.9.3) - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2): + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.6.1 - postcss: 8.5.8 + postcss: 8.5.9 tsx: 4.21.0 yaml: 2.8.2 - postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39): + postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39): dependencies: postcss: 7.0.39 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0)(postcss-jsx@0.36.4)(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) remark: 10.0.1 unist-util-find-all-after: 1.0.5 @@ -13229,9 +13159,9 @@ snapshots: dependencies: postcss: 7.0.39 - postcss-safe-parser@7.0.1(postcss@8.5.8): + postcss-safe-parser@7.0.1(postcss@8.5.9): dependencies: - postcss: 8.5.8 + postcss: 8.5.9 postcss-sass@0.3.5: dependencies: @@ -13242,9 +13172,9 @@ snapshots: dependencies: postcss: 7.0.39 - postcss-scss@4.0.9(postcss@8.5.8): + postcss-scss@4.0.9(postcss@8.5.9): dependencies: - postcss: 8.5.8 + postcss: 8.5.9 postcss-selector-parser@3.1.2: dependencies: @@ -13257,23 +13187,23 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-sorting@10.0.0(postcss@8.5.8): + postcss-sorting@10.0.0(postcss@8.5.9): dependencies: - postcss: 8.5.8 + postcss: 8.5.9 postcss-sorting@4.1.0: dependencies: lodash: 4.17.21 postcss: 7.0.39 - postcss-syntax@0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39): + postcss-syntax@0.36.2(postcss-html@0.36.0)(postcss-jsx@0.36.4)(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39): dependencies: postcss: 7.0.39 optionalDependencies: - postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) - postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) + postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39) + postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39) postcss-less: 3.1.4 - postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) + postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39) postcss-scss: 2.1.1 postcss-value-parser@3.3.1: {} @@ -13285,7 +13215,7 @@ snapshots: picocolors: 0.2.1 source-map: 0.6.1 - postcss@8.5.8: + postcss@8.5.9: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -13307,10 +13237,10 @@ snapshots: optionalDependencies: prettier: 3.8.1 - prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.48.0): + prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.55.2): dependencies: prettier: 3.8.1 - svelte: 5.48.0 + svelte: 5.55.2 prettier@2.8.8: {} @@ -13599,7 +13529,7 @@ snapshots: glob: 13.0.6 package-json-from-dist: 1.0.1 - robust-predicates@3.0.2: {} + robust-predicates@3.0.3: {} rollup@4.53.3: dependencies: @@ -13706,14 +13636,14 @@ snapshots: safer-buffer@2.1.2: {} - sanitize-html@2.17.1: + sanitize-html@2.17.2: dependencies: deepmerge: 4.3.1 escape-string-regexp: 4.0.0 - htmlparser2: 8.0.2 + htmlparser2: 10.1.0 is-plain-object: 5.0.0 parse-srcset: 1.0.2 - postcss: 8.5.8 + postcss: 8.5.9 sass@1.97.3: dependencies: @@ -14113,8 +14043,8 @@ snapshots: stylelint-order@8.1.1(stylelint@17.6.0(typescript@5.9.3)): dependencies: - postcss: 8.5.8 - postcss-sorting: 10.0.0(postcss@8.5.8) + postcss: 8.5.9 + postcss-sorting: 10.0.0(postcss@8.5.9) stylelint: 17.6.0(typescript@5.9.3) stylelint-prettier@5.0.3(prettier@3.8.1)(stylelint@17.6.0(typescript@5.9.3)): @@ -14152,8 +14082,8 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.8 - postcss-safe-parser: 7.0.1(postcss@8.5.8) + postcss: 8.5.9 + postcss-safe-parser: 7.0.1(postcss@8.5.9) postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 string-width: 8.2.0 @@ -14192,10 +14122,10 @@ snapshots: normalize-selector: 0.2.0 pify: 4.0.1 postcss: 7.0.39 - postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) - postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) + postcss-html: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39) + postcss-jsx: 0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39) postcss-less: 3.1.4 - postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39) + postcss-markdown: 0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.9))(postcss@8.5.9))(postcss@7.0.39) postcss-media-query-parser: 0.2.3 postcss-reporter: 6.0.1 postcss-resolve-nested-selector: 0.1.6 @@ -14203,7 +14133,7 @@ snapshots: postcss-sass: 0.3.5 postcss-scss: 2.1.1 postcss-selector-parser: 3.1.2 - postcss-syntax: 0.36.2(postcss-html@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-jsx@0.36.4(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-less@3.1.4)(postcss-markdown@0.36.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.8))(postcss@8.5.8))(postcss@7.0.39))(postcss-scss@2.1.1)(postcss@7.0.39) + postcss-syntax: 0.36.2(postcss-html@0.36.0)(postcss-jsx@0.36.4)(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39) postcss-value-parser: 3.3.1 resolve-from: 4.0.0 signal-exit: 3.0.7 @@ -14243,9 +14173,9 @@ snapshots: dependencies: postcss: 7.0.39 - sugarss@5.0.1(postcss@8.5.8): + sugarss@5.0.1(postcss@8.5.9): dependencies: - postcss: 8.5.8 + postcss: 8.5.9 supports-color@10.2.2: {} @@ -14269,31 +14199,31 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.48.0)(typescript@5.9.3): + svelte-check@4.4.6(picomatch@4.0.4)(svelte@5.55.2)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 - fdir: 6.5.0(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.4) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.48.0 + svelte: 5.55.2 typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.6.0(svelte@5.55.0): + svelte-eslint-parser@1.6.0(svelte@5.55.2): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - postcss: 8.5.8 - postcss-scss: 4.0.9(postcss@8.5.8) + postcss: 8.5.9 + postcss-scss: 4.0.9(postcss@8.5.9) postcss-selector-parser: 7.1.1 semver: 7.7.4 optionalDependencies: - svelte: 5.55.0 + svelte: 5.55.2 - svelte-i18n@4.0.1(svelte@5.48.0): + svelte-i18n@4.0.1(svelte@5.55.2): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -14301,43 +14231,25 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.16 sade: 1.8.1 - svelte: 5.48.0 + svelte: 5.55.2 tiny-glob: 0.2.9 - svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.8)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(svelte@5.48.0)(typescript@5.9.3): + svelte-preprocess@6.0.3(@babel/core@7.29.0)(coffeescript@2.7.0)(less@4.6.4)(postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(yaml@2.8.2))(postcss@8.5.9)(pug@3.0.3)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(svelte@5.55.2)(typescript@5.9.3): dependencies: - svelte: 5.48.0 + svelte: 5.55.2 optionalDependencies: '@babel/core': 7.29.0 coffeescript: 2.7.0 less: 4.6.4 - postcss: 8.5.8 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) + postcss: 8.5.9 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(yaml@2.8.2) pug: 3.0.3 sass: 1.97.3 stylus: 0.64.0 - sugarss: 5.0.1(postcss@8.5.8) + sugarss: 5.0.1(postcss@8.5.9) typescript: 5.9.3 - svelte@5.48.0: - dependencies: - '@jridgewell/remapping': 2.3.5 - '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@types/estree': 1.0.8 - acorn: 8.16.0 - aria-query: 5.3.2 - axobject-query: 4.1.0 - clsx: 2.1.1 - devalue: 5.6.4 - esm-env: 1.2.2 - esrap: 2.2.4 - is-reference: 3.0.3 - locate-character: 3.0.0 - magic-string: 0.30.21 - zimmerframe: 1.1.4 - - svelte@5.55.0: + svelte@5.55.2: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -14348,14 +14260,13 @@ snapshots: aria-query: 5.3.1 axobject-query: 4.1.0 clsx: 2.1.1 - devalue: 5.6.4 + devalue: 5.7.0 esm-env: 1.2.2 esrap: 2.2.4 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.21 zimmerframe: 1.1.4 - optional: true svg-tags@1.0.0: {} @@ -14409,10 +14320,10 @@ snapshots: tinyexec@0.3.2: {} - tinyexec@1.0.2: {} - tinyexec@1.0.4: {} + tinyexec@1.1.1: {} + tinyglobby@0.2.14: dependencies: fdir: 6.4.4(picomatch@4.0.2) @@ -14423,6 +14334,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + to-object-path@0.3.0: dependencies: kind-of: 3.2.2 @@ -14485,14 +14401,14 @@ snapshots: optionalDependencies: '@swc/core': 1.15.18 - ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.0)(typescript@5.9.3): + ts-node@10.9.2(@swc/core@1.15.18)(@types/node@25.5.2)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 25.5.0 + '@types/node': 25.5.2 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -14515,7 +14431,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.5.0))(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): + tsup@8.5.1(@microsoft/api-extractor@7.52.10(@types/node@25.5.2))(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): dependencies: bundle-require: 5.1.0(esbuild@0.27.0) cac: 6.7.14 @@ -14526,7 +14442,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.9)(tsx@4.21.0)(yaml@2.8.2) resolve-from: 5.0.0 rollup: 4.53.3 source-map: 0.7.6 @@ -14535,9 +14451,9 @@ snapshots: tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: - '@microsoft/api-extractor': 7.52.10(@types/node@25.5.0) + '@microsoft/api-extractor': 7.52.10(@types/node@25.5.2) '@swc/core': 1.15.18 - postcss: 8.5.8 + postcss: 8.5.9 typescript: 5.9.3 transitivePeerDependencies: - jiti @@ -14593,12 +14509,12 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.58.1(@typescript-eslint/parser@8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.58.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.58.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -14785,12 +14701,12 @@ snapshots: unist-util-stringify-position: 1.1.2 vfile-message: 1.1.1 - vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - postcss: 8.5.8 + postcss: 8.5.9 rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: @@ -14801,14 +14717,14 @@ snapshots: lightningcss: 1.31.1 sass: 1.97.3 stylus: 0.64.0 - sugarss: 5.0.1(postcss@8.5.8) + sugarss: 5.0.1(postcss@8.5.9) terser: 5.46.0 tsx: 4.21.0 yaml: 2.8.2 - vitefu@1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vitefu@1.1.2(vite@7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): optionalDependencies: - vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@18.19.130)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(sugarss@5.0.1(postcss@8.5.9))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vm2@3.10.4: dependencies: From a962e0a9ade8a83c37cee9c1524ddc889dafb41e Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 8 Apr 2026 14:48:43 +0800 Subject: [PATCH 20/31] fix: property alias --- .../components/antd/config_provider/__init__.py | 2 +- .../modelscope_studio/components/antd/layout/sider/__init__.py | 2 +- backend/modelscope_studio/components/antd/menu/__init__.py | 2 +- backend/modelscope_studio/components/antd/menu/item/__init__.py | 2 +- .../modelscope_studio/components/antdx/x_provider/__init__.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/modelscope_studio/components/antd/config_provider/__init__.py b/backend/modelscope_studio/components/antd/config_provider/__init__.py index 936c3711..4b6bdf82 100644 --- a/backend/modelscope_studio/components/antd/config_provider/__init__.py +++ b/backend/modelscope_studio/components/antd/config_provider/__init__.py @@ -87,7 +87,7 @@ def __init__(self, warnings.warn( """[antd.ConfigProvider]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_config` instead.""" ) - self.theme_config = theme_config + self.theme_config = theme_config or theme self.variant = variant self.virtual = virtual self.warning = warning diff --git a/backend/modelscope_studio/components/antd/layout/sider/__init__.py b/backend/modelscope_studio/components/antd/layout/sider/__init__.py index dd4fb41a..838db015 100644 --- a/backend/modelscope_studio/components/antd/layout/sider/__init__.py +++ b/backend/modelscope_studio/components/antd/layout/sider/__init__.py @@ -102,7 +102,7 @@ def __init__( warnings.warn( """[antd.Layout.Sider]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_value` instead.""" ) - self.theme_value = theme_value + self.theme_value = theme_value or theme self.trigger = trigger self.width = width self.zero_width_trigger_style = zero_width_trigger_style diff --git a/backend/modelscope_studio/components/antd/menu/__init__.py b/backend/modelscope_studio/components/antd/menu/__init__.py index dfc639ad..f8729c6f 100644 --- a/backend/modelscope_studio/components/antd/menu/__init__.py +++ b/backend/modelscope_studio/components/antd/menu/__init__.py @@ -98,7 +98,7 @@ def __init__( warnings.warn( """[antd.Menu.Item]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_value` instead.""" ) - self.theme_value = theme_value + self.theme_value = theme_value or theme self.trigger_sub_menu_action = trigger_sub_menu_action self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/menu/item/__init__.py b/backend/modelscope_studio/components/antd/menu/item/__init__.py index 2af492fd..6cb4e9af 100644 --- a/backend/modelscope_studio/components/antd/menu/item/__init__.py +++ b/backend/modelscope_studio/components/antd/menu/item/__init__.py @@ -66,7 +66,7 @@ def __init__( warnings.warn( """[antd.Menu.Item]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_value` instead.""" ) - self.theme_value = theme_value + self.theme_value = theme_value or theme self.type = type self.popup_class_name = popup_class_name self.popup_offset = popup_offset diff --git a/backend/modelscope_studio/components/antdx/x_provider/__init__.py b/backend/modelscope_studio/components/antdx/x_provider/__init__.py index c7518c48..9068c726 100644 --- a/backend/modelscope_studio/components/antdx/x_provider/__init__.py +++ b/backend/modelscope_studio/components/antdx/x_provider/__init__.py @@ -75,7 +75,7 @@ def __init__(self, warnings.warn( """[antdx.XProvider]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_config` instead.""" ) - self.theme_config = theme_config + self.theme_config = theme_config or theme self.variant = variant self.virtual = virtual self.warning = warning From bb4001ac2092d4c5d1a54cfc29ecde4856ca6539 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Fri, 10 Apr 2026 18:32:21 +0800 Subject: [PATCH 21/31] fix: antdx docs --- .gitignore | 2 + .../components/antd/__init__.py | 2 + .../components/antd/components.py | 2 + .../components/antd/masonry/__init__.py | 82 +++++++++++++ .../components/antd/masonry/item/__init__.py | 64 ++++++++++ docs/app.py | 28 ++++- .../antd/config_provider/demos/basic.py | 4 +- docs/components/antd/masonry/README-zh_CN.md | 9 ++ docs/components/antd/masonry/README.md | 9 ++ docs/components/antd/masonry/app.py | 6 + docs/components/antd/masonry/demos/basic.py | 36 ++++++ docs/components/antd/masonry/demos/columns.py | 49 ++++++++ .../antd/masonry/demos/responsive.py | 40 +++++++ .../antdx/attachments/README-zh_CN.md | 1 - docs/components/antdx/attachments/README.md | 1 - .../antdx/attachments/demos/file_card.py | 71 ----------- docs/components/antdx/bubble/demos/basic.py | 36 +++--- .../antdx/bubble/demos/bubble_list.py | 23 ++-- docs/components/antdx/bubble/demos/chatbot.py | 14 +-- .../antdx/bubble/demos/custom_list_content.py | 38 +++--- .../antdx/bubble/demos/typing_effect.py | 15 ++- docs/components/antdx/bubble/demos/variant.py | 25 ++-- .../antdx/code_highlighter/README-zh_CN.md | 7 ++ .../antdx/code_highlighter/README.md | 7 ++ docs/components/antdx/code_highlighter/app.py | 6 + .../antdx/code_highlighter/demos/basic.py | 75 ++++++++++++ .../antdx/file_card/README-zh_CN.md | 7 ++ docs/components/antdx/file_card/README.md | 7 ++ docs/components/antdx/file_card/app.py | 6 + .../components/antdx/file_card/demos/basic.py | 96 +++++++++++++++ docs/components/antdx/folder/README-zh_CN.md | 7 ++ docs/components/antdx/folder/README.md | 7 ++ docs/components/antdx/folder/app.py | 6 + docs/components/antdx/folder/demos/basic.py | 110 ++++++++++++++++++ docs/components/antdx/mermaid/README-zh_CN.md | 7 ++ docs/components/antdx/mermaid/README.md | 7 ++ docs/components/antdx/mermaid/app.py | 6 + docs/components/antdx/mermaid/demos/basic.py | 14 +++ .../antdx/notification/README-zh_CN.md | 7 ++ docs/components/antdx/notification/README.md | 7 ++ docs/components/antdx/notification/app.py | 6 + .../antdx/notification/demos/basic.py | 23 ++++ .../antdx/prompts/demos/nest_usage.py | 2 +- docs/components/antdx/sources/README-zh_CN.md | 7 ++ docs/components/antdx/sources/README.md | 7 ++ docs/components/antdx/sources/app.py | 6 + docs/components/antdx/sources/demos/basic.py | 64 ++++++++++ docs/components/antdx/think/README-zh_CN.md | 7 ++ docs/components/antdx/think/README.md | 7 ++ docs/components/antdx/think/app.py | 6 + docs/components/antdx/think/demos/basic.py | 42 +++++++ .../antdx/thought_chain/demos/basic.py | 18 +-- .../antdx/thought_chain/demos/item_status.py | 14 +-- .../antdx/thought_chain/demos/nested_use.py | 14 +-- docs/helper/Site.py | 15 ++- docs/layout_templates/chatbot/demos/basic.py | 7 +- .../layout_templates/chatbot/demos/copilot.py | 4 +- .../chatbot/demos/fine_grained_control.py | 41 ++++--- .../coder_artifacts/demos/app.py | 8 +- frontend/antd/masonry/Index.svelte | 63 ++++++++++ frontend/antd/masonry/context.ts | 6 + frontend/antd/masonry/gradio.config.js | 3 + frontend/antd/masonry/item/Index.svelte | 80 +++++++++++++ frontend/antd/masonry/item/gradio.config.js | 3 + frontend/antd/masonry/item/masonry.item.tsx | 15 +++ frontend/antd/masonry/item/package.json | 14 +++ frontend/antd/masonry/masonry.tsx | 51 ++++++++ frontend/antd/masonry/package.json | 14 +++ frontend/antdx/bubble/bubble.tsx | 1 + frontend/antdx/bubble/list/bubble.list.tsx | 1 + frontend/antdx/bubble/list/item/Item.svelte | 2 +- frontend/antdx/bubble/list/role/Role.svelte | 2 +- frontend/antdx/bubble/list/utils.tsx | 55 +++------ frontend/antdx/folder/Index.svelte | 4 +- frontend/antdx/folder/folder.tsx | 3 +- frontend/antdx/notification/notification.tsx | 13 ++- frontend/antdx/sources/sources.tsx | 3 +- frontend/antdx/welcome/welcome.tsx | 9 +- frontend/base/auto-loading/auto-loading.less | 20 ++-- frontend/base/auto-loading/auto-loading.tsx | 2 +- frontend/base/each/EachItem.svelte | 5 +- frontend/base/each/Index.svelte | 3 +- frontend/base/each/each.tsx | 1 + frontend/base/fragment/Index.svelte | 4 +- frontend/base/slot/Index.svelte | 3 +- frontend/pro/chatbot/chatbot.tsx | 37 +++--- .../component/props.svelte.ts | 50 ++++++-- pyproject.toml | 2 + 88 files changed, 1409 insertions(+), 304 deletions(-) create mode 100644 backend/modelscope_studio/components/antd/masonry/__init__.py create mode 100644 backend/modelscope_studio/components/antd/masonry/item/__init__.py create mode 100644 docs/components/antd/masonry/README-zh_CN.md create mode 100644 docs/components/antd/masonry/README.md create mode 100644 docs/components/antd/masonry/app.py create mode 100644 docs/components/antd/masonry/demos/basic.py create mode 100644 docs/components/antd/masonry/demos/columns.py create mode 100644 docs/components/antd/masonry/demos/responsive.py delete mode 100644 docs/components/antdx/attachments/demos/file_card.py create mode 100644 docs/components/antdx/code_highlighter/README-zh_CN.md create mode 100644 docs/components/antdx/code_highlighter/README.md create mode 100644 docs/components/antdx/code_highlighter/app.py create mode 100644 docs/components/antdx/code_highlighter/demos/basic.py create mode 100644 docs/components/antdx/file_card/README-zh_CN.md create mode 100644 docs/components/antdx/file_card/README.md create mode 100644 docs/components/antdx/file_card/app.py create mode 100644 docs/components/antdx/file_card/demos/basic.py create mode 100644 docs/components/antdx/folder/README-zh_CN.md create mode 100644 docs/components/antdx/folder/README.md create mode 100644 docs/components/antdx/folder/app.py create mode 100644 docs/components/antdx/folder/demos/basic.py create mode 100644 docs/components/antdx/mermaid/README-zh_CN.md create mode 100644 docs/components/antdx/mermaid/README.md create mode 100644 docs/components/antdx/mermaid/app.py create mode 100644 docs/components/antdx/mermaid/demos/basic.py create mode 100644 docs/components/antdx/notification/README-zh_CN.md create mode 100644 docs/components/antdx/notification/README.md create mode 100644 docs/components/antdx/notification/app.py create mode 100644 docs/components/antdx/notification/demos/basic.py create mode 100644 docs/components/antdx/sources/README-zh_CN.md create mode 100644 docs/components/antdx/sources/README.md create mode 100644 docs/components/antdx/sources/app.py create mode 100644 docs/components/antdx/sources/demos/basic.py create mode 100644 docs/components/antdx/think/README-zh_CN.md create mode 100644 docs/components/antdx/think/README.md create mode 100644 docs/components/antdx/think/app.py create mode 100644 docs/components/antdx/think/demos/basic.py create mode 100644 frontend/antd/masonry/Index.svelte create mode 100644 frontend/antd/masonry/context.ts create mode 100644 frontend/antd/masonry/gradio.config.js create mode 100644 frontend/antd/masonry/item/Index.svelte create mode 100644 frontend/antd/masonry/item/gradio.config.js create mode 100644 frontend/antd/masonry/item/masonry.item.tsx create mode 100644 frontend/antd/masonry/item/package.json create mode 100644 frontend/antd/masonry/masonry.tsx create mode 100644 frontend/antd/masonry/package.json diff --git a/.gitignore b/.gitignore index 21b86773..b8470bf2 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,5 @@ yalc.lock .stylelintcache .DS_Store .pytest_cache + +.qoder diff --git a/backend/modelscope_studio/components/antd/__init__.py b/backend/modelscope_studio/components/antd/__init__.py index 89ac0cd6..70b72749 100644 --- a/backend/modelscope_studio/components/antd/__init__.py +++ b/backend/modelscope_studio/components/antd/__init__.py @@ -72,6 +72,8 @@ from .list.item.meta import AntdListItemMeta as ListItemMeta from .mentions import AntdMentions as Mentions from .mentions.option import AntdMentionsOption as MentionsOption +from .masonry import AntdMasonry as Masonry +from .masonry.item import AntdMasonryItem as MasonryItem from .menu import AntdMenu as Menu from .menu.item import AntdMenuItem as MenuItem from .message import AntdMessage as Message diff --git a/backend/modelscope_studio/components/antd/components.py b/backend/modelscope_studio/components/antd/components.py index 33414c9e..424f11b3 100644 --- a/backend/modelscope_studio/components/antd/components.py +++ b/backend/modelscope_studio/components/antd/components.py @@ -67,6 +67,8 @@ from .list import AntdList from .list.item import AntdListItem from .list.item.meta import AntdListItemMeta +from .masonry import AntdMasonry +from .masonry.item import AntdMasonryItem from .mentions import AntdMentions from .mentions.option import AntdMentionsOption from .menu import AntdMenu diff --git a/backend/modelscope_studio/components/antd/masonry/__init__.py b/backend/modelscope_studio/components/antd/masonry/__init__.py new file mode 100644 index 00000000..8ec8ae22 --- /dev/null +++ b/backend/modelscope_studio/components/antd/masonry/__init__.py @@ -0,0 +1,82 @@ +from __future__ import annotations + +from typing import Any +from gradio.events import EventListener + +from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir +from .item import AntdMasonryItem + + +class AntdMasonry(ModelScopeLayoutComponent): + """ + Ant Design: https://ant.design/components/masonry + + A masonry layout component for displaying content with different heights. + + When to use: + - When displaying images or cards with irregular heights + - When content needs to be evenly distributed in columns + - When column count needs to be responsive + """ + Item = AntdMasonryItem + + EVENTS = [ + EventListener("layout_change", + callback=lambda block: block._internal.update( + bind_layoutChange_event=True)), + ] + SLOTS = ['items', 'itemRender'] + + def __init__( + self, + additional_props: dict | None = None, + *, + columns: int | dict | None = None, + gutter: int | tuple[int | dict, int | dict] | dict | None = None, + fresh: bool | None = None, + items: list[dict] | None = None, + item_render: str | None = None, + class_names: dict | None = None, + styles: dict | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.columns = columns + self.gutter = gutter + self.fresh = fresh + self.items = items + self.item_render = item_render + self.class_names = class_names + self.styles = styles + + FRONTEND_DIR = resolve_frontend_dir("masonry") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/backend/modelscope_studio/components/antd/masonry/item/__init__.py b/backend/modelscope_studio/components/antd/masonry/item/__init__.py new file mode 100644 index 00000000..c94311f7 --- /dev/null +++ b/backend/modelscope_studio/components/antd/masonry/item/__init__.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +from typing import Any + +from .....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdMasonryItem(ModelScopeLayoutComponent): + """ + Ant Design: https://ant.design/components/masonry + """ + + EVENTS = [] + + # supported slots + SLOTS = [] + + def __init__( + self, + key: str | float | int | None = None, + *, + column: int | None = None, + data: Any | None = None, + height: int | float | None = None, + additional_props: dict | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.key = key + self.column = column + self.data = data + self.height = height + + FRONTEND_DIR = resolve_frontend_dir("masonry", "item") + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/docs/app.py b/docs/app.py index 9af292be..68fa1e0f 100644 --- a/docs/app.py +++ b/docs/app.py @@ -224,6 +224,9 @@ def render(self): }, { "label": get_text("Layout", "Layout 布局"), "key": "layout" + }, { + "label": get_text("Masonry", "Masonry 瀑布流"), + "key": "masonry" }, { "label": get_text("Space", "Space 间距"), "key": "space" @@ -451,6 +454,9 @@ def render(self): }, { "label": get_text("Conversations", "Conversations 管理对话"), "key": "conversations" + }, { + "label": get_text("Notification", "Notification 系统通知"), + "key": "notification" }] }, { "label": @@ -485,6 +491,9 @@ def render(self): "type": "group", "children": [{ + "label": get_text("Think", "Think 思考过程"), + "key": "think" + }, { "label": get_text("ThoughtChain", "ThoughtChain 思考链"), "key": "thought_chain" }] @@ -496,6 +505,21 @@ def render(self): "children": [{ "label": get_text("Actions", "Actions 操作列表"), "key": "actions" + }, { + "label": get_text("CodeHighlighter", "CodeHighlighter 代码高亮"), + "key": "code_highlighter" + }, { + "label": get_text("FileCard", "FileCard 文件卡片"), + "key": "file_card" + }, { + "label": get_text("Folder", "Folder 文件夹"), + "key": "folder" + }, { + "label": get_text("Mermaid", "Mermaid 图表工具"), + "key": "mermaid" + }, { + "label": get_text("Sources", "Sources 来源引用"), + "key": "sources" }] }, { "label": @@ -587,8 +611,8 @@ def more_components(): default_active_tab=default_active_tab, logo=logo) -demo = site.render() +demo, css = site.render() if __name__ == "__main__": demo.queue(default_concurrency_limit=100, - max_size=100).launch(ssr_mode=False, max_threads=100) + max_size=100).launch(css=css, ssr_mode=False, max_threads=100) diff --git a/docs/components/antd/config_provider/demos/basic.py b/docs/components/antd/config_provider/demos/basic.py index 58b16056..7989f9a7 100644 --- a/docs/components/antd/config_provider/demos/basic.py +++ b/docs/components/antd/config_provider/demos/basic.py @@ -10,7 +10,7 @@ with antd.ConfigProvider( locale=default_locale, direction=default_direction, - theme=dict(token=dict( + theme_config=dict(token=dict( colorPrimary=default_color))) as config_provider: with antd.Card(): with ms.Div(elem_style=dict(marginBottom=16)): @@ -61,7 +61,7 @@ outputs=[config_provider]) gr.on( [theme.change, color.change], - fn=lambda _theme, _color: gr.update(theme=dict( + fn=lambda _theme, _color: gr.update(theme_config=dict( token=dict(colorPrimary=_color) if _color else None, algorithm=dict(dark=True if _theme and 'dark' in _theme else False, diff --git a/docs/components/antd/masonry/README-zh_CN.md b/docs/components/antd/masonry/README-zh_CN.md new file mode 100644 index 00000000..b296ce79 --- /dev/null +++ b/docs/components/antd/masonry/README-zh_CN.md @@ -0,0 +1,9 @@ +# Masonry + +A masonry/waterfall layout component for displaying content with different heights. See [Ant Design](https://ant.design/components/masonry/) for more information. + +## Examples + + + + diff --git a/docs/components/antd/masonry/README.md b/docs/components/antd/masonry/README.md new file mode 100644 index 00000000..b296ce79 --- /dev/null +++ b/docs/components/antd/masonry/README.md @@ -0,0 +1,9 @@ +# Masonry + +A masonry/waterfall layout component for displaying content with different heights. See [Ant Design](https://ant.design/components/masonry/) for more information. + +## Examples + + + + diff --git a/docs/components/antd/masonry/app.py b/docs/components/antd/masonry/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antd/masonry/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antd/masonry/demos/basic.py b/docs/components/antd/masonry/demos/basic.py new file mode 100644 index 00000000..090062e6 --- /dev/null +++ b/docs/components/antd/masonry/demos/basic.py @@ -0,0 +1,36 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.base as ms + +card_contents = [ + ("Nature", "The natural world is full of wonder and beauty.", 120), + ("Technology", "Modern technology shapes how we live and work every day.", + 100), + ("Travel", + "Exploring new destinations broadens the mind and enriches the soul.", + 140), + ("Food", "Culinary traditions reflect the culture and history of a place.", + 80), + ("Science", + "Scientific discoveries have transformed our understanding of the universe.", + 160), + ("Art", + "Artistic expression takes countless forms across different cultures and eras.", + 110), +] + +with gr.Blocks() as demo: + with ms.Application(): + with antd.ConfigProvider(): + with antd.Masonry(columns=3, gutter=16): + for title, content, height in card_contents: + with antd.Masonry.Item(): + with antd.Card(title=title, + elem_style=dict(marginBottom=0)): + ms.Div(content, + elem_style=dict(height=height, + display='flex', + alignItems='center')) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antd/masonry/demos/columns.py b/docs/components/antd/masonry/demos/columns.py new file mode 100644 index 00000000..b3a4cd97 --- /dev/null +++ b/docs/components/antd/masonry/demos/columns.py @@ -0,0 +1,49 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.base as ms + +card_contents = [ + ("Card 1", 120), + ("Card 2", 80), + ("Card 3", 160), + ("Card 4", 100), + ("Card 5", 140), + ("Card 6", 90), + ("Card 7", 110), + ("Card 8", 130), +] + +default_columns = 3 + +with gr.Blocks() as demo: + with ms.Application(): + with antd.ConfigProvider(): + with antd.Flex(gap="middle", vertical=True): + ms.Div("Select number of columns:") + columns_segmented = antd.Segmented(default_columns, + options=[ + dict(label="1 Column", + value=1), + dict(label="2 Columns", + value=2), + dict(label="3 Columns", + value=3), + dict(label="4 Columns", + value=4), + ]) + with antd.Masonry(columns=default_columns, + gutter=16) as masonry: + for title, height in card_contents: + with antd.Masonry.Item(): + with antd.Card(title=title, + elem_style=dict(marginBottom=0)): + ms.Div(elem_style=dict(height=height, + background='#f0f5ff', + borderRadius=4)) + columns_segmented.change( + fn=lambda _columns: gr.update(columns=_columns), + inputs=[columns_segmented], + outputs=[masonry]) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antd/masonry/demos/responsive.py b/docs/components/antd/masonry/demos/responsive.py new file mode 100644 index 00000000..d6acb86a --- /dev/null +++ b/docs/components/antd/masonry/demos/responsive.py @@ -0,0 +1,40 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.base as ms + +items = [ + dict(color='#1677ff', height=150, label='Item A'), + dict(color='#52c41a', height=80, label='Item B'), + dict(color='#fa8c16', height=200, label='Item C'), + dict(color='#722ed1', height=120, label='Item D'), + dict(color='#eb2f96', height=100, label='Item E'), + dict(color='#13c2c2', height=180, label='Item F'), + dict(color='#faad14', height=90, label='Item G'), + dict(color='#f5222d', height=160, label='Item H'), + dict(color='#1677ff', height=110, label='Item I'), + dict(color='#52c41a', height=140, label='Item J'), + dict(color='#fa8c16', height=70, label='Item K'), + dict(color='#722ed1', height=190, label='Item L'), +] + +with gr.Blocks() as demo: + with ms.Application(): + with antd.ConfigProvider(): + with antd.Masonry(columns=4, gutter=12): + for item in items: + with antd.Masonry.Item(): + ms.Div(item['label'], + elem_style=dict( + height=item['height'], + background=item['color'], + borderRadius=8, + display='flex', + alignItems='center', + justifyContent='center', + color='#fff', + fontSize=16, + fontWeight='bold', + )) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/attachments/README-zh_CN.md b/docs/components/antdx/attachments/README-zh_CN.md index 75f87891..6e9888ce 100644 --- a/docs/components/antdx/attachments/README-zh_CN.md +++ b/docs/components/antdx/attachments/README-zh_CN.md @@ -6,4 +6,3 @@ Display the collection of attachment information. See [Ant Design X](https://x.a - diff --git a/docs/components/antdx/attachments/README.md b/docs/components/antdx/attachments/README.md index 75f87891..6e9888ce 100644 --- a/docs/components/antdx/attachments/README.md +++ b/docs/components/antdx/attachments/README.md @@ -6,4 +6,3 @@ Display the collection of attachment information. See [Ant Design X](https://x.a - diff --git a/docs/components/antdx/attachments/demos/file_card.py b/docs/components/antdx/attachments/demos/file_card.py deleted file mode 100644 index a5c69790..00000000 --- a/docs/components/antdx/attachments/demos/file_card.py +++ /dev/null @@ -1,71 +0,0 @@ -import gradio as gr -import modelscope_studio.components.antd as antd -import modelscope_studio.components.antdx as antdx -import modelscope_studio.components.base as ms - -file_list = [ - { - "uid": '1', - "name": 'excel-file.xlsx', - "size": 111111, - }, - { - "uid": '2', - "name": 'word-file.docx', - "size": 222222, - }, - { - "uid": '3', - "name": 'image-file.png', - "size": 333333, - }, - { - "uid": '4', - "name": 'pdf-file.pdf', - "size": 444444, - }, - { - "uid": '5', - "name": 'ppt-file.pptx', - "size": 555555, - }, - { - "uid": '6', - "name": 'video-file.mp4', - "size": 666666, - }, - { - "uid": '7', - "name": 'audio-file.mp3', - "size": 777777, - }, - { - "uid": '8', - "name": 'zip-file.zip', - "size": 888888, - }, - { - "uid": '9', - "name": 'markdown-file.md', - "size": 999999, - "description": 'Custom description here', - }, - { - "uid": '10', - "name": 'image-file.png', - "thumbUrl": - 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', - "url": - 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', - "size": 123456, - }, -] -with gr.Blocks() as demo: - with ms.Application(): - with antdx.XProvider(): - with antd.Flex(vertical=True, gap="middle"): - for file in file_list: - antdx.Attachments.FileCard(item=file) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/docs/components/antdx/bubble/demos/basic.py b/docs/components/antdx/bubble/demos/basic.py index 31763fda..205d0edc 100644 --- a/docs/components/antdx/bubble/demos/basic.py +++ b/docs/components/antdx/bubble/demos/basic.py @@ -31,28 +31,32 @@ with antd.Avatar(elem_style=fooAvatar): with ms.Slot("icon"): antd.Icon("UserOutlined") - antdx.Bubble(placement="start", - content="What a beautiful day!", - avatar=dict(), - styles={"avatar": hideAvatar}) + with antdx.Bubble(placement="start", + content="What a beautiful day!", + styles={"avatar": hideAvatar}): + with ms.Slot("avatar"): + antd.Avatar() with antdx.Bubble(placement="end", content="Hi, good morning, I'm fine!"): with ms.Slot("avatar"): with antd.Avatar(elem_style=barAvatar): with ms.Slot("icon"): antd.Icon("UserOutlined") - antdx.Bubble(placement="end", - content="Thank you!", - avatar=dict(), - styles={"avatar": hideAvatar}) + with antdx.Bubble(placement="end", + content="Thank you!", + styles={"avatar": hideAvatar}): + with ms.Slot("avatar"): + antd.Avatar() antd.Divider("Header and footer") with antdx.Bubble( "Hello, welcome to use Ant Design X! Just ask if you have any questions.", header="Ant Design X"): - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") with ms.Slot("footer"): with antd.Space(size="small"): with antd.Button(value=None, @@ -73,16 +77,20 @@ ms.Span("Loading State") loading_switch = antd.Switch(value=False) with antdx.Bubble("hello world !") as loading_bubble: - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") loading_switch.change(fn=lambda x: gr.update(loading=x), inputs=[loading_switch], outputs=[loading_bubble]) antd.Divider("Markdown") with antdx.Bubble(): - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") with ms.Slot("content"): ms.Markdown("Hello `Markdown`!") diff --git a/docs/components/antdx/bubble/demos/bubble_list.py b/docs/components/antdx/bubble/demos/bubble_list.py index 041bb903..56225808 100644 --- a/docs/components/antdx/bubble/demos/bubble_list.py +++ b/docs/components/antdx/bubble/demos/bubble_list.py @@ -1,3 +1,4 @@ +import time import gradio as gr import modelscope_studio.components.antd as antd import modelscope_studio.components.antdx as antdx @@ -14,6 +15,7 @@ def get_bubble_items(count): "content": content, "key": i - 1 }) + time.sleep(2) return result @@ -27,7 +29,7 @@ def add_bubble(state_value): with ms.Application(): state = gr.State({"history_count": 3}) - with antdx.XProvider(): + with antdx.XProvider(), ms.AutoLoading(): antd.Typography.Paragraph( "Preset Bubble list. Support auto scroll. Use role to set default properties of Bubble." ) @@ -35,10 +37,10 @@ def add_bubble(state_value): with antd.Flex(gap="small", elem_style=dict(alignSelf="flex-end")): add_bubble_btn = antd.Button("Add Bubble") - scroll_btn = antd.Button("Scroll To First") - with antdx.Bubble.List(items=get_bubble_items(3), - elem_style=dict(maxHeight=300), - elem_id="bubble-list") as bubble_list: + with antdx.Bubble.List( + items=get_bubble_items(3), + elem_style={"height": 300}, + class_names=dict(scroll="bubble-list")) as bubble_list: # Define Role with ms.Slot("role"): with antdx.Bubble.List.Role( @@ -51,9 +53,9 @@ def add_bubble(state_value): backgroundColor="#fde3cf")): with ms.Slot("icon"): antd.Icon("UserOutlined") - # use messageRender to render markdown content + # use contentRender to render markdown content with ms.Slot( - "messageRender", + "contentRender", params_mapping="""content => content"""): ms.Markdown() @@ -67,17 +69,12 @@ def add_bubble(state_value): with ms.Slot("icon"): antd.Icon("UserOutlined") with ms.Slot( - "messageRender", + "contentRender", params_mapping="(content) => content"): ms.Markdown() add_bubble_btn.click(fn=add_bubble, inputs=[state], outputs=[state, bubble_list]) - scroll_btn.click(fn=None, - js="""() => { - const bubbleList = document.getElementById("bubble-list"); - bubbleList.scrollTo({ top:0, behavior:'smooth' }); -}""") if __name__ == "__main__": demo.queue().launch() diff --git a/docs/components/antdx/bubble/demos/chatbot.py b/docs/components/antdx/bubble/demos/chatbot.py index b01128e5..a5a27136 100644 --- a/docs/components/antdx/bubble/demos/chatbot.py +++ b/docs/components/antdx/bubble/demos/chatbot.py @@ -64,9 +64,8 @@ def dislike(state_value, e: gr.EventData): with antd.Flex(gap="small", elem_style=dict(alignSelf="flex-end")): add_bubble_btn = antd.Button("Add Bubble") - scroll_btn = antd.Button("Scroll To First") with antdx.Bubble.List(items=default_history, - elem_style=dict(maxHeight=500), + elem_style=dict(height=500), elem_id="chatbot") as bubble_list: # Define Role with ms.Slot("role"): @@ -81,9 +80,9 @@ def dislike(state_value, e: gr.EventData): backgroundColor="#fde3cf")): with ms.Slot("icon"): antd.Icon("UserOutlined") - # use messageRender to render markdown content + # use contentRender to render markdown content with ms.Slot( - "messageRender", + "contentRender", params_mapping="""content => content"""): ms.Markdown() @@ -149,17 +148,12 @@ def dislike(state_value, e: gr.EventData): with ms.Slot("icon"): antd.Icon("UserOutlined") with ms.Slot( - "messageRender", + "contentRender", params_mapping="(content) => content"): ms.Markdown() add_bubble_btn.click(fn=add_bubble, inputs=[state], outputs=[state, bubble_list]) - scroll_btn.click(fn=None, - js="""() => { - const bubbleList = document.getElementById("chatbot"); - bubbleList.scrollTo({ top:0, behavior:'smooth' }); -}""") if __name__ == "__main__": demo.queue().launch() diff --git a/docs/components/antdx/bubble/demos/custom_list_content.py b/docs/components/antdx/bubble/demos/custom_list_content.py index f458f129..84e180f2 100644 --- a/docs/components/antdx/bubble/demos/custom_list_content.py +++ b/docs/components/antdx/bubble/demos/custom_list_content.py @@ -45,16 +45,14 @@ "content": [ { "uid": '1', - "name": 'excel-file.xlsx', - "size": 111111, + "filename": 'excel-file.xlsx', + "byte": 111111, "description": 'Checking the data', }, { "uid": '2', - "name": 'word-file.docx', - "size": 222222, - "status": 'uploading', - "percent": 23, + "filename": 'word-file.docx', + "byte": 222222 }, ], }, @@ -77,7 +75,7 @@ backgroundColor="#fde3cf")): with ms.Slot("icon"): antd.Icon("UserOutlined") - with ms.Slot("messageRender", + with ms.Slot("contentRender", params_mapping="(content) => content"): ms.Markdown() with antdx.Bubble.List.Role(role="ai-error-message", @@ -87,32 +85,28 @@ backgroundColor="#fde3cf")): with ms.Slot("icon"): antd.Icon("UserOutlined") - with ms.Slot("messageRender", + with ms.Slot("contentRender", params_mapping="(content) => content"): antd.Typography.Text(type="danger") - with antdx.Bubble.List.Role( - role="ai-suggestion", - placement="start", - variant="borderless", - avatar=dict(style=dict(visibility='hidden'))): - with ms.Slot("messageRender", + with antdx.Bubble.List.Role(role="ai-suggestion", + placement="start", + variant="borderless"): + with ms.Slot("contentRender", params_mapping="(items) => ({ items })"): prompts = antdx.Prompts(vertical=True) - with antdx.Bubble.List.Role( - role="ai-file", - placement="start", - variant="borderless", - avatar=dict(style=dict(visibility='hidden'))): - with ms.Slot("messageRender", + with antdx.Bubble.List.Role(role="ai-file", + placement="start", + variant="borderless"): + with ms.Slot("contentRender", params_mapping="""(content) => { return { - each: content?.map(item => ({ item })) + each: content } }"""): with antd.Flex(vertical=True, gap="middle"): with ms.Each(as_item="each"): - antdx.Attachments.FileCard() + antdx.FileCard() if __name__ == "__main__": demo.queue().launch() diff --git a/docs/components/antdx/bubble/demos/typing_effect.py b/docs/components/antdx/bubble/demos/typing_effect.py index 63e5ef4a..15d27808 100644 --- a/docs/components/antdx/bubble/demos/typing_effect.py +++ b/docs/components/antdx/bubble/demos/typing_effect.py @@ -28,13 +28,16 @@ def repeat(state_value): with antd.Flex(vertical=True, gap="small"): with antdx.Bubble(content=text, typing=dict(step=2, interval=50)) as bubble1: - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") with antdx.Bubble(content=text, - typing=dict(step=2, interval=50, - suffix="💗")) as bubble2: - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + typing=dict(step=2, interval=50)) as bubble2: + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") btn = antd.Button("Repeat 1 Times", elem_style=dict(alignSelf="flex-end")) btn.click(fn=repeat, diff --git a/docs/components/antdx/bubble/demos/variant.py b/docs/components/antdx/bubble/demos/variant.py index 6b5ff50e..e4ed890c 100644 --- a/docs/components/antdx/bubble/demos/variant.py +++ b/docs/components/antdx/bubble/demos/variant.py @@ -11,18 +11,27 @@ ) with antd.Flex(vertical=True, gap="middle"): with antdx.Bubble(variant="filled", content="variant: filled"): - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") with antdx.Bubble(variant="outlined", content="variant: outlined"): - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") with antdx.Bubble(variant="shadow", content="variant: shadow"): - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") with antdx.Bubble(variant="borderless"): - with ms.Slot("avatar.icon"): - antd.Icon("UserOutlined") + with ms.Slot("avatar"): + with antd.Avatar(): + with ms.Slot("icon"): + antd.Icon("UserOutlined") with ms.Slot("content"): with antdx.Prompts( vertical=True, diff --git a/docs/components/antdx/code_highlighter/README-zh_CN.md b/docs/components/antdx/code_highlighter/README-zh_CN.md new file mode 100644 index 00000000..b6a6cacb --- /dev/null +++ b/docs/components/antdx/code_highlighter/README-zh_CN.md @@ -0,0 +1,7 @@ +# CodeHighlighter + +A component for syntax highlighting of code blocks. See [Ant Design X](https://x.ant.design/components/code-highlighter/) for more information. + +## Examples + + diff --git a/docs/components/antdx/code_highlighter/README.md b/docs/components/antdx/code_highlighter/README.md new file mode 100644 index 00000000..b6a6cacb --- /dev/null +++ b/docs/components/antdx/code_highlighter/README.md @@ -0,0 +1,7 @@ +# CodeHighlighter + +A component for syntax highlighting of code blocks. See [Ant Design X](https://x.ant.design/components/code-highlighter/) for more information. + +## Examples + + diff --git a/docs/components/antdx/code_highlighter/app.py b/docs/components/antdx/code_highlighter/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antdx/code_highlighter/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antdx/code_highlighter/demos/basic.py b/docs/components/antdx/code_highlighter/demos/basic.py new file mode 100644 index 00000000..ded31c28 --- /dev/null +++ b/docs/components/antdx/code_highlighter/demos/basic.py @@ -0,0 +1,75 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + +python_code = """import gradio as gr +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + antdx.CodeHighlighter( + value="print('Hello, World!')", + lang="python", + header=True + ) + +if __name__ == "__main__": + demo.queue().launch() +""" + +javascript_code = """function greet(name) { + return `Hello, ${name}!`; +} + +const result = greet('World'); +console.log(result); +""" + +typescript_code = """interface User { + id: number; + name: string; + email: string; +} + +function createUser(name: string, email: string): User { + return { + id: Math.random(), + name, + email, + }; +} +""" + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + antd.Divider("Python Code") + antdx.CodeHighlighter(value=python_code, + lang="python", + header=True) + + antd.Divider("JavaScript Code") + antdx.CodeHighlighter(value=javascript_code, + lang="javascript", + header=True) + + antd.Divider("TypeScript Code") + antdx.CodeHighlighter(value=typescript_code, + lang="typescript", + header=True) + + antd.Divider("Custom Header Slot") + with antdx.CodeHighlighter(value=python_code, lang="python"): + with ms.Slot("header"): + with antd.Flex(justify="space-between", align="center"): + ms.Span("Python Example") + with antd.Button(value=None, size="small", + type="text"): + with ms.Slot("icon"): + antd.Icon("CopyOutlined") + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/file_card/README-zh_CN.md b/docs/components/antdx/file_card/README-zh_CN.md new file mode 100644 index 00000000..7c051497 --- /dev/null +++ b/docs/components/antdx/file_card/README-zh_CN.md @@ -0,0 +1,7 @@ +# FileCard + +Used to display files during conversations or input. See [Ant Design X](https://x.ant.design/components/file-card/) for more information. + +## Examples + + diff --git a/docs/components/antdx/file_card/README.md b/docs/components/antdx/file_card/README.md new file mode 100644 index 00000000..7c051497 --- /dev/null +++ b/docs/components/antdx/file_card/README.md @@ -0,0 +1,7 @@ +# FileCard + +Used to display files during conversations or input. See [Ant Design X](https://x.ant.design/components/file-card/) for more information. + +## Examples + + diff --git a/docs/components/antdx/file_card/app.py b/docs/components/antdx/file_card/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antdx/file_card/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antdx/file_card/demos/basic.py b/docs/components/antdx/file_card/demos/basic.py new file mode 100644 index 00000000..129158b3 --- /dev/null +++ b/docs/components/antdx/file_card/demos/basic.py @@ -0,0 +1,96 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + antd.Divider("File Types") + with antd.Flex(gap="middle", wrap=True): + antdx.FileCard(filename="document.pdf", + type="file", + icon="pdf", + byte=204800) + antdx.FileCard(filename="spreadsheet.xlsx", + type="file", + icon="excel", + byte=102400) + antdx.FileCard(filename="presentation.pptx", + type="file", + icon="ppt", + byte=512000) + antdx.FileCard(filename="report.docx", + type="file", + icon="word", + byte=81920) + antdx.FileCard(filename="archive.zip", + type="file", + icon="zip", + byte=1048576) + antdx.FileCard(filename="README.md", + type="file", + icon="markdown", + byte=4096) + antdx.FileCard(filename="script.py", + type="file", + icon="python", + byte=8192) + + antd.Divider("Image Type") + with antd.Flex(gap="middle", wrap=True): + antdx.FileCard( + filename="photo.jpg", + type="image", + src= + "https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg", + byte=327680) + + antd.Divider("Loading State") + with antd.Flex(gap="middle", wrap=True): + antdx.FileCard(filename="loading-file.pdf", + type="file", + icon="pdf", + loading=True) + + antd.Divider("With Description") + with antd.Flex(gap="middle", wrap=True): + antdx.FileCard(filename="notes.txt", + type="file", + description="Last modified today", + byte=2048) + + antd.Divider("FileCard.List") + antdx.FileCard.List(items=[{ + "filename": "file1.pdf", + "type": "file", + "icon": "pdf", + "byte": 204800 + }, { + "filename": "image1.jpg", + "type": "image", + "byte": 327680 + }, { + "filename": "audio.mp3", + "type": "audio", + "byte": 5242880 + }, { + "filename": "video.mp4", + "type": "video", + "byte": 52428800 + }], + removable=True) + + antd.Divider("FileCard.List with Custom Items") + with antdx.FileCard.List(removable=True): + antdx.FileCard.List.Item(filename="custom1.xlsx", + type="file", + icon="excel", + byte=102400) + antdx.FileCard.List.Item(filename="custom2.pdf", + type="file", + icon="pdf", + byte=204800) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/folder/README-zh_CN.md b/docs/components/antdx/folder/README-zh_CN.md new file mode 100644 index 00000000..dd33337c --- /dev/null +++ b/docs/components/antdx/folder/README-zh_CN.md @@ -0,0 +1,7 @@ +# Folder + +A folder tree component for displaying file structures. See [Ant Design X](https://x.ant.design/components/folder/) for more information. + +## Examples + + diff --git a/docs/components/antdx/folder/README.md b/docs/components/antdx/folder/README.md new file mode 100644 index 00000000..dd33337c --- /dev/null +++ b/docs/components/antdx/folder/README.md @@ -0,0 +1,7 @@ +# Folder + +A folder tree component for displaying file structures. See [Ant Design X](https://x.ant.design/components/folder/) for more information. + +## Examples + + diff --git a/docs/components/antdx/folder/app.py b/docs/components/antdx/folder/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antdx/folder/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antdx/folder/demos/basic.py b/docs/components/antdx/folder/demos/basic.py new file mode 100644 index 00000000..0c60768d --- /dev/null +++ b/docs/components/antdx/folder/demos/basic.py @@ -0,0 +1,110 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + + +def on_file_click(e: gr.EventData): + print("file clicked:", e._data["payload"]) + + +def on_folder_click(e: gr.EventData): + print("folder clicked:", e._data["payload"]) + + +def on_selected_file_change(e: gr.EventData): + print("selected file changed:", e._data["payload"]) + + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + antd.Divider("Basic Folder Tree") + with antdx.Folder(default_expand_all=True) as folder1: + with antdx.Folder.TreeNode(title="src", path="/src"): + antdx.Folder.TreeNode(title="index.ts", + path="/src/index.ts", + content="export * from './app';") + antdx.Folder.TreeNode( + title="app.ts", + path="/src/app.ts", + content= + "// Application entry point\nconsole.log('Hello World');" + ) + with antdx.Folder.TreeNode(title="components", + path="/src/components"): + antdx.Folder.TreeNode( + title="Button.tsx", + path="/src/components/Button.tsx", + content= + "import React from 'react';\n\nexport const Button = () => ;" + ) + antdx.Folder.TreeNode( + title="Input.tsx", + path="/src/components/Input.tsx", + content= + "import React from 'react';\n\nexport const Input = () => ;" + ) + with antdx.Folder.TreeNode(title="utils", + path="/src/utils"): + antdx.Folder.TreeNode( + title="helpers.ts", + path="/src/utils/helpers.ts", + content= + "export const add = (a: number, b: number) => a + b;" + ) + antdx.Folder.TreeNode( + title="package.json", + path="/package.json", + content= + '{\n "name": "my-project",\n "version": "1.0.0"\n}') + antdx.Folder.TreeNode( + title="README.md", + path="/README.md", + content="# My Project\n\nA sample project.") + + antd.Divider("Using tree_data Prop") + antdx.Folder( + default_expand_all=True, + tree_data=[{ + "title": + "project", + "path": + "/project", + "children": [{ + "title": "main.py", + "path": "/project/main.py", + "content": "print('Hello, World!')" + }, { + "title": + "utils.py", + "path": + "/project/utils.py", + "content": + "def greet(name):\n return f'Hello, {name}!'" + }, { + "title": + "tests", + "path": + "/project/tests", + "children": [{ + "title": + "test_main.py", + "path": + "/project/tests/test_main.py", + "content": + "import unittest\n\nclass TestMain(unittest.TestCase):\n pass" + }] + }] + }, { + "title": "requirements.txt", + "path": "/requirements.txt", + "content": "gradio\nmodelscope-studio" + }]) + + folder1.file_click(fn=on_file_click) + folder1.folder_click(fn=on_folder_click) + folder1.selected_file_change(fn=on_selected_file_change) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/mermaid/README-zh_CN.md b/docs/components/antdx/mermaid/README-zh_CN.md new file mode 100644 index 00000000..41a6992f --- /dev/null +++ b/docs/components/antdx/mermaid/README-zh_CN.md @@ -0,0 +1,7 @@ +# Mermaid + +A Mermaid diagram rendering component. See [Ant Design X](https://x.ant.design/components/mermaid/) for more information. + +## Examples + + diff --git a/docs/components/antdx/mermaid/README.md b/docs/components/antdx/mermaid/README.md new file mode 100644 index 00000000..41a6992f --- /dev/null +++ b/docs/components/antdx/mermaid/README.md @@ -0,0 +1,7 @@ +# Mermaid + +A Mermaid diagram rendering component. See [Ant Design X](https://x.ant.design/components/mermaid/) for more information. + +## Examples + + diff --git a/docs/components/antdx/mermaid/app.py b/docs/components/antdx/mermaid/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antdx/mermaid/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antdx/mermaid/demos/basic.py b/docs/components/antdx/mermaid/demos/basic.py new file mode 100644 index 00000000..d1bda9bf --- /dev/null +++ b/docs/components/antdx/mermaid/demos/basic.py @@ -0,0 +1,14 @@ +import gradio as gr +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + antdx.Mermaid(value="""graph TD + A[Start] --> B{Decision} + B -->|Yes| C[OK] + B -->|No| D[Cancel]""") + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/notification/README-zh_CN.md b/docs/components/antdx/notification/README-zh_CN.md new file mode 100644 index 00000000..2d27e0e7 --- /dev/null +++ b/docs/components/antdx/notification/README-zh_CN.md @@ -0,0 +1,7 @@ +# Notification + +A browser native notification component. See [Ant Design X](https://x.ant.design/components/notification/) for more information. + +## Examples + + diff --git a/docs/components/antdx/notification/README.md b/docs/components/antdx/notification/README.md new file mode 100644 index 00000000..2d27e0e7 --- /dev/null +++ b/docs/components/antdx/notification/README.md @@ -0,0 +1,7 @@ +# Notification + +A browser native notification component. See [Ant Design X](https://x.ant.design/components/notification/) for more information. + +## Examples + + diff --git a/docs/components/antdx/notification/app.py b/docs/components/antdx/notification/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antdx/notification/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antdx/notification/demos/basic.py b/docs/components/antdx/notification/demos/basic.py new file mode 100644 index 00000000..4f9f4a52 --- /dev/null +++ b/docs/components/antdx/notification/demos/basic.py @@ -0,0 +1,23 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + notification = antdx.Notification( + title="Hello Notification", + body= + "This is a browser native notification triggered from Gradio.", + duration=5000, + visible=False) + btn = antd.Button("Send Notification", type="primary") + + btn.click( + fn=lambda: gr.update(visible=True), + outputs=[notification], + ) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/prompts/demos/nest_usage.py b/docs/components/antdx/prompts/demos/nest_usage.py index 54ebb754..25668714 100644 --- a/docs/components/antdx/prompts/demos/nest_usage.py +++ b/docs/components/antdx/prompts/demos/nest_usage.py @@ -11,7 +11,7 @@ def item_click(e: gr.EventData): with gr.Blocks() as demo: with ms.Application(): - with antdx.XProvider(theme=dict(algorithm=dict(dark=False))): + with antdx.XProvider(theme_config=dict(algorithm=dict(dark=False))): with antd.Card(elem_style=dict(borderRadius=0, border=0)): with antdx.Prompts( title="Do you want?", diff --git a/docs/components/antdx/sources/README-zh_CN.md b/docs/components/antdx/sources/README-zh_CN.md new file mode 100644 index 00000000..eac020b4 --- /dev/null +++ b/docs/components/antdx/sources/README-zh_CN.md @@ -0,0 +1,7 @@ +# Sources + +A component for displaying information source lists in AI chat scenarios. See [Ant Design X](https://x.ant.design/components/sources/) for more information. + +## Examples + + diff --git a/docs/components/antdx/sources/README.md b/docs/components/antdx/sources/README.md new file mode 100644 index 00000000..eac020b4 --- /dev/null +++ b/docs/components/antdx/sources/README.md @@ -0,0 +1,7 @@ +# Sources + +A component for displaying information source lists in AI chat scenarios. See [Ant Design X](https://x.ant.design/components/sources/) for more information. + +## Examples + + diff --git a/docs/components/antdx/sources/app.py b/docs/components/antdx/sources/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antdx/sources/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antdx/sources/demos/basic.py b/docs/components/antdx/sources/demos/basic.py new file mode 100644 index 00000000..79bcc4b7 --- /dev/null +++ b/docs/components/antdx/sources/demos/basic.py @@ -0,0 +1,64 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + + +def on_click(e: gr.EventData): + item = e._data["payload"][0] + gr.Info("Clicked: " + str(item.get("title", ""))) + + +def on_expand(e: gr.EventData): + expanded = e._data["payload"][0] + gr.Info("Expanded: " + str(expanded)) + + +source_items = [ + { + "title": "Ant Design X", + "description": "The AI-Native UI solution of Ant Design", + "href": "https://x.ant.design", + }, + { + "title": "Ant Design", + "description": "An enterprise-class UI design language", + "href": "https://ant.design", + }, + { + "title": "GitHub", + "description": "Where the world builds software", + "href": "https://github.com", + }, +] + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + antd.Divider("Basic Sources") + sources1 = antdx.Sources(title="References", + items=source_items, + default_expanded=True) + + antd.Divider("Inline Sources") + sources2 = antdx.Sources(title="References", + items=source_items, + inline=True) + + antd.Divider("Sources with Slot Items") + with antdx.Sources(title="Sources") as sources3: + with ms.Slot("items"): + antdx.Sources.Item(title="Ant Design X", + description="The AI-Native UI solution", + url="https://x.ant.design") + antdx.Sources.Item( + title="ModelScope Studio", + description="Gradio component library", + url="https://github.com/modelscope/modelscope-studio") + + sources1.click(fn=on_click) + sources2.click(fn=on_click) + sources1.expand(fn=on_expand) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/think/README-zh_CN.md b/docs/components/antdx/think/README-zh_CN.md new file mode 100644 index 00000000..6f1d5186 --- /dev/null +++ b/docs/components/antdx/think/README-zh_CN.md @@ -0,0 +1,7 @@ +# Think + +A component for displaying AI model thinking process in chat scenarios. See [Ant Design X](https://x.ant.design/components/think/) for more information. + +## Examples + + diff --git a/docs/components/antdx/think/README.md b/docs/components/antdx/think/README.md new file mode 100644 index 00000000..6f1d5186 --- /dev/null +++ b/docs/components/antdx/think/README.md @@ -0,0 +1,7 @@ +# Think + +A component for displaying AI model thinking process in chat scenarios. See [Ant Design X](https://x.ant.design/components/think/) for more information. + +## Examples + + diff --git a/docs/components/antdx/think/app.py b/docs/components/antdx/think/app.py new file mode 100644 index 00000000..0018b7c1 --- /dev/null +++ b/docs/components/antdx/think/app.py @@ -0,0 +1,6 @@ +from helper.Docs import Docs + +docs = Docs(__file__) + +if __name__ == "__main__": + docs.render().queue().launch() diff --git a/docs/components/antdx/think/demos/basic.py b/docs/components/antdx/think/demos/basic.py new file mode 100644 index 00000000..ad28db92 --- /dev/null +++ b/docs/components/antdx/think/demos/basic.py @@ -0,0 +1,42 @@ +import gradio as gr +import modelscope_studio.components.antd as antd +import modelscope_studio.components.antdx as antdx +import modelscope_studio.components.base as ms + +thinking_content = """I need to analyze the user's question carefully. + +First, let me consider the context and requirements. +Then, I'll formulate a comprehensive response based on my analysis. +Finally, I'll present the answer in a clear and concise manner.""" + +with gr.Blocks() as demo: + with ms.Application(): + with antdx.XProvider(): + antd.Divider("Basic Think") + with antdx.Think(title="Thinking...", default_expanded=True): + ms.Span(thinking_content) + + antd.Divider("Loading State") + with antd.Space(): + ms.Span("Loading State") + loading_switch = antd.Switch(value=True) + with antdx.Think(title="Thinking...", blink=True) as think_loading: + ms.Span(thinking_content) + + antd.Divider("Expanded Control") + with antd.Space(): + ms.Span("Expanded") + expanded_switch = antd.Switch(value=True) + with antdx.Think(title="Think Result", + expanded=True) as think_expanded: + ms.Span(thinking_content) + + loading_switch.change(fn=lambda x: gr.update(loading=x, blink=x), + inputs=[loading_switch], + outputs=[think_loading]) + expanded_switch.change(fn=lambda x: gr.update(expanded=x), + inputs=[expanded_switch], + outputs=[think_expanded]) + +if __name__ == "__main__": + demo.queue().launch() diff --git a/docs/components/antdx/thought_chain/demos/basic.py b/docs/components/antdx/thought_chain/demos/basic.py index 762983df..5ba59201 100644 --- a/docs/components/antdx/thought_chain/demos/basic.py +++ b/docs/components/antdx/thought_chain/demos/basic.py @@ -3,8 +3,6 @@ import modelscope_studio.components.antdx as antdx import modelscope_studio.components.base as ms -default_collapsible = False - def mock_content(): with antd.Typography.Paragraph(): @@ -24,13 +22,10 @@ def mock_content(): with gr.Blocks() as demo: with ms.Application(): with antdx.XProvider(): - collapsible = antd.Switch(default_collapsible, - checked_children="Collapsible", - un_checked_children="Not Collapsible") with antd.Card(): - with antdx.ThoughtChain( - collapsible=default_collapsible) as thought_chain: - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain(): + with antdx.ThoughtChain.ThoughtChainItem( + collapsible=True, title="Thought Chain Item Title 1", description="description", status="success"): @@ -43,7 +38,7 @@ def mock_content(): with ms.Slot("footer"): antd.Button("Thought Chain Item Footer", block=True) - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain.ThoughtChainItem( title="Thought Chain Item Title 2", description="description", status="error"): @@ -56,7 +51,7 @@ def mock_content(): with ms.Slot("footer"): antd.Button("Thought Chain Item Footer", block=True) - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain.ThoughtChainItem( title="Thought Chain Item Title 3", description="description", status="pending"): @@ -69,8 +64,5 @@ def mock_content(): with ms.Slot("footer"): antd.Button("Thought Chain Item Footer", block=True) - collapsible.change(fn=lambda x: gr.update(collapsible=x), - inputs=[collapsible], - outputs=[thought_chain]) if __name__ == "__main__": demo.queue().launch() diff --git a/docs/components/antdx/thought_chain/demos/item_status.py b/docs/components/antdx/thought_chain/demos/item_status.py index 8e7284f1..ac22f950 100644 --- a/docs/components/antdx/thought_chain/demos/item_status.py +++ b/docs/components/antdx/thought_chain/demos/item_status.py @@ -9,26 +9,22 @@ def run_next(each_value): each_value.append({ "title": f'Thought Chain Item - {len(each_value) + 1}', - "status": 'pending', + "status": 'loading', "description": 'status: pending', - "icon": "LoadingOutlined", "key": str(len(each_value) + 1) }) yield gr.update(value="Running", loading=True), gr.update(value=each_value) time.sleep(0.8) each_value[-1]["status"] = "error" each_value[-1]["description"] = 'status: error' - each_value[-1]["icon"] = "InfoCircleOutlined" yield gr.skip(), gr.update(value=each_value) time.sleep(0.8) - each_value[-1]["status"] = "pending" + each_value[-1]["status"] = "loading" each_value[-1]["description"] = 'status: pending' - each_value[-1]["icon"] = 'LoadingOutlined' yield gr.skip(), gr.update(value=each_value) time.sleep(0.8) each_value[-1]["status"] = "success" each_value[-1]["description"] = 'status: success' - each_value[-1]["icon"] = "CheckCircleOutlined" yield gr.update(value="Run Next", loading=False), gr.update(value=each_value) @@ -49,20 +45,16 @@ def run_next(each_value): "title": 'Thought Chain Item - 1', "status": 'success', "description": 'status: success', - "icon": 'CheckCircleOutlined', "key": "1" }, { "title": 'Thought Chain Item - 2', "status": 'error', "description": 'status: error', - "icon": 'InfoCircleOutlined', "key": "2" }, ]) as each: - with antdx.ThoughtChain.Item(): - with ms.Slot("icon"): - antd.Icon(as_item="icon") + antdx.ThoughtChain.ThoughtChainItem() btn.click(fn=run_next, inputs=[each], outputs=[btn, each]) diff --git a/docs/components/antdx/thought_chain/demos/nested_use.py b/docs/components/antdx/thought_chain/demos/nested_use.py index 9ba98583..01c1473a 100644 --- a/docs/components/antdx/thought_chain/demos/nested_use.py +++ b/docs/components/antdx/thought_chain/demos/nested_use.py @@ -7,8 +7,8 @@ with ms.Application(): with antdx.XProvider(): with antd.Card(): - with antdx.ThoughtChain(collapsible=True): - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain(): + with antdx.ThoughtChain.ThoughtChainItem( title="1 - Thought Chain Item", description="description"): with ms.Slot("extra"): @@ -17,7 +17,7 @@ antd.Icon("MoreOutlined") with ms.Slot("content"): with antdx.ThoughtChain(): - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain.ThoughtChainItem( title="1-1 - Thought Chain Item", description="description"): with ms.Slot("extra"): @@ -25,7 +25,7 @@ type="text"): with ms.Slot("icon"): antd.Icon("MoreOutlined") - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain.ThoughtChainItem( title="1-2 - Thought Chain Item", description="description"): with ms.Slot("extra"): @@ -35,7 +35,7 @@ antd.Icon("MoreOutlined") with ms.Slot("footer"): antd.Button("1 - Thought Chain Item Footer") - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain.ThoughtChainItem( title="2 - Thought Chain Item", description="description"): with ms.Slot("extra"): @@ -44,7 +44,7 @@ antd.Icon("MoreOutlined") with ms.Slot("content"): with antdx.ThoughtChain(): - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain.ThoughtChainItem( title="2-1 - Thought Chain Item", description="description"): with ms.Slot("extra"): @@ -52,7 +52,7 @@ type="text"): with ms.Slot("icon"): antd.Icon("MoreOutlined") - with antdx.ThoughtChain.Item( + with antdx.ThoughtChain.ThoughtChainItem( title="2-2 - Thought Chain Item", description="description"): with ms.Slot("extra"): diff --git a/docs/helper/Site.py b/docs/helper/Site.py index 26eca9a1..d3c3d217 100644 --- a/docs/helper/Site.py +++ b/docs/helper/Site.py @@ -57,20 +57,22 @@ def on_tab_menu_select(e: gr.EventData): for category in self.docs: for component in self.docs[category]: css += self.docs[category][component].get_css() - with gr.Blocks(css=css + """ + css = css + """ .gradio-container { max-width: 100% !important; padding: 0 !important; } -.gradio-container > main.fillable { +.gradio-container > .main.fillable { max-width: 100% !important; padding: 0 !important; + margin:0 !important; } .docs-layout-sider { width: 100% !important; max-width: 100% !important; } -""") as demo: +""" + with gr.Blocks() as demo: with ms.Application() as app: with antd.ConfigProvider(): with antd.Layout(elem_style=dict( @@ -167,7 +169,10 @@ def on_tab_menu_select(e: gr.EventData): else: tab["extra_menu_footer"].render( ) - with antd.Splitter.Panel(): + with antd.Splitter.Panel( + elem_style=dict( + overflow="auto" + )): with antd.Layout( elem_style=dict( width= @@ -251,4 +256,4 @@ def on_app_mount(e: gr.EventData): tab_menu.select( fn=on_tab_menu_select, outputs=[tab_menu, tabs, *tab_components]) - return demo + return demo, css diff --git a/docs/layout_templates/chatbot/demos/basic.py b/docs/layout_templates/chatbot/demos/basic.py index 5bf8cdbf..52d7c293 100644 --- a/docs/layout_templates/chatbot/demos/basic.py +++ b/docs/layout_templates/chatbot/demos/basic.py @@ -468,7 +468,7 @@ def logo(): ms.Span("Chatbot") -with gr.Blocks(css=css, fill_width=True) as demo: +with gr.Blocks(fill_width=True) as demo: state = gr.State({ "conversations_history": {}, "conversations": [], @@ -476,7 +476,8 @@ def logo(): }) with ms.Application(), antdx.XProvider( - theme=DEFAULT_THEME, locale=DEFAULT_LOCALE), ms.AutoLoading(): + theme_config=DEFAULT_THEME, + locale=DEFAULT_LOCALE), ms.AutoLoading(): with antd.Row(gutter=[20, 20], wrap=False, elem_id="chatbot"): # Left Column with antd.Col(md=dict(flex="0 0 260px", span=24, order=0), @@ -694,4 +695,4 @@ def logo(): queue=False) if __name__ == "__main__": - demo.queue().launch(ssr_mode=False) + demo.queue().launch(css=css, ssr_mode=False) diff --git a/docs/layout_templates/chatbot/demos/copilot.py b/docs/layout_templates/chatbot/demos/copilot.py index ac88cdfb..21774d60 100644 --- a/docs/layout_templates/chatbot/demos/copilot.py +++ b/docs/layout_templates/chatbot/demos/copilot.py @@ -171,7 +171,7 @@ def resize_window(e: gr.EventData): } """ -with gr.Blocks(css=css) as demo, ms.Application() as app, antdx.XProvider(): +with gr.Blocks() as demo, ms.Application() as app, antdx.XProvider(): with antd.Row(elem_classes="copilot-container", wrap=True): # Content column with antd.Col(md=16, xs=24, @@ -322,4 +322,4 @@ def resize_window(e: gr.EventData): fn=resize_window, outputs=[copilot_open_btn, copilot_close_btn]) if __name__ == "__main__": - demo.queue().launch() + demo.queue().launch(css=css) diff --git a/docs/layout_templates/chatbot/demos/fine_grained_control.py b/docs/layout_templates/chatbot/demos/fine_grained_control.py index 627e8769..2f36a042 100644 --- a/docs/layout_templates/chatbot/demos/fine_grained_control.py +++ b/docs/layout_templates/chatbot/demos/fine_grained_control.py @@ -525,7 +525,7 @@ def logo(): ms.Span("Chatbot") -with gr.Blocks(css=css, fill_width=True) as demo: +with gr.Blocks(fill_width=True) as demo: state = gr.State({ "conversations_history": {}, "conversations": [], @@ -535,7 +535,8 @@ def logo(): }) with ms.Application(), antdx.XProvider( - theme=DEFAULT_THEME, locale=DEFAULT_LOCALE), ms.AutoLoading(): + theme_config=DEFAULT_THEME, + locale=DEFAULT_LOCALE), ms.AutoLoading(): with antd.Row(gutter=[20, 20], wrap=False, elem_id="chatbot"): # Left Column with antd.Col(md=dict(flex="0 0 260px", span=24, order=0), @@ -580,9 +581,11 @@ def logo(): # Placeholder Role with antdx.Bubble.List.Role( role="placeholder", - styles=dict(content=dict(width="100%")), + styles=dict(content=dict(width="100%"), + root=dict(paddingInlineEnd=0), + body=dict(width='100%')), variant="borderless"): - with ms.Slot("messageRender"): + with ms.Slot("contentRender"): with antd.Space( direction="vertical", size=16, @@ -633,12 +636,12 @@ def logo(): with antd.Avatar(): with ms.Slot("icon"): antd.Icon("UserOutlined") - with ms.Slot("messageRender", + with ms.Slot("contentRender", params_mapping="""(content) => { if (typeof content === 'string') { return { content, files: [], files_container: { style: { display: 'none' }} } } - return { content: content.text, files_container: content.files?.length > 0 ? undefined : { style: { display: 'none' }}, files: (content.files || []).map(file => ({ item: file }))} + return { content: content.text, files_container: content.files?.length > 0 ? undefined : { style: { display: 'none' }}, files: (content.files || []).map(file => file)} }"""): with antd.Flex(vertical=True, @@ -648,16 +651,17 @@ def logo(): wrap=True, as_item="files_container"): with ms.Each(as_item="files"): - antdx.Attachments.FileCard() + antdx.FileCard() ms.Markdown(as_item="content") with ms.Slot("footer", - params_mapping="""(bubble) => { + params_mapping= + """(content, info, bubble) => { return { copy_btn: { copyable: { text: typeof bubble.content === 'string' ? bubble.content : bubble.content?.text, tooltips: false }, }, - edit_btn: { conversationKey: bubble.key, disabled: bubble.meta.disabled }, - delete_btn: { conversationKey: bubble.key, disabled: bubble.meta.disabled }, + edit_btn: { conversationKey: bubble.key, disabled: bubble.meta?.disabled }, + delete_btn: { conversationKey: bubble.key, disabled: bubble.meta?.disabled }, }; }"""): with antd.Typography.Text( @@ -712,9 +716,9 @@ def logo(): with antd.Avatar(): with ms.Slot("icon"): antd.Icon("RobotOutlined") - with ms.Slot( - "messageRender", - params_mapping="""(content, bubble) => { + with ms.Slot("contentRender", + params_mapping= + """(content, info, bubble) => { if (bubble.meta?.canceled) { return { value: content } } @@ -727,15 +731,16 @@ def logo(): as_item="canceled", type="warning") with ms.Slot("footer", - params_mapping="""(bubble) => { + params_mapping= + """(content, info, bubble) => { if (bubble?.meta?.end) { return { copy_btn: { copyable: { text: bubble.content, tooltips: false }, }, - regenerate_btn: { conversationKey: bubble.key, disabled: bubble.meta.disabled }, - delete_btn: { conversationKey: bubble.key, disabled: bubble.meta.disabled }, - edit_btn: { conversationKey: bubble.key, disabled: bubble.meta.disabled }, + regenerate_btn: { conversationKey: bubble.key, disabled: bubble.meta?.disabled }, + delete_btn: { conversationKey: bubble.key, disabled: bubble.meta?.disabled }, + edit_btn: { conversationKey: bubble.key, disabled: bubble.meta?.disabled }, like_btn: { conversationKey: bubble.key, color: bubble.meta?.action === 'like' ? 'primary' : 'default', @@ -1034,4 +1039,4 @@ def logo(): queue=False) if __name__ == "__main__": - demo.queue().launch(ssr_mode=False) + demo.queue().launch(css=css, ssr_mode=False) diff --git a/docs/layout_templates/coder_artifacts/demos/app.py b/docs/layout_templates/coder_artifacts/demos/app.py index 302e8e97..5e573d78 100644 --- a/docs/layout_templates/coder_artifacts/demos/app.py +++ b/docs/layout_templates/coder_artifacts/demos/app.py @@ -217,11 +217,12 @@ def clear_history(e: gr.EventData, state_value): } """ -with gr.Blocks(css=css) as demo: +with gr.Blocks() as demo: # Global State state = gr.State({"system_prompt": DEFAULT_SYSTEM_PROMPT, "history": []}) with ms.Application(elem_id="coder-artifacts") as app: - with antd.ConfigProvider(theme=DEFAULT_THEME, locale=DEFAULT_LOCALE): + with antd.ConfigProvider(theme_config=DEFAULT_THEME, + locale=DEFAULT_LOCALE): # Header with antd.Flex(justify="center", align="center", gap="middle"): antd.Typography.Title("Coder-Artifacts", @@ -382,7 +383,6 @@ def clear_history(e: gr.EventData, state_value): width="750px") as history_drawer: history_output = gr.Chatbot( show_label=False, - type="messages", height='100%', elem_classes="history_chatbot") # Tour @@ -476,4 +476,4 @@ def clear_history(e: gr.EventData, state_value): outputs=[output_code_drawer]) if __name__ == "__main__": - demo.queue().launch(ssr_mode=False) + demo.queue().launch(css=css, ssr_mode=False) diff --git a/frontend/antd/masonry/Index.svelte b/frontend/antd/masonry/Index.svelte new file mode 100644 index 00000000..f1a58717 --- /dev/null +++ b/frontend/antd/masonry/Index.svelte @@ -0,0 +1,63 @@ + + +{#if proceedProps.visible} + {#await AwaitedMasonry then Masonry} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antd/masonry/context.ts b/frontend/antd/masonry/context.ts new file mode 100644 index 00000000..1e31f6cb --- /dev/null +++ b/frontend/antd/masonry/context.ts @@ -0,0 +1,6 @@ +import { createItemsContext } from '@utils/createItemsContext'; + +export const { withItemsContextProvider, useItems, ItemHandler } = + createItemsContext('antd-masonry-items'); + +export * from '@utils/createItemsContext'; diff --git a/frontend/antd/masonry/gradio.config.js b/frontend/antd/masonry/gradio.config.js new file mode 100644 index 00000000..916857c0 --- /dev/null +++ b/frontend/antd/masonry/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../defineConfig.js'; + +export default config(); diff --git a/frontend/antd/masonry/item/Index.svelte b/frontend/antd/masonry/item/Index.svelte new file mode 100644 index 00000000..797edac7 --- /dev/null +++ b/frontend/antd/masonry/item/Index.svelte @@ -0,0 +1,80 @@ + + +{#await AwaitedMasonryItem then MasonryItem} + + {#if proceedProps.visible} + + {@render children?.()} + + {/if} + +{/await} + + diff --git a/frontend/antd/masonry/item/gradio.config.js b/frontend/antd/masonry/item/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antd/masonry/item/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antd/masonry/item/masonry.item.tsx b/frontend/antd/masonry/item/masonry.item.tsx new file mode 100644 index 00000000..32be0fc8 --- /dev/null +++ b/frontend/antd/masonry/item/masonry.item.tsx @@ -0,0 +1,15 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import { type MasonryProps } from 'antd'; + +import { ItemHandler, type ItemHandlerProps } from '../context'; + +type MasonryItemType = NonNullable[number]; + +export const MasonryItem = sveltify< + Partial & ItemHandlerProps +>((props) => { + return ; +}); + +export default MasonryItem; diff --git a/frontend/antd/masonry/item/package.json b/frontend/antd/masonry/item/package.json new file mode 100644 index 00000000..fa763a00 --- /dev/null +++ b/frontend/antd/masonry/item/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antd-masonry.item", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antd/masonry/masonry.tsx b/frontend/antd/masonry/masonry.tsx new file mode 100644 index 00000000..1cc51f4c --- /dev/null +++ b/frontend/antd/masonry/masonry.tsx @@ -0,0 +1,51 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React, { useMemo } from 'react'; +import { useFunction } from '@utils/hooks/useFunction'; +import { renderItems } from '@utils/renderItems'; +import { renderParamsSlot } from '@utils/renderParamsSlot'; +import { Masonry as AMasonry, type MasonryProps } from 'antd'; + +import { useItems, withItemsContextProvider } from './context'; + +export const Masonry = sveltify< + MasonryProps & { + children?: React.ReactNode; + }, + ['itemRender'] +>( + withItemsContextProvider( + ['default', 'items'], + ({ children, slots, items, ...props }) => { + const { items: slotItems } = useItems<['default', 'items']>(); + const resolvedSlotItems = + slotItems.items.length > 0 ? slotItems.items : slotItems.default; + const itemRenderFunction = useFunction(props.itemRender); + return ( + <> +
{children}
+ { + return ( + items || + renderItems[number]>( + resolvedSlotItems + ) + ); + }, [items, resolvedSlotItems])} + /> + + ); + } + ) +); + +export default Masonry; diff --git a/frontend/antd/masonry/package.json b/frontend/antd/masonry/package.json new file mode 100644 index 00000000..dc3c6f9b --- /dev/null +++ b/frontend/antd/masonry/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antd-masonry", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antdx/bubble/bubble.tsx b/frontend/antdx/bubble/bubble.tsx index 772c4a58..dc9944cf 100644 --- a/frontend/antdx/bubble/bubble.tsx +++ b/frontend/antdx/bubble/bubble.tsx @@ -35,6 +35,7 @@ export const Bubble = sveltify< const editableConfig = getConfig(props.editable); const supportEdit = props.editable || slots['editable.cancelText'] || slots['editable.okText']; + return ( <>
{children}
diff --git a/frontend/antdx/bubble/list/bubble.list.tsx b/frontend/antdx/bubble/list/bubble.list.tsx index c3adbaa0..e75d8d0f 100644 --- a/frontend/antdx/bubble/list/bubble.list.tsx +++ b/frontend/antdx/bubble/list/bubble.list.tsx @@ -22,6 +22,7 @@ export const BubbleList = sveltify( const resolvedSlotItems = slotItems.items?.length ? slotItems.items : slotItems.default; + return ( <>
{children}
diff --git a/frontend/antdx/bubble/list/item/Item.svelte b/frontend/antdx/bubble/list/item/Item.svelte index 7f808e41..ecbb097d 100644 --- a/frontend/antdx/bubble/list/item/Item.svelte +++ b/frontend/antdx/bubble/list/item/Item.svelte @@ -126,7 +126,7 @@ withParams: true, }, contentRender: { - el: slots.value.messageRender, + el: slots.value.contentRender, clone: true, withParams: true, }, diff --git a/frontend/antdx/bubble/list/role/Role.svelte b/frontend/antdx/bubble/list/role/Role.svelte index 550ea553..1672cd68 100644 --- a/frontend/antdx/bubble/list/role/Role.svelte +++ b/frontend/antdx/bubble/list/role/Role.svelte @@ -124,7 +124,7 @@ withParams: true, }, contentRender: { - el: slots.value.messageRender, + el: slots.value.contentRender, clone: true, withParams: true, }, diff --git a/frontend/antdx/bubble/list/utils.tsx b/frontend/antdx/bubble/list/utils.tsx index 9bbf639c..0c5e54fc 100644 --- a/frontend/antdx/bubble/list/utils.tsx +++ b/frontend/antdx/bubble/list/utils.tsx @@ -5,7 +5,6 @@ import type { RoleType, } from '@ant-design/x/es/bubble/interface'; import { createFunction } from '@utils/createFunction'; -import { useMemoizedEqualValue } from '@utils/hooks/useMemoizedEqualValue'; import { useMemoizedFn } from '@utils/hooks/useMemoizedFn'; import { patchSlots } from '@utils/patchSlots'; import { renderItems } from '@utils/renderItems'; @@ -20,22 +19,22 @@ function patchBubbleSlots(role: RoleProps, params: any[]) { return { ...role, avatar: patchSlotRender(role.avatar, { - unshift: true, + // unshift: true, }), extra: patchSlotRender(role.extra, { - unshift: true, + // unshift: true, }), footer: patchSlotRender(role.footer, { - unshift: true, + // unshift: true, }), header: patchSlotRender(role.header, { - unshift: true, + // unshift: true, }), loadingRender: patchSlotRender(role.loadingRender, { - unshift: true, + // unshift: true, }), contentRender: patchSlotRender(role.contentRender, { - unshift: true, + // unshift: true, }), }; }); @@ -43,23 +42,16 @@ function patchBubbleSlots(role: RoleProps, params: any[]) { export interface UseRoleOptions { role?: RoleType; - defaultRoleKeys?: string[]; preProcess?: (bubbleProps: T, index: number) => RoleProps; defaultRolePostProcess?: (bubbleProps: T, index: number) => RoleProps | void; } export function useRole( - { - role: roleProp, - defaultRoleKeys, - preProcess, - defaultRolePostProcess, - }: UseRoleOptions, + { role: roleProp, preProcess, defaultRolePostProcess }: UseRoleOptions, deps: React.DependencyList = [] ) { const memoizedPreProcess = useMemoizedFn(preProcess); const memoizedDefaultRolePostProcess = useMemoizedFn(defaultRolePostProcess); - const memoizedDefaultRoleKeys = useMemoizedEqualValue(defaultRoleKeys); const { items: { role: roleItems }, @@ -88,26 +80,21 @@ export function useRole( {} ); }, [roleItems, roleProp]); - const resolvedRole = useMemo(() => { - const roleKeys = [ - ...new Set([ - ...(memoizedDefaultRoleKeys || []), - ...Object.keys(role || {}), - ]), - ]; - if (roleKeys.length > 0) { - return roleKeys.reduce( - (acc, key) => { + + const resolvedRole: typeof role = useMemo(() => { + return new Proxy( + {}, + { + get: (_, key: string) => { if (typeof role[key] === 'string') { const functionRole = createFunction(role[key]); if (functionRole) { - acc[key] = functionRole; + return functionRole; } } else { - acc[key] = (data) => { + return (data: T) => { const index = data[messageIndexSymbol]; - const preProcessResult = - memoizedPreProcess(data as T, index) || data; + const preProcessResult = memoizedPreProcess(data, index) || data; if (role[key]) { return patchBubbleSlots( isFunction(role[key]) @@ -124,7 +111,7 @@ export function useRole( return postProcessResult; } return { - contentRender(content) { + contentRender(content: any) { return ( <>{isObject(content) ? JSON.stringify(content) : content} ); @@ -132,14 +119,10 @@ export function useRole( }; }; } - return acc; }, - {} as typeof role - ); - } - return role; + } + ); }, [ - memoizedDefaultRoleKeys, role, memoizedPreProcess, memoizedDefaultRolePostProcess, diff --git a/frontend/antdx/folder/Index.svelte b/frontend/antdx/folder/Index.svelte index 1fcd9a76..5464f69f 100644 --- a/frontend/antdx/folder/Index.svelte +++ b/frontend/antdx/folder/Index.svelte @@ -71,9 +71,7 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} - treeData={proceedProps.additionalProps.treeData || - proceedProps.treeData || - []} + treeData={proceedProps.additionalProps.treeData || proceedProps.treeData} slots={slots.value} > {@render children?.()} diff --git a/frontend/antdx/folder/folder.tsx b/frontend/antdx/folder/folder.tsx index 31e6dcda..825cc8b8 100644 --- a/frontend/antdx/folder/folder.tsx +++ b/frontend/antdx/folder/folder.tsx @@ -65,7 +65,8 @@ export const Folder = sveltify< { clone: true, } - ) + ) || + [] ); }, [props.treeData, resolvedTreeNodeItems])} directoryIcons={useMemo(() => { diff --git a/frontend/antdx/notification/notification.tsx b/frontend/antdx/notification/notification.tsx index 00eeb640..07f27555 100644 --- a/frontend/antdx/notification/notification.tsx +++ b/frontend/antdx/notification/notification.tsx @@ -9,7 +9,7 @@ export const Notification = sveltify< onVisible: (visible: boolean) => void; onPermission?: (permission: NotificationPermission) => void; } ->(({ slots, onClose, visible, onVisible, tag, onPermission, ...props }) => { +>(({ onClose, visible, onVisible, tag, duration, onPermission, ...props }) => { const [{ permission }, { open, close, requestPermission }] = notification.useNotification(); const onPermissionMemoized = useMemoizedFn(onPermission); @@ -18,7 +18,13 @@ export const Notification = sveltify< onPermissionMemoized(permission); }, [permission, onPermissionMemoized]); useEffect(() => { + let timer: ReturnType | undefined; if (visible) { + if (typeof duration === 'number') { + timer = setTimeout(() => { + onVisible?.(false); + }, duration); + } const run = async () => { let result = permission; if (result !== 'granted') { @@ -29,6 +35,7 @@ export const Notification = sveltify< ...props, tag, onClose(...args) { + timer && clearTimeout(timer); onVisible?.(false); onClose?.(...args); }, @@ -42,8 +49,10 @@ export const Notification = sveltify< return () => { close(tag ? [tag] : undefined); + timer && clearTimeout(timer); }; - }, [visible, tag]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [visible, duration, tag]); return null; }); diff --git a/frontend/antdx/sources/sources.tsx b/frontend/antdx/sources/sources.tsx index d8426a11..ea083be6 100644 --- a/frontend/antdx/sources/sources.tsx +++ b/frontend/antdx/sources/sources.tsx @@ -13,13 +13,12 @@ export const Sources = sveltify( const { items: slotItems } = useItems<['default', 'items']>(); const resolvedSlotItems = slotItems.items.length > 0 ? slotItems.items : slotItems.default; - return ( <>
{children}
: slots.title} + title={slots.title ? : props.title} items={useMemo(() => { return ( items || diff --git a/frontend/antdx/welcome/welcome.tsx b/frontend/antdx/welcome/welcome.tsx index d83d46af..75a36289 100644 --- a/frontend/antdx/welcome/welcome.tsx +++ b/frontend/antdx/welcome/welcome.tsx @@ -13,13 +13,20 @@ export const Welcome = sveltify< children?: React.ReactNode; }, ['description', 'icon', 'extra', 'title'] ->(({ slots, children, apiPrefix, rootUrl, ...props }) => { +>(({ slots, children, apiPrefix, rootUrl, styles, ...props }) => { return ( <>
{children}
: props.extra} + styles={{ + ...styles, + icon: { + flexShrink: 0, + ...styles?.icon, + }, + }} icon={ slots.icon ? ( diff --git a/frontend/base/auto-loading/auto-loading.less b/frontend/base/auto-loading/auto-loading.less index ee9e057b..caab7653 100644 --- a/frontend/base/auto-loading/auto-loading.less +++ b/frontend/base/auto-loading/auto-loading.less @@ -1,19 +1,19 @@ .ms-gr-auto-loading { position: relative; - > .ms-gr-ant-spin-nested-loading { + & .ms-gr-auto-loading-default-antd { + position: absolute !important; + display: flex !important; + align-items: center; + justify-content: center; + max-height: 100% !important; + inset: 0; + } + + & .ms-gr-ant-spin-container { position: absolute !important; width: 100%; height: 100%; - - .ms-gr-auto-loading-default-antd { - position: absolute !important; - display: flex !important; - align-items: center; - justify-content: center; - max-height: 100% !important; - inset: 0; - } } & .ms-gr-auto-loading-error-default-antd { diff --git a/frontend/base/auto-loading/auto-loading.tsx b/frontend/base/auto-loading/auto-loading.tsx index c0bf8f1f..123c7459 100644 --- a/frontend/base/auto-loading/auto-loading.tsx +++ b/frontend/base/auto-loading/auto-loading.tsx @@ -85,7 +85,7 @@ export const AutoLoading = sveltify< zIndex: token.zIndexPopupBase, backgroundColor: showMask ? token.colorBgMask : undefined, }} - tip={ + description={ showLoadingText ? ( slots.loadingText ? ( renderParamsSlot({ diff --git a/frontend/base/each/EachItem.svelte b/frontend/base/each/EachItem.svelte index e83e11a9..c2a4b3c9 100644 --- a/frontend/base/each/EachItem.svelte +++ b/frontend/base/each/EachItem.svelte @@ -1,5 +1,6 @@ - + {#await AwaitedEachItem then EachItem} {@render children?.()} diff --git a/frontend/base/each/Index.svelte b/frontend/base/each/Index.svelte index bdacbefe..dc38b581 100644 --- a/frontend/base/each/Index.svelte +++ b/frontend/base/each/Index.svelte @@ -93,8 +93,9 @@ {@render children?.()} diff --git a/frontend/base/each/each.tsx b/frontend/base/each/each.tsx index 9c43ce77..ba82436b 100644 --- a/frontend/base/each/each.tsx +++ b/frontend/base/each/each.tsx @@ -35,6 +35,7 @@ const Item: React.FC<{ export const Each = sveltify( ({ value, contextValue, children, __internal_slot_key }) => { const targets = useTargets(children, __internal_slot_key); + return ( <>
diff --git a/frontend/base/fragment/Index.svelte b/frontend/base/fragment/Index.svelte index fe1c6063..fee0e875 100644 --- a/frontend/base/fragment/Index.svelte +++ b/frontend/base/fragment/Index.svelte @@ -15,6 +15,7 @@ const getProceedProps = processProps( () => { const { visible, _internal, as_item, ...restProps } = getComponentProps(); + return { gradio, additionalProps: getAdditionalProps(), @@ -44,6 +45,3 @@ {/await} {/if} - - diff --git a/frontend/base/slot/Index.svelte b/frontend/base/slot/Index.svelte index 6608c66a..a9d096a3 100644 --- a/frontend/base/slot/Index.svelte +++ b/frontend/base/slot/Index.svelte @@ -8,10 +8,11 @@ import { createFunction } from '@utils/createFunction'; const props = $props(); + const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ value: string; params_mapping: string; - }>(() => props); + }>(() => props, { i18n: false }); const getProceedProps = processProps(() => { const { value, visible, as_item, _internal, params_mapping } = diff --git a/frontend/pro/chatbot/chatbot.tsx b/frontend/pro/chatbot/chatbot.tsx index 3ad38ff1..42de442c 100644 --- a/frontend/pro/chatbot/chatbot.tsx +++ b/frontend/pro/chatbot/chatbot.tsx @@ -138,21 +138,25 @@ export const Chatbot = sveltify<{ const newValue = (value || []).map((item, i) => { const isLastMessage = i === value.length - 1; const resolvedItem = omitUndefinedProps(item, { omitNull: true }); - return omitUndefinedProps({ - ...omit(resolvedItem, [ - 'header', - 'footer', - 'avatar', - 'divider_props', - ]), - dividerProps: resolvedItem.divider_props, - [messageIndexSymbol]: i, - [messageHeaderSymbol]: resolvedItem.header, - [messageFooterSymbol]: resolvedItem.footer, - [messageAvatarSymbol]: resolvedItem.avatar, - [lastMessageSymbol]: isLastMessage, - key: resolvedItem.key ?? `${i}`, - }); + return { + ...omitUndefinedProps({ + ...omit(resolvedItem, [ + 'header', + 'footer', + 'avatar', + 'divider_props', + ]), + dividerProps: resolvedItem.divider_props, + }), + ...{ + [messageIndexSymbol]: i, + [messageHeaderSymbol]: resolvedItem.header, + [messageFooterSymbol]: resolvedItem.footer, + [messageAvatarSymbol]: resolvedItem.avatar, + [lastMessageSymbol]: isLastMessage, + key: resolvedItem.key ?? `${i}`, + }, + }; }) as BubbleItemType[]; return newValue.length > 0 ? newValue @@ -298,8 +302,6 @@ export const Chatbot = sveltify<{ }, }; }, - // system, divider will be skipped - defaultRoleKeys: ['chatbot-internal-welcome', 'user', 'assistant'], defaultRolePostProcess(bubbleProps, index) { const isUserRole = bubbleProps.role === 'user'; switch (bubbleProps.role) { @@ -436,6 +438,7 @@ export const Chatbot = sveltify<{ autoScroll, scrollButtonOffset: scrollToBottomButtonOffset, }); + return (
, E extends Record = Record, ->(getSvelteProps: () => any) { +>( + getSvelteProps: () => any, + options?: { + i18n?: boolean; + } +) { const props: { children?: Snippet; props: P; shared_props: SharedProps; + gradio?: Gradio; + [x: PropertyKey]: any; } = getSvelteProps(); - const gradio = new Gradio(props); + const enableI18n = options?.i18n ?? true; + const gradio = props.gradio ? props.gradio : new Gradio(props); const updateProps = (updatedProps: Partial

) => { gradio.update(updatedProps); }; - - const getComponentProps = () => - omitUndefinedProps( + const getComponentProps = () => { + const originalProps = props.props; + const originalSharedProps = props.shared_props; + return omitUndefinedProps( omit( { + ...gradio.props, + label: gradio.shared.label, + ...(enableI18n + ? {} + : gradioTranslatableProps.reduce( + (acc, key) => { + if (originalProps[key] !== undefined) { + acc[key] = originalProps[key]; + } else if (originalSharedProps[key] !== undefined) { + acc[key] = originalSharedProps[key]; + } + return acc; + }, + {} as Record + )), elem_id: gradio.shared.elem_id as string | undefined, elem_classes: gradio.shared.elem_classes as | string @@ -349,15 +382,14 @@ export function getProps< elem_style: gradio.props.elem_style as React.CSSProperties, visible: gradio.shared.visible, attached_events: gradio.shared.attached_events, - as_item: gradio.props.as_item as string | undefined, - _internal: gradio.props._internal as {}, loading_status: gradio.shared.loading_status, - ...gradio.props, - label: gradio.shared.label, + as_item: gradio.props.as_item as string | undefined, + _internal: props._internal || (gradio.props._internal as {}), }, ['i18n', 'api_url', 'name', 'additional_props'] ) ); + }; let additionalProps = $state( (() => $state.snapshot(gradio.props.additional_props) || {})() as Record< diff --git a/pyproject.toml b/pyproject.toml index 0439a695..ce1bb58b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,8 @@ artifacts = [ "/backend/modelscope_studio/components/antd/dropdown/templates", "/backend/modelscope_studio/components/antd/dropdown/button/templates", "/backend/modelscope_studio/components/antd/flex/templates", + "/backend/modelscope_studio/components/antd/masonry/templates", + "/backend/modelscope_studio/components/antd/masonry/item/templates", "/backend/modelscope_studio/components/antd/layout/templates", "/backend/modelscope_studio/components/antd/layout/content/templates", "/backend/modelscope_studio/components/antd/layout/footer/templates", From e4bff150737548b63759097ab3cb199a2541174f Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 15 Apr 2026 16:13:30 +0800 Subject: [PATCH 22/31] chore: antd properties 5.x => 6.3.5 --- .../components/antd/__init__.py | 8 +- .../components/antd/alert/__init__.py | 8 +- .../components/antd/auto_complete/__init__.py | 5 + .../components/antd/breadcrumb/__init__.py | 4 +- .../components/antd/button/__init__.py | 2 + .../components/antd/carousel/__init__.py | 3 + .../components/antd/cascader/__init__.py | 16 +-- .../antd/cascader/panel/__init__.py | 4 +- .../components/antd/collapse/__init__.py | 2 + .../components/antd/components.py | 2 + .../components/antd/date_picker/__init__.py | 2 + .../components/antd/divider/__init__.py | 18 +--- .../components/antd/drawer/__init__.py | 17 ++- .../components/antd/flex/__init__.py | 2 + .../components/antd/input_number/__init__.py | 2 + .../components/antd/masonry/__init__.py | 1 + .../components/antd/menu/__init__.py | 4 +- .../components/antd/message/__init__.py | 2 + .../components/antd/modal/__init__.py | 2 + .../components/antd/modal/static/__init__.py | 2 + .../components/antd/notification/__init__.py | 9 +- .../components/antd/pagination/__init__.py | 2 +- .../components/antd/progress/__init__.py | 3 + .../components/antd/qr_code/__init__.py | 2 + .../components/antd/radio/group/__init__.py | 2 + .../components/antd/rate/__init__.py | 6 +- .../components/antd/segmented/__init__.py | 2 + .../antd/segmented/option/__init__.py | 2 + .../components/antd/select/__init__.py | 5 +- .../components/antd/slider/__init__.py | 4 +- .../components/antd/space/__init__.py | 8 +- .../components/antd/splitter/__init__.py | 12 ++- .../components/antd/steps/__init__.py | 4 +- .../components/antd/tabs/__init__.py | 3 + .../components/antd/tag/__init__.py | 6 ++ .../antd/tag/checkable_tag_group/__init__.py | 101 ++++++++++++++++++ .../checkable_tag_group/option/__init__.py | 61 +++++++++++ .../components/antd/timeline/__init__.py | 8 +- .../components/antd/timeline/item/__init__.py | 18 ++-- .../components/antd/tour/__init__.py | 2 + .../components/antd/transfer/__init__.py | 4 +- .../components/antd/upload/__init__.py | 2 +- .../antd/upload/dragger/__init__.py | 2 +- .../components/antd/watermark/__init__.py | 8 +- .../components/antdx/attachments/__init__.py | 2 +- .../pro/multimodal_input/__init__.py | 4 +- .../antdx/bubble/demos/bubble_list.py | 1 + frontend/antd/alert/alert.tsx | 16 ++- frontend/antd/auto-complete/Index.svelte | 3 +- frontend/antd/auto-complete/auto-complete.tsx | 23 ++++ frontend/antd/breadcrumb/breadcrumb.tsx | 9 +- frontend/antd/cascader/cascader.tsx | 10 +- .../antd/cascader/panel/cascader.panel.tsx | 10 +- frontend/antd/drawer/Index.svelte | 53 +++++---- frontend/antd/menu/menu.tsx | 17 ++- frontend/antd/notification/notification.tsx | 16 ++- frontend/antd/rate/rate.tsx | 1 + frontend/antd/splitter/Index.svelte | 2 + .../antd/tag/checkable-tag-group/Index.svelte | 78 ++++++++++++++ .../antd/tag/checkable-tag-group/context.ts | 6 ++ .../tag/checkable-tag-group/gradio.config.js | 3 + .../checkable-tag-group/option/Index.svelte | 73 +++++++++++++ .../option/checkable-tag-group.option.tsx | 13 +++ .../option/gradio.config.js | 3 + .../checkable-tag-group/option/package.json | 14 +++ .../antd/tag/checkable-tag-group/package.json | 14 +++ .../tag.checkable-tag-group.tsx | 50 +++++++++ frontend/antd/timeline/item/Index.svelte | 17 +-- frontend/antd/transfer/transfer.tsx | 9 ++ .../antd/upload/dragger/upload.dragger.tsx | 14 +++ frontend/antd/upload/upload.tsx | 14 +++ frontend/antdx/attachments/attachments.tsx | 14 +++ .../pro/multimodal-input/multimodal-input.tsx | 14 +++ 73 files changed, 781 insertions(+), 104 deletions(-) create mode 100644 backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py create mode 100644 backend/modelscope_studio/components/antd/tag/checkable_tag_group/option/__init__.py create mode 100644 frontend/antd/tag/checkable-tag-group/Index.svelte create mode 100644 frontend/antd/tag/checkable-tag-group/context.ts create mode 100644 frontend/antd/tag/checkable-tag-group/gradio.config.js create mode 100644 frontend/antd/tag/checkable-tag-group/option/Index.svelte create mode 100644 frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx create mode 100644 frontend/antd/tag/checkable-tag-group/option/gradio.config.js create mode 100644 frontend/antd/tag/checkable-tag-group/option/package.json create mode 100644 frontend/antd/tag/checkable-tag-group/package.json create mode 100644 frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx diff --git a/backend/modelscope_studio/components/antd/__init__.py b/backend/modelscope_studio/components/antd/__init__.py index 70b72749..e4ade5ad 100644 --- a/backend/modelscope_studio/components/antd/__init__.py +++ b/backend/modelscope_studio/components/antd/__init__.py @@ -70,10 +70,10 @@ from .list import AntdList as List from .list.item import AntdListItem as ListItem from .list.item.meta import AntdListItemMeta as ListItemMeta -from .mentions import AntdMentions as Mentions -from .mentions.option import AntdMentionsOption as MentionsOption from .masonry import AntdMasonry as Masonry from .masonry.item import AntdMasonryItem as MasonryItem +from .mentions import AntdMentions as Mentions +from .mentions.option import AntdMentionsOption as MentionsOption from .menu import AntdMenu as Menu from .menu.item import AntdMenuItem as MenuItem from .message import AntdMessage as Message @@ -125,6 +125,10 @@ from .tabs.item import AntdTabsItem as TabsItem from .tag import AntdTag as Tag from .tag.checkable_tag import AntdTagCheckableTag as TagCheckableTag +from .tag.checkable_tag_group import \ + AntdTagCheckableTagGroup as TagCheckableTagGroup +from .tag.checkable_tag_group.option import \ + AntdTagCheckableTagGroupOption as TagCheckableTagGroupOption from .time_picker import AntdTimePicker as TimePicker from .time_picker.range_picker import \ AntdTimePickerRangePicker as TimePickerRangePicker diff --git a/backend/modelscope_studio/components/antd/alert/__init__.py b/backend/modelscope_studio/components/antd/alert/__init__.py index 2aa85bd1..fe3df16f 100644 --- a/backend/modelscope_studio/components/antd/alert/__init__.py +++ b/backend/modelscope_studio/components/antd/alert/__init__.py @@ -16,7 +16,13 @@ class AntdAlert(ModelScopeLayoutComponent): EVENTS = [ EventListener("close", callback=lambda block: block._internal.update( - bind_close_event=True)) + bind_close_event=True)), + EventListener("click", + callback=lambda block: block._internal.update( + bind_click_event=True)), + EventListener("closable_close", + callback=lambda block: block._internal.update( + bind_closable_close_event=True)) ] # supported slots diff --git a/backend/modelscope_studio/components/antd/auto_complete/__init__.py b/backend/modelscope_studio/components/antd/auto_complete/__init__.py index f37f03f9..a451aedb 100644 --- a/backend/modelscope_studio/components/antd/auto_complete/__init__.py +++ b/backend/modelscope_studio/components/antd/auto_complete/__init__.py @@ -40,6 +40,9 @@ class AntdAutoComplete(ModelScopeDataLayoutComponent): EventListener("popup_visible_change", callback=lambda block: block._internal.update( bind_popupVisibleChange_event=True)), + EventListener("show_search_search", + callback=lambda block: block._internal.update( + bind_showSearch_search_event=True)), ] # supported slots @@ -76,6 +79,7 @@ def __init__( status: Literal['error', 'warning'] | None = None, variant: Literal['outlined', 'borderless', 'filled'] | None = None, + show_search: bool | dict | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, root_class_name: str | None = None, @@ -118,6 +122,7 @@ def __init__( self.variant = variant self.placement = placement self.size = size + self.show_search = show_search self.class_names = class_names self.styles = styles self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/breadcrumb/__init__.py b/backend/modelscope_studio/components/antd/breadcrumb/__init__.py index cafd714d..64842e5a 100644 --- a/backend/modelscope_studio/components/antd/breadcrumb/__init__.py +++ b/backend/modelscope_studio/components/antd/breadcrumb/__init__.py @@ -15,7 +15,7 @@ class AntdBreadcrumb(ModelScopeLayoutComponent): EVENTS = [] # supported slots - SLOTS = ['separator', 'itemRender', 'items'] + SLOTS = ['separator', 'itemRender', 'items', 'dropdownIcon'] def __init__( self, @@ -25,6 +25,7 @@ def __init__( params: dict | None = None, items: list[dict] | None = None, separator: str | None = None, + dropdown_icon: str | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -52,6 +53,7 @@ def __init__( self.items = items self.separator = separator self.root_class_name = root_class_name + self.dropdown_icon = dropdown_icon FRONTEND_DIR = resolve_frontend_dir("breadcrumb") diff --git a/backend/modelscope_studio/components/antd/button/__init__.py b/backend/modelscope_studio/components/antd/button/__init__.py index 8217a8bf..c730d459 100644 --- a/backend/modelscope_studio/components/antd/button/__init__.py +++ b/backend/modelscope_studio/components/antd/button/__init__.py @@ -63,6 +63,7 @@ def __init__( html_type: Literal["button", "submit", "reset"] | None = None, icon: str | None = None, icon_position: Literal["start", "end"] | None = None, + icon_placement: Literal["start", "end"] | None = None, loading: bool | dict | None = None, shape: Literal["default", "circle", "round"] | None = None, size: Literal["large", "middle", "small"] | None = None, @@ -124,6 +125,7 @@ def __init__( self.html_type = html_type self.icon = icon self.icon_position = icon_position + self.icon_placement = icon_placement self.loading = loading self.shape = shape self.size = size diff --git a/backend/modelscope_studio/components/antd/carousel/__init__.py b/backend/modelscope_studio/components/antd/carousel/__init__.py index e06e534d..1b5ac697 100644 --- a/backend/modelscope_studio/components/antd/carousel/__init__.py +++ b/backend/modelscope_studio/components/antd/carousel/__init__.py @@ -22,6 +22,8 @@ def __init__( adaptive_height: bool | None = None, dot_position: Literal['top', 'bottom', 'left', 'right'] | None = 'bottom', + dot_placement: Literal['top', 'bottom', 'start', 'end'] + | None = None, dots: bool | dict | None = True, draggable: bool | None = None, fade: bool | None = None, @@ -59,6 +61,7 @@ def __init__( self.autoplay_speed = autoplay_speed self.adaptive_height = adaptive_height self.dot_position = dot_position + self.dot_placement = dot_placement self.dots = dots self.draggable = draggable self.fade = fade diff --git a/backend/modelscope_studio/components/antd/cascader/__init__.py b/backend/modelscope_studio/components/antd/cascader/__init__.py index afd26e35..bb783a5c 100644 --- a/backend/modelscope_studio/components/antd/cascader/__init__.py +++ b/backend/modelscope_studio/components/antd/cascader/__init__.py @@ -37,18 +37,10 @@ class AntdCascader(ModelScopeDataLayoutComponent): # supported slots SLOTS = [ - 'allowClear.clearIcon', - 'suffixIcon', - 'maxTagPlaceholder', - 'notFoundContent', - 'expandIcon', - 'removeIcon', - 'prefix', - 'displayRender', - 'tagRender', - 'dropdownRender', - 'popupRender' - 'showSearch.render', + 'allowClear.clearIcon', 'suffixIcon', 'maxTagPlaceholder', + 'notFoundContent', 'expandIcon', 'removeIcon', 'prefix', + 'displayRender', 'tagRender', 'dropdownRender', 'popupRender' + 'showSearch.render', 'optionRender' ] def __init__( diff --git a/backend/modelscope_studio/components/antd/cascader/panel/__init__.py b/backend/modelscope_studio/components/antd/cascader/panel/__init__.py index 5f891756..03c438a7 100644 --- a/backend/modelscope_studio/components/antd/cascader/panel/__init__.py +++ b/backend/modelscope_studio/components/antd/cascader/panel/__init__.py @@ -23,7 +23,7 @@ class AntdCascaderPanel(ModelScopeDataLayoutComponent): ] # supported slots - SLOTS = ['notFoundContent', 'expandIcon'] + SLOTS = ['notFoundContent', 'expandIcon', 'optionRender'] def __init__( self, @@ -40,6 +40,7 @@ def __init__( multiple: bool | None = None, show_checked_strategy: Literal['SHOW_PARENT', 'SHOW_CHILD'] | None = None, + option_render: str | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -73,6 +74,7 @@ def __init__( self.multiple = multiple self.show_checked_strategy = show_checked_strategy self.root_class_name = root_class_name + self.option_render = option_render FRONTEND_DIR = resolve_frontend_dir("cascader", "panel") diff --git a/backend/modelscope_studio/components/antd/collapse/__init__.py b/backend/modelscope_studio/components/antd/collapse/__init__.py index 819a24e1..ee6f9bea 100644 --- a/backend/modelscope_studio/components/antd/collapse/__init__.py +++ b/backend/modelscope_studio/components/antd/collapse/__init__.py @@ -38,6 +38,7 @@ def __init__( destroy_on_hidden: bool | None = None, expand_icon: str | None = None, expand_icon_position: Literal['start', 'end'] | None = None, + expand_icon_placement: Literal['start', 'end'] | None = None, ghost: bool | None = None, items: list[dict] | None = None, size: Literal['large', 'middle', 'small'] | None = None, @@ -72,6 +73,7 @@ def __init__( self.destroy_inactive_panel = destroy_inactive_panel self.expand_icon = expand_icon self.expand_icon_position = expand_icon_position + self.expand_icon_placement = expand_icon_placement self.ghost = ghost self.items = items self.size = size diff --git a/backend/modelscope_studio/components/antd/components.py b/backend/modelscope_studio/components/antd/components.py index 424f11b3..2a721e34 100644 --- a/backend/modelscope_studio/components/antd/components.py +++ b/backend/modelscope_studio/components/antd/components.py @@ -121,6 +121,8 @@ from .tabs.item import AntdTabsItem from .tag import AntdTag from .tag.checkable_tag import AntdTagCheckableTag +from .tag.checkable_tag_group import AntdTagCheckableTagGroup +from .tag.checkable_tag_group.option import AntdTagCheckableTagGroupOption from .time_picker import AntdTimePicker from .time_picker.range_picker import AntdTimePickerRangePicker from .timeline import AntdTimeline diff --git a/backend/modelscope_studio/components/antd/date_picker/__init__.py b/backend/modelscope_studio/components/antd/date_picker/__init__.py index 4ff4e3ca..e1e32930 100644 --- a/backend/modelscope_studio/components/antd/date_picker/__init__.py +++ b/backend/modelscope_studio/components/antd/date_picker/__init__.py @@ -97,6 +97,7 @@ def __init__( show_now: bool | None = None, show_time: bool | dict | None = None, show_week: bool | None = None, + preview_value: bool | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -162,6 +163,7 @@ def __init__( self.show_now = show_now self.show_time = show_time self.show_week = show_week + self.preview_value = preview_value self.root_class_name = root_class_name FRONTEND_DIR = resolve_frontend_dir("date-picker") diff --git a/backend/modelscope_studio/components/antd/divider/__init__.py b/backend/modelscope_studio/components/antd/divider/__init__.py index 7cebe7b6..b36c37bc 100644 --- a/backend/modelscope_studio/components/antd/divider/__init__.py +++ b/backend/modelscope_studio/components/antd/divider/__init__.py @@ -25,12 +25,13 @@ def __init__( *, dashed: bool | None = None, variant: Literal["dashed", "dotted", "solid"] = "solid", - orientation: Literal["left", "right", "center", "start", - "end"] = "center", + orientation: Literal["horizontal", "vertical"] = "horizontal", orientation_margin: str | int | float | None = None, plain: bool | None = None, type: Literal["horizontal", "vertical"] = "horizontal", size: Literal["small", "middle", "large"] | None = None, + title_placement: Literal["start", "end", "center"] | None = None, + vertical: bool | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -43,17 +44,6 @@ def __init__( elem_style: dict | None = None, render: bool = True, **kwargs): - """ - Parameters: - value: The wrapped title. - dashed: Whether line is dashed. - variant: Whether line is dashed, dotted or solid. - orientation: The position of title inside divider. - orientation_margin: The margin-left/right between the title and its closest border, while the orientation must be left or right, If a numeric value of type string is provided without a unit, it is assumed to be in pixels (px) by default. - plain: Divider text show as plain style. - type: The direction type of divider. - size: The size of divider. Only valid for horizontal layout. - """ super().__init__(visible=visible, elem_id=elem_id, elem_classes=elem_classes, @@ -69,6 +59,8 @@ def __init__( self.variant = variant self.orientation = orientation self.orientation_margin = orientation_margin + self.title_placement = title_placement + self.vertical = vertical self.plain = plain self.type = type self.size = size diff --git a/backend/modelscope_studio/components/antd/drawer/__init__.py b/backend/modelscope_studio/components/antd/drawer/__init__.py index 60893a4c..1dd4e3f6 100644 --- a/backend/modelscope_studio/components/antd/drawer/__init__.py +++ b/backend/modelscope_studio/components/antd/drawer/__init__.py @@ -14,7 +14,16 @@ class AntdDrawer(ModelScopeLayoutComponent): EVENTS = [ EventListener("close", callback=lambda block: block._internal.update( - bind_close_event=True)) + bind_close_event=True)), + EventListener("resizable_resize_start", + callback=lambda block: block._internal.update( + bind_resizable_resizeStart_event=True)), + EventListener("resizable_resize", + callback=lambda block: block._internal.update( + bind_resizable_resize_event=True)), + EventListener("resizable_resize_end", + callback=lambda block: block._internal.update( + bind_resizable_resizeEnd_event=True)) ] # supported slots @@ -35,6 +44,7 @@ def __init__( closable: bool | dict | None = None, destroy_on_close: bool | None = None, destroy_on_hidden: bool | None = None, + draggable: bool | None = None, extra: str | None = None, footer: str | None = None, force_render: bool | None = None, @@ -45,6 +55,8 @@ def __init__( mask_closable: bool | None = None, placement: Literal['left', 'right', 'top', 'bottom'] | None = None, push: bool | dict | None = None, + resizable: bool | dict | None = None, + focusable: dict | None = None, size: Literal['default', 'large'] | None = None, styles: dict | str | None = None, title: str | None = None, @@ -80,6 +92,8 @@ def __init__( self.class_names = class_names self.destroy_on_close = destroy_on_close self.destroy_on_hidden = destroy_on_hidden + self.draggable = draggable + self.focusable = focusable self.extra = extra self.footer = footer self.force_render = force_render @@ -90,6 +104,7 @@ def __init__( self.mask_closable = mask_closable self.placement = placement self.push = push + self.resizable = resizable self.size = size self.styles = styles self.title = title diff --git a/backend/modelscope_studio/components/antd/flex/__init__.py b/backend/modelscope_studio/components/antd/flex/__init__.py index 6e8b649a..c2a75c70 100644 --- a/backend/modelscope_studio/components/antd/flex/__init__.py +++ b/backend/modelscope_studio/components/antd/flex/__init__.py @@ -22,6 +22,7 @@ def __init__( self, additional_props: dict | None = None, *, + orientation: Literal['horizontal', 'vertical'] | None = None, vertical: bool | None = None, wrap: Literal['nowrap', 'wrap', 'wrap-reverse'] | bool = "nowrap", justify: Literal['normal', 'start', 'end', 'flex-start', @@ -67,6 +68,7 @@ def __init__( self.class_names = class_names self.styles = styles self.additional_props = additional_props + self.orientation = orientation self.vertical = vertical self.wrap = wrap self.justify = justify diff --git a/backend/modelscope_studio/components/antd/input_number/__init__.py b/backend/modelscope_studio/components/antd/input_number/__init__.py index 401973f4..c2726aa1 100644 --- a/backend/modelscope_studio/components/antd/input_number/__init__.py +++ b/backend/modelscope_studio/components/antd/input_number/__init__.py @@ -54,6 +54,7 @@ def __init__( keyboard: bool = True, max: int | float | None = None, min: int | float | None = None, + mode: Literal['default', 'spinner'] | None = None, parser: str | None = None, precision: int | float | None = None, prefix: str | None = None, @@ -102,6 +103,7 @@ def __init__( self.keyboard = keyboard self.max = max self.min = min + self.mode = mode self.parser = parser self.precision = precision self.prefix = prefix diff --git a/backend/modelscope_studio/components/antd/masonry/__init__.py b/backend/modelscope_studio/components/antd/masonry/__init__.py index 8ec8ae22..5a5130b3 100644 --- a/backend/modelscope_studio/components/antd/masonry/__init__.py +++ b/backend/modelscope_studio/components/antd/masonry/__init__.py @@ -1,6 +1,7 @@ from __future__ import annotations from typing import Any + from gradio.events import EventListener from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir diff --git a/backend/modelscope_studio/components/antd/menu/__init__.py b/backend/modelscope_studio/components/antd/menu/__init__.py index f8729c6f..af5a223a 100644 --- a/backend/modelscope_studio/components/antd/menu/__init__.py +++ b/backend/modelscope_studio/components/antd/menu/__init__.py @@ -31,7 +31,7 @@ class AntdMenu(ModelScopeLayoutComponent): ] # supported slots - SLOTS = ["expandIcon", 'overflowedIndicator', "items"] + SLOTS = ["expandIcon", 'overflowedIndicator', "items", 'popupRender'] def __init__( self, @@ -56,6 +56,7 @@ def __init__( theme: Literal['light', 'dark'] | None = None, theme_value: Literal['light', 'dark'] | None = None, trigger_sub_menu_action: Literal['click', 'hover'] = 'hover', + popup_render: str | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -94,6 +95,7 @@ def __init__( self.sub_menu_close_delay = sub_menu_close_delay self.sub_menu_open_delay = sub_menu_open_delay self.theme = theme + self.popup_render = popup_render if theme: warnings.warn( """[antd.Menu.Item]: the `theme` property conflicts with Gradio's preset properties. Please use `theme_value` instead.""" diff --git a/backend/modelscope_studio/components/antd/message/__init__.py b/backend/modelscope_studio/components/antd/message/__init__.py index 08339b56..73006166 100644 --- a/backend/modelscope_studio/components/antd/message/__init__.py +++ b/backend/modelscope_studio/components/antd/message/__init__.py @@ -33,6 +33,7 @@ def __init__( duration: float | int | None = None, icon: str | None = None, key: str | int | float | None = None, + pause_on_hover: bool | None = None, get_container: str | None = None, rtl: bool | None = None, top: int | float | None = None, @@ -62,6 +63,7 @@ def __init__( self.icon = icon self.type = type self.key = key + self.pause_on_hover = pause_on_hover self.get_container = get_container self.rtl = rtl self.top = top diff --git a/backend/modelscope_studio/components/antd/modal/__init__.py b/backend/modelscope_studio/components/antd/modal/__init__.py index cdcca0ff..af757942 100644 --- a/backend/modelscope_studio/components/antd/modal/__init__.py +++ b/backend/modelscope_studio/components/antd/modal/__init__.py @@ -47,6 +47,7 @@ def __init__( destroy_on_close: bool | None = None, destroy_on_hidden: bool | None = None, focus_trigger_after_close: bool | None = None, + focusable: dict | None = None, footer: str | Literal['DEFAULT_FOOTER'] | None = "DEFAULT_FOOTER", force_render: bool | None = None, get_container: str | None = None, @@ -94,6 +95,7 @@ def __init__( self.destroy_on_close = destroy_on_close self.destroy_on_hidden = destroy_on_hidden self.focus_trigger_after_close = focus_trigger_after_close + self.focusable = focusable self.footer = footer self.force_render = force_render self.get_container = get_container diff --git a/backend/modelscope_studio/components/antd/modal/static/__init__.py b/backend/modelscope_studio/components/antd/modal/static/__init__.py index 209d9eeb..534ed4b2 100644 --- a/backend/modelscope_studio/components/antd/modal/static/__init__.py +++ b/backend/modelscope_studio/components/antd/modal/static/__init__.py @@ -45,6 +45,7 @@ def __init__( confirm_loading: bool | None = None, destroy_on_close: bool | None = None, focus_trigger_after_close: bool | None = None, + focusable: dict | None = None, content: str | None = None, footer: str | None = None, force_render: bool | None = None, @@ -92,6 +93,7 @@ def __init__( self.close_icon = close_icon self.confirm_loading = confirm_loading self.destroy_on_close = destroy_on_close + self.focusable = focusable self.focus_trigger_after_close = focus_trigger_after_close self.content = content self.footer = footer diff --git a/backend/modelscope_studio/components/antd/notification/__init__.py b/backend/modelscope_studio/components/antd/notification/__init__.py index 2264981c..8d745fb9 100644 --- a/backend/modelscope_studio/components/antd/notification/__init__.py +++ b/backend/modelscope_studio/components/antd/notification/__init__.py @@ -21,7 +21,10 @@ class AntdNotification(ModelScopeLayoutComponent): ] # supported slots - SLOTS = ['actions', 'closeIcon', "description", "icon", "message"] + SLOTS = [ + 'actions', 'closable.closeIcon', 'closeIcon', "description", "icon", + "message", "title" + ] def __init__( self, @@ -29,8 +32,10 @@ def __init__( description: str | None = "", additional_props: dict | None = None, *, + title: str | None = None, type: Literal['success', 'info', 'warning', 'error'] | None = None, btn: str | None = None, + closable: bool | dict | None = None, close_icon: str | bool | None = None, duration: int | float | None = 4.5, show_progress: bool | None = None, @@ -68,9 +73,11 @@ def __init__( self.styles = styles self.additional_props = additional_props self.message = message + self.title = title self.type = type self.description = description self.btn = btn + self.closable = closable self.close_icon = close_icon self.duration = duration self.show_progress = show_progress diff --git a/backend/modelscope_studio/components/antd/pagination/__init__.py b/backend/modelscope_studio/components/antd/pagination/__init__.py index 5de41ff6..d39812ce 100644 --- a/backend/modelscope_studio/components/antd/pagination/__init__.py +++ b/backend/modelscope_studio/components/antd/pagination/__init__.py @@ -43,7 +43,7 @@ def __init__( show_title: bool = True, show_total: str | None = None, simple: bool | dict | None = None, - size: Literal['small', 'default'] | None = None, + size: Literal['small', 'medium', 'large'] | None = None, total: int = 0, root_class_name: str | None = None, class_names: dict | str | None = None, diff --git a/backend/modelscope_studio/components/antd/progress/__init__.py b/backend/modelscope_studio/components/antd/progress/__init__.py index 4d35f26e..7e847422 100644 --- a/backend/modelscope_studio/components/antd/progress/__init__.py +++ b/backend/modelscope_studio/components/antd/progress/__init__.py @@ -36,6 +36,8 @@ def __init__( stroke_width: int | float | None = None, gap_degree: int | float | None = None, gap_position: Literal['top', 'bottom', 'left', 'right'] + | None = None, + gap_placement: Literal['top', 'bottom', 'left', 'right'] | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, @@ -75,6 +77,7 @@ def __init__( self.stroke_width = stroke_width self.gap_degree = gap_degree self.gap_position = gap_position + self.gap_placement = gap_placement self.root_class_name = root_class_name FRONTEND_DIR = resolve_frontend_dir("progress") diff --git a/backend/modelscope_studio/components/antd/qr_code/__init__.py b/backend/modelscope_studio/components/antd/qr_code/__init__.py index d9694bd9..ee52208c 100644 --- a/backend/modelscope_studio/components/antd/qr_code/__init__.py +++ b/backend/modelscope_studio/components/antd/qr_code/__init__.py @@ -34,6 +34,7 @@ def __init__( error_level: Literal['L', 'M', 'Q', 'H'] | None = 'M', icon: str | None = None, icon_size: int | dict | None = 40, + margin_size: int | float | None = None, size: int = 160, status: Literal['active', 'expired', 'loading', 'scanned'] | None = 'active', @@ -69,6 +70,7 @@ def __init__( self.error_level = error_level self.icon = icon self.icon_size = icon_size + self.margin_size = margin_size self.size = size self.status = status self.status_render = status_render diff --git a/backend/modelscope_studio/components/antd/radio/group/__init__.py b/backend/modelscope_studio/components/antd/radio/group/__init__.py index 0682ebdb..66bbf482 100644 --- a/backend/modelscope_studio/components/antd/radio/group/__init__.py +++ b/backend/modelscope_studio/components/antd/radio/group/__init__.py @@ -36,6 +36,7 @@ def __init__( option_type: Literal['default', 'button'] | None = None, size: Literal['small', 'middle', 'large'] | None = None, block: bool | None = None, + vertical: bool | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -68,6 +69,7 @@ def __init__( self.size = size self.block = block self.root_class_name = root_class_name + self.vertical = vertical FRONTEND_DIR = resolve_frontend_dir("radio", "group") diff --git a/backend/modelscope_studio/components/antd/rate/__init__.py b/backend/modelscope_studio/components/antd/rate/__init__.py index 1a06830e..5b5615b8 100644 --- a/backend/modelscope_studio/components/antd/rate/__init__.py +++ b/backend/modelscope_studio/components/antd/rate/__init__.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any +from typing import Any, Literal from gradio.events import EventListener @@ -47,7 +47,8 @@ def __init__( default_value: int | float | None = None, disabled: bool | None = None, keyboard: bool | None = None, - tooltips: list[str] | None = None, + size: Literal['default', 'small', 'large'] | None = None, + tooltips: list[str] | list[dict] | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -79,6 +80,7 @@ def __init__( self.default_value = default_value self.disabled = disabled self.keyboard = keyboard + self.size = size self.tooltips = tooltips self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/segmented/__init__.py b/backend/modelscope_studio/components/antd/segmented/__init__.py index eaf57429..eaa5ba0d 100644 --- a/backend/modelscope_studio/components/antd/segmented/__init__.py +++ b/backend/modelscope_studio/components/antd/segmented/__init__.py @@ -36,6 +36,7 @@ def __init__( size: Literal['large', 'middle', 'small'] | None = None, shape: Literal['default', 'round'] | None = None, form_name: str | None = None, + orientation: Literal['horizontal', 'vertical'] | None = None, vertical: bool | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, @@ -67,6 +68,7 @@ def __init__( self.size = size self.form_name = form_name self.shape = shape + self.orientation = orientation self.vertical = vertical self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/segmented/option/__init__.py b/backend/modelscope_studio/components/antd/segmented/option/__init__.py index 6864acb4..c375d841 100644 --- a/backend/modelscope_studio/components/antd/segmented/option/__init__.py +++ b/backend/modelscope_studio/components/antd/segmented/option/__init__.py @@ -21,6 +21,7 @@ def __init__( value: str | int | float | None = None, additional_props: dict | None = None, *, + tooltip: str | dict | None = None, icon: str | None = None, disabled: bool | None = None, as_item: str | None = None, @@ -42,6 +43,7 @@ def __init__( self.label = label self.value = value self.additional_props = additional_props + self.tooltip = tooltip self.icon = icon self.disabled = disabled diff --git a/backend/modelscope_studio/components/antd/select/__init__.py b/backend/modelscope_studio/components/antd/select/__init__.py index d5e58dc5..3f5c35ba 100644 --- a/backend/modelscope_studio/components/antd/select/__init__.py +++ b/backend/modelscope_studio/components/antd/select/__init__.py @@ -43,6 +43,9 @@ class AntdSelect(ModelScopeDataLayoutComponent): EventListener("popup_visible_change", callback=lambda block: block._internal.update( bind_popupVisibleChange_event=True)), + EventListener("active", + callback=lambda block: block._internal.update( + bind_active_event=True)), ] # supported slots @@ -86,7 +89,7 @@ def __init__( mode: Literal['multiple', 'tags'] | None = None, not_found_content: str | None = None, open: bool | None = None, - option_filter_prop: str | None = None, + option_filter_prop: str | list[str] | None = None, option_label_prop: str | None = None, options: list[dict] | None = None, option_render: str | None = None, diff --git a/backend/modelscope_studio/components/antd/slider/__init__.py b/backend/modelscope_studio/components/antd/slider/__init__.py index 48200244..c042f339 100644 --- a/backend/modelscope_studio/components/antd/slider/__init__.py +++ b/backend/modelscope_studio/components/antd/slider/__init__.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any +from typing import Any, Literal from gradio.events import EventListener @@ -49,6 +49,7 @@ def __init__( step: int | float | None = 1, styles: dict | str | None = None, tooltip: dict | None = None, + orientation: Literal['horizontal', 'vertical'] | None = None, vertical: bool | None = None, root_class_name: str | None = None, as_item: str | None = None, @@ -84,6 +85,7 @@ def __init__( self.step = step self.styles = styles self.tooltip = tooltip + self.orientation = orientation self.vertical = vertical self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/space/__init__.py b/backend/modelscope_studio/components/antd/space/__init__.py index f7d9868c..37bd6f6c 100644 --- a/backend/modelscope_studio/components/antd/space/__init__.py +++ b/backend/modelscope_studio/components/antd/space/__init__.py @@ -34,11 +34,13 @@ def __init__( align: Literal['start', 'end', 'center', 'baseline'] | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, - direction: Literal['vertical', 'horizontal'] | None = 'horizontal', + direction: Literal['vertical', 'horizontal'] | None = None, + orientation: Literal['vertical', 'horizontal'] | None = None, size: Literal['small', 'middle', 'large'] | int | float | list[Literal['small', 'middle', 'large'] | int | float] | None = None, split: str | None = None, + separator: str | None = None, wrap: bool | None = None, root_class_name: str | None = None, as_item: str | None = None, @@ -55,8 +57,10 @@ def __init__( align: Align items. class_names: dict | str | None direction: The space direction. + orientation: The space orientation (v6 alias for direction). size: The space size. split: Set split. + separator: Set separator (v6 alias for split). styles: dict | str | None wrap: Auto wrap line, when horizontal effective. """ @@ -72,8 +76,10 @@ def __init__( self.class_names = class_names self.styles = styles self.direction = direction + self.orientation = orientation self.size = size self.split = split + self.separator = separator self.wrap = wrap self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/splitter/__init__.py b/backend/modelscope_studio/components/antd/splitter/__init__.py index dac10570..85e9ca90 100644 --- a/backend/modelscope_studio/components/antd/splitter/__init__.py +++ b/backend/modelscope_studio/components/antd/splitter/__init__.py @@ -36,6 +36,10 @@ class AntdSplitter(ModelScopeLayoutComponent): doc="Callback when expanding or collapsing.", callback=lambda block: block._internal.update( bind_collapse_event=True)), + EventListener("dragger_double_click", + doc="Callback when dragger double clicked.", + callback=lambda block: block._internal.update( + bind_draggerDoubleClick_event=True)), ] def __init__( @@ -43,6 +47,8 @@ def __init__( additional_props: dict | None = None, *, layout: Literal['horizontal', 'vertical'] | None = 'horizontal', + orientation: Literal['horizontal', 'vertical'] | None = None, + vertical: bool | None = None, lazy: bool | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, @@ -56,10 +62,6 @@ def __init__( elem_style: dict | None = None, render: bool = True, **kwargs): - """ - Parameters: - layout: Layout direction. - """ super().__init__(visible=visible, elem_id=elem_id, elem_classes=elem_classes, @@ -71,6 +73,8 @@ def __init__( self.styles = styles self.additional_props = additional_props self.layout = layout + self.vertical = vertical + self.orientation = orientation self.lazy = lazy self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/steps/__init__.py b/backend/modelscope_studio/components/antd/steps/__init__.py index 52a65951..5ae34c59 100644 --- a/backend/modelscope_studio/components/antd/steps/__init__.py +++ b/backend/modelscope_studio/components/antd/steps/__init__.py @@ -29,7 +29,8 @@ def __init__( current: int = 0, direction: Literal['vertical', 'horizontal'] = "horizontal", initial: int = 0, - label_placement: Literal['horizontal', 'vertical'] = 'horizontal', + label_placement: Literal['horizontal', 'vertical'] | None = None, + title_placement: Literal['horizontal', 'vertical'] | None = None, percent: int | None = None, progress_dot: bool | str = False, responsive: bool = True, @@ -63,6 +64,7 @@ def __init__( self.direction = direction self.initial = initial self.label_placement = label_placement + self.title_placement = title_placement self.percent = percent self.progress_dot = progress_dot self.responsive = responsive diff --git a/backend/modelscope_studio/components/antd/tabs/__init__.py b/backend/modelscope_studio/components/antd/tabs/__init__.py index 58872e0a..8c7f8e8c 100644 --- a/backend/modelscope_studio/components/antd/tabs/__init__.py +++ b/backend/modelscope_studio/components/antd/tabs/__init__.py @@ -56,6 +56,8 @@ def __init__( tab_bar_gutter: int | float | None = None, tab_bar_style: dict | None = None, tab_position: Literal["left", "right", "top", "bottom"] + | None = None, + tab_placement: Literal["top", "bottom", "start", "end"] | None = None, destroy_inactive_tab_pane: bool | None = None, destroy_on_hidden: bool | None = None, @@ -99,6 +101,7 @@ def __init__( self.tab_bar_gutter = tab_bar_gutter self.tab_bar_style = tab_bar_style self.tab_position = tab_position + self.tab_placement = tab_placement self.destroy_inactive_tab_pane = destroy_inactive_tab_pane self.destroy_on_hidden = destroy_on_hidden self.type = type diff --git a/backend/modelscope_studio/components/antd/tag/__init__.py b/backend/modelscope_studio/components/antd/tag/__init__.py index 80214ef5..b95812f6 100644 --- a/backend/modelscope_studio/components/antd/tag/__init__.py +++ b/backend/modelscope_studio/components/antd/tag/__init__.py @@ -6,6 +6,7 @@ from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir from .checkable_tag import AntdTagCheckableTag +from .checkable_tag_group import AntdTagCheckableTagGroup class AntdTag(ModelScopeLayoutComponent): @@ -13,6 +14,7 @@ class AntdTag(ModelScopeLayoutComponent): Ant Design: https://ant.design/components/tag """ CheckableTag = AntdTagCheckableTag + CheckableTagGroup = AntdTagCheckableTagGroup EVENTS = [ EventListener("close", @@ -28,6 +30,8 @@ def __init__( value: str | None = None, additional_props: dict | None = None, *, + disabled: bool | None = None, + href: str | None = None, bordered: bool | None = None, close_icon: str | bool | None = None, color: str | None = None, @@ -60,6 +64,8 @@ def __init__( self.color = color self.icon = icon self.root_class_name = root_class_name + self.disabled = disabled + self.href = href FRONTEND_DIR = resolve_frontend_dir("tag") diff --git a/backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py b/backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py new file mode 100644 index 00000000..9fb53d0a --- /dev/null +++ b/backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +from typing import Any + +from gradio.events import EventListener + +from .....utils.dev import ModelScopeDataLayoutComponent, resolve_frontend_dir +from .option import AntdTagCheckableTagGroupOption + + +# as inputs, outputs +class AntdTagCheckableTagGroup(ModelScopeDataLayoutComponent): + """ + Ant Design: https://ant.design/components/tag + """ + Option = AntdTagCheckableTagGroupOption + + EVENTS = [ + EventListener("change", + callback=lambda block: block._internal.update( + bind_change_event=True)), + ] + + # supported slots + SLOTS = ["options"] + + def __init__( + self, + value: int | float | str | list[str | int | float] | None = None, + additional_props: dict | None = None, + *, + options: list[dict | int | float | str] | None = None, + disabled: bool | None = None, + multiple: bool | None = None, + default_value: int | float | str | list[str | int | float] + | None = None, + root_class_name: str | None = None, + class_names: dict | str | None = None, + styles: dict | str | None = None, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(value=value, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.class_names = class_names + self.styles = styles + self.additional_props = additional_props + self.root_class_name = root_class_name + self.options = options + self.disabled = disabled + self.multiple = multiple + self.default_value = default_value + + FRONTEND_DIR = resolve_frontend_dir("tag", 'checkable-tag-group') + + @property + def skip_api(self): + return False + + def api_info(self) -> dict[str, Any]: + return { + "anyOf": [{ + "type": "string" + }, { + "type": "number" + }, { + "type": "array", + "items": { + "anyOf": [{ + "type": "number" + }, { + "type": "string" + }] + } + }] + } + + def preprocess(self, payload: bool | None) -> bool | None: + return payload + + def postprocess(self, value: bool | None) -> bool | None: + + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/backend/modelscope_studio/components/antd/tag/checkable_tag_group/option/__init__.py b/backend/modelscope_studio/components/antd/tag/checkable_tag_group/option/__init__.py new file mode 100644 index 00000000..fd26210f --- /dev/null +++ b/backend/modelscope_studio/components/antd/tag/checkable_tag_group/option/__init__.py @@ -0,0 +1,61 @@ +from __future__ import annotations + +from typing import Any + +from ......utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir + + +class AntdTagCheckableTagGroupOption(ModelScopeLayoutComponent): + """ + Ant Design: https://ant.design/components/tag + """ + + EVENTS = [] + + # supported slots + SLOTS = ["label"] + + def __init__( + self, + value: str | None = None, + label: str | None = None, + additional_props: dict | None = None, + *, + as_item: str | None = None, + _internal: None = None, + # gradio properties + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + elem_style: dict | None = None, + render: bool = True, + **kwargs): + super().__init__(visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + as_item=as_item, + elem_style=elem_style, + **kwargs) + self.additional_props = additional_props + self.value = value + self.label = label + + FRONTEND_DIR = resolve_frontend_dir("tag", + ['checkable-tag-group', 'option']) + + @property + def skip_api(self): + return True + + def preprocess(self, payload: None) -> None: + return payload + + def postprocess(self, value: None) -> None: + return value + + def example_payload(self) -> Any: + return None + + def example_value(self) -> Any: + return None diff --git a/backend/modelscope_studio/components/antd/timeline/__init__.py b/backend/modelscope_studio/components/antd/timeline/__init__.py index 0ab83aec..c1915735 100644 --- a/backend/modelscope_studio/components/antd/timeline/__init__.py +++ b/backend/modelscope_studio/components/antd/timeline/__init__.py @@ -20,9 +20,12 @@ def __init__( self, additional_props: dict | None = None, *, - mode: Literal["left", "alternate", "right"] | None = None, + mode: Literal["start", "alternate", "end"] | None = None, pending: str | bool | None = None, pending_dot: str | None = None, + orientation: Literal["horizontal", "vertical"] | None = None, + title_span: int | float | str | None = None, + variant: Literal["filled", "outlined"] | None = None, reverse: bool | None = None, items: list[dict] | None = None, root_class_name: str | None = None, @@ -51,6 +54,9 @@ def __init__( self.pending = pending self.pending_dot = pending_dot self.reverse = reverse + self.orientation = orientation + self.title_span = title_span + self.variant = variant self.items = items self.root_class_name = root_class_name diff --git a/backend/modelscope_studio/components/antd/timeline/item/__init__.py b/backend/modelscope_studio/components/antd/timeline/item/__init__.py index a42e0769..944258cf 100644 --- a/backend/modelscope_studio/components/antd/timeline/item/__init__.py +++ b/backend/modelscope_studio/components/antd/timeline/item/__init__.py @@ -12,16 +12,18 @@ class AntdTimelineItem(ModelScopeLayoutComponent): EVENTS = [] # supported slots - SLOTS = ['dot', "label", "children"] + SLOTS = ['icon', "content", "title"] def __init__( self, additional_props: dict | None = None, *, color: str | None = None, - dot: str | None = None, - label: str | None = None, - position: Literal["left", "right"] | None = None, + icon: str | None = None, + content: str | None = None, + title: str | None = None, + placement: Literal["start", "end"] | None = None, + loading: bool | None = None, as_item: str | None = None, _internal: None = None, # gradio properties @@ -40,9 +42,11 @@ def __init__( **kwargs) self.additional_props = additional_props self.color = color - self.dot = dot - self.label = label - self.position = position + self.loading = loading + self.icon = icon + self.content = content + self.title = title + self.placement = placement FRONTEND_DIR = resolve_frontend_dir("timeline", "item") diff --git a/backend/modelscope_studio/components/antd/tour/__init__.py b/backend/modelscope_studio/components/antd/tour/__init__.py index 5226a84f..de631e5f 100644 --- a/backend/modelscope_studio/components/antd/tour/__init__.py +++ b/backend/modelscope_studio/components/antd/tour/__init__.py @@ -50,6 +50,7 @@ def __init__( actions_render: str | None = None, z_index: int | None = None, get_popup_container: str | None = None, + keyboard: bool | None = None, root_class_name: str | None = None, class_names: dict | str | None = None, styles: dict | str | None = None, @@ -86,6 +87,7 @@ def __init__( self.actions_render = actions_render self.z_index = z_index self.get_popup_container = get_popup_container + self.keyboard = keyboard self.root_class_name = root_class_name FRONTEND_DIR = resolve_frontend_dir("tour") diff --git a/backend/modelscope_studio/components/antd/transfer/__init__.py b/backend/modelscope_studio/components/antd/transfer/__init__.py index cf0dcb1b..1852206c 100644 --- a/backend/modelscope_studio/components/antd/transfer/__init__.py +++ b/backend/modelscope_studio/components/antd/transfer/__init__.py @@ -31,7 +31,7 @@ class AntdTransfer(ModelScopeDataLayoutComponent): # supported slots SLOTS = [ 'selectionsIcon', 'titles', 'footer', 'locale.notFoundContent', - 'selectAllLabels', 'render' + 'selectAllLabels', 'render', 'actions' ] def __init__( @@ -39,6 +39,7 @@ def __init__( value: list[float | int | str] | None = None, additional_props: dict | None = None, *, + actions: list[str] | None = None, data_source: list[dict] | None = None, disabled: bool | None = None, selections_icon: str | None = None, @@ -83,6 +84,7 @@ def __init__( self.class_names = class_names self.styles = styles self.additional_props = additional_props + self.actions = actions self.data_source = data_source self.disabled = disabled self.selections_icon = selections_icon diff --git a/backend/modelscope_studio/components/antd/upload/__init__.py b/backend/modelscope_studio/components/antd/upload/__init__.py index 8d474adf..1e91eb23 100644 --- a/backend/modelscope_studio/components/antd/upload/__init__.py +++ b/backend/modelscope_studio/components/antd/upload/__init__.py @@ -61,7 +61,7 @@ def __init__( value: list[str] | Callable | None = None, additional_props: dict | None = None, *, - accept: str | None = None, + accept: str | dict | None = None, action: str | None = None, before_upload: str | None = None, custom_request: str | None = None, diff --git a/backend/modelscope_studio/components/antd/upload/dragger/__init__.py b/backend/modelscope_studio/components/antd/upload/dragger/__init__.py index 276940f9..f89c3ae0 100644 --- a/backend/modelscope_studio/components/antd/upload/dragger/__init__.py +++ b/backend/modelscope_studio/components/antd/upload/dragger/__init__.py @@ -57,7 +57,7 @@ def __init__( value: list[str] | Callable | None = None, additional_props: dict | None = None, *, - accept: str | None = None, + accept: str | dict | None = None, action: str | None = None, before_upload: str | None = None, custom_request: str | None = None, diff --git a/backend/modelscope_studio/components/antd/watermark/__init__.py b/backend/modelscope_studio/components/antd/watermark/__init__.py index 8f68c1eb..815d5c0d 100644 --- a/backend/modelscope_studio/components/antd/watermark/__init__.py +++ b/backend/modelscope_studio/components/antd/watermark/__init__.py @@ -1,5 +1,7 @@ from __future__ import annotations +from gradio.events import EventListener + from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir @@ -7,7 +9,11 @@ class AntdWatermark(ModelScopeLayoutComponent): """ Ant Design: https://ant.design/components/watermark """ - EVENTS = [] + EVENTS = [ + EventListener("remove", + callback=lambda block: block._internal.update( + bind_remove_event=True)), + ] def __init__( self, diff --git a/backend/modelscope_studio/components/antdx/attachments/__init__.py b/backend/modelscope_studio/components/antdx/attachments/__init__.py index 7112ce2c..82a257a4 100644 --- a/backend/modelscope_studio/components/antdx/attachments/__init__.py +++ b/backend/modelscope_studio/components/antdx/attachments/__init__.py @@ -69,7 +69,7 @@ def __init__( additional_props: dict | None = None, *, image_props: dict | None = None, - accept: str | None = None, + accept: str | dict | None = None, action: str | None = None, before_upload: str | None = None, custom_request: str | None = None, diff --git a/backend/modelscope_studio/components/pro/multimodal_input/__init__.py b/backend/modelscope_studio/components/pro/multimodal_input/__init__.py index 94da7e9f..7d79490e 100644 --- a/backend/modelscope_studio/components/pro/multimodal_input/__init__.py +++ b/backend/modelscope_studio/components/pro/multimodal_input/__init__.py @@ -3,7 +3,7 @@ import tempfile from dataclasses import field from pathlib import Path -from typing import Optional +from typing import Optional, Union import gradio_client.utils as client_utils from gradio import FileData, processing_utils @@ -53,7 +53,7 @@ class MultimodalInputUploadConfig(GradioModel): allow_speech: Optional[bool] = False show_count: Optional[bool] = True upload_button_tooltip: Optional[str] = None - accept: Optional[str] = None + accept: Optional[Union[str, dict]] = None max_count: Optional[int] = None directory: Optional[bool] = False multiple: Optional[bool] = False diff --git a/docs/components/antdx/bubble/demos/bubble_list.py b/docs/components/antdx/bubble/demos/bubble_list.py index 56225808..bc1cd7f4 100644 --- a/docs/components/antdx/bubble/demos/bubble_list.py +++ b/docs/components/antdx/bubble/demos/bubble_list.py @@ -1,4 +1,5 @@ import time + import gradio as gr import modelscope_studio.components.antd as antd import modelscope_studio.components.antdx as antdx diff --git a/frontend/antd/alert/alert.tsx b/frontend/antd/alert/alert.tsx index 177c4872..0c139802 100644 --- a/frontend/antd/alert/alert.tsx +++ b/frontend/antd/alert/alert.tsx @@ -4,6 +4,13 @@ import React from 'react'; import { useFunction } from '@utils/hooks/useFunction'; import { Alert as AAlert, type GetProps } from 'antd'; +function getConfig(value: T): Partial> { + if (typeof value === 'object' && value !== null) { + return value as any; + } + return {} as any; +} + export const Alert = sveltify< GetProps & { children?: React.ReactNode; @@ -11,6 +18,8 @@ export const Alert = sveltify< ['action', 'closable.closeIcon', 'description', 'icon', 'message'] >(({ slots, afterClose, children, ...props }) => { const afterCloseFunction = useFunction(afterClose); + const closableConfig = getConfig(props.closable); + const closableAfterCloseFunction = useFunction(closableConfig.afterClose); return ( <>

{children}
@@ -21,7 +30,12 @@ export const Alert = sveltify< closable={ slots['closable.closeIcon'] ? { - ...(typeof props.closable === 'object' ? props.closable : {}), + ...(typeof props.closable === 'object' + ? props.closable + : { + ...closableConfig, + afterClose: closableAfterCloseFunction, + }), closeIcon: , } : props.closable diff --git a/frontend/antd/auto-complete/Index.svelte b/frontend/antd/auto-complete/Index.svelte index 150cc4b8..f894e2e1 100644 --- a/frontend/antd/auto-complete/Index.svelte +++ b/frontend/antd/auto-complete/Index.svelte @@ -5,7 +5,6 @@ processProps, } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; - import type React from 'react'; import cls from 'classnames'; const AwaitedAutoComplete = importComponent(() => import('./auto-complete')); @@ -27,6 +26,7 @@ }; dropdown_visible_change?: any; popup_visible_change?: any; + show_search_search?: any; }>(() => props); const getProceedProps = processProps( @@ -57,6 +57,7 @@ { dropdown_visible_change: 'dropdownVisibleChange', popup_visible_change: 'popupVisibleChange', + show_search_search: 'showSearch_search', } ); const proceedProps = $derived(getProceedProps()); diff --git a/frontend/antd/auto-complete/auto-complete.tsx b/frontend/antd/auto-complete/auto-complete.tsx index 5dd5d915..dd943c10 100644 --- a/frontend/antd/auto-complete/auto-complete.tsx +++ b/frontend/antd/auto-complete/auto-complete.tsx @@ -29,6 +29,13 @@ const AutoCompleteChildrenWrapper = forwardRef< ); }); +function getConfig(value: T): Partial> { + if (typeof value === 'object' && value !== null) { + return value as any; + } + return {} as any; +} + export const AutoComplete = sveltify< GetProps & { onValueChange: (value: string) => void; @@ -53,9 +60,15 @@ export const AutoComplete = sveltify< getPopupContainer, dropdownRender, popupRender, + showSearch, elRef, ...props }) => { + const showSearchConfig = getConfig(showSearch); + const showSearchConfigFilterOption = useFunction( + showSearchConfig.filterOption + ); + const getPopupContainerFunction = useFunction(getPopupContainer); const filterOptionFunction = useFunction(filterOption); const dropdownRenderFunction = useFunction(dropdownRender); @@ -75,6 +88,16 @@ export const AutoComplete = sveltify< , - ['separator', 'itemRender'] + ['separator', 'itemRender', 'dropdownIcon'] >( withItemsContextProvider( ['default', 'items'], @@ -23,6 +23,13 @@ export const Breadcrumb = sveltify<
{children}
+ ) : ( + props.dropdownIcon + ) + } itemRender={ slots['itemRender'] ? renderParamsSlot( diff --git a/frontend/antd/cascader/cascader.tsx b/frontend/antd/cascader/cascader.tsx index 5a702d59..ef89a880 100644 --- a/frontend/antd/cascader/cascader.tsx +++ b/frontend/antd/cascader/cascader.tsx @@ -34,6 +34,7 @@ export const Cascader = sveltify< 'dropdownRender', 'popupRender', 'showSearch.render', + 'optionRender', ] >( withItemsContextProvider( @@ -110,7 +111,14 @@ export const Cascader = sveltify< : showSearch } loadData={onLoadData} - optionRender={optionRenderFunction} + optionRender={ + slots.optionRender + ? renderParamsSlot({ + slots, + key: 'optionRender', + }) + : optionRenderFunction + } getPopupContainer={getPopupContainerFunction} prefix={ slots.prefix ? : props.prefix diff --git a/frontend/antd/cascader/panel/cascader.panel.tsx b/frontend/antd/cascader/panel/cascader.panel.tsx index c11ed03a..5905780e 100644 --- a/frontend/antd/cascader/panel/cascader.panel.tsx +++ b/frontend/antd/cascader/panel/cascader.panel.tsx @@ -1,8 +1,10 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import { useMemo } from 'react'; +import { useFunction } from '@utils/hooks/useFunction'; import { useValueChange } from '@utils/hooks/useValueChange'; import { renderItems } from '@utils/renderItems'; +import { renderParamsSlot } from '@utils/renderParamsSlot'; import { Cascader as ACascader, type CascaderPanelProps } from 'antd'; import { useItems, withItemsContextProvider } from '../context'; @@ -13,7 +15,7 @@ export const CascaderPanel = sveltify< onLoadData?: (...args: any[]) => void; children?: React.ReactNode; }, - ['notFoundContent', 'expandIcon'] + ['notFoundContent', 'expandIcon', 'optionRender'] >( withItemsContextProvider( ['default', 'options'], @@ -30,6 +32,7 @@ export const CascaderPanel = sveltify< onValueChange, value: props.value, }); + const optionRenderFunction = useFunction(props.optionRender); const { items: slotItems } = useItems<['default', 'options']>(); const resolvedSlotItems = slotItems.options.length > 0 ? slotItems.options : slotItems.default; @@ -39,6 +42,11 @@ export const CascaderPanel = sveltify< { return ( options || diff --git a/frontend/antd/drawer/Index.svelte b/frontend/antd/drawer/Index.svelte index cc950b51..35e84067 100644 --- a/frontend/antd/drawer/Index.svelte +++ b/frontend/antd/drawer/Index.svelte @@ -12,34 +12,41 @@ const props = $props(); const { gradio, getComponentProps, getAdditionalProps, children } = getProps<{ additional_props?: Record; - _internal: { layout?: boolean; }; + resizable_resize_start?: any; + resizable_resize_end?: any; }>(() => props); - const getProceedProps = processProps(() => { - const { - visible, - _internal, - as_item, - elem_classes, - elem_id, - elem_style, - ...restProps - } = getComponentProps(); - return { - gradio, - additionalProps: getAdditionalProps(), - _internal, - as_item, - restProps, - visible, - elem_id, - elem_classes, - elem_style, - }; - }); + const getProceedProps = processProps( + () => { + const { + visible, + _internal, + as_item, + elem_classes, + elem_id, + elem_style, + ...restProps + } = getComponentProps(); + return { + gradio, + additionalProps: getAdditionalProps(), + _internal, + as_item, + restProps, + visible, + elem_id, + elem_classes, + elem_style, + }; + }, + { + resizable_resize_start: 'resizable_resizeStart', + resizable_resize_end: 'resizable_resizeEnd', + } + ); const proceedProps = $derived(getProceedProps()); const slots = getSlots(); diff --git a/frontend/antd/menu/menu.tsx b/frontend/antd/menu/menu.tsx index 9adacefa..b72c91b7 100644 --- a/frontend/antd/menu/menu.tsx +++ b/frontend/antd/menu/menu.tsx @@ -1,6 +1,7 @@ import { sveltify } from '@svelte-preprocess-react'; import { ReactSlot } from '@svelte-preprocess-react/react-slot'; import React, { useMemo } from 'react'; +import { useFunction } from '@utils/hooks/useFunction'; import { omitUndefinedProps } from '@utils/omitUndefinedProps'; import { renderItems } from '@utils/renderItems'; import { renderParamsSlot } from '@utils/renderParamsSlot'; @@ -13,7 +14,7 @@ import './menu.less'; export const Menu = sveltify< GetProps & {}, - ['expandIcon', 'overflowedIndicator'] + ['expandIcon', 'overflowedIndicator', 'popupRender'] >( withItemsContextProvider( ['default', 'items'], @@ -29,6 +30,7 @@ export const Menu = sveltify< const { items: slotItems } = useItems<['default', 'items']>(); const resolvedSlotItems = slotItems.items.length > 0 ? slotItems.items : slotItems.default; + const popupRenderFunction = useFunction(props.popupRender); return ( <>
{children}
@@ -72,6 +74,19 @@ export const Menu = sveltify< props.overflowedIndicator ) } + popupRender={ + slots.popupRender + ? renderParamsSlot( + { + key: 'popupRender', + slots, + }, + { + clone: true, + } + ) + : popupRenderFunction + } /> ); diff --git a/frontend/antd/notification/notification.tsx b/frontend/antd/notification/notification.tsx index b75d6765..fa983cdb 100644 --- a/frontend/antd/notification/notification.tsx +++ b/frontend/antd/notification/notification.tsx @@ -13,7 +13,15 @@ export const Notification = sveltify< visible?: boolean; onVisible?: (visible: boolean) => void; }, - ['btn', 'actions', 'closeIcon', 'description', 'icon', 'message'] + [ + 'btn', + 'actions', + 'closeIcon', + 'description', + 'icon', + 'message', + 'closable.closeIcon', + ] >( ({ slots, @@ -41,6 +49,12 @@ export const Notification = sveltify< ...props, key: notificationKey, btn: slots.btn ? : props.btn, + closable: slots['closable.closeIcon'] + ? { + ...(typeof props.closable === 'object' ? props.closable : {}), + closeIcon: , + } + : props.closable, actions: slots.actions ? ( ) : ( diff --git a/frontend/antd/rate/rate.tsx b/frontend/antd/rate/rate.tsx index 071060a9..854f502b 100644 --- a/frontend/antd/rate/rate.tsx +++ b/frontend/antd/rate/rate.tsx @@ -20,6 +20,7 @@ export const Rate = sveltify< ...props }) => { const characterFunction = useFunction(character, true); + return ( <>
{children}
diff --git a/frontend/antd/splitter/Index.svelte b/frontend/antd/splitter/Index.svelte index a9773939..60511cad 100644 --- a/frontend/antd/splitter/Index.svelte +++ b/frontend/antd/splitter/Index.svelte @@ -20,6 +20,7 @@ resize_start?: any; resize_end?: any; + dragger_double_click?: any; }>(() => props); const getProceedProps = processProps( @@ -48,6 +49,7 @@ { resize_start: 'resizeStart', resize_end: 'resizeEnd', + dragger_double_click: 'draggerDoubleClick', } ); const proceedProps = $derived(getProceedProps()); diff --git a/frontend/antd/tag/checkable-tag-group/Index.svelte b/frontend/antd/tag/checkable-tag-group/Index.svelte new file mode 100644 index 00000000..bdf45c41 --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/Index.svelte @@ -0,0 +1,78 @@ + + +{#if proceedProps.visible} + {#await AwaitedCheckableTagGroup then CheckableTagGroup} + { + updateProps({ value: v }); + }} + > + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antd/tag/checkable-tag-group/context.ts b/frontend/antd/tag/checkable-tag-group/context.ts new file mode 100644 index 00000000..334bbc0e --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/context.ts @@ -0,0 +1,6 @@ +import { createItemsContext } from '@utils/createItemsContext'; + +export const { withItemsContextProvider, useItems, ItemHandler } = + createItemsContext('antd-checkable-tag-group-options'); + +export * from '@utils/createItemsContext'; diff --git a/frontend/antd/tag/checkable-tag-group/gradio.config.js b/frontend/antd/tag/checkable-tag-group/gradio.config.js new file mode 100644 index 00000000..1992403d --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antd/tag/checkable-tag-group/option/Index.svelte b/frontend/antd/tag/checkable-tag-group/option/Index.svelte new file mode 100644 index 00000000..9bc181c4 --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/option/Index.svelte @@ -0,0 +1,73 @@ + + +{#if proceedProps.visible} + {#await AwaitedCheckableTagGroupOption then CheckableTagGroupOption} + + {@render children?.()} + + {/await} +{/if} diff --git a/frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx b/frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx new file mode 100644 index 00000000..49753ddd --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx @@ -0,0 +1,13 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React from 'react'; +import type { CheckableTagGroupProps } from 'antd/es/tag'; + +import { ItemHandler, type ItemHandlerProps } from '../context'; + +export const CheckableTagGroupOption = sveltify< + NonNullable['options']>[number] & ItemHandlerProps +>((props) => { + return ; +}); + +export default CheckableTagGroupOption; diff --git a/frontend/antd/tag/checkable-tag-group/option/gradio.config.js b/frontend/antd/tag/checkable-tag-group/option/gradio.config.js new file mode 100644 index 00000000..7b2fe8dd --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/option/gradio.config.js @@ -0,0 +1,3 @@ +import config from '../../../../defineConfig.js'; + +export default config(); diff --git a/frontend/antd/tag/checkable-tag-group/option/package.json b/frontend/antd/tag/checkable-tag-group/option/package.json new file mode 100644 index 00000000..1abfb34e --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/option/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antd-tag-checkable-tag-group.option", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antd/tag/checkable-tag-group/package.json b/frontend/antd/tag/checkable-tag-group/package.json new file mode 100644 index 00000000..d6c0f755 --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/package.json @@ -0,0 +1,14 @@ +{ + "name": "@modelscope-studio/antd-tag-checkable-tag-group", + "type": "module", + "exports": { + ".": { + "gradio": "./Index.svelte", + "default": "./Index.svelte" + }, + "./package.json": { + "gradio": "./package.json", + "default": "./package.json" + } + } +} diff --git a/frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx b/frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx new file mode 100644 index 00000000..1f13d32e --- /dev/null +++ b/frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx @@ -0,0 +1,50 @@ +import { sveltify } from '@svelte-preprocess-react'; +import React, { useMemo } from 'react'; +import { renderItems } from '@utils/renderItems'; +import { type GetProps, Tag as ATag } from 'antd'; + +import { useItems, withItemsContextProvider } from './context'; + +export const CheckableTagGroup = sveltify< + GetProps & { + onValueChange: (value: any) => void; + children?: React.ReactNode; + } +>( + withItemsContextProvider( + ['options', 'default'], + ({ onChange, onValueChange, children, elRef, options, ...props }) => { + const { items: slotItems } = useItems<['options', 'default']>(); + const resolvedSlotItems = + slotItems.options.length > 0 ? slotItems.options : slotItems.default; + return ( + <> +
{children}
+ { + return ( + options || + renderItems< + NonNullable< + GetProps['options'] + >[number] + >(resolvedSlotItems, { + children: 'options', + clone: true, + }) + ); + }, [resolvedSlotItems, options])} + onChange={(v) => { + onValueChange(v); + onChange?.(v as any); + }} + /> + + ); + } + ) +); + +export default CheckableTagGroup; diff --git a/frontend/antd/timeline/item/Index.svelte b/frontend/antd/timeline/item/Index.svelte index 89603c17..85914093 100644 --- a/frontend/antd/timeline/item/Index.svelte +++ b/frontend/antd/timeline/item/Index.svelte @@ -44,8 +44,6 @@ const proceedProps = $derived(getProceedProps()); const slots = getSlots(); - - let slot = $state(); {#await AwaitedTimelineItem then TimelineItem} @@ -55,23 +53,12 @@ id={proceedProps.elem_id} {...proceedProps.restProps} {...proceedProps.additionalProps} - slots={{ - children: slot, - ...slots.value, - }} + slots={slots.value} itemIndex={proceedProps._internal.index || 0} itemSlotKey={slotKey?.value} > {#if proceedProps.visible} - - {@render children?.()} - + {@render children?.()} {/if} {/await} - - diff --git a/frontend/antd/transfer/transfer.tsx b/frontend/antd/transfer/transfer.tsx index 45c01a8f..67d04a12 100644 --- a/frontend/antd/transfer/transfer.tsx +++ b/frontend/antd/transfer/transfer.tsx @@ -18,6 +18,7 @@ export const Transfer = sveltify< 'locale.notFoundContent', 'selectAllLabels', 'render', + 'actions', ] >( ({ @@ -34,6 +35,7 @@ export const Transfer = sveltify< }) => { const titles = useTargets(children, 'titles'); const selectAllLabels = useTargets(children, 'selectAllLabels'); + const actions = useTargets(children, 'actions'); const renderFunction = useFunction(render); const listStyleFunction = useFunction(listStyle); const footerFunction = useFunction(footer); @@ -87,6 +89,13 @@ export const Transfer = sveltify< : props.titles } listStyle={listStyleFunction || listStyle} + actions={ + actions.length > 0 + ? actions.map((target, index) => { + return ; + }) + : props.actions + } selectAllLabels={ selectAllLabels.length > 0 ? selectAllLabels.map((target, index) => { diff --git a/frontend/antd/upload/dragger/upload.dragger.tsx b/frontend/antd/upload/dragger/upload.dragger.tsx index 7517f2df..1d5e8fe6 100644 --- a/frontend/antd/upload/dragger/upload.dragger.tsx +++ b/frontend/antd/upload/dragger/upload.dragger.tsx @@ -50,8 +50,21 @@ export const UploadDragger = sveltify< onRemove, fileList: fileListProp, maxCount, + accept, ...props }) => { + const acceptConfig = getConfig(accept); + const acceptFilterFunction = useFunction(acceptConfig.filter, true); + const resolvedAccept: typeof accept = + typeof accept === 'boolean' + ? accept + : accept + ? { + ...acceptConfig, + format: acceptConfig.format, + filter: acceptFilterFunction || acceptConfig.filter, + } + : undefined; const supportShowUploadListConfig = slots['showUploadList.downloadIcon'] || slots['showUploadList.removeIcon'] || @@ -114,6 +127,7 @@ export const UploadDragger = sveltify< return ( { + const acceptConfig = getConfig(accept); + const acceptFilterFunction = useFunction(acceptConfig.filter, true); + const resolvedAccept: typeof accept = + typeof accept === 'boolean' + ? accept + : accept + ? { + ...acceptConfig, + format: acceptConfig.format, + filter: acceptFilterFunction || acceptConfig.filter, + } + : undefined; const supportShowUploadListConfig = slots['showUploadList.downloadIcon'] || slots['showUploadList.removeIcon'] || @@ -116,6 +129,7 @@ export const Upload = sveltify< return ( { + const acceptConfig = getConfig(accept); + const acceptFilterFunction = useFunction(acceptConfig.filter, true); + const resolvedAccept: typeof accept = + typeof accept === 'boolean' + ? accept + : accept + ? { + ...acceptConfig, + format: acceptConfig.format, + filter: acceptFilterFunction || acceptConfig.filter, + } + : undefined; // imageProps const previewConfig = getConfig(imageProps?.preview); const supportPreview = @@ -173,6 +186,7 @@ export const Attachments = sveltify<
{ try { @@ -473,6 +486,7 @@ export const MultimodalInput = sveltify< ]), { omitNull: true } )} + accept={resolvedAccept} imageProps={{ ...uploadConfig?.imageProps, }} From e009cd0408d4505f4105e494af192c6f832fa48c Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 15 Apr 2026 16:22:35 +0800 Subject: [PATCH 23/31] chore: add changeset --- .changeset/pink-sails-itch.md | 12 ++++++++++++ .changeset/pre.json | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changeset/pink-sails-itch.md diff --git a/.changeset/pink-sails-itch.md b/.changeset/pink-sails-itch.md new file mode 100644 index 00000000..3a8e7eb4 --- /dev/null +++ b/.changeset/pink-sails-itch.md @@ -0,0 +1,12 @@ +--- +'@modelscope-studio/lint-config': patch +'@modelscope-studio/changelog': patch +'@modelscope-studio/antdx': patch +'@modelscope-studio/antd': patch +'@modelscope-studio/base': patch +'@modelscope-studio/pro': patch +'@modelscope-studio/frontend': patch +'modelscope_studio': patch +--- + +feat: complete new features of antd & antdx diff --git a/.changeset/pre.json b/.changeset/pre.json index c74b580b..471b7fc2 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -11,5 +11,7 @@ "@modelscope-studio/base": "1.6.1", "@modelscope-studio/pro": "1.6.1" }, - "changesets": ["eleven-aliens-sell"] + "changesets": [ + "eleven-aliens-sell" + ] } From 8e3441eabb5e3add60affeca0b73da44359f8fa5 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 15 Apr 2026 16:23:00 +0800 Subject: [PATCH 24/31] chore: update versions --- .changeset/pre.json | 4 +--- CHANGELOG.md | 6 ++++++ backend/modelscope_studio/version.py | 2 +- config/changelog/CHANGELOG.md | 6 ++++++ config/changelog/package.json | 2 +- config/lint-config/CHANGELOG.md | 6 ++++++ config/lint-config/package.json | 2 +- docs/requirements.txt | 2 +- docs/src/pyproject.toml | 2 +- frontend/CHANGELOG.md | 6 ++++++ frontend/antd/CHANGELOG.md | 6 ++++++ frontend/antd/package.json | 2 +- frontend/antdx/CHANGELOG.md | 6 ++++++ frontend/antdx/package.json | 2 +- frontend/base/CHANGELOG.md | 6 ++++++ frontend/base/package.json | 2 +- frontend/package.json | 2 +- frontend/pro/CHANGELOG.md | 6 ++++++ frontend/pro/package.json | 2 +- package.json | 2 +- pyproject.toml | 2 +- 21 files changed, 61 insertions(+), 15 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 471b7fc2..edd5cdf2 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -11,7 +11,5 @@ "@modelscope-studio/base": "1.6.1", "@modelscope-studio/pro": "1.6.1" }, - "changesets": [ - "eleven-aliens-sell" - ] + "changesets": ["eleven-aliens-sell", "pink-sails-itch"] } diff --git a/CHANGELOG.md b/CHANGELOG.md index cd14c58d..4a2620c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # modelscope_studio +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/backend/modelscope_studio/version.py b/backend/modelscope_studio/version.py index ce304548..e28bc3c5 100644 --- a/backend/modelscope_studio/version.py +++ b/backend/modelscope_studio/version.py @@ -1 +1 @@ -__version__ = "2.0.0-beta.0" +__version__ = "2.0.0-beta.1" diff --git a/config/changelog/CHANGELOG.md b/config/changelog/CHANGELOG.md index f04a2edc..86031e98 100644 --- a/config/changelog/CHANGELOG.md +++ b/config/changelog/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/changelog +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/config/changelog/package.json b/config/changelog/package.json index 90b4da81..8860eb8f 100644 --- a/config/changelog/package.json +++ b/config/changelog/package.json @@ -1,6 +1,6 @@ { "name": "@modelscope-studio/changelog", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "private": false, "description": "ModelScope Studio Changelog", "repository": "git@github.com:modelscope/modelscope-studio.git", diff --git a/config/lint-config/CHANGELOG.md b/config/lint-config/CHANGELOG.md index 66c520ab..5dc6a7b9 100644 --- a/config/lint-config/CHANGELOG.md +++ b/config/lint-config/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/lint-config +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/config/lint-config/package.json b/config/lint-config/package.json index 4947e2d8..b86bcad8 100644 --- a/config/lint-config/package.json +++ b/config/lint-config/package.json @@ -1,6 +1,6 @@ { "name": "@modelscope-studio/lint-config", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "private": false, "description": "ModelScope Studio Lint Config", "repository": "git@github.com:modelscope/modelscope-studio.git", diff --git a/docs/requirements.txt b/docs/requirements.txt index 9abd576a..f2402e34 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ gradio==5.34.1 -modelscope_studio==2.0.0-beta.0 +modelscope_studio==2.0.0-beta.1 openai diff --git a/docs/src/pyproject.toml b/docs/src/pyproject.toml index cf8711e2..fd4e02ea 100644 --- a/docs/src/pyproject.toml +++ b/docs/src/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "hatchling.build" [project] name = "modelscope_studio" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" description = "A third-party component library based on Gradio." readme = "README.md" license = "Apache-2.0" diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index 998130e7..132b9a99 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/frontend +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/frontend/antd/CHANGELOG.md b/frontend/antd/CHANGELOG.md index 804f5c84..9ccb4d98 100644 --- a/frontend/antd/CHANGELOG.md +++ b/frontend/antd/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/antd +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/frontend/antd/package.json b/frontend/antd/package.json index ce811551..846c50c5 100644 --- a/frontend/antd/package.json +++ b/frontend/antd/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/antd", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "type": "module" } diff --git a/frontend/antdx/CHANGELOG.md b/frontend/antdx/CHANGELOG.md index eb3a6d74..1df71eab 100644 --- a/frontend/antdx/CHANGELOG.md +++ b/frontend/antdx/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/antdx +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/frontend/antdx/package.json b/frontend/antdx/package.json index b37fccb6..e5c3ad19 100644 --- a/frontend/antdx/package.json +++ b/frontend/antdx/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/antdx", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "type": "module" } diff --git a/frontend/base/CHANGELOG.md b/frontend/base/CHANGELOG.md index bab5c073..ffbe65bd 100644 --- a/frontend/base/CHANGELOG.md +++ b/frontend/base/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/base +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/frontend/base/package.json b/frontend/base/package.json index 9fc16323..74d10b47 100644 --- a/frontend/base/package.json +++ b/frontend/base/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/base", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "type": "module" } diff --git a/frontend/package.json b/frontend/package.json index b5f30c30..ad9fb845 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@modelscope-studio/frontend", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "private": false, "description": "ModelScope Gradio Components", "license": "Apache-2.0", diff --git a/frontend/pro/CHANGELOG.md b/frontend/pro/CHANGELOG.md index 9fb60a12..0cd3e940 100644 --- a/frontend/pro/CHANGELOG.md +++ b/frontend/pro/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelscope-studio/pro +## 2.0.0-beta.1 + +### Features + +- [`e009cd0`](https://github.com/modelscope/modelscope-studio/commit/e009cd0408d4505f4105e494af192c6f832fa48c) - complete new features of antd & antdx. Thanks [@Col0ring](https://github.com/Col0ring)! + ## 2.0.0-beta.0 ### Misc Changes diff --git a/frontend/pro/package.json b/frontend/pro/package.json index 74ec97aa..eaf5356f 100644 --- a/frontend/pro/package.json +++ b/frontend/pro/package.json @@ -1,5 +1,5 @@ { "name": "@modelscope-studio/pro", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "type": "module" } diff --git a/package.json b/package.json index 897ca8f6..ef3e8d4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "modelscope_studio", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "private": true, "description": "ModelScope Gradio Components", "repository": "git@github.com:modelscope/modelscope-studio.git", diff --git a/pyproject.toml b/pyproject.toml index ce1bb58b..9543e563 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "hatchling.build" [project] name = "modelscope_studio" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" description = "A third-party component library based on Gradio." readme = "README.md" license = "Apache-2.0" From 9d9b41a3676f4a3e1942f528364601c81b7b7a17 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 15 Apr 2026 16:42:24 +0800 Subject: [PATCH 25/31] docs: update readme --- README-zh_CN.md | 10 +++++++++- README.md | 26 +++++++++----------------- docs/README-zh_CN.md | 10 +++++++++- docs/README.md | 10 +++++++++- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 162d52bd..8e145b1d 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -33,7 +33,9 @@ ## 依赖 -- Gradio >= 4.43.0 +- Gradio >= 6.0.0 + +> 注意:您的 Gradio 版本必须`<=6.8.0`,[为什么?](https://github.com/gradio-app/gradio/issues/13131) ## 安装 @@ -41,6 +43,12 @@ pip install modelscope_studio ``` +如果您需要使用`4.43.0 <= Gradio < 6.0.0`,请使用 1.x 版本: + +```sh +pip install modelscope_studio~=1.0 +``` + ## 快速开始 ```python diff --git a/README.md b/README.md index 0e894a9b..3caf799e 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,9 @@ However, when your application needs Gradio to handle more built-in data on the ## Dependencies -- Gradio >= 4.43.0 +- Gradio >= 6.0.0 + +> Note: Your Gradio version must`<=6.8.0`, [why?](https://github.com/gradio-app/gradio/issues/13131) ## Installation @@ -41,6 +43,12 @@ However, when your application needs Gradio to handle more built-in data on the pip install modelscope_studio ``` +If you need to use `4.43.0 <= Gradio < 6.0.0`, please use 1.x version: + +```sh +pip install modelscope_studio~=1.0 +``` + ## Quick Start ```python @@ -61,22 +69,6 @@ demo.queue().launch() - ModelScope: [中文](https://modelscope.cn/studios/modelscope/modelscope-studio) - Hugging Face: [English](https://huggingface.co/spaces/modelscope/modelscope-studio) -## Migration to 1.0 - -If you have used the `modelscope_studio` component before and want to continue using it in the new version, you do not need to make any changes to the original component, just import `ms.Application` in the outer layer. - -```python -import gradio as gr -import modelscope_studio.components.base as ms -import modelscope_studio.components.legacy as mgr - -with gr.Blocks() as demo: - with ms.Application(): - mgr.Chatbot() - -demo.launch() -``` - ## Development Clone this repo locally: diff --git a/docs/README-zh_CN.md b/docs/README-zh_CN.md index d7e6f832..2822f710 100644 --- a/docs/README-zh_CN.md +++ b/docs/README-zh_CN.md @@ -27,7 +27,9 @@ ## 依赖 -- Gradio >= 4.43.0 +- Gradio >= 6.0.0 + +> 注意:您的 Gradio 版本必须`<=6.8.0`,[为什么?](https://github.com/gradio-app/gradio/issues/13131) ## 安装 @@ -35,6 +37,12 @@ pip install modelscope_studio ``` +如果您需要使用`4.43.0 <= Gradio < 6.0.0`,请使用 1.x 版本: + +```sh +pip install modelscope_studio~=1.0 +``` + ## 示例 diff --git a/docs/README.md b/docs/README.md index 0772dfc6..63cef3fd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -45,7 +45,9 @@ However, when your application needs Gradio to handle more built-in data on the ## Dependencies -- Gradio >= 4.43.0 +- Gradio >= 6.0.0 + +> Note: Your Gradio version must`<=6.8.0`, [why?](https://github.com/gradio-app/gradio/issues/13131) ## Installation @@ -53,6 +55,12 @@ However, when your application needs Gradio to handle more built-in data on the pip install modelscope_studio ``` +If you need to use `4.43.0 <= Gradio < 6.0.0`, please use 1.x version: + +```sh +pip install modelscope_studio~=1.0 +``` + ## Examples From 0fde948639517305471564f8c85da5052725b0c9 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Wed, 15 Apr 2026 16:48:20 +0800 Subject: [PATCH 26/31] chore: update versions --- frontend/antd/avatar/Index.svelte | 1 - frontend/antd/badge/Index.svelte | 1 - frontend/antd/calendar/Index.svelte | 1 - pyproject.toml | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/antd/avatar/Index.svelte b/frontend/antd/avatar/Index.svelte index 1b3b1afa..a4f31417 100644 --- a/frontend/antd/avatar/Index.svelte +++ b/frontend/antd/avatar/Index.svelte @@ -5,7 +5,6 @@ processProps, } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; - import type React from 'react'; import type { FileData } from '@gradio/client'; import cls from 'classnames'; diff --git a/frontend/antd/badge/Index.svelte b/frontend/antd/badge/Index.svelte index 1fdd2a2f..9a5a414f 100644 --- a/frontend/antd/badge/Index.svelte +++ b/frontend/antd/badge/Index.svelte @@ -5,7 +5,6 @@ processProps, } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; - import type React from 'react'; import cls from 'classnames'; const AwaitedBadge = importComponent(() => import('./badge')); diff --git a/frontend/antd/calendar/Index.svelte b/frontend/antd/calendar/Index.svelte index 9fe94853..eaf5005b 100644 --- a/frontend/antd/calendar/Index.svelte +++ b/frontend/antd/calendar/Index.svelte @@ -5,7 +5,6 @@ processProps, } from '@svelte-preprocess-react/component'; import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte'; - import type React from 'react'; import cls from 'classnames'; const AwaitedCalender = importComponent(() => import('./calendar')); diff --git a/pyproject.toml b/pyproject.toml index 9543e563..8866a357 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ keywords = [ 'gradio-antdx', ] # Add dependencies here -dependencies = ["6.0==6.0,<=6.8.0"] classifiers = [ 'Development Status :: 3 - Alpha', 'License :: OSI Approved :: Apache Software License', From dd2f3fd01435ea272c8e23fd56b14ae795b80c4a Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Fri, 17 Apr 2026 16:02:28 +0800 Subject: [PATCH 27/31] fix: docs --- docs/components/pro/chatbot/demos/multimodal.py | 2 +- docs/helper/Site.py | 3 +++ docs/layout_templates/chatbot/demos/basic.py | 2 +- docs/layout_templates/chatbot/demos/fine_grained_control.py | 2 +- frontend/svelte-preprocess-react/component/props.svelte.ts | 5 ++++- frontend/svelte-preprocess-react/internal/Bridge.svelte.ts | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/components/pro/chatbot/demos/multimodal.py b/docs/components/pro/chatbot/demos/multimodal.py index 1d0b11dd..bd495449 100644 --- a/docs/components/pro/chatbot/demos/multimodal.py +++ b/docs/components/pro/chatbot/demos/multimodal.py @@ -19,7 +19,7 @@ api_key=os.getenv("MODELSCOPE_ACCESS_TOKEN"), # ModelScope Token ) -model = "Qwen/Qwen2.5-VL-72B-Instruct" +model = "Qwen/Qwen3-VL-8B-Instruct" def prompt_select(input_value, e: gr.EventData): diff --git a/docs/helper/Site.py b/docs/helper/Site.py index d3c3d217..bdb7e8f8 100644 --- a/docs/helper/Site.py +++ b/docs/helper/Site.py @@ -32,6 +32,7 @@ def _render_docs(self, items: list, tab: dict): if key in tab_docs: with antd.Tabs.Item( key=key, + additional_props=dict(ms_auto_loading=False), visible=True if tab.get("default_active_key") == key else False) as docs_tab: docs_tabs.append(docs_tab) @@ -107,6 +108,8 @@ def on_tab_menu_select(e: gr.EventData): for tab in self.tabs: with antd.Tabs.Item( key=tab["key"], + additional_props=dict( + ms_auto_loading=False), elem_style=dict( height= "calc(100vh - var(--size-4) - var(--body-text-size) * 1.5 - 64px)" diff --git a/docs/layout_templates/chatbot/demos/basic.py b/docs/layout_templates/chatbot/demos/basic.py index 52d7c293..a9e54b20 100644 --- a/docs/layout_templates/chatbot/demos/basic.py +++ b/docs/layout_templates/chatbot/demos/basic.py @@ -25,7 +25,7 @@ api_key=MODELSCOPE_ACCESS_TOKEN, ) -model = "Qwen/Qwen2.5-VL-72B-Instruct" +model = "Qwen/Qwen3-VL-8B-Instruct" save_history = False diff --git a/docs/layout_templates/chatbot/demos/fine_grained_control.py b/docs/layout_templates/chatbot/demos/fine_grained_control.py index 2f36a042..6171f333 100644 --- a/docs/layout_templates/chatbot/demos/fine_grained_control.py +++ b/docs/layout_templates/chatbot/demos/fine_grained_control.py @@ -18,7 +18,7 @@ api_key=MODELSCOPE_ACCESS_TOKEN, ) -model = "Qwen/Qwen2.5-VL-72B-Instruct" +model = "Qwen/Qwen3-VL-8B-Instruct" save_history = False diff --git a/frontend/svelte-preprocess-react/component/props.svelte.ts b/frontend/svelte-preprocess-react/component/props.svelte.ts index 4c301557..bddb2631 100644 --- a/frontend/svelte-preprocess-react/component/props.svelte.ts +++ b/frontend/svelte-preprocess-react/component/props.svelte.ts @@ -270,7 +270,10 @@ export function processProps< } // for loading_status - if (shouldSetLoadingStatus) { + if ( + shouldSetLoadingStatus && + props.additionalProps?.ms_auto_loading !== false + ) { setLoadingStatus(() => props.restProps.loading_status); } diff --git a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts index bb1e70f5..6f96cd4c 100644 --- a/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts +++ b/frontend/svelte-preprocess-react/internal/Bridge.svelte.ts @@ -21,7 +21,7 @@ import type { TreeNode } from './types'; // omit attached_events function omitNodeProps(props: Record) { - const excludes = ['attachedEvents', '$$slots']; + const excludes = ['attachedEvents', '$$slots', 'ms_auto_loading']; const newProps = { ...props }; for (const exclude of excludes) { if (Reflect.has(newProps, exclude)) { From ce62f0004f2218ef779888ca8f11b592a3a7ff17 Mon Sep 17 00:00:00 2001 From: Col0ring <1561999073@qq.com> Date: Fri, 17 Apr 2026 16:06:12 +0800 Subject: [PATCH 28/31] docs: add repo wiki --- .wiki/en/API Reference/API Reference.md | 514 ++++++++++++ .../JavaScript API/JavaScript API.md | 413 ++++++++++ .../JavaScript API/Markdown Component API.md | 417 ++++++++++ .../React Component Bridge API.md | 378 +++++++++ .../Ant Design Components API.md | 479 ++++++++++++ .../Data Display Components API.md | 578 ++++++++++++++ .../Data Entry Components API.md | 523 +++++++++++++ .../Feedback Components API.md | 383 +++++++++ .../General Components API.md | 442 +++++++++++ .../Layout Components API.md | 398 ++++++++++ .../Navigation Components API.md | 462 +++++++++++ .../Other Components API.md | 278 +++++++ .../Ant Design X Components API.md | 436 +++++++++++ .../Awakening Components API.md | 348 +++++++++ .../Confirmation Components API.md | 331 ++++++++ .../Expression Components API.md | 344 +++++++++ .../Feedback Components API.md | 395 ++++++++++ .../General Components API.md | 518 +++++++++++++ .../Tool Components API.md | 377 +++++++++ .../Basic Components API.md | 570 ++++++++++++++ .../Pro Components API.md | 413 ++++++++++ .../Svelte Components API.md | 415 ++++++++++ .../JavaScript API/Utility Functions API.md | 582 ++++++++++++++ .../Antd Components API.md | 371 +++++++++ .../Data Display Components API.md | 661 ++++++++++++++++ .../Data Entry Components API.md | 453 +++++++++++ .../Feedback Components API.md | 611 +++++++++++++++ .../General Components API.md | 370 +++++++++ .../Layout Components API.md | 439 +++++++++++ .../Navigation Components API.md | 569 ++++++++++++++ .../Other Components API.md | 422 ++++++++++ .../Antdx Components API.md | 443 +++++++++++ .../Confirmation Components API.md | 366 +++++++++ .../Expression Components API.md | 359 +++++++++ .../Feedback Components API.md | 446 +++++++++++ .../General Components API.md | 390 ++++++++++ .../Utility Components API.md | 399 ++++++++++ .../Wake Components API.md | 334 ++++++++ .../Python API/Basic Components API.md | 495 ++++++++++++ .../Python API/Pro Components API.md | 487 ++++++++++++ .../en/API Reference/Python API/Python API.md | 433 +++++++++++ .../Ant Design Components.md | 531 +++++++++++++ .../Components Overview.md | 384 +++++++++ .../Avatar and Badge.md | 328 ++++++++ .../Calendar and Card.md | 359 +++++++++ .../Carousel and Collapse.md | 317 ++++++++ .../Data Display Components.md | 664 ++++++++++++++++ .../Descriptions and Empty.md | 350 +++++++++ .../Data Display Components/Image and List.md | 324 ++++++++ .../Popover and QRCode.md | 332 ++++++++ .../Segmented and Statistic.md | 312 ++++++++ .../Data Display Components/Table and Tabs.md | 345 +++++++++ .../Tag and Timeline.md | 438 +++++++++++ .../Tooltip and Tour.md | 304 ++++++++ .../Data Display Components/Tree.md | 348 +++++++++ .../Color and File Components.md | 364 +++++++++ .../Data Entry Components.md | 520 +++++++++++++ .../DateTime Components.md | 463 +++++++++++ .../Data Entry Components/Input Components.md | 516 +++++++++++++ .../Selection Components.md | 673 ++++++++++++++++ .../Feedback Components/Alert.md | 287 +++++++ .../Feedback Components/Drawer.md | 348 +++++++++ .../Feedback Components.md | 437 +++++++++++ .../Interactive Feedback.md | 301 ++++++++ .../Message and Notification.md | 332 ++++++++ .../Feedback Components/Modal.md | 322 ++++++++ .../Progress and Result.md | 289 +++++++ .../Feedback Components/Spin and Skeleton.md | 327 ++++++++ .../Feedback Components/Watermark.md | 434 +++++++++++ .../General Components/Button.md | 312 ++++++++ .../General Components/FloatButton.md | 351 +++++++++ .../General Components/General Components.md | 375 +++++++++ .../General Components/Icon.md | 360 +++++++++ .../General Components/Typography.md | 251 ++++++ .../Layout Components/Divider.md | 291 +++++++ .../Layout Components/Flex.md | 291 +++++++ .../Layout Components/Grid.md | 348 +++++++++ .../Layout Components/Layout Components.md | 385 +++++++++ .../Layout Components/Layout.md | 295 +++++++ .../Layout Components/Masonry.md | 464 +++++++++++ .../Layout Components/Space.md | 268 +++++++ .../Layout Components/Splitter.md | 387 ++++++++++ .../Navigation Components/Anchor.md | 302 ++++++++ .../Navigation Components/Breadcrumb.md | 393 ++++++++++ .../Navigation Components/Dropdown.md | 325 ++++++++ .../Navigation Components/Menu.md | 344 +++++++++ .../Navigation Components.md | 542 +++++++++++++ .../Navigation Components/Pagination.md | 340 ++++++++ .../Navigation Components/Steps.md | 425 ++++++++++ .../Ant Design Components/Other Components.md | 325 ++++++++ .../Ant Design X Components.md | 626 +++++++++++++++ .../Components Overview.md | 368 +++++++++ .../Confirmation Components.md | 408 ++++++++++ .../ThoughtChain Component.md | 380 +++++++++ .../ThoughtChainItem Component.md | 410 ++++++++++ .../Data Components/Data Components.md | 372 +++++++++ .../Data Components/FileCard Component.md | 441 +++++++++++ .../Data Components/Folder Component.md | 359 +++++++++ .../Data Components/Sources Component.md | 422 ++++++++++ .../Data Components/Think Component.md | 457 +++++++++++ .../Attachments Component.md | 731 ++++++++++++++++++ .../Expression Components.md | 322 ++++++++ .../Expression Components/Sender Component.md | 315 ++++++++ .../Suggestion Component.md | 338 ++++++++ .../ActionItem Component.md | 258 +++++++ .../Feedback Components/Actions Overview.md | 335 ++++++++ .../Feedback Components/Audio Component.md | 315 ++++++++ .../Feedback Components/Copy Component.md | 429 ++++++++++ .../Feedback Components/Feedback Component.md | 268 +++++++ .../Feedback Components.md | 340 ++++++++ .../Feedback Components/Item Component.md | 318 ++++++++ .../Bubble Chat Bubble/Bubble Chat Bubble.md | 227 ++++++ .../Bubble Component Overview.md | 188 +++++ .../Bubble.Divider Component.md | 80 ++ .../Bubble.Item Component.md | 80 ++ .../Bubble.List Component.md | 66 ++ .../Bubble.Role Component.md | 93 +++ .../Bubble.System Component.md | 97 +++ .../Conversations/API Reference.md | 105 +++ .../Conversations/Component Overview.md | 113 +++ .../Conversation Item Component.md | 92 +++ .../Conversations/Conversations Management.md | 160 ++++ .../Conversations/Usage Examples.md | 140 ++++ .../General Components/General Components.md | 310 ++++++++ .../CodeHighlighter Component.md | 335 ++++++++ .../Tool Components/Mermaid Component.md | 334 ++++++++ .../Tool Components/Notification Component.md | 367 +++++++++ .../Tool Components/Tool Components.md | 374 +++++++++ .../Tool Components/XProvider Component.md | 284 +++++++ .../Wake Components/Prompts Component.md | 408 ++++++++++ .../Wake Components/Wake Components.md | 293 +++++++ .../Wake Components/Welcome Component.md | 424 ++++++++++ .../Base Components/Application Component.md | 424 ++++++++++ .../Base Components/AutoLoading Component.md | 339 ++++++++ .wiki/en/Base Components/Base Components.md | 505 ++++++++++++ .../en/Base Components/Fragment Component.md | 328 ++++++++ .wiki/en/Base Components/Layout Components.md | 386 +++++++++ .../Base Components/Rendering Components.md | 371 +++++++++ .wiki/en/Base Components/Slot Component.md | 333 ++++++++ .wiki/en/Deployment Guide/Build Process.md | 405 ++++++++++ .wiki/en/Deployment Guide/CI CD.md | 436 +++++++++++ .wiki/en/Deployment Guide/Deployment Guide.md | 333 ++++++++ .../Environment Configuration.md | 315 ++++++++ .wiki/en/Deployment Guide/Release Process.md | 441 +++++++++++ .../en/Development Guide/Build and Deploy.md | 370 +++++++++ .../Backend Component Development.md | 363 +++++++++ .../Component Development Best Practices.md | 407 ++++++++++ .../Component Development.md | 366 +++++++++ .../Component Documentation Writing.md | 345 +++++++++ .../Component Testing.md | 310 ++++++++ .../Frontend Component Development.md | 418 ++++++++++ .../Development Guide/Contributing Guide.md | 317 ++++++++ .../en/Development Guide/Development Guide.md | 325 ++++++++ .../Development Guide/Development Workflow.md | 302 ++++++++ .../Development Guide/Documentation System.md | 382 +++++++++ .../en/Development Guide/Environment Setup.md | 276 +++++++ .../Testing and Debugging.md | 311 ++++++++ .../en/Pro Components/Chatbot/Basic Usage.md | 388 ++++++++++ .wiki/en/Pro Components/Chatbot/Chatbot.md | 348 +++++++++ .../Chatbot/Configuration Options.md | 364 +++++++++ .wiki/en/Pro Components/Chatbot/Data Model.md | 441 +++++++++++ .../Chatbot/Integration Examples.md | 349 +++++++++ .../Chatbot/Message Processing.md | 397 ++++++++++ .../Chatbot/Multimodal Support.md | 397 ++++++++++ .../Chatbot/Thinking Process Display.md | 329 ++++++++ .../MonacoEditor/Advanced Features.md | 305 ++++++++ .../MonacoEditor/Basic Usage.md | 379 +++++++++ .../MonacoEditor/Configuration Options.md | 406 ++++++++++ .../MonacoEditor/Diff Editor.md | 383 +++++++++ .../MonacoEditor/Getting Started.md | 331 ++++++++ .../MonacoEditor/MonacoEditor.md | 367 +++++++++ .../MultimodalInput/Basic Usage.md | 324 ++++++++ .../MultimodalInput/Configuration Options.md | 330 ++++++++ .../MultimodalInput/File Upload.md | 464 +++++++++++ .../MultimodalInput/Integration Examples.md | 333 ++++++++ .../MultimodalInput/MultimodalInput.md | 399 ++++++++++ .wiki/en/Pro Components/Pro Components.md | 355 +++++++++ .../Pro Components/WebSandbox/Basic Usage.md | 329 ++++++++ .../WebSandbox/Configuration Options.md | 381 +++++++++ .../WebSandbox/Event Handling.md | 300 +++++++ .../WebSandbox/Integration Examples.md | 309 ++++++++ .../WebSandbox/Security Mechanism.md | 294 +++++++ .../Pro Components/WebSandbox/WebSandbox.md | 365 +++++++++ .wiki/en/Project Overview/Core Features.md | 321 ++++++++ .../Project Overview/Project Introduction.md | 441 +++++++++++ .wiki/en/Project Overview/Project Overview.md | 432 +++++++++++ .wiki/en/Project Overview/Tech Stack.md | 397 ++++++++++ .wiki/en/Project Overview/Use Cases.md | 337 ++++++++ .wiki/en/Project Overview/Version Info.md | 335 ++++++++ .wiki/en/Quick Start.md | 436 +++++++++++ .wiki/en/Troubleshooting.md | 400 ++++++++++ .../API \345\217\202\350\200\203.md" | 514 ++++++++++++ .../JavaScript API/JavaScript API.md" | 413 ++++++++++ .../Markdown \347\273\204\344\273\266 API.md" | 417 ++++++++++ ...44\273\266\346\241\245\346\216\245 API.md" | 378 +++++++++ ... Design X \347\273\204\344\273\266 API.md" | 436 +++++++++++ ...51\246\210\347\273\204\344\273\266 API.md" | 395 ++++++++++ ...51\206\222\347\273\204\344\273\266 API.md" | 348 +++++++++ ...45\205\267\347\273\204\344\273\266 API.md" | 377 +++++++++ ...50\256\244\347\273\204\344\273\266 API.md" | 331 ++++++++ ...50\276\276\347\273\204\344\273\266 API.md" | 344 +++++++++ ...47\224\250\347\273\204\344\273\266 API.md" | 518 +++++++++++++ ...nt Design \347\273\204\344\273\266 API.md" | 479 ++++++++++++ ...44\273\226\347\273\204\344\273\266 API.md" | 278 +++++++ ...51\246\210\347\273\204\344\273\266 API.md" | 383 +++++++++ ...50\210\252\347\273\204\344\273\266 API.md" | 462 +++++++++++ ...45\261\200\347\273\204\344\273\266 API.md" | 398 ++++++++++ ...47\244\272\347\273\204\344\273\266 API.md" | 578 ++++++++++++++ ...45\205\245\347\273\204\344\273\266 API.md" | 523 +++++++++++++ ...47\224\250\347\273\204\344\273\266 API.md" | 442 +++++++++++ .../Svelte \347\273\204\344\273\266 API.md" | 415 ++++++++++ ...44\270\232\347\273\204\344\273\266 API.md" | 413 ++++++++++ ...47\241\200\347\273\204\344\273\266 API.md" | 550 +++++++++++++ ...45\205\267\345\207\275\346\225\260 API.md" | 582 ++++++++++++++ .../Antd \347\273\204\344\273\266 API.md" | 371 +++++++++ ...44\273\226\347\273\204\344\273\266 API.md" | 422 ++++++++++ ...51\246\210\347\273\204\344\273\266 API.md" | 611 +++++++++++++++ ...50\210\252\347\273\204\344\273\266 API.md" | 578 ++++++++++++++ ...45\261\200\347\273\204\344\273\266 API.md" | 465 +++++++++++ ...47\244\272\347\273\204\344\273\266 API.md" | 661 ++++++++++++++++ ...45\205\245\347\273\204\344\273\266 API.md" | 453 +++++++++++ ...47\224\250\347\273\204\344\273\266 API.md" | 370 +++++++++ .../Antdx \347\273\204\344\273\266 API.md" | 443 +++++++++++ ...51\246\210\347\273\204\344\273\266 API.md" | 446 +++++++++++ ...51\206\222\347\273\204\344\273\266 API.md" | 334 ++++++++ ...45\205\267\347\273\204\344\273\266 API.md" | 399 ++++++++++ ...50\256\244\347\273\204\344\273\266 API.md" | 366 +++++++++ ...50\276\276\347\273\204\344\273\266 API.md" | 359 +++++++++ ...47\224\250\347\273\204\344\273\266 API.md" | 390 ++++++++++ .../Python API/Python API.md" | 433 +++++++++++ ...44\270\232\347\273\204\344\273\266 API.md" | 487 ++++++++++++ ...47\241\200\347\273\204\344\273\266 API.md" | 495 ++++++++++++ ...X \347\273\204\344\273\266\345\272\223.md" | 626 +++++++++++++++ ...m \346\223\215\344\275\234\351\241\271.md" | 258 +++++++ .../Actions \346\246\202\350\247\210.md" | 335 ++++++++ ...63\351\242\221\346\223\215\344\275\234.md" | 315 ++++++++ ...15\345\210\266\346\223\215\344\275\234.md" | 431 +++++++++++ ...15\351\246\210\346\223\215\344\275\234.md" | 268 +++++++ .../Item \345\256\271\345\231\250.md" | 318 ++++++++ ...15\351\246\210\347\273\204\344\273\266.md" | 340 ++++++++ ...72\351\233\206\347\273\204\344\273\266.md" | 408 ++++++++++ ...42\350\277\216\347\273\204\344\273\266.md" | 424 ++++++++++ ...44\351\206\222\347\273\204\344\273\266.md" | 293 +++++++ ...43\347\240\201\351\253\230\344\272\256.md" | 335 ++++++++ ...d \346\265\201\347\250\213\345\233\276.md" | 334 ++++++++ .../Notification \351\200\232\347\237\245.md" | 367 +++++++++ ...50\345\261\200\351\205\215\347\275\256.md" | 284 +++++++ ...45\345\205\267\347\273\204\344\273\266.md" | 374 +++++++++ ...41\347\211\207\347\273\204\344\273\266.md" | 441 +++++++++++ ...66\345\244\271\347\273\204\344\273\266.md" | 359 +++++++++ ...56\346\272\220\347\273\204\344\273\266.md" | 422 ++++++++++ ...35\350\200\203\347\273\204\344\273\266.md" | 457 +++++++++++ ...60\346\215\256\347\273\204\344\273\266.md" | 372 +++++++++ ...03\351\223\276\347\273\204\344\273\266.md" | 380 +++++++++ ...03\351\241\271\347\273\204\344\273\266.md" | 410 ++++++++++ ...56\350\256\244\347\273\204\344\273\266.md" | 408 ++++++++++ ...04\344\273\266\346\246\202\350\247\210.md" | 368 +++++++++ ...04\344\273\266\347\273\204\344\273\266.md" | 731 ++++++++++++++++++ ...01\345\231\250\347\273\204\344\273\266.md" | 315 ++++++++ ...07\344\273\244\347\273\204\344\273\266.md" | 338 ++++++++ ...50\350\276\276\347\273\204\344\273\266.md" | 322 ++++++++ ...71\350\257\235\346\260\224\346\263\241.md" | 407 ++++++++++ ...04\344\273\266\346\246\202\350\247\210.md" | 359 +++++++++ ...62\347\272\277\347\273\204\344\273\266.md" | 231 ++++++ ...57\351\241\271\347\273\204\344\273\266.md" | 390 ++++++++++ ...27\350\241\250\347\273\204\344\273\266.md" | 335 ++++++++ ...07\350\257\206\347\273\204\344\273\266.md" | 346 +++++++++ ...10\346\201\257\347\273\204\344\273\266.md" | 331 ++++++++ .../API \345\217\202\350\200\203.md" | 376 +++++++++ ...71\350\257\235\347\256\241\347\220\206.md" | 345 +++++++++ ...77\347\224\250\347\244\272\344\276\213.md" | 361 +++++++++ ...35\351\241\271\347\273\204\344\273\266.md" | 382 +++++++++ ...04\344\273\266\346\246\202\350\247\210.md" | 294 +++++++ ...32\347\224\250\347\273\204\344\273\266.md" | 310 ++++++++ ...n \347\273\204\344\273\266\345\272\223.md" | 531 +++++++++++++ ...66\344\273\226\347\273\204\344\273\266.md" | 325 ++++++++ ...46\345\221\212\346\217\220\347\244\272.md" | 287 +++++++ .../Drawer \346\212\275\345\261\211.md" | 348 +++++++++ .../Watermark \346\260\264\345\215\260.md" | 434 +++++++++++ ...15\351\246\210\347\273\204\344\273\266.md" | 301 ++++++++ ...50\346\236\266\347\273\204\344\273\266.md" | 327 ++++++++ ...15\351\246\210\347\273\204\344\273\266.md" | 437 +++++++++++ ...35\346\241\206\347\273\204\344\273\266.md" | 322 ++++++++ ...32\347\237\245\347\273\204\344\273\266.md" | 332 ++++++++ ...23\346\236\234\347\273\204\344\273\266.md" | 289 +++++++ ...225\347\273\204\344\273\266 (Dropdown).md" | 325 ++++++++ ...5\347\273\204\344\273\266 (Pagination).md" | 340 ++++++++ ...74\350\210\252\347\273\204\344\273\266.md" | 542 +++++++++++++ ...215\225\347\273\204\344\273\266 (Menu).md" | 344 +++++++++ ...35\241\347\273\204\344\273\266 (Steps).md" | 425 ++++++++++ ...2\271\347\273\204\344\273\266 (Anchor).md" | 302 ++++++++ ...1\347\273\204\344\273\266 (Breadcrumb).md" | 393 ++++++++++ ...r \345\210\206\345\211\262\347\272\277.md" | 291 +++++++ ...71\346\200\247\345\270\203\345\261\200.md" | 291 +++++++ .../Grid \346\240\205\346\240\274.md" | 348 +++++++++ .../Layout \345\270\203\345\261\200.md" | 295 +++++++ ...03\346\265\201\345\270\203\345\261\200.md" | 464 +++++++++++ .../Space \351\227\264\350\267\235.md" | 268 +++++++ ...06\345\211\262\351\235\242\346\235\277.md" | 387 ++++++++++ ...03\345\261\200\347\273\204\344\273\266.md" | 385 +++++++++ ...60\345\200\274\347\273\204\344\273\266.md" | 312 ++++++++ ...27\350\241\250\347\273\204\344\273\266.md" | 324 ++++++++ ...75\346\240\207\347\273\204\344\273\266.md" | 328 ++++++++ ...66\346\200\201\347\273\204\344\273\266.md" | 350 +++++++++ ...25\347\244\272\347\273\204\344\273\266.md" | 664 ++++++++++++++++ ...25\345\257\274\347\273\204\344\273\266.md" | 304 ++++++++ ...41\347\211\207\347\273\204\344\273\266.md" | 358 +++++++++ ...64\350\275\264\347\273\204\344\273\266.md" | 438 +++++++++++ ...47\344\273\266\347\273\204\344\273\266.md" | 348 +++++++++ ...64\347\240\201\347\273\204\344\273\266.md" | 332 ++++++++ ...76\351\241\265\347\273\204\344\273\266.md" | 340 ++++++++ ...30\345\217\240\347\273\204\344\273\266.md" | 317 ++++++++ ...25\345\205\245\347\273\204\344\273\266.md" | 520 +++++++++++++ ...66\351\227\264\347\273\204\344\273\266.md" | 463 +++++++++++ ...45\347\261\273\347\273\204\344\273\266.md" | 516 +++++++++++++ ...51\347\261\273\347\273\204\344\273\266.md" | 673 ++++++++++++++++ ...07\344\273\266\347\273\204\344\273\266.md" | 364 +++++++++ ...04\344\273\266\346\246\202\350\247\210.md" | 384 +++++++++ .../Button \346\214\211\351\222\256.md" | 312 ++++++++ ...54\346\265\256\346\214\211\351\222\256.md" | 351 +++++++++ .../Icon \345\233\276\346\240\207.md" | 360 +++++++++ .../Typography \346\216\222\347\211\210.md" | 251 ++++++ ...32\347\224\250\347\273\204\344\273\266.md" | 375 +++++++++ ...51\346\234\272\345\231\250\344\272\272.md" | 354 +++++++++ ...72\347\241\200\344\275\277\347\224\250.md" | 388 ++++++++++ ...41\346\200\201\346\224\257\346\214\201.md" | 401 ++++++++++ ...07\347\250\213\345\261\225\347\244\272.md" | 329 ++++++++ ...60\346\215\256\346\250\241\345\236\213.md" | 441 +++++++++++ ...10\346\201\257\345\244\204\347\220\206.md" | 397 ++++++++++ ...15\347\275\256\351\200\211\351\241\271.md" | 364 +++++++++ ...06\346\210\220\347\244\272\344\276\213.md" | 349 +++++++++ ...01\347\274\226\350\276\221\345\231\250.md" | 367 +++++++++ ...72\347\241\200\344\275\277\347\224\250.md" | 331 ++++++++ ...02\347\274\226\350\276\221\345\231\250.md" | 383 +++++++++ ...04\344\273\266\346\246\202\350\247\210.md" | 379 +++++++++ ...15\347\275\256\351\200\211\351\241\271.md" | 406 ++++++++++ ...30\347\272\247\345\212\237\350\203\275.md" | 305 ++++++++ ...01\350\276\223\345\205\245\346\241\206.md" | 401 ++++++++++ ...77\347\224\250\347\244\272\344\276\213.md" | 337 ++++++++ ...04\347\220\206\346\234\272\345\210\266.md" | 478 ++++++++++++ ...04\344\273\266\346\246\202\350\247\210.md" | 324 ++++++++ ...11\351\241\271\350\257\246\350\247\243.md" | 377 +++++++++ ...21\351\241\265\346\262\231\347\233\222.md" | 365 +++++++++ ...13\344\273\266\345\244\204\347\220\206.md" | 300 +++++++ ...77\347\224\250\347\244\272\344\276\213.md" | 309 ++++++++ ...11\345\205\250\346\234\272\345\210\266.md" | 294 +++++++ ...04\344\273\266\346\246\202\350\247\210.md" | 329 ++++++++ ...15\347\275\256\351\200\211\351\241\271.md" | 381 +++++++++ ...23\344\270\232\347\273\204\344\273\266.md" | 355 +++++++++ .../Application \347\273\204\344\273\266.md" | 424 ++++++++++ .../AutoLoading \347\273\204\344\273\266.md" | 339 ++++++++ .../Fragment \347\273\204\344\273\266.md" | 328 ++++++++ .../Slot \347\273\204\344\273\266.md" | 333 ++++++++ ...72\347\241\200\347\273\204\344\273\266.md" | 505 ++++++++++++ ...03\345\261\200\347\273\204\344\273\266.md" | 386 +++++++++ ...62\346\237\223\347\273\204\344\273\266.md" | 371 +++++++++ ...00\345\217\221\346\214\207\345\215\227.md" | 325 ++++++++ ...00\345\217\221\346\265\201\347\250\213.md" | 302 ++++++++ ...57\345\242\203\346\220\255\345\273\272.md" | 276 +++++++ ...07\346\241\243\347\263\273\347\273\237.md" | 382 +++++++++ ...72\344\270\216\351\203\250\347\275\262.md" | 370 +++++++++ ...25\344\270\216\350\260\203\350\257\225.md" | 311 ++++++++ ...04\344\273\266\345\274\200\345\217\221.md" | 418 ++++++++++ ...04\344\273\266\345\274\200\345\217\221.md" | 363 +++++++++ ...04\344\273\266\345\274\200\345\217\221.md" | 366 +++++++++ ...00\344\275\263\345\256\236\350\267\265.md" | 407 ++++++++++ ...07\346\241\243\347\274\226\345\206\231.md" | 345 +++++++++ ...04\344\273\266\346\265\213\350\257\225.md" | 310 ++++++++ ...41\347\214\256\346\214\207\345\215\227.md" | 317 ++++++++ ...53\351\200\237\345\274\200\345\247\213.md" | 436 +++++++++++ ...05\351\232\234\346\216\222\351\231\244.md" | 400 ++++++++++ ...21\345\270\203\346\265\201\347\250\213.md" | 441 +++++++++++ ...20\344\270\216\351\203\250\347\275\262.md" | 436 +++++++++++ ...04\345\273\272\346\265\201\347\250\213.md" | 405 ++++++++++ ...57\345\242\203\351\205\215\347\275\256.md" | 315 ++++++++ ...50\347\275\262\346\214\207\345\215\227.md" | 333 ++++++++ ...24\347\224\250\345\234\272\346\231\257.md" | 337 ++++++++ .../\346\212\200\346\234\257\346\240\210.md" | 397 ++++++++++ ...70\345\277\203\347\211\271\346\200\247.md" | 321 ++++++++ ...10\346\234\254\344\277\241\346\201\257.md" | 335 ++++++++ ...71\347\233\256\344\273\213\347\273\215.md" | 441 +++++++++++ ...71\347\233\256\346\246\202\350\277\260.md" | 432 +++++++++++ 382 files changed, 144246 insertions(+) create mode 100644 .wiki/en/API Reference/API Reference.md create mode 100644 .wiki/en/API Reference/JavaScript API/JavaScript API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Markdown Component API.md create mode 100644 .wiki/en/API Reference/JavaScript API/React Component Bridge API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Ant Design Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Display Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Entry Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Feedback Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/General Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Layout Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Navigation Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Other Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Ant Design X Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Awakening Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Confirmation Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Expression Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Feedback Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/General Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Tool Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Basic Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Pro Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Svelte Component API/Svelte Components API.md create mode 100644 .wiki/en/API Reference/JavaScript API/Utility Functions API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/Antd Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/Data Display Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/Data Entry Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/Feedback Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/General Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/Layout Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/Navigation Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antd Components API/Other Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antdx Components API/Antdx Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antdx Components API/Confirmation Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antdx Components API/Expression Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antdx Components API/Feedback Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antdx Components API/General Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antdx Components API/Utility Components API.md create mode 100644 .wiki/en/API Reference/Python API/Antdx Components API/Wake Components API.md create mode 100644 .wiki/en/API Reference/Python API/Basic Components API.md create mode 100644 .wiki/en/API Reference/Python API/Pro Components API.md create mode 100644 .wiki/en/API Reference/Python API/Python API.md create mode 100644 .wiki/en/Ant Design Components/Ant Design Components.md create mode 100644 .wiki/en/Ant Design Components/Components Overview.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Avatar and Badge.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Calendar and Card.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Carousel and Collapse.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Data Display Components.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Descriptions and Empty.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Image and List.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Popover and QRCode.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Segmented and Statistic.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Table and Tabs.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Tag and Timeline.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Tooltip and Tour.md create mode 100644 .wiki/en/Ant Design Components/Data Display Components/Tree.md create mode 100644 .wiki/en/Ant Design Components/Data Entry Components/Color and File Components.md create mode 100644 .wiki/en/Ant Design Components/Data Entry Components/Data Entry Components.md create mode 100644 .wiki/en/Ant Design Components/Data Entry Components/DateTime Components.md create mode 100644 .wiki/en/Ant Design Components/Data Entry Components/Input Components.md create mode 100644 .wiki/en/Ant Design Components/Data Entry Components/Selection Components.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Alert.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Drawer.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Feedback Components.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Interactive Feedback.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Message and Notification.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Modal.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Progress and Result.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Spin and Skeleton.md create mode 100644 .wiki/en/Ant Design Components/Feedback Components/Watermark.md create mode 100644 .wiki/en/Ant Design Components/General Components/Button.md create mode 100644 .wiki/en/Ant Design Components/General Components/FloatButton.md create mode 100644 .wiki/en/Ant Design Components/General Components/General Components.md create mode 100644 .wiki/en/Ant Design Components/General Components/Icon.md create mode 100644 .wiki/en/Ant Design Components/General Components/Typography.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Divider.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Flex.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Grid.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Layout Components.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Layout.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Masonry.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Space.md create mode 100644 .wiki/en/Ant Design Components/Layout Components/Splitter.md create mode 100644 .wiki/en/Ant Design Components/Navigation Components/Anchor.md create mode 100644 .wiki/en/Ant Design Components/Navigation Components/Breadcrumb.md create mode 100644 .wiki/en/Ant Design Components/Navigation Components/Dropdown.md create mode 100644 .wiki/en/Ant Design Components/Navigation Components/Menu.md create mode 100644 .wiki/en/Ant Design Components/Navigation Components/Navigation Components.md create mode 100644 .wiki/en/Ant Design Components/Navigation Components/Pagination.md create mode 100644 .wiki/en/Ant Design Components/Navigation Components/Steps.md create mode 100644 .wiki/en/Ant Design Components/Other Components.md create mode 100644 .wiki/en/Ant Design X Components/Ant Design X Components.md create mode 100644 .wiki/en/Ant Design X Components/Components Overview.md create mode 100644 .wiki/en/Ant Design X Components/Confirmation Components/Confirmation Components.md create mode 100644 .wiki/en/Ant Design X Components/Confirmation Components/ThoughtChain Component.md create mode 100644 .wiki/en/Ant Design X Components/Confirmation Components/ThoughtChainItem Component.md create mode 100644 .wiki/en/Ant Design X Components/Data Components/Data Components.md create mode 100644 .wiki/en/Ant Design X Components/Data Components/FileCard Component.md create mode 100644 .wiki/en/Ant Design X Components/Data Components/Folder Component.md create mode 100644 .wiki/en/Ant Design X Components/Data Components/Sources Component.md create mode 100644 .wiki/en/Ant Design X Components/Data Components/Think Component.md create mode 100644 .wiki/en/Ant Design X Components/Expression Components/Attachments Component.md create mode 100644 .wiki/en/Ant Design X Components/Expression Components/Expression Components.md create mode 100644 .wiki/en/Ant Design X Components/Expression Components/Sender Component.md create mode 100644 .wiki/en/Ant Design X Components/Expression Components/Suggestion Component.md create mode 100644 .wiki/en/Ant Design X Components/Feedback Components/ActionItem Component.md create mode 100644 .wiki/en/Ant Design X Components/Feedback Components/Actions Overview.md create mode 100644 .wiki/en/Ant Design X Components/Feedback Components/Audio Component.md create mode 100644 .wiki/en/Ant Design X Components/Feedback Components/Copy Component.md create mode 100644 .wiki/en/Ant Design X Components/Feedback Components/Feedback Component.md create mode 100644 .wiki/en/Ant Design X Components/Feedback Components/Feedback Components.md create mode 100644 .wiki/en/Ant Design X Components/Feedback Components/Item Component.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Chat Bubble.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Component Overview.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Divider Component.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Item Component.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.List Component.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Role Component.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.System Component.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Conversations/API Reference.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Conversations/Component Overview.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Conversations/Conversation Item Component.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Conversations/Conversations Management.md create mode 100644 .wiki/en/Ant Design X Components/General Components/Conversations/Usage Examples.md create mode 100644 .wiki/en/Ant Design X Components/General Components/General Components.md create mode 100644 .wiki/en/Ant Design X Components/Tool Components/CodeHighlighter Component.md create mode 100644 .wiki/en/Ant Design X Components/Tool Components/Mermaid Component.md create mode 100644 .wiki/en/Ant Design X Components/Tool Components/Notification Component.md create mode 100644 .wiki/en/Ant Design X Components/Tool Components/Tool Components.md create mode 100644 .wiki/en/Ant Design X Components/Tool Components/XProvider Component.md create mode 100644 .wiki/en/Ant Design X Components/Wake Components/Prompts Component.md create mode 100644 .wiki/en/Ant Design X Components/Wake Components/Wake Components.md create mode 100644 .wiki/en/Ant Design X Components/Wake Components/Welcome Component.md create mode 100644 .wiki/en/Base Components/Application Component.md create mode 100644 .wiki/en/Base Components/AutoLoading Component.md create mode 100644 .wiki/en/Base Components/Base Components.md create mode 100644 .wiki/en/Base Components/Fragment Component.md create mode 100644 .wiki/en/Base Components/Layout Components.md create mode 100644 .wiki/en/Base Components/Rendering Components.md create mode 100644 .wiki/en/Base Components/Slot Component.md create mode 100644 .wiki/en/Deployment Guide/Build Process.md create mode 100644 .wiki/en/Deployment Guide/CI CD.md create mode 100644 .wiki/en/Deployment Guide/Deployment Guide.md create mode 100644 .wiki/en/Deployment Guide/Environment Configuration.md create mode 100644 .wiki/en/Deployment Guide/Release Process.md create mode 100644 .wiki/en/Development Guide/Build and Deploy.md create mode 100644 .wiki/en/Development Guide/Component Development/Backend Component Development.md create mode 100644 .wiki/en/Development Guide/Component Development/Component Development Best Practices.md create mode 100644 .wiki/en/Development Guide/Component Development/Component Development.md create mode 100644 .wiki/en/Development Guide/Component Development/Component Documentation Writing.md create mode 100644 .wiki/en/Development Guide/Component Development/Component Testing.md create mode 100644 .wiki/en/Development Guide/Component Development/Frontend Component Development.md create mode 100644 .wiki/en/Development Guide/Contributing Guide.md create mode 100644 .wiki/en/Development Guide/Development Guide.md create mode 100644 .wiki/en/Development Guide/Development Workflow.md create mode 100644 .wiki/en/Development Guide/Documentation System.md create mode 100644 .wiki/en/Development Guide/Environment Setup.md create mode 100644 .wiki/en/Development Guide/Testing and Debugging.md create mode 100644 .wiki/en/Pro Components/Chatbot/Basic Usage.md create mode 100644 .wiki/en/Pro Components/Chatbot/Chatbot.md create mode 100644 .wiki/en/Pro Components/Chatbot/Configuration Options.md create mode 100644 .wiki/en/Pro Components/Chatbot/Data Model.md create mode 100644 .wiki/en/Pro Components/Chatbot/Integration Examples.md create mode 100644 .wiki/en/Pro Components/Chatbot/Message Processing.md create mode 100644 .wiki/en/Pro Components/Chatbot/Multimodal Support.md create mode 100644 .wiki/en/Pro Components/Chatbot/Thinking Process Display.md create mode 100644 .wiki/en/Pro Components/MonacoEditor/Advanced Features.md create mode 100644 .wiki/en/Pro Components/MonacoEditor/Basic Usage.md create mode 100644 .wiki/en/Pro Components/MonacoEditor/Configuration Options.md create mode 100644 .wiki/en/Pro Components/MonacoEditor/Diff Editor.md create mode 100644 .wiki/en/Pro Components/MonacoEditor/Getting Started.md create mode 100644 .wiki/en/Pro Components/MonacoEditor/MonacoEditor.md create mode 100644 .wiki/en/Pro Components/MultimodalInput/Basic Usage.md create mode 100644 .wiki/en/Pro Components/MultimodalInput/Configuration Options.md create mode 100644 .wiki/en/Pro Components/MultimodalInput/File Upload.md create mode 100644 .wiki/en/Pro Components/MultimodalInput/Integration Examples.md create mode 100644 .wiki/en/Pro Components/MultimodalInput/MultimodalInput.md create mode 100644 .wiki/en/Pro Components/Pro Components.md create mode 100644 .wiki/en/Pro Components/WebSandbox/Basic Usage.md create mode 100644 .wiki/en/Pro Components/WebSandbox/Configuration Options.md create mode 100644 .wiki/en/Pro Components/WebSandbox/Event Handling.md create mode 100644 .wiki/en/Pro Components/WebSandbox/Integration Examples.md create mode 100644 .wiki/en/Pro Components/WebSandbox/Security Mechanism.md create mode 100644 .wiki/en/Pro Components/WebSandbox/WebSandbox.md create mode 100644 .wiki/en/Project Overview/Core Features.md create mode 100644 .wiki/en/Project Overview/Project Introduction.md create mode 100644 .wiki/en/Project Overview/Project Overview.md create mode 100644 .wiki/en/Project Overview/Tech Stack.md create mode 100644 .wiki/en/Project Overview/Use Cases.md create mode 100644 .wiki/en/Project Overview/Version Info.md create mode 100644 .wiki/en/Quick Start.md create mode 100644 .wiki/en/Troubleshooting.md create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/API \345\217\202\350\200\203.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/JavaScript API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Markdown \347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/React \347\273\204\344\273\266\346\241\245\346\216\245 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API/\345\217\215\351\246\210\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API/\345\224\244\351\206\222\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API/\345\267\245\345\205\267\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API/\347\241\256\350\256\244\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API/\350\241\250\350\276\276\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design X \347\273\204\344\273\266 API/\351\200\232\347\224\250\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/\345\205\266\344\273\226\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/\345\217\215\351\246\210\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/\345\257\274\350\210\252\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/\345\270\203\345\261\200\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Ant Design \347\273\204\344\273\266 API/\351\200\232\347\224\250\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/Svelte \347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/\344\270\223\344\270\232\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/Svelte \347\273\204\344\273\266 API/\345\237\272\347\241\200\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/JavaScript API/\345\267\245\345\205\267\345\207\275\346\225\260 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/Antd \347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/\345\205\266\344\273\226\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/\345\217\215\351\246\210\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/\345\257\274\350\210\252\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/\345\270\203\345\261\200\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antd \347\273\204\344\273\266 API/\351\200\232\347\224\250\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antdx \347\273\204\344\273\266 API/Antdx \347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antdx \347\273\204\344\273\266 API/\345\217\215\351\246\210\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antdx \347\273\204\344\273\266 API/\345\224\244\351\206\222\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antdx \347\273\204\344\273\266 API/\345\267\245\345\205\267\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antdx \347\273\204\344\273\266 API/\347\241\256\350\256\244\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antdx \347\273\204\344\273\266 API/\350\241\250\350\276\276\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Antdx \347\273\204\344\273\266 API/\351\200\232\347\224\250\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/Python API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/\344\270\223\344\270\232\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/API \345\217\202\350\200\203/Python API/\345\237\272\347\241\200\347\273\204\344\273\266 API.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/Ant Design X \347\273\204\344\273\266\345\272\223.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/ActionItem \346\223\215\344\275\234\351\241\271.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Actions \346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Audio \351\237\263\351\242\221\346\223\215\344\275\234.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Copy \345\244\215\345\210\266\346\223\215\344\275\234.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Feedback \345\217\215\351\246\210\346\223\215\344\275\234.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Item \345\256\271\345\231\250.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/\345\217\215\351\246\210\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\224\244\351\206\222\347\273\204\344\273\266/Prompts \346\217\220\347\244\272\351\233\206\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\224\244\351\206\222\347\273\204\344\273\266/Welcome \346\254\242\350\277\216\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\224\244\351\206\222\347\273\204\344\273\266/\345\224\244\351\206\222\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\267\245\345\205\267\347\273\204\344\273\266/CodeHighlighter \344\273\243\347\240\201\351\253\230\344\272\256.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\267\245\345\205\267\347\273\204\344\273\266/Mermaid \346\265\201\347\250\213\345\233\276.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\267\245\345\205\267\347\273\204\344\273\266/Notification \351\200\232\347\237\245.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\267\245\345\205\267\347\273\204\344\273\266/XProvider \345\205\250\345\261\200\351\205\215\347\275\256.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\345\267\245\345\205\267\347\273\204\344\273\266/\345\267\245\345\205\267\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\347\273\204\344\273\266/FileCard \346\226\207\344\273\266\345\215\241\347\211\207\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\347\273\204\344\273\266/Folder \346\226\207\344\273\266\345\244\271\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\347\273\204\344\273\266/Sources \346\225\260\346\215\256\346\272\220\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\347\273\204\344\273\266/Think \346\200\235\350\200\203\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\347\273\204\344\273\266/\346\225\260\346\215\256\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\347\241\256\350\256\244\347\273\204\344\273\266/ThoughtChain \346\200\235\350\200\203\351\223\276\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\347\241\256\350\256\244\347\273\204\344\273\266/ThoughtChainItem \346\200\235\350\200\203\351\241\271\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\347\241\256\350\256\244\347\273\204\344\273\266/\347\241\256\350\256\244\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\347\273\204\344\273\266\346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\350\241\250\350\276\276\347\273\204\344\273\266/Attachments \351\231\204\344\273\266\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\350\241\250\350\276\276\347\273\204\344\273\266/Sender \345\217\221\351\200\201\345\231\250\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\350\241\250\350\276\276\347\273\204\344\273\266/Suggestion \345\277\253\346\215\267\346\214\207\344\273\244\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\350\241\250\350\276\276\347\273\204\344\273\266/\350\241\250\350\276\276\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Bubble \345\257\271\350\257\235\346\260\224\346\263\241/Bubble \345\257\271\350\257\235\346\260\224\346\263\241.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Bubble \345\257\271\350\257\235\346\260\224\346\263\241/Bubble \347\273\204\344\273\266\346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Bubble \345\257\271\350\257\235\346\260\224\346\263\241/Bubble.Divider \345\210\206\345\211\262\347\272\277\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Bubble \345\257\271\350\257\235\346\260\224\346\263\241/Bubble.Item \346\266\210\346\201\257\351\241\271\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Bubble \345\257\271\350\257\235\346\260\224\346\263\241/Bubble.List \345\210\227\350\241\250\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Bubble \345\257\271\350\257\235\346\260\224\346\263\241/Bubble.Role \350\247\222\350\211\262\346\240\207\350\257\206\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Bubble \345\257\271\350\257\235\346\260\224\346\263\241/Bubble.System \347\263\273\347\273\237\346\266\210\346\201\257\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Conversations \345\257\271\350\257\235\347\256\241\347\220\206/API \345\217\202\350\200\203.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Conversations \345\257\271\350\257\235\347\256\241\347\220\206/Conversations \345\257\271\350\257\235\347\256\241\347\220\206.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Conversations \345\257\271\350\257\235\347\256\241\347\220\206/\344\275\277\347\224\250\347\244\272\344\276\213.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Conversations \345\257\271\350\257\235\347\256\241\347\220\206/\345\257\271\350\257\235\351\241\271\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Conversations \345\257\271\350\257\235\347\256\241\347\220\206/\347\273\204\344\273\266\346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/Ant Design X \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/\351\200\232\347\224\250\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/Ant Design \347\273\204\344\273\266\345\272\223.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\205\266\344\273\226\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Alert \350\255\246\345\221\212\346\217\220\347\244\272.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Drawer \346\212\275\345\261\211.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/Watermark \346\260\264\345\215\260.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/\344\272\244\344\272\222\345\217\215\351\246\210\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/\345\212\240\350\275\275\351\252\250\346\236\266\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/\345\217\215\351\246\210\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/\346\250\241\346\200\201\345\257\271\350\257\235\346\241\206\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/\346\266\210\346\201\257\351\200\232\347\237\245\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\217\215\351\246\210\347\273\204\344\273\266/\350\277\233\345\272\246\347\273\223\346\236\234\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\257\274\350\210\252\347\273\204\344\273\266/\344\270\213\346\213\211\350\217\234\345\215\225\347\273\204\344\273\266 (Dropdown).md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\257\274\350\210\252\347\273\204\344\273\266/\345\210\206\351\241\265\347\273\204\344\273\266 (Pagination).md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\257\274\350\210\252\347\273\204\344\273\266/\345\257\274\350\210\252\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\257\274\350\210\252\347\273\204\344\273\266/\345\257\274\350\210\252\350\217\234\345\215\225\347\273\204\344\273\266 (Menu).md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\257\274\350\210\252\347\273\204\344\273\266/\346\255\245\351\252\244\346\235\241\347\273\204\344\273\266 (Steps).md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\257\274\350\210\252\347\273\204\344\273\266/\351\224\232\347\202\271\347\273\204\344\273\266 (Anchor).md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\257\274\350\210\252\347\273\204\344\273\266/\351\235\242\345\214\205\345\261\221\347\273\204\344\273\266 (Breadcrumb).md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/Divider \345\210\206\345\211\262\347\272\277.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/Flex \345\274\271\346\200\247\345\270\203\345\261\200.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/Grid \346\240\205\346\240\274.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/Layout \345\270\203\345\261\200.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/Masonry \347\200\221\345\270\203\346\265\201\345\270\203\345\261\200.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/Space \351\227\264\350\267\235.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/Splitter \345\210\206\345\211\262\351\235\242\346\235\277.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\345\270\203\345\261\200\347\273\204\344\273\266/\345\270\203\345\261\200\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\345\210\206\346\256\265\346\216\247\345\210\266\345\231\250\344\270\216\347\273\237\350\256\241\346\225\260\345\200\274\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\345\233\276\347\211\207\344\270\216\345\210\227\350\241\250\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\345\244\264\345\203\217\344\270\216\345\276\275\346\240\207\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\346\217\217\350\277\260\345\210\227\350\241\250\344\270\216\347\251\272\347\212\266\346\200\201\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\346\226\207\345\255\227\346\217\220\347\244\272\344\270\216\346\274\253\346\270\270\345\274\225\345\257\274\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\346\227\245\345\216\206\344\270\216\345\215\241\347\211\207\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\346\240\207\347\255\276\344\270\216\346\227\266\351\227\264\350\275\264\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\346\240\221\345\275\242\346\216\247\344\273\266\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\346\260\224\346\263\241\345\215\241\347\211\207\344\270\216\344\272\214\347\273\264\347\240\201\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\350\241\250\346\240\274\344\270\216\346\240\207\347\255\276\351\241\265\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\261\225\347\244\272\347\273\204\344\273\266/\350\275\256\346\222\255\344\270\216\346\212\230\345\217\240\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266/\346\227\245\346\234\237\346\227\266\351\227\264\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266/\350\276\223\345\205\245\347\261\273\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266/\351\200\211\346\213\251\347\261\273\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\346\225\260\346\215\256\345\275\225\345\205\245\347\273\204\344\273\266/\351\242\234\350\211\262\346\226\207\344\273\266\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\347\273\204\344\273\266\346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Button \346\214\211\351\222\256.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/FloatButton \346\202\254\346\265\256\346\214\211\351\222\256.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Icon \345\233\276\346\240\207.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/Typography \346\216\222\347\211\210.md" create mode 100644 ".wiki/zh/Ant Design \347\273\204\344\273\266\345\272\223/\351\200\232\347\224\250\347\273\204\344\273\266/\351\200\232\347\224\250\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/\345\237\272\347\241\200\344\275\277\347\224\250.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/\345\244\232\346\250\241\346\200\201\346\224\257\346\214\201.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/\346\200\235\350\200\203\350\277\207\347\250\213\345\261\225\347\244\272.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/\346\225\260\346\215\256\346\250\241\345\236\213.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/\346\266\210\346\201\257\345\244\204\347\220\206.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/\351\205\215\347\275\256\351\200\211\351\241\271.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/Chatbot \350\201\212\345\244\251\346\234\272\345\231\250\344\272\272/\351\233\206\346\210\220\347\244\272\344\276\213.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MonacoEditor \344\273\243\347\240\201\347\274\226\350\276\221\345\231\250/MonacoEditor \344\273\243\347\240\201\347\274\226\350\276\221\345\231\250.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MonacoEditor \344\273\243\347\240\201\347\274\226\350\276\221\345\231\250/\345\237\272\347\241\200\344\275\277\347\224\250.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MonacoEditor \344\273\243\347\240\201\347\274\226\350\276\221\345\231\250/\345\267\256\345\274\202\347\274\226\350\276\221\345\231\250.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MonacoEditor \344\273\243\347\240\201\347\274\226\350\276\221\345\231\250/\347\273\204\344\273\266\346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MonacoEditor \344\273\243\347\240\201\347\274\226\350\276\221\345\231\250/\351\205\215\347\275\256\351\200\211\351\241\271.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MonacoEditor \344\273\243\347\240\201\347\274\226\350\276\221\345\231\250/\351\253\230\347\272\247\345\212\237\350\203\275.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MultimodalInput \345\244\232\346\250\241\346\200\201\350\276\223\345\205\245\346\241\206/MultimodalInput \345\244\232\346\250\241\346\200\201\350\276\223\345\205\245\346\241\206.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MultimodalInput \345\244\232\346\250\241\346\200\201\350\276\223\345\205\245\346\241\206/\344\275\277\347\224\250\347\244\272\344\276\213.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MultimodalInput \345\244\232\346\250\241\346\200\201\350\276\223\345\205\245\346\241\206/\346\225\260\346\215\256\345\244\204\347\220\206\346\234\272\345\210\266.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MultimodalInput \345\244\232\346\250\241\346\200\201\350\276\223\345\205\245\346\241\206/\347\273\204\344\273\266\346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/MultimodalInput \345\244\232\346\250\241\346\200\201\350\276\223\345\205\245\346\241\206/\351\205\215\347\275\256\351\200\211\351\241\271\350\257\246\350\247\243.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/WebSandbox \347\275\221\351\241\265\346\262\231\347\233\222/WebSandbox \347\275\221\351\241\265\346\262\231\347\233\222.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/WebSandbox \347\275\221\351\241\265\346\262\231\347\233\222/\344\272\213\344\273\266\345\244\204\347\220\206.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/WebSandbox \347\275\221\351\241\265\346\262\231\347\233\222/\344\275\277\347\224\250\347\244\272\344\276\213.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/WebSandbox \347\275\221\351\241\265\346\262\231\347\233\222/\345\256\211\345\205\250\346\234\272\345\210\266.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/WebSandbox \347\275\221\351\241\265\346\262\231\347\233\222/\347\273\204\344\273\266\346\246\202\350\247\210.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/WebSandbox \347\275\221\351\241\265\346\262\231\347\233\222/\351\205\215\347\275\256\351\200\211\351\241\271.md" create mode 100644 ".wiki/zh/\344\270\223\344\270\232\347\273\204\344\273\266/\344\270\223\344\270\232\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\237\272\347\241\200\347\273\204\344\273\266/Application \347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\237\272\347\241\200\347\273\204\344\273\266/AutoLoading \347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\237\272\347\241\200\347\273\204\344\273\266/Fragment \347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\237\272\347\241\200\347\273\204\344\273\266/Slot \347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\237\272\347\241\200\347\273\204\344\273\266/\345\237\272\347\241\200\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\237\272\347\241\200\347\273\204\344\273\266/\345\270\203\345\261\200\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\237\272\347\241\200\347\273\204\344\273\266/\346\270\262\346\237\223\347\273\204\344\273\266.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\345\274\200\345\217\221\346\214\207\345\215\227.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\345\274\200\345\217\221\346\265\201\347\250\213.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\345\274\200\345\217\221\347\216\257\345\242\203\346\220\255\345\273\272.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\346\226\207\346\241\243\347\263\273\347\273\237.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\346\236\204\345\273\272\344\270\216\351\203\250\347\275\262.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\346\265\213\350\257\225\344\270\216\350\260\203\350\257\225.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\347\273\204\344\273\266\345\274\200\345\217\221/\345\211\215\347\253\257\347\273\204\344\273\266\345\274\200\345\217\221.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\347\273\204\344\273\266\345\274\200\345\217\221/\345\220\216\347\253\257\347\273\204\344\273\266\345\274\200\345\217\221.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\347\273\204\344\273\266\345\274\200\345\217\221/\347\273\204\344\273\266\345\274\200\345\217\221.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\347\273\204\344\273\266\345\274\200\345\217\221/\347\273\204\344\273\266\345\274\200\345\217\221\346\234\200\344\275\263\345\256\236\350\267\265.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\347\273\204\344\273\266\345\274\200\345\217\221/\347\273\204\344\273\266\346\226\207\346\241\243\347\274\226\345\206\231.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\347\273\204\344\273\266\345\274\200\345\217\221/\347\273\204\344\273\266\346\265\213\350\257\225.md" create mode 100644 ".wiki/zh/\345\274\200\345\217\221\346\214\207\345\215\227/\350\264\241\347\214\256\346\214\207\345\215\227.md" create mode 100644 ".wiki/zh/\345\277\253\351\200\237\345\274\200\345\247\213.md" create mode 100644 ".wiki/zh/\346\225\205\351\232\234\346\216\222\351\231\244.md" create mode 100644 ".wiki/zh/\351\203\250\347\275\262\346\214\207\345\215\227/\345\217\221\345\270\203\346\265\201\347\250\213.md" create mode 100644 ".wiki/zh/\351\203\250\347\275\262\346\214\207\345\215\227/\346\214\201\347\273\255\351\233\206\346\210\220\344\270\216\351\203\250\347\275\262.md" create mode 100644 ".wiki/zh/\351\203\250\347\275\262\346\214\207\345\215\227/\346\236\204\345\273\272\346\265\201\347\250\213.md" create mode 100644 ".wiki/zh/\351\203\250\347\275\262\346\214\207\345\215\227/\347\216\257\345\242\203\351\205\215\347\275\256.md" create mode 100644 ".wiki/zh/\351\203\250\347\275\262\346\214\207\345\215\227/\351\203\250\347\275\262\346\214\207\345\215\227.md" create mode 100644 ".wiki/zh/\351\241\271\347\233\256\346\246\202\350\277\260/\345\272\224\347\224\250\345\234\272\346\231\257.md" create mode 100644 ".wiki/zh/\351\241\271\347\233\256\346\246\202\350\277\260/\346\212\200\346\234\257\346\240\210.md" create mode 100644 ".wiki/zh/\351\241\271\347\233\256\346\246\202\350\277\260/\346\240\270\345\277\203\347\211\271\346\200\247.md" create mode 100644 ".wiki/zh/\351\241\271\347\233\256\346\246\202\350\277\260/\347\211\210\346\234\254\344\277\241\346\201\257.md" create mode 100644 ".wiki/zh/\351\241\271\347\233\256\346\246\202\350\277\260/\351\241\271\347\233\256\344\273\213\347\273\215.md" create mode 100644 ".wiki/zh/\351\241\271\347\233\256\346\246\202\350\277\260/\351\241\271\347\233\256\346\246\202\350\277\260.md" diff --git a/.wiki/en/API Reference/API Reference.md b/.wiki/en/API Reference/API Reference.md new file mode 100644 index 00000000..c7324149 --- /dev/null +++ b/.wiki/en/API Reference/API Reference.md @@ -0,0 +1,514 @@ +# API Reference + + +**Files Referenced in This Document** +- [backend/modelscope_studio/__init__.py](file://backend/modelscope_studio/__init__.py) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) +- [backend/modelscope_studio/components/__init__.py](file://backend/modelscope_studio/components/__init__.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/base/application/application.ts](file://frontend/base/application/application.ts) +- [frontend/pro/chatbot/chatbot.ts](file://frontend/pro/chatbot/chatbot.ts) +- [frontend/pro/monaco-editor/monaco-editor.ts](file://frontend/pro/monaco-editor/monaco-editor.ts) +- [frontend/pro/multimodal-input/multimodal-input.ts](file://frontend/pro/multimodal-input/multimodal-input.ts) +- [frontend/pro/web-sandbox/web-sandbox.ts](file://frontend/pro/web-sandbox/web-sandbox.ts) +- [frontend/utils/hooks/useAsyncEffect.ts](file://frontend/utils/hooks/useAsyncEffect.ts) +- [frontend/utils/hooks/useAsyncMemo.ts](file://frontend/utils/hooks/useAsyncMemo.ts) +- [frontend/utils/hooks/useDeepCompareEffect.ts](file://frontend/utils/hooks/useDeepCompareEffect.ts) +- [frontend/utils/hooks/useEvent.ts](file://frontend/utils/hooks/useEvent.ts) +- [frontend/utils/hooks/useMount.ts](file://frontend/utils/hooks/useMount.ts) +- [frontend/utils/hooks/useUnmount.ts](file://frontend/utils/hooks/useUnmount.ts) +- [frontend/utils/hooks/useUpdateEffect.ts](file://frontend/utils/hooks/useUpdateEffect.ts) +- [frontend/utils/createFunction.ts](file://frontend/utils/createFunction.ts) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/patchProps.tsx](file://frontend/utils/patchProps.tsx) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) +- [frontend/utils/tick.ts](file://frontend/utils/tick.ts) +- [frontend/utils/upload.ts](file://frontend/utils/upload.ts) +- [frontend/globals/components/index.ts](file://frontend/globals/components/index.ts) +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the complete API reference for ModelScope Studio, covering both the Python backend component system and the frontend JavaScript/Svelte component system. The Python API provides a third-party component library wrapper based on Gradio, the frontend is implemented in Svelte, and the two work together through Gradio's custom component mechanism. This document is intended for developers and covers component import methods, class definitions, method signatures, parameter descriptions, return value types (Python), component props and events (JavaScript/Svelte), lifecycle hooks, public methods, usage examples, and notes, along with supplementary parameter validation rules, error handling mechanisms, and version compatibility information. + +## Project Structure + +ModelScope Studio adopts a multi-package structure with frontend-backend separation: + +- Backend Python Package: `modelscope_studio`, providing component exports and version information +- Frontend Svelte Packages: Multiple sub-packages organized by functional domain (antd, antdx, base, pro), with utility functions and a global component entry +- Build and Release: Custom component builds via the Gradio CLI, with support for disabling auto-generated documentation + +```mermaid +graph TB +subgraph "Backend Python" +PY_PKG["modelscope_studio Package"] +PY_VERSION["Version Information"] +PY_EXPORTS["Component Exports"] +end +subgraph "Frontend Svelte" +FE_ANTD["antd Sub-Package"] +FE_ANTDX["antdx Sub-Package"] +FE_BASE["base Sub-Package"] +FE_PRO["pro Sub-Package"] +FE_UTILS["utils Utility Set"] +FE_GLOBALS["globals Global Components"] +end +PY_PKG --> PY_EXPORTS +PY_EXPORTS --> FE_ANTD +PY_EXPORTS --> FE_ANTDX +PY_EXPORTS --> FE_BASE +PY_EXPORTS --> FE_PRO +FE_ANTD --> FE_UTILS +FE_ANTDX --> FE_UTILS +FE_BASE --> FE_UTILS +FE_PRO --> FE_UTILS +FE_GLOBALS --> FE_UTILS +``` + +Diagram Sources + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [frontend/globals/components/index.ts:1-2](file://frontend/globals/components/index.ts#L1-L2) + +Section Sources + +- [backend/modelscope_studio/**init**.py:1-3](file://backend/modelscope_studio/__init__.py#L1-L3) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [frontend/globals/components/index.ts:1-2](file://frontend/globals/components/index.ts#L1-L2) + +## Core Components + +This section provides an overview of the export and organization of Python and frontend components, helping developers quickly locate target components. + +- Python Imports and Exports + - Root package export: Imports all components from the `components` module and exposes the version number + - Component aggregation: Grouped exports by domain (antd, antdx, base, pro) + - antd sub-package: Exports numerous UI component aliases for direct use + - antdx sub-package: Exports conversation and content-related components +- Frontend Component Organization + - Each component typically corresponds to a Svelte file (e.g., `button.tsx`, `form.tsx`, `table.tsx`) + - Utility functions are centralized in `utils`, including hooks, renderers, prop patching, etc. + - `globals` provides the global component entry point, currently exporting the `markdown` sub-module + +Section Sources + +- [backend/modelscope_studio/**init**.py:1-3](file://backend/modelscope_studio/__init__.py#L1-L3) +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [frontend/globals/components/index.ts:1-2](file://frontend/globals/components/index.ts#L1-L2) + +## Architecture Overview + +The diagram below shows the interaction and data flow between the Python backend and frontend components: + +```mermaid +graph TB +PY_API["Python API
modelscope_studio.components.*"] +GRADIO["Gradio Runtime"] +FE_COMP["Frontend Components
Svelte Component Tree"] +UTILS["Frontend Utilities
hooks & renderers"] +PY_API --> GRADIO +GRADIO --> FE_COMP +FE_COMP --> UTILS +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) + +## Detailed Component Analysis + +### Python API Reference (Overview) + +- Version and Dependencies + - Version: 2.0.0-beta.1 + - Dependencies: Gradio 6.0 ≤ v ≤ 6.8.0 +- Import Methods + - `from modelscope_studio import ComponentName` + - Or `from modelscope_studio.components.antd import ComponentName` + - Or `from modelscope_studio.components.antdx import ComponentName` + - Or `from modelscope_studio.components.pro import Chatbot, MonacoEditor, MultimodalInput, WebSandbox` +- Classes and Aliases + - The antd sub-package exports numerous component aliases such as Button, Form, Table, etc. + - The antdx sub-package exports conversation and content-related components such as Bubble, Chatbot, Sender, etc. + - The pro sub-package exports professional capability components: Chatbot, MonacoEditor (including sub-component MonacoEditorDiffEditor), MultimodalInput, WebSandbox +- Example Paths + - Refer to component examples under `docs/demos` (e.g., the chatbot example) +- Notes + - Ensure the Gradio version meets the range requirements + - Some components may require additional frontend templates or assets (bundled by the build system) + +Section Sources + +- [pyproject.toml:26-26](file://pyproject.toml#L26-L26) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) + +### JavaScript/Svelte API Reference (Overview) + +- Component Organization + - antd: General UI components such as Button, Form, Table, etc. + - antdx: Conversation and content extension components such as Bubble, Sender, ThoughtChain, etc. + - base: Base container and logic components such as Application, Each, Filter, etc. + - pro: Professional capability components such as Chatbot, MonacoEditor, MultimodalInput, WebSandbox +- Props, Events, and Lifecycle + - Props: Passed via `props`, following Svelte conventions + - Events: Via `$on`/`$off` or Svelte event binding + - Lifecycle: mount/unmount/update and other hooks provided by the hooks utilities +- Public Methods + - Callable methods created via tools like `createFunction` + - Upload, slot rendering, prop patching, etc. provided by `utils` + +Section Sources + +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/base/application/application.ts](file://frontend/base/application/application.ts) +- [frontend/pro/chatbot/chatbot.ts](file://frontend/pro/chatbot/chatbot.ts) +- [frontend/pro/monaco-editor/monaco-editor.ts](file://frontend/pro/monaco-editor/monaco-editor.ts) +- [frontend/pro/multimodal-input/multimodal-input.ts](file://frontend/pro/multimodal-input/multimodal-input.ts) +- [frontend/pro/web-sandbox/web-sandbox.ts](file://frontend/pro/web-sandbox/web-sandbox.ts) + +### Component A: Button + +- Python Import and Alias + - `from modelscope_studio.components.antd import Button` +- Frontend Component + - Path: `frontend/antd/button/button.tsx` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file + - Lifecycle: Managed via hooks (e.g., `useMount`, `useUnmount`) +- Usage Examples + - Refer to example files under `docs/components/antd/button` +- Notes + - Ensure consistency with Gradio interaction patterns + - Use Ant Design icons when icons are required + +Section Sources + +- [backend/modelscope_studio/components/antd/**init**.py:14-14](file://backend/modelscope_studio/components/antd/__init__.py#L14-L14) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) + +### Component B: Form + +- Python Import and Aliases + - `from modelscope_studio.components.antd import Form, FormItem, FormProvider` +- Frontend Component + - Path: `frontend/antd/form/form.tsx` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file + - Form Validation: `FormItem.Rule` supports rule configuration +- Usage Examples + - Refer to example files under `docs/components/antd/form` +- Notes + - Form state must be kept in sync with Gradio data flow + - Rule configuration must conform to Ant Design specifications + +Section Sources + +- [backend/modelscope_studio/components/antd/**init**.py:48-51](file://backend/modelscope_studio/components/antd/__init__.py#L48-L51) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) + +### Component C: Table + +- Python Import and Aliases + - `from modelscope_studio.components.antd import Table, TableColumn, TableRowSelection` +- Frontend Component + - Path: `frontend/antd/table/table.tsx` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file + - Selection Column: `TableRowSelection` provides selection capability +- Usage Examples + - Refer to example files under `docs/components/antd/table` +- Notes + - Column configuration must match the data structure + - Selection behavior must align with Gradio output format + +Section Sources + +- [backend/modelscope_studio/components/antd/**init**.py:116-122](file://backend/modelscope_studio/components/antd/__init__.py#L116-L122) +- [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) + +### Component D: Bubble + +- Python Import and Alias + - `from modelscope_studio.components.antdx import Bubble` +- Frontend Component + - Path: `frontend/antdx/bubble/bubble.tsx` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file +- Usage Examples + - Refer to example files under `docs/components/antdx/bubble` +- Notes + - Message content and styles should be adapted for conversation scenarios + +Section Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:8-13](file://backend/modelscope_studio/components/antdx/__init__.py#L8-L13) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) + +### Component E: Application + +- Frontend Component + - Path: `frontend/base/application/application.ts` + - Purpose: Serves as the application root container, managing context and layout +- Usage Examples + - Refer to example files under `docs/components/base/application` +- Notes + - Used in conjunction with other base components (e.g., Each, Filter) + +Section Sources + +- [frontend/base/application/application.ts](file://frontend/base/application/application.ts) + +### Component F: Chatbot + +- Python Import and Alias + - `from modelscope_studio.components.pro import Chatbot` +- Frontend Component + - Path: `frontend/pro/chatbot/chatbot.ts` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file +- Usage Examples + - Refer to example files under `docs/components/pro/chatbot` +- Notes + - Pay attention to data formats when integrating with backend model services + +Section Sources + +- [backend/modelscope_studio/components/pro/components.py:1-20](file://backend/modelscope_studio/components/pro/components.py#L1-L20) +- [frontend/pro/chatbot/chatbot.ts](file://frontend/pro/chatbot/chatbot.ts) + +### Component G: MonacoEditor + +- Python Import and Alias + - `from modelscope_studio.components.pro import MonacoEditor` +- Frontend Component + - Path: `frontend/pro/monaco-editor/monaco-editor.ts` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file +- Usage Examples + - Refer to example files under `docs/components/pro/monaco_editor` +- Notes + - Editor theme and language configuration must be consistent with Gradio interaction + +Section Sources + +- [backend/modelscope_studio/components/pro/components.py:1-20](file://backend/modelscope_studio/components/pro/components.py#L1-L20) +- [frontend/pro/monaco-editor/monaco-editor.ts](file://frontend/pro/monaco-editor/monaco-editor.ts) + +### Component H: MultimodalInput + +- Python Import and Alias + - `from modelscope_studio.components.pro import MultimodalInput` +- Frontend Component + - Path: `frontend/pro/multimodal-input/multimodal-input.ts` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file +- Usage Examples + - Refer to example files under `docs/components/pro/multimodal_input` +- Notes + - Input types must match the backend model interface + +Section Sources + +- [backend/modelscope_studio/components/pro/components.py:1-20](file://backend/modelscope_studio/components/pro/components.py#L1-L20) +- [frontend/pro/multimodal-input/multimodal-input.ts](file://frontend/pro/multimodal-input/multimodal-input.ts) + +### Component I: WebSandbox + +- Python Import and Alias + - `from modelscope_studio.components.pro import WebSandbox` +- Frontend Component + - Path: `frontend/pro/web-sandbox/web-sandbox.ts` + - Props: Refer to the props definition in the component file + - Events: Refer to the event bindings in the component file +- Usage Examples + - Refer to example files under `docs/components/pro/web_sandbox` +- Notes + - Security policies and cross-origin restrictions must be configured during deployment + +Section Sources + +- [backend/modelscope_studio/components/pro/components.py:1-20](file://backend/modelscope_studio/components/pro/components.py#L1-L20) +- [frontend/pro/web-sandbox/web-sandbox.ts](file://frontend/pro/web-sandbox/web-sandbox.ts) + +### Component J: Global Components (Markdown) + +- Frontend Component + - Path: `frontend/globals/components/index.ts` + - Currently exports the `markdown` sub-module +- Usage Examples + - Refer to example files under `docs/components/base/markdown` +- Notes + - Global components must be uniformly registered at the application entry point + +Section Sources + +- [frontend/globals/components/index.ts:1-2](file://frontend/globals/components/index.ts#L1-L2) + +## Dependency Analysis + +- Python Side + - Dependencies: Gradio 6.0 ≤ v ≤ 6.8.0 + - Version: 2.0.0-beta.1 +- Frontend Side + - Build scripts: Component builds executed via Gradio CLI + - Dev scripts: Start the documentation site dev server +- Tools and Rendering + - hooks: `useMount`, `useUnmount`, `useUpdateEffect`, `useAsyncEffect`, `useAsyncMemo`, `useDeepCompareEffect`, `useEvent` + - Renderers: `renderSlot`, `renderParamsSlot`, `renderItems` + - Prop handling: `patchProps`, `omitUndefinedProps` + - Others: `createFunction`, `tick`, `upload` + +```mermaid +graph TB +PY_DEPS["Python Dependencies
Gradio 6.0 ≤ v ≤ 6.8.0"] +FE_SCRIPTS["Frontend Scripts
Build/Dev"] +FE_HOOKS["hooks Utility Set"] +FE_RENDER["Renderers"] +FE_PATCH["Prop Handling"] +FE_OTHER["Other Utilities"] +PY_DEPS --> FE_SCRIPTS +FE_SCRIPTS --> FE_HOOKS +FE_SCRIPTS --> FE_RENDER +FE_SCRIPTS --> FE_PATCH +FE_SCRIPTS --> FE_OTHER +``` + +Diagram Sources + +- [pyproject.toml:26-26](file://pyproject.toml#L26-L26) +- [package.json:8-24](file://package.json#L8-L24) +- [frontend/utils/hooks/useMount.ts](file://frontend/utils/hooks/useMount.ts) +- [frontend/utils/hooks/useUnmount.ts](file://frontend/utils/hooks/useUnmount.ts) +- [frontend/utils/hooks/useUpdateEffect.ts](file://frontend/utils/hooks/useUpdateEffect.ts) +- [frontend/utils/hooks/useAsyncEffect.ts](file://frontend/utils/hooks/useAsyncEffect.ts) +- [frontend/utils/hooks/useAsyncMemo.ts](file://frontend/utils/hooks/useAsyncMemo.ts) +- [frontend/utils/hooks/useDeepCompareEffect.ts](file://frontend/utils/hooks/useDeepCompareEffect.ts) +- [frontend/utils/hooks/useEvent.ts](file://frontend/utils/hooks/useEvent.ts) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/patchProps.tsx](file://frontend/utils/patchProps.tsx) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) +- [frontend/utils/createFunction.ts](file://frontend/utils/createFunction.ts) +- [frontend/utils/tick.ts](file://frontend/utils/tick.ts) +- [frontend/utils/upload.ts](file://frontend/utils/upload.ts) + +Section Sources + +- [pyproject.toml:26-26](file://pyproject.toml#L26-L26) +- [package.json:8-24](file://package.json#L8-L24) +- [frontend/utils/hooks/useMount.ts](file://frontend/utils/hooks/useMount.ts) +- [frontend/utils/hooks/useUnmount.ts](file://frontend/utils/hooks/useUnmount.ts) +- [frontend/utils/hooks/useUpdateEffect.ts](file://frontend/utils/hooks/useUpdateEffect.ts) +- [frontend/utils/hooks/useAsyncEffect.ts](file://frontend/utils/hooks/useAsyncEffect.ts) +- [frontend/utils/hooks/useAsyncMemo.ts](file://frontend/utils/hooks/useAsyncMemo.ts) +- [frontend/utils/hooks/useDeepCompareEffect.ts](file://frontend/utils/hooks/useDeepCompareEffect.ts) +- [frontend/utils/hooks/useEvent.ts](file://frontend/utils/hooks/useEvent.ts) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/patchProps.tsx](file://frontend/utils/patchProps.tsx) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) +- [frontend/utils/createFunction.ts](file://frontend/utils/createFunction.ts) +- [frontend/utils/tick.ts](file://frontend/utils/tick.ts) +- [frontend/utils/upload.ts](file://frontend/utils/upload.ts) + +## Performance Considerations + +- Component Lazy Loading and On-Demand Import: Prefer importing specific components to avoid importing too many modules at once +- Rendering Optimization: Use tools like `renderItems` and `renderParamsSlot` to reduce redundant rendering +- Async Processing: Use `useAsyncEffect`/`useAsyncMemo` to handle async side effects, avoiding blocking the main thread +- Prop Patching: Use `patchProps` to merge props appropriately, reducing unnecessary re-renders +- Upload and Resources: The `upload` utility should be combined with Gradio's upload flow to avoid blocking with large files + +## Troubleshooting Guide + +- Version Incompatibility + - Symptom: Runtime errors or functional anomalies + - Diagnosis: Confirm the Gradio version is within the 6.0 ≤ v ≤ 6.8.0 range +- Component Not Taking Effect + - Symptom: Frontend component not displaying or unresponsive + - Diagnosis: Check that the component is correctly imported; confirm that the build artifacts have been generated; verify props being passed +- Form Validation Failure + - Symptom: Error on submit or no feedback + - Diagnosis: Check `FormItem.Rule` configuration; confirm field names match the data structure +- Upload Anomaly + - Symptom: File upload failure or progress anomaly + - Diagnosis: Check `upload` utility calls; confirm backend interface is consistent with Gradio's upload protocol +- Lifecycle Issues + - Symptom: Side effects persist after component unmount + - Diagnosis: Ensure `useUnmount` is used to register cleanup logic; use `useUpdateEffect` to monitor changes when necessary + +Section Sources + +- [pyproject.toml:26-26](file://pyproject.toml#L26-L26) +- [frontend/utils/hooks/useUnmount.ts](file://frontend/utils/hooks/useUnmount.ts) +- [frontend/utils/hooks/useUpdateEffect.ts](file://frontend/utils/hooks/useUpdateEffect.ts) +- [frontend/utils/upload.ts](file://frontend/utils/upload.ts) + +## Conclusion + +This API reference document outlines ModelScope Studio's Python and frontend component systems, clarifying import methods, component structure, props and events, lifecycle hooks, and utility function usage. It is recommended that developers adhere to version constraints, import components on demand, use utility functions appropriately, and integrate quickly by referencing the example files. + +## Appendix + +- Quick Index + - Python Components: Refer to the export lists of the antd and antdx sub-packages + - Frontend Components: Refer to the Svelte files under each sub-package + - Utility Functions: Refer to hooks and renderers in the `utils` directory +- Version and Compatibility + - Python: 2.0.0-beta.1 + - Gradio: 6.0 ≤ v ≤ 6.8.0 +- Build and Development + - Build command: `pnpm run build` + - Dev command: `pnpm run dev` + +Section Sources + +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [pyproject.toml:26-26](file://pyproject.toml#L26-L26) +- [package.json:8-24](file://package.json#L8-L24) diff --git a/.wiki/en/API Reference/JavaScript API/JavaScript API.md b/.wiki/en/API Reference/JavaScript API/JavaScript API.md new file mode 100644 index 00000000..723ae230 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/JavaScript API.md @@ -0,0 +1,413 @@ +# JavaScript API + + +**Files referenced in this document** +- [frontend/package.json](file://frontend/package.json) +- [frontend/tsconfig.json](file://frontend/tsconfig.json) +- [frontend/antd/package.json](file://frontend/antd/package.json) +- [frontend/antdx/package.json](file://frontend/antdx/package.json) +- [frontend/base/package.json](file://frontend/base/package.json) +- [frontend/pro/package.json](file://frontend/pro/package.json) +- [frontend/globals/components/index.ts](file://frontend/globals/components/index.ts) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/form/Index.svelte](file://frontend/antd/form/Index.svelte) +- [frontend/antd/layout/Index.svelte](file://frontend/antd/layout/Index.svelte) +- [frontend/antd/modal/Index.svelte](file://frontend/antd/modal/Index.svelte) +- [frontend/antd/table/Index.svelte](file://frontend/antd/table/Index.svelte) +- [frontend/svelte-preprocess-react/index.ts](file://frontend/svelte-preprocess-react/index.ts) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts](file://frontend/svelte-preprocess-react/sveltify.svelte.ts) +- [frontend/svelte-preprocess-react/inject.ts](file://frontend/svelte-preprocess-react/inject.ts) +- [frontend/svelte-preprocess-react/react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Memory Management](#performance-and-memory-management) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: API Index and Navigation](#appendix-api-index-and-navigation) + +## Introduction + +This document is the JavaScript API reference for ModelScope Studio, focusing on the Svelte component layer and the React component bridging solution. It covers the following topics: + +- Property definitions, event handling, lifecycle, and public methods of Svelte components +- Inter-component communication (props passing, event bubbling, slot system) +- React component bridge implementation (property conversion, event binding, state synchronization) +- Standard instantiation and configuration examples (basic and complex scenarios) +- Style customization, theme configuration, and responsive design support +- TypeScript type definitions, interface specifications, and generic usage +- Performance optimization, memory management, and best practices +- Complete API index and navigation + +## Project Structure + +The frontend adopts a multi-package structure, split by functional domain: + +- Base component library: base +- Ant Design component library: antd +- Ant Design extended component library: antdx +- Pro advanced component library: pro +- Global component entry: globals/components + +All packages use Svelte 5 as the core runtime, and inject React components into Svelte through the in-house `svelte-preprocess-react` bridging solution. + +```mermaid +graph TB +subgraph "Frontend Packages" +BASE["@modelscope-studio/base"] +ANTD["@modelscope-studio/antd"] +ANTHDX["@modelscope-studio/antdx"] +PRO["@modelscope-studio/pro"] +GLOBALS["@globals/components"] +end +subgraph "Bridge Layer" +PRE["@svelte-preprocess-react
index.ts"] +INJ["inject.ts"] +SLOT["react-slot.tsx"] +SVLT["sveltify.svelte.ts"] +end +BASE --> PRE +ANTD --> PRE +ANTHDX --> PRE +PRO --> PRE +GLOBALS --> PRE +PRE --> INJ +PRE --> SLOT +PRE --> SVLT +``` + +Diagram sources + +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) +- [frontend/svelte-preprocess-react/inject.ts:1-103](file://frontend/svelte-preprocess-react/inject.ts#L1-L103) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) + +Section sources + +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) + +## Core Components + +This section provides an overview of common patterns and capability boundaries of Svelte components in the bridge layer, making it easier to quickly locate and reuse them. + +- Property passthrough and filtering + - Props are uniformly retrieved via `getProps`, with visibility flags, internal markers, and element identifiers being filtered or preserved + - `processProps` is used to merge name mappings (e.g., `fields_change` → `fieldsChange`) with additional properties +- Slot system + - Svelte slot content is collected via `getSlots` and injected into the `slots` field of React components + - `ReactSlot` is responsible for cloning or mounting DOM nodes into React components, with support for attribute observation and event cloning +- Async loading and rendering + - `importComponent` dynamically imports React components, combined with Svelte `await` fragments for async rendering +- Event and state synchronization + - Callbacks such as `onValueChange` and `onResetFormAction` are used to write back to parent state + - `updateProps` is used to update mutable properties (e.g., `value`) + +Section sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/modal/Index.svelte:1-63](file://frontend/antd/modal/Index.svelte#L1-L63) +- [frontend/antd/table/Index.svelte:1-61](file://frontend/antd/table/Index.svelte#L1-L61) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +## Architecture Overview + +The following diagram shows the bridge path from Svelte to React and key nodes: + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Component
Index.svelte" +participant Bridge as "Bridge Tool
sveltify.ts" +participant Inject as "Global Injection
inject.ts" +participant React as "React Component" +participant Slot as "Slot Bridge
react-slot.tsx" +Svelte->>Bridge : "importComponent + getProps + processProps" +Bridge->>Inject : "Initialize shared root node and context" +Bridge->>React : "Create Portal and mount" +Svelte->>Slot : "getSlots() -> slots.value" +Slot-->>React : "Clone/mount DOM and propagate events" +React-->>Svelte : "onValueChange and other callbacks trigger updateProps" +``` + +Diagram sources + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/svelte-preprocess-react/inject.ts:1-103](file://frontend/svelte-preprocess-react/inject.ts#L1-L103) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + +## Component Details + +### Button + +- Property definitions + - `additional_props?: Record` + - `value?: string | undefined` + - `as_item?: string | undefined` + - `_internal: { layout?: boolean }` + - `href_target?: string` + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` +- Events and methods + - Default slot content is injected via `slots` + - Appearance is controlled via `className`, `style`, `id` +- Lifecycle + - After `$props()` initialization, enters async rendering flow immediately +- Complexity and performance + - Dynamic import and derived computation to avoid unnecessary re-renders + +Section sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + +### Form + +- Property definitions + - `value?: Record` + - `form_action?: FormProps['formAction'] | null` + - `form_name?: string` + - `fields_change?: any` + - `finish_failed?: any` + - `values_change?: any` + - Internal and style: `_internal`, `elem_id`, `elem_classes`, `elem_style` +- Events and methods + - `onValueChange` writes back `value` + - `onResetFormAction` clears `form_action` +- Lifecycle + - Async rendering; only displayed when `visible` is true +- Complexity and performance + - Uses derived properties to reduce props computation overhead + +Section sources + +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) + +### Modal + +- Property definitions + - `as_item?: string | undefined` + - `_internal: { layout?: boolean }` + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` +- Events and methods + - Content is injected via `slots` +- Lifecycle + - Conditional rendering; React components are loaded asynchronously + +Section sources + +- [frontend/antd/modal/Index.svelte:1-63](file://frontend/antd/modal/Index.svelte#L1-L63) + +### Table + +- Property definitions + - `as_item?: string | undefined` + - `_internal: {}` + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` +- Events and methods + - Column/row content is injected via `slots` +- Lifecycle + - Async rendering with conditional display + +Section sources + +- [frontend/antd/table/Index.svelte:1-61](file://frontend/antd/table/Index.svelte#L1-L61) + +### Layout + +- Property definitions + - `children: Snippet` + - Other properties are handled by the Base component +- Events and methods + - No explicit event bindings; primarily responsible for structural rendering +- Lifecycle + - Props are passed through directly to the Base component + +Section sources + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) + +### React Slot Bridge (ReactSlot) + +- Functionality + - Clones and mounts Svelte slots into React components + - Supports event listener cloning, attribute change observation, and application of class names and inline styles +- Key parameters + - `slot: HTMLElement` + - `clone?: boolean` + - `style?: React.CSSProperties` + - `className?: string` + - `observeAttributes?: boolean` +- Behavior + - `MutationObserver` observes subtree changes of the slot and dynamically rebuilds cloned nodes + - React subtrees are mounted to target containers via `createPortal` + +Section sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +### Bridge Core (sveltify) + +- Functionality + - Wraps React components as Svelte components with support for slots, styles, class names, and id passthrough + - Maintains shared root nodes and node trees to enable rendering and updates across component trees +- Key points + - Initializes Promise and global shared root node + - Recursively builds node tree and triggers rerender + - Provides the `Sveltified` factory function + +Section sources + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) + +### Global Injection (inject) + +- Functionality + - Injects global objects required by React ecosystem and the bridge into `window` + - Defines custom elements (`react-portal-target`, `react-child`, `svelte-slot`) + - Initializes global state (`initializePromise`, `sharedRoot`, `autokey`, etc.) +- Impact + - Provides a unified runtime environment for the bridge layer + +Section sources + +- [frontend/svelte-preprocess-react/inject.ts:1-103](file://frontend/svelte-preprocess-react/inject.ts#L1-L103) + +## Dependency Analysis + +```mermaid +graph LR +A["@modelscope-studio/antd"] --> B["@svelte-preprocess-react/index.ts"] +C["@modelscope-studio/antdx"] --> B +D["@modelscope-studio/base"] --> B +E["@modelscope-studio/pro"] --> B +F["@globals/components"] --> B +B --> G["inject.ts"] +B --> H["react-slot.tsx"] +B --> I["sveltify.svelte.ts"] +``` + +Diagram sources + +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/globals/components/index.ts:1-2](file://frontend/globals/components/index.ts#L1-L2) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) +- [frontend/svelte-preprocess-react/inject.ts:1-103](file://frontend/svelte-preprocess-react/inject.ts#L1-L103) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) + +Section sources + +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) + +## Performance and Memory Management + +- Async component loading + - Use `importComponent` for dynamic imports to avoid blocking the initial render +- Derived computation and minimized re-renders + - Use `$derived` and `processProps` to reduce redundant renders +- Slot cloning strategy + - `ReactSlot` enables cloning and `MutationObserver` by default to ensure stability during DOM changes; disabling cloning can reduce overhead in high-frequency update scenarios +- Portal management + - `inject.ts` centrally creates and destroys root nodes to avoid memory leaks from repeated mounting +- Styles and themes + - Styles are controlled via `elem_style`, `elem_classes`, and `className`; Ant Design theme variables are injected by `antdCssinjs` to ensure a consistent theme experience + +[This section provides general guidance and does not require specific file sources] + +## Troubleshooting Guide + +- Slot not taking effect + - Check whether `getSlots` is called correctly and `slots.value` is passed to the React component + - Confirm that the `slot` parameter of `ReactSlot` points to a valid DOM element +- Event not triggered + - Ensure event name mapping is correct (e.g., `fields_change` → `fieldsChange`) + - Check the `observeAttributes` and `clone` settings of `ReactSlot` +- Style not applied + - Confirm whether `elem_style` and `elem_classes` are properly passed through + - Check whether theme injection is complete (`inject.ts` initialization) +- Performance issues + - Reduce unnecessary `visible` toggling + - Disable `ReactSlot` cloning or lower observation granularity for high-frequency update scenarios + +Section sources + +- [frontend/antd/form/Index.svelte:60-99](file://frontend/antd/form/Index.svelte#L60-L99) +- [frontend/svelte-preprocess-react/react-slot.tsx:158-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L158-L224) +- [frontend/svelte-preprocess-react/inject.ts:95-103](file://frontend/svelte-preprocess-react/inject.ts#L95-L103) + +## Conclusion + +This API uses Svelte as its core, seamlessly integrating React components through an in-house bridge layer to form a unified component ecosystem. Through standardized property passthrough, event mapping, and slot bridging, developers can use both types of components in a consistent manner. Combined with comprehensive type definitions and performance optimization recommendations, this enables a good development experience and runtime efficiency in complex scenarios. + +[This section is a summary and does not require specific file sources] + +## Appendix: API Index and Navigation + +### Component Categories and Entry Points + +- Base components: base +- Ant Design components: antd +- Ant Design extensions: antdx +- Pro advanced components: pro +- Global component entry: globals/components + +Section sources + +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/globals/components/index.ts:1-2](file://frontend/globals/components/index.ts#L1-L2) + +### Svelte Component Common Patterns + +- Property retrieval and filtering: `getProps` +- Property mapping and merging: `processProps` +- Slot collection: `getSlots` +- Async rendering: `importComponent` + `{#await ...}` +- Event writeback: `updateProps` + +Section sources + +- [frontend/antd/button/Index.svelte:12-56](file://frontend/antd/button/Index.svelte#L12-L56) +- [frontend/antd/form/Index.svelte:14-71](file://frontend/antd/form/Index.svelte#L14-L71) +- [frontend/antd/modal/Index.svelte:12-47](file://frontend/antd/modal/Index.svelte#L12-L47) +- [frontend/antd/table/Index.svelte:12-45](file://frontend/antd/table/Index.svelte#L12-L45) + +### React Component Bridge + +- `sveltify`: Wraps React components as Svelte components +- `inject`: Global runtime injection and initialization +- `react-slot`: Slot DOM cloning and mounting + +Section sources + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:30-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L30-L119) +- [frontend/svelte-preprocess-react/inject.ts:20-103](file://frontend/svelte-preprocess-react/inject.ts#L20-L103) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L224) + +### TypeScript and Type Definitions + +- The top-level `tsconfig` extends the global tsconfig, enabling ESNext modules and browser types +- Components extensively use generics and read-only array constraints for slot key names + +Section sources + +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:9-39](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L9-L39) diff --git a/.wiki/en/API Reference/JavaScript API/Markdown Component API.md b/.wiki/en/API Reference/JavaScript API/Markdown Component API.md new file mode 100644 index 00000000..3fcbae5e --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Markdown Component API.md @@ -0,0 +1,417 @@ +# Markdown Component API + + +**Files referenced in this document** +- [frontend/globals/components/markdown/index.tsx](file://frontend/globals/components/markdown/index.tsx) +- [frontend/globals/components/markdown/utils.ts](file://frontend/globals/components/markdown/utils.ts) +- [frontend/globals/components/markdown/sanitize.ts](file://frontend/globals/components/markdown/sanitize.ts) +- [frontend/globals/components/markdown/markdown.less](file://frontend/globals/components/markdown/markdown.less) +- [frontend/globals/components/markdown/prism.less](file://frontend/globals/components/markdown/prism.less) +- [frontend/globals/components/markdown/html-tags.ts](file://frontend/globals/components/markdown/html-tags.ts) +- [frontend/base/markdown/Index.svelte](file://frontend/base/markdown/Index.svelte) +- [frontend/base/markdown/markdown.tsx](file://frontend/base/markdown/markdown.tsx) +- [backend/modelscope_studio/components/base/markdown/__init__.py](file://backend/modelscope_studio/components/base/markdown/__init__.py) +- [docs/components/base/markdown/README.md](file://docs/components/base/markdown/README.md) +- [docs/components/base/markdown/demos/basic.py](file://docs/components/base/markdown/demos/basic.py) +- [docs/components/base/markdown/demos/custom_copy_buttons.py](file://docs/components/base/markdown/demos/custom_copy_buttons.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides detailed API documentation for the Markdown component in the ModelScope Studio base components, covering the following aspects: + +- Property definitions and default values +- Rendering options (line breaks, header links, math formulas, Mermaid diagrams) +- Code highlighting (Prism.js integration and language support) +- Security filtering (HTML allowlist and external link handling) +- Style customization (CSS class names, inline styles, theme variables) +- Usage examples (basic rendering, copy button, custom buttons) +- Performance optimization recommendations (lazy loading, caching strategies) +- Common issues and debugging methods + +## Project Structure + +The Markdown component is implemented collaboratively by a frontend React component and a backend Gradio component, bridged through a Svelte wrapper. The frontend parsing and rendering logic is centralized in the global components directory, while the backend handles parameter passthrough and event binding. + +```mermaid +graph TB +subgraph "Frontend" +A["Index.svelte
Base Wrapper"] --> B["markdown.tsx
React Component Entry"] +B --> C["utils.ts
Parse/Highlight/Sanitize/Mermaid"] +B --> D["sanitize.ts
HTML Filtering"] +B --> E["markdown.less
General Styles"] +B --> F["prism.less
Code Highlight Theme"] +B --> G["html-tags.ts
Allowlisted Tags"] +end +subgraph "Backend" +H["backend/base/markdown/__init__.py
Gradio Component Definition"] +end +A --> H +H --> B +``` + +**Diagram sources** + +- [frontend/base/markdown/Index.svelte:1-63](file://frontend/base/markdown/Index.svelte#L1-L63) +- [frontend/base/markdown/markdown.tsx:1-34](file://frontend/base/markdown/markdown.tsx#L1-L34) +- [frontend/globals/components/markdown/index.tsx:1-272](file://frontend/globals/components/markdown/index.tsx#L1-L272) +- [frontend/globals/components/markdown/utils.ts:1-411](file://frontend/globals/components/markdown/utils.ts#L1-L411) +- [frontend/globals/components/markdown/sanitize.ts:1-26](file://frontend/globals/components/markdown/sanitize.ts#L1-L26) +- [frontend/globals/components/markdown/markdown.less:1-140](file://frontend/globals/components/markdown/markdown.less#L1-L140) +- [frontend/globals/components/markdown/prism.less:1-185](file://frontend/globals/components/markdown/prism.less#L1-L185) +- [frontend/globals/components/markdown/html-tags.ts:1-210](file://frontend/globals/components/markdown/html-tags.ts#L1-L210) +- [backend/modelscope_studio/components/base/markdown/**init**.py:1-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L1-L174) + +**Section sources** + +- [frontend/base/markdown/Index.svelte:1-63](file://frontend/base/markdown/Index.svelte#L1-L63) +- [frontend/base/markdown/markdown.tsx:1-34](file://frontend/base/markdown/markdown.tsx#L1-L34) +- [frontend/globals/components/markdown/index.tsx:1-272](file://frontend/globals/components/markdown/index.tsx#L1-L272) +- [backend/modelscope_studio/components/base/markdown/**init**.py:1-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L1-L174) + +## Core Components + +- Frontend React component: Responsible for Markdown parsing, code highlighting, math formula rendering, Mermaid diagram rendering, HTML security filtering, and copy button interactions. +- Backend Gradio component: Responsible for parameter passthrough, event binding (such as copy/change/mouse events), default values, and example data. + +Key responsibility division: + +- Parsing and rendering: Marked + marked-highlight (Prism) + custom extensions (LaTeX, Mermaid) +- Security filtering: Amuchina + external link handling +- Math formulas: KaTeX loaded on-demand with auto-rendering +- Diagrams: Mermaid loaded on-demand with error fallback +- Styles: General styles + Prism theme variables + +**Section sources** + +- [frontend/globals/components/markdown/index.tsx:27-48](file://frontend/globals/components/markdown/index.tsx#L27-L48) +- [frontend/globals/components/markdown/utils.ts:286-344](file://frontend/globals/components/markdown/utils.ts#L286-L344) +- [backend/modelscope_studio/components/base/markdown/**init**.py:11-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L11-L174) + +## Architecture Overview + +The Markdown component receives parameters from the backend, and after being wrapped by the frontend, performs parsing and rendering. The parsing phase can enable line breaks, header links, LaTeX, and Mermaid extensions; the rendering phase integrates Prism for code highlighting, KaTeX/Mermaid for math and diagram rendering, and applies security filtering to the output HTML. + +```mermaid +sequenceDiagram +participant Backend as "Backend Component" +participant Wrapper as "Frontend Wrapper (Svelte)" +participant ReactComp as "React Component" +participant Parser as "Marked/Prism/KaTeX/Mermaid" +participant Sanitizer as "HTML Filter" +Backend->>Wrapper : Pass parameters (value, config) +Wrapper->>ReactComp : Render component and inject props +ReactComp->>Parser : Initialize parser (with extensions/highlighting) +ReactComp->>Parser : Parse Markdown +Parser-->>ReactComp : Return HTML fragment +ReactComp->>Sanitizer : Optional security filtering +Sanitizer-->>ReactComp : Return safe HTML +ReactComp-->>Wrapper : Render final content +``` + +**Diagram sources** + +- [frontend/base/markdown/Index.svelte:19-62](file://frontend/base/markdown/Index.svelte#L19-L62) +- [frontend/globals/components/markdown/index.tsx:86-92](file://frontend/globals/components/markdown/index.tsx#L86-L92) +- [frontend/globals/components/markdown/utils.ts:286-344](file://frontend/globals/components/markdown/utils.ts#L286-L344) +- [frontend/globals/components/markdown/sanitize.ts:12-25](file://frontend/globals/components/markdown/sanitize.ts#L12-L25) + +## Detailed Component Analysis + +### Property Definitions and Default Values + +- `value`: String, Markdown content +- `sanitizeHtml`: Boolean, whether to enable HTML security filtering, enabled by default +- `latexDelimiters`: Array, custom LaTeX delimiters, containing left/right/display triplets +- `lineBreaks`: Boolean, whether to convert newlines to `
`, enabled by default +- `headerLinks`: Boolean, whether to generate header anchors and link icons, disabled by default +- `showCopyButton`: Boolean, whether to show the overall copy button +- `rtl`: Boolean, whether to enable right-to-left layout +- `themeMode`: String, theme mode (`light`/`dark`), used for styles and Mermaid theme +- `rootUrl`: String, root path, used for external link detection and resource location +- `allowTags`: Boolean or string array, controls the allowed HTML/SVG tags +- `onCopy`: Callback, triggered on successful copy +- `onChange`: Callback, triggered when rendering is complete +- `copyButtons`: Custom copy button collection (via slots) + +The default LaTeX delimiter set contains multiple common expression groups (inline/block, parenthesis variants, etc.). + +**Section sources** + +- [frontend/globals/components/markdown/index.tsx:27-48](file://frontend/globals/components/markdown/index.tsx#L27-L48) +- [frontend/globals/components/markdown/index.tsx:50-60](file://frontend/globals/components/markdown/index.tsx#L50-L60) +- [backend/modelscope_studio/components/base/markdown/**init**.py:54-141](file://backend/modelscope_studio/components/base/markdown/__init__.py#L54-L141) + +### Rendering Options and Parser Configuration + +- Line breaks: Controlled by the `breaks` option of Marked +- Header links: When `headerLinks` is enabled, IDs are generated for headers and anchor link icons are inserted +- LaTeX: Custom tokenizer supports multiple delimiter groups, rendered as block-level containers +- Mermaid: Custom tokenizer supports marking code blocks as `mermaid`, rendered as diagrams +- Code highlighting: Integrates Prism via `marked-highlight`, renders by language class name +- HTML sanitization: External links get `target`/`rel` attributes, and Amuchina allowlist filtering is applied + +```mermaid +flowchart TD +Start(["Start"]) --> Init["Initialize Marked
Enable GFM/line breaks/highlighting"] +Init --> Header{"Enable header links?"} +Header --> |Yes| AddHeader["Register header extension
Generate ID/anchor"] +Header --> |No| SkipHeader["Skip header extension"] +AddHeader --> Ext +SkipHeader --> Ext +Ext["Register LaTeX/Mermaid extensions"] --> Parse["Parse Markdown"] +Parse --> Math{"LaTeX syntax present?"} +Math --> |Yes| LoadKatex["Load KaTeX on-demand and render"] +Math --> |No| SkipMath["Skip math rendering"] +LoadKatex --> Safe{"HTML filtering enabled?"} +SkipMath --> Safe +Safe --> |Yes| Sanitize["External link handling / allowlist filtering"] +Safe --> |No| NoSanitize["Preserve original HTML"] +Sanitize --> Render["Render result"] +NoSanitize --> Render +Render --> End(["End"]) +``` + +**Diagram sources** + +- [frontend/globals/components/markdown/utils.ts:286-344](file://frontend/globals/components/markdown/utils.ts#L286-L344) +- [frontend/globals/components/markdown/index.tsx:107-138](file://frontend/globals/components/markdown/index.tsx#L107-L138) +- [frontend/globals/components/markdown/sanitize.ts:12-25](file://frontend/globals/components/markdown/sanitize.ts#L12-L25) + +**Section sources** + +- [frontend/globals/components/markdown/utils.ts:286-344](file://frontend/globals/components/markdown/utils.ts#L286-L344) +- [frontend/globals/components/markdown/index.tsx:107-138](file://frontend/globals/components/markdown/index.tsx#L107-L138) + +### Code Highlighting and Language Support + +- Highlighting library: Prism.js (integrated via `marked-highlight`) +- Language support: Built-in loading of commonly used languages including Python, LaTeX, Bash, JSX, TypeScript, and TSX +- Rendering method: Dynamically selects Prism language based on code block language; unrecognized languages are kept as-is +- Theme: Applied via `prism.less` theme variables, with dark color scheme in dark mode + +```mermaid +classDiagram +class Prism { ++highlight(code, lang, alias) ++languages +} +class MarkedHighlight { ++highlight(code, lang) +} +class MarkdownUtils { ++create_marked() +} +MarkdownUtils --> MarkedHighlight : "uses" +MarkedHighlight --> Prism : "calls" +``` + +**Diagram sources** + +- [frontend/globals/components/markdown/utils.ts:9-16](file://frontend/globals/components/markdown/utils.ts#L9-L16) +- [frontend/globals/components/markdown/utils.ts:303-310](file://frontend/globals/components/markdown/utils.ts#L303-L310) + +**Section sources** + +- [frontend/globals/components/markdown/utils.ts:9-16](file://frontend/globals/components/markdown/utils.ts#L9-L16) +- [frontend/globals/components/markdown/utils.ts:303-310](file://frontend/globals/components/markdown/utils.ts#L303-L310) + +### HTML Security Filtering and Allowlist + +- External link handling: Automatically sets `target="_blank"` and `rel="noopener noreferrer"` for external links +- Allowlist filtering: Uses Amuchina to sanitize HTML, retaining only standard HTML and SVG tags +- Allowed tags: Supports boolean toggle or explicit array; tags not in the allowlist are escaped + +```mermaid +flowchart TD +A["Input HTML"] --> B["Traverse nodes (A/IMG, etc.)"] +B --> C{"Is external link?"} +C --> |Yes| D["Set target/_blank + rel"] +C --> |No| E["Keep unchanged"] +D --> F["Amuchina allowlist filtering"] +E --> F +F --> G["Output safe HTML"] +``` + +**Diagram sources** + +- [frontend/globals/components/markdown/sanitize.ts:12-25](file://frontend/globals/components/markdown/sanitize.ts#L12-L25) +- [frontend/globals/components/markdown/html-tags.ts:206-210](file://frontend/globals/components/markdown/html-tags.ts#L206-L210) + +**Section sources** + +- [frontend/globals/components/markdown/sanitize.ts:1-26](file://frontend/globals/components/markdown/sanitize.ts#L1-L26) +- [frontend/globals/components/markdown/html-tags.ts:1-210](file://frontend/globals/components/markdown/html-tags.ts#L1-L210) + +### Style Customization and Theme Variables + +- CSS class names: The component root element includes classes such as `ms-gr-markdown`, `md`, and `prose`, making overrides easy +- Theme variables: CSS variables control colors, spacing, border radius, shadows, etc. +- Code highlighting theme: `prism.less` provides light and dark color schemes, switching with `themeMode` +- Copy button: Absolutely positioned with support for custom button collections (copy/copied states) + +```mermaid +classDiagram +class Styles { ++ms-gr-markdown ++md ++prose ++code_wrap ++copy_code_button +} +class ThemeVars { ++--block-background-fill ++--border-color-primary ++--body-text-color ++--code-background-fill ++... +} +Styles --> ThemeVars : "uses" +``` + +**Diagram sources** + +- [frontend/globals/components/markdown/markdown.less:1-140](file://frontend/globals/components/markdown/markdown.less#L1-L140) +- [frontend/globals/components/markdown/prism.less:1-185](file://frontend/globals/components/markdown/prism.less#L1-L185) + +**Section sources** + +- [frontend/globals/components/markdown/markdown.less:1-140](file://frontend/globals/components/markdown/markdown.less#L1-L140) +- [frontend/globals/components/markdown/prism.less:1-185](file://frontend/globals/components/markdown/prism.less#L1-L185) + +### Usage Examples + +- Basic text rendering: Pass a Markdown string directly +- Show copy button: Enable `showCopyButton` or provide custom buttons via slots +- Custom buttons: Use Slot to inject two buttons (e.g., copy/copied states) + +Reference example scripts and documentation: + +- Basic example: [basic.py:1-10](file://docs/components/base/markdown/demos/basic.py#L1-L10) +- Custom copy buttons: [custom_copy_buttons.py:1-21](file://docs/components/base/markdown/demos/custom_copy_buttons.py#L1-L21) +- Component description: [README.md:1-13](file://docs/components/base/markdown/README.md#L1-L13) + +**Section sources** + +- [docs/components/base/markdown/demos/basic.py:1-10](file://docs/components/base/markdown/demos/basic.py#L1-L10) +- [docs/components/base/markdown/demos/custom_copy_buttons.py:1-21](file://docs/components/base/markdown/demos/custom_copy_buttons.py#L1-L21) +- [docs/components/base/markdown/README.md:1-13](file://docs/components/base/markdown/README.md#L1-L13) + +## Dependency Analysis + +- Frontend dependencies + - Marked: Markdown parsing and rendering + - marked-highlight + Prism: Code highlighting + - KaTeX: Math formula rendering (loaded on-demand) + - Mermaid: Diagram rendering (loaded on-demand) + - Amuchina: HTML allowlist filtering + - github-slugger: Header ID generation +- Backend dependencies + - Gradio event listeners: copy/change/mouse series + - Frontend directory resolution: `resolve_frontend_dir("markdown")` + +```mermaid +graph LR +A["Marked"] --> B["marked-highlight"] +B --> C["Prism"] +A --> D["LaTeX Tokenizer"] +A --> E["Mermaid Tokenizer"] +A --> F["HTML Renderer"] +F --> G["Amuchina"] +A --> H["KaTeX (on-demand)"] +A --> I["Mermaid (on-demand)"] +``` + +**Diagram sources** + +- [frontend/globals/components/markdown/utils.ts:6-18](file://frontend/globals/components/markdown/utils.ts#L6-L18) +- [frontend/globals/components/markdown/utils.ts:286-344](file://frontend/globals/components/markdown/utils.ts#L286-L344) + +**Section sources** + +- [frontend/globals/components/markdown/utils.ts:6-18](file://frontend/globals/components/markdown/utils.ts#L6-L18) +- [backend/modelscope_studio/components/base/markdown/**init**.py:15-46](file://backend/modelscope_studio/components/base/markdown/__init__.py#L15-L46) + +## Performance Considerations + +- Lazy loading + - KaTeX: Styles and auto-render module are only loaded when math formulas first appear + - Mermaid: Loaded asynchronously and executed on the next frame before rendering + - Prism: Highlights on-demand during the parsing phase to avoid unnecessary overhead +- Caching strategy + - Loaded KaTeX modules are globally flagged to avoid duplicate imports + - Mermaid initialization parameters are fixed to reduce repeated initialization costs +- Rendering timing + - `requestAnimationFrame` is used to defer rendering to the browser's idle frame + - Re-parsing and re-rendering only occur when content changes +- Security filtering + - Filtering is only performed when `sanitizeHtml` is enabled, avoiding unnecessary DOM parsing + +**Section sources** + +- [frontend/globals/components/markdown/index.tsx:140-173](file://frontend/globals/components/markdown/index.tsx#L140-L173) +- [frontend/globals/components/markdown/utils.ts:177-223](file://frontend/globals/components/markdown/utils.ts#L177-L223) + +## Troubleshooting Guide + +- Copy button not working + - Check whether the container correctly binds the click event (`bind_copy_event`) + - Confirm whether the `copyButtons` slot is properly injected +- Math formulas not rendering + - Confirm whether `latexDelimiters` is correctly configured + - Check if `sanitizeHtml` is enabled and causing scripts to be removed +- Mermaid diagram errors + - Check the console error log + - Confirm that the mermaid code block is properly closed with correct syntax + - Check whether `themeMode` matches the page theme +- External links not opening in new window + - Confirm that `rootUrl` matches the link's origin + - Check whether `target`/`rel` is correctly set in the sanitize flow +- Code highlighting not working + - Confirm whether the language identifier is in the Prism supported list + - Check whether `prism.less` is correctly imported and theme variables are taking effect + +**Section sources** + +- [frontend/globals/components/markdown/utils.ts:346-380](file://frontend/globals/components/markdown/utils.ts#L346-L380) +- [frontend/globals/components/markdown/sanitize.ts:12-25](file://frontend/globals/components/markdown/sanitize.ts#L12-L25) +- [frontend/globals/components/markdown/utils.ts:177-223](file://frontend/globals/components/markdown/utils.ts#L177-L223) + +## Conclusion + +The Markdown component of ModelScope Studio provides rich rendering capabilities and a flexible customization interface while ensuring security and accessibility. Through the combination of Marked + Prism + KaTeX + Mermaid, it meets diverse needs from basic text to complex formulas and diagrams; allowlist filtering and external link handling ensure safe output; theme variables and style class names achieve consistent visual style and good customizability. + +## Appendix + +### Backend Component Parameter Overview + +- Parameter names: `value`, `rtl`, `latex_delimiters`, `sanitize_html`, `line_breaks`, `header_links`, `allow_tags`, `show_copy_button`, `copy_buttons` +- Events: `change`, `copy`, `click`, `dblclick`, `mousedown`, `mouseup`, `mouseover`, `mouseout`, `mousemove`, `scroll` +- Examples: `example_payload`/`example_value` returns a simple Markdown string + +**Section sources** + +- [backend/modelscope_studio/components/base/markdown/**init**.py:54-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L54-L174) + +### Frontend Component Property Overview + +- `value`, `sanitizeHtml`, `latexDelimiters`, `lineBreaks`, `headerLinks`, `showCopyButton`, `rtl`, `themeMode`, `rootUrl`, `allowTags`, `onCopy`, `onChange`, `copyButtons` +- Default LaTeX delimiter set, copy button icons and feedback, Mermaid error fallback + +**Section sources** + +- [frontend/globals/components/markdown/index.tsx:27-48](file://frontend/globals/components/markdown/index.tsx#L27-L48) +- [frontend/globals/components/markdown/index.tsx:50-60](file://frontend/globals/components/markdown/index.tsx#L50-L60) diff --git a/.wiki/en/API Reference/JavaScript API/React Component Bridge API.md b/.wiki/en/API Reference/JavaScript API/React Component Bridge API.md new file mode 100644 index 00000000..2861584f --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/React Component Bridge API.md @@ -0,0 +1,378 @@ +# React Component Bridge API + + +**Files referenced in this document** +- [frontend/svelte-preprocess-react/index.ts](file://frontend/svelte-preprocess-react/index.ts) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts](file://frontend/svelte-preprocess-react/sveltify.svelte.ts) +- [frontend/svelte-preprocess-react/inject.ts](file://frontend/svelte-preprocess-react/inject.ts) +- [frontend/svelte-preprocess-react/react-slot.tsx](file://frontend/svelte-preprocess-react/reactSlot.tsx) +- [frontend/svelte-preprocess-react/internal/types.ts](file://frontend/svelte-preprocess-react/internal/types.ts) +- [frontend/svelte-preprocess-react/react-contexts/index.ts](file://frontend/svelte-preprocess-react/react-contexts/index.ts) +- [frontend/utils/convertToCamelCase.ts](file://frontend/utils/convertToCamelCase.ts) +- [frontend/utils/createFunction.ts](file://frontend/utils/createFunction.ts) +- [frontend/utils/patchProps.tsx](file://frontend/utils/patchProps.tsx) +- [frontend/utils/hooks/useMemoizedEqualValue.ts](file://frontend/utils/hooks/useMemoizedEqualValue.ts) +- [frontend/utils/style.ts](file://frontend/utils/style.ts) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/base/text/text.tsx](file://frontend/base/text/text.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Standard Usage and Example Paths](#appendix-standard-usage-and-example-paths) + +## Introduction + +This document provides comprehensive API documentation for the React component bridge system in ModelScope Studio, focusing on the following aspects: + +- Conversion mechanism from React components to Svelte components (sveltify) +- Property mapping, event binding, and state synchronization +- Event handling (bubbling, delegation, custom events) +- Corresponding lifecycle hook implementations in Svelte +- Property conversion rules (camelCase, booleans, function properties) +- Context system (React Context and Svelte Context interoperability) +- Performance optimization (lazy loading, caching, memory management) +- Error handling and debugging techniques + +## Project Structure + +The bridge system consists of three main parts: + +- Injection layer: Initializes the global runtime environment and library bridging +- Conversion layer: `sveltify` wraps React components as Svelte components +- Rendering layer: `ReactSlot` renders Svelte slot content as React elements, with support for cloning and property injection + +```mermaid +graph TB +Inject["Injection Layer
inject.ts"] --> Types["Type Definitions
internal/types.ts"] +Inject --> ReactContexts["React Contexts
react-contexts/index.ts"] +Sveltify["Conversion Layer
sveltify.svelte.ts"] --> Bridge["Bridge
Bridge.svelte"] +Sveltify --> ReactWrapper["React Wrapper
ReactWrapper.svelte"] +ReactSlot["Rendering Layer
react-slot.tsx"] --> Portal["DOM Portal
createPortal"] +Utils["Utilities
convertToCamelCase.ts
createFunction.ts
patchProps.tsx
style.ts"] --> Sveltify +Utils --> ReactSlot +DemoBtn["Example Component
antd/button/button.tsx"] --> Sveltify +DemoForm["Example Component
antd/form/form.tsx"] --> Sveltify +DemoText["Example Component
base/text/text.tsx"] --> Sveltify +``` + +Diagram sources + +- [frontend/svelte-preprocess-react/inject.ts:1-103](file://frontend/svelte-preprocess-react/inject.ts#L1-L103) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/svelte-preprocess-react/internal/types.ts:1-79](file://frontend/svelte-preprocess-react/internal/types.ts#L1-L79) +- [frontend/svelte-preprocess-react/react-contexts/index.ts:1-123](file://frontend/svelte-preprocess-react/react-contexts/index.ts#L1-L123) +- [frontend/utils/convertToCamelCase.ts:1-22](file://frontend/utils/convertToCamelCase.ts#L1-L22) +- [frontend/utils/createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) +- [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- [frontend/utils/style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/base/text/text.tsx:1-11](file://frontend/base/text/text.tsx#L1-L11) + +Section sources + +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) +- [frontend/svelte-preprocess-react/inject.ts:1-103](file://frontend/svelte-preprocess-react/inject.ts#L1-L103) + +## Core Components + +- `sveltify`: Wraps any React component as a Svelte component; responsible for property passthrough, slot mapping, event bridging, and tree node construction. +- `ReactSlot`: Renders Svelte slot content as React elements, supporting DOM cloning, event listener migration, and style/class name injection. +- Type system: Unified event naming, property exclusion, and Svelte/SvelteKit type adaptation. +- Context system: Bridge and merge strategy between React Context and Svelte. + +Section sources + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:27-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L27-L119) +- [frontend/svelte-preprocess-react/react-slot.tsx:8-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L8-L224) +- [frontend/svelte-preprocess-react/internal/types.ts:4-79](file://frontend/svelte-preprocess-react/internal/types.ts#L4-L79) +- [frontend/svelte-preprocess-react/react-contexts/index.ts:1-123](file://frontend/svelte-preprocess-react/react-contexts/index.ts#L1-L123) + +## Architecture Overview + +The following diagram shows the complete call chain and data flow from the Svelte consumer to the React component: + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Component" +participant Sveltify as "sveltify Wrapper" +participant Bridge as "Bridge" +participant ReactWrapper as "ReactWrapper" +participant ReactComp as "React Component" +participant DOM as "DOM Portal" +Svelte->>Sveltify : Pass props and slots +Sveltify->>Bridge : Create/update tree node +Bridge->>ReactWrapper : Render ReactWrapper +ReactWrapper->>ReactComp : Pass props/events/slots +ReactComp-->>DOM : Render to target container via createPortal +DOM-->>Svelte : Slot content becomes visible +``` + +Diagram sources + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:40-104](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L40-L104) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L224) + +## Detailed Component Analysis + +### sveltify Function and Conversion Mechanism + +- Functional overview + - Wraps React components as Svelte components, automatically handling property passthrough, slot mapping, event bridging, and tree rendering. + - Supports an optional ignore-render option (`ignore`) to control whether a node participates in rendering. +- Key points + - Initializes shared root node and bridge container to ensure the React root is mounted at the document head. + - Generates a unique key for each Svelte instance and establishes parent-child node relationships. + - Completes rendering and updates through cooperation between `Bridge` and `ReactWrapper`. + - Provides a Promise-based return; can only be used after global initialization is complete. +- Parameters and return value + - First parameter: React component type (can include generic slot declarations). + - Second parameter: Optional configuration object, currently supporting the `ignore` field. + - Returns: `Sveltified` type Svelte component (Promise or already-initialized version). + +```mermaid +flowchart TD +Start(["Call sveltify"]) --> InitRoot["Initialize shared root node and bridge container"] +InitRoot --> BuildNode["Build tree node
Set key/ignore/reactComponent"] +BuildNode --> AttachParent["Attach to parent node
Add to nodes and trigger rerender"] +AttachParent --> Render["Call Bridge to render"] +Render --> Done(["Return Sveltified component"]) +``` + +Diagram sources + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:40-104](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L40-L104) + +Section sources + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:27-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L27-L119) +- [frontend/svelte-preprocess-react/index.ts:6-8](file://frontend/svelte-preprocess-react/index.ts#L6-L8) + +### ReactSlot Slot Rendering and Event Handling + +- Functional overview + - Renders Svelte slot content as React elements, supporting DOM cloning, event listener migration, and style/class name injection. + - Optionally observes attribute changes to accommodate dynamic rendering scenarios (such as table column rendering). +- Key points + - Cloning strategy: Traverses child nodes, copies text nodes and element nodes; deep-clones React elements and migrates internally registered side effects. + - Event migration: Reads the event listener list on elements and re-binds them to cloned nodes. + - Property injection: Supports injection of `className` and `style`, converting React style objects to inline styles. + - Observer: Uses a debounced `MutationObserver` to monitor slot changes, ensuring dynamic content is reflected in a timely manner. +- Parameters + - `slot`: The `HTMLElement` corresponding to the slot. + - `clone`: Whether to clone the DOM (default: `false`). + - `className`/`style`: Injected class name and style object. + - `observeAttributes`: Whether to observe attribute changes (default: `false`). + +```mermaid +flowchart TD +Enter(["ReactSlot Render"]) --> CheckSlot{"Does slot exist?"} +CheckSlot --> |No| Exit["Exit"] +CheckSlot --> |Yes| CloneMode{"clone is true?"} +CloneMode --> |Yes| Clone["Clone DOM tree
Migrate event listeners"] +CloneMode --> |No| Mount["Mount directly to container"] +Clone --> Observe{"Observer enabled?"} +Observe --> |Yes| Debounce["Re-render after debounce"] +Observe --> |No| MountProps["Inject className/style and mount"] +Debounce --> Render["Re-clone and render"] +Render --> MountProps +MountProps --> Cleanup["Clean up DOM and observer on unmount"] +Cleanup --> Exit +``` + +Diagram sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:16-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L16-L224) + +Section sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:8-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L8-L224) + +### Type System and Event Mapping + +- Event naming and mapping + - React-side event properties start with uppercase (e.g., `onClick`); Svelte-side event handlers use the `on` prefix (e.g., `onClick` corresponds to `on-click`). + - Type utilities map React event properties to Svelte event handler signatures. +- Property exclusion + - React event properties are excluded from regular properties to avoid conflicts when passed to Svelte components. +- Svelte Props adaptation + - The `children` property is adapted to Svelte's `Snippet` type to support slots and fragments. + +Section sources + +- [frontend/svelte-preprocess-react/internal/types.ts:4-79](file://frontend/svelte-preprocess-react/internal/types.ts#L4-L79) + +### Context System (React Context and Svelte Interoperability) + +- React Context + - Provides contexts such as `IconFont`, `FormItem`, `AutoComplete`, `Suggestion`, and `SuggestionOpen` for sharing state and callbacks between components. +- Svelte-side bridging + - `ContextPropsContext` reads context values inside `ReactSlot`, supporting force-clone and parameter change detection. + - Supports context merge strategy to prevent state loss caused by duplicate Providers. +- Usage recommendations + - In scenarios requiring dynamic rendering or DOM cloning, combine `forceClone` with `observeAttributes` for improved stability. + +Section sources + +- [frontend/svelte-preprocess-react/react-contexts/index.ts:1-123](file://frontend/svelte-preprocess-react/react-contexts/index.ts#L1-L123) + +### Property Conversion Rules and Utilities + +- CamelCase conversion + - Converts underscore-style keys to lowerCamelCase or UpperCamelCase to maintain consistency with React properties. +- Boolean value handling + - Utility functions correctly map boolean values to React properties. +- Function property binding + - Supports function definitions in string form, automatically parsed into executable functions, making it convenient to pass callback logic from the outside. +- Slot property patching + - Special properties like `key` are internally stashed and restored to avoid conflicts with Svelte's internal mechanisms. + +Section sources + +- [frontend/utils/convertToCamelCase.ts:1-22](file://frontend/utils/convertToCamelCase.ts#L1-L22) +- [frontend/utils/createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) +- [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) + +### Event Handling Mechanism + +- Event bubbling and delegation + - `ReactSlot` migrates event listeners during cloning to ensure cloned elements can still respond to events. +- Custom events + - Custom callbacks are injected into React components as stable functions through `ContextPropsContext` and the `useFunction` hook. +- Styles and units + - React style objects are converted to inline style strings or objects, with pixel units automatically added (except for unitless properties). + +Section sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:67-96](file://frontend/svelte-preprocess-react/react-slot.tsx#L67-L96) +- [frontend/utils/hooks/useMemoizedEqualValue.ts:1-15](file://frontend/utils/hooks/useMemoizedEqualValue.ts#L1-L15) +- [frontend/utils/style.ts:1-77](file://frontend/utils/style.ts#L1-L77) + +### Lifecycle Hook Implementations in Svelte + +- Initialization + - A global initialization Promise ensures the runtime environment is ready before rendering. +- Update + - Each node change triggers a rerender; Bridge re-renders `ReactWrapper` and the subtree. +- Destruction + - Cleans up DOM nodes and observers, releasing resources. + +Section sources + +- [frontend/svelte-preprocess-react/inject.ts:95-103](file://frontend/svelte-preprocess-react/inject.ts#L95-L103) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:75-82](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L75-L82) +- [frontend/svelte-preprocess-react/react-slot.tsx:204-212](file://frontend/svelte-preprocess-react/react-slot.tsx#L204-L212) + +## Dependency Analysis + +- Runtime dependencies + - Libraries such as React, ReactDOM, `@ant-design/cssinjs`, `@ant-design/icons`, `@ant-design/x`, and `dayjs` are provided via global injection. +- Utility dependencies + - `lodash-es` provides utilities such as `isEqual`, `debounce`, and `noop`. +- Component dependencies + - `sveltify` depends on `Bridge` and `ReactWrapper` to complete rendering; `ReactSlot` depends on `createPortal` and style utilities. + +```mermaid +graph LR +Inject["inject.ts"] --> Libs["Global Library Injection"] +Sveltify["sveltify.svelte.ts"] --> Bridge["Bridge.svelte"] +Sveltify --> ReactWrapper["ReactWrapper.svelte"] +ReactSlot["react-slot.tsx"] --> Portal["createPortal"] +Utils["Utilities"] --> Sveltify +Utils --> ReactSlot +``` + +Diagram sources + +- [frontend/svelte-preprocess-react/inject.ts:20-85](file://frontend/svelte-preprocess-react/inject.ts#L20-L85) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-7](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L7) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-6](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L6) + +Section sources + +- [frontend/svelte-preprocess-react/inject.ts:1-103](file://frontend/svelte-preprocess-react/inject.ts#L1-L103) + +## Performance Considerations + +- Lazy loading and deferred initialization + - The global initialization Promise and shared root node prevent repeated mounting and multiple initializations. +- Caching and deduplication + - `useMemoizedEqualValue` and `ContextPropsContext` change detection reduce unnecessary re-renders. +- Memory management + - On unmount, disconnects `MutationObserver`, removes DOM nodes and bridge containers to prevent memory leaks. +- Rendering optimization + - `ReactSlot`'s cloning and observation use a debounce strategy to reduce performance pressure from frequent changes. + +Section sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:180-198](file://frontend/svelte-preprocess-react/react-slot.tsx#L180-L198) +- [frontend/utils/hooks/useMemoizedEqualValue.ts:1-15](file://frontend/utils/hooks/useMemoizedEqualValue.ts#L1-L15) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:67-82](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L67-L82) + +## Troubleshooting Guide + +- Slot not displaying + - Check whether the slot exists and has not been destroyed; confirm `clone` mode and `observeAttributes` settings. +- Events not working + - Confirm whether event listeners are migrated along with cloning; check if event listeners are overwritten or removed. +- Style anomalies + - Check whether style objects are correctly converted to inline styles; confirm that units are as expected. +- Performance issues + - Use `forceClone` and debounced observers judiciously; avoid re-renders caused by frequent changes. +- Context conflicts + - Use the merge strategy and parameter change detection of `ContextPropsProvider` to prevent state loss from duplicate Providers. + +Section sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:156-212](file://frontend/svelte-preprocess-react/react-slot.tsx#L156-L212) +- [frontend/utils/style.ts:39-77](file://frontend/utils/style.ts#L39-L77) +- [frontend/svelte-preprocess-react/react-contexts/index.ts:67-123](file://frontend/svelte-preprocess-react/react-contexts/index.ts#L67-L123) + +## Conclusion + +ModelScope Studio's React component bridge system achieves seamless collaboration between React and Svelte through `sveltify` and `ReactSlot`. Its design emphasizes: + +- Clear type constraints and event mapping +- Robust slot rendering and event migration +- Extensible context system and performance optimization strategies +- Clear lifecycle management and resource reclamation + +This system provides a unified component bridging solution for complex frontend applications, ensuring both a good development experience and runtime performance and stability. + +## Appendix: Standard Usage and Example Paths + +- Simple component bridging + - Example: Basic text component bridge + - Path: [frontend/base/text/text.tsx:1-11](file://frontend/base/text/text.tsx#L1-L11) +- Complex component bridging (with slots and events) + - Example: Button component bridge (icon and loading state slots) + - Path: [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- Form component bridging (with state synchronization and action dispatch) + - Example: Form component bridge (value synchronization, action reset, event forwarding) + - Path: [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- Key points for using sveltify + - Path: [frontend/svelte-preprocess-react/sveltify.svelte.ts:27-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L27-L119) +- Key points for using ReactSlot + - Path: [frontend/svelte-preprocess-react/react-slot.tsx:8-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L8-L224) +- Type and event mapping + - Path: [frontend/svelte-preprocess-react/internal/types.ts:4-79](file://frontend/svelte-preprocess-react/internal/types.ts#L4-L79) +- Context system + - Path: [frontend/svelte-preprocess-react/react-contexts/index.ts:1-123](file://frontend/svelte-preprocess-react/react-contexts/index.ts#L1-L123) +- Property conversion and function binding + - Path: [frontend/utils/convertToCamelCase.ts:1-22](file://frontend/utils/convertToCamelCase.ts#L1-L22) + - Path: [frontend/utils/createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) + - Path: [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- Style utilities + - Path: [frontend/utils/style.ts:1-77](file://frontend/utils/style.ts#L1-L77) diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Ant Design Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Ant Design Components API.md new file mode 100644 index 00000000..3134655f --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Ant Design Components API.md @@ -0,0 +1,479 @@ +# Ant Design Components API + + +**Files referenced in this document** +- [frontend/antd/package.json](file://frontend/antd/package.json) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/form/Index.svelte](file://frontend/antd/form/Index.svelte) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/layout/Index.svelte](file://frontend/antd/layout/Index.svelte) +- [frontend/antd/layout/layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) +- [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) +- [frontend/antd/select/select.tsx](file://frontend/antd/select/select.tsx) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/antd/grid/context.ts](file://frontend/antd/grid/context.ts) +- [frontend/antd/table/context.ts](file://frontend/antd/table/context.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design Svelte-based components in ModelScope Studio. It systematically covers the encapsulation approach of Ant Design components at the frontend layer, spanning general components, layout components, navigation components, data entry components, data display components, feedback components, and more. It clarifies property definitions, event handling, slot system, style customization, state management, and data binding mechanisms for each component, providing correspondence with native Ant Design components and TypeScript type specifications. It also provides reference paths for instantiation and configuration, as well as performance optimization and best practice recommendations. + +## Project Structure + +ModelScope Studio's Ant Design Svelte components adopt a "Svelte shell + React component bridge" architecture: the Svelte layer handles property passthrough, slots, and visibility control; the React layer bridges Ant Design components into the Svelte ecosystem via `sveltify`. The utility layer provides unified function wrapping, slot rendering, and context injection capabilities. + +```mermaid +graph TB +subgraph "Svelte Shell Layer" +IDX_BTN["button/Index.svelte"] +IDX_FORM["form/Index.svelte"] +IDX_LAYOUT["layout/Index.svelte"] +end +subgraph "React Bridge Layer" +BTN_TSX["button/button.tsx"] +FORM_TSX["form/form.tsx"] +LAYOUT_BASE["layout/layout.base.tsx"] +TABLE_TSX["table/table.tsx"] +SELECT_TSX["select/select.tsx"] +end +subgraph "Utilities and Contexts" +USE_FN["utils/hooks/useFunction.ts"] +RENDER_ITEMS["utils/renderItems.tsx"] +RENDER_SLOT["utils/renderParamsSlot.tsx"] +GRID_CTX["antd/grid/context.ts"] +TABLE_CTX["antd/table/context.ts"] +end +IDX_BTN --> BTN_TSX +IDX_FORM --> FORM_TSX +IDX_LAYOUT --> LAYOUT_BASE +TABLE_TSX --> TABLE_CTX +SELECT_TSX --> GRID_CTX +BTN_TSX --> USE_FN +FORM_TSX --> USE_FN +TABLE_TSX --> USE_FN +SELECT_TSX --> USE_FN +TABLE_TSX --> RENDER_ITEMS +SELECT_TSX --> RENDER_ITEMS +TABLE_TSX --> RENDER_SLOT +SELECT_TSX --> RENDER_SLOT +``` + +Diagram sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [frontend/antd/table/context.ts:1-29](file://frontend/antd/table/context.ts#L1-L29) + +Section sources + +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) + +## Core Components + +This section provides an overview of responsibilities and typical usage highlights for each component layer: + +- General components: Such as Button, responsible for property passthrough, slots (icon, loading state icon), and visibility control. +- Form components: Such as Form, responsible for two-way form value binding, action triggers (reset/submit/validate), and callback merging. +- Layout components: Such as Layout, selecting specific Header/Footer/Content/Layout components on-demand via the Base component and injecting style class names. +- Data display components: Such as Table, supporting complex scenarios including columns, expand, row selection, pagination, sticky headers, summary, title/footer slots, etc. +- Selector components: Such as Select, supporting option lists, filtering, dropdown/popup rendering, tag/tag-item rendering, and other slots. + +Section sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) + +## Architecture Overview + +The Svelte shell collects and transforms properties via `getProps`/`processProps`/`importComponent`, and then the `sveltify`-wrapped React components carry the actual UI logic. The slot system implements parameterized rendering and context injection via `ReactSlot` and `renderItems`/`renderParamsSlot`. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Shell (Index.svelte)" +participant Utils as "Utilities (useFunction/renderItems/renderParamsSlot)" +participant Bridge as "sveltify-wrapped React Component" +participant AntD as "Ant Design Component" +Svelte->>Utils : "Use useFunction to wrap callbacks/function-type props" +Svelte->>Utils : "Use renderItems to render child items/slots" +Svelte->>Utils : "Use renderParamsSlot to render parameterized slots" +Svelte->>Bridge : "Import and await component loading (importComponent)" +Bridge->>AntD : "Pass through props/events/slots" +AntD-->>Bridge : "Return render result" +Bridge-->>Svelte : "Output final UI" +``` + +Diagram sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +## Detailed Component Analysis + +### Button Component + +- Property definitions + - Common properties: Inherits all properties of Ant Design Button. + - Slots: `icon`, `loading.icon`. + - Meta info: `elem_id`, `elem_classes`, `elem_style`, `visible` for visibility and style control. + - Link behavior: `href_target` maps to `target`. +- Event handling + - Passes through events such as `onClick` from Ant Design Button. +- Slot system + - Supports passing icons or loading state icons as slots, rendered internally via `ReactSlot`. +- Style customization + - Injects class names and inline styles via `elem_classes` and `elem_style`. +- State management and data binding + - No two-way binding; visibility can be controlled by updating props externally. +- TypeScript types + - Uses Ant Design Button's `GetProps` type alias for constraints. +- Correspondence + - React component: Ant Design Button. +- Example reference paths + - [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + - [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant Shell as "button/Index.svelte" +participant Btn as "button/button.tsx" +participant AntBtn as "Ant Design Button" +UI->>Shell : "Pass properties and slots" +Shell->>Btn : "Pass through after processProps" +Btn->>AntBtn : "Render Button and inject slots" +AntBtn-->>UI : "Trigger events / display content" +``` + +Diagram sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) + +Section sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) + +### Form Component + +- Property definitions + - `value`: Form initial or controlled value. + - `formAction`: `'reset'` | `'submit'` | `'validate'` | `null`, used to trigger actions. + - Callbacks: `onValueChange`, `onResetFormAction`. + - Others: `requiredMark`, `feedbackIcons`, `as_item`, `visible`, etc. +- Event handling + - `onValuesChange` merges `onValueChange` to implement value change notifications. + - Action execution: Calls `form.resetFields`/`form.submit`/`form.validateFields` based on `formAction`. +- Slot system + - `requiredMark` can be rendered via a slot. +- Style and visibility + - `elem_id`, `elem_classes`, `elem_style`, `visible` control appearance and display. +- State management and data binding + - Two-way binding: `onValueChange` updates the external `value`; external `value` changes sync back to the form. + - Action decoupling: `onResetFormAction` resets `formAction` after an action completes. +- TypeScript types + - `FormProps` extends Ant Design Form's `GetProps`, adding `value`, `onValueChange`, `formAction`, etc. +- Correspondence + - React component: Ant Design Form. +- Example reference paths + - [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) + - [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant Shell as "form/Index.svelte" +participant Form as "form/form.tsx" +participant AntForm as "Ant Design Form" +UI->>Shell : "Set value/formAction" +Shell->>Form : "Pass through properties and callbacks" +Form->>AntForm : "Create and operate Form instance" +AntForm-->>Form : "onValuesChange/value change" +Form-->>Shell : "onValueChange(value)" +Shell-->>UI : "updateProps({ value })" +UI->>Shell : "formAction='reset'/'submit'/'validate'" +Shell->>Form : "Trigger action" +Form-->>Shell : "onResetFormAction()" +``` + +Diagram sources + +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +Section sources + +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +### Layout Component + +- Property definitions + - `component`: `'header'` | `'footer'` | `'content'` | `'layout'`, determines the specific Ant Design component to render. + - Others: `className`, `id`, `style`, etc. are passed through. +- Slot system + - Receives `children` via the Base component and renders them. +- Style customization + - Base injects different class name prefixes for different `component` values to facilitate theming. +- Correspondence + - React component: Ant Design Layout and its Content/Header/Footer. +- Example reference paths + - [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) + - [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +```mermaid +flowchart TD +Start(["Start"]) --> Choose["Select specific component based on 'component'"] +Choose --> |header| Header["Ant Design Layout.Header"] +Choose --> |footer| Footer["Ant Design Layout.Footer"] +Choose --> |content| Content["Ant Design Layout.Content"] +Choose --> |layout| Layout["Ant Design Layout"] +Header --> Render["Render and inject class names"] +Footer --> Render +Content --> Render +Layout --> Render +Render --> End(["End"]) +``` + +Diagram sources + +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +Section sources + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +### Table Component + +- Property definitions + - `columns`: Column definitions, supporting default columns and extended column constants. + - `rowSelection`, `expandable`: Row selection and expandable configuration, supporting slot injection. + - `pagination`: Pagination configuration, supporting slot injection for quick-jump buttons and page number rendering. + - `loading`: Supports `tip` and `indicator` slots. + - `sticky`, `showSorterTooltip`, `footer`, `title`, `summary`, etc. +- Slot system + - Injects column, row selection, and expandable items via `withColumnItemsContextProvider`/`withRowSelectionItemsContextProvider`/`withExpandableItemsContextProvider`. + - `renderItems` renders columns and child items; `renderParamsSlot` renders parameterized slots (such as pagination buttons, page number rendering, sorter tooltips, etc.). +- Function-type properties + - `useFunction` wraps function-type properties such as `getPopupContainer`, `rowClassName`, `rowKey`, `summary`, and `footer`. +- Performance notes + - Configurations such as columns and row selection are optimized with `useMemo`. +- Correspondence + - React component: Ant Design Table. +- Example reference paths + - [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) + - [frontend/antd/table/context.ts:1-29](file://frontend/antd/table/context.ts#L1-L29) + - [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) + - [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant Shell as "table/Index.svelte" +participant Table as "table/table.tsx" +participant Ctx as "Context (columns/rowSelection/expandable)" +participant AntTable as "Ant Design Table" +UI->>Shell : "Pass columns/rowSelection/expandable/pagination, etc." +Shell->>Table : "processProps and slots" +Table->>Ctx : "Read columns/row selection/expandable items" +Table->>AntTable : "Render and inject slots/function-type properties" +AntTable-->>Table : "Events/render result" +Table-->>Shell : "Output final UI" +``` + +Diagram sources + +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/table/context.ts:1-29](file://frontend/antd/table/context.ts#L1-L29) + +Section sources + +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/table/context.ts:1-29](file://frontend/antd/table/context.ts#L1-L29) + +### Select Component + +- Property definitions + - `options`: Option list, supporting injection via slots. + - `onChange`/`onValueChange`: Value change callbacks. + - `filterOption`/`filterSort`: Filtering and sorting functions. + - `dropdownRender`/`popupRender`/`optionRender`/`tagRender`/`labelRender`: Slot-based rendering. + - `allowClear.prefix`/`removeIcon`/`suffixIcon`/`notFoundContent`/`menuItemSelectedIcon`: Slot-based icons and text. +- Slot system + - `withItemsContextProvider` injects `options`/`default` child items; `renderItems` renders options. + - `renderParamsSlot` renders parameterized slots (such as `maxTagPlaceholder`). +- Function-type properties + - `useFunction` wraps `getPopupContainer`, `dropdownRender`, `popupRender`, `optionRender`, `tagRender`, `labelRender`, `filterOption`, `filterSort`. +- Correspondence + - React component: Ant Design Select. +- Example reference paths + - [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) + - [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + - [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) + - [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +```mermaid +flowchart TD +Start(["Start"]) --> Options["Resolve options/default slot items"] +Options --> RenderOpts["renderItems renders options"] +RenderOpts --> Hooks["useFunction wraps function-type properties"] +Hooks --> Slots["Slot-based icons/text/renderers"] +Slots --> AntSelect["Render Ant Design Select"] +AntSelect --> End(["End"]) +``` + +Diagram sources + +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + +Section sources + +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + +## Dependency Analysis + +- Inter-component dependencies + - Button/Form/Layout/Table/Select all depend on `sveltify` to bridge Ant Design components to Svelte. + - Slots and contexts depend on `renderItems`/`renderParamsSlot` and `createItemsContext`. + - Function-type properties depend on `useFunction` to be wrapped as executable functions. +- External dependencies + - Ant Design: Provides UI foundation capabilities as a React component library. + - Utility libraries: `classnames`, `lodash-es`, etc. assist with styles and object handling. +- Circular dependencies + - No direct circular dependencies found; context injection is exported through independent modules. + +```mermaid +graph LR +Svelte["Svelte Shell"] --> Sveltify["sveltify wrapper"] +Sveltify --> AntD["Ant Design Components"] +Svelte --> Utils["Utility Functions"] +Utils --> RenderItems["renderItems"] +Utils --> RenderSlot["renderParamsSlot"] +Utils --> UseFunction["useFunction"] +Svelte --> Ctx["Context (createItemsContext)"] +``` + +Diagram sources + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +Section sources + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +## Performance Considerations + +- Function-type property wrapping + - Use `useFunction` to wrap incoming strings/functions as executable functions, avoiding recreation of closures on each render. +- Slots and contexts + - `renderItems` and `renderParamsSlot` support cloning and parameterized rendering to reduce redundant rendering overhead. +- Computation caching + - Table/Select extensively use `useMemo` to cache computation results (such as columns, row keys, container functions, etc.). +- Async loading + - The Svelte shell asynchronously loads React components via `importComponent` to reduce initial render pressure. +- Best practices + - Prefer using slots over inline JSX to improve reusability and maintainability. + - Use `$derived` or `useMemo` wrappers for frequently changing props to avoid unnecessary re-renders. + - Properly split components to avoid a single component taking on too many responsibilities. + +## Troubleshooting Guide + +- Slot not taking effect + - Check that the slot key is correct (e.g., `'loading.icon'`, `'pagination.showQuickJumper.goButton'`) and ensure the passed value is an `HTMLElement` or an object with `withParams`. + - Confirm the `forceClone` and `clone` settings for `renderParamsSlot`/`renderItems`. +- Function-type properties not working + - Ensure that the passed string expression is correctly wrapped by `useFunction`; pass `plainText=true` when necessary. +- Form action not triggered + - Confirm the `formAction` value is `'reset'` | `'submit'` | `'validate'` | `null`, and reset `formAction` after the action completes. +- Style anomalies + - Check that `elem_classes` and `elem_style` are correctly injected; for Layout components, ensure the `component` parameter matches the actual layout element. + +Section sources + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +## Conclusion + +ModelScope Studio's Ant Design Svelte components achieve high-fidelity encapsulation of Ant Design components through clear layered design and a powerful slot/context system. Developers can use Ant Design's rich capabilities in Svelte at minimal cost while maintaining good maintainability and performance. It is recommended to prioritize slots and contexts in complex scenarios, combined with function-type property wrapping and `useMemo` caching, for a better development experience and runtime efficiency. + +## Appendix + +- Component inventory (categorized by module) + - General components: Button, Icon, Spin, Space, Typography, etc. + - Layout components: Layout (Header/Footer/Content/Layout), Grid (Row/Col), etc. + - Navigation components: Anchor, Breadcrumb, Dropdown, Menu, Pagination, Steps, Tabs, Tour, etc. + - Data entry components: AutoComplete, Cascader, Checkbox, ColorPicker, DatePicker, Mentions, Radio, Rate, Select, Slider, Switch, TimePicker, TreeSelect, Upload, Input/InputNumber/TextArea/Search/Password/OTP, etc. + - Data display components: Avatar, Badge, Calendar, Card/Card.Grid/Card.Meta, Carousel, Descriptions, Divider, Empty, Image/Image.PreviewGroup, List/List.Item/List.Item.Meta, Masonry/Masonry.Item, Result, Statistical/Countdown/Timer, Table/Table.Column/Table.ColumnGroup/Table.Expandable/Table.RowSelection, etc. + - Feedback components: Alert, Drawer, FloatButton/BackTop/Group, Modal/Static, Message, Notification, Popconfirm, Popover, Progress, QRCode, Result, Tour, Tooltip, Tour/Step, etc. +- Correspondence with native Ant Design + - Each Svelte component wraps the corresponding Ant Design React component via `sveltify`, with consistent properties and events. +- TypeScript type specifications + - Component types are all extended from Ant Design's `GetProps` type alias to ensure type safety. +- Example reference paths + - General components: [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + - Form components: [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) + - Layout components: [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) + - Data display components: [frontend/antd/table/table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) + - Selector components: [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Display Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Display Components API.md new file mode 100644 index 00000000..04812ea8 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Display Components API.md @@ -0,0 +1,578 @@ +# Data Display Components API + + +**Files referenced in this document** +- [avatar.tsx](file://frontend/antd/avatar/avatar.tsx) +- [badge.tsx](file://frontend/antd/badge/badge.tsx) +- [calendar.tsx](file://frontend/antd/calendar/calendar.tsx) +- [card.tsx](file://frontend/antd/card/card.tsx) +- [carousel.tsx](file://frontend/antd/carousel/carousel.tsx) +- [collapse.tsx](file://frontend/antd/collapse/collapse.tsx) +- [descriptions.tsx](file://frontend/antd/descriptions/descriptions.tsx) +- [empty.tsx](file://frontend/antd/empty/empty.tsx) +- [image.tsx](file://frontend/antd/image/image.tsx) +- [list.tsx](file://frontend/antd/list/list.tsx) +- [popover.tsx](file://frontend/antd/popover/popover.tsx) +- [qr-code.tsx](file://frontend/antd/qr-code/qr-code.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [statistic.tsx](file://frontend/antd/statistic/statistic.tsx) +- [table.tsx](file://frontend/antd/table/table.tsx) +- [tabs.tsx](file://frontend/antd/tabs/tabs.tsx) +- [tag.tsx](file://frontend/antd/tag/tag.tsx) +- [timeline.tsx](file://frontend/antd/timeline/timeline.tsx) +- [tooltip.tsx](file://frontend/antd/tooltip/tooltip.tsx) +- [tour.tsx](file://frontend/antd/tour/tour.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design-based data display components in ModelScope Studio, covering: Avatar, Badge, Calendar, Card, Carousel, Collapse, Descriptions, Empty, Image, List, Popover, QRCode, Segmented, Statistic, Table, Tabs, Tag, Timeline, Tooltip, Tour, and Tree. It includes: + +- Property definitions and data format requirements +- Display logic and interaction behaviors +- Standard instantiation and configuration examples (provided as paths) +- Data binding, virtual scrolling, lazy loading, and performance optimization mechanisms +- Key TypeScript type definitions, data transformation, and chart library integration ideas +- Visual design principles and user experience optimization recommendations + +## Project Structure + +These components reside in the `antd` submodule of the frontend directory and follow a unified wrapping pattern: bridging Ant Design components into the Svelte ecosystem via `sveltify`, and implementing flexible content slots and function parameter rendering using `slots` and `renderParamsSlot`. + +```mermaid +graph TB +subgraph "Ant Design Component Layer" +AD_Avatar["Avatar"] +AD_Badge["Badge"] +AD_Calendar["Calendar"] +AD_Card["Card"] +AD_Carousel["Carousel"] +AD_Collapse["Collapse"] +AD_Descriptions["Descriptions"] +AD_Empty["Empty"] +AD_Image["Image"] +AD_List["List"] +AD_Popover["Popover"] +AD_QRCode["QRCode"] +AD_Segmented["Segmented"] +AD_Statistic["Statistic"] +AD_Table["Table"] +AD_Tabs["Tabs"] +AD_Tag["Tag"] +AD_Timeline["Timeline"] +AD_Tooltip["Tooltip"] +AD_Tour["Tour"] +AD_Tree["Tree"] +end +subgraph "sveltify Wrapper Layer" +S_Avatar["avatar.tsx"] +S_Badge["badge.tsx"] +S_Calendar["calendar.tsx"] +S_Card["card.tsx"] +S_Carousel["carousel.tsx"] +S_Collapse["collapse.tsx"] +S_Descriptions["descriptions.tsx"] +S_Empty["empty.tsx"] +S_Image["image.tsx"] +S_List["list.tsx"] +S_Popover["popover.tsx"] +S_QRCode["qr-code.tsx"] +S_Segmented["segmented.tsx"] +S_Statistic["statistic.tsx"] +S_Table["table.tsx"] +S_Tabs["tabs.tsx"] +S_Tag["tag.tsx"] +S_Timeline["timeline.tsx"] +S_Tooltip["tooltip.tsx"] +S_Tour["tour.tsx"] +S_Tree["tree.tsx"] +end +S_Avatar --> AD_Avatar +S_Badge --> AD_Badge +S_Calendar --> AD_Calendar +S_Card --> AD_Card +S_Carousel --> AD_Carousel +S_Collapse --> AD_Collapse +S_Descriptions --> AD_Descriptions +S_Empty --> AD_Empty +S_Image --> AD_Image +S_List --> AD_List +S_Popover --> AD_Popover +S_QRCode --> AD_QRCode +S_Segmented --> AD_Segmented +S_Statistic --> AD_Statistic +S_Table --> AD_Table +S_Tabs --> AD_Tabs +S_Tag --> AD_Tag +S_Timeline --> AD_Timeline +S_Tooltip --> AD_Tooltip +S_Tour --> AD_Tour +S_Tree --> AD_Tree +``` + +Diagram sources + +- [avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) +- [calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) +- [carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) +- [image.tsx:1-89](file://frontend/antd/image/image.tsx#L1-L89) +- [list.tsx:1-36](file://frontend/antd/list/list.tsx#L1-L36) +- [popover.tsx:1-37](file://frontend/antd/popover/popover.tsx#L1-L37) +- [qr-code.tsx:1-200](file://frontend/antd/qr-code/qr-code.tsx#L1-L200) +- [segmented.tsx:1-47](file://frontend/antd/segmented/segmented.tsx#L1-L47) +- [statistic.tsx:1-34](file://frontend/antd/statistic/statistic.tsx#L1-L34) +- [table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [tabs.tsx:1-121](file://frontend/antd/tabs/tabs.tsx#L1-L121) +- [tag.tsx:1-200](file://frontend/antd/tag/tag.tsx#L1-L200) +- [timeline.tsx:1-200](file://frontend/antd/timeline/timeline.tsx#L1-L200) +- [tooltip.tsx:1-200](file://frontend/antd/tooltip/tooltip.tsx#L1-L200) +- [tour.tsx:1-200](file://frontend/antd/tour/tour.tsx#L1-L200) +- [tree.tsx:1-200](file://frontend/antd/tree/tree.tsx#L1-L200) + +Section sources + +- [avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) +- [calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) +- [carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) +- [image.tsx:1-89](file://frontend/antd/image/image.tsx#L1-L89) +- [list.tsx:1-36](file://frontend/antd/list/list.tsx#L1-L36) +- [popover.tsx:1-37](file://frontend/antd/popover/popover.tsx#L1-L37) +- [segmented.tsx:1-47](file://frontend/antd/segmented/segmented.tsx#L1-L47) +- [statistic.tsx:1-34](file://frontend/antd/statistic/statistic.tsx#L1-L34) +- [table.tsx:1-279](file://frontend/antd/table/table.tsx#L1-L279) +- [tabs.tsx:1-121](file://frontend/antd/tabs/tabs.tsx#L1-L121) + +## Core Components + +This section provides an overview of each component's responsibility and common wrapping strategy: + +- All components use `sveltify` to wrap Ant Design components, supporting `slots` and `renderParamsSlot` render function parameters. +- Most components support `children` forwarding and various named slots (e.g., `title`, `extra`, `footer`, `header`, `content`, `image`, `description`, `placeholder`, `mask`, `toolbarRender`, `imageRender`, `tabBarExtraContent`, `tabProps.*`, etc.) for flexible appearance and behavior customization. +- Some components wrap event callbacks to ensure correct execution in the Svelte environment. + +Section sources + +- [avatar.tsx:6-25](file://frontend/antd/avatar/avatar.tsx#L6-L25) +- [badge.tsx:6-18](file://frontend/antd/badge/badge.tsx#L6-L18) +- [card.tsx:37-146](file://frontend/antd/card/card.tsx#L37-L146) +- [carousel.tsx:8-28](file://frontend/antd/carousel/carousel.tsx#L8-L28) +- [collapse.tsx:11-49](file://frontend/antd/collapse/collapse.tsx#L11-L49) +- [descriptions.tsx:10-37](file://frontend/antd/descriptions/descriptions.tsx#L10-L37) +- [empty.tsx:6-49](file://frontend/antd/empty/empty.tsx#L6-L49) +- [image.tsx:15-85](file://frontend/antd/image/image.tsx#L15-L85) +- [list.tsx:8-33](file://frontend/antd/list/list.tsx#L8-L33) +- [popover.tsx:7-34](file://frontend/antd/popover/popover.tsx#L7-L34) +- [segmented.tsx:10-43](file://frontend/antd/segmented/segmented.tsx#L10-L43) +- [statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) +- [table.tsx:28-275](file://frontend/antd/table/table.tsx#L28-L275) +- [tabs.tsx:12-117](file://frontend/antd/tabs/tabs.tsx#L12-L117) + +## Architecture Overview + +The following sequence diagram illustrates the key flow from component wrapping to rendering: Svelte converts props and slots into Ant Design component props via `sveltify`; functional parameters are wrapped with `useFunction` or `createFunction`; complex configuration objects are merged with `omitUndefinedProps` and slots are injected. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Component" +participant Sveltify as "sveltify Wrapper" +participant AntD as "Ant Design Component" +participant Utils as "Utility Functions
useFunction/createFunction/renderParamsSlot" +Svelte->>Sveltify : Passes props and slots +Sveltify->>Utils : Wraps function params / merges config +Utils-->>Sveltify : Returns executable functions or config objects +Sveltify->>AntD : Renders and passes props +AntD-->>Svelte : Fires callbacks / returns render result +``` + +Diagram sources + +- [table.tsx:76-134](file://frontend/antd/table/table.tsx#L76-L134) +- [card.tsx:40-49](file://frontend/antd/card/card.tsx#L40-L49) +- [image.tsx:32-34](file://frontend/antd/image/image.tsx#L32-L34) +- [popover.tsx:10-12](file://frontend/antd/popover/popover.tsx#L10-L12) + +## Component Details + +### Avatar + +- **Purpose**: Displays user avatars or icons; supports `icon` and `src` slots. +- **Key Points**: + - Supports `slots.icon` and `slots.src`; slot content takes priority if present, otherwise falls back to props. + - Slots are rendered via `ReactSlot`. +- **Typical usage path**: + - [Avatar basic usage:6-25](file://frontend/antd/avatar/avatar.tsx#L6-L25) + +Section sources + +- [avatar.tsx:6-25](file://frontend/antd/avatar/avatar.tsx#L6-L25) + +### Badge + +- **Purpose**: Displays a badge count or text on avatars, buttons, and other elements. +- **Key Points**: + - Supports `slots.count` and `slots.text` for dynamic badge content rendering. +- **Typical usage path**: + - [Badge count and text:6-18](file://frontend/antd/badge/badge.tsx#L6-L18) + +Section sources + +- [badge.tsx:6-18](file://frontend/antd/badge/badge.tsx#L6-L18) + +### Calendar + +- **Purpose**: Date selection and schedule display. +- **Key Points**: + - `value`/`defaultValue`/`validRange` are processed with `dayjs` formatting. + - `onChange`/`onPanelChange`/`onSelect` callbacks are uniformly converted to second-level timestamps. + - Supports `slots.cellRender`/`fullCellRender`/`headerRender` function slots. +- **Typical usage path**: + - [Calendar date formatting and callbacks:17-98](file://frontend/antd/calendar/calendar.tsx#L17-L98) + +Section sources + +- [calendar.tsx:17-98](file://frontend/antd/calendar/calendar.tsx#L17-L98) + +### Card + +- **Purpose**: Container component supporting title, extra actions, cover image, action area, and tab pages. +- **Key Points**: + - Supports `slots.title`/`extra`/`cover`/`tabBarExtraContent`/`left`/`right`, etc. + - `actions` are automatically collected from child nodes via `useTargets`. + - `tabList` is resolved from context via `renderItems`. + - `tabProps.indicator.size`, `more.icon`, `tabProps.renderTabBar`, `tabProps.tabBarExtraContent.*`, etc. can all be slotted. +- **Typical usage path**: + - [Card with tab pages and action area:37-146](file://frontend/antd/card/card.tsx#L37-L146) + +Section sources + +- [card.tsx:37-146](file://frontend/antd/card/card.tsx#L37-L146) + +### Carousel + +- **Purpose**: Carousel display of multiple images or content panels. +- **Key Points**: + - Uses `useTargets` to extract child nodes as carousel items. + - `afterChange`/`beforeChange` are wrapped via `useFunction`. +- **Typical usage path**: + - [Carousel item rendering:8-28](file://frontend/antd/carousel/carousel.tsx#L8-L28) + +Section sources + +- [carousel.tsx:8-28](file://frontend/antd/carousel/carousel.tsx#L8-L28) + +### Collapse + +- **Purpose**: Grouping content with collapse/expand behavior. +- **Key Points**: + - Supports `slots.expandIcon` function slot. + - `items` are resolved from context via `renderItems`, supporting `label`/`extra`/`children` structure. +- **Typical usage path**: + - [Collapse items and expand icon:11-49](file://frontend/antd/collapse/collapse.tsx#L11-L49) + +Section sources + +- [collapse.tsx:11-49](file://frontend/antd/collapse/collapse.tsx#L11-L49) + +### Descriptions + +- **Purpose**: Displays information in key-value pairs. +- **Key Points**: + - Supports `slots.title`/`extra`; `items` are resolved via `renderItems` with `label`/`children` fields. +- **Typical usage path**: + - [Descriptions item rendering:10-37](file://frontend/antd/descriptions/descriptions.tsx#L10-L37) + +Section sources + +- [descriptions.tsx:10-37](file://frontend/antd/descriptions/descriptions.tsx#L10-L37) + +### Empty + +- **Purpose**: Placeholder displayed when there is no data. +- **Key Points**: + - Supports `slots.description`/`image`; `image` supports default constant mapping. + - `styles` supports a function that returns a style object. +- **Typical usage path**: + - [Empty with custom image and description:6-49](file://frontend/antd/empty/empty.tsx#L6-L49) + +Section sources + +- [empty.tsx:6-49](file://frontend/antd/empty/empty.tsx#L6-L49) + +### Image + +- **Purpose**: Image display and preview. +- **Key Points**: + - Supports `slots.placeholder`, `preview.mask`, `preview.closeIcon`, `preview.toolbarRender`, `preview.imageRender`. + - `preview` configuration is merged via `getConfig`/`omitUndefinedProps`; `getContainer`/`toolbarRender`/`imageRender` are wrapped via `useFunction`. +- **Typical usage path**: + - [Image preview and toolbar rendering:15-85](file://frontend/antd/image/image.tsx#L15-L85) + +Section sources + +- [image.tsx:15-85](file://frontend/antd/image/image.tsx#L15-L85) + +### List + +- **Purpose**: Long list display with load-more support. +- **Key Points**: + - Supports `slots.footer`/`header`/`loadMore`/`renderItem`; `renderItem` is rendered via `renderParamsSlot` with forced cloning. +- **Typical usage path**: + - [List header, footer, and load more:8-33](file://frontend/antd/list/list.tsx#L8-L33) + +Section sources + +- [list.tsx:8-33](file://frontend/antd/list/list.tsx#L8-L33) + +### Popover + +- **Purpose**: Floating bubble card displaying a title and content. +- **Key Points**: + - Supports `slots.title`/`content`; `title`/`content` are cloned via `ReactSlot`. + - `afterOpenChange`/`getPopupContainer` are wrapped via `useFunction`. +- **Typical usage path**: + - [Popover title and content:7-34](file://frontend/antd/popover/popover.tsx#L7-L34) + +Section sources + +- [popover.tsx:7-34](file://frontend/antd/popover/popover.tsx#L7-L34) + +### QRCode + +- **Purpose**: Generate and display QR codes. +- **Typical usage path**: + - [QRCode component:1-200](file://frontend/antd/qr-code/qr-code.tsx#L1-L200) + +Section sources + +- [qr-code.tsx:1-200](file://frontend/antd/qr-code/qr-code.tsx#L1-L200) + +### Segmented + +- **Purpose**: Switching between multiple options. +- **Key Points**: + - Supports resolving `options`/`default` from context; `onChange` exposes the selected value via `onValueChange`. +- **Typical usage path**: + - [Segmented option rendering:10-43](file://frontend/antd/segmented/segmented.tsx#L10-L43) + +Section sources + +- [segmented.tsx:10-43](file://frontend/antd/segmented/segmented.tsx#L10-L43) + +### Statistic + +- **Purpose**: Displays numeric values with units, prefix, and suffix. +- **Key Points**: + - Supports `slots.prefix`/`suffix`/`title`/`formatter`; `formatter` is rendered via `renderParamsSlot`. +- **Typical usage path**: + - [Statistic value formatting:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) + +Section sources + +- [statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) + +### Table + +- **Purpose**: Data table display and interaction. +- **Key Points**: + - Supports complex configurations including `columns`, `rowSelection`, `expandable`, `sticky`, `pagination`, `loading`, `footer`, `title`, `summary`, `showSorterTooltip`, etc. + - Injects column, expand, and row-selection contexts via multiple `with*ContextProvider` layers. + - Uses `renderItems` and `renderParamsSlot` to dynamically resolve items and function parameters; uses `createFunction`/`omitUndefinedProps` to wrap and merge configuration. +- **Typical usage path**: + - [Table columns and pagination slots:28-275](file://frontend/antd/table/table.tsx#L28-L275) + +Section sources + +- [table.tsx:28-275](file://frontend/antd/table/table.tsx#L28-L275) + +### Tabs + +- **Purpose**: Tab container and switching. +- **Key Points**: + - Supports `slots.addIcon`/`removeIcon`/`renderTabBar`/`tabBarExtraContent`/`left`/`right`/`more.icon`. + - `indicator.size`, `more.getPopupContainer`, `renderTabBar` are wrapped via `useFunction`; `items` are resolved via `renderItems`. +- **Typical usage path**: + - [Tabs with extra content:12-117](file://frontend/antd/tabs/tabs.tsx#L12-L117) + +Section sources + +- [tabs.tsx:12-117](file://frontend/antd/tabs/tabs.tsx#L12-L117) + +### Tag + +- **Purpose**: Marking and categorization. +- **Typical usage path**: + - [Tag component:1-200](file://frontend/antd/tag/tag.tsx#L1-L200) + +Section sources + +- [tag.tsx:1-200](file://frontend/antd/tag/tag.tsx#L1-L200) + +### Timeline + +- **Purpose**: Displays events in chronological order. +- **Typical usage path**: + - [Timeline component:1-200](file://frontend/antd/timeline/timeline.tsx#L1-L200) + +Section sources + +- [timeline.tsx:1-200](file://frontend/antd/timeline/timeline.tsx#L1-L200) + +### Tooltip + +- **Purpose**: Concise hint text. +- **Typical usage path**: + - [Tooltip component:1-200](file://frontend/antd/tooltip/tooltip.tsx#L1-L200) + +Section sources + +- [tooltip.tsx:1-200](file://frontend/antd/tooltip/tooltip.tsx#L1-L200) + +### Tour + +- **Purpose**: Guided tutorial. +- **Typical usage path**: + - [Tour component:1-200](file://frontend/antd/tour/tour.tsx#L1-L200) + +Section sources + +- [tour.tsx:1-200](file://frontend/antd/tour/tour.tsx#L1-L200) + +### Tree + +- **Purpose**: Hierarchical data display and selection. +- **Typical usage path**: + - [Tree component:1-200](file://frontend/antd/tree/tree.tsx#L1-L200) + +Section sources + +- [tree.tsx:1-200](file://frontend/antd/tree/tree.tsx#L1-L200) + +## Dependency Analysis + +- **Inter-component Coupling**: + - Card and Tabs share context (the `tabList` context is reused when Card embeds Tabs). + - Table injects column, expand, and row-selection contexts via multiple context providers. + - Most components share utilities such as `renderItems`, `renderParamsSlot`, `useFunction`, and `omitUndefinedProps`. +- **External Dependencies**: + - Ant Design component library and `dayjs` (for the Calendar component). + - `lodash-es` (for type checking in the Empty component). + +```mermaid +graph LR +RenderItems["renderItems"] +RenderParam["renderParamsSlot"] +UseFunc["useFunction"] +OmitUndef["omitUndefinedProps"] +Card["card.tsx"] --> RenderItems +Card --> UseFunc +Tabs["tabs.tsx"] --> RenderItems +Tabs --> UseFunc +Collapse["collapse.tsx"] --> RenderItems +Collapse --> UseFunc +Descriptions["descriptions.tsx"] --> RenderItems +Table["table.tsx"] --> RenderItems +Table --> RenderParam +Table --> UseFunc +Table --> OmitUndef +Image["image.tsx"] --> UseFunc +Image --> OmitUndef +Popover["popover.tsx"] --> UseFunc +Statistic["statistic.tsx"] --> UseFunc +Segmented["segmented.tsx"] --> RenderItems +Calendar["calendar.tsx"] --> UseFunc +``` + +Diagram sources + +- [card.tsx:10-14](file://frontend/antd/card/card.tsx#L10-L14) +- [tabs.tsx:6-10](file://frontend/antd/tabs/tabs.tsx#L6-L10) +- [collapse.tsx:4-8](file://frontend/antd/collapse/collapse.tsx#L4-L8) +- [descriptions.tsx:4-7](file://frontend/antd/descriptions/descriptions.tsx#L4-L7) +- [table.tsx:7-18](file://frontend/antd/table/table.tsx#L7-L18) +- [image.tsx:3-6](file://frontend/antd/image/image.tsx#L3-L6) +- [popover.tsx:4-5](file://frontend/antd/popover/popover.tsx#L4-L5) +- [statistic.tsx:4-6](file://frontend/antd/statistic/statistic.tsx#L4-L6) +- [segmented.tsx:3-6](file://frontend/antd/segmented/segmented.tsx#L3-L6) +- [calendar.tsx:3-4](file://frontend/antd/calendar/calendar.tsx#L3-L4) + +Section sources + +- [card.tsx:10-14](file://frontend/antd/card/card.tsx#L10-L14) +- [tabs.tsx:6-10](file://frontend/antd/tabs/tabs.tsx#L6-L10) +- [table.tsx:7-18](file://frontend/antd/table/table.tsx#L7-L18) + +## Performance Considerations + +- **Virtual Scrolling and Lazy Loading** + - List-type components (List, Table) can enable virtual scrolling and lazy loading via external configuration to reduce DOM count and reflow overhead. + - It is recommended to enable virtualization and paginated loading for large data sets. +- **Render Optimization** + - Use `useMemo` to cache computed results (e.g., Table's `columns`, `rowSelection`, `expandable`). + - Split slot rendering appropriately to avoid unnecessary repeated rendering. +- **Event and Function Wrapping** + - Use `useFunction`/`createFunction` to wrap callbacks, ensuring stable execution within the Svelte lifecycle and avoiding closure pitfalls. +- **Image and Preview** + - The Image component supports `placeholder` and preview toolbar customization; set dimensions and lazy loading strategies appropriately to reduce initial page load pressure. + +## Troubleshooting Guide + +- **Slot Not Working** + - Confirm that the slot name is correct (e.g., `preview.mask`, `tabProps.renderTabBar`, `loading.tip`, etc.). + - Check for missing combinations of `slots.*` and props. +- **Callback Not Firing** + - Ensure callbacks are wrapped via `useFunction`; verify event naming and parameter signatures. +- **Date Format Issues (Calendar)** + - The Calendar component internally converts time to second-level timestamps; confirm the input value type and range. +- **Table Columns and Expand Configuration** + - When `columns` is empty, the component attempts to resolve from context; confirm that the context correctly provides `default`/`items`. +- **Style Overrides** + - Empty's `styles` supports functional returns; pay attention to the return object structure and key names. + +Section sources + +- [image.tsx:32-34](file://frontend/antd/image/image.tsx#L32-L34) +- [popover.tsx:10-12](file://frontend/antd/popover/popover.tsx#L10-L12) +- [calendar.tsx:85-94](file://frontend/antd/calendar/calendar.tsx#L85-L94) +- [table.tsx:67-75](file://frontend/antd/table/table.tsx#L67-L75) +- [empty.tsx:34-45](file://frontend/antd/empty/empty.tsx#L34-L45) + +## Conclusion + +ModelScope Studio's data display components achieve seamless integration with Ant Design through a unified `sveltify` wrapper, providing powerful slot and function parameter extension capabilities. With context resolution and utility functions, developers can quickly build card layouts, carousels, collapse panels, description lists, image previews, data tables, tag clouds, and other common data display scenarios. It is recommended to combine virtual scrolling, lazy loading, and style optimization strategies in real-world projects to further improve performance and user experience. + +## Appendix + +- **TypeScript Type Definition Key Points** + - Most components obtain types via `GetProps`, then extend props as needed (e.g., `onValueChange`, `containsGrid`, etc.). + - For complex configuration objects (e.g., `preview`, `loading`, `pagination`, `sticky`, `showSorterTooltip`, `components`), use `getConfig`/`omitUndefinedProps` to merge and inject slots. +- **Data Transformation and Chart Integration** + - The Calendar component internally converts time to `dayjs` and outputs second-level timestamps in callbacks, making it easy to interface with backends or chart libraries. + - The Table component supports mapping business data to columns and rows via `slots` and `renderItems`, making it easy to integrate with visualization libraries (e.g., ECharts, AntV). +- **Visual Design and Experience Optimization** + - Use `Empty` to improve readability in no-data scenarios. + - Use `Tooltip`/`Popover` to provide contextual help information. + - Use `Statistic`/`Segmented`/`Tag` and other components to enhance information density and interaction feedback. diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Entry Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Entry Components API.md new file mode 100644 index 00000000..e4889737 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Data Entry Components API.md @@ -0,0 +1,523 @@ +# Data Entry Components API + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/auto-complete/auto-complete.tsx](file://frontend/antd/auto-complete/auto-complete.tsx) +- [frontend/antd/cascader/cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [frontend/antd/checkbox/checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [frontend/antd/color-picker/color-picker.tsx](file://frontend/antd/color-picker/color-picker.tsx) +- [frontend/antd/date-picker/date-picker.tsx](file://frontend/antd/date-picker/date-picker.tsx) +- [frontend/antd/input/input.tsx](file://frontend/antd/input/input.tsx) +- [frontend/antd/input-number/input-number.tsx](file://frontend/antd/input-number/input-number.tsx) +- [frontend/antd/mentions/mentions.tsx](file://frontend/antd/mentions/mentions.tsx) +- [frontend/antd/radio/radio.tsx](file://frontend/antd/radio/radio.tsx) +- [frontend/antd/rate/rate.tsx](file://frontend/antd/rate/rate.tsx) +- [frontend/antd/select/select.tsx](file://frontend/antd/select/select.tsx) +- [frontend/antd/slider/slider.tsx](file://frontend/antd/slider/slider.tsx) +- [frontend/antd/switch/switch.tsx](file://frontend/antd/switch/switch.tsx) +- [frontend/antd/time-picker/time-picker.tsx](file://frontend/antd/time-picker/time-picker.tsx) +- [frontend/antd/transfer/transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [frontend/antd/tree-select/tree-select.tsx](file://frontend/antd/tree-select/tree-select.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design-based data entry components in ModelScope Studio, covering: AutoComplete, Cascader, Checkbox, ColorPicker, DatePicker, Form, Input, InputNumber, Mentions, Radio, Rate, Select, Slider, Switch, TimePicker, Transfer, TreeSelect, Upload (to be added). It includes: + +- Property definitions and type constraints +- Data validation and formatting strategies +- Event callbacks and data binding mechanisms +- Standard usage example paths (using source code paths instead of inline code) +- Recommendations for interfacing with backend APIs +- Key points for user experience and performance optimization + +## Project Structure + +ModelScope Studio wraps Ant Design components as Svelte components, uniformly using `sveltify` to wrap the React AntD components, and providing a unified `onValueChange` callback, slot rendering, and value change hooks at the frontend layer for two-way data binding with the Python backend. + +```mermaid +graph TB +subgraph "Backend Component Export" +PY["components.py
Exports each AntD component"] +end +subgraph "Frontend Wrapper Layer" +F_FORM["form/form.tsx"] +F_AUTO["auto-complete/auto-complete.tsx"] +F_CASCADE["cascader/cascader.tsx"] +F_CHECK["checkbox/checkbox.tsx"] +F_COLOR["color-picker/color-picker.tsx"] +F_DATE["date-picker/date-picker.tsx"] +F_INPUT["input/input.tsx"] +F_NUM["input-number/input-number.tsx"] +F_MENTIONS["mentions/mentions.tsx"] +F_RADIO["radio/radio.tsx"] +F_RATE["rate/rate.tsx"] +F_SELECT["select/select.tsx"] +F_SLIDER["slider/slider.tsx"] +F_SWITCH["switch/switch.tsx"] +F_TIME["time-picker/time-picker.tsx"] +F_TRANS["transfer/transfer.tsx"] +F_TSELECT["tree-select/tree-select.tsx"] +end +PY --> F_FORM +PY --> F_AUTO +PY --> F_CASCADE +PY --> F_CHECK +PY --> F_COLOR +PY --> F_DATE +PY --> F_INPUT +PY --> F_NUM +PY --> F_MENTIONS +PY --> F_RADIO +PY --> F_RATE +PY --> F_SELECT +PY --> F_SLIDER +PY --> F_SWITCH +PY --> F_TIME +PY --> F_TRANS +PY --> F_TSELECT +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/auto-complete/auto-complete.tsx:1-151](file://frontend/antd/auto-complete/auto-complete.tsx#L1-L151) +- [frontend/antd/cascader/cascader.tsx:1-207](file://frontend/antd/cascader/cascader.tsx#L1-L207) +- [frontend/antd/checkbox/checkbox.tsx:1-22](file://frontend/antd/checkbox/checkbox.tsx#L1-L22) +- [frontend/antd/color-picker/color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [frontend/antd/date-picker/date-picker.tsx:1-234](file://frontend/antd/date-picker/date-picker.tsx#L1-L234) +- [frontend/antd/input/input.tsx:1-119](file://frontend/antd/input/input.tsx#L1-L119) +- [frontend/antd/input-number/input-number.tsx:1-92](file://frontend/antd/input-number/input-number.tsx#L1-L92) +- [frontend/antd/mentions/mentions.tsx:1-80](file://frontend/antd/mentions/mentions.tsx#L1-L80) +- [frontend/antd/radio/radio.tsx:1-32](file://frontend/antd/radio/radio.tsx#L1-L32) +- [frontend/antd/rate/rate.tsx:1-45](file://frontend/antd/rate/rate.tsx#L1-L45) +- [frontend/antd/select/select.tsx:1-181](file://frontend/antd/select/select.tsx#L1-L181) +- [frontend/antd/slider/slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [frontend/antd/switch/switch.tsx:1-42](file://frontend/antd/switch/switch.tsx#L1-L42) +- [frontend/antd/time-picker/time-picker.tsx:1-201](file://frontend/antd/time-picker/time-picker.tsx#L1-L201) +- [frontend/antd/transfer/transfer.tsx:1-112](file://frontend/antd/transfer/transfer.tsx#L1-L112) +- [frontend/antd/tree-select/tree-select.tsx:1-163](file://frontend/antd/tree-select/tree-select.tsx#L1-L163) + +Section sources + +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +## Core Components + +This section provides an overview of the common patterns and key interfaces for all data entry components: + +- **Value binding**: All support `value` and `onValueChange` for controlled/uncontrolled switching and two-way binding. +- **Slot system**: Many components support `slots` (e.g., `allowClear.clearIcon`, `prefix`, `suffix`, `popupRender`, etc.) for custom rendering. +- **Functional props**: Some props support function values (e.g., `formatter`, `parser`, `disabledDate`, etc.), wrapped via `useFunction`. +- **Options/tree data**: Select, Cascader, TreeSelect, AutoComplete, Mentions, etc. support rendering items via `children` or `options`/`treeData`. +- **Form integration**: Form provides global form state management, reset, submit, validate actions, and `requiredMark`/`feedbackIcons` support. + +Section sources + +- [frontend/antd/form/form.tsx:8-76](file://frontend/antd/form/form.tsx#L8-L76) +- [frontend/antd/select/select.tsx:11-178](file://frontend/antd/select/select.tsx#L11-L178) +- [frontend/antd/cascader/cascader.tsx:19-204](file://frontend/antd/cascader/cascader.tsx#L19-L204) +- [frontend/antd/tree-select/tree-select.tsx:14-161](file://frontend/antd/tree-select/tree-select.tsx#L14-L161) +- [frontend/antd/auto-complete/auto-complete.tsx:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) +- [frontend/antd/mentions/mentions.tsx:11-77](file://frontend/antd/mentions/mentions.tsx#L11-L77) + +## Architecture Overview + +The following diagram shows the common call chain for data entry components: frontend components pass values upstream via the `onValueChange` callback; the Form component handles form-level actions (reset/submit/validate) and global `requiredMark`/`feedbackIcons`; some components format values internally (e.g., date/time components). + +```mermaid +sequenceDiagram +participant U as "User" +participant C as "Data Entry Component" +participant F as "Form Component" +participant B as "Backend Service" +U->>C : Input/Select/Change +C->>C : Triggers onChange/onValueChange +C-->>F : onValueChange(value) +F->>F : setFieldsValue / submit / validate +F-->>B : Submits form data +B-->>F : Returns result/error +F-->>U : Displays feedback/error message +``` + +Diagram sources + +- [frontend/antd/form/form.tsx:27-76](file://frontend/antd/form/form.tsx#L27-L76) +- [frontend/antd/date-picker/date-picker.tsx:162-170](file://frontend/antd/date-picker/date-picker.tsx#L162-L170) +- [frontend/antd/time-picker/time-picker.tsx:131-143](file://frontend/antd/time-picker/time-picker.tsx#L131-L143) + +## Component Details + +### Form + +- **Responsibility**: Wraps AntD Form, providing `value`, `onValueChange`, `formAction` (reset/submit/validate), `requiredMark`, and `feedbackIcons` capabilities. +- **Key Points**: + - Creates a form instance via `AForm.useForm`. + - Executes reset/submit/validate when `formAction` changes. + - Syncs upstream value via `onValuesChange` and triggers `onValueChange`. +- **Typical usage path** + - [Form container implementation:15-76](file://frontend/antd/form/form.tsx#L15-L76) + +Section sources + +- [frontend/antd/form/form.tsx:8-76](file://frontend/antd/form/form.tsx#L8-L76) + +### AutoComplete + +- **Capabilities**: Supports options list, filtering, popup rendering, clear icon, empty placeholder, etc. +- **Key Points**: + - Uses `useValueChange` for controlled `value`. + - Supports slots: `allowClear.clearIcon`, `dropdownRender`, `popupRender`, `notFoundContent`. + - Supports `filterOption` function and `getPopupContainer`. +- **Typical usage path** + - [AutoComplete component:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) + +Section sources + +- [frontend/antd/auto-complete/auto-complete.tsx:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) + +### Cascader + +- **Capabilities**: Multi-level cascading selection; supports dynamic loading, search, tag rendering, and custom dropdown panel. +- **Key Points**: + - Supports two data sources: `options` and `children`. + - `showSearch` supports object configuration and `slots['showSearch.render']`. + - Supports `onLoadData` for dynamic loading. +- **Typical usage path** + - [Cascader component:19-204](file://frontend/antd/cascader/cascader.tsx#L19-L204) + +Section sources + +- [frontend/antd/cascader/cascader.tsx:19-204](file://frontend/antd/cascader/cascader.tsx#L19-L204) + +### Checkbox + +- **Capabilities**: Boolean selection; supports `onValueChange`. +- **Key Points**: + - Forwards the native event in `onChange` and triggers `onValueChange(value)`. +- **Typical usage path** + - [Checkbox component:4-19](file://frontend/antd/checkbox/checkbox.tsx#L4-L19) + +Section sources + +- [frontend/antd/checkbox/checkbox.tsx:4-19](file://frontend/antd/checkbox/checkbox.tsx#L4-L19) + +### ColorPicker + +- **Capabilities**: Supports solid color/gradient, preset colors, and multiple output formats (rgb/hex/hsb). +- **Key Points**: + - `onChange` returns different format arrays or a single string depending on whether gradient mode is active. + - Supports `presets` slot and `panelRender`/`showText` customization. +- **Typical usage path** + - [ColorPicker component:11-103](file://frontend/antd/color-picker/color-picker.tsx#L11-L103) + +Section sources + +- [frontend/antd/color-picker/color-picker.tsx:11-103](file://frontend/antd/color-picker/color-picker.tsx#L11-L103) + +### DatePicker + +- **Capabilities**: Single-date/range selection, time selection, preset shortcuts, disabled dates/times, custom cell/panel rendering. +- **Key Points**: + - Internally formats input values as `dayjs` and outputs second-level timestamps in `onChange`/`onPanelChange`. + - Supports `defaultValue` formatting within the `showTime` object. + - Supports slots: `presets`, `cellRender`, `panelRender`, `renderExtraFooter`, etc. +- **Typical usage path** + - [DatePicker component:40-231](file://frontend/antd/date-picker/date-picker.tsx#L40-L231) + +Section sources + +- [frontend/antd/date-picker/date-picker.tsx:40-231](file://frontend/antd/date-picker/date-picker.tsx#L40-L231) + +### Input + +- **Capabilities**: Basic text input; supports prefix/suffix, character counter, clear icon, and slot extensions. +- **Key Points**: + - `useValueChange` for controlled `value`. + - Supports `showCount.formatter` slot and `count`-series functions. + - Supports `addonBefore`/`addonAfter`, `prefix`/`suffix`, `allowClear.clearIcon`. +- **Typical usage path** + - [Input component:10-116](file://frontend/antd/input/input.tsx#L10-L116) + +Section sources + +- [frontend/antd/input/input.tsx:10-116](file://frontend/antd/input/input.tsx#L10-L116) + +### InputNumber + +- **Capabilities**: Numeric input; supports custom step buttons, prefix/suffix, `formatter`/`parser`. +- **Key Points**: + - `useValueChange` for controlled `value`. + - Supports `controls.upIcon`/`downIcon` slots and `addonBefore`/`addonAfter`, `prefix`/`suffix`. +- **Typical usage path** + - [InputNumber component:7-91](file://frontend/antd/input-number/input-number.tsx#L7-L91) + +Section sources + +- [frontend/antd/input-number/input-number.tsx:7-91](file://frontend/antd/input-number/input-number.tsx#L7-L91) + +### Mentions + +- **Capabilities**: `@` mention functionality; supports options list, filtering, and popup rendering. +- **Key Points**: + - `useValueChange` for controlled `value`. + - Supports `options`, `filterOption`, `validateSearch`, `getPopupContainer`. +- **Typical usage path** + - [Mentions component:11-77](file://frontend/antd/mentions/mentions.tsx#L11-L77) + +Section sources + +- [frontend/antd/mentions/mentions.tsx:11-77](file://frontend/antd/mentions/mentions.tsx#L11-L77) + +### Radio + +- **Capabilities**: Single-choice selection; supports `onValueChange`. +- **Key Points**: + - Forwards the native event in `onChange` and triggers `onValueChange(value)`. + - Injects theme tokens to adapt to style variables. +- **Typical usage path** + - [Radio component:6-29](file://frontend/antd/radio/radio.tsx#L6-L29) + +Section sources + +- [frontend/antd/radio/radio.tsx:6-29](file://frontend/antd/radio/radio.tsx#L6-L29) + +### Rate + +- **Capabilities**: Star rating; supports custom characters. +- **Key Points**: + - Supports `character` slot and functional configuration. + - `onChange` triggers `onValueChange`. +- **Typical usage path** + - [Rate component:6-42](file://frontend/antd/rate/rate.tsx#L6-L42) + +Section sources + +- [frontend/antd/rate/rate.tsx:6-42](file://frontend/antd/rate/rate.tsx#L6-L42) + +### Select + +- **Capabilities**: Single/multi-select; supports tag rendering, custom dropdown panel, filtering and sorting. +- **Key Points**: + - Supports two data sources: `options` and `children`. + - Supports `allowClear.clearIcon`, `prefix`/`removeIcon`/`suffixIcon`, `notFoundContent`, `menuItemSelectedIcon`. + - Supports `dropdownRender`/`popupRender`/`optionRender`/`tagRender`/`labelRender`. + - Supports `filterOption`/`filterSort`. +- **Typical usage path** + - [Select component:11-178](file://frontend/antd/select/select.tsx#L11-L178) + +Section sources + +- [frontend/antd/select/select.tsx:11-178](file://frontend/antd/select/select.tsx#L11-L178) + +### Slider + +- **Capabilities**: Single/double sliders; supports tick mark labels and tooltip formatting. +- **Key Points**: + - `marks` are rendered via `children`, supporting a `label` child slot. + - `tooltip` supports a `formatter` slot and function. +- **Typical usage path** + - [Slider component:37-94](file://frontend/antd/slider/slider.tsx#L37-L94) + +Section sources + +- [frontend/antd/slider/slider.tsx:37-94](file://frontend/antd/slider/slider.tsx#L37-L94) + +### Switch + +- **Capabilities**: Boolean toggle; supports custom label slots. +- **Key Points**: + - Supports `checkedChildren`/`unCheckedChildren` slots. + - `onChange` triggers `onValueChange`. +- **Typical usage path** + - [Switch component:6-39](file://frontend/antd/switch/switch.tsx#L6-L39) + +Section sources + +- [frontend/antd/switch/switch.tsx:6-39](file://frontend/antd/switch/switch.tsx#L6-L39) + +### TimePicker + +- **Capabilities**: Time selection, range selection, custom panel, disabled times. +- **Key Points**: + - Internally formats input values as `dayjs` and outputs second-level timestamps in `onChange`/`onPanelChange`/`onCalendarChange`. + - Supports slots: `cellRender`, `panelRender`, `renderExtraFooter`, etc. +- **Typical usage path** + - [TimePicker component:37-198](file://frontend/antd/time-picker/time-picker.tsx#L37-L198) + +Section sources + +- [frontend/antd/time-picker/time-picker.tsx:37-198](file://frontend/antd/time-picker/time-picker.tsx#L37-L198) + +### Transfer + +- **Capabilities**: Left-right list transfer; supports titles, select-all labels, action buttons, custom rendering and filtering. +- **Key Points**: + - `onChange` returns `targetKeys`. + - Supports `titles`/`selectAllLabels`/`actions` slots. + - Supports `render`/`footer`/`locale.notFoundContent`. +- **Typical usage path** + - [Transfer component:9-110](file://frontend/antd/transfer/transfer.tsx#L9-L110) + +Section sources + +- [frontend/antd/transfer/transfer.tsx:9-110](file://frontend/antd/transfer/transfer.tsx#L9-L110) + +### TreeSelect + +- **Capabilities**: Tree-structured selection; supports dynamic loading, filtering, tag rendering, and custom dropdown panel. +- **Key Points**: + - Supports two data sources: `treeData` and `children`. + - Supports `dropdownRender`/`popupRender`/`tagRender`/`treeTitleRender`. + - Supports `allowClear.clearIcon`, `prefix`/`suffix`, `switcherIcon`, `maxTagPlaceholder`, `notFoundContent`. + - `onLoadData` is integrated via a wrapper function. +- **Typical usage path** + - [TreeSelect component:14-161](file://frontend/antd/tree-select/tree-select.tsx#L14-L161) + +Section sources + +- [frontend/antd/tree-select/tree-select.tsx:14-161](file://frontend/antd/tree-select/tree-select.tsx#L14-L161) + +### Upload (pending) + +- The current repository does not provide a frontend wrapper implementation for Upload; API details and example paths are not available. +- It is recommended to refer to the official Ant Design Upload component and add `onValueChange` and slot support following the existing wrapper pattern. + +[No file analysis for this section; no section sources] + +## Dependency Analysis + +- **Inter-component Coupling**: Most components are decoupled via the unified `sveltify` wrapper and hooks (`useValueChange`, `useFunction`, `renderItems`, `renderParamsSlot`). +- **External Dependencies**: Ant Design React component library, `dayjs` (date/time formatting), React Slot/Svelte Preprocess (slot system). +- **Form Integration**: The Form component centrally manages form state and actions; other components collaborate with it via `onValueChange`. + +```mermaid +graph LR +A["AntD React Component Library"] --> B["sveltify wrapper"] +B --> C["Each data entry component"] +C --> D["hooks: useValueChange/useFunction"] +C --> E["renderItems/renderParamsSlot"] +F["Form Component"] --> C +``` + +Diagram sources + +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/input/input.tsx:3-42](file://frontend/antd/input/input.tsx#L3-L42) +- [frontend/antd/select/select.tsx:49-56](file://frontend/antd/select/select.tsx#L49-L56) + +Section sources + +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/input/input.tsx:3-42](file://frontend/antd/input/input.tsx#L3-L42) +- [frontend/antd/select/select.tsx:49-56](file://frontend/antd/select/select.tsx#L49-L56) + +## Performance Considerations + +- **Controlled vs. Uncontrolled**: Prefer controlled components (`value` + `onValueChange`) to avoid redundant rendering and state drift. +- **Slots and Functions**: Externalize complex slot logic as functions where possible to reduce unnecessary re-renders. +- **Option Rendering**: For Select/Cascader/TreeSelect/Mentions etc., it is recommended to pass static `options` to avoid generating new arrays on every render. +- **Date/Time**: DatePicker/TimePicker internally format `dayjs`; avoid redundant conversions in the parent component. +- **Slider and Rate**: Custom characters/labels in Rate/Slider should be kept lightweight to avoid heavy DOM structures. + +[This section provides general guidance; no specific file analysis] + +## Troubleshooting Guide + +- **Form Action Not Working** + - Confirm that Form's `formAction` is set to `reset`/`submit`/`validate` and reset the value after the action completes. + - Reference path: [Form action handling:32-45](file://frontend/antd/form/form.tsx#L32-L45) +- **Value Not Updating** + - Ensure `onValueChange` has been correctly set and triggered. + - Reference path: [Input value change:49-54](file://frontend/antd/input/input.tsx#L49-L54) +- **Date/Time Format Abnormality** + - DatePicker/TimePicker output second-level timestamps; ensure the backend converts them as needed. + - Reference path: [Date formatting:26-38](file://frontend/antd/date-picker/date-picker.tsx#L26-L38) +- **Options Not Displaying or Filter Not Working** + - Check that `options` have been passed or that `children` are rendering correctly. + - Reference path: [Select option rendering:64-77](file://frontend/antd/select/select.tsx#L64-L77) +- **Inconsistent Color Format** + - ColorPicker supports rgb/hex/hsb output; confirm the `value_format` configuration. + - Reference path: [Color formatting:71-95](file://frontend/antd/color-picker/color-picker.tsx#L71-L95) + +Section sources + +- [frontend/antd/form/form.tsx:32-45](file://frontend/antd/form/form.tsx#L32-L45) +- [frontend/antd/input/input.tsx:49-54](file://frontend/antd/input/input.tsx#L49-L54) +- [frontend/antd/date-picker/date-picker.tsx:26-38](file://frontend/antd/date-picker/date-picker.tsx#L26-L38) +- [frontend/antd/select/select.tsx:64-77](file://frontend/antd/select/select.tsx#L64-L77) +- [frontend/antd/color-picker/color-picker.tsx:71-95](file://frontend/antd/color-picker/color-picker.tsx#L71-L95) + +## Conclusion + +ModelScope Studio's data entry components achieve seamless integration with Ant Design through a unified wrapper pattern, providing rich slots and functional props to meet diverse business requirements. In practice, it is recommended to follow the controlled component principle, make good use of slots and functions, pay attention to date/time and color format conversion, and use the Form component to complete the full form interaction loop. + +[This section provides summary content; no specific file analysis] + +## Appendix + +### Component API Overview (by theme) + +- **Text Input** + - **Input**: Supports `value`, `onValueChange`, `addonBefore`/`addonAfter`, `prefix`/`suffix`, `allowClear.clearIcon`, `showCount.formatter` + - Reference path: [Input component:10-116](file://frontend/antd/input/input.tsx#L10-L116) + - **InputNumber**: Supports `value`, `onValueChange`, `formatter`, `parser`, `controls.upIcon`/`downIcon`, `addonBefore`/`addonAfter`, `prefix`/`suffix` + - Reference path: [InputNumber component:7-91](file://frontend/antd/input-number/input-number.tsx#L7-L91) + - **AutoComplete**: Supports `value`, `onValueChange`, `options`, `filterOption`, `dropdownRender`, `popupRender`, `allowClear.clearIcon`, `notFoundContent` + - Reference path: [AutoComplete component:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) + - **Mentions**: Supports `value`, `onValueChange`, `options`, `filterOption`, `validateSearch`, `getPopupContainer`, `notFoundContent` + - Reference path: [Mentions component:11-77](file://frontend/antd/mentions/mentions.tsx#L11-L77) + +- **Selectors** + - **Select**: Supports `value`, `onValueChange`, `options`, `filterOption`, `filterSort`, `allowClear.clearIcon`, `prefix`/`removeIcon`/`suffixIcon`, `notFoundContent`, `menuItemSelectedIcon`, `dropdownRender`/`popupRender`/`optionRender`/`tagRender`/`labelRender` + - Reference path: [Select component:11-178](file://frontend/antd/select/select.tsx#L11-L178) + - **Cascader**: Supports `value`, `onValueChange`, `options`, `showSearch`, `loadData`, `displayRender`/`tagRender`/`optionRender`, `dropdownRender`/`popupRender`, `allowClear.clearIcon`, `prefix`/`suffixIcon`, `expandIcon`, `removeIcon`, `notFoundContent`, `maxTagPlaceholder` + - Reference path: [Cascader component:19-204](file://frontend/antd/cascader/cascader.tsx#L19-L204) + - **TreeSelect**: Supports `value`, `onValueChange`, `treeData`, `filterTreeNode`, `loadData`, `dropdownRender`/`popupRender`/`tagRender`/`treeTitleRender`, `allowClear.clearIcon`, `prefix`/`suffix`, `switcherIcon`, `notFoundContent`, `maxTagPlaceholder` + - Reference path: [TreeSelect component:14-161](file://frontend/antd/tree-select/tree-select.tsx#L14-L161) + +- **Date and Time** + - **DatePicker**: Supports `value`, `onChange`/`onPanelChange`, `pickerValue`/`defaultPickerValue`, `showTime`, `disabledDate`/`disabledTime`, `cellRender`/`panelRender`, `presets`, `renderExtraFooter`, `prevIcon`/`nextIcon`/`suffixIcon`/`superNextIcon`/`superPrevIcon`, `allowClear.clearIcon` + - Reference path: [DatePicker component:40-231](file://frontend/antd/date-picker/date-picker.tsx#L40-L231) + - **TimePicker**: Supports `value`, `onChange`/`onPanelChange`/`onCalendarChange`, `pickerValue`/`defaultPickerValue`, `disabledDate`/`disabledTime`, `cellRender`/`panelRender`, `renderExtraFooter`, `prevIcon`/`nextIcon`/`suffixIcon`/`superNextIcon`/`superPrevIcon`, `allowClear.clearIcon` + - Reference path: [TimePicker component:37-198](file://frontend/antd/time-picker/time-picker.tsx#L37-L198) + +- **Interaction and Rating** + - **Checkbox**: Supports `value`, `onValueChange`, `onChange` + - Reference path: [Checkbox component:4-19](file://frontend/antd/checkbox/checkbox.tsx#L4-L19) + - **Radio**: Supports `value`, `onValueChange`, `onChange`, theme token injection + - Reference path: [Radio component:6-29](file://frontend/antd/radio/radio.tsx#L6-L29) + - **Rate**: Supports `value`, `onValueChange`, `onChange`, `character` slot/function + - Reference path: [Rate component:6-42](file://frontend/antd/rate/rate.tsx#L6-L42) + - **Switch**: Supports `value`, `onChange`, `checkedChildren`/`unCheckedChildren` slots + - Reference path: [Switch component:6-39](file://frontend/antd/switch/switch.tsx#L6-L39) + - **Slider**: Supports `value`, `onChange`, `marks` (children rendering), `tooltip.formatter` slot + - Reference path: [Slider component:37-94](file://frontend/antd/slider/slider.tsx#L37-L94) + +- **Color and Form** + - **ColorPicker**: Supports `value`, `onValueChange`, `onChange`, `value_format` (rgb/hex/hsb), `presets`, `panelRender`, `showText` + - Reference path: [ColorPicker component:11-103](file://frontend/antd/color-picker/color-picker.tsx#L11-L103) + - **Form**: Supports `value`, `onValueChange`, `formAction` (reset/submit/validate), `requiredMark`, `feedbackIcons` + - Reference path: [Form component:8-76](file://frontend/antd/form/form.tsx#L8-L76) + +- **Transfer** + - **Transfer**: Supports `value` (targetKeys), `onChange`, `titles`/`selectAllLabels`/`actions` slots, `render`/`footer`/`locale.notFoundContent`, `selectionsIcon` + - Reference path: [Transfer component:9-110](file://frontend/antd/transfer/transfer.tsx#L9-L110) + +[This section provides a summary overview; no specific file analysis] diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Feedback Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Feedback Components API.md new file mode 100644 index 00000000..58608580 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Feedback Components API.md @@ -0,0 +1,383 @@ +# Feedback Components API + + +**Files referenced in this document** +- [frontend/antd/alert/alert.tsx](file://frontend/antd/alert/alert.tsx) +- [frontend/antd/drawer/drawer.tsx](file://frontend/antd/drawer/drawer.tsx) +- [frontend/antd/message/message.tsx](file://frontend/antd/message/message.tsx) +- [frontend/antd/modal/modal.tsx](file://frontend/antd/modal/modal.tsx) +- [frontend/antd/notification/notification.tsx](file://frontend/antd/notification/notification.tsx) +- [frontend/antd/popconfirm/popconfirm.tsx](file://frontend/antd/popconfirm/popconfirm.tsx) +- [frontend/antd/progress/progress.tsx](file://frontend/antd/progress/progress.tsx) +- [frontend/antd/result/result.tsx](file://frontend/antd/result/result.tsx) +- [frontend/antd/skeleton/skeleton.tsx](file://frontend/antd/skeleton/skeleton.tsx) +- [frontend/antd/spin/spin.tsx](file://frontend/antd/spin/spin.tsx) +- [frontend/antd/watermark/watermark.tsx](file://frontend/antd/watermark/watermark.tsx) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [docs/components/antd/alert/README.md](file://docs/components/antd/alert/README.md) +- [docs/components/antd/drawer/README.md](file://docs/components/antd/drawer/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design-based feedback components in ModelScope Studio, covering: Alert, Drawer, Message, Modal, Notification, Popconfirm, Progress, Result, Skeleton, Spin, and Watermark. It includes: + +- Property definitions and type constraints +- State management and lifecycle +- Animation and interaction logic +- Standard instantiation and configuration example paths +- Event callbacks and asynchronous handling +- Accessibility and user experience design principles + +## Project Structure + +Feedback components are implemented on the frontend as Svelte wrappers that bridge Ant Design React components, and are uniformly exported via backend Python modules for on-demand use in applications. + +```mermaid +graph TB +subgraph "Frontend" +A1["alert.tsx"] +A2["drawer.tsx"] +A3["message.tsx"] +A4["modal.tsx"] +A5["notification.tsx"] +A6["popconfirm.tsx"] +A7["progress.tsx"] +A8["result.tsx"] +A9["skeleton.tsx"] +A10["spin.tsx"] +A11["watermark.tsx"] +end +subgraph "Backend" +B1["__init__.py"] +B2["components.py"] +end +A1 --> B1 +A2 --> B1 +A3 --> B1 +A4 --> B1 +A5 --> B1 +A6 --> B1 +A7 --> B1 +A8 --> B1 +A9 --> B1 +A10 --> B1 +A11 --> B1 +B1 --> B2 +``` + +Diagram sources + +- [frontend/antd/alert/alert.tsx:1-46](file://frontend/antd/alert/alert.tsx#L1-L46) +- [frontend/antd/drawer/drawer.tsx:1-60](file://frontend/antd/drawer/drawer.tsx#L1-L60) +- [frontend/antd/message/message.tsx:1-79](file://frontend/antd/message/message.tsx#L1-L79) +- [frontend/antd/modal/modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) +- [frontend/antd/notification/notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [frontend/antd/popconfirm/popconfirm.tsx:1-65](file://frontend/antd/popconfirm/popconfirm.tsx#L1-L65) +- [frontend/antd/progress/progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [frontend/antd/result/result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- [frontend/antd/watermark/watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +Section sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +## Core Components + +- **Alert**: Displays warning information requiring user attention; supports slots for `description`, `icon`, `action`, `closable.closeIcon`, etc. +- **Drawer**: A drawer panel that slides in from the screen edge; supports `title`, `footer`, `extra`, `closeIcon`, and render hooks. +- **Message**: Global hint message; supports visibility control, custom content and icons, and destroy/open operations. +- **Modal**: Modal dialog; supports `title`, `footer`, button icons, render hooks, and container mounting. +- **Notification**: Global notification alert; supports position, actions, close icon, description, and message. +- **Popconfirm**: Bubble confirmation; supports confirm/cancel text and icons, and popup container. +- **Progress**: Progress bar; supports `format` and `rounding` function handling. +- **Result**: Result page; supports `title`, `subTitle`, `icon`, and `extra` slots. +- **Skeleton**: Skeleton screen placeholder. +- **Spin**: Loading indicator; supports `tip` text and `indicator` slots. +- **Watermark**: Watermark overlay. + +Section sources + +- [frontend/antd/alert/alert.tsx:1-46](file://frontend/antd/alert/alert.tsx#L1-L46) +- [frontend/antd/drawer/drawer.tsx:1-60](file://frontend/antd/drawer/drawer.tsx#L1-L60) +- [frontend/antd/message/message.tsx:1-79](file://frontend/antd/message/message.tsx#L1-L79) +- [frontend/antd/modal/modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) +- [frontend/antd/notification/notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [frontend/antd/popconfirm/popconfirm.tsx:1-65](file://frontend/antd/popconfirm/popconfirm.tsx#L1-L65) +- [frontend/antd/progress/progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [frontend/antd/result/result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- [frontend/antd/watermark/watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) + +## Architecture Overview + +Feedback components follow a layered architecture of "Svelte wrapper + Ant Design React component + unified backend export": + +- **Frontend layer**: Each component wraps an Ant Design component with `sveltify`, supporting `slots` and function callback conversion. +- **Interaction layer**: Bridges callbacks and child nodes via utilities like `useFunction`/`useTargets`. +- **Export layer**: Python modules centrally export each component for unified import and aliasing in applications. + +```mermaid +sequenceDiagram +participant App as "Application" +participant Wrapper as "Svelte Wrapper" +participant AD as "Ant Design Component" +participant Util as "Utility Hooks" +App->>Wrapper : Passes props and slots +Wrapper->>Util : useFunction()/useTargets() +Util-->>Wrapper : Converted callbacks/target nodes +Wrapper->>AD : Renders and passes props/slots +AD-->>App : Fires event callbacks/state changes +``` + +Diagram sources + +- [frontend/antd/alert/alert.tsx:12-43](file://frontend/antd/alert/alert.tsx#L12-L43) +- [frontend/antd/drawer/drawer.tsx:24-57](file://frontend/antd/drawer/drawer.tsx#L24-L57) +- [frontend/antd/message/message.tsx:18-76](file://frontend/antd/message/message.tsx#L18-L76) +- [frontend/antd/modal/modal.tsx:22-104](file://frontend/antd/modal/modal.tsx#L22-L104) +- [frontend/antd/notification/notification.tsx:17-103](file://frontend/antd/notification/notification.tsx#L17-L103) + +## Component Details + +### Alert + +- **Key Capabilities** + - Supports slots: `message`, `description`, `icon`, `action`, `closable.closeIcon` + - The `afterClose` callback is converted via `useFunction` +- **Lifecycle** + - Renders based on props after mounting; fires `afterClose` upon dismissal +- **Interaction and Animation** + - Controlled by Ant Design's built-in animation and transitions +- **Example path** + - [docs/components/antd/alert/README.md:1-8](file://docs/components/antd/alert/README.md#L1-L8) + +Section sources + +- [frontend/antd/alert/alert.tsx:7-43](file://frontend/antd/alert/alert.tsx#L7-L43) + +### Drawer + +- **Key Capabilities** + - Supports slots: `title`, `footer`, `extra`, `closeIcon`, `closable.closeIcon`, `drawerRender` + - `afterOpenChange`, `getContainer`, `drawerRender` are handled via `useFunction`/`renderParamsSlot` +- **Lifecycle** + - Fires `afterOpenChange` when open/close state changes +- **Interaction and Animation** + - Ant Design drawer slide-in/slide-out animation +- **Example path** + - [docs/components/antd/drawer/README.md:1-9](file://docs/components/antd/drawer/README.md#L1-L9) + +Section sources + +- [frontend/antd/drawer/drawer.tsx:8-57](file://frontend/antd/drawer/drawer.tsx#L8-L57) + +### Message + +- **Key Capabilities** + - Obtains the API via `message.useMessage` + - Supports `visible` to control show/hide, with `onVisible` callback + - `content` and `icon` slots support customization + - `getContainer` is handled functionally +- **Lifecycle** + - Opens when `visible=true`; destroys when `visible=false` or on unmount +- **Async and Events** + - `onClose` simultaneously triggers `onVisible(false)` and the original `onClose` +- **Example path** + - Refer to demo examples in each component's README + +Section sources + +- [frontend/antd/message/message.tsx:9-76](file://frontend/antd/message/message.tsx#L9-L76) + +### Modal + +- **Key Capabilities** + - Supports `okText`, `okButtonProps.icon`, `cancelText`, `cancelButtonProps.icon`, `footer`, `title`, `modalRender`, `closable.closeIcon`, `closeIcon`, etc. + - `afterOpenChange`, `afterClose`, `getContainer`, `footer`, `modalRender` are handled via `useFunction`/`renderParamsSlot` +- **Lifecycle** + - Fires `afterOpenChange`/`afterClose` when open/close state changes +- **Interaction and Animation** + - Ant Design dialog open/close animation and overlay behavior + +Section sources + +- [frontend/antd/modal/modal.tsx:8-104](file://frontend/antd/modal/modal.tsx#L8-L104) + +### Notification + +- **Key Capabilities** + - Obtains the API via `notification.useNotification` + - Supports `visible` to control show/hide, with `onVisible` callback + - Supports slots: `btn`, `actions`, `closeIcon`, `description`, `icon`, `message` + - Position parameters: `top`, `bottom`, `rtl`, `stack` +- **Lifecycle** + - Opens when `visible=true`; destroys when `visible=false` or on unmount +- **Async and Events** + - `onClose` simultaneously triggers `onVisible(false)` and the original `onClose` + +Section sources + +- [frontend/antd/notification/notification.tsx:8-103](file://frontend/antd/notification/notification.tsx#L8-L103) + +### Popconfirm + +- **Key Capabilities** + - Supports `okText`, `okButtonProps.icon`, `cancelText`, `cancelButtonProps.icon`, `title`, `description` + - `afterOpenChange`, `getPopupContainer` are handled via `useFunction` +- **Lifecycle** + - Fires `afterOpenChange` when the popup opens/closes +- **Interaction and Animation** + - Ant Design bubble confirmation popup behavior + +Section sources + +- [frontend/antd/popconfirm/popconfirm.tsx:7-62](file://frontend/antd/popconfirm/popconfirm.tsx#L7-L62) + +### Progress + +- **Key Capabilities** + - Supports `format` and `rounding` function handling +- **Performance and Complexity** + - Pure display component with no complex computation + +Section sources + +- [frontend/antd/progress/progress.tsx:5-21](file://frontend/antd/progress/progress.tsx#L5-L21) + +### Result + +- **Key Capabilities** + - Supports slots: `title`, `subTitle`, `icon`, `extra` + - Uses `useTargets` to manage child node rendering strategy +- **Lifecycle** + - Renders child nodes when slots are present; hides default children otherwise + +Section sources + +- [frontend/antd/result/result.tsx:7-30](file://frontend/antd/result/result.tsx#L7-L30) + +### Skeleton + +- **Key Capabilities** + - Directly wraps Ant Design Skeleton +- **Usage Recommendations** + - Use as a placeholder display before data loads + +Section sources + +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) + +### Spin + +- **Key Capabilities** + - Supports `tip` and `indicator` slots + - Uses `useTargets` to control child node visibility +- **Lifecycle** + - Shows children when no slots are present; hides children and delegates rendering to Spin when slots exist + +Section sources + +- [frontend/antd/spin/spin.tsx:7-35](file://frontend/antd/spin/spin.tsx#L7-L35) + +### Watermark + +- **Key Capabilities** + - Directly wraps Ant Design Watermark +- **Usage Recommendations** + - Use for content protection and copyright marking + +Section sources + +- [frontend/antd/watermark/watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) + +## Dependency Analysis + +- **Unified Export** + - Backend modules centrally export each component for unified import and alias management on the application side +- **Inter-component Coupling** + - Components are relatively independent; collaboration primarily occurs through the Ant Design ecosystem and common utility hooks + +```mermaid +graph LR +Init["__init__.py"] --> Comp["components.py"] +Init --> |exports| C1["Alert"] +Init --> |exports| C2["Drawer"] +Init --> |exports| C3["Message"] +Init --> |exports| C4["Modal"] +Init --> |exports| C5["Notification"] +Init --> |exports| C6["Popconfirm"] +Init --> |exports| C7["Progress"] +Init --> |exports| C8["Result"] +Init --> |exports| C9["Skeleton"] +Init --> |exports| C10["Spin"] +Init --> |exports| C11["Watermark"] +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +Section sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +## Performance Considerations + +- **Slot and Function Conversion** + - Use `useFunction` to bridge callback functions to the React environment, avoiding re-renders caused by redundant function creation +- **Conditional Rendering** + - Result/Spin precisely control child node rendering via `useTargets`, reducing unnecessary DOM structures +- **Destroy and Cleanup** + - Message/Notification actively `destroy` on unmount or when `visible=false`, preventing memory leaks and duplicate notifications + +## Troubleshooting Guide + +- **Slot Not Working** + - Confirm that the slot name matches the component definition (e.g., `closable.closeIcon`, `okButtonProps.icon`, etc.) +- **Callback Not Firing** + - Check that callbacks are wrapped via `useFunction`; ensure the function signature matches what Ant Design expects +- **Container Mounting Issues** + - `getContainer` supports string selectors or functions; if a string is passed, it is internally converted to a function +- **Notification/Message Not Dismissing** + - Ensure `destroy` is triggered when `visible=false` or the component unmounts; inspect the `onClose` callback chain + +Section sources + +- [frontend/antd/alert/alert.tsx:12-43](file://frontend/antd/alert/alert.tsx#L12-L43) +- [frontend/antd/drawer/drawer.tsx:24-57](file://frontend/antd/drawer/drawer.tsx#L24-L57) +- [frontend/antd/message/message.tsx:35-68](file://frontend/antd/message/message.tsx#L35-L68) +- [frontend/antd/notification/notification.tsx:38-95](file://frontend/antd/notification/notification.tsx#L38-L95) + +## Conclusion + +ModelScope Studio's feedback components achieve flexible extension of Ant Design components and a consistent usage experience through unified Svelte wrappers and utility hooks. Developers can quickly customize interaction and visual presentation via slots and functional callbacks, while simplified module management is enabled by unified backend exports. It is recommended to make appropriate use of each feedback component in real-world scenarios, combining loading strategies, visibility control, and accessibility requirements to enhance the user experience. + +## Appendix + +- **Examples and Demos** + - Refer to the demo examples in each component's README for a quick start: + - [docs/components/antd/alert/README.md:1-8](file://docs/components/antd/alert/README.md#L1-L8) + - [docs/components/antd/drawer/README.md:1-9](file://docs/components/antd/drawer/README.md#L1-L9) diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/General Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/General Components API.md new file mode 100644 index 00000000..4a649ac1 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/General Components API.md @@ -0,0 +1,442 @@ +# General Components API + + +**Files referenced in this document** +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/float-button/float-button.tsx](file://frontend/antd/float-button/float-button.tsx) +- [frontend/antd/float-button/Index.svelte](file://frontend/antd/float-button/Index.svelte) +- [frontend/antd/icon/icon.tsx](file://frontend/antd/icon/icon.tsx) +- [frontend/antd/icon/Index.svelte](file://frontend/antd/icon/Index.svelte) +- [frontend/antd/typography/typography.base.tsx](file://frontend/antd/typography/typography.base.tsx) +- [frontend/antd/typography/Base.svelte](file://frontend/antd/typography/Base.svelte) +- [frontend/antd/typography/title/Index.svelte](file://frontend/antd/typography/title/Index.svelte) +- [frontend/antd/typography/paragraph/Index.svelte](file://frontend/antd/typography/paragraph/Index.svelte) +- [frontend/antd/typography/text/Index.svelte](file://frontend/antd/typography/text/Index.svelte) +- [frontend/antd/typography/link/Index.svelte](file://frontend/antd/typography/link/Index.svelte) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for general Ant Design-based components in ModelScope Studio, covering Button, FloatButton, Icon, and Typography. It includes: + +- Property definitions and event handling +- Slots and style customization +- Use cases and best practices +- TypeScript types and their correspondence to native Ant Design +- Responsive design, accessibility, and performance optimization recommendations + +## Project Structure + +These components follow a unified "Svelte entry + React wrapper" pattern: the Svelte entry handles prop forwarding, class name composition, and visibility control; the React wrapper interfaces with Ant Design components to implement slot rendering and complex interactions. + +```mermaid +graph TB +subgraph "Button" +B_Index["button/Index.svelte"] +B_Impl["button/button.tsx"] +end +subgraph "FloatButton" +F_Index["float-button/Index.svelte"] +F_Impl["float-button/float-button.tsx"] +end +subgraph "Icon" +I_Index["icon/Index.svelte"] +I_Impl["icon/icon.tsx"] +end +subgraph "Typography" +T_Base["typography/Base.svelte"] +T_Impl["typography/typography.base.tsx"] +T_Title["typography/title/Index.svelte"] +T_Para["typography/paragraph/Index.svelte"] +T_Text["typography/text/Index.svelte"] +T_Link["typography/link/Index.svelte"] +end +B_Index --> B_Impl +F_Index --> F_Impl +I_Index --> I_Impl +T_Title --> T_Base --> T_Impl +T_Para --> T_Base +T_Text --> T_Base +T_Link --> T_Base +``` + +Diagram sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/float-button/Index.svelte:1-70](file://frontend/antd/float-button/Index.svelte#L1-L70) +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) +- [frontend/antd/icon/icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [frontend/antd/typography/Base.svelte:1-85](file://frontend/antd/typography/Base.svelte#L1-L85) +- [frontend/antd/typography/typography.base.tsx:1-170](file://frontend/antd/typography/typography.base.tsx#L1-L170) +- [frontend/antd/typography/title/Index.svelte:1-12](file://frontend/antd/typography/title/Index.svelte#L1-L12) +- [frontend/antd/typography/paragraph/Index.svelte:1-12](file://frontend/antd/typography/paragraph/Index.svelte#L1-L12) +- [frontend/antd/typography/text/Index.svelte:1-12](file://frontend/antd/typography/text/Index.svelte#L1-L12) +- [frontend/antd/typography/link/Index.svelte:1-12](file://frontend/antd/typography/link/Index.svelte#L1-L12) + +Section sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/float-button/Index.svelte:1-70](file://frontend/antd/float-button/Index.svelte#L1-L70) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) +- [frontend/antd/typography/Base.svelte:1-85](file://frontend/antd/typography/Base.svelte#L1-L85) + +## Core Components + +- **Button**: Aligned with Ant Design Button; supports `icon` and `loading.icon` slots, with priority logic between `value` and child nodes. +- **FloatButton**: Aligned with Ant Design FloatButton; supports `icon`, `description`, `tooltip`, `tooltip.title`, and `badge.count` slots, with function bridging for tooltip configuration. +- **Icon**: Supports built-in Ant Design icon name mapping and IconFont; supports a custom `component` slot. +- **Typography**: A unified typography base supporting `title`, `paragraph`, `text`, and `link` variants, with slot-based configuration for `copyable`, `editable`, and `ellipsis`. + +Section sources + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/icon/icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [frontend/antd/typography/typography.base.tsx:1-170](file://frontend/antd/typography/typography.base.tsx#L1-L170) + +## Architecture Overview + +All components are unified through the Svelte entry, which handles: + +- Prop forwarding and extra prop merging +- Visibility control and class name composition +- Slot context injection +- Lazy loading and async component rendering + +The React wrapper layer handles: + +- Interfacing with Ant Design components +- Mapping slots to ReactSlot +- Conditional rendering and function bridging for complex configuration objects (e.g., `tooltip`, `ellipsis`) + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Entry (Index.svelte)" +participant Loader as "importComponent" +participant ReactImpl as "React Wrapper (button.tsx/float-button.tsx/icon.tsx/typography.base.tsx)" +participant AntD as "Ant Design Component" +Svelte->>Loader : Dynamically imports component module +Loader-->>Svelte : Returns renderable component +Svelte->>ReactImpl : Passes props + slots + value +ReactImpl->>AntD : Renders and injects slots/config +AntD-->>ReactImpl : Render result +ReactImpl-->>Svelte : Render result +``` + +Diagram sources + +- [frontend/antd/button/Index.svelte:10-73](file://frontend/antd/button/Index.svelte#L10-L73) +- [frontend/antd/button/button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) +- [frontend/antd/float-button/Index.svelte:10-69](file://frontend/antd/float-button/Index.svelte#L10-L69) +- [frontend/antd/float-button/float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) +- [frontend/antd/icon/Index.svelte:10-66](file://frontend/antd/icon/Index.svelte#L10-L66) +- [frontend/antd/icon/icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- [frontend/antd/typography/Base.svelte:11-83](file://frontend/antd/typography/Base.svelte#L11-L83) +- [frontend/antd/typography/typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) + +## Component Details + +### Button + +- **Capability Overview** + - Supports all Ant Design Button props and events + - Slots: `icon`, `loading.icon` + - Content priority: renders child nodes when present, otherwise falls back to `value` +- **Key Behaviors** + - Injects `slots.icon` into Ant Design Button's `icon` + - Injects `slots.loading.icon` into `loading.icon`, preserving `loading.delay` if `loading` is an object +- **Use Cases** + - Basic buttons, buttons with icons, loading buttons +- **Examples (paths)** + - Basic usage: [frontend/antd/button/Index.svelte:59-73](file://frontend/antd/button/Index.svelte#L59-L73) + - Slot icons: [frontend/antd/button/button.tsx:18-30](file://frontend/antd/button/button.tsx#L18-L30) +- **Types and Native Correspondence** + - Wraps Ant Design Button's `GetProps` type via `sveltify`, maintaining a consistent prop signature +- **Styles and Accessibility** + - Controlled via `elem_classes`/`elem_id`/`elem_style`; accessibility provided by Ant Design +- **Performance** + - Child node detection with conditional rendering avoids unnecessary DOM updates + +```mermaid +flowchart TD +Start(["Enter Button Render"]) --> HasChildren{"Does child node exist?"} +HasChildren --> |Yes| RenderChild["Render child node"] +HasChildren --> |No| RenderValue["Render value"] +RenderChild --> InjectIcon["Inject slots.icon into AntD Button"] +RenderValue --> InjectIcon +InjectIcon --> LoadingCfg{"Is loading.icon configured?"} +LoadingCfg --> |Yes| MergeLoading["Merge loading with loading.icon.delay"] +LoadingCfg --> |No| PassThrough["Pass through loading directly"] +MergeLoading --> End(["Done"]) +PassThrough --> End +``` + +Diagram sources + +- [frontend/antd/button/button.tsx:11-36](file://frontend/antd/button/button.tsx#L11-L36) + +Section sources + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + +### FloatButton + +- **Capability Overview** + - Supports all Ant Design FloatButton props and events + - Slots: `icon`, `description`, `tooltip`, `tooltip.title`, `badge.count` + - `tooltip` supports object configuration; internally bridges `afterOpenChange`, `getPopupContainer`, and other functions via `useFunction` +- **Key Behaviors** + - Enables tooltip configuration when `slots.tooltip` exists or `tooltip` is an object + - Maps `slots.icon`/`description`/`badge.count` to their corresponding props +- **Use Cases** + - Back-to-top, floating action panels, floating entry points with description and badge +- **Examples (paths)** + - Basic usage: [frontend/antd/float-button/Index.svelte:56-69](file://frontend/antd/float-button/Index.svelte#L56-L69) + - Slots and tooltip configuration: [frontend/antd/float-button/float-button.tsx:19-72](file://frontend/antd/float-button/float-button.tsx#L19-L72) +- **Types and Native Correspondence** + - Wraps Ant Design FloatButton's `GetProps` type via `sveltify`, with an additional `id` field +- **Styles and Accessibility** + - Controlled via `elem_classes`/`elem_id`/`elem_style`; accessibility provided by Ant Design +- **Performance** + - Conditional rendering of tooltip and slots reduces unnecessary overhead + +```mermaid +sequenceDiagram +participant S as "Svelte Entry" +participant R as "React Wrapper" +participant T as "tooltip config" +participant A as "AntD FloatButton" +S->>R : Passes props + slots +R->>T : Checks if tooltip is an object or slots.tooltip.title exists +alt Tooltip enabled +T-->>R : Merges config and bridges functions +else Not enabled +T-->>R : Passes through tooltip directly +end +R->>A : Renders and injects icon/description/badge/count +A-->>R : Render result +``` + +Diagram sources + +- [frontend/antd/float-button/float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) +- [frontend/antd/float-button/Index.svelte:1-70](file://frontend/antd/float-button/Index.svelte#L1-L70) + +Section sources + +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/float-button/Index.svelte:1-70](file://frontend/antd/float-button/Index.svelte#L1-L70) + +### Icon + +- **Capability Overview** + - Supports Ant Design built-in icon name mapping + - Supports font icons provided by `IconFontProvider` + - Slot: `component` (for custom SVG components) +- **Key Behaviors** + - If `slots.component` is provided, renders the custom component with Ant Design `IconWrapper` + - Otherwise, looks up the built-in icon by `value` or uses `IconFont.type` +- **Use Cases** + - Inline text icons, button icons, custom vector icons +- **Examples (paths)** + - Basic usage: [frontend/antd/icon/Index.svelte:52-66](file://frontend/antd/icon/Index.svelte#L52-L66) + - Custom component and IconFont: [frontend/antd/icon/icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- **Types and Native Correspondence** + - Wraps Ant Design Icons' `GetProps` type via `sveltify`, with an additional `value` field +- **Styles and Accessibility** + - Controlled via `elem_classes`/`elem_id`/`elem_style`; accessibility provided by Ant Design +- **Performance** + - `useMemo` caches custom components to avoid redundant creation + +```mermaid +flowchart TD +Start(["Enter Icon Render"]) --> HasCustom{"Does slots.component exist?"} +HasCustom --> |Yes| WrapCustom["Wrap custom component with Ant Design IconWrapper"] +HasCustom --> |No| LookupIcon{"Is value a built-in icon name?"} +LookupIcon --> |Yes| RenderBuiltin["Render built-in icon"] +LookupIcon --> |No| UseIconFont{"Does IconFont context exist?"} +UseIconFont --> |Yes| RenderIconFont["Use IconFont(type=value)"] +UseIconFont --> |No| Noop["Not rendered"] +WrapCustom --> End(["Done"]) +RenderBuiltin --> End +RenderIconFont --> End +Noop --> End +``` + +Diagram sources + +- [frontend/antd/icon/icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) + +Section sources + +- [frontend/antd/icon/icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) + +### Typography + +- **Capability Overview** + - Unified base: four variants — `title`, `paragraph`, `text`, `link` + - Supports slot-based configuration for `copyable`, `editable`, and `ellipsis` + - Slots: `copyable.icon`, `copyable.tooltips`, `editable.icon`, `editable.tooltip`, `editable.enterIcon`, `ellipsis.symbol`, `ellipsis.tooltip`, `ellipsis.tooltip.title` +- **Key Behaviors** + - Selects the corresponding Ant Design Typography component based on `component` + - Conditionally injects `copyable`, `editable`, and `ellipsis` configuration + - `ellipsis` enablement conditions differ for the `link` component +- **Use Cases** + - Unified typography and interaction for headings, paragraphs, text, and links +- **Examples (paths)** + - Basic usage: [frontend/antd/typography/Base.svelte:65-84](file://frontend/antd/typography/Base.svelte#L65-L84) + - Sub-component aliases: [frontend/antd/typography/title/Index.svelte:9-11](file://frontend/antd/typography/title/Index.svelte#L9-L11) + - Slot and config merging: [frontend/antd/typography/typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) +- **Types and Native Correspondence** + - Wraps multiple Ant Design Typography types via `sveltify`, with additional `component` and `value` fields +- **Styles and Accessibility** + - Controlled via `elem_classes`/`elem_id`/`elem_style`; accessibility provided by Ant Design +- **Performance** + - Conditional rendering with slot target collection reduces unnecessary overhead + +```mermaid +sequenceDiagram +participant S as "Base.svelte" +participant R as "typography.base.tsx" +participant T as "Typography Component" +participant C as "copyable/editable/ellipsis" +S->>R : Passes component/value + slots +R->>R : Parses copyable/editable/ellipsis config +alt Capability supported +R->>C : Injects slots.icon/tooltip/symbol/... and merges config +else Not supported +R->>C : No injection, keeps undefined +end +R->>T : Renders corresponding Typography component +T-->>R : Render result +``` + +Diagram sources + +- [frontend/antd/typography/Base.svelte:11-83](file://frontend/antd/typography/Base.svelte#L11-L83) +- [frontend/antd/typography/typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) + +Section sources + +- [frontend/antd/typography/typography.base.tsx:1-170](file://frontend/antd/typography/typography.base.tsx#L1-L170) +- [frontend/antd/typography/Base.svelte:1-85](file://frontend/antd/typography/Base.svelte#L1-L85) +- [frontend/antd/typography/title/Index.svelte:1-12](file://frontend/antd/typography/title/Index.svelte#L1-L12) +- [frontend/antd/typography/paragraph/Index.svelte:1-12](file://frontend/antd/typography/paragraph/Index.svelte#L1-L12) +- [frontend/antd/typography/text/Index.svelte:1-12](file://frontend/antd/typography/text/Index.svelte#L1-L12) +- [frontend/antd/typography/link/Index.svelte:1-12](file://frontend/antd/typography/link/Index.svelte#L1-L12) + +## Dependency Analysis + +- **Inter-component Coupling** + - The four Typography sub-components are merely aliases for Base, reducing duplication and coupling + - Button/FloatButton/Icon separate entry from implementation for ease of maintenance and extension +- **External Dependencies** + - Ant Design component library (Button, FloatButton, Typography, Icon, etc.) + - `@svelte-preprocess-react` (sveltify, ReactSlot, useFunction, etc.) + - Utility functions: `useTargets`, `useSlotsChildren`, `omitUndefinedProps`, `renderParamsSlot`, etc. +- **Potential Circular Dependencies** + - No direct circular dependencies found; all components follow a unidirectional dependency: entry → implementation → Ant Design + +```mermaid +graph LR +S_Button["button/Index.svelte"] --> R_Button["button/button.tsx"] +S_Float["float-button/Index.svelte"] --> R_Float["float-button/float-button.tsx"] +S_Icon["icon/Index.svelte"] --> R_Icon["icon/icon.tsx"] +S_TBase["typography/Base.svelte"] --> R_TBase["typography/typography.base.tsx"] +R_TBase --> AntD["Ant Design Components"] +R_Button --> AntD +R_Float --> AntD +R_Icon --> AntD +``` + +Diagram sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/float-button/Index.svelte:1-70](file://frontend/antd/float-button/Index.svelte#L1-L70) +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) +- [frontend/antd/icon/icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [frontend/antd/typography/Base.svelte:1-85](file://frontend/antd/typography/Base.svelte#L1-L85) +- [frontend/antd/typography/typography.base.tsx:1-170](file://frontend/antd/typography/typography.base.tsx#L1-L170) + +Section sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/float-button/Index.svelte:1-70](file://frontend/antd/float-button/Index.svelte#L1-L70) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) +- [frontend/antd/typography/Base.svelte:1-85](file://frontend/antd/typography/Base.svelte#L1-L85) + +## Performance Considerations + +- **On-demand Rendering** + - Conditional checks and slot detection inject configuration and slots only when needed, reducing rendering cost +- **Function Bridging** + - Callbacks in configurations like `tooltip` are bridged via `useFunction`, avoiding new function creation on every render +- **Computed Caching** + - `Icon` uses `useMemo` to cache custom components, avoiding redundant creation +- **Async Loading** + - Lazy loading via `importComponent` reduces initial page load pressure + +## Troubleshooting Guide + +- **Slot Not Working** + - Verify that the slot name matches the component's supported list (e.g., Button: `icon`, `loading.icon`; FloatButton: `icon`/`description`/`tooltip`/`badge.count`; Typography: `copyable.*`, `editable.*`, `ellipsis.*`) +- **Tooltip Callback Not Working** + - When `tooltip` is an object, ensure related callbacks have been bridged via `useFunction` +- **Custom Icon Not Displayed** + - Ensure `value` is a valid icon name or that the IconFont context is available +- **`ellipsis` Not Working on `link`** + - Ensure `ellipsis` configuration is present or the slot has been provided +- **Visibility Issues** + - Ensure the `visible` prop is correctly passed to the entry component + +Section sources + +- [frontend/antd/button/button.tsx:11-36](file://frontend/antd/button/button.tsx#L11-L36) +- [frontend/antd/float-button/float-button.tsx:19-72](file://frontend/antd/float-button/float-button.tsx#L19-L72) +- [frontend/antd/icon/icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- [frontend/antd/typography/typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) +- [frontend/antd/button/Index.svelte:59-73](file://frontend/antd/button/Index.svelte#L59-L73) +- [frontend/antd/float-button/Index.svelte:56-69](file://frontend/antd/float-button/Index.svelte#L56-L69) +- [frontend/antd/icon/Index.svelte:52-66](file://frontend/antd/icon/Index.svelte#L52-L66) +- [frontend/antd/typography/Base.svelte:65-84](file://frontend/antd/typography/Base.svelte#L65-L84) + +## Conclusion + +The above components implement deep alignment with and flexible extension of Ant Design through a unified Svelte + React wrapper pattern. Using the slot system and utility functions, developers can achieve rich interaction and style customization while maintaining type safety. It is recommended to follow the prop and slot conventions documented here, combined with the performance and accessibility recommendations, to achieve a more stable and maintainable user experience. + +## Appendix + +- **Props and Slots Summary** + - **Button** + - Props: inherits all Ant Design Button props + - Slots: `icon`, `loading.icon` + - **FloatButton** + - Props: inherits all Ant Design FloatButton props + - Slots: `icon`, `description`, `tooltip`, `tooltip.title`, `badge.count` + - **Icon** + - Props: `value` (string), inherits all Ant Design Icon props + - Slots: `component` (custom SVG component) + - **Typography** + - Props: `component` (`'title'|'paragraph'|'text'|'link'`), `value` (string) + - Slots: `copyable.icon`, `copyable.tooltips`; `editable.icon`, `editable.tooltip`, `editable.enterIcon`; `ellipsis.symbol`, `ellipsis.tooltip`, `ellipsis.tooltip.title` diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Layout Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Layout Components API.md new file mode 100644 index 00000000..83606490 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Layout Components API.md @@ -0,0 +1,398 @@ +# Layout Components API + + +**Files referenced in this document** +- [divider.tsx](file://frontend/antd/divider/divider.tsx) +- [flex.tsx](file://frontend/antd/flex/flex.tsx) +- [grid/context.ts](file://frontend/antd/grid/context.ts) +- [grid/row/row.tsx](file://frontend/antd/grid/row/row.tsx) +- [grid/col/col.tsx](file://frontend/antd/grid/col/col.tsx) +- [layout/layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) +- [layout/Base.svelte](file://frontend/antd/layout/Base.svelte) +- [layout.sider/layout.sider.tsx](file://frontend/antd/layout/sider/layout.sider.tsx) +- [space/space.tsx](file://frontend/antd/space/space.tsx) +- [splitter/splitter.tsx](file://frontend/antd/splitter/splitter.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design-based layout components in ModelScope Studio, covering Divider, Flex, Grid (Row/Col), Layout (Header/Footer/Sider/Content), Space, and Splitter. It includes: + +- Property definitions and type sources for each component +- Layout algorithms and nesting rules +- Responsive behavior and key points of size calculation +- Correspondence with CSS Grid/Flexbox +- Standard usage paths and best practices +- Performance optimization and mobile adaptation recommendations + +## Project Structure + +These layout components expose Ant Design's React components as Svelte components through a unified Svelte preprocessing bridge. The core patterns are: + +- Using `sveltify` to wrap Ant Design components as Svelte components +- Collecting and rendering child items via context and Slot mechanisms +- Dynamically selecting specific Ant Design sub-components (e.g., Header/Footer/Content/Layout) via a Base component as needed + +```mermaid +graph TB +subgraph "Antd Wrapper Layer" +D["Divider
divider.tsx"] +F["Flex
flex.tsx"] +G["Grid.Row/Col
row.tsx / col.tsx"] +L["Layout.Base
layout.base.tsx"] +S["Space
space.tsx"] +SP["Splitter
splitter.tsx"] +end +subgraph "Context and Slots" +Ctx["Grid Context
grid/context.ts"] +Slots["ReactSlot / useTargets
Space Rendering"] +end +D --> |"sveltify"| AntD_D["antd.Divider"] +F --> |"sveltify"| AntD_F["antd.Flex"] +G --> |"useItems context"| Ctx +G --> |"ReactSlot"| Slots +L --> |"Dynamic component selection"| AntD_L["antd.Layout.*"] +S --> |"ReactSlot / useTargets"| Slots +SP --> |"withItemsContextProvider"| Ctx +SP --> |"ReactSlot"| Slots +``` + +Diagram sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) + +Section sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) + +## Core Components + +- **Divider**: A dividing line supporting child nodes as custom content or empty content. +- **Flex**: A flexbox layout container that forwards all Ant Design Flex props. +- **Grid**: A Row/Col combination implementing a grid system; Col registers itself to Row via context. +- **Layout**: The Base component dynamically maps to Header/Footer/Content/Layout based on the `component` prop. +- **Space**: Enhances slot rendering and separator slots on top of Ant Design Space. +- **Splitter**: A split-panel container that collects Panel children via context and renders them. + +Section sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) + +## Architecture Overview + +The following diagram shows how layout components organize child items through context and Slot mechanisms, ultimately rendering as an Ant Design component tree. + +```mermaid +sequenceDiagram +participant App as "Application" +participant Row as "Grid.Row
row.tsx" +participant Ctx as "Grid Context
context.ts" +participant Col as "Grid.Col
col.tsx" +participant Base as "Layout.Base
layout.base.tsx" +App->>Row : Renders Row and provides children +Row->>Ctx : withItemsContextProvider registers default list +Col->>Ctx : ItemHandler registers column item +Row->>Row : useItems retrieves default list +Row->>App : Renders ARow + ACol*ReactSlot rendering +App->>Base : Renders Base and specifies component +Base->>Base : Selects ALayout.Header/Footer/Content/Layout based on component +Base-->>App : Returns Ant Design component +``` + +Diagram sources + +- [grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [layout/layout.base.tsx:13-37](file://frontend/antd/layout/layout.base.tsx#L13-L37) + +## Component Details + +### Divider + +- **Function**: Provides horizontal or vertical dividing lines, with optional custom child nodes (e.g., icons, text). +- **Key Points**: + - When child nodes are present, they are passed to Ant Design Divider; otherwise, an empty divider is rendered. + - Types come from Ant Design Divider Props. +- **Typical usage path** + - [divider.tsx:5-12](file://frontend/antd/divider/divider.tsx#L5-L12) + +Section sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) + +### Flex + +- **Function**: An Ant Design Flex container supporting main-axis/cross-axis alignment, wrapping, and other layout props. +- **Key Points**: + - Directly forwards all Ant Design Flex Props. + - Suitable for complex flexbox layout scenarios. +- **Typical usage path** + - [flex.tsx:4-8](file://frontend/antd/flex/flex.tsx#L4-L8) + +Section sources + +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) + +### Grid + +- **Row/Col Combination** + - **Row**: Collects Col children via context, renders as Ant Design Row, and renders Col content via Slot. + - **Col**: Registers itself into Row's context via `ItemHandler`. +- **Context** + - Provides `withItemsContextProvider`, `useItems`, and `ItemHandler` for collecting and distributing child items. +- **Responsive and Nesting** + - Supports responsive breakpoint props (controlled by Ant Design Row/Col Props); Col can be nested within Row. +- **Typical usage paths** + - [grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) + - [grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) + - [grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) + +```mermaid +classDiagram +class GridContext { ++withItemsContextProvider(slots) ++useItems() ++ItemHandler +} +class Row { ++props : RowProps ++children : Col* ++render() : ARow + ACol* +} +class Col { ++props : ColProps ++register() : ItemHandler +} +Row --> GridContext : "Registers/consumes default list" +Col --> GridContext : "Registers into default list" +``` + +Diagram sources + +- [grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) +- [grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) + +Section sources + +- [grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + +### Layout + +- **Base Component** + - Dynamically maps to Header/Footer/Content/Layout based on the `component` prop. + - Supports extra class names and style forwarding. +- **Sider Sub-component** + - Exported via a separate file; used with Layout to implement sidebars. +- **Typical usage paths** + - [layout/layout.base.tsx:13-37](file://frontend/antd/layout/layout.base.tsx#L13-L37) + - [layout/Base.svelte:53-67](file://frontend/antd/layout/Base.svelte#L53-L67) + - [layout.sider/layout.sider.tsx](file://frontend/antd/layout/sider/layout.sider.tsx) + +```mermaid +sequenceDiagram +participant Svelte as "Base.svelte" +participant Base as "layout.base.tsx" +participant AD as "antd.Layout.*" +Svelte->>Base : Passes component and props +Base->>Base : Selects Header/Footer/Content/Layout based on component +Base->>AD : Renders corresponding component and forwards props +AD-->>Svelte : Returns DOM +``` + +Diagram sources + +- [layout/Base.svelte:53-67](file://frontend/antd/layout/Base.svelte#L53-L67) +- [layout/layout.base.tsx:13-37](file://frontend/antd/layout/layout.base.tsx#L13-L37) + +Section sources + +- [layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [layout.sider/layout.sider.tsx](file://frontend/antd/layout/sider/layout.sider.tsx) + +### Space + +- **Function**: Inserts spacing between elements, supporting a custom separator slot. +- **Key Points**: + - Uses `useTargets` to parse children, hides the real DOM, and renders via Ant Design Space. + - Supports a `split` slot for custom separators. +- **Typical usage path** + - [space/space.tsx:7-26](file://frontend/antd/space/space.tsx#L7-L26) + +```mermaid +flowchart TD +Start(["Start"]) --> Parse["Parse children into target list"] +Parse --> Hide["Hide real DOM"] +Hide --> Render["Render Ant Design Space"] +Render --> Split{"Is split slot provided?"} +Split --> |Yes| UseSplit["Use split slot"] +Split --> |No| UseProp["Use props.split"] +UseSplit --> Done(["Done"]) +UseProp --> Done +``` + +Diagram sources + +- [space/space.tsx:8-26](file://frontend/antd/space/space.tsx#L8-L26) + +Section sources + +- [space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) + +### Splitter + +- **Function**: Splits an area into multiple panels with draggable size adjustment. +- **Key Points**: + - Collects Panel children from the default slot via `withItemsContextProvider`. + - Uses `ReactSlot` to render each Panel's content. +- **Typical usage path** + - [splitter/splitter.tsx:7-35](file://frontend/antd/splitter/splitter.tsx#L7-L35) + +```mermaid +sequenceDiagram +participant App as "Application" +participant Splitter as "Splitter
splitter.tsx" +participant Ctx as "Context
context.ts" +participant Panel as "Panel" +App->>Splitter : Renders Splitter and provides children +Splitter->>Ctx : withItemsContextProvider registers default panel list +Splitter->>Splitter : useItems retrieves default panels +Splitter->>Panel : Renders each Panel and injects content +Panel-->>App : Returns draggable panel +``` + +Diagram sources + +- [splitter/splitter.tsx:7-35](file://frontend/antd/splitter/splitter.tsx#L7-L35) +- [grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) + +Section sources + +- [splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + +## Dependency Analysis + +- **Inter-component Coupling** + - Grid.Row/Col depends on Grid context for child item collection and distribution. + - Space/Splitter depends on the common Slot mechanism and target resolution utilities. + - Layout.Base implements multi-form layouts through dynamic component selection. +- **External Dependencies** + - Ant Design component library (Divider, Flex, Grid, Layout, Space, Splitter). + - Svelte preprocessing toolchain (sveltify, ReactSlot, useTargets). + - Style utilities (classnames) for conditional class name composition. + +```mermaid +graph LR +Row["Grid.Row"] --> Ctx["Grid Context"] +Col["Grid.Col"] --> Ctx +Space["Space"] --> Slot["ReactSlot / useTargets"] +Splitter["Splitter"] --> Ctx +Splitter --> Slot +LayoutBase["Layout.Base"] --> AD["antd.Layout.*"] +``` + +Diagram sources + +- [grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) +- [space/space.tsx:8-26](file://frontend/antd/space/space.tsx#L8-L26) +- [splitter/splitter.tsx:7-35](file://frontend/antd/splitter/splitter.tsx#L7-L35) +- [layout/layout.base.tsx:13-37](file://frontend/antd/layout/layout.base.tsx#L13-L37) + +Section sources + +- [grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +## Performance Considerations + +- **Virtualization and Lazy Loading** + - For Grid/Space/Splitter with long lists or many children, prefer virtualization or pagination strategies to reduce upfront rendering overhead. +- **Slot Rendering Optimization** + - Space hides the real DOM and only renders Ant Design Space, avoiding redundant rendering and style jitter. +- **Conditional Rendering** + - Layout.Base dynamically selects components based on `component`, avoiding unnecessary DOM structure. +- **Responsive Breakpoints** + - Grid uses Ant Design breakpoint params; set responsive thresholds appropriately to avoid frequent reflows. +- **Mobile Adaptation** + - On small screens, prefer Flex or Space's compact mode to reduce overflow issues from fixed-width layouts. + - For Splitter on mobile, it is recommended to limit minimum panel size and disable dragging to improve interaction stability. + +## Troubleshooting Guide + +- **Grid Children Not Displayed** + - Check that Row correctly wraps Col and that Col has registered to the context via `ItemHandler`. + - Confirm that Row's children include Col and that Col's `el` is valid. +- **Space Separator Not Working** + - Confirm that the `split` slot or `props.split` has been provided, and that the slot content can be correctly rendered by ReactSlot. +- **Splitter Panel Empty** + - Confirm that Panel has been registered in the default slot and that Panel's `el` is valid. +- **Layout Style Abnormalities** + - Check that the `component` passed to the Base component matches expectations, and confirm that the class name composition logic has not been overridden. + +Section sources + +- [grid/row/row.tsx:12-29](file://frontend/antd/grid/row/row.tsx#L12-L29) +- [grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [space/space.tsx:13-22](file://frontend/antd/space/space.tsx#L13-L22) +- [splitter/splitter.tsx:9-31](file://frontend/antd/splitter/splitter.tsx#L9-L31) +- [layout/layout.base.tsx:31-35](file://frontend/antd/layout/layout.base.tsx#L31-L35) + +## Conclusion + +ModelScope Studio's layout components present Ant Design's layout capabilities in a more ergonomic way through a unified Svelte preprocessing bridge. Grid, Layout, Space, Splitter, and other components maintain consistency with the Ant Design API while enhancing slot and context capabilities, making them suitable for composing and reusing complex layout scenarios. Following the property definitions, nesting rules, and performance recommendations in this document will deliver a stable and efficient layout experience on both desktop and mobile. + +## Appendix + +- **Correspondence with CSS Grid/Flexbox** + - Grid.Row/Col corresponds to row/column division in CSS Grid; Flex corresponds to CSS Flexbox. + - Space corresponds to flex gap distribution; Splitter corresponds to draggable area partitioning. +- **Common Layout Scenarios** + - **Grid system**: Row + Col combination, controlling column width and wrapping by breakpoint. + - **Flexbox layout**: Flex container with multiple children, controlling main-axis and cross-axis alignment. + - **Split panels**: Splitter with multiple Panels, supporting draggable size adjustment. + - **Page layout**: Layout.Base selecting Header/Footer/Content/Sider combinations as needed. diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Navigation Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Navigation Components API.md new file mode 100644 index 00000000..b66562ca --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Navigation Components API.md @@ -0,0 +1,462 @@ +# Navigation Components API + + +**Files referenced in this document** +- [frontend/antd/anchor/Index.svelte](file://frontend/antd/anchor/Index.svelte) +- [frontend/antd/anchor/anchor.tsx](file://frontend/antd/anchor/anchor.tsx) +- [frontend/antd/anchor/context.ts](file://frontend/antd/anchor/context.ts) +- [frontend/antd/breadcrumb/Index.svelte](file://frontend/antd/breadcrumb/Index.svelte) +- [frontend/antd/breadcrumb/breadcrumb.tsx](file://frontend/antd/breadcrumb/breadcrumb.tsx) +- [frontend/antd/breadcrumb/context.ts](file://frontend/antd/breadcrumb/context.ts) +- [frontend/antd/breadcrumb/item/Index.svelte](file://frontend/antd/breadcrumb/item/Index.svelte) +- [frontend/antd/dropdown/Index.svelte](file://frontend/antd/dropdown/Index.svelte) +- [frontend/antd/dropdown/dropdown.tsx](file://frontend/antd/dropdown/dropdown.tsx) +- [frontend/antd/menu/Index.svelte](file://frontend/antd/menu/Index.svelte) +- [frontend/antd/menu/menu.tsx](file://frontend/antd/menu/menu.tsx) +- [frontend/antd/menu/context.ts](file://frontend/antd/menu/context.ts) +- [frontend/antd/menu/item/Index.svelte](file://frontend/antd/menu/item/Index.svelte) +- [frontend/antd/pagination/Index.svelte](file://frontend/antd/pagination/Index.svelte) +- [frontend/antd/pagination/pagination.tsx](file://frontend/antd/pagination/pagination.tsx) +- [frontend/antd/steps/Index.svelte](file://frontend/antd/steps/Index.svelte) +- [frontend/antd/steps/steps.tsx](file://frontend/antd/steps/steps.tsx) +- [frontend/antd/steps/context.ts](file://frontend/antd/steps/context.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design-based navigation components in ModelScope Studio, covering: Anchor, Breadcrumb, Dropdown, Menu, Pagination, and Steps. It provides a systematic overview of architecture design, data flow, processing logic, type definitions, event binding, routing integration, permission control, and dynamic loading, along with reusable usage patterns and best practices. + +## Project Structure + +Navigation components use a unified "Svelte wrapper layer + React component bridge" pattern on the frontend: + +- The Svelte layer handles prop forwarding, visibility control, style injection, slot rendering, and lazy loading. +- The React layer bridges native Ant Design components into the Svelte ecosystem via `sveltify`, while providing slot rendering, function hooks, and context injection capabilities. + +```mermaid +graph TB +subgraph "Svelte Wrapper Layer" +A_Index["anchor/Index.svelte"] +B_Index["breadcrumb/Index.svelte"] +C_Index["dropdown/Index.svelte"] +D_Index["menu/Index.svelte"] +E_Index["pagination/Index.svelte"] +F_Index["steps/Index.svelte"] +end +subgraph "React Bridge Layer" +A_Core["anchor.tsx"] +B_Core["breadcrumb.tsx"] +C_Core["dropdown.tsx"] +D_Core["menu.tsx"] +E_Core["pagination.tsx"] +F_Core["steps.tsx"] +end +A_Index --> A_Core +B_Index --> B_Core +C_Index --> C_Core +D_Index --> D_Core +E_Index --> E_Core +F_Index --> F_Core +``` + +Diagram sources + +- [frontend/antd/anchor/Index.svelte:1-66](file://frontend/antd/anchor/Index.svelte#L1-L66) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/dropdown/Index.svelte:1-70](file://frontend/antd/dropdown/Index.svelte#L1-L70) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/Index.svelte:1-75](file://frontend/antd/menu/Index.svelte#L1-L75) +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/pagination/Index.svelte:1-68](file://frontend/antd/pagination/Index.svelte#L1-L68) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [frontend/antd/steps/Index.svelte:1-63](file://frontend/antd/steps/Index.svelte#L1-L63) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) + +Section sources + +- [frontend/antd/anchor/Index.svelte:1-66](file://frontend/antd/anchor/Index.svelte#L1-L66) +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/dropdown/Index.svelte:1-70](file://frontend/antd/dropdown/Index.svelte#L1-L70) +- [frontend/antd/menu/Index.svelte:1-75](file://frontend/antd/menu/Index.svelte#L1-L75) +- [frontend/antd/pagination/Index.svelte:1-68](file://frontend/antd/pagination/Index.svelte#L1-L68) +- [frontend/antd/steps/Index.svelte:1-63](file://frontend/antd/steps/Index.svelte#L1-L63) + +## Core Components + +This section provides an overview of the responsibilities and common characteristics of the six navigation components: + +- **Anchor**: In-page anchor navigation supporting container selection and current anchor callbacks. +- **Breadcrumb**: Displays the current page's position in the hierarchy; supports custom separators, item rendering, and dropdown icons. +- **Dropdown**: Wraps a trigger element and renders a dropdown menu; supports custom popup rendering and menu item injection. +- **Menu**: Side or top navigation menu; supports themes, expand icons, overflow indicators, and select/expand events. +- **Pagination**: Data pagination control; supports quick-jump buttons and custom page item rendering. +- **Steps**: Step flow indicator; supports step item lists and custom progress dot rendering. + +Section sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) + +## Architecture Overview + +Component bridging follows a unified pattern of "lazy loading + slot rendering + function hooks": + +- **Prop forwarding**: The wrapper layer forwards common props such as `visible`, `elem_id`, `elem_classes`, `elem_style`, `_internal`, and `as_item` to the React component. +- **Slot rendering**: Slot name mapping and parameterized rendering are supported via `ReactSlot` and `renderParamsSlot`. +- **Dynamic injection**: `items` lists are injected via `withItemsContextProvider`, supporting both default slots and explicit `items` params. +- **Event binding**: Events such as `onOpenChange`, `onSelect`, `onDeselect`, and `onChange` are ensured to be reactive through the `useFunction` hook. + +```mermaid +sequenceDiagram +participant S as "Svelte Wrapper Layer (Index.svelte)" +participant P as "Prop Processor (processProps)" +participant R as "React Component (sveltify)" +participant C as "Context/Slots (Items/Slots)" +S->>P : Parses component props and extra props +P-->>S : Returns normalized prop set +S->>R : Renders Antd component and passes props +R->>C : Reads items context and slots +C-->>R : Provides items list and slot functions +R-->>S : Fires event callbacks (onChange/onSelect, etc.) +S-->>S : Processes result via Gradio/routing callback +``` + +Diagram sources + +- [frontend/antd/anchor/Index.svelte:22-44](file://frontend/antd/anchor/Index.svelte#L22-L44) +- [frontend/antd/anchor/anchor.tsx:10-43](file://frontend/antd/anchor/anchor.tsx#L10-L43) +- [frontend/antd/breadcrumb/breadcrumb.tsx:15-63](file://frontend/antd/breadcrumb/breadcrumb.tsx#L15-L63) +- [frontend/antd/dropdown/dropdown.tsx:26-108](file://frontend/antd/dropdown/dropdown.tsx#L26-L108) +- [frontend/antd/menu/menu.tsx:18-92](file://frontend/antd/menu/menu.tsx#L18-L92) +- [frontend/antd/pagination/pagination.tsx:14-52](file://frontend/antd/pagination/pagination.tsx#L14-L52) +- [frontend/antd/steps/steps.tsx:16-49](file://frontend/antd/steps/steps.tsx#L16-L49) + +## Component Details + +### Anchor + +- **Responsibility**: Provides in-page anchor navigation; supports container selection and current anchor callbacks. +- **Key Props and Behaviors** + - Container selection: `getContainer` specifies the scroll container. + - Current anchor: `getCurrentAnchor` retrieves the currently active anchor. + - Items injection: `items` are injected via context, supporting default slot and explicit `items`. +- **Events and State** + - No explicit event callbacks; scroll positioning and highlight sync are achieved via callback functions. +- **Usage Notes** + - Use with anchor items on long pages; ensure the container is set correctly. + - Use slots to render custom anchor titles. + +```mermaid +flowchart TD +Start(["Enter Anchor"]) --> Items["Parse items context"] +Items --> Render["Render Antd Anchor"] +Render --> Events{"Scroll/Click event"} +Events --> |Positioning| SetActive["Set current anchor"] +Events --> |Switch| Callback["Execute callback function"] +SetActive --> End(["Done"]) +Callback --> End +``` + +Diagram sources + +- [frontend/antd/anchor/anchor.tsx:10-43](file://frontend/antd/anchor/anchor.tsx#L10-L43) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) + +Section sources + +- [frontend/antd/anchor/Index.svelte:1-66](file://frontend/antd/anchor/Index.svelte#L1-L66) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) + +### Breadcrumb + +- **Responsibility**: Displays the current page's path in the hierarchy; supports custom separators, item rendering, and dropdown icons. +- **Key Props and Behaviors** + - Separator: `separator` supports slots and functions. + - Item rendering: `itemRender` supports slots and functions. + - Dropdown icon: `dropdownIcon` supports slots. + - Items injection: supports `default` and `items` slots. +- **Events and State** + - Rendering is controlled via props and slots; no direct event callbacks. +- **Usage Notes** + - Generate a hierarchical structure in combination with a routing system; use `itemRender` to customize link styles when necessary. + +```mermaid +sequenceDiagram +participant B as "Breadcrumb" +participant S as "Slots" +participant I as "Items Context" +B->>I : Reads items/default +B->>S : Renders separator/itemRender/dropdownIcon +B-->>B : Renders Antd Breadcrumb +``` + +Diagram sources + +- [frontend/antd/breadcrumb/breadcrumb.tsx:15-63](file://frontend/antd/breadcrumb/breadcrumb.tsx#L15-L63) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) + +Section sources + +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) +- [frontend/antd/breadcrumb/item/Index.svelte:1-72](file://frontend/antd/breadcrumb/item/Index.svelte#L1-L72) + +### Dropdown + +- **Responsibility**: Wraps a trigger element and renders a dropdown menu; supports custom popup rendering and menu item injection. +- **Key Props and Behaviors** + - Popup container: `getPopupContainer`. + - Dropdown rendering: `dropdownRender`, `popupRender` support slots and functions. + - Menu expand icon: `menu.expandIcon` supports slots. + - Overflow indicator: `menu.overflowedIndicator` supports slots. + - Menu item injection: items are injected via the menu context. +- **Events and State** + - Rendering is controlled via props and slots; no direct event callbacks. +- **Usage Notes** + - Place the trigger element inside the component to avoid style occlusion. + - Use slots to implement complex dropdown panel layouts. + +```mermaid +classDiagram +class Dropdown { ++props : GetProps ++slots : dropdownRender,popupRender,menu.expandIcon,menu.overflowedIndicator ++getPopupContainer() ++render() +} +class MenuItems { ++items : ItemType[] ++expandIcon() ++overflowedIndicator() +} +Dropdown --> MenuItems : "Injects menu items" +``` + +Diagram sources + +- [frontend/antd/dropdown/dropdown.tsx:15-108](file://frontend/antd/dropdown/dropdown.tsx#L15-L108) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) + +Section sources + +- [frontend/antd/dropdown/Index.svelte:1-70](file://frontend/antd/dropdown/Index.svelte#L1-L70) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) + +### Menu + +- **Responsibility**: Side or top navigation menu; supports themes, expand icons, overflow indicators, and select/expand events. +- **Key Props and Behaviors** + - Theme: `theme` supports external injection. + - Expand icon: `expandIcon` supports slots. + - Overflow indicator: `overflowedIndicator` supports slots. + - Popup rendering: `popupRender` supports slots. + - Events: `onOpenChange`, `onSelect`, `onDeselect`. + - Items injection: supports `default` and `items` slots. +- **Events and State** + - State management and routing integration are achieved via `onOpenChange`, `onSelect`, and `onDeselect`. +- **Usage Notes** + - When integrating with a routing library, handle routing navigation and selection state sync inside `onSelect`. + +```mermaid +sequenceDiagram +participant M as "Menu" +participant E as "Event Callbacks" +participant R as "Router/Gradio" +M->>E : onSelect/onDeselect/onOpenChange +E->>R : Update route/state +R-->>M : Sync selected/expanded state +``` + +Diagram sources + +- [frontend/antd/menu/menu.tsx:18-92](file://frontend/antd/menu/menu.tsx#L18-L92) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) + +Section sources + +- [frontend/antd/menu/Index.svelte:1-75](file://frontend/antd/menu/Index.svelte#L1-L75) +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [frontend/antd/menu/item/Index.svelte:1-84](file://frontend/antd/menu/item/Index.svelte#L1-L84) + +### Pagination + +- **Responsibility**: Data pagination control; supports quick-jump buttons and custom page item rendering. +- **Key Props and Behaviors** + - Quick jump: `showQuickJumper` supports the `goButton` slot. + - Total display: `showTotal` supports functions. + - Page item rendering: `itemRender` supports slots and functions. + - Events: `onChange(page, pageSize)`. +- **Events and State** + - Handle pagination logic and data refresh inside `onChange`. +- **Usage Notes** + - When interfacing with backend pagination APIs, pay attention to `page`/`pageSize` conversion and boundary handling. + +```mermaid +flowchart TD +Start(["User action"]) --> Jump["Click page number / quick jump"] +Jump --> Call["Call onChange(page,pageSize)"] +Call --> Fetch["Request new page data"] +Fetch --> Update["Update list and total count"] +Update --> End(["Done"]) +``` + +Diagram sources + +- [frontend/antd/pagination/pagination.tsx:14-52](file://frontend/antd/pagination/pagination.tsx#L14-L52) + +Section sources + +- [frontend/antd/pagination/Index.svelte:1-68](file://frontend/antd/pagination/Index.svelte#L1-L68) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) + +### Steps + +- **Responsibility**: Step flow indicator; supports step item lists and custom progress dot rendering. +- **Key Props and Behaviors** + - Step items: `items` injection, supporting `default` and `items` slots. + - Progress dot: `progressDot` supports slots and functions. + - Events: step switching is implemented via callback functions. +- **Events and State** + - No direct event callbacks; step state management is achieved via function hooks. +- **Usage Notes** + - When combined with form wizards, control the availability of the next step based on the current step. + +```mermaid +sequenceDiagram +participant S as "Steps" +participant P as "progressDot slot" +participant I as "items context" +S->>I : Reads items/default +S->>P : Renders progress dot +S-->>S : Renders Antd Steps +``` + +Diagram sources + +- [frontend/antd/steps/steps.tsx:16-49](file://frontend/antd/steps/steps.tsx#L16-L49) +- [frontend/antd/steps/context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) + +Section sources + +- [frontend/antd/steps/Index.svelte:1-63](file://frontend/antd/steps/Index.svelte#L1-L63) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/steps/context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) + +## Dependency Analysis + +- **Inter-component Coupling** + - Dropdown depends on Menu's context injection for unified menu item management. + - All components with `items` depend on the context and rendering utilities provided by `createItemsContext`. +- **External Dependencies** + - Native Ant Design components as the rendering foundation. + - `@svelte-preprocess-react` provides tools such as `sveltify`, `ReactSlot`, `renderItems`, and `renderParamsSlot`. +- **Potential Circular Dependencies** + - Direct circular imports are avoided via context injection; each component independently maintains its own context. + +```mermaid +graph LR +Ctx["createItemsContext"] --> A["Anchor Items"] +Ctx --> B["Breadcrumb Items"] +Ctx --> M["Menu Items"] +Ctx --> S["Steps Items"] +D["Dropdown"] --> M +A --> Antd["Antd Anchor"] +B --> Antd2["Antd Breadcrumb"] +D --> Antd3["Antd Dropdown"] +M --> Antd4["Antd Menu"] +P["Pagination"] --> Antd5["Antd Pagination"] +S --> Antd6["Antd Steps"] +``` + +Diagram sources + +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [frontend/antd/steps/context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) +- [frontend/antd/dropdown/dropdown.tsx:10-13](file://frontend/antd/dropdown/dropdown.tsx#L10-L13) + +Section sources + +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [frontend/antd/steps/context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) +- [frontend/antd/dropdown/dropdown.tsx:10-13](file://frontend/antd/dropdown/dropdown.tsx#L10-L13) + +## Performance Considerations + +- **Lazy Loading**: The Svelte wrapper layer lazy-loads React components to reduce the initial page load burden. +- **Computed Caching**: The React layer uses `useMemo` to stabilize `items`, avoiding unnecessary re-renders. +- **Slot Cloning**: Slot rendering enables cloning by default to ensure independence, but be mindful of cloning overhead. +- **Event Hooks**: The `useFunction` hook ensures stable callback references, preventing re-renders caused by function reference changes. + +## Troubleshooting Guide + +- **Event Not Triggered** + - Check that `onOpenChange`/`onSelect`/`onDeselect`/`onChange` callbacks have been correctly passed. + - Confirm that the callback functions are wrapped with the `useFunction` hook. +- **Slot Not Working** + - Confirm that the slot name matches the mapping (e.g., `menu.expandIcon`, `itemRender`, etc.). + - Check that the slot has cloning enabled (`clone: true`). +- **Items Not Displayed** + - Confirm that `items` have been injected via context or passed explicitly. + - Check the priority and naming of the default slot vs. the `items` slot. +- **Style Conflicts** + - Check whether `elem_id`/`elem_classes` conflict with global styles. + - Ensure the component style class prefix `ms-gr-antd-*` has not been overridden. + +Section sources + +- [frontend/antd/anchor/anchor.tsx:10-43](file://frontend/antd/anchor/anchor.tsx#L10-L43) +- [frontend/antd/breadcrumb/breadcrumb.tsx:15-63](file://frontend/antd/breadcrumb/breadcrumb.tsx#L15-L63) +- [frontend/antd/dropdown/dropdown.tsx:26-108](file://frontend/antd/dropdown/dropdown.tsx#L26-L108) +- [frontend/antd/menu/menu.tsx:18-92](file://frontend/antd/menu/menu.tsx#L18-L92) +- [frontend/antd/pagination/pagination.tsx:14-52](file://frontend/antd/pagination/pagination.tsx#L14-L52) +- [frontend/antd/steps/steps.tsx:16-49](file://frontend/antd/steps/steps.tsx#L16-L49) + +## Conclusion + +ModelScope Studio's navigation components achieve seamless integration of Ant Design components in the frontend ecosystem through a unified Svelte wrapper layer and React bridge layer. The design emphasizes: + +- **Ease of use**: Unified prop forwarding and slot mapping. +- **Extensibility**: Context injection and function hooks for greater flexibility. +- **Maintainability**: Clear separation of responsibilities and dependencies. + +It is recommended to normalize event callbacks and state management in combination with routing systems and permission frameworks in real-world projects to achieve a better user experience and development efficiency. + +## Appendix + +- **Routing Integration Recommendations** + - Handle routing navigation and state sync uniformly in Menu/Pagination/Steps callbacks. + - Handle scroll positioning and highlight sync uniformly in Anchor and Steps callbacks. +- **Permission Control Recommendations** + - Filter invisible items at the items injection stage, or hide them based on permission conditions at the rendering layer. +- **Dynamic Loading Recommendations** + - Use lazy loading and `useMemo` caching strategies to avoid frequent re-renders. +- **Accessibility Recommendations** + - Provide keyboard accessibility and screen-reader-friendly labels for clickable items. + - Provide clear ARIA attributes and state hints for step indicators and pagination controls. diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Other Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Other Components API.md new file mode 100644 index 00000000..4162672a --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design Components API/Other Components API.md @@ -0,0 +1,278 @@ +# Other Components API + + +**Files referenced in this document** +- [frontend/antd/affix/Index.svelte](file://frontend/antd/affix/Index.svelte) +- [frontend/antd/affix/affix.tsx](file://frontend/antd/affix/affix.tsx) +- [frontend/antd/affix/package.json](file://frontend/antd/affix/package.json) +- [frontend/antd/config-provider/Index.svelte](file://frontend/antd/config-provider/Index.svelte) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) +- [frontend/antd/config-provider/package.json](file://frontend/antd/config-provider/package.json) +- [docs/components/antd/affix/README.md](file://docs/components/antd/affix/README.md) +- [docs/components/antd/config_provider/README.md](file://docs/components/antd/config_provider/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides a systematic overview of special-function Ant Design components in ModelScope Studio: Affix (sticky positioning) and ConfigProvider (global configuration). It covers their APIs, type definitions, context provision, theme and internationalization mechanisms, and how they integrate into the component system. The document also presents standard usage workflows, typical scenarios, and best practices to help developers quickly understand and correctly use these components. + +## Project Structure + +- Components are organized as Svelte packages; each component directory contains: + - `Index.svelte`: The Gradio/Svelte wrapper layer, responsible for prop forwarding, slot rendering, visibility control, and lazy loading. + - Component implementation files (e.g., `affix.tsx`, `config-provider.tsx`): Bridge React components into a Svelte-usable form via `@svelte-preprocess-react`, extending necessary types and behaviors. + - `package.json`: The export entry, supporting both Gradio and default modes. +- Documentation is located under `docs/components/antd`, providing examples and explanations. + +```mermaid +graph TB +subgraph "Ant Design Components" +A["affix/Index.svelte"] +B["affix/affix.tsx"] +C["config-provider/Index.svelte"] +D["config-provider/config-provider.tsx"] +E["config-provider/locales.ts"] +end +A --> B +C --> D +D --> E +``` + +Diagram sources + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) + +Section sources + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/antd/affix/package.json:1-15](file://frontend/antd/affix/package.json#L1-L15) +- [frontend/antd/config-provider/package.json:1-15](file://frontend/antd/config-provider/package.json#L1-L15) +- [docs/components/antd/affix/README.md:1-9](file://docs/components/antd/affix/README.md#L1-L9) +- [docs/components/antd/config_provider/README.md:1-8](file://docs/components/antd/config_provider/README.md#L1-L8) + +## Core Components + +- **Affix** + - **Responsibility**: Fixes child elements to the viewport or container boundaries; commonly used for sidebars, back-to-top buttons, etc. + - **Key Points**: Dynamically determines the scroll container via the `target` function; supports `visible` to control rendering; supports extra prop forwarding and slot rendering. +- **ConfigProvider** + - **Responsibility**: Provides unified global configuration for Ant Design components, including themes, locales, popup containers, and empty state rendering. + - **Key Points**: Supports theme algorithm toggles (dark/compact), internationalization locale switching, style injection, and container function callbacks; can be used as the context root node. + +Section sources + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) + +## Architecture Overview + +The following diagram illustrates the call chain from the Svelte wrapper layer to React components, as well as the theme and internationalization processing flow for ConfigProvider. + +```mermaid +sequenceDiagram +participant UI as "Page/Application" +participant Wrap as "Svelte Wrapper Layer (Index.svelte)" +participant Impl as "Component Implementation (.tsx)" +participant AD as "Ant Design Component Library" +participant CSS as "Style Injection (StyleProvider)" +UI->>Wrap : Renders component and passes props/slots +Wrap->>Impl : Lazy-imports and forwards props +Impl->>AD : Instantiates target component (e.g., Affix/ConfigProvider) +Impl->>CSS : Injects style prefix and hash strategy +AD-->>UI : Render result +``` + +Diagram sources + +- [frontend/antd/affix/Index.svelte:55-68](file://frontend/antd/affix/Index.svelte#L55-L68) +- [frontend/antd/affix/affix.tsx:6-11](file://frontend/antd/affix/affix.tsx#L6-L11) +- [frontend/antd/config-provider/Index.svelte:54-71](file://frontend/antd/config-provider/Index.svelte#L54-L71) +- [frontend/antd/config-provider/config-provider.tsx:108-149](file://frontend/antd/config-provider/config-provider.tsx#L108-L149) + +## Component Details + +### Affix + +- **Responsibility** + - Fixes child content to the viewport or a specified container boundary, showing/hiding as the user scrolls. +- **Props and Behaviors** + - Supports a `target` container function for dynamically selecting the scroll container. + - Supports `visible` to control whether to render. + - Supports extra prop forwarding and slot rendering. +- **Use Cases** + - Sidebar toolbars, back-to-top buttons, floating action areas, etc. +- **Types and Implementation Notes** + - Bridges Ant Design's `Affix` as a Svelte component via `sveltify` from `@svelte-preprocess-react`. + - `target` is wrapped via `useFunction` to ensure reactive updates. +- **Examples and Documentation** + - Documentation provides two examples: "Basic" and "Container scroll" for quick onboarding. + +```mermaid +sequenceDiagram +participant P as "Parent Component" +participant W as "affix/Index.svelte" +participant T as "affix.tsx (Antd Affix)" +participant R as "React/Antd" +P->>W : Passes props (including target/visible/slots) +W->>T : Forwards after processProps +T->>R : Wraps target via useFunction and renders +R-->>P : DOM result with sticky positioning applied +``` + +Diagram sources + +- [frontend/antd/affix/Index.svelte:23-49](file://frontend/antd/affix/Index.svelte#L23-L49) +- [frontend/antd/affix/affix.tsx:6-11](file://frontend/antd/affix/affix.tsx#L6-L11) + +Section sources + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [docs/components/antd/affix/README.md:1-9](file://docs/components/antd/affix/README.md#L1-L9) + +### ConfigProvider + +- **Responsibility** + - Provides unified global configuration covering theme, locale, popup container, empty state rendering, and more. +- **Theme and Algorithms** + - `theme.algorithm` supports automatic detection: dark/compact algorithms can be enabled based on `themeMode` or explicit configuration. +- **Internationalization** + - `locale` supports multi-language mapping, switching based on browser language or explicit input; also synchronizes `dayjs` locale settings. +- **Slots and Prop Composition** + - Supports converting slots into a prop tree for declarative passing of complex configuration items. +- **Context and Containers** + - Marks the context as `antd` type via `setConfigType`, affecting behaviors like shared theming. + - Supports `getPopupContainer`/`getTargetContainer` for customizing popup and mount containers. + +```mermaid +flowchart TD +Start(["Enter ConfigProvider"]) --> Locale["Parse locale
Load corresponding Antd and dayjs language pack"] +Locale --> Theme["Merge theme.algorithm
Generate final algorithm array based on themeMode and props"] +Theme --> Slots["Convert slots to prop tree
Functionalize slots like renderEmpty"] +Slots --> Style["Inject style prefix and hash strategy"] +Style --> Render["Render subtree"] +Render --> End(["Done"]) +``` + +Diagram sources + +- [frontend/antd/config-provider/config-provider.tsx:85-105](file://frontend/antd/config-provider/config-provider.tsx#L85-L105) +- [frontend/antd/config-provider/config-provider.tsx:127-143](file://frontend/antd/config-provider/config-provider.tsx#L127-L143) +- [frontend/antd/config-provider/config-provider.tsx:29-49](file://frontend/antd/config-provider/config-provider.tsx#L29-L49) +- [frontend/antd/config-provider/locales.ts:15-27](file://frontend/antd/config-provider/locales.ts#L15-L27) + +Section sources + +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [docs/components/antd/config_provider/README.md:1-8](file://docs/components/antd/config_provider/README.md#L1-L8) + +## Dependency Analysis + +- **Component Export** + - Both components provide Gradio and default entry points via the `exports` field in `package.json`, making them usable across different runtime environments. +- **Runtime Dependencies** + - ConfigProvider depends on Ant Design's `ConfigProvider`, theme algorithms, and style injection; it also depends on `dayjs` and the locales mapping. + - Affix depends on Ant Design's `Affix` and the `useFunction` utility to wrap callback functions. +- **Wrapper Layer Coupling** + - Both components use lazy imports and prop forwarding to reduce initial load pressure and improve rendering controllability. + +```mermaid +graph LR +PkgA["@modelscope-studio/antd-affix/package.json"] --> IA["affix/Index.svelte"] +PkgB["@modelscope-studio/antd-config-provider/package.json"] --> IC["config-provider/Index.svelte"] +IA --> TA["affix.tsx"] +IC --> TC["config-provider.tsx"] +TC --> L["locales.ts"] +``` + +Diagram sources + +- [frontend/antd/affix/package.json:1-15](file://frontend/antd/affix/package.json#L1-L15) +- [frontend/antd/config-provider/package.json:1-15](file://frontend/antd/config-provider/package.json#L1-L15) +- [frontend/antd/affix/Index.svelte:10-13](file://frontend/antd/affix/Index.svelte#L10-L13) +- [frontend/antd/config-provider/Index.svelte:11-13](file://frontend/antd/config-provider/Index.svelte#L11-L13) + +Section sources + +- [frontend/antd/affix/package.json:1-15](file://frontend/antd/affix/package.json#L1-L15) +- [frontend/antd/config-provider/package.json:1-15](file://frontend/antd/config-provider/package.json#L1-L15) + +## Performance Considerations + +- **Lazy Loading** + - Components are loaded on demand via `importComponent` and the `{#await}` pattern, avoiding initial page blocking. +- **Prop Forwarding and Derived Computation** + - Using `processProps` and `$derived` avoids unnecessary re-renders, only updating when essential props change. +- **Style Injection Strategy** + - Using `StyleProvider` with a high-priority hash reduces style conflicts and repaint costs. +- **Callback Function Wrapping** + - Using `useFunction` to wrap callbacks like `target`/`getPopupContainer` ensures stable function references, reducing unnecessary updates. + +## Troubleshooting Guide + +- **Sticky Positioning Not Working** + - Check that `target` returns the correct scroll container; confirm that `visible` is `true` and the container has a scrollbar. + - Reference paths: [frontend/antd/affix/Index.svelte:47-49](file://frontend/antd/affix/Index.svelte#L47-L49), [frontend/antd/affix/affix.tsx:7-10](file://frontend/antd/affix/affix.tsx#L7-L10) +- **Popup/Float Position Abnormal** + - Check that `getPopupContainer` returns the correct container; confirm the `getTargetContainer` setting in ConfigProvider. + - Reference path: [frontend/antd/config-provider/config-provider.tsx:93-95](file://frontend/antd/config-provider/config-provider.tsx#L93-L95) +- **Theme Not Switching or Algorithm Not Taking Effect** + - Confirm the combination of `themeMode` and `theme.algorithm`; note that the algorithm array is composed of multiple algorithm functions. + - Reference paths: [frontend/antd/config-provider/config-provider.tsx:88-91](file://frontend/antd/config-provider/config-provider.tsx#L88-L91), [frontend/antd/config-provider/config-provider.tsx:127-143](file://frontend/antd/config-provider/config-provider.tsx#L127-L143) +- **Locale Not Taking Effect** + - Check the `locale` parameter format and the locales mapping; confirm that the `dayjs` locale has been synchronized. + - Reference paths: [frontend/antd/config-provider/config-provider.tsx:85-105](file://frontend/antd/config-provider/config-provider.tsx#L85-L105), [frontend/antd/config-provider/locales.ts:15-27](file://frontend/antd/config-provider/locales.ts#L15-L27) + +Section sources + +- [frontend/antd/affix/Index.svelte:47-49](file://frontend/antd/affix/Index.svelte#L47-L49) +- [frontend/antd/affix/affix.tsx:7-10](file://frontend/antd/affix/affix.tsx#L7-L10) +- [frontend/antd/config-provider/config-provider.tsx:85-105](file://frontend/antd/config-provider/config-provider.tsx#L85-L105) +- [frontend/antd/config-provider/config-provider.tsx:88-91](file://frontend/antd/config-provider/config-provider.tsx#L88-L91) +- [frontend/antd/config-provider/config-provider.tsx:127-143](file://frontend/antd/config-provider/config-provider.tsx#L127-L143) +- [frontend/antd/config-provider/locales.ts:15-27](file://frontend/antd/config-provider/locales.ts#L15-L27) + +## Conclusion + +- Affix and ConfigProvider in ModelScope Studio are seamlessly integrated with the Ant Design component library through a unified Svelte wrapper layer and `@svelte-preprocess-react` bridging. +- ConfigProvider provides powerful global configuration capabilities covering themes, internationalization, and container strategies; Affix focuses on sticky positioning scenarios with good configurability and performance. +- It is recommended to place ConfigProvider at the application root to unify style and locale; use Affix for areas requiring sticky positioning, and set `target` and `visible` appropriately. + +## Appendix + +- **Examples and Demos** + - Affix examples: Basic, Container scroll + - ConfigProvider examples: Basic +- **Reference Documentation** + - Ant Design official Affix and ConfigProvider documentation links are in each component's README. + +Section sources + +- [docs/components/antd/affix/README.md:1-9](file://docs/components/antd/affix/README.md#L1-L9) +- [docs/components/antd/config_provider/README.md:1-8](file://docs/components/antd/config_provider/README.md#L1-L8) diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Ant Design X Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Ant Design X Components API.md new file mode 100644 index 00000000..84e46c54 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Ant Design X Components API.md @@ -0,0 +1,436 @@ +# Ant Design X Components API + + +**Files referenced in this document** +- [backend/modelscope_studio/components/__init__.py](file://backend/modelscope_studio/components/__init__.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/components/pro/__init__.py](file://backend/modelscope_studio/components/pro/__init__.py) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/antdx/conversations/conversations.tsx](file://frontend/antdx/conversations/conversations.tsx) +- [frontend/antdx/sender/sender.tsx](file://frontend/antdx/sender/sender.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design X-based Svelte components in ModelScope Studio, covering the following component families: + +- **General Components**: Common UI component wrappers from Ant Design (antd) +- **Awakening Components**: Components for guiding user interaction, hints, or triggering flows +- **Expression Components**: Components for content display, rich text, chat bubbles, and other expressive uses +- **Confirmation Components**: Interaction components for secondary confirmation and popup confirmation +- **Feedback Components**: Feedback components for messages, notifications, progress, and results +- **Tool Components**: Auxiliary capabilities including forms, layouts, toolbars, and contexts + +The document focuses on property definitions, event handlers, slot systems, state management, message passing, conversation flow control mechanisms, and provides usage patterns and best practices for AI/ML scenarios. + +## Project Structure + +ModelScope Studio's frontend uses a combination of Svelte + Ant Design X, bridging React components into the Svelte ecosystem through a unified adapter layer. The backend Python layer is responsible for exporting component collections for on-demand use in applications. + +```mermaid +graph TB +subgraph "Backend Component Export" +A_init["backend/modelscope_studio/components/__init__.py"] +A_antd_init["backend/modelscope_studio/components/antd/__init__.py"] +A_antdx_init["backend/modelscope_studio/components/antdx/__init__.py"] +A_base_init["backend/modelscope_studio/components/base/__init__.py"] +A_pro_init["backend/modelscope_studio/components/pro/__init__.py"] +end +subgraph "Frontend Adapter Layer" +F_button["frontend/antd/button/button.tsx"] +F_form["frontend/antd/form/form.tsx"] +F_actions["frontend/antdx/actions/actions.tsx"] +F_bubble["frontend/antdx/bubble/bubble.tsx"] +F_conversations["frontend/antdx/conversations/conversations.tsx"] +F_sender["frontend/antdx/sender/sender.tsx"] +end +A_init --> A_antd_init +A_init --> A_antdx_init +A_init --> A_base_init +A_init --> A_pro_init +A_antd_init --> F_button +A_antd_init --> F_form +A_antdx_init --> F_actions +A_antdx_init --> F_bubble +A_antdx_init --> F_conversations +A_antdx_init --> F_sender +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +**Section sources** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) + +## Core Components + +This section provides a quick overview of each component family's key responsibilities and typical use cases for rapid identification and selection. + +- **General Components (Antd)** + - Responsibility: Provide basic UI capabilities such as buttons, inputs, forms, layouts, messages, notifications, etc. + - Typical components: Button, Form, Input, Modal, Message, Notification, etc. + - Feature: Bridges Ant Design's React components as Svelte components via an adapter; supports slots and functional props. + +- **Awakening Components (AntdX)** + - Responsibility: Guide users to their next action, such as action menus, hints, skill toggles, etc. + - Typical components: Actions, Sender, Suggestion, Welcome, etc. + - Feature: Supports complex slots, context injection, event forwarding, and value change integration. + +- **Expression Components (AntdX)** + - Responsibility: For content expression and conversational display, such as bubbles, thought chains, file cards, attachments, etc. + - Typical components: Bubble, ThoughtChain, FileCard, Attachments, Prompts, etc. + - Feature: Supports render functions, editable configuration, header/footer, and extra area slots. + +- **Confirmation Components (AntdX)** + - Responsibility: For secondary confirmation, popup confirmation, and similar interactions. + - Typical components: Popconfirm, Modal (static), Tour, etc. + - Feature: Consistent interaction semantics with AntdX, maintaining a uniform slot and event model. + +- **Feedback Components (AntdX)** + - Responsibility: Messages, notifications, progress, results, and other feedback. + - Typical components: Message, Notification, Progress, Result, etc. + - Feature: Supports slot-based rendering, functional callbacks, and state-driven updates. + +- **Tool Components (AntdX)** + - Responsibility: Auxiliary capabilities for forms, layouts, contexts, and application containers. + - Typical components: Form, Layout, XProvider, Markdown, Slot, etc. + - Feature: Provides contexts, rendering utility functions, and the slot system. + +**Section sources** + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +## Architecture Overview + +The following diagram shows the mapping from backend component exports to the frontend adapter layer to specific components, as well as the processing paths for slots and functional props. + +```mermaid +graph TB +subgraph "Backend Export" +B1["antd/__init__.py
Exports Button/Form etc."] +B2["antdx/__init__.py
Exports Actions/Bubble etc."] +B3["base/__init__.py
Exports Application/Slot etc."] +B4["pro/__init__.py
Exports Chatbot/Monaco etc."] +end +subgraph "Frontend Adapter" +F1["sveltify
Bridges React components"] +F2["Slot System
ReactSlot/renderParamsSlot"] +F3["Functional Props
useFunction/createFunction"] +F4["Context and Menu Items
withItemsContextProvider/useItems"] +end +subgraph "Component Instances" +C1["Button"] +C2["Form"] +C3["Actions"] +C4["Bubble"] +C5["Conversations"] +C6["Sender"] +end +B1 --> F1 --> C1 +B1 --> F1 --> C2 +B2 --> F1 --> C3 +B2 --> F1 --> C4 +B2 --> F1 --> C5 +B2 --> F1 --> C6 +F1 --> F2 +F1 --> F3 +F1 --> F4 +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +## Component Details + +### General Components API (Antd) + +#### Button + +- **Purpose**: Bridges Ant Design's Button as a Svelte component; supports slots and loading icon slots. +- **Key Points** + - Slots: `icon`, `loading.icon` + - Value binding: Intelligent selection between `value` and `children` + - Loading state: `loading` supports object input with configurable delay +- **Usage Notes** + - When slots exist, slot rendering takes priority; otherwise falls back to prop values. + - Uses `useTargets` to handle target nodes in `children`. + +**Section sources** + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) + +#### Form + +- **Purpose**: Bridges Ant Design's Form as a Svelte component; provides controlled value and action sync. +- **Key Points** + - Controlled value: `value` and `onValueChange` + - Action sync: `formAction` (reset/submit/validate) and `onResetFormAction` + - Slots: `requiredMark` + - Callbacks: `onValuesChange` +- **Usage Notes** + - Uses `useEffect` to execute reset/submit/validate based on `formAction`. + - Syncs external `value` to the internal form instance. + +**Section sources** + +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +### Awakening Components API (AntdX) + +#### Actions + +- **Purpose**: Bridges AntdX's Actions as a Svelte component; supports menu items and dropdown render slots. +- **Key Points** + - Slots: `dropdownProps.menu.items`, `dropdownProps.menu.expandIcon`, `dropdownProps.menu.overflowedIndicator`, `dropdownProps.dropdownRender`, `dropdownProps.popupRender` + - Context: Integrates with menu item context, supporting `items`/`default` slots + - Rendering: `renderItems`, `renderParamsSlot`, `createFunction` +- **Usage Notes** + - Prioritizes `items` from slots; falls back to prop `items` if absent. + - Conditionally replaces dropdown render and menu items. + +**Section sources** + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) + +#### Sender + +- **Purpose**: Svelte adapter for AntdX Sender; supports file upload, paste, suggestion context, and slotted header/footer. +- **Key Points** + - Slots: `suffix`, `header`, `prefix`, `footer`, `skill.*` series + - Events: `onSubmit` (fires when suggestion is not open), `onChange`, `onPasteFile` + - Value change: `onValueChange` and `useValueChange` + - Upload: The `upload` function returns an array of file data +- **Usage Notes** + - Calls `upload` when pasting files and returns the path. + - Formats results and customizes rendering via `slotConfig`. + +**Section sources** + +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +### Expression Components API (AntdX) + +#### Bubble + +- **Purpose**: Svelte adapter for AntdX Bubble; supports header/body/footer/extra areas and editable configuration. +- **Key Points** + - Slots: `avatar`, `editable.okText`, `editable.cancelText`, `content`, `footer`, `header`, `extra`, `loadingRender`, `contentRender` + - Functions: `typing`, `contentRender`, `header`/`footer`/`avatar`/`extra`, `editable` +- **Usage Notes** + - Supports boolean `editable` or object configuration; slot content takes priority when slots exist. + - Converts props to functional rendering via `useFunction`. + +**Section sources** + +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) + +#### Conversations + +- **Purpose**: Svelte adapter for AntdX Conversations; supports grouping, menus, and slotted labels. +- **Key Points** + - Slots: `menu.trigger`, `menu.expandIcon`, `menu.overflowedIndicator`, `groupable.label` + - Context: Menu item context and conversation item context + - Rendering: `renderItems`, `patchMenuEvents` (event forwarding) +- **Usage Notes** + - Supports string or object form for `menu` configuration; auto-falls back when no `items`. + - Injects style class names via `classNames`. + +**Section sources** + +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) + +### Confirmation Components API (AntdX) + +- **Popconfirm**: Secondary confirmation popup; supports slotted title and description. +- **Modal (static)**: Static modal dialog; suitable for fixed content display. +- **Tour**: Guided tour; supports steps and slotted rendering. + +[This section is conceptual; no specific file analysis] + +### Feedback Components API (AntdX) + +- **Message**: Message hint; supports slotted content and functional rendering. +- **Notification**: Notification alert; supports slotted rendering and close callbacks. +- **Progress**: Progress bar; supports slotted formatting. +- **Result**: Result page; supports slotted action areas. + +[This section is conceptual; no specific file analysis] + +### Tool Components API (AntdX) + +- **Form**: See "General Components" section. +- **Layout**: Layout container supporting Content/Footer/Header/Sider. +- **XProvider**: Context provider supplying global configuration for AntdX components. +- **Markdown**: Markdown rendering component. +- **Slot**: Slot container for dynamic content mounting. + +**Section sources** + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +## Dependency Analysis + +```mermaid +graph TB +subgraph "Backend Export" +A["components/__init__.py"] +A_antd["antd/__init__.py"] +A_antdx["antdx/__init__.py"] +A_base["base/__init__.py"] +A_pro["pro/__init__.py"] +end +subgraph "Frontend Adapter" +U_render["renderItems/renderParamsSlot"] +U_func["useFunction/createFunction"] +U_slot["ReactSlot"] +U_ctx["withItemsContextProvider/useItems"] +end +subgraph "Components" +C_btn["Button"] +C_form["Form"] +C_act["Actions"] +C_bub["Bubble"] +C_conv["Conversations"] +C_snd["Sender"] +end +A --> A_antd --> C_btn +A --> A_antd --> C_form +A --> A_antdx --> C_act +A --> A_antdx --> C_bub +A --> A_antdx --> C_conv +A --> A_antdx --> C_snd +C_btn -.-> U_render +C_form -.-> U_func +C_act -.-> U_render +C_act -.-> U_ctx +C_bub -.-> U_func +C_bub -.-> U_slot +C_conv -.-> U_render +C_conv -.-> U_ctx +C_snd -.-> U_func +C_snd -.-> U_slot +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +**Section sources** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +## Performance Considerations + +- **Lazy Rendering of Slots and Functional Props** + - Corresponding content is only rendered when slots exist, avoiding unnecessary computation. + - `useMemo` wraps menu and rendering logic to reduce repeated renders. +- **Controlled Value and Action Sync** + - Uses `useEffect` to trigger reset/submit/validate based on `formAction`, avoiding frequent redraws. + - Uses `useValueChange` to manage input value changes, reducing upstream jitter. +- **Event Forwarding and Debouncing** + - Stops DOM event bubbling on `onClick` in menu events to avoid unexpected triggers. + - Uses `useMemoizedFn` to cache callbacks for functional props. + +[This section provides general guidance; no specific file analysis] + +## Troubleshooting Guide + +- **Slot Not Working** + - Check that slot key names match the component's convention (e.g., `menu.items`, `dropdownRender`, etc.). + - Confirm that the slot is not hidden by `children` or not passed correctly. +- **Value Not Synced** + - For Form: Confirm that `value` is correctly passed in and `onValueChange` is being fired. + - For Sender: Confirm the binding of `onValueChange` and `useValueChange`. +- **Dropdown Menu Not Showing** + - Check that `dropdownProps` and `menu.items` are correctly configured. + - Confirm that `withItemsContextProvider` wraps the component. +- **Upload Failing** + - Confirm that the return value of the `upload` function contains a `path` field. + - Check that the path returned by `onPasteFile` is correct. + +**Section sources** + +- [frontend/antd/form/form.tsx:32-53](file://frontend/antd/form/form.tsx#L32-L53) +- [frontend/antdx/sender/sender.tsx:135-138](file://frontend/antdx/sender/sender.tsx#L135-L138) +- [frontend/antdx/actions/actions.tsx:39-96](file://frontend/antdx/actions/actions.tsx#L39-L96) + +## Conclusion + +This document covers the APIs and usage patterns of Ant Design X Svelte components in ModelScope Studio, focusing on key mechanisms such as the slot system, functional props, context and menu item integration, value change and action sync. For AI/ML scenarios, it is recommended to prioritize Sender, Bubble, Conversations, and Actions for building conversation and expression flows, using slots and functional props to achieve highly customized content rendering and interaction behaviors. + +## Appendix + +### Component Instantiation and Configuration (AI/ML Scenario Recommendations) + +- **Conversation Flow** + - Use Sender as the input entry; configure `upload` to support multimodal input. + - Use Bubble to render response content; enable `editable` when secondary editing is needed. + - Use Conversations to manage the conversation list; combine `menu` and `groupable` for grouping and operations. +- **Form and Validation** + - Use Form for controlled value and action sync; combine reset/submit/validate for flow control. +- **Actions and Guidance** + - Use Actions for context menus and guidance items; combine slots for custom rendering. + +[This section is conceptual; no specific file analysis] diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Awakening Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Awakening Components API.md new file mode 100644 index 00000000..1c62f5ae --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Awakening Components API.md @@ -0,0 +1,348 @@ +# Awakening Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/welcome/__init__.py](file://backend/modelscope_studio/components/antdx/welcome/__init__.py) +- [backend/modelscope_studio/components/antdx/prompts/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/__init__.py) +- [frontend/antdx/welcome/Index.svelte](file://frontend/antdx/welcome/Index.svelte) +- [frontend/antdx/welcome/welcome.tsx](file://frontend/antdx/welcome/welcome.tsx) +- [frontend/antdx/prompts/Index.svelte](file://frontend/antdx/prompts/Index.svelte) +- [frontend/antdx/prompts/prompts.tsx](file://frontend/antdx/prompts/prompts.tsx) +- [frontend/antdx/prompts/context.ts](file://frontend/antdx/prompts/context.ts) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Ant Design X Awakening Components API reference for ModelScope Studio, focusing on the following two components: + +- Welcome Component (AntdXWelcome): Used to display welcome messages on the first load or in specific scenarios, supporting slot-based configuration for title, description, icon, and extra content. +- Prompts Component (AntdXPrompts): Used to display a set of clickable prompt cards, supporting configuration for title, vertical layout, fade-in animation, line wrapping, etc., and providing an item click event callback. + +This document provides an in-depth analysis of system architecture, component relationships, data flow, processing logic, integration points, error handling, and performance characteristics, as well as lifecycle hooks, event handling, state management mechanisms, TypeScript type definitions, and interface specifications, helping developers build smooth first-time experiences and prompt guidance in AI applications. + +## Project Structure + +ModelScope Studio's frontend adopts the Svelte + Ant Design X component system, with the backend bridging frontend components via Python components. The Welcome and Prompts components are located in the `antdx` module; backend components handle property passing and event binding, while frontend components handle rendering and interaction. + +```mermaid +graph TB +subgraph "Backend" +B_Welcome["AntdXWelcome
Python Component"] +B_Prompts["AntdXPrompts
Python Component"] +end +subgraph "Frontend" +F_Welcome["welcome/Index.svelte
Renderer"] +F_Welcome_TSX["welcome/welcome.tsx
Component Implementation"] +F_Prompts["prompts/Index.svelte
Renderer"] +F_Prompts_TSX["prompts/prompts.tsx
Component Implementation"] +F_Prompts_Context["prompts/context.ts
Context"] +end +B_Welcome --> F_Welcome +F_Welcome --> F_Welcome_TSX +B_Prompts --> F_Prompts +F_Prompts --> F_Prompts_TSX +F_Prompts_TSX --> F_Prompts_Context +``` + +**Chart Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) +- [frontend/antdx/welcome/Index.svelte:1-72](file://frontend/antdx/welcome/Index.svelte#L1-L72) +- [frontend/antdx/welcome/welcome.tsx](file://frontend/antdx/welcome/welcome.tsx) +- [frontend/antdx/prompts/Index.svelte:1-71](file://frontend/antdx/prompts/Index.svelte#L1-L71) +- [frontend/antdx/prompts/prompts.tsx](file://frontend/antdx/prompts/prompts.tsx) +- [frontend/antdx/prompts/context.ts](file://frontend/antdx/prompts/context.ts) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:1-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:1-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L1-L88) +- [frontend/antdx/welcome/Index.svelte:1-72](file://frontend/antdx/welcome/Index.svelte#L1-L72) +- [frontend/antdx/prompts/Index.svelte:1-71](file://frontend/antdx/prompts/Index.svelte#L1-L71) + +## Core Components + +This section provides an overview of the key responsibilities and capability boundaries of the two components: + +- Welcome Component (AntdXWelcome) + - Responsibility: Display welcome messages, supporting multiple slots (title, description, icon, extra content) with optional styles and variants. + - Key Points: Does not expose standard API (`skip_api` is true); implemented via slots and static resource path injection. +- Prompts Component (AntdXPrompts) + - Responsibility: Display a set of prompt cards, supporting title, vertical layout, fade-in animation, line wrapping, etc.; provides an item click event callback. + - Key Points: Internally nested item components; event binding is configured via `EventListener`. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) + +## Architecture Overview + +The diagram below shows the call chain from backend components to frontend renderers to specific component implementations, as well as the event binding and slot passing mechanism. + +```mermaid +sequenceDiagram +participant Py as "Python Backend Component" +participant Svelte as "Svelte Renderer" +participant TSX as "TSX Component Implementation" +Py->>Py : "Initialize component properties and events" +Py->>Svelte : "Pass props and visibility control" +Svelte->>TSX : "Dynamically import and render component" +TSX-->>Svelte : "Render complete, await slot content" +Svelte-->>Py : "Event callback binding (e.g., item_click)" +``` + +**Chart Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:55-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L55-L73) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:70-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L70-L88) +- [frontend/antdx/welcome/Index.svelte:10-72](file://frontend/antdx/welcome/Index.svelte#L10-L72) +- [frontend/antdx/prompts/Index.svelte:10-71](file://frontend/antdx/prompts/Index.svelte#L10-L71) + +## Detailed Component Analysis + +### Welcome Component (AntdXWelcome) + +- Component Purpose: Used for first-time experience or onboarding scenarios, carrying title, description, icon, and extra content. +- Slot Support: `extra`, `icon`, `description`, `title`. +- Properties and Behavior: + - Supports additional properties `additional_props`, styles `styles`/`class_names`, and root class name `root_class_name`. + - The `icon` parameter is processed through static asset service (`serve_static_file`). + - Does not expose standard API (`skip_api` is true); suitable for use through slot and static resource combinations. +- Lifecycle and Hooks: + - `preprocess`/`postprocess`/`example_payload`/`example_value` all return null, indicating this component does not participate in regular data flow transformation. +- Typical Use Cases: + - Welcome pages after app startup, new user onboarding, feature entry hints, etc. + +```mermaid +classDiagram +class AntdXWelcome { ++EVENTS : list ++SLOTS : list ++additional_props : dict|None ++extra : str|None ++icon : str|None ++styles : dict|str|None ++class_names : dict|str|None ++description : str|None ++variant : "filled"| "borderless"| None ++title : str|None ++root_class_name : str|None ++skip_api() : bool ++preprocess(payload) : None ++postprocess(value) : None ++example_payload() : None ++example_value() : None +} +``` + +**Chart Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) +- [frontend/antdx/welcome/Index.svelte:1-72](file://frontend/antdx/welcome/Index.svelte#L1-L72) +- [frontend/antdx/welcome/welcome.tsx](file://frontend/antdx/welcome/welcome.tsx) + +### Prompts Component (AntdXPrompts) + +- Component Purpose: Display a set of prompt cards, supporting title, vertical layout, fade-in animation, line wrapping, etc. +- Internal Structure: + - Nested item component: `AntdXPrompts.Item`. + - Events: `item_click` (triggered when a prompt item is clicked). +- Properties and Behavior: + - `items`: List of prompt items (array of dicts). + - Styles and layout: `prefix_cls`, `vertical`, `fade_in`, `fade_in_left`, `wrap`. + - Supports `additional_props`, `styles`, `class_names`, `root_class_name`. + - Does not expose standard API (`skip_api` is true). +- Event Handling: + - Maps click events to internal state updates (`bind_itemClick_event`) via `EventListener("item_click")`. + +```mermaid +classDiagram +class AntdXPrompts { ++Item : AntdXPromptsItem ++EVENTS : list ++SLOTS : list ++items : list[dict]|None ++prefix_cls : str|None ++title : str|None ++vertical : bool|None ++fade_in : bool|None ++fade_in_left : bool|None ++wrap : bool|None ++styles : dict|str|None ++class_names : dict|str|None ++root_class_name : str|None ++skip_api() : bool ++preprocess(payload) : None ++postprocess(value) : None ++example_payload() : Any ++example_value() : Any +} +class AntdXPromptsItem { ++... item-level properties and behavior ... +} +AntdXPrompts --> AntdXPromptsItem : "contains" +``` + +**Chart Sources** + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) +- [frontend/antdx/prompts/Index.svelte:1-71](file://frontend/antdx/prompts/Index.svelte#L1-L71) +- [frontend/antdx/prompts/prompts.tsx](file://frontend/antdx/prompts/prompts.tsx) +- [frontend/antdx/prompts/context.ts](file://frontend/antdx/prompts/context.ts) + +### Component Rendering and Event Binding Flow + +The following sequence diagram shows how backend components bind events and render components through frontend renderers. + +```mermaid +sequenceDiagram +participant Backend as "Backend Component" +participant Renderer as "Svelte Renderer" +participant Frontend as "TSX Component" +Backend->>Renderer : "Pass component properties and event configuration" +Renderer->>Frontend : "Dynamically import and render" +Frontend-->>Renderer : "Register event listeners (e.g., item_click)" +Renderer-->>Backend : "Event callbacks take effect" +``` + +**Chart Sources** + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) +- [frontend/antdx/prompts/Index.svelte:10-71](file://frontend/antdx/prompts/Index.svelte#L10-L71) + +## Dependency Analysis + +- Component Base Class and Utilities: + - All components inherit from `ModelScopeLayoutComponent`, uniformly handling visibility, element ID/classes, styles, and render switches. + - Frontend directory resolution is done via `resolve_frontend_dir`, ensuring correct mapping between Python backend and Svelte frontend. +- Inter-component Coupling: + - The Welcome and Prompts components are independent UI components with no direct dependency on each other. + - The Prompts component's internal item component interacts with the context, but is still exposed externally as a whole component. + +```mermaid +graph LR +Base["ModelScopeLayoutComponent
Component Base Class"] --> Welcome["AntdXWelcome"] +Base --> Prompts["AntdXPrompts"] +Resolve["resolve_frontend_dir
Frontend Directory Resolution"] --> Welcome +Resolve --> Prompts +``` + +**Chart Sources** + +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:55-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L55-L55) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:70-70](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L70-L70) + +**Section Sources** + +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:55-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L55-L55) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:70-70](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L70-L70) + +## Performance Considerations + +- Rendering Strategy + - Components are rendered via dynamic import, avoiding first-screen blocking and improving initial load performance. +- Event Binding + - Events are only bound when needed, and unnecessary re-renders are reduced through internal state updates. +- Resource Handling + - Static resources such as icons are handled via `serve_static_file`; caching and preloading are recommended for optimizing user experience. + +[This section provides general guidance and requires no specific file sources] + +## Troubleshooting Guide + +- Component Not Displaying + - Check whether `visible`, `elem_id`, `elem_classes`, `elem_style` are correctly set. + - Confirm the render switch `render` is true. +- Slot Content Not Taking Effect + - Confirm slot names match the component's supported `SLOTS` list (Welcome: `extra`, `icon`, `description`, `title`; Prompts: `title`, `items`). +- Event Not Firing + - Confirm event listeners are correctly configured (Prompts component's `item_click`). +- Icon or Static Resources Cannot Load + - Confirm the `icon` path is valid and `serve_static_file` is working properly. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:14-15](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L14-L15) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:25-26](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L25-L26) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) + +## Conclusion + +AntdXWelcome and AntdXPrompts serve as the core components for "welcome onboarding" and "prompt guidance" respectively in ModelScope Studio. The former achieves flexible welcome page display through slots and static resources; the latter provides efficient prompt word guidance through item click events and layout configuration. Both use dynamic rendering and event binding mechanisms, with good extensibility and maintainability. Combined with the type definitions, interface specifications, and best practices provided in this document, developers can quickly build consistent and smooth first-time experience and prompt guidance flows in AI applications. + +[This section is a summary and requires no specific file sources] + +## Appendix + +### TypeScript Type Definitions and Interface Specifications + +- Welcome Component (AntdXWelcome) + - Supported Properties: `additional_props`, `extra`, `icon`, `styles`, `class_names`, `description`, `variant`, `title`, `root_class_name`, `as_item`, `visible`, `elem_id`, `elem_classes`, `elem_style`, `render`. + - Slots: `extra`, `icon`, `description`, `title`. + - Events: None. + - Lifecycle Hooks: `preprocess`/`postprocess`/`example_payload`/`example_value` return null. +- Prompts Component (AntdXPrompts) + - Supported Properties: `items`, `prefix_cls`, `title`, `vertical`, `fade_in`, `fade_in_left`, `wrap`, `styles`, `class_names`, `root_class_name`, `additional_props`, `as_item`, `visible`, `elem_id`, `elem_classes`, `elem_style`, `render`. + - Slots: `title`, `items`. + - Events: `item_click` (triggered when a prompt item is clicked). + - Lifecycle Hooks: `preprocess`/`postprocess`/`example_payload`/`example_value` return null. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:17-54](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L17-L54) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:14-15](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L14-L15) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:61-69](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L61-L69) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:28-68](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L28-L68) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:25-26](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L25-L26) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:76-87](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L76-L87) + +### Integration with Conversation Systems + +- The Prompts component can serve as a guidance layer before conversation input; after the user clicks a prompt item, the upper-level business logic injects the prompt content into the conversation input field or directly initiates a conversation request. +- The Welcome component can serve as the entry point hint for a conversation session, deciding whether to display it based on context state. + +[This section is a conceptual explanation and requires no specific file sources] + +### Best Practices + +- Welcome Component + - Use slots to organize title, description, and icon for clear visual hierarchy. + - For multilingual scenarios, pass `title` and `description` through an external copy management module. +- Prompts Component + - Set `vertical`, `fade_in`, `fade_in_left`, `wrap` appropriately to adapt to different screen sizes and interaction paces. + - Provide clear semantic labels for each prompt item to facilitate accessibility and SEO. +- Event Handling + - Perform the minimum necessary operations in the `item_click` callback (such as writing the prompt content to the input field) to avoid blocking the UI. +- State Management + - Decouple the visibility of the Prompts collection from the current conversation state, allowing reuse across different pages or views. + +[This section provides general guidance and requires no specific file sources] diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Confirmation Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Confirmation Components API.md new file mode 100644 index 00000000..2fb63a41 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Confirmation Components API.md @@ -0,0 +1,331 @@ +# Confirmation Components API + + +**Files Referenced in This Document** +- [thought_chain/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py) +- [think/__init__.py](file://backend/modelscope_studio/components/antdx/think/__init__.py) +- [thought-chain.tsx](file://frontend/antdx/thought-chain/thought-chain.tsx) +- [think.tsx](file://frontend/antdx/think/think.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Ant Design X Confirmation Components API reference for ModelScope Studio, focusing on the complete interface and behavioral specifications of the ThoughtChain component and the Think component. Content includes: + +- Component property, event, and slot definitions +- Visualization and node management mechanisms for the thinking process +- Confirmation flow control and state management +- Integration recommendations for AI reasoning processes and decision display scenarios +- TypeScript type and interface specifications +- Best practices and common issue troubleshooting + +## Project Structure + +Ant Design X components are wrapped by Python component packages on the backend and bridged to the native `@ant-design/x` implementation on the frontend via Svelte/React hybrid bridging. Core file organization: + +- Backend Python wrapper: Located under `backend/modelscope_studio/components/antdx`, providing Python component classes for ThoughtChain and Think respectively +- Frontend implementation: Located under `frontend/antdx`, providing TSX implementations for `thought-chain` and `think` respectively + +```mermaid +graph TB +subgraph "Backend" +PY_TC["AntdXThoughtChain
Python Component"] +PY_TH["AntdXThink
Python Component"] +end +subgraph "Frontend" +FE_TC["ThoughtChain
TSX Implementation"] +FE_TH["Think
TSX Implementation"] +end +subgraph "Third-Party Libraries" +ADX["@ant-design/x
Native Component Library"] +end +PY_TC --> FE_TC +PY_TH --> FE_TH +FE_TC --> ADX +FE_TH --> ADX +``` + +Chart Sources + +- [thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +Section Sources + +- [thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +## Core Components + +This section provides an overview of the responsibilities and capability boundaries of the two core components: + +- ThoughtChain: Used to visually display a sequence of reasoning or decision-making nodes in tree/list form, supporting expand/collapse, connector styles, and node collection management +- Think: Used to encapsulate a single thought unit, supporting title, icon, loading state, and expandable state, with slot extension points + +Section Sources + +- [thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) + +## Architecture Overview + +The diagram below shows the call chain from backend Python components to frontend TSX implementations to `@ant-design/x` native components. + +```mermaid +sequenceDiagram +participant PyTC as "Backend : AntdXThoughtChain" +participant PyTH as "Backend : AntdXThink" +participant FETC as "Frontend : ThoughtChain" +participant FETH as "Frontend : Think" +participant ADX as "@ant-design/x" +PyTC->>FETC : Render ThoughtChain component +FETC->>ADX : Render using XThoughtChain +PyTH->>FETH : Render Think component +FETH->>ADX : Render using XThink +``` + +Chart Sources + +- [thought_chain/**init**.py:68-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L68-L86) +- [think/**init**.py:61-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L61-L79) +- [thought-chain.tsx:11-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L43) +- [think.tsx:6-24](file://frontend/antdx/think/think.tsx#L6-L24) + +## Detailed Component Analysis + +### ThoughtChain Component + +- Component Purpose: Used to present "thought chain"-style data flows or decision sequences, supporting node collections (`items`), expanded keys (`expanded_keys`), default expanded keys (`default_expanded_keys`), connector styles (`line`), etc. +- Slots: Supports `items` slot for injecting node collections +- Events: `expand` event, triggered when expanded keys change +- Property Notes: + - `expanded_keys` / `default_expanded_keys`: Control node expand state + - `items`: Node data collection, can be passed via slot or property + - `line`: Connector style, supports boolean values and specific string enumerations + - `prefix_cls` / `styles` / `class_names` / `root_class_name`: Style and class name customization + - Other general properties: `visible`, `elem_id`, `elem_classes`, `elem_style`, `render`, etc. + +```mermaid +classDiagram +class AntdXThoughtChain { ++expanded_keys : list[str] | None ++default_expanded_keys : list[str] | None ++items : list[dict] | None ++line : bool | "solid" | "dashed" | "dotted" | None ++prefix_cls : str | None ++additional_props : dict | None ++styles : dict | str | None ++class_names : dict | str | None ++root_class_name : str | None ++EVENTS : ["expand"] ++SLOTS : ["items"] ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +``` + +Chart Sources + +- [thought_chain/**init**.py:30-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L30-L86) + +Section Sources + +- [thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [thought-chain.tsx:11-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L43) + +### Think Component + +- Component Purpose: Used to encapsulate a single thought unit, supporting title (`title`), icon (`icon`), loading state (`loading`), default expanded (`default_expanded`), current expanded (`expanded`), and blink (`blink`), etc. +- Slots: Supports `loading`, `icon`, and `title` slots for custom rendering +- Events: `expand` event, for expanded state change notifications +- Property Notes: + - `icon` / `title` / `loading`: Basic display properties + - `default_expanded` / `expanded`: Expand state control + - `blink`: Visual indicator + - Other general properties: `visible`, `elem_id`, `elem_classes`, `elem_style`, `render`, etc. + +```mermaid +classDiagram +class AntdXThink { ++additional_props : dict | None ++icon : str | None ++styles : dict | str | None ++class_names : dict | str | None ++loading : str | bool | None ++title : str | None ++root_class_name : str | None ++default_expanded : bool | None ++expanded : bool | None ++blink : bool | None ++EVENTS : ["expand"] ++SLOTS : ["loading","icon","title"] ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +``` + +Chart Sources + +- [think/**init**.py:21-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L21-L79) + +Section Sources + +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [think.tsx:6-24](file://frontend/antdx/think/think.tsx#L6-L24) + +### Frontend Implementation and Slot Mechanism + +- The ThoughtChain frontend implementation reads slot `items`/`default` via context and clones nodes when necessary to avoid side effects; finally passes the parsed `items` to `@ant-design/x`'s `XThoughtChain` +- The Think frontend implementation injects `slots.loading`/`icon`/`title` into `@ant-design/x`'s `XThink` via `ReactSlot`; falls back to property values if no slot is provided + +```mermaid +flowchart TD +Start(["Enter ThoughtChain Render"]) --> ReadSlot["Read slots items/default"] +ReadSlot --> HasItems{"Does slot items exist and is non-empty?"} +HasItems -- Yes --> UseItems["Use slot items"] +HasItems -- No --> UseDefault["Use slot default"] +UseItems --> Clone["Optional: clone nodes"] +UseDefault --> Clone +Clone --> RenderADX["Render XThoughtChain with items"] +RenderADX --> End(["Done"]) +``` + +Chart Sources + +- [thought-chain.tsx:14-39](file://frontend/antdx/thought-chain/thought-chain.tsx#L14-L39) + +Section Sources + +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [think.tsx:6-24](file://frontend/antdx/think/think.tsx#L6-L24) + +## Dependency Analysis + +- Backend Python components are only responsible for declaring properties, events, slots, and frontend directory mappings; they do not directly handle business logic +- Frontend TSX components are responsible for: + - Parsing slots and properties, merging them into the props required by `@ant-design/x` + - Bridging to the React ecosystem via `sveltify` +- Third-party library `@ant-design/x` provides the actual UI behavior and styles + +```mermaid +graph LR +PY["Backend Python Component"] --> FE["Frontend TSX Component"] +FE --> ADX["@ant-design/x"] +``` + +Chart Sources + +- [thought_chain/**init**.py:68-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L68-L86) +- [think/**init**.py:61-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L61-L79) +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +Section Sources + +- [thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +## Performance Considerations + +- Node Cloning: The frontend clones slot nodes when necessary to avoid side effects from shared references, but this increases memory and computation overhead. Use with caution when the number of nodes is large +- Slot Parsing: Prioritize using the `items` slot, falling back to the `default` slot, to reduce unnecessary property passing +- Expand State: Set `expanded_keys`/`default_expanded_keys` appropriately to avoid expanding too many nodes at once, which causes rendering pressure +- Loading State: The Think component's `loading` slot/property should be enabled on demand to avoid redundant animations and DOM structure + +## Troubleshooting Guide + +- Slot Not Taking Effect + - Check whether the `items`/`default` slot is used correctly; confirm slot name casing and ordering + - If using the `items` property, ensure the type matches `@ant-design/x`'s expectations +- Expand Event Not Working + - Confirm the `expand` event is bound; check whether `bind_expand_event` or related state is updated in the callback +- Loading State and Slot Conflict + - When a `loading` slot is provided, the slot takes priority over the property; if no slot is provided, it falls back to the property value +- Styles and Class Names + - To override styles, prefer using `styles`/`class_names`/`root_class_name`; watch for conflicts with the third-party library's default styles + +Section Sources + +- [thought-chain.tsx:14-39](file://frontend/antdx/thought-chain/thought-chain.tsx#L14-L39) +- [think.tsx:10-17](file://frontend/antdx/think/think.tsx#L10-L17) +- [thought_chain/**init**.py:20-25](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L20-L25) +- [think/**init**.py:12-16](file://backend/modelscope_studio/components/antdx/think/__init__.py#L12-L16) + +## Conclusion + +- ThoughtChain and Think components provide a stable foundation for visualizing AI reasoning and decision-making processes through their clear property, event, and slot design +- For large-scale node scenarios, it is recommended to optimize slot usage and expand strategies, combining loading states and style customization to enhance the user experience +- Through `expand` events and expand state control, interactive confirmation flows and step-by-step displays can be implemented + +## Appendix + +### API Specifications and Type Definitions (Based on Source Code) + +- AntdXThoughtChain + - Properties + - `expanded_keys`: List, node expand keys + - `default_expanded_keys`: List, initial expand keys + - `items`: List, node data + - `line`: Boolean or specific string, connector style + - `prefix_cls`: String, prefix class name + - `additional_props`/`styles`/`class_names`/`root_class_name`: Style and class name customization + - `visible`/`elem_id`/`elem_classes`/`elem_style`/`render`: General properties + - Events + - `expand`: Expand key change callback + - Slots + - `items`: Node collection +- AntdXThink + - Properties + - `icon`/`title`/`loading`: Icon, title, loading state + - `default_expanded`/`expanded`: Default/current expand state + - `blink`: Blink effect + - `styles`/`class_names`/`root_class_name`: Style and class name customization + - `visible`/`elem_id`/`elem_classes`/`elem_style`/`render`: General properties + - Events + - `expand`: Expand state change callback + - Slots + - `loading`/`icon`/`title`: Slot alternatives to the corresponding properties + +Section Sources + +- [thought_chain/**init**.py:30-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L30-L86) +- [think/**init**.py:21-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L21-L79) + +### Integration and Best Practices + +- Reasoning Process Visualization + - Use ThoughtChain to display multi-step reasoning/decision sequences; each Think represents a single thought unit + - Control step-by-step display via `expand`, combined with the `loading` slot to indicate thinking in progress +- User Understanding Optimization + - Use the `line` connector style and `prefix_cls` appropriately to enhance hierarchical sense + - Use `icon`/`title` in Think to clarify roles and intent; use `blink` when attention is needed +- State Management and Flow Control + - Manage node expansion via `expanded_keys`/`default_expanded_keys`; drive subsequent steps via `expand` events + - For long chains, consider pagination/segmented loading to avoid rendering too many nodes at once diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Expression Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Expression Components API.md new file mode 100644 index 00000000..0c2f2b76 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Expression Components API.md @@ -0,0 +1,344 @@ +# Expression Components API + + +**Files Referenced in This Document** +- [frontend/antdx/attachments/Index.svelte](file://frontend/antdx/attachments/Index.svelte) +- [frontend/antdx/attachments/attachments.tsx](file://frontend/antdx/attachments/attachments.tsx) +- [frontend/antdx/sender/Index.svelte](file://frontend/antdx/sender/Index.svelte) +- [frontend/antdx/sender/sender.tsx](file://frontend/antdx/sender/sender.tsx) +- [frontend/antdx/suggestion/Index.svelte](file://frontend/antdx/suggestion/Index.svelte) +- [frontend/antdx/suggestion/suggestion.tsx](file://frontend/antdx/suggestion/suggestion.tsx) +- [frontend/antdx/suggestion/context.ts](file://frontend/antdx/suggestion/context.ts) +- [frontend/antdx/file-card/base.tsx](file://frontend/antdx/file-card/base.tsx) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/hooks/useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [docs/components/antdx/attachments/README.md](file://docs/components/antdx/attachments/README.md) +- [docs/components/antdx/sender/README.md](file://docs/components/antdx/sender/README.md) +- [docs/components/antdx/suggestion/README.md](file://docs/components/antdx/suggestion/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for Ant Design X Expression Components in ModelScope Studio, focusing on the following three components: + +- Attachments Component: For displaying and uploading files/images and other attachments in multimodal input +- Sender Component: For chat message input, quick command triggering, and paste upload +- Suggestion Component: For providing selectable suggestion items within an input field + +The document covers component property interfaces, event callbacks, data binding, state synchronization, TypeScript type definitions, integration with the chat system, and best practices for multimodal data processing and user input optimization. + +## Project Structure + +- Components are organized with a Svelte wrapper layer (`Index.svelte`) + React implementation layer (`*.tsx`), bridging Ant Design X React components as Svelte components via `svelte-preprocess-react`. +- The Attachments component supports custom placeholder images, preview containers, icon rendering, list item rendering, and other slot extensions; the Sender component supports prefix/suffix/header/footer slots, skill panels, and paste upload; the Suggestion component supports dynamic item rendering and keyboard trigger control. + +```mermaid +graph TB +subgraph "Svelte Wrapper Layer" +A_Index["attachments/Index.svelte"] +B_Index["sender/Index.svelte"] +C_Index["suggestion/Index.svelte"] +end +subgraph "React Implementation Layer" +A_Impl["attachments.tsx"] +B_Impl["sender.tsx"] +C_Impl["suggestion.tsx"] +end +A_Index --> A_Impl +B_Index --> B_Impl +C_Index --> C_Impl +``` + +Chart Sources + +- [frontend/antdx/attachments/Index.svelte:1-98](file://frontend/antdx/attachments/Index.svelte#L1-L98) +- [frontend/antdx/sender/Index.svelte:1-102](file://frontend/antdx/sender/Index.svelte#L1-L102) +- [frontend/antdx/suggestion/Index.svelte:1-75](file://frontend/antdx/suggestion/Index.svelte#L1-L75) +- [frontend/antdx/attachments/attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) +- [frontend/antdx/suggestion/suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) + +Section Sources + +- [frontend/antdx/attachments/Index.svelte:1-98](file://frontend/antdx/attachments/Index.svelte#L1-L98) +- [frontend/antdx/sender/Index.svelte:1-102](file://frontend/antdx/sender/Index.svelte#L1-L102) +- [frontend/antdx/suggestion/Index.svelte:1-75](file://frontend/antdx/suggestion/Index.svelte#L1-L75) + +## Core Components + +- Attachments Component + - Responsibility: Display and manage attachment lists, supporting drag-and-drop/click upload, count limits, placeholder images, preview configuration, custom rendering, and icon slots. + - Key Properties: `items`, `maxCount`, `placeholder`, `imageProps`, `showUploadList`, `beforeUpload`, `customRequest`, `isImageUrl`, `itemRender`, `iconRender`, `getDropContainer`, `progress`, `onChange`/`onValueChange`, `upload`. + - Data Flow: Receives `items` and maintains a local `fileList`; `onChange`/`onValueChange` syncs external values; the `upload` callback handles file uploading and backfills `uid`. +- Sender Component + - Responsibility: Chat input field supporting text input, paste upload, quick command panel, prefix/suffix and header/footer slots, submission interception, and coordination. + - Key Properties: `value`, `onValueChange`, `onChange`, `onSubmit`, `suffix`/`header`/`prefix`/`footer`, `skill`, `slotConfig`, `onPasteFile`, `upload`. + - Data Flow: Uses `useValueChange` to sync external `value`; when the quick command panel is open, `onSubmit` is not triggered; when pasting files, file path arrays are obtained via `upload`. +- Suggestion Component + - Responsibility: Provides selectable suggestion items within an input field, supporting dynamic `items` rendering, slot extensions, keyboard trigger control, and popup container configuration. + - Key Properties: `items`, `open`, `onOpenChange`, `getPopupContainer`, `shouldTrigger`, `children` slot. + - Data Flow: Maintains `open` state internally; merges `items` from slots and props; shares state with subtree via `SuggestionOpenContext`. + +Section Sources + +- [frontend/antdx/attachments/attachments.tsx:36-410](file://frontend/antdx/attachments/attachments.tsx#L36-L410) +- [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) +- [frontend/antdx/suggestion/suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) + +## Architecture Overview + +The diagram below shows the bridging relationship and data flow between the three components across Svelte and React layers. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Wrapper Layer" +participant ReactImpl as "React Implementation Layer" +participant Gradio as "Gradio Client" +Svelte->>ReactImpl : Pass props/slots/callbacks +ReactImpl->>ReactImpl : useFunction/useValueChange handles function and value sync +ReactImpl->>Gradio : upload callback for file upload +Gradio-->>ReactImpl : Returns FileData list +ReactImpl-->>Svelte : Triggers onValueChange/onChange +Svelte-->>Svelte : updateProps updates value +``` + +Chart Sources + +- [frontend/antdx/attachments/Index.svelte:77-92](file://frontend/antdx/attachments/Index.svelte#L77-L92) +- [frontend/antdx/sender/Index.svelte:71-78](file://frontend/antdx/sender/Index.svelte#L71-L78) +- [frontend/antdx/attachments/attachments.tsx:329-348](file://frontend/antdx/attachments/attachments.tsx#L329-L348) +- [frontend/antdx/sender/sender.tsx:135-138](file://frontend/antdx/sender/sender.tsx#L135-L138) + +## Detailed Component Analysis + +### Attachments Component + +- Types and Interfaces + - Exported types: Based on `@ant-design/x`'s `AttachmentsProps`, with additional declarations for `onValueChange`, `onChange`, `upload`, `items`, etc. + - Supported slot keys: `showUploadList.extra`, `showUploadList.previewIcon`, `showUploadList.removeIcon`, `showUploadList.downloadIcon`, `iconRender`, `itemRender`, `placeholder`, `placeholder.title`, `placeholder.description`, `placeholder.icon`, `imageProps.placeholder`, `imageProps.preview.mask`, `imageProps.preview.closeIcon`, `imageProps.preview.toolbarRender`, `imageProps.preview.imageRender`. +- Upload Flow + - In `onChange`, distinguishes between add/remove operations: on add, executes `beforeUpload` first, then calls `upload` to get `FileData`, merges into `fileList`, and finally triggers `onValueChange`. + - On remove, if not currently uploading, triggers `onRemove` and updates the value. +- Configuration Notes + - `maxCount` controls single/multi-file upload strategy. + - `imageProps.preview` supports custom `mask`/`closeIcon`/`toolbarRender`/`imageRender`, or completely disables preview. + - `placeholder` supports object-based configuration combined with slots. + - `showUploadList` supports object-based configuration combined with slots, injecting `downloadIcon`/`removeIcon`/`previewIcon`/`extra` separately. +- Events and State + - `onValueChange`: Returns `FileData[]`, for external value binding. + - `onChange`: Returns string path arrays, for downstream processing by path. + - `upload`: `Promise<(FileData|null)[]>`, must preserve the original file `uid` for subsequent matching. + +```mermaid +flowchart TD +Start(["Start"]) --> Change["Listen to onChange event"] +Change --> IsRemove{"Is this a remove operation?"} +IsRemove --> |Yes| RemoveLogic["Trigger onRemove
Update fileList
Trigger onValueChange/onChange"] +IsRemove --> |No| AddLogic["Execute beforeUpload
Check maxCount and upload status
Call upload to get FileData
Merge into fileList
Trigger onValueChange/onChange"] +RemoveLogic --> End(["End"]) +AddLogic --> End +``` + +Chart Sources + +- [frontend/antdx/attachments/attachments.tsx:275-354](file://frontend/antdx/attachments/attachments.tsx#L275-L354) + +Section Sources + +- [frontend/antdx/attachments/attachments.tsx:36-410](file://frontend/antdx/attachments/attachments.tsx#L36-L410) +- [frontend/antdx/attachments/Index.svelte:72-92](file://frontend/antdx/attachments/Index.svelte#L72-L92) + +### Sender Component + +- Types and Interfaces + - Exported types: Based on `@ant-design/x`'s `SenderProps`, with additional declarations for `onValueChange`, `upload`, `onPasteFile`, etc. + - Slot keys: `suffix`, `header`, `prefix`, `footer`, `skill.title`, `skill.toolTip.title`, `skill.closable.closeIcon`. + - `slotConfig`: Supports `formatResult`/`customRender` function wrapping. +- Submission Flow + - `onSubmit` is intercepted: when the quick command panel is open, submission is blocked to avoid accidental triggers. + - `onChange` syncs the internal `value` and triggers the external `onChange`. +- Paste Upload + - `onPasteFile`: Reads clipboard files, calls `upload` to get a `FileData` array, and passes the path array back to `onPasteFile`. +- Events and State + - `onValueChange`: When the external `value` changes, `useValueChange` syncs the internal state. + - `onChange`: Real-time change notification. + - `upload`: `Promise`, used for paste upload and external extensions. + +```mermaid +sequenceDiagram +participant User as "User" +participant Sender as "Sender" +participant Sugg as "Suggestion" +participant Gradio as "Gradio Client" +User->>Sender : Input / paste file +Sender->>Sugg : Check open state +alt Quick command panel is open +Sender-->>User : Block onSubmit +else Quick command panel is closed +Sender->>Gradio : Call upload(files) +Gradio-->>Sender : Returns FileData[] +Sender-->>User : Trigger onPasteFile(paths) +end +``` + +Chart Sources + +- [frontend/antdx/sender/sender.tsx:126-138](file://frontend/antdx/sender/sender.tsx#L126-L138) +- [frontend/antdx/suggestion/suggestion.tsx:135-140](file://frontend/antdx/suggestion/suggestion.tsx#L135-L140) + +Section Sources + +- [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) +- [frontend/antdx/sender/Index.svelte:71-78](file://frontend/antdx/sender/Index.svelte#L71-L78) + +### Suggestion Component + +- Types and Interfaces + - Exported types: Based on `@ant-design/x`'s `SuggestionProps`, with additional `shouldTrigger` and `children` slot declarations. + - Internal context: `SuggestionContext`/`SuggestionOpenContext`, passes trigger logic and `open` state to the subtree. + - Context items: `withItemsContextProvider` injects `items`/`default`, supporting merging of slots and props. +- Trigger Mechanism + - `shouldTrigger`: Allows custom keyboard event trigger logic, combined with `onTrigger`/`onKeyDown`. + - `open`/`onOpenChange`: Controlled/uncontrolled mode switching, defaults to `false` internally. +- Slots and Rendering + - `children` slot: Acts as the render container, rendered with `ReactSlot`. + - `items`: Supports functional and static arrays; internally extends sub-item `extra`/`icon`/`label`, etc. via `renderItems`/`patchSlots`. + +```mermaid +classDiagram +class SuggestionContext { ++onKeyDown(e) ++onTrigger(...) ++elRef +} +class SuggestionOpenContext { ++open : boolean +} +class ItemsContext { ++items : SuggestionItem[] +} +SuggestionContext --> ItemsContext : "shared items/default" +SuggestionOpenContext --> SuggestionContext : "influences trigger behavior" +``` + +Chart Sources + +- [frontend/antdx/suggestion/suggestion.tsx:22-62](file://frontend/antdx/suggestion/suggestion.tsx#L22-L62) +- [frontend/antdx/suggestion/suggestion.tsx:131-160](file://frontend/antdx/suggestion/suggestion.tsx#L131-L160) +- [frontend/antdx/suggestion/context.ts:1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) + +Section Sources + +- [frontend/antdx/suggestion/suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) +- [frontend/antdx/suggestion/context.ts:1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) + +## Dependency Analysis + +- Component Bridging + - The Svelte wrapper layer dynamically loads the React implementation layer via `importComponent`, uniformly handling props, slots, and callbacks. + - Uses `processProps` to map camelCase names to React-expected property names (e.g., `keyPress` → `keyPress`). +- Utilities and Hooks + - `useFunction`: Converts incoming functions/slots to stable functions, avoiding re-renders. + - `useValueChange`: Maintains value synchronization between controlled and uncontrolled modes, ensuring external `value` changes correctly reflect in internal state. +- File Processing + - `BaseFileCard`: Uniformly parses file `src`, supporting strings and `FileData`, and automatically concatenates accessible URLs. + - The Attachments component internally handles compatibility between `FileData` and `UploadFile`, ensuring `uid` consistency. + +```mermaid +graph LR +Svelte["Svelte Wrapper Layer"] --> Hooks["Utility Hooks
useFunction/useValueChange"] +Svelte --> Impl["React Implementation Layer"] +Impl --> ADX["@ant-design/x Components"] +Impl --> Utils["BaseFileCard/Upload Utilities"] +Hooks --> Impl +``` + +Chart Sources + +- [frontend/antdx/attachments/Index.svelte:28-56](file://frontend/antdx/attachments/Index.svelte#L28-L56) +- [frontend/antdx/sender/Index.svelte:35-66](file://frontend/antdx/sender/Index.svelte#L35-L66) +- [frontend/antdx/suggestion/Index.svelte:26-54](file://frontend/antdx/suggestion/Index.svelte#L26-L54) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/hooks/useValueChange.ts:9-29](file://frontend/utils/hooks/useValueChange.ts#L9-L29) +- [frontend/antdx/file-card/base.tsx:15-41](file://frontend/antdx/file-card/base.tsx#L15-L41) + +Section Sources + +- [frontend/antdx/attachments/Index.svelte:28-56](file://frontend/antdx/attachments/Index.svelte#L28-L56) +- [frontend/antdx/sender/Index.svelte:35-66](file://frontend/antdx/sender/Index.svelte#L35-L66) +- [frontend/antdx/suggestion/Index.svelte:26-54](file://frontend/antdx/suggestion/Index.svelte#L26-L54) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/hooks/useValueChange.ts:9-29](file://frontend/utils/hooks/useValueChange.ts#L9-L29) +- [frontend/antdx/file-card/base.tsx:15-41](file://frontend/antdx/file-card/base.tsx#L15-L41) + +## Performance Considerations + +- Slot and Functionalization + - Use `useFunction` to wrap props and slots, reducing unnecessary re-renders. + - Use `useMemo` and `useMemoizedEqualValue` to cache results for complex computations (such as `items` rendering). +- Upload State + - The Attachments component sets the `uploading` state during upload to prevent concurrent uploads and accidental deletions. + - Use `maxCount` and a temporary `fileList` to avoid excess uploads and UI jitter. +- Value Synchronization + - `useValueChange` only updates internal state when the external `value` changes, preventing circular updates. + +Section Sources + +- [frontend/antdx/attachments/attachments.tsx:122-132](file://frontend/antdx/attachments/attachments.tsx#L122-L132) +- [frontend/antdx/attachments/attachments.tsx:304-312](file://frontend/antdx/attachments/attachments.tsx#L304-L312) +- [frontend/antdx/sender/sender.tsx:68-72](file://frontend/antdx/sender/sender.tsx#L68-L72) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/hooks/useValueChange.ts:9-29](file://frontend/utils/hooks/useValueChange.ts#L9-L29) + +## Troubleshooting Guide + +- Attachment Upload Failure + - Check whether the `upload` callback correctly returns `FileData[]` with `uid` matching the original files. + - Confirm the Gradio client upload path is consistent with the `rootUrl`/`apiPrefix` configuration. +- Quick Command Not Triggering + - Confirm `shouldTrigger` is set and works in coordination with the input field's `onKeyDown`/`onTrigger`. + - Check whether the `open` state is being overridden externally, or whether `SuggestionOpenContext` is being correctly passed. +- Sender Submission Intercepted + - If the quick command panel is open, `onSubmit` will be intercepted; close the panel or wait for it to close before submitting. +- Preview and Icons Not Displaying + - Check whether the slot keys for `imageProps.preview` and `showUploadList` are correctly configured. + - Ensure slot content is correctly rendered; use `ReactSlot` wrapping if necessary. + +Section Sources + +- [frontend/antdx/attachments/attachments.tsx:329-348](file://frontend/antdx/attachments/attachments.tsx#L329-L348) +- [frontend/antdx/suggestion/suggestion.tsx:135-140](file://frontend/antdx/suggestion/suggestion.tsx#L135-L140) +- [frontend/antdx/sender/sender.tsx:126-130](file://frontend/antdx/sender/sender.tsx#L126-L130) + +## Conclusion + +- The Attachments component provides comprehensive multimodal upload capabilities and flexible slot extensions, suitable for handling image/file multimedia input in chat scenarios. +- The Sender component integrates input, paste upload, and the quick command panel, offering good interaction consistency and controllability. +- The Suggestion component achieves a highly customizable suggestion experience through the context and slot system, adapting to various triggering and rendering requirements. +- It is recommended to use the Gradio client and `BaseFileCard` together in real applications to uniformly handle file paths, ensuring cross-module consistency and maintainability. + +## Appendix + +- Example and Documentation Entry Points + - Attachments component examples: see demo tab in the documentation directory + - Sender component examples: see demo tab in the documentation directory + - Suggestion component examples: see demo tab in the documentation directory + +Section Sources + +- [docs/components/antdx/attachments/README.md:1-9](file://docs/components/antdx/attachments/README.md#L1-L9) +- [docs/components/antdx/sender/README.md:1-10](file://docs/components/antdx/sender/README.md#L1-L10) +- [docs/components/antdx/suggestion/README.md:1-10](file://docs/components/antdx/suggestion/README.md#L1-L10) diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Feedback Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Feedback Components API.md new file mode 100644 index 00000000..eec901af --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Feedback Components API.md @@ -0,0 +1,395 @@ +# Feedback Components API + + +**Files Referenced in This Document** +- [frontend/antd/notification/notification.tsx](file://frontend/antd/notification/notification.tsx) +- [frontend/antd/notification/Index.svelte](file://frontend/antd/notification/Index.svelte) +- [frontend/antdx/notification/notification.tsx](file://frontend/antdx/notification/notification.tsx) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/item/actions.item.tsx](file://frontend/antdx/actions/item/actions.item.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Ant Design X Feedback Components API reference for ModelScope Studio, focusing on two types of feedback capabilities: + +- Actions Component: Provides a set of clickable action items in conversations or workflows, supporting dropdown menus, sub-items, icons, and other extensions. +- Notification Component: For global notification messages and browser native notification permission management, covering both Ant Design and Ant Design X implementations. + +This document systematically covers interface definitions, data structures, event and state management, user interaction mechanisms, type specifications and best practices, and provides typical use cases and configuration recommendations for AI applications. + +## Project Structure + +Feedback components are primarily distributed in the following paths: + +- Frontend Ant Design implementation: `frontend/antd/notification` +- Frontend Ant Design X implementation: `frontend/antdx/notification` and `frontend/antdx/actions` +- Common utilities: `frontend/utils` — items context and rendering utilities + +```mermaid +graph TB +subgraph "Ant Design Implementation" +A1["antd/notification/notification.tsx"] +A2["antd/notification/Index.svelte"] +end +subgraph "Ant Design X Implementation" +B1["antdx/notification/notification.tsx"] +B2["antdx/actions/actions.tsx"] +B3["antdx/actions/context.ts"] +B4["antdx/actions/feedback/actions.feedback.tsx"] +B5["antdx/actions/action-item/actions.action-item.tsx"] +B6["antdx/actions/item/actions.item.tsx"] +end +subgraph "Common Utilities" +C1["utils/createItemsContext.tsx"] +C2["utils/renderItems.tsx"] +C3["utils/renderParamsSlot.tsx"] +C4["utils/renderSlot.tsx"] +end +A2 --> A1 +B2 --> B3 +B2 --> C1 +B2 --> C2 +B2 --> C3 +B2 --> C4 +B4 --> B2 +B5 --> B3 +B6 --> B2 +``` + +Chart Sources + +- [frontend/antd/notification/notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [frontend/antd/notification/Index.svelte:56-79](file://frontend/antd/notification/Index.svelte#L56-L79) +- [frontend/antdx/notification/notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:1-16](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L1-L16) +- [frontend/antdx/actions/action-item/actions.action-item.tsx:1-23](file://frontend/antdx/actions/action-item/actions.action-item.tsx#L1-L23) +- [frontend/antdx/actions/item/actions.item.tsx:1-34](file://frontend/antdx/actions/item/actions.item.tsx#L1-L34) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) + +Section Sources + +- [frontend/antd/notification/notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [frontend/antd/notification/Index.svelte:56-79](file://frontend/antd/notification/Index.svelte#L56-L79) +- [frontend/antdx/notification/notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:1-16](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L1-L16) +- [frontend/antdx/actions/action-item/actions.action-item.tsx:1-23](file://frontend/antdx/actions/action-item/actions.action-item.tsx#L1-L23) +- [frontend/antdx/actions/item/actions.item.tsx:1-34](file://frontend/antdx/actions/item/actions.item.tsx#L1-L34) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) + +## Core Components + +- Actions Component + - Responsible for rendering a set of interactive action items, supporting dropdown menus, sub-items, icon slots, and menu item context injection. + - Provides the `Actions.Feedback` sub-component to adapt to specific feedback scenarios. +- Notification Component + - Ant Design version: Based on `antd.notification.useNotification`, supports visibility control and slot rendering. + - Ant Design X version: Based on `@ant-design/x/notification`, with built-in browser notification permission requests and the ability to close by tag. + +Section Sources + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:1-16](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L1-L16) +- [frontend/antd/notification/notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [frontend/antdx/notification/notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) + +## Architecture Overview + +The runtime architecture of feedback components consists of a "component bridge layer + notification/action library + rendering pipeline": + +- Component Bridge Layer: Wraps Svelte components as React components via `sveltify`, uniformly exposing properties and slots externally. +- Notification/Action Library: Connects to notification and action capabilities from both `antd` and `@ant-design/x`. +- Rendering Pipeline: Uses utilities such as `createItemsContext` and `renderItems` to convert DOM nodes from slots into a React component tree, supporting parameterized slots and cloning strategies. + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant Actions as "Actions Component" +participant ItemsCtx as "ItemsContext" +participant Renderer as "Rendering Pipeline" +participant XActions as "@ant-design/x Actions" +UI->>Actions : Pass items/dropdownProps/slots +Actions->>ItemsCtx : Inject context and collect slot items +Actions->>Renderer : Parse slots into React components +Renderer-->>Actions : Return renderable items +Actions->>XActions : Render as Ant Design X action list +XActions-->>UI : User interaction callbacks (onClick, etc.) +``` + +Chart Sources + +- [frontend/antdx/actions/actions.tsx:17-120](file://frontend/antdx/actions/actions.tsx#L17-L120) +- [frontend/utils/createItemsContext.tsx:97-274](file://frontend/utils/createItemsContext.tsx#L97-L274) +- [frontend/utils/renderItems.tsx:8-114](file://frontend/utils/renderItems.tsx#L8-L114) + +## Detailed Component Analysis + +### Actions Component API + +- Component Name: Actions +- Appearance: Ant Design X Actions component, supporting dropdown menus and multi-level sub-items. +- Key Properties (partial): + - `items`: Action item array, supporting default slot and sub-item slots. + - `dropdownProps`: Configuration passed through to the dropdown menu, including `dropdownRender`, `popupRender`, `menu`, etc. + - `slots`: Slot mapping, supporting `menu.expandIcon`, `menu.overflowedIndicator`, `menu.items`, etc. +- Slots and Context: + - Uses `createItemsContext` to maintain `default` and `items` slot item collections. + - Writes child nodes to the context via `ItemHandler`, supporting dynamic calculation of `itemProps`, `itemChildren`, etc. +- Rendering Flow: + - Merges external `items` with slot parsing results to generate the final menu items. + - Performs parameterized slot rendering for `dropdownRender`/`popupRender` and menu items. +- Typical Sub-components: + - `Actions.Feedback`: Directly forwards `@ant-design/x`'s `Actions.Feedback`. + - `Actions.Item`: Encapsulates slots for default icon and running icon. + - `ActionsActionItem`: A convenience wrapper for `ItemHandler`, restricting allowed slot keys. + +```mermaid +classDiagram +class Actions { ++props : ActionsProps ++slots : Record ++dropdownProps ++items +} +class ActionsItem { ++props : ActionsItemProps ++slots : defaultIcon, runningIcon +} +class ActionsFeedback { ++props : ActionsFeedbackProps +} +class ItemsContext { ++items : Record ++setItem() ++useItems() +} +class ItemHandler { ++itemIndex ++itemSlotKey ++allowedSlots ++itemChildrenKey +} +Actions --> ItemsContext : "collect/read" +Actions --> ItemHandler : "sub-item injection" +ActionsItem --> Actions : "as sub-item" +ActionsFeedback --> Actions : "sub-component" +``` + +Chart Sources + +- [frontend/antdx/actions/actions.tsx:17-120](file://frontend/antdx/actions/actions.tsx#L17-L120) +- [frontend/antdx/actions/item/actions.item.tsx:6-34](file://frontend/antdx/actions/item/actions.item.tsx#L6-L34) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:5-16](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L5-L16) +- [frontend/antdx/actions/context.ts:3-4](file://frontend/antdx/actions/context.ts#L3-L4) +- [frontend/antdx/actions/action-item/actions.action-item.tsx:7-20](file://frontend/antdx/actions/action-item/actions.action-item.tsx#L7-L20) + +Section Sources + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:1-16](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L1-L16) +- [frontend/antdx/actions/action-item/actions.action-item.tsx:1-23](file://frontend/antdx/actions/action-item/actions.action-item.tsx#L1-L23) +- [frontend/antdx/actions/item/actions.item.tsx:1-34](file://frontend/antdx/actions/item/actions.item.tsx#L1-L34) +- [frontend/utils/createItemsContext.tsx:20-95](file://frontend/utils/createItemsContext.tsx#L20-L95) +- [frontend/utils/renderItems.tsx:8-114](file://frontend/utils/renderItems.tsx#L8-L114) +- [frontend/utils/renderParamsSlot.tsx:5-51](file://frontend/utils/renderParamsSlot.tsx#L5-L51) +- [frontend/utils/renderSlot.tsx:13-29](file://frontend/utils/renderSlot.tsx#L13-L29) + +### Notification Component API + +- Ant Design Version (antd/notification) + - Property Notes: + - `visible`: Whether to show the notification. + - `onVisible`: Callback when closed, used to sync `visible` state. + - `notificationKey`: Unique identifier, used for `destroy`/`open`. + - Supported slots: `btn`, `actions`, `closeIcon`, `description`, `icon`, `message`. + - Behavior Mechanism: + - When `visible` is true, calls `open`; otherwise, `destroy`. + - In the `onClose` callback, triggers `onVisible(false)` first, then executes the user's custom `onClose`. +- Ant Design X Version (@ant-design/x/notification) + - Property Notes: + - `visible`: Whether to show the notification. + - `onVisible`: Callback when closed. + - `onPermission`: Browser notification permission change callback. + - `tag`: Notification tag, used for closing by tag. + - Behavior Mechanism: + - If not yet authorized before the first display, requests permission; only `open` when `granted`. + - When `visible` is true, `open`; otherwise, `close(tag)`. + - Automatically closes notifications with the corresponding `tag` when the component unmounts. + +```mermaid +sequenceDiagram +participant Caller as "Caller" +participant ANTD as "antd Notification" +participant XNOTI as "X Notification" +Caller->>ANTD : Set visible=true, pass message/description etc. +ANTD->>ANTD : useNotification initialization +ANTD->>ANTD : open({ key, message, description, ... }) +ANTD-->>Caller : onClose callback triggers onVisible(false) +Caller->>XNOTI : Set visible=true, pass tag/message +XNOTI->>XNOTI : useNotification gets permission +alt Not authorized +XNOTI->>XNOTI : requestPermission() +end +XNOTI->>XNOTI : open({ tag, message, onClose }) +XNOTI-->>Caller : onClose callback triggers onVisible(false) +``` + +Chart Sources + +- [frontend/antd/notification/notification.tsx:38-95](file://frontend/antd/notification/notification.tsx#L38-L95) +- [frontend/antdx/notification/notification.tsx:17-46](file://frontend/antdx/notification/notification.tsx#L17-L46) + +Section Sources + +- [frontend/antd/notification/notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [frontend/antd/notification/Index.svelte:56-79](file://frontend/antd/notification/Index.svelte#L56-L79) +- [frontend/antdx/notification/notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) + +## Dependency Analysis + +- Actions and Rendering Toolchain + - Actions depends on `createItemsContext` to maintain the slot item collection. + - Uses `renderItems` to convert slot items into a React component tree, supporting the `children` key and `itemPropsTransformer`. + - `renderParamsSlot` and `renderSlot` support parameterized slots and cloning strategies. +- Actions and Menu Context + - Works with the `antd/menu` context; prioritizes `dropdownProps.menu.items` provided by the menu context. +- Notification and Permissions + - The X version has built-in permission requests and callbacks, avoiding duplicate requests. + - The ANTD version does not involve browser permissions; local notifications only. + +```mermaid +graph LR +Actions["Actions"] --> Ctx["createItemsContext"] +Actions --> RItems["renderItems"] +Actions --> RPSlot["renderParamsSlot"] +Actions --> RSlot["renderSlot"] +Actions --> MenuCtx["antd/menu context"] +XNoti["X Notification"] --> Perm["requestPermission/onPermission"] +ANoti["antd Notification"] --> Local["Local Notifications"] +``` + +Chart Sources + +- [frontend/antdx/actions/actions.tsx:10-15](file://frontend/antdx/actions/actions.tsx#L10-L15) +- [frontend/utils/createItemsContext.tsx:97-274](file://frontend/utils/createItemsContext.tsx#L97-L274) +- [frontend/utils/renderItems.tsx:8-114](file://frontend/utils/renderItems.tsx#L8-L114) +- [frontend/utils/renderParamsSlot.tsx:5-51](file://frontend/utils/renderParamsSlot.tsx#L5-L51) +- [frontend/utils/renderSlot.tsx:13-29](file://frontend/utils/renderSlot.tsx#L13-L29) +- [frontend/antdx/notification/notification.tsx:13-19](file://frontend/antdx/notification/notification.tsx#L13-L19) + +Section Sources + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/antdx/notification/notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) + +## Performance Considerations + +- Slot Rendering Optimization + - Use `useMemo` to wrap `dropdownProps` modifications, reducing unnecessary re-renders. + - `renderItems` supports `clone`/`forceClone` controls to avoid unnecessary React node rebuilding. +- Notification Lifecycle + - ANTD: Destroys the corresponding key when `visible` toggles, and also destroys on unmount to avoid memory leaks. + - X: Closes by tag when `visible=false` or on unmount, ensuring resource cleanup. +- Permission Request Debouncing + - The X version checks permissions before first open, avoiding duplicate requests. + +Section Sources + +- [frontend/antdx/actions/actions.tsx:39-96](file://frontend/antdx/actions/actions.tsx#L39-L96) +- [frontend/antd/notification/notification.tsx:74-95](file://frontend/antd/notification/notification.tsx#L74-L95) +- [frontend/antdx/notification/notification.tsx:17-46](file://frontend/antdx/notification/notification.tsx#L17-L46) + +## Troubleshooting Guide + +- Actions Sub-items Not Displaying + - Check slot keys: verify `default` and `subItems` match the `ItemHandler`'s `itemChildrenKey`. + - Confirm the return value logic of `allowedSlots` and `itemChildren` is consistent. +- Slot Not Taking Effect + - Confirm elements in `slots` have been correctly passed to `ItemHandler` or Actions's `slots`. + - For parameterized slots, confirm `renderParamsSlot`'s `targets` and `withParams` configuration. +- Notification Not Displaying + - ANTD: Confirm `visible` is true and `notificationKey` is unique; check whether `onVisible(false)` is called in `onClose`. + - X: Confirm browser notification permission is `granted`; check whether `tag` is correctly passed; check whether `onVisible(false)` is called in `onClose`. +- Performance Issues + - Check whether `dropdownProps` changes frequently; reuse object references or use `useMemo` as much as possible. + - Reduce unnecessary cloning; only enable `forceClone` when necessary. + +Section Sources + +- [frontend/antdx/actions/action-item/actions.action-item.tsx:11-19](file://frontend/antdx/actions/action-item/actions.action-item.tsx#L11-L19) +- [frontend/antdx/actions/context.ts:3-4](file://frontend/antdx/actions/context.ts#L3-L4) +- [frontend/utils/renderParamsSlot.tsx:23-49](file://frontend/utils/renderParamsSlot.tsx#L23-L49) +- [frontend/antd/notification/notification.tsx:38-95](file://frontend/antd/notification/notification.tsx#L38-L95) +- [frontend/antdx/notification/notification.tsx:17-46](file://frontend/antdx/notification/notification.tsx#L17-L46) + +## Conclusion + +- Actions transforms complex UI structures into composable and extensible action lists through slot and context mechanisms, suitable for carrying multi-step task and multi-turn conversation action feedback in AI applications. +- Notification provides unified visibility and lifecycle management on both the ANTD and X sides; the X version additionally supports browser notification permissions, meeting richer user feedback needs. +- It is recommended to choose the appropriate implementation version based on business semantics in real applications, and to follow slot and context best practices for stable and high-performance feedback experiences. + +## Appendix + +### Type and Interface Summary + +- Actions + - `ActionsProps`: From `@ant-design/x`, includes `items`, `dropdownProps`, etc. + - `ActionsItemProps`: Property collection for `Actions.Item`. + - `ActionsFeedbackProps`: Property collection for `Actions.Feedback`. +- Notification + - ANTD: `ArgsProps` and `NotificationConfig`, supporting `visible`, `onVisible`, slots, etc. + - X: `XNotificationOpenArgs`, supporting `visible`, `onVisible`, `onPermission`, `tag`, etc. + +Section Sources + +- [frontend/antdx/actions/actions.tsx:3-8](file://frontend/antdx/actions/actions.tsx#L3-L8) +- [frontend/antd/notification/notification.tsx:8-16](file://frontend/antd/notification/notification.tsx#L8-L16) +- [frontend/antdx/notification/notification.tsx:6-11](file://frontend/antdx/notification/notification.tsx#L6-L11) + +### Usage Scenarios and Best Practices + +- Action Feedback in AI Applications + - Use `Actions.Feedback` to quickly mount feedback-type actions. + - Use `Actions.Item` to customize icons and text, combined with slots for dynamic text and status indicators. + - For multi-level menus, use `subItems` and `allowedSlots` to manage hierarchy. +- Notification Timing Control + - ANTD: Use `visible` for precise show/hide control; use brief notifications for critical errors or success states. + - X: Enable for system-level alerts; note that permission requests only trigger on the first use, avoiding frequent interruptions. +- State Synchronization + - Uniformly set `onVisible(false)` in `onClose` to ensure UI and state consistency. + - For batch closures, use `tag` or `key` for precise targeting. diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/General Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/General Components API.md new file mode 100644 index 00000000..4ee600b7 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/General Components API.md @@ -0,0 +1,518 @@ +# General Components API + + +**Files Referenced in This Document** +- [bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [conversations.tsx](file://frontend/antdx/conversations/conversations.tsx) +- [prompts.tsx](file://frontend/antdx/prompts/prompts.tsx) +- [suggestion.tsx](file://frontend/antdx/suggestion/suggestion.tsx) +- [sender.tsx](file://frontend/antdx/sender/sender.tsx) +- [context.ts (suggestion item context)](file://frontend/antdx/suggestion/context.ts) +- [context.ts (conversation item context)](file://frontend/antdx/conversations/context.ts) +- [context.ts (prompt item context)](file://frontend/antdx/prompts/context.ts) +- [renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [createFunction.ts](file://frontend/utils/createFunction.ts) +- [patchSlots.ts](file://frontend/utils/patchSlots.ts) +- [useMemoizedEqualValue.ts](file://frontend/utils/hooks/useMemoizedEqualValue.ts) +- [react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) +- [react-contexts.ts](file://frontend/svelte-preprocess-react/react-contexts.ts) +- [sveltify.svelte.ts](file://frontend/svelte-preprocess-react/sveltify.svelte.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Ant Design X General Components API reference for ModelScope Studio. It focuses on the complete interface specifications and usage guides for the following core general components: + +- Bubble: Conversation bubble component, supports avatar, content, footer, extra actions, and other slots and render functions +- Conversations: Conversation list/group management, supports menus, group labels, overflow indicators, and other extensions +- Prompts: Prompt card collection, supports title slots and dynamic item rendering +- Suggestion: Quick commands/suggestion input, supports popup containers, trigger strategies, and sub-item slot patching +- Sender: Sender component, supports paste upload, skill panel, prefix/suffix/header/footer slots + +This document covers property definitions, event handling, slot systems, state management, message passing, and conversation flow control mechanisms. It also provides instantiation and configuration example paths for AI chat and conversation scenarios, TypeScript types and integration with Ant Design components, as well as performance optimization and best practices. + +## Project Structure + +Ant Design X general components are located in the `antdx` submodule of the frontend directory. They adopt a "Svelte wrapper + React component bridge" architecture: using `svelte-preprocess-react` to use `@ant-design/x` React components in a Svelte-compatible way, while providing a unified slot system and context injection capability. + +```mermaid +graph TB +subgraph "Ant Design X General Components" +B["Bubble
Bubble Component"] +C["Conversations
Conversation List/Groups"] +P["Prompts
Prompt Cards"] +S["Suggestion
Quick Commands/Suggestions"] +SD["Sender
Sender"] +end +subgraph "Utilities and Context" +U1["renderItems.tsx
Render Items Utility"] +U2["renderParamsSlot.tsx
Parameterized Slot Renderer"] +U3["useFunction.ts
Function Wrapper Hook"] +U4["useValueChange.ts
Value Change Hook"] +U5["createFunction.ts
Function Factory"] +U6["patchSlots.ts
Slot Patching"] +U7["react-slot.tsx
React Slot"] +U8["react-contexts.ts
React Contexts"] +U9["sveltify.svelte.ts
Svelte Wrapper"] +end +B --> U1 +B --> U2 +B --> U3 +B --> U7 +C --> U1 +C --> U2 +C --> U3 +C --> U8 +P --> U1 +P --> U2 +S --> U1 +S --> U2 +S --> U3 +S --> U6 +SD --> U1 +SD --> U2 +SD --> U3 +SD --> U4 +SD --> U5 +SD --> U7 +SD --> U8 +``` + +Chart Sources + +- [bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) +- [sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) +- [renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [createFunction.ts](file://frontend/utils/createFunction.ts) +- [patchSlots.ts](file://frontend/utils/patchSlots.ts) +- [react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) +- [react-contexts.ts](file://frontend/svelte-preprocess-react/react-contexts.ts) +- [sveltify.svelte.ts](file://frontend/svelte-preprocess-react/sveltify.svelte.ts) + +Section Sources + +- [bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) +- [sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +## Core Components + +This section provides an overview of the five core general components, their responsibilities and typical use cases, to help quickly locate specific implementations and example paths. + +- Bubble (Conversation Bubble) + - Supports avatar, content, header, footer, extra actions, editable text, loading state, and custom content rendering + - Slot keys: `avatar`, `content`, `header`, `footer`, `extra`, `editable.okText`, `editable.cancelText`, `loadingRender`, `contentRender` + - Typical use cases: User/system message display, editable replies, async loading states + +- Conversations (Conversation Management) + - Supports conversation item lists, grouping, menus, overflow indicators, expand icons, and triggers + - Slot keys: `menu.items`, `menu.trigger`, `menu.expandIcon`, `menu.overflowedIndicator`, `groupable.label` + - Typical use cases: Historical conversation browsing, group collapsing, right-click menu operations + +- Prompts (Prompt Collection) + - Supports prompt card title slots and dynamic item rendering + - Slot keys: `title` + - Typical use cases: Chat guidance, quick prompts, templated input + +- Suggestion (Quick Commands) + - Supports suggestion item lists, sub-item slot patching, popup containers, open state, and keyboard trigger strategies + - Slot keys: `children` + - Typical use cases: @mentions, /commands, quick suggestions + +- Sender (Sender) + - Supports paste upload, skill panel, prefix/suffix/header/footer slots, value change, and submission interception + - Slot keys: `suffix`, `header`, `prefix`, `footer`, `skill.title`, `skill.toolTip.title`, `skill.closable.closeIcon` + - Typical use cases: Text input, file paste upload, skill toggles + +Section Sources + +- [bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) +- [conversations.tsx:59-175](file://frontend/antdx/conversations/conversations.tsx#L59-L175) +- [prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) +- [suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) +- [sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) + +## Architecture Overview + +The diagram below shows the call relationships and data flow between general components and the utility library, reflecting the overall flow of "slot parsing → function wrapping → render item generation → React component bridging". + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Comp as "Svelte Wrapper Component" +participant Utils as "Utility Library" +participant X as "@ant-design/x Component" +Dev->>Comp : Pass props and slots +Comp->>Utils : Parse slots / wrap functions / handle value changes +Utils-->>Comp : Return render results / function handles +Comp->>X : Pass through props and bridge React component +X-->>Dev : Render UI and trigger callbacks +``` + +Chart Sources + +- [bubble.tsx:27-115](file://frontend/antdx/bubble/bubble.tsx#L27-L115) +- [conversations.tsx:72-171](file://frontend/antdx/conversations/conversations.tsx#L72-L171) +- [prompts.tsx:16-37](file://frontend/antdx/prompts/prompts.tsx#L16-L37) +- [suggestion.tsx:77-159](file://frontend/antdx/suggestion/suggestion.tsx#L77-L159) +- [sender.tsx:35-169](file://frontend/antdx/sender/sender.tsx#L35-L169) +- [renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [createFunction.ts](file://frontend/utils/createFunction.ts) +- [patchSlots.ts](file://frontend/utils/patchSlots.ts) +- [react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) + +## Detailed Component Analysis + +### Bubble Component API + +- Component Responsibilities + - Wraps `@ant-design/x`'s Bubble in Svelte form, providing slot and function wrapping capabilities + - Supports editable text, loading state, custom content rendering, and avatar/header/footer/extra action slots +- Key Properties and Slots + - Props: Inherits from `BubbleProps`, supports `editable`, `typing`, `content`, `avatar`, `extra`, `footer`, `header`, `loadingRender`, `contentRender`, etc. + - Slots: `avatar`, `content`, `header`, `footer`, `extra`, `editable.okText`, `editable.cancelText`, `loadingRender`, `contentRender` +- Events and State + - Callbacks are wrapped via `useFunction` to ensure reactive updates; `editable` supports boolean or config objects +- Usage Notes + - Edit mode is enabled when `editable` config exists or slots are present; `loadingRender`/`contentRender` support parameterized slots +- Example Path + - [Bubble Implementation:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) + +```mermaid +classDiagram +class Bubble { ++props : BubbleProps ++slots : slot collection ++useFunction() ++ReactSlot ++renderParamsSlot() +} +class XBubble { ++Inherits from @ant-design/x +} +Bubble --> XBubble : "bridge" +``` + +Chart Sources + +- [bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) + +Section Sources + +- [bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) + +### Conversations Component API + +- Component Responsibilities + - Wraps `@ant-design/x`'s Conversations in Svelte form, providing menu and grouping capabilities +- Key Properties and Slots + - Props: Inherits from `ConversationsProps`, supports `items`, `menu`, `groupable`, `classNames`, etc. + - Slots: `menu.items`, `menu.trigger`, `menu.expandIcon`, `menu.overflowedIndicator`, `groupable.label` +- Events and State + - Menu callbacks are wrapped via `useFunction`; menu events are wrapped to pass the current conversation context + - Group labels support both slot and function configuration +- Usage Notes + - `menu` supports strings or objects; when `items` is not provided, they can be injected from context + - `classNames.item` injects style class names for improved consistency +- Example Path + - [Conversations Implementation:59-175](file://frontend/antdx/conversations/conversations.tsx#L59-L175) + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Conv as "Conversations" +participant Ctx as "Context/Slots" +participant XConv as "X Conversations" +Dev->>Conv : Pass items/menu/groupable +Conv->>Ctx : Read slots/context items +Conv->>Conv : Wrap menu callbacks via useFunction +Conv->>XConv : Pass through props and render +XConv-->>Dev : Render conversation list/groups +``` + +Chart Sources + +- [conversations.tsx:59-175](file://frontend/antdx/conversations/conversations.tsx#L59-L175) +- [context.ts (conversation item context):1-7](file://frontend/antdx/conversations/context.ts#L1-L7) + +Section Sources + +- [conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [context.ts (conversation item context):1-7](file://frontend/antdx/conversations/context.ts#L1-L7) + +### Prompts Component API + +- Component Responsibilities + - Wraps `@ant-design/x`'s Prompts in Svelte form, providing title slots and dynamic item rendering +- Key Properties and Slots + - Props: Inherits from `PromptsProps`, supports `items`, `title`, etc. + - Slots: `title` +- Events and State + - Item lists are dynamically generated via `renderItems`; slot `items`/`default` takes priority +- Usage Notes + - Suitable for "quick prompts", "templated input", and similar scenarios +- Example Path + - [Prompts Implementation:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) + +```mermaid +flowchart TD +Start(["Start"]) --> Read["Read slot items/default"] +Read --> HasItems{"Has items?"} +HasItems --> |Yes| Render["renderItems render"] +HasItems --> |No| UseProps["Use props.items"] +Render --> SetTitle["Set title slot"] +UseProps --> SetTitle +SetTitle --> End(["End"]) +``` + +Chart Sources + +- [prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) +- [context.ts (prompt item context):1-7](file://frontend/antdx/prompts/context.ts#L1-L7) + +Section Sources + +- [prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [context.ts (prompt item context):1-7](file://frontend/antdx/prompts/context.ts#L1-L7) + +### Suggestion Component API + +- Component Responsibilities + - Wraps `@ant-design/x`'s Suggestion in Svelte form, providing suggestion item slot patching, popup containers, open state, and keyboard trigger strategies +- Key Properties and Slots + - Props: Inherits from `SuggestionProps`, adds `children` slot and `shouldTrigger` callback + - Slots: `children` +- Events and State + - `SuggestionOpenContext` and `useSuggestionOpenContext` control and observe the open state + - `patchSlots` patches suggestion item `icon`/`label`/`extra`/`children` slots + - `useMemoizedEqualValue` optimizes rendering overhead +- Usage Notes + - Supports injecting context into `children` render function to customize `onTrigger`/`onKeyDown` + - Supports controlled/uncontrolled `open` state switching +- Example Path + - [Suggestion Implementation:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Sug as "Suggestion" +participant Ctx as "SuggestionContext/SuggestionOpenContext" +participant Patch as "patchSlots" +participant XSug as "X Suggestion" +Dev->>Sug : Pass items/children/shouldTrigger +Sug->>Patch : Patch suggestion item slots +Sug->>Ctx : Provider injects context +Sug->>XSug : Pass through props and render +XSug-->>Dev : Popup and suggestion items +``` + +Chart Sources + +- [suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) +- [context.ts (suggestion item context):1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) +- [react-contexts.ts](file://frontend/svelte-preprocess-react/react-contexts.ts) + +Section Sources + +- [suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) +- [context.ts (suggestion item context):1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) + +### Sender Component API + +- Component Responsibilities + - Wraps `@ant-design/x`'s Sender in Svelte form, providing paste upload, skill panel, slots, and value change hooks +- Key Properties and Slots + - Props: Inherits from `SenderProps`, adds `upload`, `onPasteFile`, `onValueChange`, etc. + - Slots: `suffix`, `header`, `prefix`, `footer`, `skill.title`, `skill.toolTip.title`, `skill.closable.closeIcon` +- Events and State + - `useValueChange` manages controlled/uncontrolled `value` + - `useSuggestionOpenContext` intercepts submission when Suggestion is open + - `createFunction`/`formatResult`/`customRender` customize `slotConfig` +- Usage Notes + - When pasting files, calls `upload` and backfills the path array + - Skill panel supports combinations of slots and configuration for tooltip/closable +- Example Path + - [Sender Implementation:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) + +```mermaid +flowchart TD +A["onPasteFile triggered"] --> B["Call upload(files)"] +B --> C["Backfill path array to onPasteFile"] +D["onSubmit triggered"] --> E{"Is Suggestion open?"} +E --> |Yes| F["Intercept submission"] +E --> |No| G["Normal submission"] +H["onChange triggered"] --> I["useValueChange updates value"] +``` + +Chart Sources + +- [sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) + +Section Sources + +- [sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +## Dependency Analysis + +There is a clear dependency relationship between general components and the utility library: components consume utility library capabilities through the context and slot systems, ultimately bridging to `@ant-design/x` React components. + +```mermaid +graph LR +subgraph "Components" +B["Bubble"] +C["Conversations"] +P["Prompts"] +S["Suggestion"] +SD["Sender"] +end +subgraph "Utilities" +R1["renderItems"] +R2["renderParamsSlot"] +H1["useFunction"] +H2["useValueChange"] +H3["useMemoizedEqualValue"] +F1["createFunction"] +F2["patchSlots"] +RS["ReactSlot"] +RC["ReactContexts"] +end +B --> R1 +B --> R2 +B --> H1 +B --> RS +C --> R1 +C --> R2 +C --> H1 +C --> RC +P --> R1 +P --> R2 +S --> R1 +S --> R2 +S --> H1 +S --> F2 +S --> H3 +SD --> R1 +SD --> R2 +SD --> H1 +SD --> H2 +SD --> F1 +SD --> RS +SD --> RC +``` + +Chart Sources + +- [bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) +- [sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) +- [renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [createFunction.ts](file://frontend/utils/createFunction.ts) +- [patchSlots.ts](file://frontend/utils/patchSlots.ts) +- [react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) +- [react-contexts.ts](file://frontend/svelte-preprocess-react/react-contexts.ts) + +Section Sources + +- [bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) +- [sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +## Performance Considerations + +- Slot and Function Wrapping + - Use `useMemoizedEqualValue` and `useMemo` to reduce render jitter and redundant computation + - Wrap callbacks via `useFunction` to prevent child component re-renders caused by new function instances on every render +- Render Items and Slots + - `renderItems` and `renderParamsSlot` execute only when necessary, reducing unnecessary cloning and rendering + - `patchSlots` patches suggestion items on demand, avoiding full replacement +- Value Change and Event Interception + - `useValueChange` unifies value management to prevent external state inconsistencies + - Sender intercepts submission when Suggestion is open, reducing invalid requests +- Best Practices + - Properly split slots and functions, avoid heavy logic inside slots + - Use stable references for high-frequency update data, combined with `useMemo`/`useCallback` + - Reuse already-parsed `items` in Conversations/Prompts as much as possible to reduce duplicate rendering + +[This section provides general performance guidance and requires no specific file sources] + +## Troubleshooting Guide + +- Slot Not Taking Effect + - Check if slot key names match the component declarations (e.g., `bubble`'s `editable.okText`, `conversations`'s `menu.items`, etc.) + - Confirm that slot content is properly wrapped in `ReactSlot` or `renderParamsSlot` +- Event Not Firing + - Confirm that the callback wrapped by `useFunction` is correctly passed to the underlying component + - For Conversations menu events, check if `patchMenuEvents` correctly wraps the original event +- Suggestion Item Slot Not Displaying + - Confirm that `patchSlots` has patched `icon`/`label`/`extra`/`children` + - Check if the Suggestion `children` render function returns the correct nodes +- Sender Submission Intercepted + - Confirm whether `SuggestionOpenContext` state is `true` + - Check if `shouldTrigger` correctly fires on keyboard events +- Value Not Updating + - Confirm that `useValueChange`'s `onValueChange` is being called + - Check the synchronization logic between `props.value` and internal state + +Section Sources + +- [bubble.tsx:27-115](file://frontend/antdx/bubble/bubble.tsx#L27-L115) +- [conversations.tsx:35-122](file://frontend/antdx/conversations/conversations.tsx#L35-L122) +- [suggestion.tsx:100-159](file://frontend/antdx/suggestion/suggestion.tsx#L100-L159) +- [sender.tsx:126-138](file://frontend/antdx/sender/sender.tsx#L126-L138) + +## Conclusion + +ModelScope Studio's Ant Design X general components achieve seamless bridging with `@ant-design/x` components through a unified slot system and function wrapping mechanism. Bubble, Conversations, Prompts, Suggestion, and Sender provide powerful extensibility and ease of use for AI chat and conversation scenarios. Following this document's property definitions, event handling, slot system, and state management recommendations, you can efficiently build high-quality conversational interfaces and interaction flows. + +[This section is a summary and requires no specific file sources] + +## Appendix + +- TypeScript Types and Interfaces + - All components extend or trim the corresponding `Props` types from `@ant-design/x` to ensure type safety + - Slots and function wrapping leverage generics and utility functions to guarantee type inference +- Integration with Ant Design Components + - Svelte-to-React bridging is achieved via `sveltify` and `ReactSlot` from `svelte-preprocess-react` + - Property and callback functionalization is achieved via utility tools such as `createFunction`/`useFunction` +- Example Path Index + - Bubble: [bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) + - Conversations: [conversations.tsx:59-175](file://frontend/antdx/conversations/conversations.tsx#L59-L175) + - Prompts: [prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) + - Suggestion: [suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) + - Sender: [sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) + +[This section is supplementary information and requires no specific file sources] diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Tool Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Tool Components API.md new file mode 100644 index 00000000..652751cf --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Ant Design X Components API/Tool Components API.md @@ -0,0 +1,377 @@ +# Tool Components API + + +**Files Referenced in This Document** +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antdx/code-highlighter/code-highlighter.tsx](file://frontend/antdx/code-highlighter/code-highlighter.tsx) +- [frontend/antdx/file-card/file-card.tsx](file://frontend/antdx/file-card/file-card.tsx) +- [frontend/antdx/file-card/base.tsx](file://frontend/antdx/file-card/base.tsx) +- [frontend/antdx/folder/folder.tsx](file://frontend/antdx/folder/folder.tsx) +- [frontend/antdx/folder/context.ts](file://frontend/antdx/folder/context.ts) +- [frontend/antdx/mermaid/mermaid.tsx](file://frontend/antdx/mermaid/mermaid.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [docs/components/antdx/x_provider/README.md](file://docs/components/antdx/x_provider/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document covers the Ant Design X Tool Components API for ModelScope Studio, focusing on the complete interface and usage of the following components: + +- XProvider Global Configuration Component (based on antd's ConfigProvider extension) +- CodeHighlighter Code Highlighting Component +- FileCard File Card Component +- Folder Directory Component +- Mermaid Flowchart Component + +The document covers global configuration approaches, code highlighting language and theme support, file management interactions, flowchart drawing and action integration, and integration with the Gradio ecosystem. It also provides key type definition notes, context provision and state management mechanisms, performance optimization, and best extension practices. + +## Project Structure + +Key directories and files around tool components: + +- Frontend component implementations are in `frontend/antdx` and `frontend/antd`, corresponding to Ant Design X components and the antd configuration layer respectively +- Each component is wrapped via `sveltify` as a React component usable in Svelte, bridged through slots and parameters +- Shared context between components is provided via `createItemsContext`, used for tree nodes, directory icons, and action items, etc. + +```mermaid +graph TB +subgraph "Antd Configuration Layer" +CP["ConfigProvider
frontend/antd/config-provider/config-provider.tsx"] +end +subgraph "Ant Design X Tool Components" +CH["CodeHighlighter
frontend/antdx/code-highlighter/code-highlighter.tsx"] +FC["FileCard
frontend/antdx/file-card/file-card.tsx"] +FCB["BaseFileCard
frontend/antdx/file-card/base.tsx"] +FD["Folder
frontend/antdx/folder/folder.tsx"] +FDCtx["Folder Context
frontend/antdx/folder/context.ts"] +MM["Mermaid
frontend/antdx/mermaid/mermaid.tsx"] +ActCtx["Actions Context
frontend/antdx/actions/context.ts"] +end +CP --> CH +CP --> FC +FC --> FCB +CP --> FD +FD --> FDCtx +CP --> MM +MM --> ActCtx +``` + +Chart Sources + +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) +- [frontend/antdx/folder/folder.tsx:1-123](file://frontend/antdx/folder/folder.tsx#L1-L123) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) + +Section Sources + +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) +- [frontend/antdx/folder/folder.tsx:1-123](file://frontend/antdx/folder/folder.tsx#L1-L123) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) + +## Core Components + +This section provides an overview of each component's responsibilities and key capabilities: + +- XProvider: Replaces antd's ConfigProvider in Gradio Blocks scenarios, uniformly providing global configuration for Ant Design X components (theme, localization, popup containers, etc.), and compatible with slot injection +- CodeHighlighter: Encapsulates `@ant-design/x`'s code highlighting component, supporting custom `header` slots and syntax highlighting styles in light/dark themes +- FileCard: File card component, supporting slot-based configuration for image placeholders, preview masks, close icons, toolbar rendering, indicators, and description text +- Folder: Directory tree component, supporting slot injection for tree node data, directory icon mapping, empty state rendering, and title/preview rendering, and can connect to file content services +- Mermaid: Flowchart component, supporting theme switching, highlight styles, action item context injection, and custom actions + +Section Sources + +- [docs/components/antdx/x_provider/README.md:1-19](file://docs/components/antdx/x_provider/README.md#L1-L19) +- [frontend/antd/config-provider/config-provider.tsx:51-151](file://frontend/antd/config-provider/config-provider.tsx#L51-L151) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:29-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L29-L51) +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/folder/folder.tsx:16-120](file://frontend/antdx/folder/folder.tsx#L16-L120) +- [frontend/antdx/mermaid/mermaid.tsx:33-84](file://frontend/antdx/mermaid/mermaid.tsx#L33-L84) + +## Architecture Overview + +XProvider serves as the top-level configuration container, providing unified theme, localization, and popup container strategies to tool components below; tool components use slot and parameter bridging, combined with context providers for flexible slot-based and dynamic rendering. + +```mermaid +sequenceDiagram +participant App as "Application" +participant XProv as "XProvider (ConfigProvider)" +participant Comp as "Tool Component" +participant Slots as "Slot System" +App->>XProv : "Wrap application and pass configuration" +XProv->>Comp : "Provide theme/localization/container strategy" +Comp->>Slots : "Read slots (e.g., header, mask, previewRender)" +Slots-->>Comp : "Return React nodes" +Comp-->>App : "Render final UI" +``` + +Chart Sources + +- [frontend/antd/config-provider/config-provider.tsx:108-149](file://frontend/antd/config-provider/config-provider.tsx#L108-L149) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:35-49](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L35-L49) +- [frontend/antdx/file-card/file-card.tsx:46-123](file://frontend/antdx/file-card/file-card.tsx#L46-L123) +- [frontend/antdx/folder/folder.tsx:48-116](file://frontend/antdx/folder/folder.tsx#L48-L116) +- [frontend/antdx/mermaid/mermaid.tsx:47-81](file://frontend/antdx/mermaid/mermaid.tsx#L47-L81) + +## Component Details + +### XProvider Global Configuration Component + +- Role: Replaces antd's ConfigProvider, providing unified global configuration for `@ant-design/x` components +- Key Capabilities + - Theme Mode: Supports `themeMode` to control dark/compact algorithms + - Localization: Automatically parses and loads the corresponding `antd`/`dayjs` locale resources based on the browser language + - Popup Containers: Supports `getPopupContainer`/`getTargetContainer` function injection + - Slot-based: Injects slots into component properties via `combinePropsAndSlots` + - Custom Rendering: `renderEmpty` supports both slot and function forms +- Usage Recommendations + - Use `antdx.XProvider` instead of `antd.ConfigProvider` in Gradio Blocks + - Switch light/dark themes via `themeMode`, avoiding re-render issues caused by duplicate keys + - Set `getPopupContainer` appropriately to ensure floating layers render in the correct container + +Section Sources + +- [docs/components/antdx/x_provider/README.md:1-19](file://docs/components/antdx/x_provider/README.md#L1-L19) +- [frontend/antd/config-provider/config-provider.tsx:51-151](file://frontend/antd/config-provider/config-provider.tsx#L51-L151) + +### CodeHighlighter Code Highlighting Component + +- Role: Renders code with syntax highlighting, supporting `header` slots and light/dark theme styles +- Key Capabilities + - Language Support: Relies on `react-syntax-highlighter`'s Prism style, can directly render multiple languages + - Light/Dark Theme: Switches `materialDark`/`materialLight` styles based on `themeMode`, uniformly removing the code block outer margin + - Slot-based: Supports `header` slot for custom header injection + - Value Binding: Both the `value` property and child node content can serve as code input +- Usage Recommendations + - In AI applications, prefer consistent light/dark theme styles for a better reading experience + - Add copy, download, and other action buttons via the `header` slot + +Section Sources + +- [frontend/antdx/code-highlighter/code-highlighter.tsx:29-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L29-L51) + +### FileCard File Card Component + +- Role: Displays file information, supporting slot-based configuration for image placeholders, preview masks, toolbars, indicators, and description text +- Key Capabilities + - Image Processing: Supports slot-based placeholders, preview containers, close icons, toolbars, and image rendering + - Loading State: `spinProps` supports `size`, `icon`, `description`, `indicator` slots + - Description and Icons: `description` and `icon` slots allow custom display content + - Resource Resolution: Resolves relative paths and `FileData` via `BaseFileCard`'s `resolveFileSrc` +- Usage Recommendations + - For remote images, ensure `rootUrl` and `apiPrefix` are correctly concatenated for an accessible URL + - Enable preview functionality on demand to avoid unnecessary DOM rendering + +```mermaid +flowchart TD +Start(["Enter FileCard"]) --> CheckImg["Check if imageProps.preview is enabled"] +CheckImg --> |Enabled| BuildPreview["Build preview config (with slots)"] +CheckImg --> |Disabled| NoPreview["Disable preview"] +BuildPreview --> ResolveSrc["Resolve src to accessible URL"] +NoPreview --> ResolveSrc +ResolveSrc --> Render["Render BaseFileCard"] +Render --> End(["Done"]) +``` + +Chart Sources + +- [frontend/antdx/file-card/file-card.tsx:34-123](file://frontend/antdx/file-card/file-card.tsx#L34-L123) +- [frontend/antdx/file-card/base.tsx:15-41](file://frontend/antdx/file-card/base.tsx#L15-L41) + +Section Sources + +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/file-card/base.tsx:9-41](file://frontend/antdx/file-card/base.tsx#L9-L41) + +### Folder Directory Component + +- Role: Directory tree component, supporting tree node data, directory icon mapping, empty state and title rendering, preview rendering, and file content services +- Key Capabilities + - Tree Node Context: Provides two data sources `treeData`/`default` via `withTreeNodeItemsContextProvider` + - Directory Icon Context: Provides extension-to-icon mapping via `withDirectoryIconItemsContextProvider` + - Preview Service: `fileContentService` can inject a callback for loading file content + - Slot-based: `emptyRender`, `directoryTitle`, `previewTitle`, `previewRender` all support slots +- Usage Recommendations + - When `treeData` is empty, fall back to the default node list to ensure stable initial rendering + - Directory icon mappings are collected via slots and then converted to a dictionary for fast lookup + +```mermaid +sequenceDiagram +participant FD as "Folder" +participant Ctx as "Context Provider" +participant XFD as "@ant-design/x Folder" +participant FS as "File Content Service" +FD->>Ctx : "Read tree nodes and directory icons" +FD->>FD : "Merge treeData/default" +FD->>FD : "Build directory icon mapping" +FD->>XFD : "Pass treeData, directoryIcons, emptyRender..." +alt fileContentService exists +FD->>FS : "Call onLoadFileContent(filePath)" +FS-->>FD : "Return file content" +end +XFD-->>FD : "Render tree and preview" +``` + +Chart Sources + +- [frontend/antdx/folder/folder.tsx:24-120](file://frontend/antdx/folder/folder.tsx#L24-L120) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) + +Section Sources + +- [frontend/antdx/folder/folder.tsx:16-120](file://frontend/antdx/folder/folder.tsx#L16-L120) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) + +### Mermaid Flowchart Component + +- Role: Flowchart drawing component, supporting theme switching, highlight styles, and action item context +- Key Capabilities + - Theme and Highlight: Switches `dark`/`base` theme based on `themeMode`, and applies Prism-style highlighting + - Actions Context: Injects custom action items via `withActionItemsContextProvider` + - Slot-based: `header` and `actions.customActions` support slots + - Config Merging: `theme` in `config` will be overridden by `themeMode` +- Usage Recommendations + - In AI applications, inject copy, download, full-screen, and other actions via `actions.customActions` + - Maintain theme consistency to avoid visual breaks caused by light/dark switching + +Section Sources + +- [frontend/antdx/mermaid/mermaid.tsx:33-84](file://frontend/antdx/mermaid/mermaid.tsx#L33-L84) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) + +## Dependency Analysis + +- Component Coupling + - FileCard depends on BaseFileCard for resource resolution, reducing duplicate logic + - Folder injects tree nodes and directory icons via context providers, decoupling external data sources + - Mermaid injects custom actions via the actions context provider, enhancing extensibility +- External Dependencies + - `react-syntax-highlighter`: Provides Prism-style highlighting + - `@ant-design/x`: Provides underlying component capabilities (CodeHighlighter, Folder, Mermaid, FileCard, etc.) + - `antd`: ConfigProvider extension and theme algorithms +- Circular Dependencies + - No circular dependencies detected in the current structure; context providers are abstracted via `createItemsContext`, avoiding direct mutual references + +```mermaid +graph LR +CH["CodeHighlighter"] --> XCH["@ant-design/x CodeHighlighter"] +FC["FileCard"] --> FCB["BaseFileCard"] +FCB --> XFC["@ant-design/x FileCard"] +FD["Folder"] --> XFD["@ant-design/x Folder"] +FD --> FDCtx["Folder Context"] +MM["Mermaid"] --> XMM["@ant-design/x Mermaid"] +MM --> ActCtx["Actions Context"] +CP["ConfigProvider (XProvider)"] --> CH +CP --> FC +CP --> FD +CP --> MM +``` + +Chart Sources + +- [frontend/antdx/code-highlighter/code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) +- [frontend/antdx/folder/folder.tsx:1-123](file://frontend/antdx/folder/folder.tsx#L1-L123) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) + +Section Sources + +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/folder/folder.tsx:16-120](file://frontend/antdx/folder/folder.tsx#L16-L120) +- [frontend/antdx/mermaid/mermaid.tsx:33-84](file://frontend/antdx/mermaid/mermaid.tsx#L33-L84) +- [frontend/antd/config-provider/config-provider.tsx:51-151](file://frontend/antd/config-provider/config-provider.tsx#L51-L151) + +## Performance Considerations + +- Rendering Strategy + - Use `useMemo` to cache computed results like `treeData`, `directoryIcons`, `actions.customActions`, etc., to avoid duplicate renders + - Enable preview containers and toolbars only when needed to reduce DOM structure complexity +- Theme Switching + - When `themeMode` changes, combine light/dark algorithms and reuse style objects to avoid frequent style rebuilding +- Slot Rendering + - When using `renderParamsSlot` and `renderItems`, pass `clone: true` as much as possible to ensure independent slot node updates +- Resource Resolution + - `BaseFileCard`'s `resolveFileSrc` only recalculates when `src`/`rootUrl`/`apiPrefix` changes, avoiding unnecessary URL concatenation + +[This section provides general guidance and requires no specific file sources] + +## Troubleshooting Guide + +- Localization Not Taking Effect + - Check whether the `locale` parameter format is as expected; confirm the `locales` map has the corresponding language pack + - Confirm `dayjs.locale` has been correctly set +- Popup Layer Position Anomaly + - Check whether the container returned by `getPopupContainer`/`getTargetContainer` is visible and at the correct z-index level +- Preview Not Available + - Confirm `imageProps.preview` has not been explicitly set to `false`, and at least one of the `mask`/`closeIcon`/`toolbarRender`/`imageRender` slots is available +- Files Inaccessible + - Confirm `resolveFileSrc`'s `rootUrl` and `apiPrefix` are correctly concatenated; use `FileData.url` field if necessary +- Action Items Not Displaying + - Confirm that action items injected via `withActionItemsContextProvider` have been correctly collected and passed to `actions.customActions` + +Section Sources + +- [frontend/antd/config-provider/config-provider.tsx:96-105](file://frontend/antd/config-provider/config-provider.tsx#L96-L105) +- [frontend/antdx/file-card/file-card.tsx:34-123](file://frontend/antdx/file-card/file-card.tsx#L34-L123) +- [frontend/antdx/file-card/base.tsx:15-41](file://frontend/antdx/file-card/base.tsx#L15-L41) +- [frontend/antdx/mermaid/mermaid.tsx:40-84](file://frontend/antdx/mermaid/mermaid.tsx#L40-L84) + +## Conclusion + +This document systematically covers the API and usage of Ant Design X Tool Components in ModelScope Studio, with a focus on the interface highlights and best practices of XProvider global configuration, CodeHighlighter, FileCard, Folder, and Mermaid. Through slot-based design and context providers, the components achieve highly customizable and extensible capabilities within the Gradio ecosystem, suitable for tool integration and content display scenarios in AI applications. + +[This section is a summary and requires no specific file sources] + +## Appendix + +### Component API Quick Reference + +- XProvider + - Main Properties: `themeMode`, `locale`, `getPopupContainer`, `getTargetContainer`, `renderEmpty`, `component`, `className`, `style`, `id` + - Slots: None (injected via parameters and functions) +- CodeHighlighter + - Main Properties: `value`, `themeMode`, `highlightProps`, `header` + - Slots: `header` +- FileCard + - Main Properties: `rootUrl`, `apiPrefix`, `src`, `imageProps`, `spinProps`, `description`, `icon`, `mask` + - Slots: `imageProps.placeholder`, `imageProps.preview.mask`, `imageProps.preview.closeIcon`, `imageProps.preview.toolbarRender`, `imageProps.preview.imageRender`, `description`, `icon`, `mask`, `spinProps.icon`, `spinProps.description`, `spinProps.indicator` +- Folder + - Main Properties: `treeData`, `directoryIcons`, `emptyRender`, `directoryTitle`, `previewTitle`, `previewRender`, `fileContentService` + - Slots: `emptyRender`, `previewRender`, `directoryTitle`, `previewTitle` +- Mermaid + - Main Properties: `value`, `themeMode`, `config`, `actions`, `header` + - Slots: `header`, `actions.customActions` + +Section Sources + +- [frontend/antd/config-provider/config-provider.tsx:51-151](file://frontend/antd/config-provider/config-provider.tsx#L51-L151) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:29-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L29-L51) +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/folder/folder.tsx:16-120](file://frontend/antdx/folder/folder.tsx#L16-L120) +- [frontend/antdx/mermaid/mermaid.tsx:33-84](file://frontend/antdx/mermaid/mermaid.tsx#L33-L84) diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Basic Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Basic Components API.md new file mode 100644 index 00000000..17bbd1ec --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Basic Components API.md @@ -0,0 +1,570 @@ +# Basic Components API + + +**Files referenced in this document** +- [frontend/base/application/Index.svelte](file://frontend/base/application/Index.svelte) +- [frontend/base/auto-loading/Index.svelte](file://frontend/base/auto-loading/Index.svelte) +- [frontend/base/slot/Index.svelte](file://frontend/base/slot/Index.svelte) +- [frontend/base/fragment/Index.svelte](file://frontend/base/fragment/Index.svelte) +- [frontend/base/div/Index.svelte](file://frontend/base/div/Index.svelte) +- [frontend/base/span/Index.svelte](file://frontend/base/span/Index.svelte) +- [frontend/base/text/Index.svelte](file://frontend/base/text/Index.svelte) +- [frontend/base/markdown/Index.svelte](file://frontend/base/markdown/Index.svelte) +- [frontend/base/each/Index.svelte](file://frontend/base/each/Index.svelte) +- [frontend/base/filter/Index.svelte](file://frontend/base/filter/Index.svelte) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the authoritative reference for ModelScope Studio's basic Svelte components, covering the complete API specifications and usage instructions for the following components: Application, AutoLoading, Slot, Fragment, Div, Span, Text, Markdown, Each, and Filter. Content includes: + +- Property definitions and default values +- Event and callback conventions +- Slot system and parameter mapping +- Lifecycle and rendering control (visibility, lazy loading) +- Inter-component communication mechanisms (contexts, slot keys, loading states) +- TypeScript type constraints and interface specifications +- Instantiation and configuration example paths +- Performance optimization and best practices + +## Project Structure + +Base components are located in the `base` directory of the frontend workspace, organized with a "one directory per component" structure. Each component contains an entry `Index.svelte` and corresponding implementation files (`.tsx` or `.svelte`). Components use a unified preprocessing toolchain for property extraction, additional property injection, and lazy loading. + +```mermaid +graph TB +subgraph "Base Components" +APP["application/Index.svelte"] +AL["auto-loading/Index.svelte"] +SLOT["slot/Index.svelte"] +FRAG["fragment/Index.svelte"] +DIV["div/Index.svelte"] +SPAN["span/Index.svelte"] +TEXT["text/Index.svelte"] +MD["markdown/Index.svelte"] +EACH["each/Index.svelte"] +FILT["filter/Index.svelte"] +end +subgraph "Common Utilities" +PREACT["@svelte-preprocess-react/*"] +CLS["classnames"] +end +APP --> PREACT +AL --> PREACT +SLOT --> PREACT +FRAG --> PREACT +DIV --> PREACT +SPAN --> PREACT +TEXT --> PREACT +MD --> PREACT +EACH --> PREACT +FILT --> PREACT +DIV --> CLS +SPAN --> CLS +MD --> CLS +AL --> CLS +``` + +Diagram sources + +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) +- [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) +- [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) +- [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [frontend/base/filter/Index.svelte:1-52](file://frontend/base/filter/Index.svelte#L1-L52) + +Section sources + +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) +- [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) +- [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) +- [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [frontend/base/filter/Index.svelte:1-52](file://frontend/base/filter/Index.svelte#L1-L52) + +## Core Components + +This section systematically covers the key properties, events, slots, and lifecycle of each component, along with type constraints and usage notes. + +- **Application** + - Purpose: Dynamically imports and renders application-level components, with support for lazy loading and `children` rendering. + - Key properties + - `children`: Optional render function for passing child nodes. + - Other properties are extracted by `getProps` and passed through to internal components. + - Lifecycle + - Uses `{#await}` for async rendering, ensuring the component mounts only after the import completes. + - Example path + - [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) + +- **AutoLoading** + - Purpose: Wraps any component, providing visibility, generating state, error state, and style passthrough capabilities. + - Key properties + - `visible`: Controls whether to render. + - `generating`: Indicates the generating state, affecting the loading status. + - `showError`: Whether to display the error state. + - `elem_id`/`elem_classes`/`elem_style`: DOM attribute passthrough. + - `as_item`/`_internal`: Internal flags and container identifiers. + - Other properties are passed through after processing by `getComponentProps`/`processProps`. + - Context + - Reads config type, slot collection, and loading status. + - Example path + - [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) + +- **Slot** + - Purpose: Registers and updates named slots, supporting parameter mapping and visibility control. + - Key properties + - `value`: Slot key value. + - `params_mapping`: Parameter mapping expression string, converted to a function at runtime. + - `visible`/`as_item`/`_internal`: Controls visibility and containerization. + - Behavior + - Detects `value` changes in `effect` and calls `setSlot` to update the context. + - Sets the current slot key and parameter mapping. + - Example path + - [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) + +- **Fragment** + - Purpose: Lightweight container that wraps multiple child nodes without introducing extra DOM. + - Key properties + - `visible`/`_internal`/`as_item`: Controls visibility and containerization. + - Other properties are passed through to the internal Fragment. + - Note + - `shouldResetSlotKey`: Slot key reset is disabled in the configuration. + - Example path + - [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + +- **Div** + - Purpose: Block-level container supporting styles, class names, IDs, and internal layout flags. + - Key properties + - `value`: Text or content value. + - `elem_style`: Inline style object. + - `additional_props`: Additional properties object. + - `_internal.layout`: Marks whether this is a layout-related internal element. + - `visible`/`as_item`/`elem_id`/`elem_classes`: Controls visibility and DOM attributes. + - Example path + - [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) + +- **Span** + - Purpose: Inline container; behaves similarly to Div but with inline semantics. + - Key properties + - `value`: Text or content value. + - `additional_props`: Additional properties object. + - `_internal.layout`: Marks whether this is a layout-related internal element. + - `visible`/`as_item`/`elem_id`/`elem_classes`/`elem_style`: Controls visibility and DOM attributes. + - Example path + - [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) + +- **Text** + - Purpose: Text display component with value and common property passthrough. + - Key properties + - `value`: Text value. + - `visible`/`as_item`/`_internal`: Controls visibility and containerization. + - Example path + - [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) + +- **Markdown** + - Purpose: Markdown rendering component with support for themes, root paths, and slots. + - Key properties + - `value`: Markdown text. + - `elem_id`/`elem_classes`/`elem_style`: DOM attribute passthrough. + - `visible`/`as_item`/`_internal`: Controls visibility and containerization. + - Context + - Reads `root` and `theme` from the shared configuration. + - Reads the slot collection for custom component embedding. + - Example path + - [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) + +- **Each** + - Purpose: List rendering component supporting context merging, index calculation, and placeholders. + - Key properties + - `value`: Array to be rendered. + - `context_value`: Context object. + - `_internal.index`: Internal start index. + - `visible`/`as_item`/`elem_id`/`elem_classes`/`elem_style`: Controls visibility and DOM attributes. + - Behavior + - Uses `EachPlaceholder` to merge external changes and determines whether to force-clone rendering. + - Supports nested Each, calculating sub-indices and slot keys via `getSubIndex` and `getSlotKey`. + - Example path + - [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +- **Filter** + - Purpose: Conditional filter component that wraps `children` into a fragment filterable by parameter mapping. + - Key properties + - `params_mapping`: Parameter mapping expression string. + - `visible`/`as_item`/`_internal`: Controls visibility and containerization. + - Example path + - [frontend/base/filter/Index.svelte:1-52](file://frontend/base/filter/Index.svelte#L1-L52) + +Section sources + +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) +- [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) +- [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) +- [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [frontend/base/filter/Index.svelte:1-52](file://frontend/base/filter/Index.svelte#L1-L52) + +## Architecture Overview + +Base components complete property resolution, additional property injection, and lazy loading through a unified preprocessing pipeline, while leveraging the context system for slot registration, loading state, and config type management. Components collaborate through props and contexts, forming clear responsibility boundaries and composability. + +```mermaid +sequenceDiagram +participant U as "User Code" +participant IDX as "Index.svelte" +participant PRE as "@svelte-preprocess-react/*" +participant CMP as "Internal Component" +participant CTX as "Context (slots/config/loading)" +U->>IDX : Pass props and children +IDX->>PRE : getProps()/processProps() +PRE-->>IDX : Normalized props and additional properties +IDX->>CTX : Read/set slots/config/loading state +IDX->>CMP : Async import and render component +CMP-->>U : Render result +``` + +Diagram sources + +- [frontend/base/auto-loading/Index.svelte:15-52](file://frontend/base/auto-loading/Index.svelte#L15-L52) +- [frontend/base/slot/Index.svelte:16-54](file://frontend/base/slot/Index.svelte#L16-L54) +- [frontend/base/markdown/Index.svelte:19-44](file://frontend/base/markdown/Index.svelte#L19-L44) + +## Detailed Component Analysis + +### Application Component + +- Design highlights + - Uses `importComponent` to dynamically import internal `Application.svelte`. + - Renders `children` as slot content. +- API summary + - Properties + - `children`: Optional render function + - Other properties are extracted by `getProps` and passed through + - Slots + - Default slot: `children()` + - Lifecycle + - `{#await}` async rendering prevents mounting before import completes + +Example path + +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) + +Section sources + +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) + +### AutoLoading Component + +- Design highlights + - Wraps any component, providing visibility, generating state, error state, and style passthrough. + - Integrates with `getLoadingStatus` and config type linkage. +- API summary + - Properties + - `visible`/`generating`/`showError` + - `elem_id`/`elem_classes`/`elem_style` + - `as_item`/`_internal` + - Other properties processed by `processProps` + - Context + - Reads config type, slot collection, and loading status + - Slots + - Default slot: `children()` + +Example path + +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) + +Section sources + +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) + +### Slot Component + +- Design highlights + - Registers named slots with support for parameter mapping and visibility control. + - Detects `value` changes in `effect` and updates the context. +- API summary + - Properties + - `value`: Slot key + - `params_mapping`: Parameter mapping expression + - `visible`/`as_item`/`_internal` + - Behavior + - `setSlotKey`/`setSlotParamsMapping` + - Obtains the host element via `svelte-slot bind:this` + +Example path + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) + +Section sources + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) + +### Fragment Component + +- Design highlights + - Lightweight container that does not introduce extra DOM. + - Slot key reset is disabled to maintain context stability. +- API summary + - Properties + - `visible`/`_internal`/`as_item` + - Other properties are passed through + - Slots + - Default slot: `children()` + +Example path + +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + +Section sources + +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + +### Div Component + +- Design highlights + - Block-level container supporting styles, class names, IDs, and internal layout flags. +- API summary + - Properties + - `value`/`additional_props`/`_internal.layout` + - `elem_id`/`elem_classes`/`elem_style` + - `visible`/`as_item`/`_internal` + - Slots + - Default slot: `children()` + +Example path + +- [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) + +Section sources + +- [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) + +### Span Component + +- Design highlights + - Inline container; behaves similarly to Div. +- API summary + - Properties + - `value`/`additional_props`/`_internal.layout` + - `elem_id`/`elem_classes`/`elem_style` + - `visible`/`as_item`/`_internal` + - Slots + - Default slot: `children()` + +Example path + +- [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) + +Section sources + +- [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) + +### Text Component + +- Design highlights + - Text display component with minimal overhead. +- API summary + - Properties + - `value` + - `visible`/`as_item`/`_internal` + +Example path + +- [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) + +Section sources + +- [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) + +### Markdown Component + +- Design highlights + - Supports themes and root paths, combining with slots for extensible rendering. +- API summary + - Properties + - `value` + - `elem_id`/`elem_classes`/`elem_style` + - `visible`/`as_item`/`_internal` + - Context + - Reads `shared.root` and `theme` + - Reads the slot collection + +Example path + +- [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) + +Section sources + +- [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) + +### Each Component + +- Design highlights + - List rendering with support for context merging, index calculation, and placeholders. + - Nested Each calculates sub-indices and slot keys via `getSubIndex` and `getSlotKey`. +- API summary + - Properties + - `value`/`context_value`/`_internal.index` + - `elem_id`/`elem_classes`/`elem_style` + - `visible`/`as_item`/`_internal` + - Slots + - Default slot: `children()` + - Events + - `EachPlaceholder.onChange`: Receives merged `value` and `contextValue` + +Example path + +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +Section sources + +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +### Filter Component + +- Design highlights + - Conditional filter container that wraps `children` into a fragment filterable by parameter mapping. +- API summary + - Properties + - `params_mapping` + - `visible`/`as_item`/`_internal` + - Slots + - Default slot: `children()` + +Example path + +- [frontend/base/filter/Index.svelte:1-52](file://frontend/base/filter/Index.svelte#L1-L52) + +Section sources + +- [frontend/base/filter/Index.svelte:1-52](file://frontend/base/filter/Index.svelte#L1-L52) + +## Dependency Analysis + +Base components generally depend on the `@svelte-preprocess-react` toolkit and styling libraries, forming a unified property processing and lazy loading mechanism. Some components also depend on the context system for slot registration and loading state management. + +```mermaid +graph LR +subgraph "Utilities" +PRE["@svelte-preprocess-react/*"] +CLS["classnames"] +end +subgraph "Components" +AL["AutoLoading"] +SLOT["Slot"] +MD["Markdown"] +DIV["Div"] +SPAN["Span"] +FRAG["Fragment"] +EACH["Each"] +FILT["Filter"] +end +AL --> PRE +SLOT --> PRE +MD --> PRE +DIV --> PRE +SPAN --> PRE +FRAG --> PRE +EACH --> PRE +FILT --> PRE +DIV -.-> CLS +SPAN -.-> CLS +MD -.-> CLS +AL -.-> CLS +``` + +Diagram sources + +- [frontend/base/auto-loading/Index.svelte:1-10](file://frontend/base/auto-loading/Index.svelte#L1-L10) +- [frontend/base/slot/Index.svelte:1-8](file://frontend/base/slot/Index.svelte#L1-L8) +- [frontend/base/markdown/Index.svelte:1-8](file://frontend/base/markdown/Index.svelte#L1-L8) +- [frontend/base/div/Index.svelte:1-8](file://frontend/base/div/Index.svelte#L1-L8) +- [frontend/base/span/Index.svelte:1-7](file://frontend/base/span/Index.svelte#L1-L7) + +Section sources + +- [frontend/base/auto-loading/Index.svelte:1-10](file://frontend/base/auto-loading/Index.svelte#L1-L10) +- [frontend/base/slot/Index.svelte:1-8](file://frontend/base/slot/Index.svelte#L1-L8) +- [frontend/base/markdown/Index.svelte:1-8](file://frontend/base/markdown/Index.svelte#L1-L8) +- [frontend/base/div/Index.svelte:1-8](file://frontend/base/div/Index.svelte#L1-L8) +- [frontend/base/span/Index.svelte:1-7](file://frontend/base/span/Index.svelte#L1-L7) + +## Performance Considerations + +- Lazy loading + - Use `importComponent` and `{#await}` to load components only when needed, reducing the initial load. +- Visibility control + - Use the `visible` property to quickly show/hide without triggering unnecessary rendering and context updates. +- Slot keys and contexts + - Set slot keys and parameter mappings appropriately to avoid duplicate registration and invalid updates. +- Style passthrough + - Prefer `elem_classes` and `elem_style` to reduce frequent inline style changes. +- List rendering + - The Each component supports placeholder and force-clone strategies; choose as needed to balance performance and consistency. +- Loading state + - AutoLoading combines `generating` and `showError` states to avoid duplicate requests and flickering. + +## Troubleshooting Guide + +- Component not rendering + - Check if the `visible` property is `true`. + - Confirm that the `{#await}` import flow succeeded. +- Slot not taking effect + - Confirm that `Slot`'s `value` and `params_mapping` are correctly set. + - Check that the parent component has correctly registered the slot key. +- Each rendering abnormalities + - Check that `value` is an array and `context_value` is an object. + - For nested Each, confirm the index and slot key calculation logic. +- Markdown theme or resource path issues + - Confirm that `shared.root` and `theme` configurations are correct. +- AutoLoading state out of sync + - Check that `generating` and `showError` are consistent with the business state. + +Section sources + +- [frontend/base/each/Index.svelte:66-104](file://frontend/base/each/Index.svelte#L66-L104) +- [frontend/base/markdown/Index.svelte:47-63](file://frontend/base/markdown/Index.svelte#L47-L63) +- [frontend/base/auto-loading/Index.svelte:65-80](file://frontend/base/auto-loading/Index.svelte#L65-L80) +- [frontend/base/slot/Index.svelte:57-61](file://frontend/base/slot/Index.svelte#L57-L61) + +## Conclusion + +ModelScope Studio's base components achieve a highly cohesive, loosely coupled, and easily composable UI infrastructure through a unified preprocessing pipeline and context system. By following the property specifications, slot conventions, and performance recommendations in this document, stable runtime performance can be achieved while maintaining development efficiency. + +## Appendix + +- TypeScript type constraints and interface specifications + - `getProps()`: Extracts and normalizes component properties from `$props()`, where T is the component property interface. + - `processProps(fn, ..., options)`: Performs secondary processing on component properties, returning derived values. + - Context access: `getConfigType()`/`getSlots()`/`getLoadingStatus()`/`getSetSlot()`, etc. + - Style handling: `classnames` for class name concatenation. +- Best practices + - Prefer using `visible` to control rendering and avoid expensive operations in invisible states. + - Properly separate `value` and `context_value` in Each to improve diff efficiency. + - Use `params_mapping` to encapsulate complex logic as string expressions for easier maintenance. + - For heavy components, combine with AutoLoading and lazy loading to optimize the initial load experience. diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Pro Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Pro Components API.md new file mode 100644 index 00000000..ed47eceb --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Pro Components API.md @@ -0,0 +1,413 @@ +# Pro Components API + + +**Files referenced in this document** +- [frontend/pro/package.json](file://frontend/pro/package.json) +- [frontend/pro/chatbot/package.json](file://frontend/pro/chatbot/package.json) +- [frontend/pro/monaco-editor/package.json](file://frontend/pro/monaco-editor/package.json) +- [frontend/pro/multimodal-input/package.json](file://frontend/pro/multimodal-input/package.json) +- [frontend/pro/web-sandbox/package.json](file://frontend/pro/web-sandbox/package.json) +- [frontend/pro/chatbot/Index.svelte](file://frontend/pro/chatbot/Index.svelte) +- [frontend/pro/monaco-editor/Index.svelte](file://frontend/pro/monaco-editor/Index.svelte) +- [frontend/pro/multimodal-input/Index.svelte](file://frontend/pro/multimodal-input/Index.svelte) +- [frontend/pro/web-sandbox/Index.svelte](file://frontend/pro/web-sandbox/Index.svelte) +- [frontend/pro/chatbot/type.ts](file://frontend/pro/chatbot/type.ts) +- [frontend/pro/monaco-editor/loader.ts](file://frontend/pro/monaco-editor/loader.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the authoritative reference for ModelScope Studio Pro Svelte components, covering the complete API for the following professional components: Chatbot, MultimodalInput, WebSandbox, and MonacoEditor. Content includes: + +- Property definitions and default behaviors +- Event handling and callbacks +- Slot system and rendering extensions +- Advanced capabilities and integration points (such as Gradio shared context) +- Real-time communication and state update mechanisms +- TypeScript types and interface specifications +- Performance optimization and best practices (especially for AI applications) + +## Project Structure + +Pro components are located in the `pro` directory of the frontend workspace. Each component is exported as an independent package, bridged to the underlying React/TSX implementation through Svelte components, and leverages the `getProps`/`processProps`/`importComponent` capabilities provided by `@svelte-preprocess-react` for property passthrough, event writeback, and dynamic loading. + +```mermaid +graph TB +subgraph "Pro Component Packages" +P["@modelscope-studio/pro
Package Info"] +C["@modelscope-studio/pro-chatbot
Package Info"] +M["@modelscope-studio/pro-monaco-editor
Package Info"] +U["@modelscope-studio/pro-multimodal-input
Package Info"] +W["@modelscope-studio/pro-web-sandbox
Package Info"] +end +subgraph "Svelte Bridge Layer" +CI["chatbot/Index.svelte"] +MI["monaco-editor/Index.svelte"] +UI["multimodal-input/Index.svelte"] +WI["web-sandbox/Index.svelte"] +end +subgraph "Runtime Shared Context" +G["gradio.shared.*
root/api_prefix/theme"] +end +P --> CI +P --> MI +P --> UI +P --> WI +C --> CI +M --> MI +U --> UI +W --> WI +CI --> G +MI --> G +UI --> G +WI --> G +``` + +Diagram sources + +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/pro/chatbot/package.json:1-15](file://frontend/pro/chatbot/package.json#L1-L15) +- [frontend/pro/monaco-editor/package.json:1-15](file://frontend/pro/monaco-editor/package.json#L1-L15) +- [frontend/pro/multimodal-input/package.json:1-15](file://frontend/pro/multimodal-input/package.json#L1-L15) +- [frontend/pro/web-sandbox/package.json:1-15](file://frontend/pro/web-sandbox/package.json#L1-L15) +- [frontend/pro/chatbot/Index.svelte:1-90](file://frontend/pro/chatbot/Index.svelte#L1-L90) +- [frontend/pro/monaco-editor/Index.svelte:1-101](file://frontend/pro/monaco-editor/Index.svelte#L1-L101) +- [frontend/pro/multimodal-input/Index.svelte:1-99](file://frontend/pro/multimodal-input/Index.svelte#L1-L99) +- [frontend/pro/web-sandbox/Index.svelte:1-76](file://frontend/pro/web-sandbox/Index.svelte#L1-L76) + +Section sources + +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/pro/chatbot/package.json:1-15](file://frontend/pro/chatbot/package.json#L1-L15) +- [frontend/pro/monaco-editor/package.json:1-15](file://frontend/pro/monaco-editor/package.json#L1-L15) +- [frontend/pro/multimodal-input/package.json:1-15](file://frontend/pro/multimodal-input/package.json#L1-L15) +- [frontend/pro/web-sandbox/package.json:1-15](file://frontend/pro/web-sandbox/package.json#L1-L15) + +## Core Components + +This section provides an overview of the responsibilities and common capabilities of the four professional components: + +- **Chatbot**: Displays and interacts with conversational message streams. Supports composite content including text, tool calls, files, welcome messages, and suggested prompts. Features user/assistant actions (copy, edit, delete, like/dislike, retry) and theme adaptation. +- **MultimodalInput**: Multimodal input entry supporting text and file uploads, with upload hooks and event callbacks for easy integration with Gradio clients. +- **WebSandbox**: A compilable and renderable web sandbox providing compile error/success and render error events, with support for theme mode and slot extensions. +- **MonacoEditor**: A code editor based on Monaco, supporting initialization with local or CDN loaders, with value change events and theme mode. + +Section sources + +- [frontend/pro/chatbot/Index.svelte:1-90](file://frontend/pro/chatbot/Index.svelte#L1-L90) +- [frontend/pro/multimodal-input/Index.svelte:1-99](file://frontend/pro/multimodal-input/Index.svelte#L1-L99) +- [frontend/pro/web-sandbox/Index.svelte:1-76](file://frontend/pro/web-sandbox/Index.svelte#L1-L76) +- [frontend/pro/monaco-editor/Index.svelte:1-101](file://frontend/pro/monaco-editor/Index.svelte#L1-L101) + +## Architecture Overview + +All four components adopt a unified bridging pattern: the Svelte layer handles property resolution, event writeback, dynamic imports, and slot rendering; the underlying TSX components carry the specific UI logic; the runtime shared context (`gradio.shared`) provides global configurations such as `root`, `api_prefix`, and `theme`. + +```mermaid +sequenceDiagram +participant App as "Application" +participant S as "Svelte Bridge Layer" +participant R as "React/TSX Component" +participant G as "Gradio Shared Context" +App->>S : Pass properties and slots +S->>G : Read root/api_prefix/theme +S->>R : Dynamic import and pass properties/events +R-->>S : Value change callback +S->>App : updateProps writes back value +S-->>App : Render slot content +``` + +Diagram sources + +- [frontend/pro/chatbot/Index.svelte:14-64](file://frontend/pro/chatbot/Index.svelte#L14-L64) +- [frontend/pro/monaco-editor/Index.svelte:14-89](file://frontend/pro/monaco-editor/Index.svelte#L14-L89) +- [frontend/pro/multimodal-input/Index.svelte:17-66](file://frontend/pro/multimodal-input/Index.svelte#L17-L66) +- [frontend/pro/web-sandbox/Index.svelte:14-57](file://frontend/pro/web-sandbox/Index.svelte#L14-L57) + +## Detailed Component Analysis + +### Chatbot Component API + +- Package exports and entry point + - Package name and export mapping follow the standard; the main entry points to `Index.svelte`. +- Property definitions + - `additional_props`: Additional property passthrough + - `as_item`: Element identifier + - `_internal`: Internal layout flag + - `value`: Message array, type see `ChatbotMessages` + - `suggestion_select` / `welcome_prompt_select`: Event callback alias mappings + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` + - Runtime shared: `gradio.shared.root`, `gradio.shared.api_prefix`, `gradio.shared.theme` +- Events and callbacks + - `onValueChange`: Value change writeback to parent component +- Slot system + - Supports `children` slot and `slots` mapping +- Data model and types + - `ChatbotMessages`, `ChatbotMessage`, `ChatbotMessageContentObject`, action types (`like`/`dislike`/`retry`/`copy`/`edit`/`delete`), etc. +- Advanced features + - Theme mode inherited from `gradio.shared.theme` + - Built-in composite display of welcome messages, suggested prompts, files/tools/text content +- Usage examples (paths) + - Basic usage and value binding: [frontend/pro/chatbot/Index.svelte:76-84](file://frontend/pro/chatbot/Index.svelte#L76-L84) + - Event writeback: [frontend/pro/chatbot/Index.svelte:76-80](file://frontend/pro/chatbot/Index.svelte#L76-L80) + - Type definition reference: [frontend/pro/chatbot/type.ts:160-197](file://frontend/pro/chatbot/type.ts#L160-L197) + +```mermaid +classDiagram +class ChatbotMessage { ++role ++content ++status ++meta ++key +} +class ChatbotMessages { +} +class ChatbotMessageContentObject { ++type ++content ++options +} +ChatbotMessages --> ChatbotMessage +ChatbotMessage --> ChatbotMessageContentObject +``` + +Diagram sources + +- [frontend/pro/chatbot/type.ts:137-158](file://frontend/pro/chatbot/type.ts#L137-L158) +- [frontend/pro/chatbot/type.ts:121-135](file://frontend/pro/chatbot/type.ts#L121-L135) + +Section sources + +- [frontend/pro/chatbot/package.json:1-15](file://frontend/pro/chatbot/package.json#L1-L15) +- [frontend/pro/chatbot/Index.svelte:14-64](file://frontend/pro/chatbot/Index.svelte#L14-L64) +- [frontend/pro/chatbot/Index.svelte:76-84](file://frontend/pro/chatbot/Index.svelte#L76-L84) +- [frontend/pro/chatbot/type.ts:160-197](file://frontend/pro/chatbot/type.ts#L160-L197) + +### MultimodalInput Component API + +- Package exports and entry point + - Package name and export mapping follow the standard; the main entry points to `Index.svelte`. +- Property definitions + - `additional_props`: Additional property passthrough + - `_internal`: Internal flag + - `value`: Multimodal input value, type from the underlying component + - `key_press` / `paste_file` / `key_down`: Event callback alias mappings + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` + - Runtime shared: `gradio.shared.theme` +- Events and callbacks + - `onValueChange`: Value change writeback +- Slot system + - Supports `children` slot and `slots` mapping +- File upload + - Upload hook: Uploads files via `gradio.shared.client.upload`, returns `FileData[]` +- Usage examples (paths) + - Value binding and event writeback: [frontend/pro/multimodal-input/Index.svelte:88-92](file://frontend/pro/multimodal-input/Index.svelte#L88-L92) + - Upload flow: [frontend/pro/multimodal-input/Index.svelte:68-75](file://frontend/pro/multimodal-input/Index.svelte#L68-L75) + +```mermaid +sequenceDiagram +participant UI as "MultimodalInput" +participant GR as "Gradio Client" +participant SV as "Svelte Bridge Layer" +UI->>GR : upload(prepare_files(files)) +GR-->>UI : FileData[] +UI->>SV : updateProps({ value }) +``` + +Diagram sources + +- [frontend/pro/multimodal-input/Index.svelte:68-75](file://frontend/pro/multimodal-input/Index.svelte#L68-L75) +- [frontend/pro/multimodal-input/Index.svelte:88-92](file://frontend/pro/multimodal-input/Index.svelte#L88-L92) + +Section sources + +- [frontend/pro/multimodal-input/package.json:1-15](file://frontend/pro/multimodal-input/package.json#L1-L15) +- [frontend/pro/multimodal-input/Index.svelte:17-66](file://frontend/pro/multimodal-input/Index.svelte#L17-L66) +- [frontend/pro/multimodal-input/Index.svelte:68-75](file://frontend/pro/multimodal-input/Index.svelte#L68-L75) + +### WebSandbox Component API + +- Package exports and entry point + - Package name and export mapping follow the standard; the main entry points to `Index.svelte`. +- Property definitions + - `additional_props`: Additional property passthrough + - `_internal`: Internal flag + - `value`: Sandbox value, type from the underlying component + - `compile_error` / `compile_success` / `render_error`: Event callback alias mappings + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` + - Runtime shared: `gradio.shared.theme` +- Slot system + - Supports `children` slot and `slots` mapping +- Usage examples (paths) + - Value binding and theme: [frontend/pro/web-sandbox/Index.svelte:62-70](file://frontend/pro/web-sandbox/Index.svelte#L62-L70) + +```mermaid +flowchart TD +Start(["Start"]) --> CheckVisible["Check visible"] +CheckVisible --> |No| End(["End"]) +CheckVisible --> |Yes| Load["Dynamically load WebSandbox"] +Load --> Render["Render and pass value/slots/theme"] +Render --> End +``` + +Diagram sources + +- [frontend/pro/web-sandbox/Index.svelte:60-75](file://frontend/pro/web-sandbox/Index.svelte#L60-L75) + +Section sources + +- [frontend/pro/web-sandbox/package.json:1-15](file://frontend/pro/web-sandbox/package.json#L1-L15) +- [frontend/pro/web-sandbox/Index.svelte:14-57](file://frontend/pro/web-sandbox/Index.svelte#L14-L57) +- [frontend/pro/web-sandbox/Index.svelte:62-70](file://frontend/pro/web-sandbox/Index.svelte#L62-L70) + +### MonacoEditor Component API + +- Package exports and entry point + - Package name and export mapping follow the standard; the main entry points to `Index.svelte`. +- Property definitions + - `additional_props`: Additional property passthrough + - `_internal`: Internal flag + - `value`: Editor initial value + - `_loader`: Loader configuration + - `mode`: `'cdn'` | `'local'` + - `cdn_url`: CDN path + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` + - Runtime shared: `gradio.shared.theme` +- Events and callbacks + - `onValueChange`: Value change writeback +- Slot system + - Supports `children` slot and `slots` mapping +- Loader mechanism + - Local loading: Initializes Monaco and registers Workers by language + - CDN loading: Sets the `vs` path +- Usage examples (paths) + - Value binding and theme: [frontend/pro/monaco-editor/Index.svelte:79-89](file://frontend/pro/monaco-editor/Index.svelte#L79-L89) + - Loader selection and initialization: [frontend/pro/monaco-editor/Index.svelte:61-70](file://frontend/pro/monaco-editor/Index.svelte#L61-L70) + - Loader implementation: [frontend/pro/monaco-editor/loader.ts:27-94](file://frontend/pro/monaco-editor/loader.ts#L27-L94) + +```mermaid +flowchart TD +A["Select Loader"] --> B{"mode=local?"} +B --> |Yes| C["initLocalLoader()
Register Monaco and Workers"] +B --> |No| D{"cdn_url present?"} +D --> |Yes| E["initCDNLoader(cdn_url)
Set vs path"] +D --> |No| F["Use default configuration"] +C --> G["Done"] +E --> G +F --> G +``` + +Diagram sources + +- [frontend/pro/monaco-editor/Index.svelte:61-70](file://frontend/pro/monaco-editor/Index.svelte#L61-L70) +- [frontend/pro/monaco-editor/loader.ts:27-94](file://frontend/pro/monaco-editor/loader.ts#L27-L94) + +Section sources + +- [frontend/pro/monaco-editor/package.json:1-15](file://frontend/pro/monaco-editor/package.json#L1-L15) +- [frontend/pro/monaco-editor/Index.svelte:14-89](file://frontend/pro/monaco-editor/Index.svelte#L14-L89) +- [frontend/pro/monaco-editor/loader.ts:27-94](file://frontend/pro/monaco-editor/loader.ts#L27-L94) + +## Dependency Analysis + +- Unified dependency chain + - The Svelte bridge layer depends on `getProps`/`processProps`/`importComponent` and slot utilities from `@svelte-preprocess-react` + - Each component obtains shared configuration (`root`, `api_prefix`, `theme`) through `gradio.shared` + - File upload capability comes from `prepare_files` and `client.upload` of `@gradio/client` +- Inter-component coupling + - Low coupling: Each component independently maintains its own properties and events + - High cohesion: The bridge layer handles property processing and dynamic loading; underlying components focus on UI logic + +```mermaid +graph LR +SP["@svelte-preprocess-react/*"] --> BR["Svelte Bridge Layer"] +BR --> CH["Chatbot"] +BR --> ME["MonacoEditor"] +BR --> MU["MultimodalInput"] +BR --> WS["WebSandbox"] +GC["@gradio/client"] --> MU +GS["gradio.shared.*"] --> BR +``` + +Diagram sources + +- [frontend/pro/chatbot/Index.svelte:1-12](file://frontend/pro/chatbot/Index.svelte#L1-L12) +- [frontend/pro/monaco-editor/Index.svelte:1-12](file://frontend/pro/monaco-editor/Index.svelte#L1-L12) +- [frontend/pro/multimodal-input/Index.svelte:1-9](file://frontend/pro/multimodal-input/Index.svelte#L1-L9) +- [frontend/pro/web-sandbox/Index.svelte:1-8](file://frontend/pro/web-sandbox/Index.svelte#L1-L8) + +Section sources + +- [frontend/pro/chatbot/Index.svelte:1-12](file://frontend/pro/chatbot/Index.svelte#L1-L12) +- [frontend/pro/monaco-editor/Index.svelte:1-12](file://frontend/pro/monaco-editor/Index.svelte#L1-L12) +- [frontend/pro/multimodal-input/Index.svelte:1-9](file://frontend/pro/multimodal-input/Index.svelte#L1-L9) +- [frontend/pro/web-sandbox/Index.svelte:1-8](file://frontend/pro/web-sandbox/Index.svelte#L1-L8) + +## Performance Considerations + +- Dynamic imports and lazy loading + - Use `importComponent` to dynamically import underlying components to avoid blocking the initial render +- Computed properties and derived values + - Use `$derived` to reuse derived computations and reduce unnecessary re-renders +- Loader strategy + - MonacoEditor supports both local and CDN loaders; choose as needed to balance bundle size and network overhead +- Event writeback + - Trigger `updateProps` only when values change to avoid frequent writebacks +- File upload + - Use `prepare_files` and the Gradio client for uploads to reduce manual serialization costs + +## Troubleshooting Guide + +- Editor not loading + - Check that `_loader.mode` and `cdn_url` configurations are correct + - Confirm that `initCDNLoader`/`initLocalLoader` has completed initialization + - Reference: [frontend/pro/monaco-editor/Index.svelte:61-70](file://frontend/pro/monaco-editor/Index.svelte#L61-L70), [frontend/pro/monaco-editor/loader.ts:27-94](file://frontend/pro/monaco-editor/loader.ts#L27-L94) +- Upload failing + - Confirm that `gradio.shared.client` is available and `root` is correct + - Check `prepare_files` and the returned `FileData[]` + - Reference: [frontend/pro/multimodal-input/Index.svelte:68-75](file://frontend/pro/multimodal-input/Index.svelte#L68-L75) +- Theme not applied + - Confirm that `gradio.shared.theme` is set to `light`/`dark` + - Reference: [frontend/pro/chatbot/Index.svelte:83](file://frontend/pro/chatbot/Index.svelte#L83), [frontend/pro/web-sandbox/Index.svelte:70](file://frontend/pro/web-sandbox/Index.svelte#L70), [frontend/pro/monaco-editor/Index.svelte:88](file://frontend/pro/monaco-editor/Index.svelte#L88) + +Section sources + +- [frontend/pro/monaco-editor/Index.svelte:61-70](file://frontend/pro/monaco-editor/Index.svelte#L61-L70) +- [frontend/pro/monaco-editor/loader.ts:27-94](file://frontend/pro/monaco-editor/loader.ts#L27-L94) +- [frontend/pro/multimodal-input/Index.svelte:68-75](file://frontend/pro/multimodal-input/Index.svelte#L68-L75) +- [frontend/pro/chatbot/Index.svelte:83](file://frontend/pro/chatbot/Index.svelte#L83) +- [frontend/pro/web-sandbox/Index.svelte:70](file://frontend/pro/web-sandbox/Index.svelte#L70) +- [frontend/pro/monaco-editor/Index.svelte:88](file://frontend/pro/monaco-editor/Index.svelte#L88) + +## Conclusion + +This reference document systematically covers the API and implementation details of ModelScope Studio's Pro Svelte components, emphasizing the unified pattern of the bridge layer, the use of the runtime shared context, and deep integration with the Gradio ecosystem. Through well-designed properties, event writeback, and dynamic loading strategies, these components efficiently support core AI application scenarios such as conversation, code editing, multimodal input, and sandbox rendering. + +## Appendix + +- TypeScript types and interfaces + - Chatbot types: [frontend/pro/chatbot/type.ts:1-197](file://frontend/pro/chatbot/type.ts#L1-L197) +- Package exports and entry points + - Chatbot: [frontend/pro/chatbot/package.json:1-15](file://frontend/pro/chatbot/package.json#L1-L15) + - MonacoEditor: [frontend/pro/monaco-editor/package.json:1-15](file://frontend/pro/monaco-editor/package.json#L1-L15) + - MultimodalInput: [frontend/pro/multimodal-input/package.json:1-15](file://frontend/pro/multimodal-input/package.json#L1-L15) + - WebSandbox: [frontend/pro/web-sandbox/package.json:1-15](file://frontend/pro/web-sandbox/package.json#L1-L15) +- Component bridge implementations + - Chatbot: [frontend/pro/chatbot/Index.svelte:1-90](file://frontend/pro/chatbot/Index.svelte#L1-L90) + - MonacoEditor: [frontend/pro/monaco-editor/Index.svelte:1-101](file://frontend/pro/monaco-editor/Index.svelte#L1-L101) + - MultimodalInput: [frontend/pro/multimodal-input/Index.svelte:1-99](file://frontend/pro/multimodal-input/Index.svelte#L1-L99) + - WebSandbox: [frontend/pro/web-sandbox/Index.svelte:1-76](file://frontend/pro/web-sandbox/Index.svelte#L1-L76) diff --git a/.wiki/en/API Reference/JavaScript API/Svelte Component API/Svelte Components API.md b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Svelte Components API.md new file mode 100644 index 00000000..9784d1f0 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Svelte Component API/Svelte Components API.md @@ -0,0 +1,415 @@ +# Svelte Components API + + +**Files referenced in this document** +- [frontend/package.json](file://frontend/package.json) +- [frontend/tsconfig.json](file://frontend/tsconfig.json) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/form/Index.svelte](file://frontend/antd/form/Index.svelte) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/layout/Index.svelte](file://frontend/antd/layout/Index.svelte) +- [frontend/antd/modal/Index.svelte](file://frontend/antd/modal/Index.svelte) +- [frontend/antd/table/Index.svelte](file://frontend/antd/table/Index.svelte) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/createFunction.ts](file://frontend/utils/createFunction.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Best Practices](#performance-and-best-practices) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference for ModelScope Studio frontend Svelte components, focusing on the Svelte component encapsulation system based on the Ant Design (Antd) ecosystem. The document covers: + +- Component property definitions: props interfaces, default values, and type constraints +- Event system: user interaction events, state change events, and custom events +- Slot system: usage of default slots, named slots, and scoped slots +- Lifecycle and rendering: component instantiation, async loading, and conditional rendering +- Inter-component communication: parent-child, sibling, and cross-level communication patterns +- Style customization: CSS class names, theme variables, and inline styles +- TypeScript types: interface specifications, generic usage, and type inference +- Performance optimization: on-demand loading, derived computation, and event throttling recommendations + +## Project Structure + +The frontend uses a multi-package organization, with core components in `frontend/antd` and `frontend/antdx`, implementing Antd components in Svelte through the Svelte 5 and React component bridging solution. + +```mermaid +graph TB +subgraph "Frontend Packages" +A["frontend/package.json"] +B["frontend/tsconfig.json"] +end +subgraph "Antd Component Layer" +BTN["antd/button/Index.svelte"] +BTN_TS["antd/button/button.tsx"] +FORM["antd/form/Index.svelte"] +FORM_TS["antd/form/form.tsx"] +LYT["antd/layout/Index.svelte"] +MODAL["antd/modal/Index.svelte"] +TAB["antd/table/Index.svelte"] +end +subgraph "Common Utilities" +RS["utils/renderSlot.tsx"] +CF["utils/createFunction.ts"] +end +A --> BTN +A --> FORM +A --> LYT +A --> MODAL +A --> TAB +BTN --> BTN_TS +FORM --> FORM_TS +BTN_TS --> RS +FORM_TS --> RS +BTN_TS --> CF +FORM_TS --> CF +``` + +**Diagram sources** + +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/modal/Index.svelte:1-63](file://frontend/antd/modal/Index.svelte#L1-L63) +- [frontend/antd/table/Index.svelte:1-61](file://frontend/antd/table/Index.svelte#L1-L61) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) + +**Section sources** + +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) + +## Core Components + +This section provides an overview of the responsibilities and common characteristics of the main components: + +- **Button**: Wraps Antd Button, supports icon and loading state slots, with visibility control and class name concatenation. +- **Form**: Wraps Antd Form, provides value synchronization, action triggers (reset/submit/validate), required mark, and feedback icon slots. +- **Layout**: Basic layout container that passes through children and component identifiers. +- **Modal**: Wraps Antd Modal, supports visibility control and slots. +- **Table**: Wraps Antd Table, supports visibility control and slots. + +**Section sources** + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/modal/Index.svelte:1-63](file://frontend/antd/modal/Index.svelte#L1-L63) +- [frontend/antd/table/Index.svelte:1-61](file://frontend/antd/table/Index.svelte#L1-L61) + +## Architecture Overview + +Components adopt a three-layer architecture of "Svelte layer + React wrapping layer + utility functions": + +- Svelte layer: Responsible for property collection, slot resolution, conditional rendering, and async loading. +- React wrapping layer: Uses `sveltify` to bridge Antd components for use in Svelte, handling slots and callbacks. +- Utility functions: Provides slot rendering, function-string-to-function conversion, and other capabilities. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Component Layer (Index.svelte)" +participant Utils as "Utilities (renderSlot.tsx/createFunction.ts)" +participant ReactComp as "React Wrapping Layer (button.tsx/form.tsx)" +participant Antd as "Antd Component" +Svelte->>Svelte : Collect props and slots +Svelte->>ReactComp : Async import and pass props +ReactComp->>Utils : Render slots / wrap functions +ReactComp->>Antd : Render Antd component +Antd-->>ReactComp : Callback events +ReactComp-->>Svelte : Trigger update/action +``` + +**Diagram sources** + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) + +## Component Details + +### Button + +- Responsibility: Exposes Antd Button as a Svelte component, supports icon and loading state slots; conditionally renders based on visibility; concatenates style class names. +- Key props + - `additional_props?: Record`: Additional property passthrough + - `value?: string | undefined`: Button text or value + - `as_item?: string | undefined`: Used as item identifier + - `_internal: { layout?: boolean }`: Internal layout flag + - `href_target?: string`: Link target attribute mapping + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` +- Event system + - Events triggered by the underlying Antd Button are passed through via `{...props}` +- Slot system + - `icon`: Icon slot + - `loading.icon`: Loading state icon slot +- Lifecycle and rendering + - Uses `importComponent` to asynchronously load the wrapper component + - Conditional rendering: only renders when `visible` is true +- Style customization + - Inline `style` and `className` passthrough + - Fixed class name: `ms-gr-antd-button` +- TypeScript types + - Wraps Antd Button's `GetProps` type via `sveltify` + - Slot allowlist: `['icon', 'loading.icon']` + +```mermaid +classDiagram +class ButtonWrapper { ++props : AdditionalProps ++value : string|undefined ++as_item : string|undefined ++_internal : Internal ++href_target : string ++visible : boolean ++elem_id : string ++elem_classes : string[] ++elem_style : Record +} +class AntdButton { ++props : AntdButtonProps ++slots : Slots ++value : string +} +ButtonWrapper --> AntdButton : "sveltify wrapper" +``` + +**Diagram sources** + +- [frontend/antd/button/Index.svelte:12-56](file://frontend/antd/button/Index.svelte#L12-L56) +- [frontend/antd/button/button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) + +**Section sources** + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) + +### Form + +- Responsibility: Wraps Antd Form to provide value synchronization, action triggering, and slot extensions. +- Key props + - `additional_props?: Record` + - `_internal: { layout?: boolean }` + - `value?: Record`: Form initial values + - `form_action?: FormProps['formAction'] | null`: Action command (`reset`/`submit`/`validate`/`null`) + - `form_name?: string`: Form name mapping + - `fields_change?: any`, `finish_failed?: any`, `values_change?: any`: Event mapping + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` +- Event system + - `onValueChange(value: Record)`: Value change callback + - `onResetFormAction()`: Resets `form_action` after action execution +- Slot system + - `requiredMark`: Required mark slot +- Lifecycle and rendering + - Uses `importComponent` to asynchronously load the wrapper component + - Conditional rendering: only renders when `visible` is true +- Style customization + - Inline `style` and `className` passthrough + - Fixed class name: `ms-gr-antd-form` +- TypeScript types + - `FormProps` extends Antd Form Props, adding `value`, `onValueChange`, `formAction`, `onResetFormAction` + - Slot allowlist: `['requiredMark']` + +```mermaid +sequenceDiagram +participant S as "Svelte Form (Index.svelte)" +participant R as "React Form (form.tsx)" +participant F as "Antd Form" +participant U as "Utilities (createFunction.ts)" +S->>R : Pass props and slots +R->>U : Required mark / feedback icon function wrapping +R->>F : Render Antd Form and bind onValuesChange +F-->>R : Trigger onValuesChange(changedValues, values) +R-->>S : onValueChange(values) +S->>S : updateProps({ value }) +``` + +**Diagram sources** + +- [frontend/antd/form/Index.svelte:14-98](file://frontend/antd/form/Index.svelte#L14-L98) +- [frontend/antd/form/form.tsx:8-76](file://frontend/antd/form/form.tsx#L8-L76) +- [frontend/utils/createFunction.ts:10-37](file://frontend/utils/createFunction.ts#L10-L37) + +**Section sources** + +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +### Layout + +- Responsibility: Basic layout container that passes through children and component identifiers. +- Key props + - `children: Snippet`: Default slot content +- Lifecycle and rendering + - Directly renders the Base container component as a layout +- Style customization + - Styles and class names are handled by the Base component + +**Section sources** + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) + +### Modal + +- Responsibility: Wraps Antd Modal, supports visibility control and slots. +- Key props + - `additional_props?: Record` + - `as_item?: string | undefined` + - `_internal: { layout?: boolean }` + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` +- Slot system + - Default slot: Content area +- Style customization + - Fixed class name: `ms-gr-antd-modal` + +**Section sources** + +- [frontend/antd/modal/Index.svelte:1-63](file://frontend/antd/modal/Index.svelte#L1-L63) + +### Table + +- Responsibility: Wraps Antd Table, supports visibility control and slots. +- Key props + - `additional_props?: Record` + - `as_item?: string | undefined` + - `_internal: {}` + - Visibility and style: `visible`, `elem_id`, `elem_classes`, `elem_style` +- Slot system + - Default slot: Content area +- Style customization + - Fixed class name: `ms-gr-antd-table` + +**Section sources** + +- [frontend/antd/table/Index.svelte:1-61](file://frontend/antd/table/Index.svelte#L1-L61) + +## Dependency Analysis + +- Component dependencies + - The Svelte layer depends on `getProps`/`importComponent`/`processProps`/`getSlots` provided by `@svelte-preprocess-react` + - The React wrapping layer depends on the Ant Design component library and `sveltify`/`ReactSlot` from `@svelte-preprocess-react` + - The utility layer provides slot rendering and function-string parsing capabilities +- External dependencies + - Svelte 5, Antd, classnames, dayjs, immer, lodash-es, marked, mermaid, monaco-editor, etc. + +```mermaid +graph LR +IDX_BTN["button/Index.svelte"] --> WRAP_BTN["button/button.tsx"] +IDX_FORM["form/Index.svelte"] --> WRAP_FORM["form/form.tsx"] +WRAP_BTN --> SLOT["utils/renderSlot.tsx"] +WRAP_FORM --> SLOT +WRAP_BTN --> CF["utils/createFunction.ts"] +WRAP_FORM --> CF +``` + +**Diagram sources** + +- [frontend/antd/button/Index.svelte:6-7](file://frontend/antd/button/Index.svelte#L6-L7) +- [frontend/antd/button/button.tsx:1-6](file://frontend/antd/button/button.tsx#L1-L6) +- [frontend/antd/form/Index.svelte:6-7](file://frontend/antd/form/Index.svelte#L6-L7) +- [frontend/antd/form/form.tsx:1-6](file://frontend/antd/form/form.tsx#L1-L6) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) + +**Section sources** + +- [frontend/package.json:8-39](file://frontend/package.json#L8-L39) + +## Performance and Best Practices + +- On-demand loading + - Use `importComponent` to asynchronously import React wrapper components to avoid blocking the initial render +- Derived computation + - Use `$derived` to derive from props and reduce redundant computation +- Event throttling and debouncing + - For frequently-triggered callbacks (such as `onValuesChange`), throttle/debounce can be combined with utility functions +- Slot rendering optimization + - Use `forceClone` and `params` judiciously to avoid unnecessary cloning overhead +- Styles and themes + - Prefer combining `className` with inline styles; introduce Antd theme variables when necessary to ensure consistency + +[This section provides general guidance and does not require specific file references] + +## Troubleshooting Guide + +- Slot not taking effect + - Check if the slot name matches the wrapper layer allowlist (e.g., `icon`, `loading.icon`, `requiredMark`) + - Confirm that slot elements are properly passed to `slots` +- Function string cannot execute + - Use `createFunction` to convert the string to a function; ensure the format is valid +- Action not triggered + - Confirm the `form_action` value matches the wrapper layer switch branch (`reset`/`submit`/`validate`/`null`) + - Call `onResetFormAction` promptly after action execution to reset the state +- Visibility issues + - Ensure the component is only rendered when `visible` is truthy to avoid empty rendering + +**Section sources** + +- [frontend/antd/button/button.tsx:10-36](file://frontend/antd/button/button.tsx#L10-L36) +- [frontend/antd/form/form.tsx:32-45](file://frontend/antd/form/form.tsx#L32-L45) +- [frontend/utils/createFunction.ts:10-37](file://frontend/utils/createFunction.ts#L10-L37) + +## Conclusion + +ModelScope Studio's Svelte Component API achieves stable use of Antd components in Svelte through a unified bridge layer and utility functions. Its design emphasizes: + +- Clear props interfaces and type constraints +- Rich slot system and event mapping +- Controllable rendering and style strategies +- Extensible toolchain to support complex scenarios + +[This section is a summary and does not require specific file references] + +## Appendix + +### Component Properties and Events Quick Reference (Summary) + +- **Button** + - Properties: `additional_props`, `value`, `as_item`, `_internal`, `href_target`, `visible`, `elem_id`, `elem_classes`, `elem_style` + - Events: Passed through from Antd Button + - Slots: `icon`, `loading.icon` + - Class name: Fixed `ms-gr-antd-button` +- **Form** + - Properties: `additional_props`, `_internal`, `value`, `form_action`, `form_name`, `fields_change`, `finish_failed`, `values_change`, `visible`, `elem_id`, `elem_classes`, `elem_style` + - Events: `onValueChange`, `onResetFormAction` + - Slots: `requiredMark` + - Class name: Fixed `ms-gr-antd-form` +- **Layout** + - Properties: `children` (default slot) +- **Modal** + - Properties: `additional_props`, `as_item`, `_internal`, `visible`, `elem_id`, `elem_classes`, `elem_style` + - Class name: Fixed `ms-gr-antd-modal` +- **Table** + - Properties: `additional_props`, `as_item`, `_internal`, `visible`, `elem_id`, `elem_classes`, `elem_style` + - Class name: Fixed `ms-gr-antd-table` + +**Section sources** + +- [frontend/antd/button/Index.svelte:12-56](file://frontend/antd/button/Index.svelte#L12-L56) +- [frontend/antd/button/button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) +- [frontend/antd/form/Index.svelte:14-98](file://frontend/antd/form/Index.svelte#L14-L98) +- [frontend/antd/form/form.tsx:8-76](file://frontend/antd/form/form.tsx#L8-L76) +- [frontend/antd/layout/Index.svelte:6-14](file://frontend/antd/layout/Index.svelte#L6-L14) +- [frontend/antd/modal/Index.svelte:22-44](file://frontend/antd/modal/Index.svelte#L22-L44) +- [frontend/antd/table/Index.svelte:20-42](file://frontend/antd/table/Index.svelte#L20-L42) diff --git a/.wiki/en/API Reference/JavaScript API/Utility Functions API.md b/.wiki/en/API Reference/JavaScript API/Utility Functions API.md new file mode 100644 index 00000000..48260000 --- /dev/null +++ b/.wiki/en/API Reference/JavaScript API/Utility Functions API.md @@ -0,0 +1,582 @@ +# Utility Functions API + + +**Files referenced in this document** +- [convertToCamelCase.ts](file://frontend/utils/convertToCamelCase.ts) +- [patchProps.tsx](file://frontend/utils/patchProps.tsx) +- [omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) +- [renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [patchSlots.ts](file://frontend/utils/patchSlots.ts) +- [style.ts](file://frontend/utils/style.ts) +- [upload.ts](file://frontend/utils/upload.ts) +- [walkHtmlNodes.ts](file://frontend/utils/walkHtmlNodes.ts) +- [createFunction.ts](file://frontend/utils/createFunction.ts) +- [tick.ts](file://frontend/utils/tick.ts) +- [renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [useMemoizedEqualValue.ts](file://frontend/utils/hooks/useMemoizedEqualValue.ts) +- [useMemoizedFn.ts](file://frontend/utils/hooks/useMemoizedFn.ts) +- [useSlotsChildren.ts](file://frontend/utils/hooks/useSlotsChildren.ts) +- [useTargets.ts](file://frontend/utils/hooks/useTargets.ts) +- [useUpdate.ts](file://frontend/utils/hooks/useUpdate.ts) +- [useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the API reference and usage guide for the ModelScope Studio frontend utility function system, covering the following topics: + +- Property handling: `convertToCamelCase`, `patchProps`, `omitUndefinedProps`, etc. +- Slot handling: `renderSlot`, `renderItems`, `patchSlots`, `renderParamsSlot` +- Style handling: Style computation and application in `style.ts` +- Upload handling: URL resolution and file address conversion in `upload.ts` +- HTML traversal: Node finding and callbacks in `walkHtmlNodes` +- Functions and hooks: `createFunction`, hooks series (`useFunction`, `useMemoizedFn`, `useMemoizedEqualValue`, `useSlotsChildren`, `useTargets`, `useUpdate`, `useValueChange`) +- Practical usage examples, performance characteristics and best practices, error handling and edge cases + +## Project Structure + +Utility functions are centralized in the `frontend/utils` directory, organized by functional layers; the `hooks` subdirectory provides React Hooks wrappers. + +```mermaid +graph TB +subgraph "Utility Functions (utils)" +A["convertToCamelCase.ts"] +B["patchProps.tsx"] +C["omitUndefinedProps.ts"] +D["renderSlot.tsx"] +E["renderItems.tsx"] +F["patchSlots.ts"] +G["style.ts"] +H["upload.ts"] +I["walkHtmlNodes.ts"] +J["createFunction.ts"] +K["tick.ts"] +L["renderParamsSlot.tsx"] +end +subgraph "Hooks" +H1["useFunction.ts"] +H2["useMemoizedFn.ts"] +H3["useMemoizedEqualValue.ts"] +H4["useSlotsChildren.ts"] +H5["useTargets.ts"] +H6["useUpdate.ts"] +H7["useValueChange.ts"] +end +D --> B +E --> B +L --> D +H1 --> J +``` + +Diagram sources + +- [renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- [patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [upload.ts:1-45](file://frontend/utils/upload.ts#L1-L45) +- [walkHtmlNodes.ts:1-19](file://frontend/utils/walkHtmlNodes.ts#L1-L19) +- [createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) +- [tick.ts:1-13](file://frontend/utils/tick.ts#L1-L13) +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useMemoizedFn.ts:1-11](file://frontend/utils/hooks/useMemoizedFn.ts#L1-L11) +- [useMemoizedEqualValue.ts:1-15](file://frontend/utils/hooks/useMemoizedEqualValue.ts#L1-L15) +- [useSlotsChildren.ts:1-24](file://frontend/utils/hooks/useSlotsChildren.ts#L1-L24) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [useUpdate.ts:1-7](file://frontend/utils/hooks/useUpdate.ts#L1-L7) +- [useValueChange.ts:1-30](file://frontend/utils/hooks/useValueChange.ts#L1-L30) + +Section sources + +- [convertToCamelCase.ts:1-22](file://frontend/utils/convertToCamelCase.ts#L1-L22) +- [patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- [omitUndefinedProps.ts:1-17](file://frontend/utils/omitUndefinedProps.ts#L1-L17) +- [renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [upload.ts:1-45](file://frontend/utils/upload.ts#L1-L45) +- [walkHtmlNodes.ts:1-19](file://frontend/utils/walkHtmlNodes.ts#L1-L19) +- [createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) +- [tick.ts:1-13](file://frontend/utils/tick.ts#L1-L13) +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useMemoizedFn.ts:1-11](file://frontend/utils/hooks/useMemoizedFn.ts#L1-L11) +- [useMemoizedEqualValue.ts:1-15](file://frontend/utils/hooks/useMemoizedEqualValue.ts#L1-L15) +- [useSlotsChildren.ts:1-24](file://frontend/utils/hooks/useSlotsChildren.ts#L1-L24) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [useUpdate.ts:1-7](file://frontend/utils/hooks/useUpdate.ts#L1-L7) +- [useValueChange.ts:1-30](file://frontend/utils/hooks/useValueChange.ts#L1-L30) + +## Core Components + +- Property handling + - `convertToCamelCase`: Converts underscore-style strings to camelCase; `convertObjectKeyToCamelCase`: Batch converts object key names + - `patchProps`/`applyPatchToProps`: Internal marking and restoration for key conflicts + - `omitUndefinedProps`: Filters out undefined (optionally also null) properties +- Slot handling + - `renderSlot`: Renders an HTMLElement slot as a React component, supporting cloning, force-cloning, and parameter passing + - `renderItems`: Renders structured items as React structures, automatically injecting slots, contexts, and keys + - `patchSlots`: Injects additional parameters (prepended or appended) into slot rendering functions + - `renderParamsSlot`: Renders parameterized slots based on multiple target nodes +- Style handling + - `styleObject2String`: Converts `CSSProperties` to a string + - `styleObject2HtmlStyle`: Converts `CSSProperties` to an HTML-compatible style object (with unit handling) + - `cssUnits`: Maps numeric values to unit-bearing strings (with no units for specific properties) +- Upload handling + - `getFetchableUrl`: Generates a URL for fetching a file + - `getFileUrl`: Uniformly resolves `FileData`, URL strings, and relative paths +- HTML traversal + - `walkHtmlNodes`: Depth-first node traversal, executing callbacks on matches by name, collection, or predicate +- Functions and hooks + - `createFunction`: Creates a callable function from a string or function + - hooks: `useFunction`, `useMemoizedFn`, `useMemoizedEqualValue`, `useSlotsChildren`, `useTargets`, `useUpdate`, `useValueChange` + +Section sources + +- [convertToCamelCase.ts:1-22](file://frontend/utils/convertToCamelCase.ts#L1-L22) +- [patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- [omitUndefinedProps.ts:1-17](file://frontend/utils/omitUndefinedProps.ts#L1-L17) +- [renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [upload.ts:1-45](file://frontend/utils/upload.ts#L1-L45) +- [walkHtmlNodes.ts:1-19](file://frontend/utils/walkHtmlNodes.ts#L1-L19) +- [createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useMemoizedFn.ts:1-11](file://frontend/utils/hooks/useMemoizedFn.ts#L1-L11) +- [useMemoizedEqualValue.ts:1-15](file://frontend/utils/hooks/useMemoizedEqualValue.ts#L1-L15) +- [useSlotsChildren.ts:1-24](file://frontend/utils/hooks/useSlotsChildren.ts#L1-L24) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [useUpdate.ts:1-7](file://frontend/utils/hooks/useUpdate.ts#L1-L7) +- [useValueChange.ts:1-30](file://frontend/utils/hooks/useValueChange.ts#L1-L30) + +## Architecture Overview + +The utility functions work together across six major domains — "properties/slots/styles/uploads/traversal/functions & hooks" — forming a complete pipeline from data structures to React rendering. + +```mermaid +graph TB +subgraph "Input Layer" +IN1["Raw Properties / Objects"] +IN2["DOM Slots / HTML Nodes"] +IN3["File Data / URLs / Paths"] +end +subgraph "Processing Layer" +P1["convertToCamelCase
omitUndefinedProps"] +P2["patchProps/applyPatchToProps"] +P3["renderSlot/renderItems/patchSlots"] +P4["style.ts computation"] +P5["upload.ts resolution"] +P6["walkHtmlNodes traversal"] +P7["createFunction / function factory"] +end +subgraph "Output Layer" +OUT1["React Component Tree"] +OUT2["Inline Style String / Object"] +OUT3["Accessible File URL"] +end +IN1 --> P1 --> P2 --> P3 --> OUT1 +IN2 --> P3 --> OUT1 +IN2 --> P6 --> OUT1 +IN3 --> P5 --> OUT3 +IN1 --> P4 --> OUT2 +IN1 --> P7 --> P3 +``` + +Diagram sources + +- [convertToCamelCase.ts:1-22](file://frontend/utils/convertToCamelCase.ts#L1-L22) +- [patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- [omitUndefinedProps.ts:1-17](file://frontend/utils/omitUndefinedProps.ts#L1-L17) +- [renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [upload.ts:1-45](file://frontend/utils/upload.ts#L1-L45) +- [walkHtmlNodes.ts:1-19](file://frontend/utils/walkHtmlNodes.ts#L1-L19) +- [createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) + +## Detailed Component Analysis + +### Property Handling Functions + +#### convertToCamelCase and convertObjectKeyToCamelCase + +- Functionality: Converts underscore-style naming to camelCase; batch converts object key names +- Parameters and return values: + - `convertToCamelCase(str: string): string` + - `convertObjectKeyToCamelCase(obj: T): T` +- Use case: Backend fields are often `snake_case`; use when frontend needs camelCase key names +- Complexity: O(n) character processing; O(k) key iteration for object conversion +- Edge cases: Non-objects are returned as-is + +Section sources + +- [convertToCamelCase.ts:1-22](file://frontend/utils/convertToCamelCase.ts#L1-L22) + +#### patchProps and applyPatchToProps + +- Functionality: Resolves React `key` conflicts; internally stashes `key` and restores it at the consumer side +- Parameters and return values: + - `patchProps(props: Record): Record` + - `applyPatchToProps(props: Record): Record` +- Use case: When incoming props contain `key` and need to be passed through to child components +- Complexity: O(n) shallow copy and conditional checks +- Edge cases: No modification when no `key` is present + +Section sources + +- [patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) + +#### omitUndefinedProps + +- Functionality: Filters out undefined (optionally also null) properties +- Parameters and return values: + - `omitUndefinedProps(props: T, options?: { omitNull?: boolean }): T` +- Use case: Reduces invalid property passing and avoids rendering anomalies +- Complexity: O(n) key iteration +- Edge cases: Safe with empty objects + +Section sources + +- [omitUndefinedProps.ts:1-17](file://frontend/utils/omitUndefinedProps.ts#L1-L17) + +### Slot Handling Functions + +#### renderSlot + +- Functionality: Renders an `HTMLElement` slot as a React component, supporting cloning, force-cloning, and parameter passing +- Parameters and return values: + - `renderSlot(el?: HTMLElement, options?: { clone?: boolean; forceClone?: boolean; params?: any[] }): ReactElement | null` +- Use case: Bridges Svelte/Gradio slot nodes to React +- Complexity: O(1) rendering overhead depends on slot content +- Edge cases: Returns `null` when `el` is empty; `forceClone` and `params` require context + +Section sources + +- [renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) + +#### renderItems + +- Functionality: Renders structured items as React structures, automatically injecting slots, contexts, and keys; supports recursive children +- Parameters and return values: + - `renderItems(items: Item[], options?: { children?: string; fallback?: (item) => R; clone?: boolean; forceClone?: boolean; itemPropsTransformer?: (props) => props }, key?: React.Key): R[] | undefined` +- Use case: Multi-slot and nested rendering for complex container components +- Complexity: O(m) where m is the number of valid items; slot injection is O(s) where s is the number of slots +- Edge cases: Non-object items can fall back; the `children` key is customizable + +Section sources + +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) + +#### patchSlots + +- Functionality: Injects additional parameters (prepended or appended) into slot rendering functions to uniformly pass context to slots +- Parameters and return values: + - `patchSlots(params: any[], transform: (patch) => Record): ReturnType` +- Use case: Uniformly injecting parameters into slot functions for improved reusability +- Complexity: O(p) where p is the length of params; function wrapping is O(1) +- Edge cases: Non-function slots are not processed + +Section sources + +- [patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) + +#### renderParamsSlot + +- Functionality: Renders parameterized slots based on multiple target nodes, supporting force-cloning +- Parameters and return values: + - `renderParamsSlot({ key, slots, targets }, options?: { forceClone?: boolean } & RenderSlotOptions)` +- Use case: Multiple target nodes sharing the same slot template with parameter passing +- Complexity: O(t) where t is the number of targets +- Edge cases: Returns `undefined` when no corresponding slot exists + +Section sources + +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +### Style Handling Utilities + +#### style.ts + +- Functionality: Bidirectional conversion between style objects and strings / HTML style objects, with numeric unit handling +- Key functions: + - `styleObject2String(styleObj: React.CSSProperties): string` + - `styleObject2HtmlStyle(styleObj: React.CSSProperties): Record` + - `cssUnits(prop: T, value: number | string | undefined): string | number` +- Use case: Inline style concatenation, DOM attribute setting +- Complexity: O(n) where n is the number of style keys +- Edge cases: Numeric types automatically get `px` appended; specific properties remain unitless + +Section sources + +- [style.ts:1-77](file://frontend/utils/style.ts#L1-L77) + +### Upload Handling Functions + +#### upload.ts + +- Functionality: Uniformly resolves file sources and generates accessible URLs +- Key functions: + - `getFetchableUrl(path: string, rootUrl: string, apiPrefix: string): string` + - `getFileUrl(file: T, rootUrl: string, apiPrefix: string): string | Exclude | undefined` +- Use case: Uniform handling of local files, remote URLs, and `FileData` +- Complexity: O(1) +- Edge cases: Empty input returns `undefined`; non-http(s) strings are treated as relative paths + +Section sources + +- [upload.ts:1-45](file://frontend/utils/upload.ts#L1-L45) + +### HTML Node Traversal Utilities + +#### walkHtmlNodes + +- Functionality: Depth-first node traversal, executing callbacks on matches by name, collection, or predicate +- Parameters and return values: + - `walkHtmlNodes(node: Node | HTMLElement | null, test: string | string[] | ((node) => boolean), callback: (node) => void): void` +- Use case: Finding specific tags, batch node operations +- Complexity: O(n) where n is the total number of nodes +- Edge cases: Safe with null nodes; array and function forms allow flexible matching + +Section sources + +- [walkHtmlNodes.ts:1-19](file://frontend/utils/walkHtmlNodes.ts#L1-L19) + +### Functions and Hooks + +#### createFunction + +- Functionality: Creates a callable function from a string or function, with support for plain-text mode validation +- Parameters and return values: + - `createFunction(target: any, plainText?: boolean): T | undefined` +- Use case: Dynamic function creation, runtime code injection +- Complexity: O(1) for creation; execution depends on the function body +- Edge cases: Invalid strings return `undefined`; exceptions are caught + +Section sources + +- [createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) + +#### Hooks Series + +- `useFunction`: Memoizes the result of `createFunction` +- `useMemoizedFn`: Stabilizes function references to avoid closure traps +- `useMemoizedEqualValue`: Equal-value caching to avoid unnecessary re-renders +- `useSlotsChildren`: Distinguishes slot children from regular children +- `useTargets`: Extracts portal target nodes sorted by `slotKey` +- `useUpdate`: Triggers a state update to force a refresh +- `useValueChange`: Synchronizes external values with internal state changes + +Section sources + +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useMemoizedFn.ts:1-11](file://frontend/utils/hooks/useMemoizedFn.ts#L1-L11) +- [useMemoizedEqualValue.ts:1-15](file://frontend/utils/hooks/useMemoizedEqualValue.ts#L1-L15) +- [useSlotsChildren.ts:1-24](file://frontend/utils/hooks/useSlotsChildren.ts#L1-L24) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [useUpdate.ts:1-7](file://frontend/utils/hooks/useUpdate.ts#L1-L7) +- [useValueChange.ts:1-30](file://frontend/utils/hooks/useValueChange.ts#L1-L30) + +## Dependency Analysis + +```mermaid +graph LR +CF["createFunction.ts"] --> UF["useFunction.ts"] +PP["patchProps.tsx"] --> RS["renderSlot.tsx"] +PP --> RI["renderItems.tsx"] +PS["patchSlots.ts"] --> RI +ST["style.ts"] --> OUT1["Inline Style Output"] +UP["upload.ts"] --> OUT2["File URL Output"] +WH["walkHtmlNodes.ts"] --> RS +WH --> RI +``` + +Diagram sources + +- [createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- [renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [upload.ts:1-45](file://frontend/utils/upload.ts#L1-L45) +- [walkHtmlNodes.ts:1-19](file://frontend/utils/walkHtmlNodes.ts#L1-L19) + +## Performance Considerations + +- Batch object key conversion and property filtering: O(k) and O(n); recommended to call only when necessary +- Slot rendering: `clone` and `forceClone` increase rendering cost; enable on-demand when possible +- Style conversion: Numeric-to-string and unit concatenation are O(n); cache results for large style objects +- Upload URL resolution: O(1), but involves string concatenation and regex; validate path correctness +- HTML traversal: O(n); recommended to limit traversal scope or use more precise match conditions +- Function factory: `new Function` has compilation overhead; cache results with `useFunction` + +## Troubleshooting Guide + +- Slot not displayed + - Check whether `el` exists; confirm if `clone` or `forceClone` is needed + - If using parameterized slots, ensure `params` is provided and `targets` are correct +- Key conflicts or duplicates + - Use `patchProps`/`applyPatchToProps` for internal key mapping +- Style not applied + - Check `cssUnits` handling for specific properties; confirm whether numeric values need units +- Uploaded file not accessible + - Verify `rootUrl` and `apiPrefix` configuration; relative paths will be converted to fetchable URLs +- Nodes not found during traversal + - Check the `test` type (string/array/function) and the case sensitivity of node names +- Dynamic function not available + - In `plainText` mode, invalid strings return `undefined`; check syntax + +Section sources + +- [renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) +- [style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [upload.ts:1-45](file://frontend/utils/upload.ts#L1-L45) +- [walkHtmlNodes.ts:1-19](file://frontend/utils/walkHtmlNodes.ts#L1-L19) +- [createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) + +## Conclusion + +This utility function system provides full-stack capabilities from properties/slots/styles/uploads/traversal to functions and hooks, bridging the Svelte/Gradio ecosystem while accommodating the flexibility and performance of React rendering. Through proper parameter configuration and edge case handling, a consistent and maintainable development experience can be achieved in complex component scenarios. + +## Appendix + +### API Definitions and Key Usage Points + +- `convertToCamelCase` + - Input: underscore-style string + - Output: camelCase string + - Example path: [convertToCamelCase.ts:3-11](file://frontend/utils/convertToCamelCase.ts#L3-L11) + +- `convertObjectKeyToCamelCase` + - Input: object + - Output: new object with camelCase keys + - Example path: [convertToCamelCase.ts:13-21](file://frontend/utils/convertToCamelCase.ts#L13-L21) + +- `patchProps` / `applyPatchToProps` + - Input: props (possibly containing `key`) + - Output: props with internal `key` marked or restored + - Example path: [patchProps.tsx:3-22](file://frontend/utils/patchProps.tsx#L3-L22) + +- `omitUndefinedProps` + - Input: props, optional `omitNull` + - Output: filtered props + - Example path: [omitUndefinedProps.ts:1-16](file://frontend/utils/omitUndefinedProps.ts#L1-L16) + +- `renderSlot` + - Input: `HTMLElement`, optional `clone`/`forceClone`/`params` + - Output: `ReactElement` or `null` + - Example path: [renderSlot.tsx:13-28](file://frontend/utils/renderSlot.tsx#L13-L28) + +- `renderItems` + - Input: `Item[]`, optional `children`/`fallback`/`clone`/`forceClone`/`itemPropsTransformer` + - Output: `R[]` or `undefined` + - Example path: [renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +- `patchSlots` + - Input: `params[]`, `transform` function + - Output: enhanced return object + - Example path: [patchSlots.ts:4-31](file://frontend/utils/patchSlots.ts#L4-L31) + +- `renderParamsSlot` + - Input: `{ key, slots, targets }`, optional `options` + - Output: parameterized slot function or `undefined` + - Example path: [renderParamsSlot.tsx:5-49](file://frontend/utils/renderParamsSlot.tsx#L5-L49) + +- `style.ts` + - Input: `React.CSSProperties` + - Output: style string or HTML-compatible style object + - Example path: [style.ts:39-76](file://frontend/utils/style.ts#L39-L76) + +- `upload.ts` + - Input: `file` (`FileData | string | any`), `rootUrl`, `apiPrefix` + - Output: accessible URL or original value + - Example path: [upload.ts:27-44](file://frontend/utils/upload.ts#L27-L44) + +- `walkHtmlNodes` + - Input: `node`, `test` (string/array/function), `callback` + - Output: `void` + - Example path: [walkHtmlNodes.ts:1-18](file://frontend/utils/walkHtmlNodes.ts#L1-L18) + +- `createFunction` + - Input: `target` (function/string), `plainText` + - Output: callable function or `undefined` + - Example path: [createFunction.ts:10-37](file://frontend/utils/createFunction.ts#L10-L37) + +- hooks + - `useFunction`: [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) + - `useMemoizedFn`: [useMemoizedFn.ts:3-10](file://frontend/utils/hooks/useMemoizedFn.ts#L3-L10) + - `useMemoizedEqualValue`: [useMemoizedEqualValue.ts:4-14](file://frontend/utils/hooks/useMemoizedEqualValue.ts#L4-L14) + - `useSlotsChildren`: [useSlotsChildren.ts:4-23](file://frontend/utils/hooks/useSlotsChildren.ts#L4-L23) + - `useTargets`: [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) + - `useUpdate`: [useUpdate.ts:3-6](file://frontend/utils/hooks/useUpdate.ts#L3-L6) + - `useValueChange`: [useValueChange.ts:9-29](file://frontend/utils/hooks/useValueChange.ts#L9-L29) + +### Usage Flow Diagrams + +#### renderItems Data Flow + +```mermaid +flowchart TD +Start(["Start"]) --> Filter["Filter empty items"] +Filter --> Loop{"Iterate over each item"} +Loop --> |Is object| Merge["Merge props and set key"] +Merge --> Slots["Resolve slots mapping"] +Slots --> Children{"children key present?"} +Children --> |Yes| Recur["Recursively render children"] +Children --> |No| Push["Return current result"] +Recur --> Push +Push --> Next["Next item"] +Next --> Loop +Loop --> |End| End(["End"]) +``` + +Diagram sources + +- [renderItems.tsx:18-113](file://frontend/utils/renderItems.tsx#L18-L113) + +#### renderSlot Rendering Sequence + +```mermaid +sequenceDiagram +participant Caller as "Caller" +participant RS as "renderSlot" +participant CPS as "patchSlotProps" +participant RSP as "ReactSlot" +Caller->>RS : Pass el and options +alt Params required or force clone +RS->>CPS : Wrap children +CPS->>RSP : Pass slot/clone/params +else +RS->>RSP : Pass slot/clone directly +end +RSP-->>Caller : Return ReactElement +``` + +Diagram sources + +- [renderSlot.tsx:13-28](file://frontend/utils/renderSlot.tsx#L13-L28) +- [patchProps.tsx:31-38](file://frontend/utils/patchProps.tsx#L31-L38) diff --git a/.wiki/en/API Reference/Python API/Antd Components API/Antd Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/Antd Components API.md new file mode 100644 index 00000000..f581ba60 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/Antd Components API.md @@ -0,0 +1,371 @@ +# Antd Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/components/antd/button/__init__.py](file://backend/modelscope_studio/components/antd/button/__init__.py) +- [backend/modelscope_studio/components/antd/form/__init__.py](file://backend/modelscope_studio/components/antd/form/__init__.py) +- [backend/modelscope_studio/components/antd/table/__init__.py](file://backend/modelscope_studio/components/antd/table/__init__.py) +- [backend/modelscope_studio/components/antd/input/__init__.py](file://backend/modelscope_studio/components/antd/input/__init__.py) +- [backend/modelscope_studio/components/antd/select/__init__.py](file://backend/modelscope_studio/components/antd/select/__init__.py) +- [backend/modelscope_studio/components/antd/form/item/__init__.py](file://backend/modelscope_studio/components/antd/form/item/__init__.py) +- [backend/modelscope_studio/components/antd/table/column/__init__.py](file://backend/modelscope_studio/components/antd/table/column/__init__.py) +- [backend/modelscope_studio/components/antd/layout/__init__.py](file://backend/modelscope_studio/components/antd/layout/__init__.py) +- [backend/modelscope_studio/components/antd/menu/__init__.py](file://backend/modelscope_studio/components/antd/menu/__init__.py) +- [backend/modelscope_studio/components/antd/modal/__init__.py](file://backend/modelscope_studio/components/antd/modal/__init__.py) +- [backend/modelscope_studio/components/antd/message/__init__.py](file://backend/modelscope_studio/components/antd/message/__init__.py) +- [backend/modelscope_studio/components/antd/notification/__init__.py](file://backend/modelscope_studio/components/antd/notification/__init__.py) +- [backend/modelscope_studio/components/antd/card/__init__.py](file://backend/modelscope_studio/components/antd/card/__init__.py) +- [backend/modelscope_studio/components/antd/breadcrumb/__init__.py](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: API Index by Category](#appendix-api-index-by-category) + +## Introduction + +This document is the Python API reference for the Antd component library, covering 150+ components under `modelscope_studio.components.antd.*`. The documentation is designed for both developers and non-technical readers, providing: + +- Complete import paths and class names +- Constructor parameters, property definitions, method signatures, and return types +- Standard instantiation examples (given as code snippet paths) +- Event handling mechanisms, data binding patterns, and state management interfaces +- Parameter validation rules, exception handling strategies, and inter-component communication patterns +- API index organized by category (general, layout, navigation, data entry, data display, feedback, etc.) + +## Project Structure + +Antd components wrap frontend Svelte components as Python classes, all inheriting from base component classes, supporting event binding, slots, and Gradio data flows. + +```mermaid +graph TB +subgraph "Python Layer" +A["ModelScopeComponent
ModelScopeLayoutComponent
ModelScopeDataLayoutComponent"] +B["AntdButton"] +C["AntdForm / AntdFormItem"] +D["AntdTable / AntdTableColumn"] +E["AntdInput / AntdSelect"] +F["AntdLayout / AntdMenu / AntdModal"] +G["AntdMessage / AntdNotification"] +H["AntdCard / AntdBreadcrumb"] +end +subgraph "Frontend Layer (Svelte)" +P["button/*"] +Q["form/*"] +R["table/*"] +S["input/*"] +T["select/*"] +U["layout/*"] +V["menu/*"] +W["modal/*"] +X["message/*"] +Y["notification/*"] +Z["card/*"] +AA["breadcrumb/*"] +end +A --> B +A --> C +A --> D +A --> E +A --> F +A --> G +A --> H +B --> P +C --> Q +D --> R +E --> S +E --> T +F --> U +F --> V +F --> W +G --> X +G --> Y +H --> Z +H --> AA +``` + +Diagram sources + +- [backend/modelscope_studio/utils/dev/component.py:54-169](file://backend/modelscope_studio/utils/dev/component.py#L54-L169) +- [backend/modelscope_studio/components/antd/button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) +- [backend/modelscope_studio/components/antd/table/**init**.py:16-153](file://backend/modelscope_studio/components/antd/table/__init__.py#L16-L153) +- [backend/modelscope_studio/components/antd/input/**init**.py:16-127](file://backend/modelscope_studio/components/antd/input/__init__.py#L16-L127) +- [backend/modelscope_studio/components/antd/select/**init**.py:12-231](file://backend/modelscope_studio/components/antd/select/__init__.py#L12-L231) +- [backend/modelscope_studio/components/antd/layout/**init**.py:14-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L14-L91) +- [backend/modelscope_studio/components/antd/menu/**init**.py:12-123](file://backend/modelscope_studio/components/antd/menu/__init__.py#L12-L123) +- [backend/modelscope_studio/components/antd/modal/**init**.py:11-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L11-L136) +- [backend/modelscope_studio/components/antd/message/**init**.py:10-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L10-L91) +- [backend/modelscope_studio/components/antd/notification/**init**.py:10-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L10-L109) +- [backend/modelscope_studio/components/antd/card/**init**.py:12-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L12-L149) +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:9-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L9-L73) + +Section sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/utils/dev/component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) + +## Core Components + +- Base component classes + - `ModelScopeComponent`: General component base class; supports Gradio properties such as `value`, `visible`, `elem_*`, `key`, `inputs`, `load_fn`, `render`; provides `skip_api` to control API exposure. + - `ModelScopeLayoutComponent`: Layout component base class; supports `__enter__`/`__exit__` context management for nested layouts. + - `ModelScopeDataLayoutComponent`: Data-layout component base class; combines data component capabilities with layout capabilities. +- Events and slots + - `EVENTS`: List of events supported by the component; binds callbacks via `EventListener`. + - `SLOTS`: Set of slot names supported by the component; used for rendering child content or custom nodes. +- Frontend directory resolution + - `FRONTEND_DIR`: Points to the corresponding Svelte component directory via `resolve_frontend_dir(...)`. + +Section sources + +- [backend/modelscope_studio/utils/dev/component.py:54-169](file://backend/modelscope_studio/utils/dev/component.py#L54-L169) +- [backend/modelscope_studio/components/antd/button/**init**.py:41-49](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L49) +- [backend/modelscope_studio/components/antd/table/**init**.py:32-53](file://backend/modelscope_studio/components/antd/table/__init__.py#L32-L53) +- [backend/modelscope_studio/components/antd/input/**init**.py:25-41](file://backend/modelscope_studio/components/antd/input/__init__.py#L25-L41) + +## Architecture Overview + +The following sequence diagram shows a typical component's call chain from construction to event binding: + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Py as "Antd Component Class" +participant Base as "ModelScopeComponent/ModelScopeLayoutComponent" +participant FE as "Svelte Frontend Component" +Dev->>Py : Instantiate component (pass parameters) +Py->>Base : Call parent __init__(visible, elem_*, render, ...) +Base->>Base : Initialize internal state (_internal, as_item, elem_style) +Py->>FE : Set FRONTEND_DIR and pass props +Py->>Py : Configure EVENTS/SLOTS +Dev->>Py : Bind event listeners (EventListener) +Py->>FE : Bind frontend event callbacks via internal markers +FE-->>Py : Trigger event callbacks +Py-->>Dev : Return processed value/payload +``` + +Diagram sources + +- [backend/modelscope_studio/utils/dev/component.py:54-99](file://backend/modelscope_studio/utils/dev/component.py#L54-L99) +- [backend/modelscope_studio/components/antd/button/**init**.py:51-87](file://backend/modelscope_studio/components/antd/button/__init__.py#L51-L87) +- [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) + +## Detailed Component Analysis + +### Button + +- Import path: `modelscope_studio.components.antd.AntdButton` or `modelscope_studio.components.antd.Button` +- Sub-components: `Group` +- Events: `click` +- Slots: `icon`, `loading.icon` +- Key parameters (selected): `value`, `block`, `danger`, `ghost`, `disabled`, `href`, `html_type`, `icon`, `icon_position`, `loading`, `shape`, `size`, `type`, `variant`, `color`, `root_class_name` +- Methods: `preprocess`/`postprocess`/`example_payload`/`example_value` +- Code snippet path (example) + - [basic usage:51-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L51-L157) +- Event binding flow + - Maps callbacks to frontend events via `EventListener("click", ...)` in `EVENTS`. +- Data binding + - When used as input/output, `value` type is string; `preprocess`/`postprocess` returns string. +- Parameter validation and exceptions + - Most parameters are nullable scalars or literal enums; no explicit validation logic seen — validation is recommended at the application layer. +- Inter-component communication + - Interacts with forms or other components via Gradio's `inputs`/`outputs` mechanism. + +Section sources + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) + +### Form and Form.Item + +- Import path: `modelscope_studio.components.antd.AntdForm` / `AntdFormItem` +- Sub-components: `Item`, `Provider` +- Events: `fields_change`, `finish`, `finish_failed`, `values_change` +- Slots: `requiredMark` +- Form key parameters (selected): `colon`, `disabled`, `component`, `feedback_icons`, `initial_values`, `label_align`, `label_col`, `label_wrap`, `layout`, `preserve`, `required_mark`, `scroll_to_first_error`, `size`, `validate_messages`, `validate_trigger`, `variant`, `wrapper_col`, `clear_on_destroy`, `root_class_name`, `class_names`, `styles` +- FormItem key parameters (selected): `label`, `form_name`, `colon`, `dependencies`, `extra`, `help`, `hidden`, `initial_value`, `label_align`, `label_col`, `message_variants`, `normalize`, `no_style`, `preserve`, `required`, `rules`, `should_update`, `tooltip`, `trigger`, `validate_debounce`, `validate_first`, `validate_status`, `validate_trigger`, `value_prop_name`, `wrapper_col`, `layout`, `root_class_name` +- Methods: `preprocess`/`postprocess`/`example_payload`/`example_value` +- Code snippet paths (example) + - [form:43-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L43-L133) + - [form item:21-126](file://backend/modelscope_studio/components/antd/form/item/__init__.py#L21-L126) + +Section sources + +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) +- [backend/modelscope_studio/components/antd/form/item/**init**.py:9-126](file://backend/modelscope_studio/components/antd/form/item/__init__.py#L9-L126) + +### Table and Table.Column + +- Import path: `modelscope_studio.components.antd.AntdTable` / `AntdTableColumn` +- Sub-components: `Column`, `ColumnGroup`, `Expandable`, `RowSelection` +- Events: `change`, `scroll` +- Slots: `footer`, `title`, `summary`, `expandable`, `rowSelection`, `loading.tip`, `loading.indicator`, `pagination.showQuickJumper.goButton`, `pagination.itemRender`, `showSorterTooltip.title` +- Table key parameters (selected): `data_source`, `columns`, `bordered`, `components`, `expandable`, `footer`, `get_popup_container`, `loading`, `locale`, `pagination`, `row_class_name`, `row_key`, `row_selection`, `row_hoverable`, `scroll`, `show_header`, `show_sorter_tooltip`, `size`, `sort_directions`, `sticky`, `summary`, `table_layout`, `title`, `virtual`, `on_row`, `on_header_row`, `root_class_name`, `class_names`, `styles` +- Table.Column key parameters (selected): `built_in_column`, `align`, `col_span`, `data_index`, `default_filtered_value`, `filter_reset_to_default_filtered_value`, `default_sort_order`, `ellipsis`, `filter_dropdown`, `filter_dropdown_open`, `filtered`, `filtered_value`, `filter_icon`, `filter_on_close`, `filter_multiple`, `filter_mode`, `filter_search`, `filters`, `filter_dropdown_props`, `fixed`, `key`, `column_render`, `responsive`, `row_scope`, `should_cell_update`, `show_sorter_tooltip`, `sorter`, `sort_order`, `sort_icon`, `title`, `width`, `min_width`, `hidden`, `on_cell`, `on_header_cell`, `class_names`, `styles` +- Methods: `preprocess`/`postprocess`/`example_payload`/`example_value` +- Code snippet paths (example) + - [table:55-153](file://backend/modelscope_studio/components/antd/table/__init__.py#L55-L153) + - [table.column:33-150](file://backend/modelscope_studio/components/antd/table/column/__init__.py#L33-L150) + +Section sources + +- [backend/modelscope_studio/components/antd/table/**init**.py:16-153](file://backend/modelscope_studio/components/antd/table/__init__.py#L16-L153) +- [backend/modelscope_studio/components/antd/table/column/**init**.py:10-150](file://backend/modelscope_studio/components/antd/table/column/__init__.py#L10-L150) + +### Input and Select + +- Import path: `modelscope_studio.components.antd.AntdInput` / `AntdSelect` +- Sub-components: `Textarea`, `Password`, `OTP`, `Search` (Input); `Option` (Select) +- Input events: `change`, `press_enter`, `clear` +- Select events: `change`, `blur`, `focus`, `search`, `select`, `clear`, `popup_scroll`, `dropdown_visible_change`, `popup_visible_change`, `active` +- Slots (Input): `addonAfter`, `addonBefore`, `allowClear.clearIcon`, `prefix`, `suffix`, `showCount.formatter` +- Slots (Select): `allowClear.clearIcon`, `maxTagPlaceholder`, `menuItemSelectedIcon`, `dropdownRender`, `popupRender`, `optionRender`, `tagRender`, `labelRender`, `notFoundContent`, `removeIcon`, `suffixIcon`, `prefix`, `options` +- Input key parameters (selected): `addon_after`, `addon_before`, `allow_clear`, `count`, `default_value`, `read_only`, `disabled`, `max_length`, `prefix`, `show_count`, `size`, `status`, `suffix`, `type`, `placeholder`, `variant`, `root_class_name`, `class_names`, `styles` +- Select key parameters (selected): `allow_clear`, `auto_clear_search_value`, `auto_focus`, `default_active_first_option`, `default_open`, `default_value`, `disabled`, `popup_class_name`, `popup_match_select_width`, `dropdown_render`, `popup_render`, `dropdown_style`, `field_names`, `filter_option`, `filter_sort`, `get_popup_container`, `label_in_value`, `list_height`, `loading`, `max_count`, `max_tag_count`, `max_tag_placeholder`, `max_tag_text_length`, `menu_item_selected_icon`, `mode`, `not_found_content`, `open`, `option_filter_prop`, `option_label_prop`, `options`, `option_render`, `placeholder`, `placement`, `remove_icon`, `search_value`, `show_search`, `size`, `status`, `suffix_icon`, `prefix`, `tag_render`, `label_render`, `token_separators`, `variant`, `virtual`, `class_names`, `styles`, `root_class_name` +- Methods: `preprocess`/`postprocess`/`example_payload`/`example_value` +- Code snippet paths (example) + - [input:43-127](file://backend/modelscope_studio/components/antd/input/__init__.py#L43-L127) + - [select:59-231](file://backend/modelscope_studio/components/antd/select/__init__.py#L59-L231) + +Section sources + +- [backend/modelscope_studio/components/antd/input/**init**.py:16-127](file://backend/modelscope_studio/components/antd/input/__init__.py#L16-L127) +- [backend/modelscope_studio/components/antd/select/**init**.py:12-231](file://backend/modelscope_studio/components/antd/select/__init__.py#L12-L231) + +### Layout, Menu, and Modal + +- Import path: `modelscope_studio.components.antd.AntdLayout` / `AntdMenu` / `AntdModal` +- Sub-components: `Layout.Content`/`Footer`/`Header`/`Sider` (Layout); `Menu.Item` (Menu); `Modal.Static` (Modal) +- Events (Layout/Menu/Modal): `click`, `deselect`, `open_change`, `select`, `ok`, `cancel`, etc. +- Slots (Layout/Menu/Modal): See individual component definitions +- Code snippet paths (example) + - [layout:39-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L39-L91) + - [menu:36-123](file://backend/modelscope_studio/components/antd/menu/__init__.py#L36-L123) + - [modal:34-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L34-L136) + +Section sources + +- [backend/modelscope_studio/components/antd/layout/**init**.py:14-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L14-L91) +- [backend/modelscope_studio/components/antd/menu/**init**.py:12-123](file://backend/modelscope_studio/components/antd/menu/__init__.py#L12-L123) +- [backend/modelscope_studio/components/antd/modal/**init**.py:11-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L11-L136) + +### Message, Notification, Card, and Breadcrumb + +- Import path: `modelscope_studio.components.antd.AntdMessage` / `AntdNotification` / `AntdCard` / `AntdBreadcrumb` +- Events: `click`, `close` (some components) +- Slots: `icon`/`content` (Message); `actions`/`closeIcon`/`description`/`icon`/`message`/`title` (Notification); `title`/`tabList`/`tabProps.*` (Card); `separator`/`itemRender`/`items`/`dropdownIcon` (Breadcrumb) +- Code snippet paths (example) + - [message:26-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L26-L91) + - [notification:26-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L26-L109) + - [card:56-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L56-L149) + - [breadcrumb:20-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L20-L73) + +Section sources + +- [backend/modelscope_studio/components/antd/message/**init**.py:10-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L10-L91) +- [backend/modelscope_studio/components/antd/notification/**init**.py:10-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L10-L109) +- [backend/modelscope_studio/components/antd/card/**init**.py:12-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L12-L149) +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:9-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L9-L73) + +## Dependency Analysis + +- Component exports + - `modelscope_studio.components.antd.__init__` and `components.py` synchronize exports of all Antd component classes for unified imports. +- Base class dependencies + - All components depend on base component classes in `modelscope_studio.utils.dev.component`, ensuring a unified lifecycle, event, and slot mechanism. +- Frontend dependencies + - Each component points to its corresponding Svelte component directory via `FRONTEND_DIR`, maintaining consistent directory structures between frontend and backend. + +```mermaid +graph LR +A["antd/__init__.py"] --> B["Button/Form/Table/Input/Select/Layout/..."] +C["antd/components.py"] --> B +D["utils/dev/component.py"] --> B +B --> E["Svelte Frontend Components"] +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/utils/dev/component.py:54-169](file://backend/modelscope_studio/utils/dev/component.py#L54-L169) + +Section sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/utils/dev/component.py:54-169](file://backend/modelscope_studio/utils/dev/component.py#L54-L169) + +## Performance Considerations + +- Event binding + - Maps Python callbacks to frontend events via `EVENTS`, avoiding unnecessary re-renders; set event trigger frequency and debouncing appropriately. +- Slots and virtualization + - Components such as Table support `virtual`, `sticky`, `scroll`, and similar parameters; it is recommended to enable virtual scrolling and fixed headers in large data scenarios to improve performance. +- Render control + - Use `render` and `visible` to control component initial rendering and visibility, reducing first-screen pressure. +- Data flow + - Input components (e.g., Input, Select) are recommended to work with Form for batch validation and debouncing, reducing overhead from frequent updates. + +## Troubleshooting Guide + +- Events not triggering + - Check that `EVENTS` is correctly declared; confirm that `EventListener` names match frontend events. + - Confirm that the component has `FRONTEND_DIR` set correctly and frontend event callbacks are bound. +- Slots not working + - Verify that the corresponding slot name exists in the `SLOTS` list; ensure the slot content passed matches the expected format. +- Data type mismatch + - The return types of `preprocess`/`postprocess` for input components must match component definitions; if type errors occur, check `value` and the return type from `api_info`. +- Form validation failure + - Check FormItem's `rules`, `validate_trigger`, `validate_status`, and other configurations; adjust `validate_first` and `validate_debounce` as needed. +- Layout flickering or style anomalies + - Layout components (e.g., Layout, Menu) can optimize SSR-scenario style flickering via parameters such as `has_sider`, `inline_collapsed`, and `theme_value`. + +Section sources + +- [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) +- [backend/modelscope_studio/components/antd/form/item/**init**.py:13-19](file://backend/modelscope_studio/components/antd/form/item/__init__.py#L13-L19) +- [backend/modelscope_studio/components/antd/table/**init**.py:32-53](file://backend/modelscope_studio/components/antd/table/__init__.py#L32-L53) +- [backend/modelscope_studio/components/antd/menu/**init**.py:96-103](file://backend/modelscope_studio/components/antd/menu/__init__.py#L96-L103) +- [backend/modelscope_studio/components/antd/layout/**init**.py:33-37](file://backend/modelscope_studio/components/antd/layout/__init__.py#L33-L37) + +## Conclusion + +This reference document systematically covers the Python API of the Antd component library, clearly defining import paths, constructor parameters, events and slots, data binding, and state management interfaces for component classes. It is recommended to use example paths to quickly locate implementation details in actual development, and to optimize component usage experience according to the performance and troubleshooting guidelines. + +## Appendix: API Index by Category + +- General Components + - `Button`, `Message`, `Notification`, `Card`, `Breadcrumb` + - Example paths: [button:51-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L51-L157), [message:26-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L26-L91), [notification:26-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L26-L109), [card:56-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L56-L149), [breadcrumb:20-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L20-L73) +- Layout Components + - `Layout` (including `Content`/`Footer`/`Header`/`Sider`), `Menu` (including `Item`) + - Example paths: [layout:39-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L39-L91), [menu:36-123](file://backend/modelscope_studio/components/antd/menu/__init__.py#L36-L123) +- Navigation Components + - `Breadcrumb` (including `Item`) + - Example paths: [breadcrumb:20-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L20-L73) +- Data Entry Components + - `Input` (including `Textarea`/`Password`/`OTP`/`Search`), `Select` (including `Option`) + - Example paths: [input:43-127](file://backend/modelscope_studio/components/antd/input/__init__.py#L43-L127), [select:59-231](file://backend/modelscope_studio/components/antd/select/__init__.py#L59-L231) +- Data Display Components + - `Table` (including `Column`/`ColumnGroup`/`Expandable`/`RowSelection`) + - Example paths: [table:55-153](file://backend/modelscope_studio/components/antd/table/__init__.py#L55-L153), [table.column:33-150](file://backend/modelscope_studio/components/antd/table/column/__init__.py#L33-L150) +- Feedback Components + - `Modal` (including `Static`), `Message`, `Notification` + - Example paths: [modal:34-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L34-L136), [message:26-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L26-L91), [notification:26-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L26-L109) +- Form Components + - `Form` (including `Item`/`Provider`) + - Example paths: [form:43-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L43-L133), [form.item:21-126](file://backend/modelscope_studio/components/antd/form/item/__init__.py#L21-L126) diff --git a/.wiki/en/API Reference/Python API/Antd Components API/Data Display Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/Data Display Components API.md new file mode 100644 index 00000000..7a2033ee --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/Data Display Components API.md @@ -0,0 +1,661 @@ +# Data Display Components API + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/components/antd/avatar/__init__.py](file://backend/modelscope_studio/components/antd/avatar/__init__.py) +- [backend/modelscope_studio/components/antd/badge/__init__.py](file://backend/modelscope_studio/components/antd/badge/__init__.py) +- [backend/modelscope_studio/components/antd/calendar/__init__.py](file://backend/modelscope_studio/components/antd/calendar/__init__.py) +- [backend/modelscope_studio/components/antd/card/__init__.py](file://backend/modelscope_studio/components/antd/card/__init__.py) +- [backend/modelscope_studio/components/antd/carousel/__init__.py](file://backend/modelscope_studio/components/antd/carousel/__init__.py) +- [backend/modelscope_studio/components/antd/collapse/__init__.py](file://backend/modelscope_studio/components/antd/collapse/__init__.py) +- [backend/modelscope_studio/components/antd/descriptions/__init__.py](file://backend/modelscope_studio/components/antd/descriptions/__init__.py) +- [backend/modelscope_studio/components/antd/empty/__init__.py](file://backend/modelscope_studio/components/antd/empty/__init__.py) +- [backend/modelscope_studio/components/antd/image/__init__.py](file://backend/modelscope_studio/components/antd/image/__init__.py) +- [backend/modelscope_studio/components/antd/list/__init__.py](file://backend/modelscope_studio/components/antd/list/__init__.py) +- [backend/modelscope_studio/components/antd/popover/__init__.py](file://backend/modelscope_studio/components/antd/popover/__init__.py) +- [backend/modelscope_studio/components/antd/qr_code/__init__.py](file://backend/modelscope_studio/components/antd/qr_code/__init__.py) +- [backend/modelscope_studio/components/antd/segmented/__init__.py](file://backend/modelscope_studio/components/antd/segmented/__init__.py) +- [backend/modelscope_studio/components/antd/statistic/__init__.py](file://backend/modelscope_studio/components/antd/statistic/__init__.py) +- [backend/modelscope_studio/components/antd/table/__init__.py](file://backend/modelscope_studio/components/antd/table/__init__.py) +- [backend/modelscope_studio/components/antd/tabs/__init__.py](file://backend/modelscope_studio/components/antd/tabs/__init__.py) +- [backend/modelscope_studio/components/antd/tag/__init__.py](file://backend/modelscope_studio/components/antd/tag/__init__.py) +- [backend/modelscope_studio/components/antd/tag/checkable_tag/__init__.py](file://backend/modelscope_studio/components/antd/tag/checkable_tag/__init__.py) +- [backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py](file://backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py) +- [backend/modelscope_studio/components/antd/timeline/__init__.py](file://backend/modelscope_studio/components/antd/timeline/__init__.py) +- [backend/modelscope_studio/components/antd/tooltip/__init__.py](file://backend/modelscope_studio/components/antd/tooltip/__init__.py) +- [backend/modelscope_studio/components/antd/tour/__init__.py](file://backend/modelscope_studio/components/antd/tour/__init__.py) +- [backend/modelscope_studio/components/antd/tree/__init__.py](file://backend/modelscope_studio/components/antd/tree/__init__.py) +- [frontend/antd/timeline/timeline.tsx](file://frontend/antd/timeline/timeline.tsx) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx) +- [frontend/antd/tag/checkable-tag/Index.svelte](file://frontend/antd/tag/checkable-tag/Index.svelte) +- [frontend/antd/tag/tag.tsx](file://frontend/antd/tag/tag.tsx) + + +## Update Summary + +**Changes Made** + +- Added complete API documentation for the Timeline component, including the latest feature specifications +- Added detailed documentation for the checkable tag group component, covering both CheckableTag and CheckableTagGroup +- Updated Tag component documentation, supplementing checkable tag-related functionality +- Improved documentation of inter-component relationships and usage scenarios + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is a Python API reference and practical guide for Antd data display components, covering Avatar, Badge, Calendar, Card, Carousel, Collapse, Descriptions, Empty, Image, List, Popover, QRCode, Segmented, Statistic, Table, Tabs, Tag, Timeline, Tooltip, Tour, Tree, and other components. Content includes: + +- Constructor parameters, event binding, slots and rendering behavior +- Preprocessing and postprocessing (preprocess/postprocess) workflows +- Usage example paths and common scenarios +- Rendering optimization, lazy loading, and responsive design recommendations +- Data formatting, internationalization, and theme customization approaches +- User experience and accessibility best practices + +## Project Structure + +Antd components are encapsulated as Python classes in the backend, all inheriting from a common component base class, and mapped to corresponding Svelte implementations through frontend directory mappings. Component export entries are centralized in antd/**init**.py and antd/components.py. + +```mermaid +graph TB +A["Python Component Module
backend/modelscope_studio/components/antd"] --> B["Component Export Entry
antd/__init__.py"] +A --> C["Common Component Base Class
utils.dev.ModelScope*Component"] +D["Frontend Component Directory
frontend/antd/"] <-- "resolve_frontend_dir" --> E["Component Frontend Implementation
*.tsx / Index.svelte"] +B --> F["Concrete Component Classes
AntdXxx(...)"] +F --> E +``` + +**Chart sources** + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +**Section sources** + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +## Core Components + +The following is a list of data display components and their common characteristics covered in this document: + +- Unified inheritance: most components inherit from ModelScopeLayoutComponent or ModelScopeComponent; some data-type components inherit from ModelScopeDataLayoutComponent (e.g., Avatar, Image) +- Event system: register frontend event callbacks via EVENTS list, bound to \_internal.update +- Slot system: define available slot names via SLOTS, used for passing template fragments or render functions +- Frontend directory: point to frontend component directory via resolve_frontend_dir("component-name") +- Preprocessing/postprocessing: implement preprocess and postprocess based on component type, handling strings, file paths, Gradio FileData, and other inputs/outputs + +**Section sources** + +- [backend/modelscope_studio/components/antd/avatar/**init**.py:18-114](file://backend/modelscope_studio/components/antd/avatar/__init__.py#L18-L114) +- [backend/modelscope_studio/components/antd/image/**init**.py:18-120](file://backend/modelscope_studio/components/antd/image/__init__.py#L18-L120) +- [backend/modelscope_studio/components/antd/calendar/**init**.py:11-102](file://backend/modelscope_studio/components/antd/calendar/__init__.py#L11-L102) +- [backend/modelscope_studio/components/antd/card/**init**.py:12-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L12-L149) +- [backend/modelscope_studio/components/antd/carousel/**init**.py:8-95](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L8-L95) +- [backend/modelscope_studio/components/antd/collapse/**init**.py:11-99](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L11-L99) +- [backend/modelscope_studio/components/antd/descriptions/**init**.py:9-86](file://backend/modelscope_studio/components/antd/descriptions/__init__.py#L9-L86) +- [backend/modelscope_studio/components/antd/empty/**init**.py:8-71](file://backend/modelscope_studio/components/antd/empty/__init__.py#L8-L71) +- [backend/modelscope_studio/components/antd/list/**init**.py:11-101](file://backend/modelscope_studio/components/antd/list/__init__.py#L11-L101) +- [backend/modelscope_studio/components/antd/popover/**init**.py:10-124](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L124) +- [backend/modelscope_studio/components/antd/qr_code/**init**.py:10-96](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L10-L96) +- [backend/modelscope_studio/components/antd/tabs/**init**.py:1-145](file://backend/modelscope_studio/components/antd/tabs/__init__.py#L1-L145) +- [backend/modelscope_studio/components/antd/timeline/**init**.py:1-81](file://backend/modelscope_studio/components/antd/timeline/__init__.py#L1-L81) +- [backend/modelscope_studio/components/antd/tooltip/**init**.py:1-145](file://backend/modelscope_studio/components/antd/tooltip/__init__.py#L1-L145) +- [backend/modelscope_studio/components/antd/tour/**init**.py:1-145](file://backend/modelscope_studio/components/antd/tour/__init__.py#L1-L145) +- [backend/modelscope_studio/components/antd/tree/**init**.py:1-145](file://backend/modelscope_studio/components/antd/tree/__init__.py#L1-L145) + +## Architecture Overview + +The following diagram shows the class relationships and event binding patterns of data display components in the Python layer: + +```mermaid +classDiagram +class ModelScopeLayoutComponent +class ModelScopeComponent +class ModelScopeDataLayoutComponent +class AntdAvatar { ++EVENTS ++SLOTS ++FRONTEND_DIR ++preprocess() ++postprocess() +} +class AntdImage { ++EVENTS ++SLOTS ++FRONTEND_DIR ++preprocess() ++postprocess() +} +class AntdCalendar { ++EVENTS ++SLOTS ++FRONTEND_DIR ++api_info() +} +class AntdCard { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdCarousel { ++EVENTS ++FRONTEND_DIR +} +class AntdCollapse { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdDescriptions { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdEmpty { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdList { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdPopover { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdQRCode { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdTag { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdTagCheckableTag { ++EVENTS ++SLOTS ++FRONTEND_DIR ++api_info() +} +class AntdTagCheckableTagGroup { ++EVENTS ++SLOTS ++FRONTEND_DIR ++api_info() +} +class AntdTimeline { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +ModelScopeDataLayoutComponent <|-- AntdAvatar +ModelScopeDataLayoutComponent <|-- AntdImage +ModelScopeLayoutComponent <|-- AntdCard +ModelScopeLayoutComponent <|-- AntdCarousel +ModelScopeLayoutComponent <|-- AntdCollapse +ModelScopeLayoutComponent <|-- AntdDescriptions +ModelScopeLayoutComponent <|-- AntdEmpty +ModelScopeLayoutComponent <|-- AntdList +ModelScopeLayoutComponent <|-- AntdPopover +ModelScopeComponent <|-- AntdCalendar +ModelScopeComponent <|-- AntdQRCode +ModelScopeLayoutComponent <|-- AntdTag +ModelScopeDataLayoutComponent <|-- AntdTagCheckableTag +ModelScopeDataLayoutComponent <|-- AntdTagCheckableTagGroup +ModelScopeLayoutComponent <|-- AntdTimeline +``` + +**Chart sources** + +- [backend/modelscope_studio/components/antd/avatar/**init**.py:18-114](file://backend/modelscope_studio/components/antd/avatar/__init__.py#L18-L114) +- [backend/modelscope_studio/components/antd/image/**init**.py:18-120](file://backend/modelscope_studio/components/antd/image/__init__.py#L18-L120) +- [backend/modelscope_studio/components/antd/calendar/**init**.py:11-102](file://backend/modelscope_studio/components/antd/calendar/__init__.py#L11-L102) +- [backend/modelscope_studio/components/antd/card/**init**.py:12-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L12-L149) +- [backend/modelscope_studio/components/antd/carousel/**init**.py:8-95](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L8-L95) +- [backend/modelscope_studio/components/antd/collapse/**init**.py:11-99](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L11-L99) +- [backend/modelscope_studio/components/antd/descriptions/**init**.py:9-86](file://backend/modelscope_studio/components/antd/descriptions/__init__.py#L9-L86) +- [backend/modelscope_studio/components/antd/empty/**init**.py:8-71](file://backend/modelscope_studio/components/antd/empty/__init__.py#L8-L71) +- [backend/modelscope_studio/components/antd/list/**init**.py:11-101](file://backend/modelscope_studio/components/antd/list/__init__.py#L11-L101) +- [backend/modelscope_studio/components/antd/popover/**init**.py:10-124](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L124) +- [backend/modelscope_studio/components/antd/qr_code/**init**.py:10-96](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L10-L96) +- [backend/modelscope_studio/components/antd/tag/**init**.py:12-88](file://backend/modelscope_studio/components/antd/tag/__init__.py#L12-L88) +- [backend/modelscope_studio/components/antd/tag/checkable_tag/**init**.py:11-85](file://backend/modelscope_studio/components/antd/tag/checkable_tag/__init__.py#L11-L85) +- [backend/modelscope_studio/components/antd/tag/checkable_tag_group/**init**.py:12-102](file://backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py#L12-L102) +- [backend/modelscope_studio/components/antd/timeline/**init**.py:9-81](file://backend/modelscope_studio/components/antd/timeline/__init__.py#L9-L81) + +## Detailed Component Analysis + +### Avatar + +- Functional purpose: Avatar display, supports icon, placeholder, and error handling events +- Key points + - Supports slots: icon, src + - Events: error + - Data model: AntdAvatarData (root supports FileData or str) + - Preprocessing/postprocessing: converts FileData to path or wraps as FileData +- Key parameters (selected) + - value, alt, gap, icon, shape, size, src_set, draggable, cross_origin, class_names, styles, root_class_name +- Usage example path + - [Example: Avatar with error handling:18-114](file://backend/modelscope_studio/components/antd/avatar/__init__.py#L18-L114) + +**Section sources** + +- [backend/modelscope_studio/components/antd/avatar/**init**.py:18-114](file://backend/modelscope_studio/components/antd/avatar/__init__.py#L18-L114) + +### Badge + +- Functional purpose: Information marking, supports dot, count, status, etc. +- Key points + - Slots: count, text + - Parameters: count, dot, overflow_count, show_zero, size, status, text, title, color, etc. +- Usage example path + - [Example: Badge with status:9-87](file://backend/modelscope_studio/components/antd/badge/__init__.py#L9-87) + +**Section sources** + +- [backend/modelscope_studio/components/antd/badge/**init**.py:9-87](file://backend/modelscope_studio/components/antd/badge/__init__.py#L9-L87) + +### Calendar + +- Functional purpose: Date selection and panel switching +- Key points + - Events: change, panel_change, select + - Slots: cellRender, fullCellRender, headerRender + - API: api_info returns a union type of number|string +- Usage example path + - [Example: Calendar events and render hooks:11-102](file://backend/modelscope_studio/components/antd/calendar/__init__.py#L11-L102) + +**Section sources** + +- [backend/modelscope_studio/components/antd/calendar/**init**.py:11-102](file://backend/modelscope_studio/components/antd/calendar/__init__.py#L11-L102) + +### Card + +- Functional purpose: Information container, supports title, extra content, cover, action area, tabs, etc. +- Key points + - Sub-components: Grid, Meta + - Events: click, tab_change + - Slots: actions, cover, extra, tabBarExtraContent, title, tabList, tabProps.\*, etc. + - Lifecycle: checks for Grid in **exit** +- Usage example path + - [Example: Card layout with tabs:12-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L12-L149) + +**Section sources** + +- [backend/modelscope_studio/components/antd/card/**init**.py:12-149](file://backend/modelscope_studio/components/antd/card/__init__.py#L12-L149) + +### Carousel + +- Functional purpose: Carousel/slideshow container +- Key points + - Parameters: arrows, autoplay, autoplay_speed, adaptive_height, dot_position, dots, draggable, fade, infinite, speed, effect, after_change, before_change, wait_for_animate +- Usage example path + - [Example: Carousel configuration:8-95](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L8-L95) + +**Section sources** + +- [backend/modelscope_studio/components/antd/carousel/**init**.py:8-95](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L8-L95) + +### Collapse + +- Functional purpose: Content folding/expanding +- Key points + - Sub-components: Item + - Events: change + - Slots: expandIcon, items + - Parameters: accordion, active_key, bordered, collapsible, default_active_key, destroy_on_hidden, destroy_inactive_panel, expand_icon, ghost, items, size +- Usage example path + - [Example: Collapse panel with items:11-99](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L11-L99) + +**Section sources** + +- [backend/modelscope_studio/components/antd/collapse/**init**.py:11-99](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L11-L99) + +### Descriptions + +- Functional purpose: Key-value pair description display +- Key points + - Sub-components: Item + - Slots: extra, title, items + - Parameters: bordered, colon, column, content_style, layout, size, title, items, label_style +- Usage example path + - [Example: Descriptions list with items:9-86](file://backend/modelscope_studio/components/antd/descriptions/__init__.py#L9-86) + +**Section sources** + +- [backend/modelscope_studio/components/antd/descriptions/**init**.py:9-86](file://backend/modelscope_studio/components/antd/descriptions/__init__.py#L9-L86) + +### Empty + +- Functional purpose: Empty state placeholder +- Key points + - Slots: description, image + - Parameters: description, image (including constant enums), image_style +- Usage example path + - [Example: Empty state with image:8-71](file://backend/modelscope_studio/components/antd/empty/__init__.py#L8-71) + +**Section sources** + +- [backend/modelscope_studio/components/antd/empty/**init**.py:8-71](file://backend/modelscope_studio/components/antd/empty/__init__.py#L8-L71) + +### Image + +- Functional purpose: Image display and preview +- Key points + - Sub-components: PreviewGroup + - Events: error, preview_transform, preview_visible_change + - Slots: placeholder, preview.mask, preview.closeIcon, preview.toolbarRender, preview.imageRender + - Data model: AntdImageData (root supports FileData or str) + - Preprocessing/postprocessing: similar to Avatar, handles FileData and local paths +- Usage example path + - [Example: Image with preview group:18-120](file://backend/modelscope_studio/components/antd/image/__init__.py#L18-120) + +**Section sources** + +- [backend/modelscope_studio/components/antd/image/**init**.py:18-120](file://backend/modelscope_studio/components/antd/image/__init__.py#L18-L120) + +### List + +- Functional purpose: List rendering and pagination +- Key points + - Sub-components: Item, Item.Meta + - Events: pagination_change, pagination_show_size_change + - Slots: footer, header, loadMore, renderItem + - Parameters: bordered, data_source, footer, grid, header, item_layout, loading, load_more, locale, pagination, render_item, row_key, size, split +- Usage example path + - [Example: List with pagination:11-101](file://backend/modelscope_studio/components/antd/list/__init__.py#L11-L101) + +**Section sources** + +- [backend/modelscope_studio/components/antd/list/**init**.py:11-101](file://backend/modelscope_studio/components/antd/list/__init__.py#L11-L101) + +### Popover + +- Functional purpose: Bubble card with trigger +- Key points + - Events: open_change + - Slots: title, content + - Parameters: align, arrow, auto_adjust_overflow, color, default_open, destroy_tooltip_on_hide, destroy_on_hidden, fresh, get_popup_container, mouse_enter_delay, mouse_leave_delay, overlay_class_name, overlay_style, overlay_inner_style, placement, trigger, open, z_index +- Usage example path + - [Example: Popover with trigger:10-124](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L124) + +**Section sources** + +- [backend/modelscope_studio/components/antd/popover/**init**.py:10-124](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L124) + +### QRCode + +- Functional purpose: Dynamic QR code generation and status management +- Key points + - Events: refresh + - Slots: statusRender + - Parameters: type, bordered, color, bg_color, boost_level, error_level, icon, icon_size, margin_size, size, status, status_render +- Usage example path + - [Example: QR code with status rendering:10-96](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L10-96) + +**Section sources** + +- [backend/modelscope_studio/components/antd/qr_code/**init**.py:10-96](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L10-L96) + +### Segmented + +- Functional purpose: Segmented selector (data display type) +- Key points + - Sub-components: Option + - Parameters: options, block, size, disabled, onChange, etc. (per frontend definition) +- Usage example path + - [Example: Segmented with options](file://backend/modelscope_studio/components/antd/segmented/__init__.py) + +**Section sources** + +- [backend/modelscope_studio/components/antd/segmented/__init__.py] + +### Statistic + +- Functional purpose: Numeric display and countdown +- Key points + - Sub-components: Countdown, Timer + - Parameters: value, precision, prefix, suffix, formatter, groupSeparator, format, onFinish, etc. +- Usage example path + - [Example: Statistic and countdown](file://backend/modelscope_studio/components/antd/statistic/__init__.py) + +**Section sources** + +- [backend/modelscope_studio/components/antd/statistic/__init__.py] + +### Table + +- Functional purpose: Data table rendering and interaction +- Key points + - Sub-components: Column, ColumnGroup, Expandable, RowSelection, RowSelection.Selection + - Parameters: dataSource, columns, pagination, scroll, size, loading, onChange, onHeaderRow, onRow, etc. +- Usage example path + - [Example: Table with column configuration](file://backend/modelscope_studio/components/antd/table/__init__.py) + +**Section sources** + +- [backend/modelscope_studio/components/antd/table/__init__.py] + +### Tabs + +- Functional purpose: Tab container and switching +- Key points + - Sub-components: Item + - Parameters: activeKey, defaultActiveKey, type, tabPosition, size, hideAdd, addIcon, removeIcon, renderTabBar, onEdit, onChange, etc. +- Usage example path + - [Example: Tabs with items](file://backend/modelscope_studio/components/antd/tabs/__init__.py) + +**Section sources** + +- [backend/modelscope_studio/components/antd/tabs/__init__.py] + +### Tag + +- Functional purpose: Tag display and checkable tags +- Key points + - Sub-components: CheckableTag, CheckableTagGroup + - Events: close, change, click + - Slots: icon, closeIcon + - Parameters: value, disabled, href, bordered, close_icon, color, icon +- Usage example path + - [Example: Tag with checkable tags](file://backend/modelscope_studio/components/antd/tag/__init__.py) + +**Update** Added checkable tag group component support, including individual checkable tags and checkable tag groups + +**Section sources** + +- [backend/modelscope_studio/components/antd/tag/**init**.py:12-88](file://backend/modelscope_studio/components/antd/tag/__init__.py#L12-L88) + +### Timeline + +- Functional purpose: Timeline display +- Key points + - Sub-components: Item + - Events: none + - Slots: pending, pendingDot + - Parameters: mode, reverse, orientation, title_span, variant, pending, pending_dot, items +- Usage example path + - [Example: Timeline with items](file://backend/modelscope_studio/components/antd/timeline/__init__.py) + +**Update** Added complete API documentation for the Timeline component, including the latest feature specifications + +**Section sources** + +- [backend/modelscope_studio/components/antd/timeline/**init**.py:9-81](file://backend/modelscope_studio/components/antd/timeline/__init__.py#L9-L81) + +### Tooltip + +- Functional purpose: Text tooltip +- Key points + - Parameters: title, color, placement, trigger, mouseEnterDelay, mouseLeaveDelay, overlayClassName, overlayStyle, overlayInnerStyle, destroyTooltipOnHide, etc. +- Usage example path + - [Example: Text tooltip](file://backend/modelscope_studio/components/antd/tooltip/__init__.py) + +**Section sources** + +- [backend/modelscope_studio/components/antd/tooltip/__init__.py] + +### Tour + +- Functional purpose: Guided navigation +- Key points + - Sub-components: Step + - Parameters: steps, current, scrollIntoViewOptions, mask, gap, indicator, prefixCls, onClose, onChange, etc. +- Usage example path + - [Example: Tour with steps](file://backend/modelscope_studio/components/antd/tour/__init__.py) + +**Section sources** + +- [backend/modelscope_studio/components/antd/tour/__init__.py] + +### Tree + +- Functional purpose: Tree structure display and interaction +- Key points + - Sub-components: TreeNode, DirectoryTree + - Parameters: treeData, defaultExpandAll, defaultExpandedKeys, expandedKeys, selectedKeys, checkable, checkStrictly, multiple, fieldNames, onChange, onCheck, onSelect, etc. +- Usage example path + - [Example: Tree with nodes](file://backend/modelscope_studio/components/antd/tree/__init__.py) + +**Section sources** + +- [backend/modelscope_studio/components/antd/tree/__init__.py] + +### Checkable Tag Group Components + +#### AntdTagCheckableTag + +- Functional purpose: Tag component that supports checked state +- Key points + - Events: change, click + - Slots: icon + - Parameters: label, value, icon + - Data type: boolean, representing the checked state +- Usage example path + - [Example: Checkable tag](file://backend/modelscope_studio/components/antd/tag/checkable_tag/__init__.py) + +#### AntdTagCheckableTagGroup + +- Functional purpose: Container combining multiple checkable tags +- Key points + - Events: change + - Slots: options + - Parameters: options, disabled, multiple, default_value + - Data type: string, number, or string/number array, representing the selected tag values +- Usage example path + - [Example: Checkable tag group](file://backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py) + +**Added** Complete documentation for the checkable tag group component, covering both individual tag and tag group usage patterns + +**Section sources** + +- [backend/modelscope_studio/components/antd/tag/checkable_tag/**init**.py:11-85](file://backend/modelscope_studio/components/antd/tag/checkable_tag/__init__.py#L11-L85) +- [backend/modelscope_studio/components/antd/tag/checkable_tag_group/**init**.py:12-102](file://backend/modelscope_studio/components/antd/tag/checkable_tag_group/__init__.py#L12-L102) + +## Dependency Analysis + +- Component exports: all Antd components are centrally exported in antd/**init**.py and antd/components.py, enabling unified imports and alias usage +- Base class dependency: each component depends on the ModelScope\*Component hierarchy in utils.dev for unified event binding and frontend directory resolution +- Frontend mapping: maps Python components to frontend/antd//Index.svelte via resolve_frontend_dir("component-name") + +```mermaid +graph LR +P["Python Component Classes"] --> B["antd/__init__.py exports"] +P --> C["antd/components.py exports"] +P --> F["frontend/antd//Index.svelte"] +U["utils.dev.ModelScope*Component"] --> P +``` + +**Chart sources** + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +**Section sources** + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +## Performance Considerations + +- Rendering optimization + - Use `destroy_on_hidden`, `destroy_inactive_panel`, and similar parameters in collapse/drawer scenarios to reduce DOM overhead + - List and table components should enable virtual scrolling (scroll.y) and pagination to avoid rendering large numbers of nodes at once + - Timeline component supports the `items` parameter for direct data input, avoiding frequent re-renders +- Lazy loading + - Image component supports `placeholder` and `fallback`, improving initial screen performance when combined with lazy loading strategies + - List supports `loadMore` and `pagination` for on-demand data loading +- Responsive design + - Use `size`, `responsive`, `grid`, and other parameters to adapt to different screen sizes + - Card and Descriptions support small/default/middle sizes, adjusting to content density + - Timeline supports both horizontal and vertical orientations, adapting to different layout requirements +- Themes and styles + - Inject custom styles via `class_names`/`styles`/`root_class_name` to avoid global style pollution + - Use `color`, `status`, and other semantic parameters to express state, reducing repetitive style code + +## Troubleshooting Guide + +- Event not triggered + - Confirm that event names in the EVENTS list are consistent with frontend bindings + - Check that `_internal.update` is being called correctly +- Data not displayed or displayed incorrectly + - Avatar/Image: confirm that `value` is an http/data path or cached file path; check preprocess/postprocess workflow + - Calendar: confirm that `value` type matches the number|string type returned by api_info + - Timeline: confirm that `items` parameter format is correct; supports both direct data input and slot-provided data +- Slots not working + - Confirm that slot names in SLOTS are spelled correctly and that the frontend component has implemented the corresponding slot rendering + - Timeline supports `pending` and `pendingDot` slots; Tag component supports `icon` and `closeIcon` slots +- Performance issues + - Large lists/tables: enable pagination and virtual scrolling; avoid frequent re-renders + - Collapse panels: set `destroy_on_hidden`/`destroy_inactive_panel` appropriately + - Checkable tag group: use the `multiple` parameter to control single or multi-select mode + +**Section sources** + +- [backend/modelscope_studio/components/antd/avatar/**init**.py:89-114](file://backend/modelscope_studio/components/antd/avatar/__init__.py#L89-L114) +- [backend/modelscope_studio/components/antd/image/**init**.py:95-120](file://backend/modelscope_studio/components/antd/image/__init__.py#L95-L120) +- [backend/modelscope_studio/components/antd/calendar/**init**.py:84-102](file://backend/modelscope_studio/components/antd/calendar/__init__.py#L84-L102) +- [backend/modelscope_studio/components/antd/collapse/**init**.py:84-99](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L84-L99) +- [backend/modelscope_studio/components/antd/list/**init**.py:86-101](file://backend/modelscope_studio/components/antd/list/__init__.py#L86-L101) +- [backend/modelscope_studio/components/antd/timeline/**init**.py:65-81](file://backend/modelscope_studio/components/antd/timeline/__init__.py#L65-L81) +- [backend/modelscope_studio/components/antd/tag/**init**.py:19-27](file://backend/modelscope_studio/components/antd/tag/__init__.py#L19-L27) + +## Conclusion + +This document is based on the Python component implementations in the repository, providing an overview of the API characteristics, events and slots, data flow processing, and typical usage paths of data display components. This update specifically enhances documentation for the Timeline and checkable tag group components, providing users with a more complete component usage guide. In actual projects, it is recommended to use this reference in conjunction with frontend component documentation to ensure that event binding, slot rendering, and data formats meet business requirements. + +## Appendix + +- Internationalization support + - Pass localized text via `locale`, `title`, `description`, and other parameters; configure locale in ConfigProvider when necessary + - Timeline component supports customizing pending state text and icons through slots +- Theme customization + - Inject styles via `class_names`/`styles`/`root_class_name`; use `color`/`status` and other semantic parameters to express state + - Checkable tag group supports batch configuration of tag options via the `options` parameter +- Accessibility + - Provide explicit `aria-label` or `title` for interactive elements; ensure keyboard accessibility and visible focus + - Timeline component supports the `reverse` parameter for reverse timeline, improving user experience +- Example index + - Examples for each component can be found as `example_payload`/`example_value` return values in the corresponding component files + - Timeline component supports direct data input via the `items` parameter for simplified usage + - Checkable tag group supports multiple data formats, including simple string arrays and complex object arrays diff --git a/.wiki/en/API Reference/Python API/Antd Components API/Data Entry Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/Data Entry Components API.md new file mode 100644 index 00000000..9512ca96 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/Data Entry Components API.md @@ -0,0 +1,453 @@ +# Data Entry Components API + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/components/antd/auto_complete/__init__.py](file://backend/modelscope_studio/components/antd/auto_complete/__init__.py) +- [backend/modelscope_studio/components/antd/cascader/__init__.py](file://backend/modelscope_studio/components/antd/cascader/__init__.py) +- [backend/modelscope_studio/components/antd/checkbox/__init__.py](file://backend/modelscope_studio/components/antd/checkbox/__init__.py) +- [backend/modelscope_studio/components/antd/color_picker/__init__.py](file://backend/modelscope_studio/components/antd/color_picker/__init__.py) +- [backend/modelscope_studio/components/antd/date_picker/__init__.py](file://backend/modelscope_studio/components/antd/date_picker/__init__.py) +- [backend/modelscope_studio/components/antd/form/__init__.py](file://backend/modelscope_studio/components/antd/form/__init__.py) +- [backend/modelscope_studio/components/antd/input/__init__.py](file://backend/modelscope_studio/components/antd/input/__init__.py) +- [backend/modelscope_studio/components/antd/input_number/__init__.py](file://backend/modelscope_studio/components/antd/input_number/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for Antd data entry components, covering the following components: AutoComplete, Cascader, Checkbox, ColorPicker, DatePicker, Form, Input, InputNumber, Mentions (not found in known backend files), Radio (not found in known backend files), Rate (not found in known backend files), Select (not found in known backend files), Slider (not found in known backend files), Switch (not found in known backend files), TimePicker (not found in known backend files), Transfer (not found in known backend files), TreeSelect (not found in known backend files), Upload (not found in known backend files). +The documentation covers: constructor parameters, events and slots, property definitions, method signatures and return types, data type specifications, preprocessing/postprocessing behavior, usage examples, validation and formatting, error handling, serialization and API integration, real-time validation and UX design principles, and performance optimization recommendations. + +## Project Structure + +Antd components are exported centrally via on-demand imports in the backend, enabling unified usage. Each component has an independent Svelte implementation in the frontend directory, bridged by the backend through a unified base class and frontend directory mapping. + +```mermaid +graph TB +A["Backend Module
backend/modelscope_studio/components/antd/__init__.py"] --> B["AutoComplete
auto_complete/__init__.py"] +A --> C["Cascader
cascader/__init__.py"] +A --> D["Checkbox
checkbox/__init__.py"] +A --> E["ColorPicker
color_picker/__init__.py"] +A --> F["DatePicker
date_picker/__init__.py"] +A --> G["Form
form/__init__.py"] +A --> H["Input
input/__init__.py"] +A --> I["InputNumber
input_number/__init__.py"] +J["Frontend Directory
frontend/antd/*"]:::ext +B --> J +C --> J +D --> J +E --> J +F --> J +G --> J +H --> J +I --> J +classDef ext fill:#fff,stroke:#333,stroke-width:1px; +``` + +Chart sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/auto_complete/**init**.py:1-146](file://backend/modelscope_studio/components/antd/auto_complete/__init__.py#L1-L146) +- [backend/modelscope_studio/components/antd/cascader/**init**.py:1-191](file://backend/modelscope_studio/components/antd/cascader/__init__.py#L1-L191) +- [backend/modelscope_studio/components/antd/checkbox/**init**.py:1-83](file://backend/modelscope_studio/components/antd/checkbox/__init__.py#L1-L83) +- [backend/modelscope_studio/components/antd/color_picker/**init**.py:1-148](file://backend/modelscope_studio/components/antd/color_picker/__init__.py#L1-L148) +- [backend/modelscope_studio/components/antd/date_picker/**init**.py:1-208](file://backend/modelscope_studio/components/antd/date_picker/__init__.py#L1-L208) +- [backend/modelscope_studio/components/antd/form/**init**.py:1-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L1-L133) +- [backend/modelscope_studio/components/antd/input/**init**.py:1-127](file://backend/modelscope_studio/components/antd/input/__init__.py#L1-L127) +- [backend/modelscope_studio/components/antd/input_number/**init**.py:1-147](file://backend/modelscope_studio/components/antd/input_number/__init__.py#L1-L147) + +Section sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) + +## Core Components + +This section provides an overview of the general capabilities and differences of data entry components: + +- All components inherit from a unified data layout component base class, providing consistent lifecycle and event binding mechanisms. +- Each component provides: + - Constructor parameters: supports common properties (e.g., size, status, style, class names, etc.) and component-specific properties. + - Event list: binds frontend callbacks via event listeners. + - Slot list: used for custom rendering (e.g., dropdown panel, prefix/suffix, placeholder content, etc.). + - Data type specifications: declares input/output types through API specs. + - Preprocessing/postprocessing: type conversion or formatting of payload/value. + - Example values and example payloads: facilitates quick integration and testing. + +Section sources + +- [backend/modelscope_studio/components/antd/auto_complete/**init**.py:11-146](file://backend/modelscope_studio/components/antd/auto_complete/__init__.py#L11-L146) +- [backend/modelscope_studio/components/antd/cascader/**init**.py:13-191](file://backend/modelscope_studio/components/antd/cascader/__init__.py#L13-L191) +- [backend/modelscope_studio/components/antd/checkbox/**init**.py:12-83](file://backend/modelscope_studio/components/antd/checkbox/__init__.py#L12-L83) +- [backend/modelscope_studio/components/antd/color_picker/**init**.py:12-148](file://backend/modelscope_studio/components/antd/color_picker/__init__.py#L12-L148) +- [backend/modelscope_studio/components/antd/date_picker/**init**.py:13-208](file://backend/modelscope_studio/components/antd/date_picker/__init__.py#L13-L208) +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) +- [backend/modelscope_studio/components/antd/input/**init**.py:16-127](file://backend/modelscope_studio/components/antd/input/__init__.py#L16-L127) +- [backend/modelscope_studio/components/antd/input_number/**init**.py:11-147](file://backend/modelscope_studio/components/antd/input_number/__init__.py#L11-L147) + +## Architecture Overview + +Backend components connect to frontend directory mappings through a unified base class. The frontend components handle UI rendering and interaction, while the backend manages data type constraints, event binding, and serialization. + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Frontend Component (Svelte)" +participant BE as "Backend Component (Python)" +participant API as "Gradio/Server" +U->>FE : Input/Select/Click +FE-->>BE : Trigger event (e.g., change/search/select) +BE->>BE : Bind event callbacks
Update internal state +BE->>API : Serialize payload and submit +API-->>BE : Return processed value +BE-->>FE : Post-process result and update UI +``` + +Chart sources + +- [backend/modelscope_studio/components/antd/auto_complete/**init**.py:18-43](file://backend/modelscope_studio/components/antd/auto_complete/__init__.py#L18-L43) +- [backend/modelscope_studio/components/antd/cascader/**init**.py:20-36](file://backend/modelscope_studio/components/antd/cascader/__init__.py#L20-L36) +- [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) + +## Detailed Component Analysis + +### AutoComplete + +- Type and purpose: Auto-complete component for string input, supporting option lists and search events. +- Key properties + - Common: size, status, variant, placeholder, disabled, class_names, styles, root_class_name, as_item, etc. + - Specific: allow_clear, auto_focus, backfill, default_active_first_option, default_open, dropdown_render, popup_render, popup_class_name, popup_match_select_width, filter_option, get_popup_container, not_found_content, open, options, placement, options, etc. +- Events: change, blur, focus, search, select, clear, dropdown_visible_change, popup_visible_change. +- Slots: allowClear.clearIcon, dropdownRender, popupRender, children, notFoundContent, options. +- Data types + - Input/Output: string. + - API spec: string type. +- Preprocessing/postprocessing: pass-through. +- Usage examples + - Use as a single input in a form, combined with validation rules. + - Use `options` to provide candidate lists, combined with `search` event for remote search. +- Error handling + - Customize the prompt via `not_found_content` when no match is found. +- Real-time validation + - Trigger remote validation via `search` event, used with Form's validation trigger strategy. + +Section sources + +- [backend/modelscope_studio/components/antd/auto_complete/**init**.py:12-146](file://backend/modelscope_studio/components/antd/auto_complete/__init__.py#L12-L146) + +### Cascader + +- Type and purpose: Multi-level cascading selection, supports async loading and search. +- Key properties + - Common: size, status, variant, placeholder, disabled, class_names, styles, root_class_name, as_item, etc. + - Specific: allow_clear, auto_clear_search_value, auto_focus, change_on_select, display_render, tag_render, popup_class_name, dropdown_render, popup_render, expand_icon, prefix, expand_trigger, filed_names, get_popup_container, max_tag_count, max_tag_placeholder, max_tag_text_length, not_found_content, open, options, placement, show_search, multiple, show_checked_strategy, remove_icon, search_value, dropdown_menu_column_style, option_render, etc. +- Events: change, search, dropdown_visible_change, popup_visible_change, load_data. +- Slots: allowClear.clearIcon, suffixIcon, maxTagPlaceholder, notFoundContent, expandIcon, removeIcon, prefix, displayRender, tagRender, dropdownRender, popupRender, showSearch.render. +- Data types + - Input/Output: string array or number array (path keys). + - API spec: string array or string. +- Preprocessing/postprocessing: pass-through. +- Usage examples + - Commonly used for province/city/district selection, category filtering, and similar scenarios. + - Use `load_data` to implement lazy loading. +- Error handling + - Customize empty state via `not_found_content`. +- Real-time validation + - Combine `search` and `change` events with Form validation. + +Section sources + +- [backend/modelscope_studio/components/antd/cascader/**init**.py:13-191](file://backend/modelscope_studio/components/antd/cascader/__init__.py#L13-L191) + +### Checkbox + +- Type and purpose: Boolean value selection. +- Key properties + - Common: class_names, styles, additional_props, root_class_name, as_item, etc. + - Specific: auto_focus, default_checked, disabled, indeterminate. +- Events: change. +- Data types + - Input/Output: boolean. + - API spec: boolean type. +- Preprocessing/postprocessing: pass-through. +- Usage examples + - Use standalone or combined into a Group. +- Error handling + - No special error handling logic; follows boolean constraints. +- Real-time validation + - Can participate directly in Form validation. + +Section sources + +- [backend/modelscope_studio/components/antd/checkbox/**init**.py:12-83](file://backend/modelscope_studio/components/antd/checkbox/__init__.py#L12-L83) + +### ColorPicker + +- Type and purpose: Color value selection, supports solid color and gradient modes. +- Key properties + - Common: class_names, styles, additional_props, root_class_name, as_item, etc. + - Specific: value_format, allow_clear, arrow, presets, disabled, disabled_alpha, disabled_format, destroy_tooltip_on_hide, destroy_on_hidden, format, mode, open, default_value, default_format, show_text, placement, trigger, panel_render, size. +- Events: change, change_complete, clear, open_change, format_change. +- Slots: presets, panelRender, showText. +- Data types + - Input/Output: hex string or gradient color array object. + - API spec: string or color array object. +- Preprocessing/postprocessing: pass-through. +- Usage examples + - Used for theme color, brand color, and similar configurations. +- Error handling + - Invalid formats are intercepted by frontend validation. +- Real-time validation + - Combine `change` and `change_complete` events with validation. + +Section sources + +- [backend/modelscope_studio/components/antd/color_picker/**init**.py:12-148](file://backend/modelscope_studio/components/antd/color_picker/__init__.py#L12-L148) + +### DatePicker + +- Type and purpose: Date/time selection, supports multiple modes and range selection. +- Key properties + - Common: class_names, styles, additional_props, root_class_name, as_item, etc. + - Specific: allow_clear, auto_focus, cell_render, components, disabled, disabled_date, format, order, preserve_invalid_on_blur, input_read_only, locale, mode, need_confirm, next_icon, open, panel_render, picker, placement, placeholder, popup_class_name, popup_style, get_popup_container, min_date, max_date, prefix, prev_icon, size, presets, status, suffix_icon, super_next_icon, super_prev_icon, variant, default_picker_value, default_value, disabled_time, multiple, picker_value, render_extra_footer, show_now, show_time, show_week, preview_value. +- Events: change, ok, panel_change, open_change. +- Slots: allowClear.clearIcon, prefix, prevIcon, nextIcon, suffixIcon, superNextIcon, superPrevIcon, renderExtraFooter, cellRender, panelRender. +- Data types + - Input/Output: string, number, or array (range). + - API spec: string, number, or array. +- Preprocessing/postprocessing: pass-through. +- Usage examples + - Supports date, week, month, quarter, year, and other modes; can enable time selection and confirmation button. +- Error handling + - Restrict ranges via `disabled_date`, `min_date`, `max_date`. +- Real-time validation + - Combine `panel_change` and `change` events with validation. + +Section sources + +- [backend/modelscope_studio/components/antd/date_picker/**init**.py:13-208](file://backend/modelscope_studio/components/antd/date_picker/__init__.py#L13-L208) + +### Form + +- Type and purpose: Data collection and validation container, supports field change, submit, reset, and validation. +- Key properties + - Common: class_names, styles, additional_props, root_class_name, as_item, etc. + - Specific: form_action, colon, disabled, component, feedback_icons, initial_values, label_align, label_col, label_wrap, layout, form_name, preserve, required_mark, scroll_to_first_error, size, validate_messages, validate_trigger, variant, wrapper_col, clear_on_destroy. +- Events: fields_change, finish, finish_failed, values_change. +- Slots: requiredMark. +- Data types + - Input/Output: dict or wrapped model. + - Preprocessing: extract wrapped model into dict. +- Preprocessing/postprocessing: unpack AntdFormData to dict. +- Usage examples + - Place each data entry component as a child item in Form to manage validation and submission uniformly. +- Error handling + - Control error display and positioning via `validate_messages`, `scroll_to_first_error`. +- Real-time validation + - Control trigger timing via `validate_trigger` (e.g., onChange). + +Section sources + +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) + +### Input + +- Type and purpose: Basic text input, supports password, search, multi-line text, OTP and other variants. +- Key properties + - Common: class_names, styles, additional_props, root_class_name, as_item, etc. + - Specific: addon_after, addon_before, allow_clear, count, default_value, read_only, disabled, max_length, prefix, show_count, size, status, suffix, type, placeholder, variant. +- Events: change, press_enter, clear. +- Slots: addonAfter, addonBefore, allowClear.clearIcon, prefix, suffix, showCount.formatter. +- Data types + - Input/Output: string. + - API spec: string. +- Preprocessing/postprocessing: pass-through. +- Usage examples + - Extend to different forms via Password, Search, Textarea, OTP subclasses. +- Error handling + - Provide feedback via `status` and validation rules. +- Real-time validation + - Combine `change` and `press_enter` events with validation. + +Section sources + +- [backend/modelscope_studio/components/antd/input/**init**.py:16-127](file://backend/modelscope_studio/components/antd/input/__init__.py#L16-L127) + +### InputNumber + +- Type and purpose: Numeric input, supports stepping, precision, up/down controls, etc. +- Key properties + - Common: class_names, styles, additional_props, root_class_name, as_item, etc. + - Specific: addon_after, addon_before, auto_focus, change_on_blur, change_on_wheel, controls, decimal_separator, placeholder, default_value, disabled, formatter, keyboard, max, min, mode, parser, precision, prefix, read_only, size, status, step, string_mode, suffix, variant. +- Events: change, press_enter, step. +- Slots: addonAfter, addonBefore, controls.upIcon, controls.downIcon, prefix, suffix. +- Data types + - Input/Output: integer or float. + - API spec: number. +- Preprocessing/postprocessing: parse string to integer or float. +- Usage examples + - Suitable for price, quantity, rating, and other numeric inputs. +- Error handling + - Constrain range and granularity via `min`/`max`, `precision`, `step`. +- Real-time validation + - Combine `change` and `step` events with validation. + +Section sources + +- [backend/modelscope_studio/components/antd/input_number/**init**.py:11-147](file://backend/modelscope_studio/components/antd/input_number/__init__.py#L11-L147) + +### Mentions (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### Radio (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### Rate (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### Select (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### Slider (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### Switch (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### TimePicker (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### Transfer (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### TreeSelect (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +### Upload (not found in backend) + +- Status: No backend implementation file found in the current repository. +- Recommendation: If needed, refer to the Antd official documentation and frontend implementation, and add the backend adapter layer. + +## Dependency Analysis + +- Inter-component coupling + - All components share the same base class and event system, with low coupling and high cohesion. + - Form acts as a container, aggregating data entry components to form a loosely-coupled form ecosystem. +- External dependencies + - The event system is based on Gradio's event listeners. + - Frontend directory mappings are resolved via utility functions, ensuring frontend-backend consistency. +- Circular dependencies + - No circular dependencies detected. + +```mermaid +graph LR +Base["Unified Base Class"] --> AC["AutoComplete"] +Base --> CS["Cascader"] +Base --> CB["Checkbox"] +Base --> CP["ColorPicker"] +Base --> DP["DatePicker"] +Base --> FM["Form"] +Base --> IN["Input"] +Base --> INN["InputNumber"] +FM --> AC +FM --> CS +FM --> CB +FM --> CP +FM --> DP +FM --> IN +FM --> INN +``` + +Chart sources + +- [backend/modelscope_studio/components/antd/auto_complete/**init**.py:12](file://backend/modelscope_studio/components/antd/auto_complete/__init__.py#L12) +- [backend/modelscope_studio/components/antd/cascader/**init**.py:13](file://backend/modelscope_studio/components/antd/cascader/__init__.py#L13) +- [backend/modelscope_studio/components/antd/checkbox/**init**.py:12](file://backend/modelscope_studio/components/antd/checkbox/__init__.py#L12) +- [backend/modelscope_studio/components/antd/color_picker/**init**.py:12](file://backend/modelscope_studio/components/antd/color_picker/__init__.py#L12) +- [backend/modelscope_studio/components/antd/date_picker/**init**.py:13](file://backend/modelscope_studio/components/antd/date_picker/__init__.py#L13) +- [backend/modelscope_studio/components/antd/form/**init**.py:17](file://backend/modelscope_studio/components/antd/form/__init__.py#L17) +- [backend/modelscope_studio/components/antd/input/**init**.py:16](file://backend/modelscope_studio/components/antd/input/__init__.py#L16) +- [backend/modelscope_studio/components/antd/input_number/**init**.py:11](file://backend/modelscope_studio/components/antd/input_number/__init__.py#L11) + +Section sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) + +## Performance Considerations + +- Event binding and callbacks + - Set event bindings judiciously (e.g., only enable search/visibility change events when necessary) to avoid excessive triggering. +- Data types and serialization + - Numeric input components perform string-to-number conversion during preprocessing, reducing overhead from frontend type inconsistencies. +- Dropdowns and popups + - For complex dropdowns (e.g., Cascader), use lazy loading and virtual scrolling (if supported by the frontend) to reduce rendering costs. +- Styles and class names + - Use `class_names` and `styles` to streamline styles, avoiding repeated computation and repaints. +- Form validation + - Set `validate_trigger` appropriately to avoid performance issues from high-frequency validation. + +## Troubleshooting Guide + +- Event not triggered + - Check that event listeners are correctly bound and confirm that the frontend callback is enabled. +- Data type mismatch + - For numeric input components, preprocessing may fail when non-numeric strings are entered; ensure input format is correct. +- Validation not working + - Confirm that Form's `validate_trigger` settings are consistent with component events; check `required_mark` and `scroll_to_first_error` configuration. +- Dropdown/popup issues + - Check `get_popup_container` and `placement` configuration, ensuring the container is visible and the position is reasonable. +- Cascading load failure + - Confirm that `load_data` callback logic is consistent with the `options` structure. + +Section sources + +- [backend/modelscope_studio/components/antd/input_number/**init**.py:128-140](file://backend/modelscope_studio/components/antd/input_number/__init__.py#L128-L140) +- [backend/modelscope_studio/components/antd/form/**init**.py:48-68](file://backend/modelscope_studio/components/antd/form/__init__.py#L48-L68) +- [backend/modelscope_studio/components/antd/cascader/**init**.py:33-36](file://backend/modelscope_studio/components/antd/cascader/__init__.py#L33-L36) + +## Conclusion + +This project provides a unified Antd data entry component backend adapter layer, covering core components such as AutoComplete, Cascader, Checkbox, ColorPicker, DatePicker, Form, Input, and InputNumber. Through a consistent event system, data type specifications, and preprocessing/postprocessing mechanisms, developers can efficiently build forms and data entry interfaces. For missing components (such as Mentions, Radio, Rate, Select, Slider, Switch, TimePicker, Transfer, TreeSelect, Upload), it is recommended to refer to the Antd official documentation and frontend implementations to add backend adapter layers and maintain ecosystem consistency. + +## Appendix + +- Usage recommendations + - Place data entry components inside a Form container to manage initial values, validation, and submission uniformly. + - For complex inputs (e.g., Cascader, DatePicker), prefer controlled mode with explicit API specs. + - Use slots and variants (`variant`) to improve accessibility and consistency. +- Best practices + - Set reasonable default values and placeholders for each input to improve user experience. + - For wide-range inputs (e.g., numbers), set `min`/`max` and `step` to avoid invalid input. + - For date inputs, specify `format` and `picker` mode explicitly to reduce ambiguity. diff --git a/.wiki/en/API Reference/Python API/Antd Components API/Feedback Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/Feedback Components API.md new file mode 100644 index 00000000..c3aea9f1 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/Feedback Components API.md @@ -0,0 +1,611 @@ +# Feedback Components API + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/alert/__init__.py](file://backend/modelscope_studio/components/antd/alert/__init__.py) +- [backend/modelscope_studio/components/antd/drawer/__init__.py](file://backend/modelscope_studio/components/antd/drawer/__init__.py) +- [backend/modelscope_studio/components/antd/message/__init__.py](file://backend/modelscope_studio/components/antd/message/__init__.py) +- [backend/modelscope_studio/components/antd/modal/__init__.py](file://backend/modelscope_studio/components/antd/modal/__init__.py) +- [backend/modelscope_studio/components/antd/notification/__init__.py](file://backend/modelscope_studio/components/antd/notification/__init__.py) +- [backend/modelscope_studio/components/antd/popconfirm/__init__.py](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py) +- [backend/modelscope_studio/components/antd/progress/__init__.py](file://backend/modelscope_studio/components/antd/progress/__init__.py) +- [backend/modelscope_studio/components/antd/result/__init__.py](file://backend/modelscope_studio/components/antd/result/__init__.py) +- [backend/modelscope_studio/components/antd/skeleton/__init__.py](file://backend/modelscope_studio/components/antd/skeleton/__init__.py) +- [backend/modelscope_studio/components/antd/spin/__init__.py](file://backend/modelscope_studio/components/antd/spin/__init__.py) +- [backend/modelscope_studio/components/antd/watermark/__init__.py](file://backend/modelscope_studio/components/antd/watermark/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/components/antd/modal/static/__init__.py](file://backend/modelscope_studio/components/antd/modal/static/__init__.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) +- [frontend/antd/message/message.tsx](file://frontend/antd/message/message.tsx) +- [frontend/antd/drawer/drawer.tsx](file://frontend/antd/drawer/drawer.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for Antd feedback components, covering Alert, Drawer, Message, Modal, Notification, Popconfirm, Progress, Result, Skeleton, Spin, Watermark, and other feedback-related components. Content includes: + +- Constructor parameters and property definitions +- Method signatures and return types +- Usage examples (provided as "example paths") +- Timing control, animation, and interaction response +- Global configuration, themes, and internationalization +- UX design principles and notification strategy best practices + +## Project Structure + +Feedback components are located in the antd sub-module of the backend Python package. Each component inherits from a unified component base class, with the frontend implemented by corresponding Svelte components interfaced with the Gradio event system. + +```mermaid +graph TB +subgraph "Python Backend" +A["ModelScopeLayoutComponent
ModelScopeComponent
ModelScopeDataLayoutComponent"] +B["antd/__init__.py
exports component aliases"] +C["alert/__init__.py"] +D["drawer/__init__.py"] +E["message/__init__.py"] +F["modal/__init__.py"] +G["notification/__init__.py"] +H["popconfirm/__init__.py"] +I["progress/__init__.py"] +J["result/__init__.py"] +K["skeleton/__init__.py"] +L["spin/__init__.py"] +M["watermark/__init__.py"] +end +subgraph "Frontend Svelte" +P["config-provider/config-provider.tsx"] +Q["message/message.tsx"] +R["drawer/drawer.tsx"] +end +A --> C +A --> D +A --> E +A --> F +A --> G +A --> H +A --> I +A --> J +A --> K +A --> L +A --> M +B --> C +B --> D +B --> E +B --> F +B --> G +B --> H +B --> I +B --> J +B --> K +B --> L +B --> M +P --> E +P --> G +Q --> E +R --> D +``` + +Chart sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [frontend/antd/config-provider/config-provider.tsx:51-106](file://frontend/antd/config-provider/config-provider.tsx#L51-L106) +- [frontend/antd/message/message.tsx:55-78](file://frontend/antd/message/message.tsx#L55-L78) +- [frontend/antd/drawer/drawer.tsx:14-60](file://frontend/antd/drawer/drawer.tsx#L14-L60) + +Section sources + +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +## Core Components + +The following is an overview of common constructor parameters and properties for feedback components (grouped by component): + +- Common parameters + - visible: boolean, whether to render + - elem_id: string, element ID + - elem_classes: list or string, CSS classes + - elem_style: dict, inline styles + - render: boolean, whether to render + - as_item: string, layout item identifier + - class_names: dict or string, additional class name mapping + - styles: dict or string, additional style mapping + - root_class_name: string, root node class name + - additional_props: dict, extra properties passed through to frontend components + - \_internal: internal parameter, reserved by the framework + +- Event binding (registered via EVENTS list) + - Event callbacks are bound to frontend components via internal updates at construction time + +Section sources + +- [backend/modelscope_studio/utils/dev/component.py:28-98](file://backend/modelscope_studio/utils/dev/component.py#L28-L98) +- [backend/modelscope_studio/components/antd/alert/**init**.py:16-20](file://backend/modelscope_studio/components/antd/alert/__init__.py#L16-L20) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:14-18](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L14-L18) +- [backend/modelscope_studio/components/antd/message/**init**.py:14-21](file://backend/modelscope_studio/components/antd/message/__init__.py#L14-L21) +- [backend/modelscope_studio/components/antd/modal/**init**.py:18-25](file://backend/modelscope_studio/components/antd/modal/__init__.py#L18-L25) +- [backend/modelscope_studio/components/antd/notification/**init**.py:14-21](file://backend/modelscope_studio/components/antd/notification/__init__.py#L14-L21) +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:14-27](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L14-L27) +- [backend/modelscope_studio/components/antd/watermark/**init**.py:12-16](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L12-L16) + +## Architecture Overview + +The feedback component call chain is as follows: the Python layer constructs component instances, sets properties and events; the frontend Svelte component receives props and interfaces with Ant Design components; the global ConfigProvider provides themes and internationalization; Message/Notification display globally through frontend context. + +```mermaid +sequenceDiagram +participant Py as "Python Component Instance" +participant FE as "Svelte Frontend Component" +participant CFG as "ConfigProvider" +participant MSG as "Message Context" +participant NOTI as "Notification Context" +Py->>FE : Set properties and events +FE->>CFG : Apply theme/language configuration +CFG-->>FE : Return localization and theme +FE->>MSG : Register message display +FE->>NOTI : Register notification display +MSG-->>Py : Event callbacks e.g. click/close +NOTI-->>Py : Event callbacks e.g. click/close +``` + +Chart sources + +- [frontend/antd/config-provider/config-provider.tsx:51-106](file://frontend/antd/config-provider/config-provider.tsx#L51-L106) +- [frontend/antd/message/message.tsx:55-78](file://frontend/antd/message/message.tsx#L55-L78) +- [backend/modelscope_studio/components/antd/message/**init**.py:14-21](file://backend/modelscope_studio/components/antd/message/__init__.py#L14-L21) +- [backend/modelscope_studio/components/antd/notification/**init**.py:14-21](file://backend/modelscope_studio/components/antd/notification/__init__.py#L14-L21) + +## Detailed Component Analysis + +### Alert + +- Constructor parameters and properties + - action: string, action button content + - after_close: string, callback after closing + - banner: boolean, banner mode + - closable: boolean or dict, closable configuration + - description: string, description text + - icon: string, icon + - message: string, title + - show_icon: boolean, whether to show icon + - type: text enum (success/info/warning/error), type + - slots: supports action, closable.closeIcon, description, icon, message +- Methods + - preprocess(payload): input preprocessing + - postprocess(value): output postprocessing + - example_payload()/example_value(): example data +- Events + - close: close event binding + +Section sources + +- [backend/modelscope_studio/components/antd/alert/**init**.py:25-89](file://backend/modelscope_studio/components/antd/alert/__init__.py#L25-L89) + +### Drawer + +- Constructor parameters and properties + - after_open_change: string, callback on open state change + - auto_focus: boolean, auto focus + - body_style: dict, body style + - close_icon: string, close icon + - closable: boolean or dict, closable + - destroy_on_close/destroy_on_hidden: boolean, destroy on close/hide + - draggable: boolean, draggable + - extra: string, extra content + - footer: string, footer + - force_render: boolean, force render + - get_container: string, container selector + - height/width: number or string, size + - keyboard: boolean, keyboard support + - mask/mask_closable: boolean, mask and click-to-close mask + - placement: text enum (left/right/top/bottom), position + - push: boolean or dict, push + - resizable: boolean, resizable + - size: text enum (default/large), size + - title: string, title + - loading: boolean, loading + - open: boolean, whether open + - z_index: integer, z-index + - drawer_render: string, render function + - slots: supports closeIcon, closable.closeIcon, extra, footer, title, drawerRender +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data +- Events + - close: close event binding + - resizable_resize_start: resize start event binding + - resizable_resize: resize event binding + - resizable_resize_end: resize end event binding + +**Update** Drawer component added three resize-related event handlers: + +- resizable_resize_start: triggered when the user starts dragging to resize the drawer +- resizable_resize: continuously triggered during the resize process +- resizable_resize_end: triggered when the resize operation is complete + +These events allow developers to monitor the dynamic adjustment process of the drawer for more fine-grained interaction control. + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:14-27](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L14-L27) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:26-126](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L26-L126) +- [frontend/antd/drawer/drawer.tsx:14-60](file://frontend/antd/drawer/drawer.tsx#L14-L60) + +### Message + +- Constructor parameters and properties + - content: string, message content + - type: text enum (success/info/warning/error/loading), type + - duration: number, duration + - icon: string, icon + - key: string/number/float, unique key + - pause_on_hover: boolean, pause on hover + - get_container: string, container selector + - rtl: boolean, right-to-left + - top: number, top offset + - slots: supports icon, content +- Methods + - preprocess(payload: str|None): str|None + - postprocess(value: str|None): str|None + - example_payload()/example_value(): example data +- Events + - click/close: click and close event binding + +Section sources + +- [backend/modelscope_studio/components/antd/message/**init**.py:26-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L26-L91) +- [frontend/antd/message/message.tsx:55-78](file://frontend/antd/message/message.tsx#L55-L78) + +### Modal + +- Constructor parameters and properties + - after_close: string, callback after closing + - cancel_button_props/cancel_text: dict/string, cancel button properties and text + - centered: boolean, centered + - closable/close_icon: boolean/dict/string, closable and close icon + - confirm_loading: boolean, confirming + - destroy_on_close/destroy_on_hidden: boolean, destroy on close/hide + - focus_trigger_after_close: boolean, focus trigger after close + - focusable: boolean/dict, focusable + - footer: string or default constant, footer + - force_render: boolean, force render + - get_container: string, container selector + - keyboard: boolean, keyboard support + - mask/mask_closable: boolean, mask and click-to-close mask + - modal_render: string, render function + - ok_text/ok_type/ok_button_props: string/dict, OK button properties + - loading: boolean, loading + - title: string, title + - open: boolean, whether open + - width: number/string, width + - wrap_class_name: string, wrapper class name + - z_index: integer, z-index + - after_open_change: string, callback on open state change + - slots: supports closeIcon, cancelButtonProps.icon, cancelText, closable.closeIcon, closeIcon, footer, title, okButtonProps.icon, okText, modalRender +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data +- Events + - ok/cancel: confirm and cancel event binding +- Static sub-components + - Static: static modal component (for static scenarios) + +Section sources + +- [backend/modelscope_studio/components/antd/modal/**init**.py:34-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L34-L136) +- [backend/modelscope_studio/components/antd/modal/static/**init**.py:30-61](file://backend/modelscope_studio/components/antd/modal/static/__init__.py#L30-L61) + +### Notification + +- Constructor parameters and properties + - message/description/title: string, message, description, title + - type: text enum (success/info/warning/error), type + - btn: string, button + - close_icon: string/boolean, close icon + - duration: number, duration + - show_progress/pause_on_hover: boolean, progress bar and pause on hover + - icon: string, icon + - key: string, unique key + - placement: text enum (top/topLeft/topRight/bottom/bottomLeft/bottomRight), position + - role: text enum (alert/status), role + - bottom/top: number, margins + - rtl: boolean, right-to-left + - get_container: string, container selector + - stack: boolean/dict, stack configuration + - slots: supports actions, closeIcon, description, icon, message, title +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data +- Events + - click/close: click and close event binding + +Section sources + +- [backend/modelscope_studio/components/antd/notification/**init**.py:26-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L26-L109) + +### Popconfirm + +- Constructor parameters and properties + - title/description: string, title and description + - cancel_button_props/cancel_text: dict/string, cancel button + - disabled: boolean, disabled + - icon: string, icon + - ok_button_props/ok_text/ok_type: dict/string/enum, OK button + - show_cancel: boolean, show cancel + - align/arrow/auto_adjust_overflow: dict/boolean, positioning and auto-fit + - color: string, color + - default_open: boolean, initially open + - destroy_tooltip_on_hide/destroy_on_hidden: boolean, destroy strategy + - fresh: boolean, refresh + - get_popup_container: string, popup container + - mouse_enter_delay/mouse_leave_delay: number, delay + - overlay_class_name/overlay_style/overlay_inner_style: string/dict, overlay styles + - placement: text enum (multiple directions), position + - trigger: text enum or list (hover/focus/click/contextMenu), trigger method + - open: boolean, whether open + - z_index: integer, z-index + - slots: supports title, description, cancelButtonProps.icon, cancelText, okButtonProps.icon, okText +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data +- Events + - open_change/cancel/confirm/popup_click: open change, cancel, confirm, popup click event binding + +Section sources + +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:39-156](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L39-L156) + +### Progress + +- Constructor parameters and properties + - percent: integer, default 0, percentage + - format: string, format function + - show_info: boolean, show info + - status: text enum (success/exception/normal/active), status + - rounding: string, rounding + - stroke_color: string/list/dict, stroke color + - stroke_linecap: text enum (round/butt/square), line cap + - success: dict, success area + - trail_color: string, trail color + - type: text enum (line/circle/dashboard), type + - size: number/list/dict/enum (small/default), size + - steps: integer/dict, steps + - percent_position: dict, percent position + - stroke_width: number/float, stroke width + - gap_degree/gap_position/gap_placement: number/enum, gap degree and position +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data + +Section sources + +- [backend/modelscope_studio/components/antd/progress/**init**.py:15-100](file://backend/modelscope_studio/components/antd/progress/__init__.py#L15-L100) + +### Result + +- Constructor parameters and properties + - extra: string, extra content + - icon: string, icon + - status: text enum (success/error/info/warning/404/403/500), status + - sub_title: string, subtitle + - title: string, title + - slots: supports extra, icon, subTitle, title +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data + +Section sources + +- [backend/modelscope_studio/components/antd/result/**init**.py:17-75](file://backend/modelscope_studio/components/antd/result/__init__.py#L17-L75) + +### Skeleton + +- Constructor parameters and properties + - active: boolean, animation + - avatar: boolean/dict, avatar skeleton + - loading: boolean, loading + - paragraph: boolean/dict, paragraph skeleton + - round: boolean, rounded + - title: boolean/dict, title skeleton +- Sub-components + - Node/Avatar/Button/Image/Input: skeleton nodes and elements +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data + +Section sources + +- [backend/modelscope_studio/components/antd/skeleton/**init**.py:22-80](file://backend/modelscope_studio/components/antd/skeleton/__init__.py#L22-L80) + +### Spin + +- Constructor parameters and properties + - spinning: boolean, whether spinning + - delay: number, delay + - fullscreen: boolean, fullscreen + - indicator: string, indicator + - percent: number/float/enum ('auto'), percentage + - size: text enum (small/default/large), size + - tip: string, tip text + - wrapper_class_name: string, wrapper class name + - slots: supports tip, indicator +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data + +Section sources + +- [backend/modelscope_studio/components/antd/spin/**init**.py:17-79](file://backend/modelscope_studio/components/antd/spin/__init__.py#L17-L79) + +### Watermark + +- Constructor parameters and properties + - content: string/list, content (text or array) + - width/height: number/float, size + - inherit: boolean, inherit + - rotate: number/float, rotation angle + - z_index: integer, z-index + - image: string, image watermark + - font: dict, font configuration + - gap: list, gap + - offset: list, offset +- Methods + - preprocess()/postprocess(): preprocessing/postprocessing + - example_payload()/example_value(): example data +- Events + - remove: remove event binding + +Section sources + +- [backend/modelscope_studio/components/antd/watermark/**init**.py:18-84](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L18-L84) + +## Dependency Analysis + +- Component base classes + - ModelScopeLayoutComponent: layout-type component base class, supports events and slots + - ModelScopeComponent: data-type component base class, supports values and loading + - ModelScopeDataLayoutComponent: data+layout combined base class +- Exports and aliases + - Components are exported as public aliases via antd/**init**.py for direct import usage + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +class ModelScopeComponent { ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +class ModelScopeDataLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +class AntdAlert +class AntdDrawer +class AntdMessage +class AntdModal +class AntdNotification +class AntdPopconfirm +class AntdProgress +class AntdResult +class AntdSkeleton +class AntdSpin +class AntdWatermark +ModelScopeLayoutComponent <|-- AntdAlert +ModelScopeLayoutComponent <|-- AntdDrawer +ModelScopeLayoutComponent <|-- AntdMessage +ModelScopeLayoutComponent <|-- AntdModal +ModelScopeLayoutComponent <|-- AntdNotification +ModelScopeLayoutComponent <|-- AntdPopconfirm +ModelScopeLayoutComponent <|-- AntdResult +ModelScopeLayoutComponent <|-- AntdSkeleton +ModelScopeLayoutComponent <|-- AntdSpin +ModelScopeLayoutComponent <|-- AntdWatermark +ModelScopeComponent <|-- AntdProgress +ModelScopeDataLayoutComponent <|-- AntdSkeleton +``` + +Chart sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/antd/alert/**init**.py:11-15](file://backend/modelscope_studio/components/antd/alert/__init__.py#L11-L15) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:10-13](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L10-L13) +- [backend/modelscope_studio/components/antd/message/**init**.py:10-13](file://backend/modelscope_studio/components/antd/message/__init__.py#L10-L13) +- [backend/modelscope_studio/components/antd/modal/**init**.py:11-16](file://backend/modelscope_studio/components/antd/modal/__init__.py#L11-L16) +- [backend/modelscope_studio/components/antd/notification/**init**.py:10-13](file://backend/modelscope_studio/components/antd/notification/__init__.py#L10-L13) +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:10-13](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L10-L13) +- [backend/modelscope_studio/components/antd/progress/**init**.py:8-11](file://backend/modelscope_studio/components/antd/progress/__init__.py#L8-L11) +- [backend/modelscope_studio/components/antd/result/**init**.py:8-11](file://backend/modelscope_studio/components/antd/result/__init__.py#L8-L11) +- [backend/modelscope_studio/components/antd/skeleton/**init**.py:11-14](file://backend/modelscope_studio/components/antd/skeleton/__init__.py#L11-L14) +- [backend/modelscope_studio/components/antd/spin/**init**.py:8-11](file://backend/modelscope_studio/components/antd/spin/__init__.py#L8-L11) +- [backend/modelscope_studio/components/antd/watermark/**init**.py:8-11](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L8-L11) + +Section sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/antd/**init**.py:1-151](file://backend/modelscope_studio/components/antd/__init__.py#L1-L151) + +## Performance Considerations + +- Event binding and callbacks + - Bind callbacks at construction time via the EVENTS list to avoid the overhead of repeated binding at runtime +- Rendering strategy + - destroy_on_close/destroy_on_hidden: destroy on close or hide to reduce memory usage + - force_render: force render on demand to avoid unnecessary re-renders +- Animation and transitions + - Control visual feedback and performance balance through frontend component animation configurations (e.g., Spin's delay, Progress's active) +- Global components + - Message/Notification use context management to avoid frequent creation and destruction of instances + +## Troubleshooting Guide + +- Events not triggered + - Check that the EVENTS list and callback bindings are correct + - Confirm that the frontend component has correctly received and forwarded events +- Display issues + - Check state parameters such as visible, render, open + - For global components (Message/Notification), confirm container selectors and mount targets +- Theme and internationalization not taking effect + - Confirm ConfigProvider's locale and themeMode settings + - Check that the language pack in locales.ts is available + +Section sources + +- [backend/modelscope_studio/components/antd/alert/**init**.py:16-20](file://backend/modelscope_studio/components/antd/alert/__init__.py#L16-L20) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:14-18](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L14-L18) +- [backend/modelscope_studio/components/antd/message/**init**.py:14-21](file://backend/modelscope_studio/components/antd/message/__init__.py#L14-L21) +- [backend/modelscope_studio/components/antd/modal/**init**.py:18-25](file://backend/modelscope_studio/components/antd/modal/__init__.py#L18-L25) +- [backend/modelscope_studio/components/antd/notification/**init**.py:14-21](file://backend/modelscope_studio/components/antd/notification/__init__.py#L14-L21) +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:14-27](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L14-L27) +- [backend/modelscope_studio/components/antd/watermark/**init**.py:12-16](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L12-L16) +- [frontend/antd/config-provider/config-provider.tsx:51-106](file://frontend/antd/config-provider/config-provider.tsx#L51-L106) +- [frontend/antd/config-provider/locales.ts:159-806](file://frontend/antd/config-provider/locales.ts#L159-L806) + +## Conclusion + +This reference document covers the Python API, frontend integration, and global configuration essentials for feedback components. In practice, it is recommended to: + +- Clarify component responsibilities and applicable scenarios (alerts, dialogs, progress, skeleton, loading, watermark) +- Set event and lifecycle parameters appropriately to ensure smooth interactions +- Use ConfigProvider for unified theme and internationalization management +- Follow notification strategies and UX design principles to avoid excessive interruptions + +## Appendix + +- Usage examples (provided as "example paths") + - Message: see [docs/components/antd/message/README-zh_CN.md:1-8](file://docs/components/antd/message/README-zh_CN.md#L1-L8) + - Notification: see [docs/components/antd/notification/README-zh_CN.md:1-8](file://docs/components/antd/notification/README-zh_CN.md#L1-L8) +- Global configuration and internationalization + - ConfigProvider: see [frontend/antd/config-provider/config-provider.tsx:51-106](file://frontend/antd/config-provider/config-provider.tsx#L51-L106) + - Language packs: see [frontend/antd/config-provider/locales.ts:159-806](file://frontend/antd/config-provider/locales.ts#L159-L806) diff --git a/.wiki/en/API Reference/Python API/Antd Components API/General Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/General Components API.md new file mode 100644 index 00000000..6afa4888 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/General Components API.md @@ -0,0 +1,370 @@ +# General Components API + + +**Files Referenced in This Document** +- [button/__init__.py](file://backend/modelscope_studio/components/antd/button/__init__.py) +- [float_button/__init__.py](file://backend/modelscope_studio/components/antd/float_button/__init__.py) +- [icon/__init__.py](file://backend/modelscope_studio/components/antd/icon/__init__.py) +- [typography/__init__.py](file://backend/modelscope_studio/components/antd/typography/__init__.py) +- [affix/__init__.py](file://backend/modelscope_studio/components/antd/affix/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for Antd general components, covering Button, FloatButton, Icon, Typography, and Affix. Contents include: + +- Constructor parameters, property definitions, method signatures, and return types for each component class +- Standard instantiation examples (basic usage and advanced configuration) +- Event handling mechanisms, style customization approaches, and responsive behavior +- Parameter validation rules, exception handling strategies, and best practices +- API index organized by function for quick reference + +## Project Structure + +These components all reside in the backend Python package, wrapped through a unified layout component base class, pointing to corresponding frontend directories for UI rendering. + +```mermaid +graph TB +subgraph "Python Backend" +A["AntdButton
Constructor Parameters/Properties/Methods"] +B["AntdFloatButton
Constructor Parameters/Properties/Methods"] +C["AntdIcon
Constructor Parameters/Properties/Methods"] +D["AntdTypography
Aggregator: Text/Title/Paragraph/Link"] +E["AntdAffix
Constructor Parameters/Properties/Methods"] +end +subgraph "Frontend Directories" +F["button frontend directory"] +G["float-button frontend directory"] +H["icon frontend directory"] +I["typography frontend directory"] +J["affix frontend directory"] +end +A --> F +B --> G +C --> H +D --> I +E --> J +``` + +Diagram sources + +- [button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) +- [float_button/**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) +- [typography/**init**.py:1-12](file://backend/modelscope_studio/components/antd/typography/__init__.py#L1-L12) +- [affix/**init**.py:10-86](file://backend/modelscope_studio/components/antd/affix/__init__.py#L10-L86) + +Section sources + +- [button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) +- [float_button/**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) +- [typography/**init**.py:1-12](file://backend/modelscope_studio/components/antd/typography/__init__.py#L1-L12) +- [affix/**init**.py:10-86](file://backend/modelscope_studio/components/antd/affix/__init__.py#L10-L86) + +## Core Components + +This section provides an overview of the five general components' responsibilities and typical use cases: + +- **Button**: Triggers actions; supports multiple types, variants, sizes, shapes, and states (disabled, danger, ghost, loading). +- **FloatButton**: Floating global function button; can include description, tooltip, badge, and link. +- **Icon**: Semantic vector icon; supports rotation, spin animation, and dual-tone icon color settings. +- **Typography**: Text typography collection; contains Text, Title, Paragraph, and Link sub-components. +- **Affix**: Fixed position container; used to stick child elements to the top or bottom of the viewport. + +Section sources + +- [button/**init**.py:15-38](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L38) +- [float_button/**init**.py:12-21](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L21) +- [icon/**init**.py:9-14](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L14) +- [typography/**init**.py:7-12](file://backend/modelscope_studio/components/antd/typography/__init__.py#L7-L12) +- [affix/**init**.py:10-20](file://backend/modelscope_studio/components/antd/affix/__init__.py#L10-L20) + +## Architecture Overview + +Components follow the "Python wrapper + frontend rendering" pattern, injecting common properties (visibility, DOM ID, class names, inline styles, render toggle, etc.) through the unified layout component base class, and pointing to the corresponding frontend directory via `resolve_frontend_dir`. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Py as "AntdButton/AntdFloatButton/AntdIcon/AntdAffix" +participant Base as "ModelScopeLayoutComponent/ModelScopeDataLayoutComponent" +participant FE as "Frontend Component Directory" +Dev->>Py : Instantiate component with parameters +Py->>Base : Call parent constructor, inject common properties +Py->>FE : Set FRONTEND_DIR pointing to corresponding frontend directory +Base-->>Dev : Return renderable component object +``` + +Diagram sources + +- [button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) +- [float_button/**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) +- [affix/**init**.py:10-86](file://backend/modelscope_studio/components/antd/affix/__init__.py#L10-L86) + +## Detailed Component Analysis + +### Button Component API + +- Type and inheritance + - Class name: `AntdButton` + - Base class: `ModelScopeLayoutComponent` + - Nested sub-component: `Group` (button group) +- Events + - `click`: Click event; binds internal callback to enable event listening +- Slots + - `icon`, `loading.icon` +- Key properties and meanings + - `auto_insert_space`: Whether to automatically insert a space between Chinese characters + - `block`: Whether to span the full width of the parent container + - `class_names`: Semantic DOM class names + - `danger`/`disabled`/`ghost`/`loading`: Danger/disabled/ghost/loading states + - `href`/`html_type`: Link navigation and native HTML type + - `icon`/`icon_position`: Icon and icon position + - `shape`/`size`/`type`/`variant`/`color`: Shape, size, type, variant, color + - `styles`/`root_class_name`: Semantic styles and root class name + - Other Gradio common properties: `visible`, `elem_id`, `elem_classes`, `elem_style`, `render` +- Methods + - `preprocess(payload)`: Accepts string or None, returns string or None + - `postprocess(value)`: Accepts string or None, returns string or None + - `example_payload`/`example_value`: Example payload and example value +- Instantiation notes + - Use `type`/`variant`/`color`/`shape`/`size` to control appearance and semantics + - `loading` can be boolean or dict (if custom loading icon is needed) + - `href` works with `html_type='button'` or `'submit'`/`'reset'` +- Best practices + - Use `primary` type for main actions; use `danger` for destructive actions + - Set `loading` to prevent duplicate submissions + - For icon buttons, use `icon_position='start'`/`'end'` + +Section sources + +- [button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) + +### FloatButton Component API + +- Type and inheritance + - Class name: `AntdFloatButton` + - Base class: `ModelScopeLayoutComponent` + - Nested sub-components: `BackTop` (back to top), `Group` (button group) +- Events + - `click`: Click event; binds internal callback to enable event listening +- Slots + - `icon`, `description`, `tooltip`, `tooltip.title`, `badge.count` +- Key properties and meanings + - `icon`/`description`: Icon and description text + - `tooltip`: Tooltip text or configuration object + - `type`/`shape`: Type (default/primary), shape (circle/square) + - `href`/`href_target`/`html_type`: Hyperlink target and native HTML type + - `badge`: Badge configuration (some state-related properties not supported) + - `class_names`/`styles`/`root_class_name`: Styles and class names + - Other Gradio common properties: `visible`, `elem_id`, `elem_classes`, `elem_style`, `render` +- Methods + - `preprocess(payload)`: Accepts None, returns None + - `postprocess(value)`: Accepts None, returns None + - `example_payload`/`example_value`: Example payload and example value +- Instantiation notes + - Commonly used for global function entry points (e.g., back to top, quick actions) + - `tooltip` supports strings or objects to extend title, etc. +- Best practices + - Use `circle` shape to improve discoverability + - Combine with `BackTop` for "back to top" experience + +Section sources + +- [float_button/**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) + +### Icon Component API + +- Type and inheritance + - Class name: `AntdIcon` + - Base class: `ModelScopeDataLayoutComponent` + - Nested sub-component: `IconfontProvider` (IconFont provider) +- Events + - `click`: Click event; binds internal callback to enable event listening +- Slots + - `component`: Custom root node component +- Key properties and meanings + - `value`: Default icon name (e.g., `"GithubOutlined"`) + - `spin`: Whether to apply spin animation + - `rotate`: Rotation angle (degrees) + - `two_tone_color`: Primary color for dual-tone icons + - `component`: Root node component replacement + - `class_names`/`styles`: Styles and class names + - Other Gradio common properties: `visible`, `elem_id`, `elem_classes`, `elem_style`, `render` +- Methods + - `preprocess(payload)`: Accepts string or None, returns string or None + - `postprocess(value)`: Accepts string or None, returns string or None + - `example_payload`/`example_value`: Example payload and example value +- Instantiation notes + - When used as decorative elements, prefer semantic icon names + - `spin` and `rotate` can be used in combination +- Best practices + - Use in buttons or navigation with `icon_position` + - Explicitly specify the primary color for dual-tone icon scenarios + +Section sources + +- [icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) + +### Typography Component API + +- Type and inheritance + - Class name: `AntdTypography` + - Aggregator: Contains four sub-components: `Text`, `Title`, `Paragraph`, `Link` +- Notes + - This aggregator class only exports sub-components; specific sub-component definitions are in their respective modules +- Instantiation notes + - Access sub-components via `AntdTypography.Text`/`Title`/`Paragraph`/`Link` +- Best practices + - Use `Title` for documents and page headings + - Use `Paragraph` for body text + - Use `Link` for clickable links + +Section sources + +- [typography/**init**.py:1-12](file://backend/modelscope_studio/components/antd/typography/__init__.py#L1-L12) + +### Affix Component API + +- Type and inheritance + - Class name: `AntdAffix` + - Base class: `ModelScopeLayoutComponent` +- Events + - `change`: State change event (attached/detached); binds internal callback to enable event listening +- Key properties and meanings + - `offset_bottom`: Offset from the bottom of the viewport (pixels) + - `offset_top`: Offset from the top of the viewport (pixels) + - `get_target`: Specifies the scroll area DOM node selector + - `class_names`/`styles`/`root_class_name`: Styles and class names + - Other Gradio common properties: `visible`, `elem_id`, `elem_classes`, `elem_style`, `render` +- Methods + - `preprocess(payload)`: Accepts None, returns None + - `postprocess(value)`: Accepts None, returns None + - `example_payload`/`example_value`: Example payload and example value +- Instantiation notes + - Be careful not to block other page content, especially on small-screen devices + - `get_target` can restrict the scroll container to avoid global scroll interference +- Best practices + - Use for menus, toolbars, and other elements that need to remain in the visible area + - Combine with interaction feedback (e.g., `change` event) to update state + +Section sources + +- [affix/**init**.py:10-86](file://backend/modelscope_studio/components/antd/affix/__init__.py#L10-L86) + +## Dependency Analysis + +- Common dependencies + - Base class: `ModelScopeLayoutComponent` or `ModelScopeDataLayoutComponent` + - Event system: `gradio.events.EventListener` + - Frontend directory resolution: `resolve_frontend_dir` +- Inter-component relationships + - Button: Contains `ButtonGroup` + - FloatButton: Contains `BackTop` and `FloatButtonGroup` + - Icon: Contains `IconfontProvider` + - Typography: Aggregates `Text`/`Title`/`Paragraph`/`Link` +- Dependency visualization + +```mermaid +graph LR +subgraph "Events and Base Classes" +EL["EventListener"] +LCB["ModelScopeLayoutComponent"] +DLCB["ModelScopeDataLayoutComponent"] +end +BTN["AntdButton"] --> LCB +BTN --> EL +BTN --> |"resolve_frontend_dir('button')"| FE_BTN["button frontend directory"] +FLT["AntdFloatButton"] --> LCB +FLT --> EL +FLT --> |"resolve_frontend_dir('float-button')"| FE_FLT["float-button frontend directory"] +ICO["AntdIcon"] --> DLCB +ICO --> EL +ICO --> |"resolve_frontend_dir('icon')"| FE_ICO["icon frontend directory"] +TYP["AntdTypography"] --> |"exports Text/Title/Paragraph/Link"| SUB["Sub-components"] +AFF["AntdAffix"] --> LCB +AFF --> EL +AFF --> |"resolve_frontend_dir('affix')"| FE_AFF["affix frontend directory"] +``` + +Diagram sources + +- [button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) +- [float_button/**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) +- [typography/**init**.py:1-12](file://backend/modelscope_studio/components/antd/typography/__init__.py#L1-L12) +- [affix/**init**.py:10-86](file://backend/modelscope_studio/components/antd/affix/__init__.py#L10-L86) + +## Performance Considerations + +- Rendering and events + - Control rendering timing and visibility via Gradio common properties to reduce unnecessary redraws + - Enable event binding only when needed (e.g., `click`/`change`) to avoid excessive monitoring +- Icons and loading + - Use `spin`/`rotate` judiciously to avoid extra overhead on low-end devices + - Button's `loading` state prevents duplicate submissions, indirectly reducing server load +- Containers and scrolling + - Affix's `get_target` should be as precise as possible to avoid frequent calculations on large scroll containers +- Recommendations + - Use heavy components (e.g., Tooltip/Popover) sparingly in large lists; use lazy loading if necessary + - Maintain consistency when using appearance properties like `shape`/`size`/`type` to reduce style switching costs + +## Troubleshooting Guide + +- Events not triggering + - Confirm `EVENTS` is correctly configured and components are in an interactive state (not `disabled`/`loading`) + - For FloatButton/Affix, check that `click`/`change` events are bound +- Styles not taking effect + - Check whether `class_names`/`styles` conflicts with theme variables + - Confirm `root_class_name` is not overridden by external styles +- Icon display anomalies + - Confirm `value` is a supported icon name + - If using a custom `component`, ensure the component is renderable and has no circular dependencies +- Floating button blocking content + - Adjust `offset_top`/`offset_bottom` or use `get_target` to precisely control the scroll area +- Loading state not working + - When Button's `loading` is boolean or dict, confirm the parameter format is correct + +Section sources + +- [button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) +- [float_button/**init**.py:24-29](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L24-L29) +- [affix/**init**.py:21-26](file://backend/modelscope_studio/components/antd/affix/__init__.py#L21-L26) + +## Conclusion + +The above covers the Python API reference and best practice summary for Antd general components. Through a unified base class and event system, these components provide rich appearance and interaction capabilities while remaining simple and easy to use. It is recommended to choose component types and configuration options appropriate for the business scenario in real projects, paying attention to performance and maintainability. + +## Appendix + +- API index by category + - Button components: `AntdButton` (with `Group`), `AntdFloatButton` (with `BackTop`/`Group`) + - Icon components: `AntdIcon` (with `IconfontProvider`) + - Text typography: `AntdTypography` (`Text`/`Title`/`Paragraph`/`Link`) + - Positioning containers: `AntdAffix` +- Quick parameter reference + - Appearance: `type`, `variant`, `color`, `shape`, `size` + - State: `disabled`, `danger`, `ghost`, `loading` + - Behavior: `href`, `html_type`, `icon`, `icon_position`, `tooltip`, `badge` + - Style: `class_names`, `styles`, `root_class_name` + - Events: `click`, `change` +- Example path guide (no code content) + - Button basic usage and loading state: [button/**init**.py:88-108](file://backend/modelscope_studio/components/antd/button/__init__.py#L88-L108) + - FloatButton floating entry with back-to-top combination: [float_button/**init**.py:59-70](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L59-L70) + - Icon animation and dual-tone: [icon/**init**.py:47-53](file://backend/modelscope_studio/components/antd/icon/__init__.py#L47-L53) + - Affix positioning and scroll area: [affix/**init**.py:47-52](file://backend/modelscope_studio/components/antd/affix/__init__.py#L47-L52) diff --git a/.wiki/en/API Reference/Python API/Antd Components API/Layout Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/Layout Components API.md new file mode 100644 index 00000000..4f76af5a --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/Layout Components API.md @@ -0,0 +1,439 @@ +# Layout Components API + + +**Files Referenced in This Document** +- [divider/__init__.py](file://backend/modelscope_studio/components/antd/divider/__init__.py) +- [flex/__init__.py](file://backend/modelscope_studio/components/antd/flex/__init__.py) +- [grid/row/__init__.py](file://backend/modelscope_studio/components/antd/grid/row/__init__.py) +- [grid/col/__init__.py](file://backend/modelscope_studio/components/antd/grid/col/__init__.py) +- [layout/__init__.py](file://backend/modelscope_studio/components/antd/layout/__init__.py) +- [layout/content/__init__.py](file://backend/modelscope_studio/components/antd/layout/content/__init__.py) +- [layout/footer/__init__.py](file://backend/modelscope_studio/components/antd/layout/footer/__init__.py) +- [layout/header/__init__.py](file://backend/modelscope_studio/components/antd/layout/header/__init__.py) +- [layout/sider/__init__.py](file://backend/modelscope_studio/components/antd/layout/sider/__init__.py) +- [space/__init__.py](file://backend/modelscope_studio/components/antd/space/__init__.py) +- [space/compact/__init__.py](file://backend/modelscope_studio/components/antd/space/compact/__init__.py) +- [splitter/__init__.py](file://backend/modelscope_studio/components/antd/splitter/__init__.py) +- [splitter/panel/__init__.py](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for Antd layout components, covering Divider, Flex, Grid (Row/Col), Layout (Layout/Header/Sider/Content/Footer), Space, and Splitter (Splitter/Panel). Contents include: + +- Constructor parameters, property definitions, method signatures, and return types for each component class +- Standard layout combination usage examples (responsive layout, grid system, flex layout) +- Nesting rules, spacing control, and alignment +- Layout breakpoint configuration, media query integration, and mobile adaptation +- Component collaboration patterns and performance optimization recommendations + +## Project Structure + +These layout components all reside in the backend Python package, using a unified base class and frontend directory resolution mechanism, allowing them to map to the corresponding frontend implementations at runtime. + +```mermaid +graph TB +subgraph "Antd Layout Components" +D["Divider"] +F["Flex"] +G["Grid
Row/Col"] +L["Layout
Layout/Header/Sider/Content/Footer"] +S["Space
Space/Compact"] +SP["Splitter
Splitter/Panel"] +end +D --> |"uses"| D +F --> |"uses"| F +G --> |"uses"| G +L --> |"contains"| L +S --> |"uses"| S +SP --> |"contains"| SP +``` + +**Diagram sources** + +- [divider/**init**.py:1-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L1-L95) +- [flex/**init**.py:1-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L1-L98) +- [grid/row/**init**.py:1-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L1-L94) +- [grid/col/**init**.py:1-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L1-L114) +- [layout/**init**.py:1-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L1-L91) +- [layout/content/**init**.py:1-75](file://backend/modelscope_studio/components/antd/layout/content/__init__.py#L1-L75) +- [layout/footer/**init**.py:1-75](file://backend/modelscope_studio/components/antd/layout/footer/__init__.py#L1-L75) +- [layout/header/**init**.py:1-75](file://backend/modelscope_studio/components/antd/layout/header/__init__.py#L1-L75) +- [layout/sider/**init**.py:1-128](file://backend/modelscope_studio/components/antd/layout/sider/__init__.py#L1-L128) +- [space/**init**.py:1-104](file://backend/modelscope_studio/components/antd/space/__init__.py#L1-L104) +- [space/compact/**init**.py:1-81](file://backend/modelscope_studio/components/antd/space/compact/__init__.py#L1-L81) +- [splitter/**init**.py:1-97](file://backend/modelscope_studio/components/antd/splitter/__init__.py#L1-L97) +- [splitter/panel/**init**.py:1-86](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L1-L86) + +**Section sources** + +- [divider/**init**.py:1-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L1-L95) +- [flex/**init**.py:1-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L1-L98) +- [grid/row/**init**.py:1-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L1-L94) +- [grid/col/**init**.py:1-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L1-L114) +- [layout/**init**.py:1-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L1-L91) +- [space/**init**.py:1-104](file://backend/modelscope_studio/components/antd/space/__init__.py#L1-L104) +- [splitter/**init**.py:1-97](file://backend/modelscope_studio/components/antd/splitter/__init__.py#L1-L97) + +## Core Components + +- **Divider**: A dividing line for separating content areas; supports horizontal/vertical, title position, dashed/solid style, plain text style, etc. +- **Flex**: A flex layout container; supports main-axis/cross-axis alignment, wrapping, spacing, direction, etc. +- **Grid**: Grid system; Row provides row-level alignment, spacing, and wrapping; Col provides column span, offset, order, responsive breakpoints, etc. +- **Layout**: Overall page layout; contains Header, Sider, Content, Footer sub-components; supports responsive collapse and breakpoint events. +- **Space**: Sets spacing between child elements; supports direction, alignment, auto-wrap, separator; `Space.Compact` is used for compact form arrangements. +- **Splitter**: Draggable split panel; supports horizontal/vertical layout, panel size range, collapse, and drag events. + +**Section sources** + +- [divider/**init**.py:8-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L8-L95) +- [flex/**init**.py:8-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L8-L98) +- [grid/row/**init**.py:8-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L8-L94) +- [grid/col/**init**.py:8-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L8-L114) +- [layout/**init**.py:14-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L14-L91) +- [space/**init**.py:9-104](file://backend/modelscope_studio/components/antd/space/__init__.py#L9-L104) +- [splitter/**init**.py:11-97](file://backend/modelscope_studio/components/antd/splitter/__init__.py#L11-L97) + +## Architecture Overview + +The following class diagram shows the inheritance and composition relationships of layout components, as well as key properties and methods. + +```mermaid +classDiagram +class AntdDivider { ++__init__(value, dashed, variant, orientation, orientation_margin, plain, type, size, ...) ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdFlex { ++__init__(orientation, vertical, wrap, justify, align, flex, gap, component, ...) ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdRow { ++__init__(align, gutter, justify, wrap, ...) +} +class AntdCol { ++__init__(flex, offset, order, pull, push, span, xs, sm, md, lg, xl, xxl, ...) +} +class AntdLayout { ++__init__(has_sider, ...) ++Content ++Footer ++Header ++Sider +} +class AntdLayoutContent +class AntdLayoutFooter +class AntdLayoutHeader +class AntdLayoutSider { ++__init__(breakpoint, collapsed, collapsed_width, collapsible, default_collapsed, reverse_arrow, theme_value, trigger, width, ...) +} +class AntdSpace { ++__init__(align, direction/orientation, size, split/separator, wrap, ...) ++Compact +} +class AntdSpaceCompact { ++__init__(block, direction, size, ...) +} +class AntdSplitter { ++__init__(layout/orientation, lazy, ...) ++Panel +} +class AntdSplitterPanel { ++__init__(default_size, min, max, size, collapsible, resizable, ...) +} +AntdLayout --> AntdLayoutContent : "contains" +AntdLayout --> AntdLayoutFooter : "contains" +AntdLayout --> AntdLayoutHeader : "contains" +AntdLayout --> AntdLayoutSider : "contains" +AntdSpace --> AntdSpaceCompact : "contains" +AntdSplitter --> AntdSplitterPanel : "contains" +``` + +**Diagram sources** + +- [divider/**init**.py:8-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L8-L95) +- [flex/**init**.py:8-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L8-L98) +- [grid/row/**init**.py:8-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L8-L94) +- [grid/col/**init**.py:8-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L8-L114) +- [layout/**init**.py:14-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L14-L91) +- [layout/sider/**init**.py:11-128](file://backend/modelscope_studio/components/antd/layout/sider/__init__.py#L11-L128) +- [space/**init**.py:9-104](file://backend/modelscope_studio/components/antd/space/__init__.py#L9-L104) +- [splitter/**init**.py:11-97](file://backend/modelscope_studio/components/antd/splitter/__init__.py#L11-L97) +- [splitter/panel/**init**.py:8-86](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L8-L86) + +## Detailed Component Analysis + +### Divider + +- Constructor parameters + - `value`: Optional string as the title text inside the divider + - `dashed`: Optional boolean, whether to use dashed line + - `variant`: Enum value, `'dashed'` | `'dotted'` | `'solid'` + - `orientation`: Enum value, `'left'` | `'right'` | `'center'` | `'start'` | `'end'` + - `orientation_margin`: Optional string or number, margin between title and boundary + - `plain`: Optional boolean, plain text style + - `type`: Enum value, `'horizontal'` | `'vertical'` + - `size`: Optional enum value, `'small'` | `'middle'` | `'large'` (only valid for horizontal) + - Other common properties: `root_class_name`, `class_names`, `styles`, `as_item`, `elem_id`, `elem_classes`, `elem_style`, `visible`, `render`, etc. +- Methods + - `preprocess(payload)`: Accepts string or None, returns string or None + - `postprocess(value)`: Accepts string or None, returns string or None + - `example_payload`/`example_value`: Returns None +- Use cases + - Separating article paragraphs, table action columns, etc. + +**Section sources** + +- [divider/**init**.py:21-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L21-L95) + +### Flex (Flex Layout) + +- Constructor parameters + - `orientation`: Enum value, `'horizontal'` | `'vertical'` + - `vertical`: Boolean, vertical direction (equivalent to `flex-direction: column`) + - `wrap`: Enum value or boolean, `'nowrap'` | `'wrap'` | `'wrap-reverse'` or boolean + - `justify`: Main-axis alignment (various values) + - `align`: Cross-axis alignment (various values) + - `flex`: Flex shorthand property + - `gap`: Spacing size, supports enum or number + - `component`: Custom element type + - Other common properties as above +- Methods + - `preprocess`/`postprocess`: Accepts/returns None + - `example_payload`/`example_value`: Returns None +- Use cases + - Setting element spacing and alignment as a replacement for traditional CSS flex layout + +**Section sources** + +- [flex/**init**.py:21-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L21-L98) + +### Grid (Grid System) + +- Row + - Constructor parameters + - `align`: Vertical alignment, `'top'` | `'middle'` | `'bottom'` | `'stretch'` or object + - `gutter`: Grid spacing, supports number, string, object, or array + - `justify`: Horizontal arrangement, various values + - `wrap`: Boolean, auto wrap + - Other common properties as above + - Methods + - `preprocess`/`postprocess`: Accepts/returns None + - `example_payload`/`example_value`: Returns None +- Col + - Constructor parameters + - `flex`: Flex layout style + - `offset`: Number of grid columns to offset to the right + - `order`: Sort order + - `pull`/`push`: Move left/right + - `span`: Number of grid columns to occupy (0 corresponds to `display: none`) + - `xs`/`sm`/`md`/`lg`/`xl`/`xxl`: Span at different breakpoints or objects containing the above properties + - Other common properties as above + - Methods + - `preprocess`/`postprocess`: Accepts/returns None + - `example_payload`/`example_value`: Returns None +- Use cases + - Responsive layout based on 24-column grid; supports horizontal/vertical alignment, spacing, and breakpoints + +**Section sources** + +- [grid/row/**init**.py:30-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L30-L94) +- [grid/col/**init**.py:30-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L30-L114) + +### Layout (Page Layout) + +- Layout + - Nested sub-components: `Content`, `Footer`, `Header`, `Sider` + - Constructor parameters + - `has_sider`: Whether to include a sidebar (avoids SSR flickering) + - Other common properties as above + - Methods + - `preprocess`/`postprocess`: Accepts/returns None + - `example_payload`/`example_value`: Returns None +- Header/Footer/Content + - Constructor parameters: `class_names`, `styles`, `additional_props`, `root_class_name`, `elem_id`, `elem_classes`, `elem_style`, `visible`, `render`, etc. + - Methods: Same as above +- Sider + - Constructor parameters + - `breakpoint`: Responsive breakpoint + - `collapsed`/`collapsible`/`default_collapsed`: Collapse state related + - `collapsed_width`: Width when collapsed + - `reverse_arrow`: Reverse arrow direction (expands to the right) + - `theme_value`: Theme (light/dark); use when conflicting with Gradio preset attribute + - `trigger`: Custom trigger + - `width`: Width + - `zero_width_trigger_style`: Special trigger style when `collapsed_width` is 0 + - Other common properties as above + - Methods: Same as above +- Events + - Layout/Sider/Header/Footer/Content: Support `click` event binding + - Sider: Supports `collapse`, `breakpoint` events +- Use cases + - Overall page layout; combined with Sider for sidebar navigation and responsive collapse + +**Section sources** + +- [layout/**init**.py:14-91](file://backend/modelscope_studio/components/antd/layout/__init__.py#L14-L91) +- [layout/content/**init**.py:10-75](file://backend/modelscope_studio/components/antd/layout/content/__init__.py#L10-L75) +- [layout/footer/**init**.py:10-75](file://backend/modelscope_studio/components/antd/layout/footer/__init__.py#L10-L75) +- [layout/header/**init**.py:10-75](file://backend/modelscope_studio/components/antd/layout/header/__init__.py#L10-L75) +- [layout/sider/**init**.py:11-128](file://backend/modelscope_studio/components/antd/layout/sider/__init__.py#L11-L128) + +### Space + +- Space + - Nested sub-component: `Compact` + - Constructor parameters + - `align`: Child item alignment + - `direction`/`orientation`: Direction (`orientation` is v6 alias) + - `size`: Spacing size, supports enum, number, or array + - `split`/`separator`: Separator (`separator` is v6 alias) + - `wrap`: Auto wrap when horizontal + - Other common properties as above + - Methods + - `preprocess`/`postprocess`: Accepts/returns None + - `example_payload`/`example_value`: Returns None +- Space.Compact + - Constructor parameters + - `block`: Whether to fill parent width + - `direction`: Direction + - `size`: Child component size + - Other common properties as above + - Methods: Same as above +- Use cases + - Equal spacing arrangement of multiple inline elements; use `Compact` for compact form connections + +**Section sources** + +- [space/**init**.py:9-104](file://backend/modelscope_studio/components/antd/space/__init__.py#L9-L104) +- [space/compact/**init**.py:8-81](file://backend/modelscope_studio/components/antd/space/compact/__init__.py#L8-L81) + +### Splitter (Split Panel) + +- Splitter + - Nested sub-component: `Panel` + - Constructor parameters + - `layout`/`orientation`: Layout direction (`orientation` is v6 alias) + - `lazy`: Whether to use lazy rendering + - Other common properties as above + - Events + - `resize_start`, `resize`, `resize_end`, `collapse` + - Methods + - `preprocess`/`postprocess`: Accepts/returns None + - `example_payload`/`example_value`: Returns None +- Splitter.Panel + - Constructor parameters + - `default_size`/`min`/`max`/`size`: Initial/minimum/maximum/controlled size (supports px or percentage) + - `collapsible`: Quick collapse + - `resizable`: Whether to enable drag-and-drop + - Other common properties as above + - Methods: Same as above +- Use cases + - Divides the page into multiple draggable and resizable areas; supports collapse and range restrictions + +**Section sources** + +- [splitter/**init**.py:11-97](file://backend/modelscope_studio/components/antd/splitter/__init__.py#L11-L97) +- [splitter/panel/**init**.py:8-86](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L8-L86) + +## Dependency Analysis + +- Common component characteristics + - All inherit from the unified layout component base class, with the same preprocessing/postprocessing interface and common properties (e.g., `visible`, `elem_id`, `elem_classes`, `elem_style`, `render`, etc.) + - Locate corresponding frontend component implementations via the frontend directory resolution function +- Inter-component coupling + - Layout acts as the root container, internally composing Header/Sider/Content/Footer + - Space and Flex are semantically complementary: Space focuses on "spacing", Flex focuses on "layout" + - Grid's Row/Col can be combined with Flex/Splitter to achieve complex layouts + - Splitter can work with Space/Divider to implement panel separation and spacing control + +```mermaid +graph LR +L["Layout"] --> H["Header"] +L --> SD["Sider"] +L --> C["Content"] +L --> F["Footer"] +G["Grid.Row"] --> GC["Grid.Col"] +Fx["Flex"] -.-> G +Sp["Space"] -.-> G +Spp["Splitter"] -.-> G +Dv["Divider"] -.-> G +``` + +**Diagram sources** + +- [layout/**init**.py:28-31](file://backend/modelscope_studio/components/antd/layout/__init__.py#L28-L31) +- [grid/row/**init**.py:1-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L1-L94) +- [grid/col/**init**.py:1-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L1-L114) +- [flex/**init**.py:1-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L1-L98) +- [space/**init**.py:1-104](file://backend/modelscope_studio/components/antd/space/__init__.py#L1-L104) +- [splitter/**init**.py:1-97](file://backend/modelscope_studio/components/antd/splitter/__init__.py#L1-L97) +- [divider/**init**.py:1-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L1-L95) + +## Performance Considerations + +- Use lazy loading and deferred rendering appropriately: Splitter supports `lazy` to avoid unnecessary panel initialization +- Control the number of event bindings: Layout/Sider event callbacks should be enabled on demand to reduce unnecessary DOM updates +- Choose between grid and flex layout: Use Space for spacing between many inline elements, Flex for block-level layouts; avoid redundant wrapping +- Responsive breakpoints: Configure Grid's `xs`/`sm`/`md`/`lg`/`xl`/`xxl` based on actual device distribution; avoid excessive granularity causing computation overhead +- SSR optimization: Layout's `has_sider` can avoid flickering during server-side rendering + +## Troubleshooting Guide + +- Theme conflict hint: Sider's `theme` conflicts with Gradio preset attributes; use `theme_value` instead +- Events not working: Confirm event listeners are correctly bound (e.g., `click`, `collapse`, `breakpoint`) and the corresponding callbacks are enabled on the frontend side +- Grid overflow: When the sum of Col `span` values in a Row exceeds 24, they will wrap; check breakpoint configuration and layout logic +- Split panel anomalies: Ensure panel size units are consistent (px or percentage) and set reasonable `min`/`max` values + +**Section sources** + +- [layout/sider/**init**.py:101-104](file://backend/modelscope_studio/components/antd/layout/sider/__init__.py#L101-L104) + +## Conclusion + +This reference document covers the Python API for Antd layout components, clearly defining constructor parameters, methods, and typical usage for each component, while providing combination usage recommendations and performance optimization strategies. Through the collaboration of Layout, Grid, Flex, Space, Splitter, and Divider, a diverse range of layouts can be built from basic grids to complex interactive designs. + +## Appendix + +### Common Layout Combination Examples (Conceptual) + +- Responsive layout + - Use Layout + Sider with collapse/expand at different breakpoints; Sider supports `breakpoint` and `collapse` events + - Grid's `xs`/`sm`/`md`/`lg`/`xl`/`xxl` breakpoint configuration for multi-device adaptation +- Grid system + - Row provides `gutter`, `justify`, `align`, `wrap`; Col provides `span`, `offset`, `order`, `pull`/`push`, responsive breakpoints +- Flex layout + - Flex provides `orientation`/`vertical`, `wrap`, `justify`, `align`, `gap`, `flex`, etc.; suitable for flexible alignment and spacing control +- Spacing and separation + - Space for inline element spacing; `Space.Compact` for compact form arrangements; Divider for content separation + +### Breakpoints and Media Queries + +- Breakpoint constants: `xs` (<576px), `sm` (≥576px), `md` (≥768px), `lg` (≥992px), `xl` (≥1200px), `xxl` (≥1600px) +- Media query integration: Map to layout behavior at different screen sizes via Grid's `xs`/`sm`/`md`/`lg`/`xl`/`xxl` parameters + +### Nesting Rules and Best Practices + +- Layout must contain some sub-components from Header/Sider/Content/Footer, and sub-components must be placed inside Layout +- Grid's Col must be placed directly inside Row, and content elements placed inside Col +- Flex adds no extra wrapper, suitable for block-level layouts; Space adds a wrapper around each child element for inline alignment +- Splitter Panels are resized by dragging; it is recommended to set `min`/`max` and `collapsible` to improve usability diff --git a/.wiki/en/API Reference/Python API/Antd Components API/Navigation Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/Navigation Components API.md new file mode 100644 index 00000000..ed52390f --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/Navigation Components API.md @@ -0,0 +1,569 @@ +# Navigation Components API + + +**Files Referenced in This Document** +- [anchor/__init__.py](file://backend/modelscope_studio/components/antd/anchor/__init__.py) +- [anchor/item/__init__.py](file://backend/modelscope_studio/components/antd/anchor/item/__init__.py) +- [breadcrumb/__init__.py](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py) +- [breadcrumb/item/__init__.py](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py) +- [dropdown/__init__.py](file://backend/modelscope_studio/components/antd/dropdown/__init__.py) +- [dropdown/button/__init__.py](file://backend/modelscope_studio/components/antd/dropdown/button/__init__.py) +- [menu/__init__.py](file://backend/modelscope_studio/components/antd/menu/__init__.py) +- [menu/item/__init__.py](file://backend/modelscope_studio/components/antd/menu/item/__init__.py) +- [pagination/__init__.py](file://backend/modelscope_studio/components/antd/pagination/__init__.py) +- [steps/__init__.py](file://backend/modelscope_studio/components/antd/steps/__init__.py) +- [steps/item/__init__.py](file://backend/modelscope_studio/components/antd/steps/item/__init__.py) + + +## Update Summary + +**Changes** + +- Updated Menu component API documentation with new `popupRender` slot feature description +- Added detailed description of the `popup_render` parameter for the Menu component +- Compared the difference in `popupRender` functionality between Menu and Dropdown components + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference and usage guide for Ant Design navigation-related components, covering the following components: + +- Anchor +- Breadcrumb +- Dropdown +- Menu +- Pagination +- Steps + +Contents include: constructor parameters for component and sub-item classes, event listening, slots, state management key points, routing/frontend interaction patterns, accessibility and keyboard navigation recommendations, as well as performance optimization and best practices. + +## Project Structure + +Navigation components reside in the backend Python package, organized in a "component-level directory + sub-item directory" pattern for easy extension and maintenance. Each component class is responsible for rendering and event binding; sub-item classes carry specific item data structures. + +```mermaid +graph TB +subgraph "Antd Components" +A["anchor/__init__.py"] +B["breadcrumb/__init__.py"] +C["dropdown/__init__.py"] +D["menu/__init__.py"] +E["pagination/__init__.py"] +F["steps/__init__.py"] +end +subgraph "Sub-items" +A1["anchor/item/__init__.py"] +B1["breadcrumb/item/__init__.py"] +C1["dropdown/button/__init__.py"] +D1["menu/item/__init__.py"] +F1["steps/item/__init__.py"] +end +A --> A1 +B --> B1 +C --> C1 +D --> D1 +F --> F1 +``` + +**Section sources** + +- [anchor/**init**.py:1-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L1-L117) +- [breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [dropdown/**init**.py:1-119](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L1-L119) +- [menu/**init**.py:1-125](file://backend/modelscope_studio/components/antd/menu/__init__.py#L1-L125) +- [pagination/**init**.py:1-107](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L1-L107) +- [steps/**init**.py:1-95](file://backend/modelscope_studio/components/antd/steps/__init__.py#L1-L95) + +## Core Components + +This section provides an overview of the responsibilities, typical usage, and key parameters of each navigation component. + +- **Anchor** + - Responsibility: Provides anchor jumps within a single page; supports fixed mode and direction settings. + - Key parameters: `affix`, `bounds`, `get_container`, `offset_top`, `direction`, `replace`, `items`, etc. + - Events: `change`, `click`, `affix_change`. + - Slots: `items`. + - Use cases: Long document table of contents, section positioning. + +- **Breadcrumb** + - Responsibility: Displays the current page's position in the hierarchy. + - Key parameters: `item_render`, `params`, `items`, `separator`. + - Slots: `separator`, `itemRender`, `items`, `dropdownIcon`. + - Use cases: Page path navigation, hierarchical browsing. + +- **Dropdown** + - Responsibility: Pop-up menu triggered by click/hover. + - Key parameters: `arrow`, `auto_adjust_overflow`, `disabled`, `placement`, `trigger`, `menu`, `open`, etc. + - Events: `open_change`, `menu_click`, `menu_select`, `menu_deselect`, `menu_open_change`. + - Slots: `menu.expandIcon`, `menu.overflowedIndicator`, `menu.items`, `dropdownRender`, `popupRender`. + - Use cases: Action entry points, feature set expansion. + +- **Menu** + - Responsibility: Vertical/horizontal/inline navigation menu. + - Key parameters: `open_keys`, `selected_keys`, `mode`, `theme`/`theme_value`, `inline_indent`, `items`, `multiple`, `trigger_sub_menu_action`, `popup_render`, etc. + - Events: `click`, `deselect`, `open_change`, `select`. + - Slots: `expandIcon`, `overflowedIndicator`, `items`, `popupRender`. + - Use cases: Site main navigation, sidebar navigation. + +- **Pagination** + - Responsibility: Page display and navigation for large datasets. + - Key parameters: `current`, `default_current`, `page_size`, `default_page_size`, `total`, `pageSizeOptions`, `showQuickJumper`, `showSizeChanger`, `simple`, `size`, etc. + - Events: `change`, `show_size_change`. + - Slots: `showQuickJumper.goButton`, `itemRender`. + - Use cases: List/table pagination. + +- **Steps** + - Responsibility: Guides users through multi-step processes. + - Key parameters: `current`, `direction`, `label_placement`, `title_placement`, `percent`, `progress_dot`, `size`, `status`, `type`, `items`. + - Events: `change`. + - Slots: `progressDot`, `items`. + - Use cases: Wizards, multi-step form submissions. + +**Section sources** + +- [anchor/**init**.py:11-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L11-L117) +- [breadcrumb/**init**.py:9-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L9-L73) +- [dropdown/**init**.py:11-119](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L11-L119) +- [menu/**init**.py:12-125](file://backend/modelscope_studio/components/antd/menu/__init__.py#L12-L125) +- [pagination/**init**.py:10-107](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L10-L107) +- [steps/**init**.py:11-95](file://backend/modelscope_studio/components/antd/steps/__init__.py#L11-L95) + +## Architecture Overview + +Navigation components uniformly inherit from the layout component base class, and interact with the frontend through frontend directory mapping and event binding. Components support additional property passing, style/class name injection, visibility and render control, and other common capabilities. + +```mermaid +classDiagram +class ModelScopeLayoutComponent +class AntdAnchor { ++__init__(...) ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess(...) ++postprocess(...) ++example_payload() ++example_value() +} +class AntdBreadcrumb { ++__init__(...) ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess(...) ++postprocess(...) ++example_payload() ++example_value() +} +class AntdDropdown { ++__init__(...) ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess(...) ++postprocess(...) ++example_payload() ++example_value() +} +class AntdMenu { ++__init__(...) ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess(...) ++postprocess(...) ++example_payload() ++example_value() +} +class AntdPagination { ++__init__(...) ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess(...) ++postprocess(...) ++example_payload() ++example_value() +} +class AntdSteps { ++__init__(...) ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess(...) ++postprocess(...) ++example_payload() ++example_value() +} +AntdAnchor --> ModelScopeLayoutComponent +AntdBreadcrumb --> ModelScopeLayoutComponent +AntdDropdown --> ModelScopeLayoutComponent +AntdMenu --> ModelScopeLayoutComponent +AntdPagination --> ModelScopeLayoutComponent +AntdSteps --> ModelScopeLayoutComponent +``` + +**Diagram sources** + +- [anchor/**init**.py:11-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L11-L117) +- [breadcrumb/**init**.py:9-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L9-L73) +- [dropdown/**init**.py:11-119](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L11-L119) +- [menu/**init**.py:12-125](file://backend/modelscope_studio/components/antd/menu/__init__.py#L12-L125) +- [pagination/**init**.py:10-107](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L10-L107) +- [steps/**init**.py:11-95](file://backend/modelscope_studio/components/antd/steps/__init__.py#L11-L95) + +## Detailed Component Analysis + +### Anchor API + +- Class: `AntdAnchor` +- Sub-item class: `AntdAnchorItem` +- Events + - `change`: Monitors anchor link changes + - `click`: Handles click events + - `affix_change`: Fixed state change callback +- Slots + - `items`: Anchor item collection +- Key parameters + - `affix`: Whether to enable fixed mode + - `bounds`: Boundary distance of anchor area + - `get_container`: Scroll container selector + - `get_current_anchor`: Custom highlighted anchor + - `offset_top`: Top offset when calculating scroll position + - `show_ink_in_fixed`: Whether to show ink bar in fixed mode + - `target_offset`: Anchor scroll offset, defaults to `offsetTop` + - `items`: Item data, supports nested `children` + - `direction`: Vertical or horizontal direction + - `replace`: Replace browser history instead of adding +- Methods + - `preprocess(payload)`: Returns None + - `postprocess(value)`: Returns None + - `example_payload()`: Returns None + - `example_value()`: Returns None +- Usage examples (path reference) + - Page anchor navigation: [anchor/**init**.py:38-98](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L38-L98) + +**Section sources** + +- [anchor/**init**.py:11-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L11-L117) +- [anchor/item/**init**.py](file://backend/modelscope_studio/components/antd/anchor/item/__init__.py) + +### Breadcrumb API + +- Class: `AntdBreadcrumb` +- Sub-item class: `AntdBreadcrumbItem` +- Slots + - `separator`: Separator + - `itemRender`: Custom item rendering + - `items`: Item collection + - `dropdownIcon`: Dropdown icon +- Key parameters + - `item_render`: Custom item rendering function + - `params`: Rendering parameters + - `items`: Item array + - `separator`: Separator string +- Methods + - `preprocess(payload)`: Returns None + - `postprocess(value)`: Returns None + - `example_payload()`: Returns None + - `example_value()`: Returns None +- Usage examples (path reference) + - Breadcrumb navigation: [breadcrumb/**init**.py:20-54](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L20-L54) + +**Section sources** + +- [breadcrumb/**init**.py:9-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L9-L73) +- [breadcrumb/item/**init**.py](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py) + +### Dropdown API + +- Class: `AntdDropdown` +- Sub-item class: `AntdDropdownButton` +- Events + - `open_change`: Dropdown open/close state change + - `menu_click`: Menu item click + - `menu_select`: Menu item selected + - `menu_deselect`: Menu item deselected + - `menu_open_change`: Sub-menu open/close state change +- Slots + - `menu.expandIcon`: Menu expand icon + - `menu.overflowedIndicator`: Overflow indicator + - `menu.items`: Menu item collection + - `dropdownRender`: Custom dropdown rendering + - `popupRender`: Custom popup rendering +- Key parameters + - `arrow`: Whether to show arrow + - `auto_adjust_overflow`: Whether to auto-adjust overflow + - `auto_focus`: Whether to auto-focus + - `disabled`: Whether to disable + - `destroy_popup_on_hide`: Destroy popup when hidden + - `destroy_on_hidden`: Destroy after hidden + - `dropdown_render`: Dropdown rendering function + - `popup_render`: Popup rendering function + - `get_popup_container`: Popup mount container + - `menu`: Menu configuration object + - `overlay_class_name`: Overlay class name + - `overlay_style`: Overlay style + - `placement`: Popup placement + - `trigger`: Trigger mode (`click`/`hover`/`contextMenu`) + - `open`: Controlled open state + - `inner_elem_style`: Inner element style +- Methods + - `preprocess(payload)`: Returns None + - `postprocess(value)`: Returns None + - `example_payload()`: Returns None + - `example_value()`: Returns None +- Usage examples (path reference) + - Dropdown menu: [dropdown/**init**.py:40-100](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L40-L100) + +**Section sources** + +- [dropdown/**init**.py:11-119](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L11-L119) +- [dropdown/button/**init**.py](file://backend/modelscope_studio/components/antd/dropdown/button/__init__.py) + +### Menu API + +- Class: `AntdMenu` +- Sub-item class: `AntdMenuItem` +- Events + - `click`: Menu item click + - `deselect`: Menu item deselected + - `open_change`: Sub-menu open/close state change + - `select`: Menu item selected +- Slots + - `expandIcon`: Expand icon + - `overflowedIndicator`: Overflow indicator + - `items`: Menu item collection + - `popupRender`: Popup rendering +- Key parameters + - `open_keys`: Controlled open sub-menu keys + - `selected_keys`: Controlled selected menu keys + - `selectable`: Whether selectable + - `default_open_keys`: Default open sub-menu keys + - `default_selected_keys`: Default selected menu keys + - `expand_icon`: Expand icon + - `force_sub_menu_render`: Whether to force render sub-menus + - `inline_collapsed`: Inline collapse + - `inline_indent`: Inline indent pixels + - `items`: Menu item array + - `mode`: Mode (`vertical`/`horizontal`/`inline`) + - `multiple`: Whether multi-select + - `overflowed_indicator`: Overflow indicator + - `sub_menu_close_delay`: Sub-menu close delay + - `sub_menu_open_delay`: Sub-menu open delay + - `theme`/`theme_value`: Theme (light/dark); prefer `theme_value` + - `trigger_sub_menu_action`: Trigger sub-menu action (`click`/`hover`) + - `popup_render`: Popup rendering function +- Methods + - `preprocess(payload)`: Returns None + - `postprocess(value)`: Returns None + - `example_payload()`: Returns None + - `example_value()`: Returns None +- Usage examples (path reference) + - Navigation menu: [menu/**init**.py:36-103](file://backend/modelscope_studio/components/antd/menu/__init__.py#L36-L103) + +**Update** Added `popupRender` parameter for custom menu popup rendering + +**Section sources** + +- [menu/**init**.py:12-125](file://backend/modelscope_studio/components/antd/menu/__init__.py#L12-L125) +- [menu/item/**init**.py](file://backend/modelscope_studio/components/antd/menu/item/__init__.py) + +### Pagination API + +- Class: `AntdPagination` +- Events + - `change`: Page number or page size change + - `show_size_change`: Page size changed +- Slots + - `showQuickJumper.goButton`: Quick jump button + - `itemRender`: Custom page number rendering +- Key parameters + - `align`: Alignment (`start`/`center`/`end`) + - `current`: Current page + - `default_current`: Default current page + - `default_page_size`: Default page size + - `page_size`: Current page size + - `disabled`: Whether to disable + - `hide_on_single_page`: Hide when single page + - `item_render`: Page item rendering function + - `page_size_options`: Page size options + - `responsive`: Responsive layout + - `show_less_items`: Show fewer page numbers + - `show_quick_jumper`: Quick jump toggle or config + - `show_size_changer`: Page size changer toggle or config + - `show_title`: Whether to show title + - `show_total`: Total count rendering template + - `simple`: Simple mode toggle or config + - `size`: Size (`small`/`default`) + - `total`: Total item count +- Methods + - `preprocess(payload)`: Returns None + - `postprocess(value)`: Returns None + - `example_payload()`: Returns None + - `example_value()`: Returns None +- Usage examples (path reference) + - Pagination control: [pagination/**init**.py:26-88](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L26-L88) + +**Section sources** + +- [pagination/**init**.py:10-107](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L10-L107) + +### Steps API + +- Class: `AntdSteps` +- Sub-item class: `AntdStepsItem` +- Events + - `change`: Step change +- Slots + - `progressDot`: Progress dot rendering + - `items`: Step item collection +- Key parameters + - `current`: Current step index + - `direction`: Direction (`horizontal`/`vertical`) + - `initial`: Initial step + - `label_placement`: Label placement (`horizontal`/`vertical`) + - `title_placement`: Title placement + - `percent`: Completion percentage + - `progress_dot`: Whether to use dot-style progress + - `responsive`: Responsive + - `size`: Size (`small`/`default`) + - `status`: Status (`wait`/`process`/`finish`/`error`) + - `type`: Type (`default`/`navigation`/`inline`) + - `items`: Step item array +- Methods + - `preprocess(payload)`: Returns None + - `postprocess(value)`: Returns None + - `example_payload()`: Returns None + - `example_value()`: Returns None +- Usage examples (path reference) + - Steps bar: [steps/**init**.py:25-75](file://backend/modelscope_studio/components/antd/steps/__init__.py#L25-L75) + +**Section sources** + +- [steps/**init**.py:11-95](file://backend/modelscope_studio/components/antd/steps/__init__.py#L11-L95) +- [steps/item/**init**.py](file://backend/modelscope_studio/components/antd/steps/item/__init__.py) + +## Dependency Analysis + +- Common dependencies + - Base class: `ModelScopeLayoutComponent` (unified lifecycle and rendering) + - Event system: `gradio.events.EventListener` (event binding) + - Frontend directory resolution: `resolve_frontend_dir` (maps frontend directories by component name) +- Inter-component coupling + - Components are relatively independent; each carries item data via its own sub-item class, reducing coupling + - Unified event and slot mechanism for easy extension and reuse +- External dependencies + - Works with frontend Svelte components through event binding and props passing for interaction + +```mermaid +graph LR +Base["ModelScopeLayoutComponent"] --> Anchor["AntdAnchor"] +Base --> Breadcrumb["AntdBreadcrumb"] +Base --> Dropdown["AntdDropdown"] +Base --> Menu["AntdMenu"] +Base --> Pagination["AntdPagination"] +Base --> Steps["AntdSteps"] +Events["EventListener"] --> Anchor +Events --> Breadcrumb +Events --> Dropdown +Events --> Menu +Events --> Pagination +Events --> Steps +Resolve["resolve_frontend_dir"] --> Anchor +Resolve --> Breadcrumb +Resolve --> Dropdown +Resolve --> Menu +Resolve --> Pagination +Resolve --> Steps +``` + +**Diagram sources** + +- [anchor/**init**.py:7-99](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L7-L99) +- [breadcrumb/**init**.py:5-56](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L5-L56) +- [dropdown/**init**.py:5-102](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L5-L102) +- [menu/**init**.py:6-105](file://backend/modelscope_studio/components/antd/menu/__init__.py#L6-L105) +- [pagination/**init**.py:5-90](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L5-L90) +- [steps/**init**.py:5-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L5-L77) + +## Performance Considerations + +- Enable event binding on demand: Enable frontend binding only when the corresponding event listener is registered, avoiding unnecessary overhead. +- Controlled state: Use controlled properties like `open_keys`, `selected_keys`, `current` to reduce repeated renders. +- Slots and custom rendering: Use `itemRender`/`dropdownRender` and other slots appropriately; avoid overly complex logic causing re-renders. +- List rendering: Pagination and Menu `items` should be as flat as possible to reduce rendering costs from deep nesting. +- Fixed and scrolling: Anchor's `affix` and `bounds` parameters should be optimized in conjunction with page scroll performance to avoid frequent reflows. +- `popupRender` usage: Menu component's `popupRender` functionality should be used carefully; avoid heavy computations in rendering functions to avoid affecting menu performance. + +## Troubleshooting Guide + +- Events not triggering + - Check if event listeners are correctly registered (e.g., `change`, `click`, `open_change`, etc.) + - Confirm the frontend has the corresponding event binding enabled (triggered by component's internal `_internal` property update) +- Styles/class names not taking effect + - Confirm that `class_names`/`styles`/`root_class_name` are correctly passed + - Check for conflicts with overlay style `overlay_style`/`overlay_class_name` +- Dropdown not showing + - Check `disabled`, `destroy_on_hidden`, `get_popup_container`, and other configurations + - Confirm trigger mode `trigger` and `placement` are appropriate + - Verify `popupRender` slot is correctly configured +- Pagination not working + - Check `total`, `page_size`, `current`, and other parameters for consistency + - Confirm event callbacks update controlled state +- Steps state anomaly + - Check the `current`, `status`, `type`, `direction` parameter combination + - Confirm `items` structure matches the index +- Menu component `popupRender` issues + - Confirm the `popupRender` function or slot is correctly passed to the frontend component + - Check if the return value format of `popupRender` meets Ant Design requirements + - Verify `popupRender` does not cause menu rendering performance issues + +**Section sources** + +- [anchor/**init**.py:20-33](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L20-L33) +- [dropdown/**init**.py:16-32](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L16-L32) +- [menu/**init**.py:18-31](file://backend/modelscope_studio/components/antd/menu/__init__.py#L18-L31) +- [pagination/**init**.py:14-21](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L14-L21) +- [steps/**init**.py:16-20](file://backend/modelscope_studio/components/antd/steps/__init__.py#L16-L20) + +## Conclusion + +This guide systematically covers navigation component APIs, events, slots, and usage points, providing practical recommendations for frontend interaction, state management, accessibility, and performance optimization. It is recommended to choose the appropriate component and parameter combination for the business scenario in real projects to ensure a good user experience and development efficiency. + +**Update** The new `popupRender` slot feature added to the Menu component provides developers with more flexible menu popup customization capabilities; however, performance impact and compatibility requirements must be considered when using it. + +## Appendix + +- Accessibility and keyboard navigation recommendations + - Provide a clear focus order and keyboard operations for interactive elements (e.g., Enter/Space to trigger, Esc to close) + - Provide ARIA attributes for menus and dropdowns (role, aria-expanded, aria-haspopup, etc.) + - Provide clear semantic labels and status hints for pagination and steps +- Routing integration + - Anchor and Steps can be linked with frontend routing, updating current state via event callbacks + - Breadcrumb can dynamically generate items based on the routing path + - Menu component's `popupRender` can be used to implement custom routing navigation popups +- Best practices + - Structure `items` data and avoid heavy computations in rendering functions + - Use controlled properties appropriately to avoid state desynchronization + - Adapt responsive layouts and touch interactions for mobile + - When using `popupRender`, ensure the returned React component structure conforms to Ant Design specifications + - Avoid async operations in `popupRender` to prevent affecting menu response performance diff --git a/.wiki/en/API Reference/Python API/Antd Components API/Other Components API.md b/.wiki/en/API Reference/Python API/Antd Components API/Other Components API.md new file mode 100644 index 00000000..44723699 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antd Components API/Other Components API.md @@ -0,0 +1,422 @@ +# Other Components API + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/config_provider/__init__.py](file://backend/modelscope_studio/components/antd/config_provider/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) +- [frontend/antd/config-provider/Index.svelte](file://frontend/antd/config-provider/Index.svelte) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [docs/demos/example.py](file://docs/demos/example.py) +- [docs/components/antd/config_provider/README.md](file://docs/components/antd/config_provider/README.md) +- [frontend/antd/config-provider/package.json](file://frontend/antd/config-provider/package.json) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for "Other Components" in Ant Design Studio, focusing on the complete API specification and usage instructions for ConfigProvider (global configuration provider). Content covers: + +- Constructor parameters, property definitions, method signatures and return types +- Standard global configuration usage: theme customization, language settings, component defaults +- Scope management, configuration inheritance, and dynamic update mechanisms +- Internationalization configuration, theme switching, and component behavior customization +- Best practices and performance optimization recommendations + +## Project Structure + +ConfigProvider is implemented as a Python class in the backend and wrapped in Svelte on the frontend, interfacing with Ant Design's ConfigProvider while supporting multiple languages through the localization module. + +```mermaid +graph TB +subgraph "Python Backend" +PY_INIT["backend/modelscope_studio/components/antd/__init__.py"] +PY_CP["backend/modelscope_studio/components/antd/config_provider/__init__.py"] +PY_DEV["backend/modelscope_studio/utils/dev/component.py"] +PY_RESOLVE["backend/modelscope_studio/utils/dev/resolve_frontend_dir.py"] +end +subgraph "Frontend" +FE_INDEX["frontend/antd/config-provider/Index.svelte"] +FE_TSX["frontend/antd/config-provider/config-provider.tsx"] +FE_LOCALES["frontend/antd/config-provider/locales.ts"] +FE_PKG["frontend/antd/config-provider/package.json"] +end +PY_INIT --> PY_CP +PY_CP --> PY_RESOLVE +PY_CP --> PY_DEV +PY_CP --> FE_INDEX +FE_INDEX --> FE_TSX +FE_TSX --> FE_LOCALES +FE_INDEX --> FE_PKG +``` + +**Chart sources** + +- [backend/modelscope_studio/components/antd/**init**.py:32](file://backend/modelscope_studio/components/antd/__init__.py#L32) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:22](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L22) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4) +- [frontend/antd/config-provider/Index.svelte:11](file://frontend/antd/config-provider/Index.svelte#L11) +- [frontend/antd/config-provider/config-provider.tsx:51](file://frontend/antd/config-provider/config-provider.tsx#L51) +- [frontend/antd/config-provider/locales.ts:7](file://frontend/antd/config-provider/locales.ts#L7) +- [frontend/antd/config-provider/package.json:1](file://frontend/antd/config-provider/package.json#L1) + +**Section sources** + +- [backend/modelscope_studio/components/antd/**init**.py:32](file://backend/modelscope_studio/components/antd/__init__.py#L32) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:22](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L22) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4) +- [frontend/antd/config-provider/Index.svelte:11](file://frontend/antd/config-provider/Index.svelte#L11) +- [frontend/antd/config-provider/config-provider.tsx:51](file://frontend/antd/config-provider/config-provider.tsx#L51) +- [frontend/antd/config-provider/locales.ts:7](file://frontend/antd/config-provider/locales.ts#L7) +- [frontend/antd/config-provider/package.json:1](file://frontend/antd/config-provider/package.json#L1) + +## Core Components + +- Component name: AntdConfigProvider +- Module: backend.modelscope_studio.components.antd.config_provider +- Base class: ModelScopeLayoutComponent +- Frontend mapping: frontend/antd/config-provider/Index.svelte → frontend/antd/config-provider/config-provider.tsx +- Purpose: Provides unified global configuration (theme, language, size, prefix, popup container, etc.) to all Ant Design components within the application, supporting slot injection and dynamic updates. + +Key points: + +- Supported slots: renderEmpty +- Events: none +- Frontend directory resolution: points to frontend component directory via resolve_frontend_dir("config-provider") +- Skip API export: skip_api returns True to avoid exposing this component in certain automated exports + +**Section sources** + +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:22](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L22) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:28](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L28) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:95](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L95) +- [backend/modelscope_studio/utils/dev/component.py:20](file://backend/modelscope_studio/utils/dev/component.py#L20) + +## Architecture Overview + +The ConfigProvider call chain is as follows: + +```mermaid +sequenceDiagram +participant App as "Application Blocks" +participant CP_Py as "AntdConfigProvider (Python)" +participant CP_Index as "Index.svelte" +participant CP_TSX as "config-provider.tsx" +participant AD as "Ant Design ConfigProvider" +App->>CP_Py : Create and pass configuration parameters +CP_Py->>CP_Index : Resolve frontend directory and render +CP_Index->>CP_TSX : Pass props and slots +CP_TSX->>AD : Inject theme, language, container callback, etc. +AD-->>CP_TSX : Provide context +CP_TSX-->>CP_Index : Render sub-tree +CP_Index-->>App : Child components inherit global configuration +``` + +**Chart sources** + +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:95](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L95) +- [frontend/antd/config-provider/Index.svelte:11](file://frontend/antd/config-provider/Index.svelte#L11) +- [frontend/antd/config-provider/config-provider.tsx:108](file://frontend/antd/config-provider/config-provider.tsx#L108) + +## Detailed Component Analysis + +### Constructor and Property Definitions + +- Class name: AntdConfigProvider +- Inherits: ModelScopeLayoutComponent +- Key properties (partial): + - component_disabled: optional boolean, controls component disabled state + - component_size: optional string, values small/middle/large or None + - csp: optional dict, for CSP configuration + - direction: optional string, values ltr/rtl or None + - get_popup_container: optional string, specifies the popup mount container + - get_target_container: optional string, specifies the target container + - icon_prefix_cls: optional string, icon prefix class name + - locale: optional string, value is a predefined LocaleType + - popup_match_select_width: optional boolean or number, affects popup width strategy + - popup_overflow: optional string, values viewport/scroll + - prefix_cls: optional string, component prefix class name + - render_empty: optional string, for empty state rendering + - theme: optional dict (deprecated), warning prompts to use theme_config + - theme_config: optional dict, theme configuration (recommended) + - variant: optional string, values outlined/filled/borderless + - virtual: optional boolean + - warning: optional dict, warning configuration + - Element-level styles and class names: class_names, styles + - Layout and visibility: visible, elem_id, elem_classes, elem_style, render, as_item + - Extra properties: additional_props + - Other common properties: \_internal (internally reserved) + +Note: + +- Relationship between theme and theme_config: passing theme will trigger a warning; use theme_config instead +- Slots: only renderEmpty is supported + +Method signatures and return types: + +- preprocess(payload: None) -> None +- postprocess(value: None) -> None +- example_payload() -> Any +- example_value() -> Any + +**Section sources** + +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:31](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L31) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:42](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L42) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:86](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L86) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:101](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L101) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:104](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L104) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:108](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L108) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:111](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L111) + +### Frontend Implementation Key Points + +- Types and imports: based on Ant Design's ConfigProvider types, extended with themeMode and theme.algorithm fields +- Theme algorithm: automatically selects dark/compact algorithm based on themeMode, can be merged with external theme.algorithm +- Language settings: locale is inferred from browser environment by default, with en_US as fallback; loads corresponding language packs and dayjs language asynchronously on demand +- Container callbacks: getPopupContainer, getTargetContainer, renderEmpty are wrapped via useFunction to ensure reactive updates +- Slot handling: injects dot-separated paths from slots into corresponding prop positions; renderEmpty supports ReactSlot + +```mermaid +flowchart TD +Start(["Enter Component"]) --> LocaleCheck["Check if localeProp exists"] +LocaleCheck --> HasLocale{"Exists?"} +HasLocale --> |Yes| LoadLocale["Load Antd locale and dayjs locale by locale"] +HasLocale --> |No| UseDefault["Use en_US and default dayjs locale"] +LoadLocale --> ApplyLocale["Set antd locale and dayjs locale"] +UseDefault --> ApplyLocale +ApplyLocale --> ThemeAlg["Merge themeMode and theme.algorithm"] +ThemeAlg --> Render["Render with injected props/slots"] +Render --> End(["Done"]) +``` + +**Chart sources** + +- [frontend/antd/config-provider/config-provider.tsx:96](file://frontend/antd/config-provider/config-provider.tsx#L96) +- [frontend/antd/config-provider/config-provider.tsx:127](file://frontend/antd/config-provider/config-provider.tsx#L127) +- [frontend/antd/config-provider/config-provider.tsx:110](file://frontend/antd/config-provider/config-provider.tsx#L110) + +**Section sources** + +- [frontend/antd/config-provider/config-provider.tsx:51](file://frontend/antd/config-provider/config-provider.tsx#L51) +- [frontend/antd/config-provider/config-provider.tsx:77](file://frontend/antd/config-provider/config-provider.tsx#L77) +- [frontend/antd/config-provider/config-provider.tsx:96](file://frontend/antd/config-provider/config-provider.tsx#L96) +- [frontend/antd/config-provider/config-provider.tsx:127](file://frontend/antd/config-provider/config-provider.tsx#L127) +- [frontend/antd/config-provider/config-provider.tsx:110](file://frontend/antd/config-provider/config-provider.tsx#L110) + +### Internationalization Configuration + +- Language enumeration: LocaleType is a string literal union type covering multiple languages and regions +- Language mapping: lang2RegionMap maps short language codes to specific region codes +- Language loading: locales maps each region code to an async loader function returning antd locale and dayjs locale +- Default language: getDefaultLocale sets dayjs language to English + +Usage recommendations: + +- Use enum values from LocaleType for the locale parameter +- If locale is not provided, it will be auto-inferred from the browser environment with fallback to en_US + +**Section sources** + +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:8](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L8) +- [frontend/antd/config-provider/locales.ts:12](file://frontend/antd/config-provider/locales.ts#L12) +- [frontend/antd/config-provider/locales.ts:89](file://frontend/antd/config-provider/locales.ts#L89) +- [frontend/antd/config-provider/locales.ts:7](file://frontend/antd/config-provider/locales.ts#L7) + +### Theme and Variant Configuration + +- Theme entry: theme_config (recommended) or deprecated theme +- Theme algorithm: themeMode controls dark/compact, can be merged with external algorithm +- Component variant: variant supports outlined/filled/borderless + +Best practices: + +- Use theme_config for theme customization to avoid conflicts with Gradio presets +- Control themeMode via toggle variables to achieve dynamic switching between light/dark/compact themes + +**Section sources** + +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:86](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L86) +- [frontend/antd/config-provider/config-provider.tsx:88](file://frontend/antd/config-provider/config-provider.tsx#L88) +- [frontend/antd/config-provider/config-provider.tsx:127](file://frontend/antd/config-provider/config-provider.tsx#L127) + +### Scope Management, Inheritance, and Dynamic Updates + +- Scope: ConfigProvider as a layout component means all components in its subtree inherit the global configuration +- Inheritance: child components don't need to repeatedly pass the same configuration, reading directly from context +- Dynamic updates: output to ConfigProvider via Gradio's update to change theme_config, locale, direction, etc. in real time + +Reference examples: + +- Documentation examples demonstrate how to dynamically update ConfigProvider's locale, direction, and theme_config during interactions + +**Section sources** + +- [docs/demos/example.py:6](file://docs/demos/example.py#L6) +- [docs/components/antd/config_provider/README.md:7](file://docs/components/antd/config_provider/README.md#L7) + +### API Definitions and Type Summary + +- Constructor parameters (selected) + - component_disabled: bool | None + - component_size: "small"|"middle"|"large" | None + - csp: dict | None + - direction: "ltr"|"rtl" | None + - get_popup_container: str | None + - get_target_container: str | None + - icon_prefix_cls: str | None + - locale: LocaleType | None + - popup_match_select_width: bool | int | float | None + - popup_overflow: "viewport"|"scroll" | None + - prefix_cls: str | None + - render_empty: str | None + - theme: dict | None + - theme_config: dict | None + - variant: "outlined"|"filled"|"borderless" | None + - virtual: bool | None + - warning: dict | None + - class_names: dict | str | None + - styles: dict | str | None + - as_item: str | None + - \_internal: None + - visible: bool + - elem_id: str | None + - elem_classes: list[str] | str | None + - elem_style: dict | None + - render: bool + - additional_props: dict | None + - Other common keyword arguments + +- Methods + - preprocess(payload: None) -> None + - postprocess(value: None) -> None + - example_payload() -> Any + - example_value() -> Any + +- Properties + - skip_api: True + - FRONTEND_DIR: resolved by resolve_frontend_dir("config-provider") + +**Section sources** + +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:31](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L31) +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:95](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L95) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4) + +## Dependency Analysis + +- Python layer + - Inherits from ModelScopeLayoutComponent, enabling layout context capabilities + - Resolves frontend component directory via resolve_frontend_dir + - Exported as ConfigProvider in antd/**init**.py + +- Frontend layer + - Index.svelte converts Python-passed props and slots into React Props + - config-provider.tsx interfaces with Ant Design ConfigProvider, injecting themes, language, container callbacks, and slots + - locales.ts provides language mapping and async loading + +```mermaid +graph LR +PY["AntdConfigProvider"] --> RES["resolve_frontend_dir"] +PY --> DEV["ModelScopeLayoutComponent"] +PY --> EXP["antd/__init__.py export"] +EXP --> IDX["Index.svelte"] +IDX --> TSX["config-provider.tsx"] +TSX --> LOCALES["locales.ts"] +``` + +**Chart sources** + +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4) +- [backend/modelscope_studio/utils/dev/component.py:11](file://backend/modelscope_studio/utils/dev/component.py#L11) +- [backend/modelscope_studio/components/antd/**init**.py:32](file://backend/modelscope_studio/components/antd/__init__.py#L32) +- [frontend/antd/config-provider/Index.svelte:11](file://frontend/antd/config-provider/Index.svelte#L11) +- [frontend/antd/config-provider/config-provider.tsx:51](file://frontend/antd/config-provider/config-provider.tsx#L51) +- [frontend/antd/config-provider/locales.ts:7](file://frontend/antd/config-provider/locales.ts#L7) + +**Section sources** + +- [backend/modelscope_studio/components/antd/**init**.py:32](file://backend/modelscope_studio/components/antd/__init__.py#L32) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4) +- [frontend/antd/config-provider/Index.svelte:11](file://frontend/antd/config-provider/Index.svelte#L11) +- [frontend/antd/config-provider/config-provider.tsx:51](file://frontend/antd/config-provider/config-provider.tsx#L51) +- [frontend/antd/config-provider/locales.ts:7](file://frontend/antd/config-provider/locales.ts#L7) + +## Performance Considerations + +- Theme switching + - Use the themeMode and theme.algorithm merge strategy to avoid frequent rebuilding of theme objects + - Only trigger language pack loading when locale changes, reducing unnecessary async overhead +- Popup container and target container + - Wrap callbacks via useFunction to reduce re-renders caused by function reference changes +- Slot rendering + - renderEmpty is rendered via ReactSlot to avoid additional DOM operations +- Prefix and styles + - Use prefix_cls and class_names/styles to control style scope, avoiding global pollution + +[This section provides general guidance and does not directly analyze specific files] + +## Troubleshooting Guide + +- Theme conflicts + - Passing theme will trigger a warning; use theme_config instead +- Language not taking effect + - Confirm that locale is a valid value from LocaleType; if empty, it falls back to en_US + - Check that the locales mapping contains the corresponding region code +- Popup position issues + - Check that the container returned by get_popup_container/get_target_container exists and is correct +- Slots not displaying + - Confirm that the slot name and path are consistent (e.g., renderEmpty), and that it is correctly injected on the frontend + +**Section sources** + +- [backend/modelscope_studio/components/antd/config_provider/**init**.py:86](file://backend/modelscope_studio/components/antd/config_provider/__init__.py#L86) +- [frontend/antd/config-provider/config-provider.tsx:96](file://frontend/antd/config-provider/config-provider.tsx#L96) +- [frontend/antd/config-provider/config-provider.tsx:117](file://frontend/antd/config-provider/config-provider.tsx#L117) + +## Conclusion + +AntdConfigProvider provides global configuration capabilities for Ant Design components, covering key dimensions such as theme, language, size, container, and empty state rendering. Through unified encapsulation on the Python side and efficient frontend integration, developers can conveniently implement configuration inheritance and dynamic updates within scope. It is recommended to use theme_config for theme customization and combine locale with direction for internationalization and layout adaptation. + +[This section is a summary and does not directly analyze specific files] + +## Appendix + +### Usage Examples and References + +- Basic usage example (documentation demo) + - Example demonstrates nesting ConfigProvider within Application and AutoLoading scopes, with DatePicker used inside + - Reference path: docs/demos/example.py + +- Documentation page + - README contains a basic example placeholder; actual demo is in demos/basic.py + +**Section sources** + +- [docs/demos/example.py:6](file://docs/demos/example.py#L6) +- [docs/components/antd/config_provider/README.md:7](file://docs/components/antd/config_provider/README.md#L7) + +### Component Registration and Exports + +- Exported as ConfigProvider alias in antd/**init**.py +- Imported and exported as AntdConfigProvider in components.py + +**Section sources** + +- [backend/modelscope_studio/components/antd/**init**.py:32](file://backend/modelscope_studio/components/antd/__init__.py#L32) +- [backend/modelscope_studio/components/antd/components.py:31](file://backend/modelscope_studio/components/antd/components.py#L31) diff --git a/.wiki/en/API Reference/Python API/Antdx Components API/Antdx Components API.md b/.wiki/en/API Reference/Python API/Antdx Components API/Antdx Components API.md new file mode 100644 index 00000000..1901618e --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antdx Components API/Antdx Components API.md @@ -0,0 +1,443 @@ +# Antdx Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/antdx/bubble/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/__init__.py) +- [backend/modelscope_studio/components/antdx/conversations/__init__.py](file://backend/modelscope_studio/components/antdx/conversations/__init__.py) +- [backend/modelscope_studio/components/antdx/prompts/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/__init__.py) +- [backend/modelscope_studio/components/antdx/attachments/__init__.py](file://backend/modelscope_studio/components/antdx/attachments/__init__.py) +- [backend/modelscope_studio/components/antdx/sender/__init__.py](file://backend/modelscope_studio/components/antdx/sender/__init__.py) +- [backend/modelscope_studio/components/antdx/actions/__init__.py](file://backend/modelscope_studio/components/antdx/actions/__init__.py) +- [backend/modelscope_studio/components/antdx/file_card/__init__.py](file://backend/modelscope_studio/components/antdx/file_card/__init__.py) +- [backend/modelscope_studio/components/antdx/folder/__init__.py](file://backend/modelscope_studio/components/antdx/folder/__init__.py) +- [backend/modelscope_studio/components/antdx/code_highlighter/__init__.py](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py) +- [backend/modelscope_studio/components/antdx/notification/__init__.py](file://backend/modelscope_studio/components/antdx/notification/__init__.py) +- [backend/modelscope_studio/components/antdx/sources/__init__.py](file://backend/modelscope_studio/components/antdx/sources/__init__.py) +- [backend/modelscope_studio/components/antdx/suggestion/__init__.py](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py) +- [backend/modelscope_studio/components/antdx/think/__init__.py](file://backend/modelscope_studio/components/antdx/think/__init__.py) +- [backend/modelscope_studio/components/antdx/thought_chain/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for the Antdx component library, focusing on ML and AI application-related components under `modelscope_studio.components.antdx.*`. It covers the complete import paths, constructor parameters, property definitions, method signatures, and return type descriptions for 20+ component classes, and provides standard instantiation examples and best practices for typical scenarios such as conversational systems, file handling, and user input. It also documents the event handling mechanisms, lifecycle management, state synchronization strategies, and performance optimization recommendations. + +## Project Structure + +Antdx components reside in the backend Python package `modelscope_studio/components/antdx/`, organized by functional domain: each subdirectory corresponds to a component or component family (e.g., bubble, conversations, sender), and exports are unified through `__init__.py`. `components.py` and `__init__.py` provide consistent aggregated export entry points for direct import from `modelscope_studio.components.antdx.*`. + +```mermaid +graph TB +A["Python Package
modelscope_studio.components.antdx"] --> B["actions/*"] +A --> C["attachments/*"] +A --> D["bubble/*"] +A --> E["conversations/*"] +A --> F["file_card/*"] +A --> G["folder/*"] +A --> H["prompts/*"] +A --> I["sender/*"] +A --> J["sources/*"] +A --> K["suggestion/*"] +A --> L["think/*"] +A --> M["thought_chain/*"] +A --> N["notification/*"] +A --> O["code_highlighter/*"] +A --> P["x_provider/*"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +Section Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Core Components + +The following lists all ML and AI scenario-related component classes in `modelscope_studio.components.antdx.*` with their import paths and usage overview: + +- Layout & Display + - Bubble: For message/text display and interaction, supports editing, typing animation, variants, shapes, etc. + - Conversations: For multi-conversation management and menu interactions. + - Prompts: For displaying a set of clickable prompt items. + - Suggestions: For input suggestions and selection. + - Think: For displaying a "thinking" state and expand control. + - ThoughtChain: For displaying reasoning processes in tree/chain form. + - CodeHighlighter: For code block rendering and theme control. + - Notification: For Web Notification integration and event binding. + - Sources: For displaying source entries and expand control. + - Welcome: For landing page or welcome message display (present in exports). + - XProvider: For global context injection (present in exports). + +- Data & Input + - Attachments: For file upload, drag-and-drop, preview, download, and removal. + - Sender: For user input, keyboard shortcuts, voice, paste, and submit events. + - FileCard: For card-style display and operations on individual files. + - Folder: For tree-style directory browsing and file/folder selection. + - Actions: For a group of clickable action items and dropdown menus. + +- Pro Extensions (Pro module) + - Chatbot: For conversational flows and message stream management (present in exports). + - MultimodalInput: For multimodal input including text, images, audio, and video (present in exports). + - MonacoEditor: For code editing and highlighting (present in exports). + - WebSandbox: For secure sandbox execution (present in exports). + +Section Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Architecture Overview + +Antdx components are wrapped through a unified base class, inheriting from Gradio's component system, supporting event listeners, slots, style and class name injection, and frontend resource directory resolution. Most components are layout-type components (`skip_api=True`) that do not directly expose API schemas; a few data-type components (such as Attachments and Sender) implement `preprocess/postprocess` and expose API specifications. + +```mermaid +classDiagram +class ModelScopeLayoutComponent +class ModelScopeDataLayoutComponent +class AntdXBubble +class AntdXConversations +class AntdXPrompts +class AntdXAttachments +class AntdXSender +class AntdXActions +class AntdXFileCard +class AntdXFolder +class AntdXCodeHighlighter +class AntdXNotification +class AntdXSources +class AntdXSuggestion +class AntdXThink +class AntdXThoughtChain +AntdXBubble --|> ModelScopeLayoutComponent +AntdXConversations --|> ModelScopeLayoutComponent +AntdXPrompts --|> ModelScopeLayoutComponent +AntdXFileCard --|> ModelScopeLayoutComponent +AntdXFolder --|> ModelScopeLayoutComponent +AntdXCodeHighlighter --|> ModelScopeLayoutComponent +AntdXNotification --|> ModelScopeLayoutComponent +AntdXSources --|> ModelScopeLayoutComponent +AntdXSuggestion --|> ModelScopeLayoutComponent +AntdXThink --|> ModelScopeLayoutComponent +AntdXThoughtChain --|> ModelScopeLayoutComponent +AntdXAttachments --|> ModelScopeDataLayoutComponent +AntdXSender --|> ModelScopeDataLayoutComponent +AntdXActions --|> ModelScopeLayoutComponent +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/bubble/**init**.py:13-135](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L13-L135) +- [backend/modelscope_studio/components/antdx/conversations/**init**.py:11-109](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L11-L109) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) +- [backend/modelscope_studio/components/antdx/attachments/**init**.py:22-227](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L22-L227) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-149](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L149) +- [backend/modelscope_studio/components/antdx/actions/**init**.py:15-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L112) +- [backend/modelscope_studio/components/antdx/file_card/**init**.py:11-112](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L11-L112) +- [backend/modelscope_studio/components/antdx/folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:6-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L6-L71) +- [backend/modelscope_studio/components/antdx/notification/**init**.py:10-97](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L10-L97) +- [backend/modelscope_studio/components/antdx/sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) + +## Detailed Component Analysis + +### Bubble + +- Import Path: `modelscope_studio.components.antdx.Bubble` +- Purpose: Message/text display, supports editing, typing animation, variants, shapes, etc. +- Key Parameters (selected): content, avatar, footer, header, loading, placement, editable, shape, typing, streaming, variant, footer_placement, loading_render, content_render, root_class_name, class_names, styles, additional_props, visibility and style attributes. +- Events: typing, typing_complete, edit_confirm, edit_cancel. +- Slots: avatar, editable.okText, editable.cancelText, content, footer, header, extra, loadingRender, contentRender. +- Lifecycle & API: skip*api=True, does not expose API; preprocess/postprocess/example*\* are empty implementations. + +Section Sources + +- [backend/modelscope_studio/components/antdx/bubble/**init**.py:13-135](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L13-L135) + +### Conversations + +- Import Path: `modelscope_studio.components.antdx.Conversations` +- Sub-components: Item +- Key Parameters: active_key, default_active_key, items, menu, groupable, shortcut_keys, creation, styles, class_names, root_class_name, additional_props. +- Events: active_change, menu_click, menu_deselect, menu_open_change, menu_select, groupable_expand, creation_click. +- Slots: menu.expandIcon, menu.overflowedIndicator, menu.trigger, groupable.label, items, creation.icon, creation.label. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/conversations/**init**.py:11-109](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L11-L109) + +### Prompts + +- Import Path: `modelscope_studio.components.antdx.Prompts` +- Sub-components: Item +- Key Parameters: items, prefix_cls, title, vertical, fade_in, fade_in_left, wrap, styles, class_names, root_class_name, additional_props. +- Events: item_click. +- Slots: title, items. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) + +### Attachments + +- Import Path: `modelscope_studio.components.antdx.Attachments` +- Data Model: ListFiles +- Key Parameters: image_props, accept, action, before_upload, custom_request, data, default_file_list, directory, disabled, items, get_drop_container, overflow, placeholder, headers, icon_render, is_image_url, item_render, list_type, max_count, method, multiple, form_name, open_file_dialog_on_click, preview_file, progress, show_upload_list, with_credentials, class_names, root_style, styles, root_class_name, visibility and polling attributes. +- Events: change, drop, download, preview, remove. +- Lifecycle & API: skip_api=False; preprocess converts payload to file path list; postprocess converts file path list to ListFiles; api_info returns ListFiles JSON Schema. +- Typical Usage: As an input component receiving file lists, as an output component returning file metadata. + +Section Sources + +- [backend/modelscope_studio/components/antdx/attachments/**init**.py:22-227](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L22-L227) + +### Sender + +- Import Path: `modelscope_studio.components.antdx.Sender` +- Sub-components: Header, Switch +- Key Parameters: value, allow_speech, class_names, components, default_value, disabled, auto_size, loading, suffix, footer, header, prefix, read_only, styles, submit_type, placeholder, slot_config, skill, root_class_name, additional_props. +- Events: change, submit, cancel, allow_speech_recording_change, key_down, key_press, focus, blur, paste, paste_file, skill_closable_close. +- Slots: suffix, header, prefix, footer, skill.title, skill.toolTip.title, skill.closable.closeIcon. +- Lifecycle & API: skip*api=False; preprocess/postprocess return string; api_info returns string type description; example*\* returns None. + +Section Sources + +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-149](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L149) + +### Actions + +- Import Path: `modelscope_studio.components.antdx.Actions` +- Sub-components: ActionItem, Item, Feedback, Copy, Audio +- Key Parameters: additional_props, items, variant, dropdown_props, fade_in, fade_in_left, class_names, styles. +- Events: click, dropdown_open_change, dropdown_menu_click, dropdown_menu_deselect, dropdown_menu_open_change, dropdown_menu_select. +- Slots: items, dropdownProps.dropdownRender, dropdownProps.popupRender, dropdownProps.menu.expandIcon, dropdownProps.menu.overflowedIndicator, dropdownProps.menu.items. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:15-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L112) + +### FileCard + +- Import Path: `modelscope_studio.components.antdx.FileCard` +- Sub-components: List +- Key Parameters: image_props, filename, byte, size, description, loading, type, src, mask, icon, video_props, audio_props, spin_props, class_names, styles, additional_props. +- Events: click. +- Slots: imageProps.placeholder, imageProps.preview.mask, imageProps.preview.closeIcon, imageProps.preview.toolbarRender, imageProps.preview.imageRender, description, icon, mask, spinProps.icon, spinProps.description, spinProps.indicator. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/file_card/**init**.py:11-112](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L11-L112) + +### Folder + +- Import Path: `modelscope_studio.components.antdx.Folder` +- Sub-components: TreeNode, DirectoryIcon +- Key Parameters: additional_props, tree_data, selectable, selected_file, default_selected_file, directory_tree_width, empty_render, preview_render, expanded_paths, default_expanded_paths, default_expand_all, directory_title, preview_title, directory_icons, class_names, styles, root_class_name. +- Events: file_click, folder_click, selected_file_change, expanded_paths_change, file_content_service_load_file_content. +- Slots: emptyRender, previewRender, directoryTitle, previewTitle, treeData, directoryIcons. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) + +### CodeHighlighter + +- Import Path: `modelscope_studio.components.antdx.CodeHighlighter` +- Key Parameters: value, lang, header, highlight_props, prism_light_mode, styles, class_names, additional_props, root_class_name. +- Slots: header. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:6-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L6-L71) + +### Notification + +- Import Path: `modelscope_studio.components.antdx.Notification` +- Key Parameters: title, duration, badge, body, data, dir, icon, lang, require_interaction, silent, tag, additional_props. +- Events: permission, click, close, error, show. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/notification/**init**.py:10-97](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L10-L97) + +### Sources + +- Import Path: `modelscope_studio.components.antdx.Sources` +- Sub-components: Item +- Key Parameters: title, items, expand_icon_position, default_expanded, expanded, inline, active_key, popover_overlay_width, styles, class_names, root_class_name, additional_props. +- Events: expand, click. +- Slots: items. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) + +### Suggestion + +- Import Path: `modelscope_studio.components.antdx.Suggestion` +- Sub-components: Item +- Key Parameters: additional_props, items, block, open, should_trigger, class_names, styles, root_class_name. +- Events: select, open_change. +- Slots: items, children. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) + +### Think + +- Import Path: `modelscope_studio.components.antdx.Think` +- Key Parameters: additional_props, icon, styles, class_names, loading, title, root_class_name, default_expanded, expanded, blink. +- Events: expand. +- Slots: loading, icon, title. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) + +### ThoughtChain + +- Import Path: `modelscope_studio.components.antdx.ThoughtChain` +- Sub-components: Item, ThoughtChainItem +- Key Parameters: expanded_keys, default_expanded_keys, items, line, prefix_cls, styles, class_names, root_class_name, additional_props. +- Events: expand. +- Slots: items. +- Lifecycle & API: skip_api=True. + +Section Sources + +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) + +## Dependency Analysis + +- Components uniformly inherit from `ModelScopeLayoutComponent` or `ModelScopeDataLayoutComponent`; the latter supports `preprocess/postprocess` and API specification export for data types. +- Most components are layout-type components with `skip_api=True` that do not expose an API; a few data-type components (Attachments, Sender) implement data serialization specifications. +- Components resolve frontend resource directories via `resolve_frontend_dir("xxx", type="antdx")`, ensuring one-to-one correspondence with frontend components. + +```mermaid +graph LR +A["AntdXBubble"] --> B["ModelScopeLayoutComponent"] +C["AntdXAttachments"] --> D["ModelScopeDataLayoutComponent"] +E["AntdXSender"] --> D +F["AntdXConversations"] --> B +G["AntdXPrompts"] --> B +H["AntdXActions"] --> B +I["AntdXFileCard"] --> B +J["AntdXFolder"] --> B +K["AntdXCodeHighlighter"] --> B +L["AntdXNotification"] --> B +M["AntdXSources"] --> B +N["AntdXSuggestion"] --> B +O["AntdXThink"] --> B +P["AntdXThoughtChain"] --> B +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/bubble/**init**.py:13-135](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L13-L135) +- [backend/modelscope_studio/components/antdx/attachments/**init**.py:22-227](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L22-L227) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-149](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L149) +- [backend/modelscope_studio/components/antdx/conversations/**init**.py:11-109](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L11-L109) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) +- [backend/modelscope_studio/components/antdx/actions/**init**.py:15-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L112) +- [backend/modelscope_studio/components/antdx/file_card/**init**.py:11-112](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L11-L112) +- [backend/modelscope_studio/components/antdx/folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:6-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L6-L71) +- [backend/modelscope_studio/components/antdx/notification/**init**.py:10-97](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L10-L97) +- [backend/modelscope_studio/components/antdx/sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) + +## Performance Considerations + +- Event Binding: Callbacks are bound via `EventListener` at construction time, avoiding performance overhead from duplicate bindings. +- Data Component Serialization: Attachments and Sender explicitly implement `preprocess/postprocess`, reducing unnecessary data conversion overhead. +- Frontend Resources: `resolve_frontend_dir` ensures only necessary resources are loaded, avoiding redundant bundling. +- Rendering Optimization: Layout-type components with `skip_api=True` reduce additional processing at the API layer. + +## Troubleshooting Guide + +- Events Not Triggering: Check that callbacks in the EVENTS list are correctly bound, and confirm that the frontend component has the corresponding events enabled. +- File Upload Issues: Verify the Attachments parameters such as action, headers, with_credentials, and max_count; ensure the server is accessible and the cache directory has proper permissions. +- Input Value Not Updating: The value and default_value of Sender must maintain consistent data types; pay attention to the timing of change/submit/cancel events. +- Style and Slots: If slot content is not displayed, check whether the SLOTS definition matches the slot names passed in. + +## Conclusion + +The Antdx component library provides a rich set of layout, input, and data components centered around AI/ML application scenarios. It meets typical requirements for conversational systems, file handling, and user input while ensuring good extensibility and consistency through unified event and slot mechanisms. In practice, it is recommended to prioritize data-type components (such as Attachments and Sender) for clearer API behavior and data flow, while using layout-type components to build friendly interactive interfaces. + +## Appendix + +### API Index (by Scenario) + +- General Components + - Bubble, Conversations, Prompts, Suggestions, Think, ThoughtChain, CodeHighlighter, Notification, Sources, FileCard, Folder, Actions +- Wake/Input Components + - Sender (with Header, Switch) +- Utility Components + - Attachments (file upload/download/preview/removal) +- Feedback Components + - Actions (action group and feedback) +- Expression Components + - CodeHighlighter (code highlighting) +- State & Process Components + - Think, ThoughtChain, Notification, Sources, Folder, FileCard + +### Standard Instantiation Examples (Path References) + +- Conversational System + - Use Bubble, Conversations, Prompts, Sender, and Actions together to build a conversational interface. + - Example path references: [Bubble constructor:56-116](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L56-L116), [Conversations constructor:49-91](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L49-L91), [Prompts constructor:28-71](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L28-L71), [Sender constructor:68-128](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L68-L128), [Actions constructor:58-94](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L58-L94) +- File Handling + - Use Attachments to receive file lists, combined with Sender's paste/paste_file events for drag-and-drop and clipboard upload. + - Example path references: [Attachments constructor:66-160](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L66-L160), [Sender events and parameters:21-59](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L21-L59) +- User Input + - Use Sender's submit/cancel events and value/default_value to control input state. + - Example path references: [Sender events and parameters:21-99](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L21-L99) + +### ML Integration Interfaces and Data Formats + +- Data-type Components (Attachments, Sender) + - preprocess: Converts payload to the internal representation expected by the component (e.g., file path list). + - postprocess: Converts internal value to the data structure for external output (e.g., ListFiles). + - api_info: Exports JSON Schema, specifying API input/output types. +- Layout-type Components (all other components) + - Typically skip_api=True, not exposing an API; state changes are driven by properties and events. + +### Lifecycle and Event Handling Mechanism + +- Event Binding: Callbacks are registered via `EventListener` in the constructor; the component internally binds to frontend events via `_internal.update`. +- Slots: Supported slot names are defined via SLOTS; the component internally parses and renders the corresponding content. +- Styles and Class Names: Uniform style injection is supported via styles, class_names, and root_class_name. diff --git a/.wiki/en/API Reference/Python API/Antdx Components API/Confirmation Components API.md b/.wiki/en/API Reference/Python API/Antdx Components API/Confirmation Components API.md new file mode 100644 index 00000000..bc2b26d8 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antdx Components API/Confirmation Components API.md @@ -0,0 +1,366 @@ +# Confirmation Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/thought_chain/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py) +- [backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py) +- [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py) +- [frontend/antdx/thought-chain/thought-chain.tsx](file://frontend/antdx/thought-chain/thought-chain.tsx) +- [frontend/antdx/thought-chain/item/thought-chain.item.tsx](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx) +- [frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [docs/components/antdx/thought_chain/demos/basic.py](file://docs/components/antdx/thought_chain/demos/basic.py) +- [docs/components/antdx/thought_chain/demos/item_status.py](file://docs/components/antdx/thought_chain/demos/item_status.py) +- [docs/components/antdx/thought_chain/demos/nested_use.py](file://docs/components/antdx/thought_chain/demos/nested_use.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for Antdx confirmation components (AntdX), focusing on the ThoughtChain component's thought chain management, decision process tracking, and state visualization capabilities. Key areas covered: + +- Hierarchical structure management and node state control for ThoughtChain and ThoughtChainItem +- Chain operation processing and node connection relationships +- Data structure definitions, state change listeners, and result output mechanisms +- Standard usage examples for scenarios such as AI decision process display, thought chain analysis, and action confirmation +- Component state management strategies, event propagation mechanisms, and performance monitoring configurations +- Integration approaches with chatbots (Chatbot) and reasoning process visualization + +## Project Structure + +The ThoughtChain-related implementation in Antdx consists of backend Python components and a frontend Svelte/React wrapper layer: + +- Backend Python Components: Wrap Gradio layout components, responsible for property forwarding and frontend resource location +- Frontend Wrapper Layer: Bridges Ant Design X's ThoughtChain and ThoughtChain.Item components to the Gradio ecosystem, supporting slot rendering and context injection + +```mermaid +graph TB +subgraph "Backend Python Components" +A["AntdXThoughtChain
__init__.py"] +B["AntdXThoughtChainItem
item/__init__.py"] +C["AntdXThoughtChainThoughtChainItem
thought_chain_item/__init__.py"] +end +subgraph "Frontend Wrapper Layer" +D["thought-chain/thought-chain.tsx"] +E["thought-chain/item/thought-chain.item.tsx"] +F["thought-chain-item/thought-chain.thought-chain-item.tsx"] +end +A --> D +B --> E +C --> F +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [backend/modelscope_studio/components/antdx/thought_chain/item/**init**.py:8-78](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L8-L78) +- [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L8-L81) +- [frontend/antdx/thought-chain/thought-chain.tsx:11-42](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L42) +- [frontend/antdx/thought-chain/item/thought-chain.item.tsx:9-32](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L9-L32) +- [frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx:7-13](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L13) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [frontend/antdx/thought-chain/thought-chain.tsx:11-42](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L42) + +## Core Components + +- AntdXThoughtChain: Thought chain container, supports expanded keys, line styles, prefix class names, and other properties; listens for "expand" events to implement expanded key change callbacks; supports the "items" slot +- AntdXThoughtChainItem: Top-level node, supports title, description, icon, status, variant, blink, and other properties; supports "description", "icon", "title" slots +- AntdXThoughtChainThoughtChainItem: Nested node, supports content, extra, footer, icon, title, status, collapsible, blink, and other properties; supports "content", "description", "footer", "icon", "title" slots + +All of the above components inherit from ModelScopeLayoutComponent, with general Gradio layout component features, and specify the frontend directory via `resolve_frontend_dir`. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [backend/modelscope_studio/components/antdx/thought_chain/item/**init**.py:8-78](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L8-L78) +- [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L8-L81) + +## Architecture Overview + +The diagram below shows the complete chain from Python calls to frontend rendering, as well as the role positions of slots and context: + +```mermaid +sequenceDiagram +participant Py as "Python Components
AntdXThoughtChain/AntdXThoughtChainItem" +participant Wrap as "Frontend Wrapper Layer
thought-chain.tsx / item/thought-chain.item.tsx" +participant ADX as "Ant Design X
@ant-design/x" +participant Slot as "Slot System
ReactSlot / renderItems" +Py->>Wrap : Pass properties and visibility +Wrap->>ADX : Render ThoughtChain/Item +Wrap->>Slot : Parse and render slot content +ADX-->>Wrap : Render result +Wrap-->>Py : Return value/placeholder render +``` + +**Diagram Sources** + +- [frontend/antdx/thought-chain/thought-chain.tsx:11-42](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L42) +- [frontend/antdx/thought-chain/item/thought-chain.item.tsx:9-32](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L9-L32) +- [frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx:7-13](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L13) + +## Detailed Component Analysis + +### AntdXThoughtChain (Thought Chain Container) + +- Role and Responsibility + - Container for displaying multiple thought chain nodes + - Supports expanded key control, default expanded keys, line styles, prefix class names, and other appearance and interaction parameters + - Events: expand (triggered when expanded keys change) + - Slots: items (for batch injecting nodes) +- Key Properties + - expanded_keys: Currently expanded node key list + - default_expanded_keys: Initial default expanded key list + - items: Node data array (optional) + - line: Line style (boolean or specific string) + - prefix_cls: Prefix class name + - styles/class_names/root_class_name: Style and class name extensions +- Processing Flow + - Frontend parses slot items via context or directly uses the passed items + - Uses renderItems to clone slot nodes into React structures + - Renders the @ant-design/x ThoughtChain component + +```mermaid +flowchart TD +Start(["Enter AntdXThoughtChain"]) --> CheckItems["Check if items are passed"] +CheckItems --> |Yes| UsePassed["Use passed items"] +CheckItems --> |No| ResolveSlot["Resolve slot items/default"] +ResolveSlot --> RenderItems["Call renderItems to clone nodes"] +UsePassed --> RenderItems +RenderItems --> RenderADX["Render @ant-design/x ThoughtChain"] +RenderADX --> End(["Complete"]) +``` + +**Diagram Sources** + +- [frontend/antdx/thought-chain/thought-chain.tsx:14-39](file://frontend/antdx/thought-chain/thought-chain.tsx#L14-L39) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [frontend/antdx/thought-chain/thought-chain.tsx:11-42](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L42) + +### AntdXThoughtChainItem (Top-level Node) + +- Role and Responsibility + - Represents a top-level node in the thought chain + - Supports title, description, icon, status, variant, blink, and other properties + - Supports "description", "icon", "title" slots for custom rendering +- Key Properties + - title/description/icon: Node title, description, icon + - status: Node status (pending/success/error/abort) + - variant: Node appearance variant (solid/outlined/text) + - blink: Whether to blink as a prompt + - prefix_cls/class_names/styles: Style and class name extensions +- Slots + - description/title/icon: Replace the content of the corresponding area + +```mermaid +classDiagram +class AntdXThoughtChainItem { ++title : str|None ++description : str|None ++icon : str|None ++status : enum ++variant : enum ++blink : bool|None ++prefix_cls : str|None ++class_names : dict|str|None ++styles : dict|str|None +} +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/item/**init**.py:18-58](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L18-L58) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/item/**init**.py:8-78](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L8-L78) +- [frontend/antdx/thought-chain/item/thought-chain.item.tsx:9-32](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L9-L32) + +### AntdXThoughtChainThoughtChainItem (Nested Node) + +- Role and Responsibility + - Represents a nested node used inside a ThoughtChain + - Supports content, extra, footer, icon, title, status, collapsible, blink, and other properties + - Supports "content", "description", "footer", "icon", "title" slots +- Key Properties + - key: Node unique identifier + - title/description/content/extra/footer/icon: Content for each area of the node + - status: Node status + - collapsible: Whether collapsible + - blink: Whether to blink as a prompt +- Slots + - content/description/footer/icon/title: Replace the content of the corresponding area + +```mermaid +classDiagram +class AntdXThoughtChainThoughtChainItem { ++key : str|None ++title : str|None ++description : str|None ++content : str|None ++extra : str|None ++footer : str|None ++icon : str|None ++status : enum ++collapsible : bool|None ++blink : bool|None +} +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/**init**.py:18-60](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L18-L60) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L8-L81) +- [frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx:7-13](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L13) + +### Data Structures and Node Connection Relationships + +- Node Data Structure + - items array: Each element corresponds to a ThoughtChainItem or ThoughtChainThoughtChainItem + - Fields include but are not limited to: title, description, content, icon, status, key, collapsible, etc. +- Connection Relationships + - AntdXThoughtChain acts as the root container; multiple ThoughtChainItems can be nested inside + - The content slot of each ThoughtChainItem can nest another ThoughtChain again, forming multi-level nesting +- State Changes and Listeners + - expand event: Triggered when expanded keys change; can be used for dynamically updating UI or logging + - status property: Used to intuitively reflect the execution status of nodes (success/failure/in-progress/abort) + +**Section Sources** + +- [frontend/antdx/thought-chain/thought-chain.tsx:14-39](file://frontend/antdx/thought-chain/thought-chain.tsx#L14-L39) +- [docs/components/antdx/thought_chain/demos/nested_use.py:10-64](file://docs/components/antdx/thought_chain/demos/nested_use.py#L10-L64) +- [docs/components/antdx/thought_chain/demos/item_status.py:9-33](file://docs/components/antdx/thought_chain/demos/item_status.py#L9-L33) + +### State Management Strategy and Event Propagation + +- State Management + - Drive UI state changes via the status property (e.g., color, icon, blink) + - Control node expansion/collapse via expanded_keys/default_expanded_keys +- Event Propagation + - The expand event is listened to at the container level; `bind_expand_event` can be set in the callback to enable event binding + - Event callbacks are typically used for linked updates to other components or logging +- Result Output Mechanism + - The component does not directly produce output values; external logic (e.g., button click) can be used to update the items or state of ThoughtChain via Gradio + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:20-25](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L20-L25) + +### Performance Monitoring Configuration + +- Recommended Practices + - For scenarios with large numbers of nodes, prefer passing data via the items parameter at once to reduce slot parsing overhead + - Use expanded_keys/default_expanded_keys wisely to avoid rendering too many nodes at once + - When frequent state updates are needed, batch update items to reduce multiple re-renders +- Monitoring Metrics + - Page rendering time, node count, expand/collapse frequency, state switch count + +[This section contains general recommendations and does not require specific file references] + +## Dependency Analysis + +- Component Export and Aggregation + - The antdx component module uniformly exports ThoughtChain and its sub-items for on-demand import in business code +- Frontend Dependencies + - @ant-design/x provides core rendering capabilities + - sveltify bridges Svelte components to React/Gradio + - renderItems is used for cloning and rendering slot nodes + +```mermaid +graph LR +Export["antdx/components.py Export"] --> A["AntdXThoughtChain"] +Export --> B["AntdXThoughtChainItem"] +Export --> C["AntdXThoughtChainThoughtChainItem"] +A --> D["thought-chain/thought-chain.tsx"] +B --> E["thought-chain/item/thought-chain.item.tsx"] +C --> F["thought-chain-item/thought-chain.thought-chain-item.tsx"] +D --> ADX["@ant-design/x"] +E --> ADX +F --> ADX +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/components.py:35-40](file://backend/modelscope_studio/components/antdx/components.py#L35-L40) +- [frontend/antdx/thought-chain/thought-chain.tsx:3-6](file://frontend/antdx/thought-chain/thought-chain.tsx#L3-L6) +- [frontend/antdx/thought-chain/item/thought-chain.item.tsx:4-7](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L4-L7) +- [frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx:3-5](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L3-L5) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/components.py:35-40](file://backend/modelscope_studio/components/antdx/components.py#L35-L40) + +## Performance Considerations + +- Rendering Optimization + - Use the items parameter rather than numerous slots to reduce frontend parsing costs + - For long lists, consider pagination or lazy loading +- State Updates + - Batch update items to avoid frequent incremental changes + - Use the expand event wisely to avoid excessive responses causing redraws +- Styles and Class Names + - Use styles/class_names/root_class_name to precisely control styles and avoid global pollution + +[This section contains general recommendations and does not require specific file references] + +## Troubleshooting Guide + +- Common Issues + - Slot not taking effect: Confirm the slot name is correct and matches the slots supported by the component + - State not updating: Check whether status is correctly set and ensure external logic has triggered a Gradio update + - Expanded keys not working: Confirm that the expand event is bound and expanded_keys/default_expanded_keys are set appropriately +- Troubleshooting Steps + - Validate component behavior using a minimal example + - Gradually add slots and state to narrow down the problem scope + - Check the browser console and network panel to confirm that frontend resources are loading normally + +**Section Sources** + +- [docs/components/antdx/thought_chain/demos/basic.py:31-74](file://docs/components/antdx/thought_chain/demos/basic.py#L31-L74) +- [docs/components/antdx/thought_chain/demos/item_status.py:9-33](file://docs/components/antdx/thought_chain/demos/item_status.py#L9-L33) + +## Conclusion + +Antdx's ThoughtChain component provides a reliable visualization foundation for AI decision process display, thought chain analysis, and action confirmation through a clear hierarchical structure and rich state control. Combined with the slot system and event mechanism, it can be flexibly extended and customized in complex scenarios. For large-scale data scenarios, it is recommended to use item parameter passing and batch update strategies for better performance. + +[This section contains summary content and does not require specific file references] + +## Appendix + +### Standard Usage Examples (Paths) + +- Basic Usage: Display multiple ThoughtChainItems with configured states and slots + - [docs/components/antdx/thought_chain/demos/basic.py:31-74](file://docs/components/antdx/thought_chain/demos/basic.py#L31-L74) +- State Toggle Demo: Drive node state changes via buttons + - [docs/components/antdx/thought_chain/demos/item_status.py:46-67](file://docs/components/antdx/thought_chain/demos/item_status.py#L46-L67) +- Nested Usage: Nest another ThoughtChain within node content + - [docs/components/antdx/thought_chain/demos/nested_use.py:19-64](file://docs/components/antdx/thought_chain/demos/nested_use.py#L19-L64) + +### Quick API Reference (Paths) + +- Container Component: AntdXThoughtChain + - [backend/modelscope_studio/components/antdx/thought_chain/**init**.py:30-68](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L30-L68) +- Top-level Node: AntdXThoughtChainItem + - [backend/modelscope_studio/components/antdx/thought_chain/item/**init**.py:18-60](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L18-L60) +- Nested Node: AntdXThoughtChainThoughtChainItem + - [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/**init**.py:18-63](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L18-L63) diff --git a/.wiki/en/API Reference/Python API/Antdx Components API/Expression Components API.md b/.wiki/en/API Reference/Python API/Antdx Components API/Expression Components API.md new file mode 100644 index 00000000..ead87d5c --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antdx Components API/Expression Components API.md @@ -0,0 +1,359 @@ +# Expression Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/antdx/attachments/__init__.py](file://backend/modelscope_studio/components/antdx/attachments/__init__.py) +- [backend/modelscope_studio/components/antdx/sender/__init__.py](file://backend/modelscope_studio/components/antdx/sender/__init__.py) +- [backend/modelscope_studio/components/antdx/sender/header/__init__.py](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py) +- [backend/modelscope_studio/components/antdx/sender/switch/__init__.py](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py) +- [backend/modelscope_studio/components/antdx/suggestion/__init__.py](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py) +- [backend/modelscope_studio/components/antdx/suggestion/item/__init__.py](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document is the Python API reference for Antdx expression components, focusing on the following capabilities: + +- File attachment handling: Upload, drag-and-drop, download, preview, removal, type restrictions, and list display strategies +- Input and send control: Text input box management, submit types (Enter/Shift+Enter), paste and keyboard events, voice input toggle +- Multimodal input support: Extended header area, switch, and skill panel via Sender sub-components +- Quick commands: Suggestion component and its items' triggering, selection, and panel state management +- Chatbot integration: Data flow and interaction protocol based on Gradio data classes and event callbacks + +## Project Structure + +Antdx components reside in the backend Python package, exported through a unified entry point, and mapped to Svelte implementations in the frontend via corresponding directory mappings. The expression component-related modules are organized as follows: + +- Top-level exports: `antdx/__init__.py` and `antdx/components.py` provide aggregated component exports +- Attachments: `antdx/attachments` +- Sender: `antdx/sender` (with header, switch sub-components) +- Suggestion: `antdx/suggestion` (with item sub-component) + +```mermaid +graph TB +subgraph "Python Backend" +A["antdx/__init__.py"] +B["antdx/components.py"] +C["attachments/__init__.py"] +D["sender/__init__.py"] +E["sender/header/__init__.py"] +F["sender/switch/__init__.py"] +G["suggestion/__init__.py"] +H["suggestion/item/__init__.py"] +end +A --> C +A --> D +A --> E +A --> F +A --> G +A --> H +B --> C +B --> D +B --> E +B --> F +B --> G +B --> H +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +Section Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Core Components + +- AntdXAttachments: File attachment upload and management, supports drag-and-drop, preview, download, removal, type filtering, list styles, placeholders, etc. +- AntdXSender: Input and send control, supports auto height, read-only, loading state, placeholder, submit type, voice input, file paste, keyboard events, etc. +- AntdXSenderHeader: Sender header area, supports expand/collapse, title, closable, etc. +- AntdXSenderSwitch: Built-in switch for Sender, supports checked/unchecked labels and icons +- AntdXSuggestion: Quick command suggestion panel, supports items list, open state, select event +- AntdXSuggestionItem: Suggestion item, supports label, icon, extra content, and other slots + +Section Sources + +- [backend/modelscope_studio/components/antdx/attachments/**init**.py:22-227](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L22-L227) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-149](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L149) +- [backend/modelscope_studio/components/antdx/sender/header/**init**.py:8-74](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py#L8-L74) +- [backend/modelscope_studio/components/antdx/sender/switch/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py#L8-L81) +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/suggestion/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py#L8-L68) + +## Architecture Overview + +The frontend-backend interaction of expression components follows the Gradio data class and event model: + +- Backend components define data models (e.g., ListFiles) and event listeners +- Frontend maps to the corresponding Svelte components based on FRONTEND_DIR +- Data format conversion between Python and frontend is done via preprocess/postprocess +- Event callbacks are bound to frontend events via `_internal.update` + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Frontend Component (Svelte)" +participant PY as "Backend Component (Python)" +participant GR as "Gradio Data Class" +U->>FE : Trigger event (input/paste/drag-and-drop/click) +FE->>PY : Event callback binding (_internal.update) +PY->>GR : preprocess(payload) convert to internal value +GR-->>PY : Return processed value +PY-->>FE : postprocess(value) return frontend display value +FE-->>U : Update UI (list/preview/state) +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/attachments/**init**.py:168-207](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L168-L207) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:134-142](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L134-L142) + +## Component Details + +### Attachments Component (AntdXAttachments) + +- Key Features + - Supports file upload, drag-and-drop upload, batch selection, maximum count limit + - Supports file type filtering (accept), HTTP request parameters (headers, data, method) + - Supports custom upload requests (custom_request), pre-upload hooks (before_upload) + - List styles and overflow strategies (list_type, overflow), shows upload list by default + - Placeholder and image preview enhancements (placeholder, imageProps.\*) + - Events: change, drop, download, preview, remove + - Slots: showUploadList._, iconRender, itemRender, placeholder._, imageProps.\*, etc. +- Data Flow + - preprocess: Converts the ListFiles passed from the frontend to a local path string list + - postprocess: Downloads local paths/URLs to the cache and packages them as ListFiles to return to the frontend +- File Handling Strategy + - Remote URLs: Downloaded to cache directory + - Local paths: Used directly + - Preview: Uses Gradio FileData metadata (orig_name, size) + +```mermaid +flowchart TD +Start(["Enter preprocess"]) --> CheckNull{"Is payload empty?"} +CheckNull --> |Yes| ReturnNone["Return None"] +CheckNull --> |No| Loop["Iterate each FileData"] +Loop --> Process["_process_single_file
Generate temp filename"] +Process --> Append["Collect string paths"] +Append --> DonePre["Return string list"] +subgraph "postprocess" +PStart["Receive string list"] --> PNull{"Is empty?"} +PNull --> |Yes| PEmpty["Return empty list"] +PNull --> |No| PLoop["Iterate paths"] +PLoop --> PType{"Is URL?"} +PType --> |Yes| PDownload["Download to cache"] +PType --> |No| PUse["Use directly"] +PDownload --> PBuild["Build FileData(orig_name,size)"] +PUse --> PBuild +PBuild --> PEnd["Return ListFiles"] +end +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/attachments/**init**.py:162-207](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L162-L207) + +Section Sources + +- [backend/modelscope_studio/components/antdx/attachments/**init**.py:22-227](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L22-L227) + +### Sender Component (AntdXSender) + +- Key Features + - Input box management: auto_size, placeholder, disabled, read_only, loading + - Submit control: submit_type (enter or shiftEnter) + - Events: change, submit, cancel, allow_speech_recording_change, key_down/key_press, focus/blur, paste/paste_file, skill_closable_close + - Slots: suffix, header, prefix, footer, skill.\*, etc. + - Sub-components: Header, Switch (for extending the header area and switch) +- Data Flow + - preprocess/postprocess: Pass through string values +- Multimodal Input Support + - allow_speech: Enable voice input (boolean or dict) + - paste_file: File paste event + - skill.\*: Skill panel title, tooltip, and closable icon + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Sender Frontend" +participant PY as "AntdXSender" +U->>FE : Input/keypress/paste/click send +FE->>PY : Event callback (e.g. change/submit/paste_file) +PY-->>FE : Control submit behavior based on submit_type +FE-->>U : Update state (loading/disabled) +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/sender/**init**.py:21-59](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L21-L59) + +Section Sources + +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-149](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L149) + +### Sender Header (AntdXSenderHeader) + +- Key Features + - Expand/collapse: open, closable + - Title: title + - Slots: title +- Usage + - Used as a Sender sub-component for holding the header title and close button + +Section Sources + +- [backend/modelscope_studio/components/antdx/sender/header/**init**.py:8-74](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py#L8-L74) + +### Sender Switch (AntdXSenderSwitch) + +- Key Features + - Value: value (bool) + - Labels and Icons: checked_children, un_checked_children, icon + - States: disabled, loading + - Slots: checkedChildren, unCheckedChildren, icon +- Usage + - Used as a Sender sub-component for toggling certain send behaviors or modes + +Section Sources + +- [backend/modelscope_studio/components/antdx/sender/switch/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py#L8-L81) + +### Suggestion Component (AntdXSuggestion) and Item (AntdXSuggestionItem) + +- Suggestion Panel + - items: Suggestion item list (string or dict) + - Open state: open, block, should_trigger + - Events: select, open_change + - Slots: items, children +- Suggestion Item + - label, icon, extra, key + - Slots: label, icon, extra + +```mermaid +classDiagram +class AntdXSuggestion { ++items ++open ++block ++should_trigger ++EVENTS ++SLOTS +} +class AntdXSuggestionItem { ++value ++label ++icon ++extra ++key ++EVENTS ++SLOTS +} +AntdXSuggestion --> AntdXSuggestionItem : "contains multiple items" +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/suggestion/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py#L8-L68) + +Section Sources + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/suggestion/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py#L8-L68) + +## Dependency Analysis + +- Component Aggregation + - `antdx/__init__.py` and `antdx/components.py` uniformly export all sub-components for on-demand import by upper-level applications +- Component Cohesion + - Each component independently defines EVENTS, SLOTS, FRONTEND_DIR with clear responsibilities +- Event Coupling + - Frontend events are mapped to backend callbacks via EventListener and `_internal.update` +- Data Class Dependencies + - The Attachments component uses Gradio ListFiles and FileData to ensure cross-platform data consistency + +```mermaid +graph LR +A["antdx/__init__.py"] --> C["attachments/__init__.py"] +A --> D["sender/__init__.py"] +D --> E["sender/header/__init__.py"] +D --> F["sender/switch/__init__.py"] +A --> G["suggestion/__init__.py"] +G --> H["suggestion/item/__init__.py"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +Section Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Performance Considerations + +- File Handling + - Remote URL downloads should be combined with cache directories and async strategies to avoid blocking the main thread + - Large file uploads should use chunked or server-side direct upload strategies +- Event Callbacks + - Avoid heavy computations in callbacks for high-frequency events (e.g., change, key_down) +- UI Rendering + - Enable virtualization (if applicable) during list rendering to reduce DOM nodes + - Image preview and thumbnail generation should be done in background threads whenever possible + +## Troubleshooting Guide + +- Attachments Cannot Upload/Preview + - Check that accept and headers/data/method configurations are correct + - Confirm that custom_request and before_upload callbacks do not throw errors +- Remote Files Cannot Download + - Check URL accessibility and with_credentials settings + - Check cache directory permissions and disk space +- Sender Events Not Working + - Confirm that submit_type and keyboard event bindings match + - Check whether disabled/read_only/loading states are preventing interaction +- Suggestion Panel Not Showing + - Check whether items is empty or the should_trigger condition is met + - Confirm that open/open_change events are correctly bound + +## Conclusion + +Antdx expression components provide complete file attachment, input sending, and quick command capabilities through a clear event and slot system. Relying on Gradio data classes and the event model, flexible data conversion and interaction control can be performed on the Python side while maintaining a consistent frontend UI experience. + +## Appendix: Usage Examples and Best Practices + +- File Upload and Preview + - Use AntdXAttachments' accept to restrict types; set headers and data for authentication and additional parameter passing + - Control list styles and visibility via list_type and show_upload_list + - Enhance image preview experience with preview_file and imageProps.\* +- Input and Send Control + - Use submit_type to precisely control submit timing (enter/shiftEnter) + - Extend the header area and toggle via Sender.Header and Sender.Switch + - Handle file paste scenarios via paste/paste_file events +- Quick Commands + - Control the suggestion panel using AntdXSuggestion's items and open + - Enrich command display with AntdXSuggestionItem's label/icon/extra +- Integration with Chatbot + - Use Sender's value as the message body, and the attachment list as multimodal input + - Assemble the message body via event callbacks on the backend and call the bot API + - Use preprocess/postprocess for message and file serialization/deserialization diff --git a/.wiki/en/API Reference/Python API/Antdx Components API/Feedback Components API.md b/.wiki/en/API Reference/Python API/Antdx Components API/Feedback Components API.md new file mode 100644 index 00000000..f6018c66 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antdx Components API/Feedback Components API.md @@ -0,0 +1,446 @@ +# Feedback Components API + + +**Files Referenced in This Document** +- [actions/__init__.py](file://backend/modelscope_studio/components/antdx/actions/__init__.py) +- [action_item/__init__.py](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py) +- [item/__init__.py](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py) +- [copy/__init__.py](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py) +- [audio/__init__.py](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py) +- [feedback/__init__.py](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py) +- [notification/__init__.py](file://backend/modelscope_studio/components/antdx/notification/__init__.py) +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document is the Python API reference for Antdx feedback components, covering: the Actions component for action list management, action item configuration, and user interaction; ActionsItem for defining action items; ActionItem for specific action implementations; the Copy component for copy functionality; the Audio component for audio processing; the Feedback component for user feedback collection; and the Notification component for notification management, message push, and user feedback responses. The document also provides event handling strategies, state synchronization mechanisms, and user experience optimization configurations, along with reference solutions for chatbot integration and real-time user behavior feedback. + +## Project Structure + +Antdx feedback-related components reside in the backend Python package, organized by functional modules. Frontend resources are provided by Svelte components in the frontend directory. The Python layer exposes a unified interface to the application layer through Gradio component encapsulation and event binding. + +```mermaid +graph TB +subgraph "Antdx Components (Python)" +A["actions/__init__.py
AntdXActions"] +B["actions/action_item/__init__.py
AntdXActionsActionItem"] +C["actions/item/__init__.py
AntdXActionsItem"] +D["actions/copy/__init__.py
AntdXActionsCopy"] +E["actions/audio/__init__.py
AntdXActionsAudio"] +F["actions/feedback/__init__.py
AntdXActionsFeedback"] +G["notification/__init__.py
AntdXNotification"] +end +subgraph "Export Entry" +H["components.py
Unified Export"] +end +A --> B +A --> C +A --> D +A --> E +A --> F +H --> A +H --> G +``` + +**Diagram Sources** + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [actions/**init**.py:15-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L112) +- [action_item/**init**.py:10-80](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L10-L80) +- [item/**init**.py:10-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L10-L77) +- [copy/**init**.py:10-72](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L10-L72) +- [audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) +- [feedback/**init**.py:10-74](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L10-L74) +- [notification/**init**.py:10-97](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L10-L97) + +**Section Sources** + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Core Components + +- AntdXActions: Action set container, supports event binding and slot extension, used to hold multiple action items and submenus. +- AntdXActionsActionItem: Custom action item, supports label, icon, danger style, trigger method, and sub-items. +- AntdXActionsItem: Standard action item, supports states (loading/running/error/default), icon switching, and style customization. +- AntdXActionsCopy: Copy action, bound to click event, supports custom icon and text. +- AntdXActionsAudio: Audio status indicator, supports state enumeration and style customization. +- AntdXActionsFeedback: Feedback component for like/dislike/default states, supports click and state change events. +- AntdXNotification: Notification component, supports permission, click, close, error, show events, and multilingual/direction attributes. + +All of the above components inherit from a unified layout component base class, with Gradio-compatible event binding and rendering control capabilities. + +**Section Sources** + +- [actions/**init**.py:15-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L112) +- [action_item/**init**.py:10-80](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L10-L80) +- [item/**init**.py:10-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L10-L77) +- [copy/**init**.py:10-72](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L10-L72) +- [audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) +- [feedback/**init**.py:10-74](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L10-L74) +- [notification/**init**.py:10-97](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L10-L97) + +## Architecture Overview + +Antdx feedback components are exposed at the Python layer as Gradio components; the frontend implements UI behavior and interaction through corresponding Svelte components. Components bind callbacks via event listeners to relay user operations to the backend for event delivery and state updates. + +```mermaid +sequenceDiagram +participant U as "User" +participant A as "AntdXActions" +participant AI as "AntdXActionsActionItem" +participant AF as "AntdXActionsFeedback" +participant AN as "AntdXNotification" +U->>A : Trigger click/dropdown event +A-->>U : Trigger bound event callback +U->>AI : Click custom action item +AI-->>U : Trigger item_click callback +U->>AF : Click feedback button +AF-->>U : Trigger click/change callback +U->>AN : Trigger notification show/click/close +AN-->>U : Trigger permission/click/close/error/show callback +``` + +**Diagram Sources** + +- [actions/**init**.py:26-46](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L26-L46) +- [action_item/**init**.py:15-21](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L15-L21) +- [feedback/**init**.py:15-23](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L15-L23) +- [notification/**init**.py:14-30](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L14-L30) + +## Detailed Component Analysis + +### Actions Component (AntdXActions) + +- Responsibility: Serves as the action set container, managing action item lists, dropdown menu properties, and animation effects; supports event binding and slot extension. +- Key Properties + - items: Action item array for initializing the action list. + - variant: Appearance variant (e.g., borderless/outlined/filled). + - dropdown_props: Dropdown menu related property object. + - fade_in/fade_in_left: Entry animation toggles. + - class_names/styles: Style class names and inline style mappings. + - Slots: items, dropdownRender, popupRender, menu.expandIcon, overflowedIndicator, menu.items. +- Events + - click: Triggered when any action item is clicked. + - dropdown_open_change/dropdown_menu_open_change: Dropdown open/menu open state changes. + - dropdown_menu_click/dropdown_menu_deselect/dropdown_menu_select: Menu item click/deselect/select events. +- Processing Flow + - Internal binding flags are set at initialization so frontend events can be sent back to the backend. + - During rendering, action items and menu structures are dynamically generated based on items and dropdown_props. + - Custom rendering logic is extended through slots. + +```mermaid +classDiagram +class AntdXActions { ++Properties : items, variant, dropdown_props, fade_in, fade_in_left ++Methods : preprocess(), postprocess() ++Events : click, dropdown_open_change, dropdown_menu_*... ++Slots : items, dropdownRender, popupRender, menu.expandIcon, overflowedIndicator, menu.items +} +``` + +**Diagram Sources** + +- [actions/**init**.py:58-94](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L58-L94) + +**Section Sources** + +- [actions/**init**.py:15-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L112) + +### ActionsItem (AntdXActionsItem) + +- Responsibility: Standard action item, supports state switching and icon replacement. +- Key Properties + - status: State enumeration (loading/error/running/default). + - label: Display label. + - default_icon/running_icon: Default icon and running icon. + - class_names/styles: Style class names and inline style mappings. + - Slots: defaultIcon, runningIcon. +- Events + - click: Triggered when the item is clicked. +- Usage Recommendations + - Use with the items field of the Actions component for batch configuration. + - Customize icons and labels in different states through slots. + +```mermaid +classDiagram +class AntdXActionsItem { ++Properties : status, label, default_icon, running_icon ++Methods : preprocess(), postprocess() ++Events : click ++Slots : defaultIcon, runningIcon +} +``` + +**Diagram Sources** + +- [item/**init**.py:24-59](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L24-L59) + +**Section Sources** + +- [item/**init**.py:10-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L10-L77) + +### ActionItem (AntdXActionsActionItem) + +- Responsibility: Custom action item, supports label, icon, danger style, sub-items, and trigger method. +- Key Properties + - label/icon: Label and icon. + - danger: Whether to use danger style. + - trigger_sub_menu_action: Sub-menu trigger method (hover/click). + - sub_items: Sub-item array. + - action_render: Custom rendering function identifier. + - Slots: label, icon, actionRender, subItems. +- Events + - item_click: Triggered when the custom action button is clicked. +- Usage Recommendations + - Suitable for complex menus or scenarios requiring custom rendering. + - Sub-items are injected via the subItems slot, forming a nested menu tree. + +```mermaid +classDiagram +class AntdXActionsActionItem { ++Properties : label, icon, danger, trigger_sub_menu_action, sub_items, action_render ++Methods : preprocess(), postprocess() ++Events : item_click ++Slots : label, icon, actionRender, subItems +} +``` + +**Diagram Sources** + +- [action_item/**init**.py:26-62](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L26-L62) + +**Section Sources** + +- [action_item/**init**.py:10-80](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L10-L80) + +### Copy Component (AntdXActionsCopy) + +- Responsibility: Provides one-click copy functionality, commonly used for copying code blocks, links, and other text. +- Key Properties + - text: Text to be copied. + - icon: Custom icon. + - class_names/styles: Style class names and inline style mappings. + - Slots: icon. +- Events + - click: Triggered when the copy button is clicked. +- Usage Recommendations + - Use in combination with ActionItem or ActionsItem to improve user operation efficiency. + - Be mindful of browser permission and Clipboard API compatibility. + +```mermaid +classDiagram +class AntdXActionsCopy { ++Properties : text, icon ++Methods : preprocess(), postprocess() ++Events : click ++Slots : icon +} +``` + +**Diagram Sources** + +- [copy/**init**.py:24-54](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L24-L54) + +**Section Sources** + +- [copy/**init**.py:10-72](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L10-L72) + +### Audio Component (AntdXActionsAudio) + +- Responsibility: Audio status indicator for displaying recording/playback/loading/error states. +- Key Properties + - status: State enumeration (loading/error/running/default). + - class_names/styles: Style class names and inline style mappings. + - Slots: None. +- Events + - click: Triggered when the audio control is clicked. +- Usage Recommendations + - Pair with recording/playback functionality to provide immediate status feedback. + - Customize through styles to match the theme palette. + +```mermaid +classDiagram +class AntdXActionsAudio { ++Properties : status ++Methods : preprocess(), postprocess() ++Events : click +} +``` + +**Diagram Sources** + +- [audio/**init**.py:24-53](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L24-L53) + +**Section Sources** + +- [audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) + +### Feedback Component (AntdXActionsFeedback) + +- Responsibility: Collects user feedback on content/conversations, supports like/dislike/default states. +- Key Properties + - value: Current feedback value (like/dislike/default). + - class_names/styles: Style class names and inline style mappings. + - Slots: None. +- Events + - click: Triggered when the feedback button is clicked. + - change: Triggered when the feedback state changes. +- Usage Recommendations + - Pair with chatbot outputs or content cards to form a complete feedback loop. + - Report data via the change event, combined with backend storage and statistics. + +```mermaid +classDiagram +class AntdXActionsFeedback { ++Properties : value ++Methods : preprocess(), postprocess() ++Events : click, change +} +``` + +**Diagram Sources** + +- [feedback/**init**.py:28-56](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L28-L56) + +**Section Sources** + +- [feedback/**init**.py:10-74](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L10-L74) + +### Notification Component (AntdXNotification) + +- Responsibility: System notification management, supports permission, click, close, error, show events, and internationalization/direction attributes. +- Key Properties + - title/body: Title and body text. + - duration: Display duration. + - badge/lang/dir/icon/tag/data/silent/require_interaction: Badge, language, direction, icon, tag, data, silent mode, require interaction. + - Slots: None. +- Events + - permission/click/close/error/show: Permission request, click, close, error, show. +- Usage Recommendations + - Used for system notifications, permission prompts, error alerts, and user feedback responses. + - Combine with the Feedback component to form a "notification-feedback" closed loop. + +```mermaid +classDiagram +class AntdXNotification { ++Properties : title, body, duration, badge, lang, dir, icon, tag, data, silent, require_interaction ++Methods : preprocess(), postprocess() ++Events : permission, click, close, error, show +} +``` + +**Diagram Sources** + +- [notification/**init**.py:35-79](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L35-L79) + +**Section Sources** + +- [notification/**init**.py:10-97](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L10-L97) + +## Dependency Analysis + +- Unified Export: `components.py` centralizes all Antdx component exports for on-demand import by upper-level applications. +- Component Relationships: The Actions container combines ActionItem, Item, Copy, Audio, Feedback, and other sub-components; Notification exists independently and can work in conjunction with Feedback. + +```mermaid +graph LR +subgraph "Export Layer" +C["components.py"] +end +subgraph "Actions Family" +A1["AntdXActions"] +A2["AntdXActionsActionItem"] +A3["AntdXActionsItem"] +A4["AntdXActionsCopy"] +A5["AntdXActionsAudio"] +A6["AntdXActionsFeedback"] +end +subgraph "Notification" +N1["AntdXNotification"] +end +C --> A1 +C --> N1 +A1 --> A2 +A1 --> A3 +A1 --> A4 +A1 --> A5 +A1 --> A6 +``` + +**Diagram Sources** + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [actions/**init**.py:15-25](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L25) +- [notification/**init**.py:10-13](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L10-L13) + +**Section Sources** + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Performance Considerations + +- Minimize Event Binding: Only enable event binding when needed to avoid unnecessary callback overhead. +- Slot Rendering: Use slots wisely to reduce repeated rendering and keep the DOM structure concise. +- State Synchronization: Use component state and event linkage to avoid frequent full refreshes. +- Styles and Animation: Use entry animations and complex styles cautiously to ensure smooth performance on low-end devices. + +## Troubleshooting Guide + +- Events Not Triggering + - Check that event bindings are correctly enabled (e.g., click, dropdown\_\*, item_click, change). + - Confirm that frontend slot and property configurations match. +- State Inconsistency + - Verify the value range and default value of value/status. + - Check the state change logic in the change event. +- Style Issues + - Check whether class_names/styles has overridden the default styles. + - Confirm theme and global style conflicts. +- Notification Not Working + - Check the handling flow for the permission event. + - Confirm display duration and interaction requirement configurations. + +**Section Sources** + +- [actions/**init**.py:26-46](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L26-L46) +- [action_item/**init**.py:15-21](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L15-L21) +- [feedback/**init**.py:15-23](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L15-L23) +- [notification/**init**.py:14-30](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L14-L30) + +## Conclusion + +Antdx feedback components provide complete capabilities from action item management, copy and audio status indication to user feedback and notification management through a clear component layering and event binding mechanism. Combined with unified exports and slot extensions, developers can quickly build high-quality user feedback and interaction experiences across various scenarios. + +## Appendix: Usage Examples and Best Practices + +- User Operation Feedback + - Add the Feedback component after content cards or conversation outputs, bind click and change events to report user preferences. + - Example path: [feedback/**init**.py:15-23](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L15-L23) +- Quick Actions + - Use Actions to combine ActionItem and Item, configure subItems to form secondary menus; customize icons and labels through slots. + - Example paths: [actions/**init**.py:48-56](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L48-L56), [action_item/**init**.py:23-24](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L23-L24) +- Audio Interaction + - Use the Audio component to display recording/playback states, combined with the click event to control play/pause. + - Example path: [audio/**init**.py:15-19](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L15-L19) +- Copy Functionality + - Place the Copy component next to code blocks or links, bind the click event to improve copy efficiency. + - Example path: [copy/**init**.py:15-19](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L15-L19) +- Notification Management + - Use the Notification component for system prompts and permission alerts, bind permission/click/close/error/show events. + - Example path: [notification/**init**.py:14-30](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L14-L30) +- Integration with Chatbot + - Insert the Feedback component after chat outputs, report user feedback through the change event; use Notification when needed for confirmation or error alerts. + - Example paths: [feedback/**init**.py:15-23](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L15-L23), [notification/**init**.py:14-30](file://backend/modelscope_studio/components/antdx/notification/__init__.py#L14-L30) diff --git a/.wiki/en/API Reference/Python API/Antdx Components API/General Components API.md b/.wiki/en/API Reference/Python API/Antdx Components API/General Components API.md new file mode 100644 index 00000000..ecfb2e3d --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antdx Components API/General Components API.md @@ -0,0 +1,390 @@ +# General Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/antdx/bubble/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/__init__.py) +- [backend/modelscope_studio/components/antdx/bubble/list/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/list/__init__.py) +- [backend/modelscope_studio/components/antdx/bubble/list/item/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/list/item/__init__.py) +- [backend/modelscope_studio/components/antdx/bubble/list/role/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/list/role/__init__.py) +- [backend/modelscope_studio/components/antdx/conversations/__init__.py](file://backend/modelscope_studio/components/antdx/conversations/__init__.py) +- [backend/modelscope_studio/components/antdx/conversations/item/__init__.py](file://backend/modelscope_studio/components/antdx/conversations/item/__init__.py) +- [backend/modelscope_studio/components/antdx/prompts/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/__init__.py) +- [backend/modelscope_studio/components/antdx/prompts/item/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py) +- [docs/components/antdx/bubble/README-zh_CN.md](file://docs/components/antdx/bubble/README-zh_CN.md) +- [docs/components/antdx/conversations/README-zh_CN.md](file://docs/components/antdx/conversations/README-zh_CN.md) +- [docs/components/antdx/prompts/README-zh_CN.md](file://docs/components/antdx/prompts/README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for Antdx general components, focusing on the following core components: + +- Bubble: Conversation bubble rendering and interaction +- BubbleList: Message list management +- BubbleListItem: Message item processing +- BubbleListRole: Role identification +- Conversations: Conversation management, message storage, and state synchronization +- Prompts: Prompt template management, dynamic content rendering, and user interaction + +The documentation provides constructor parameters, property definitions, event and slot (slots) specifications for each component, and gives standard component instantiation and composition patterns for typical AI scenarios, helping developers quickly build conversational systems, message display, and prompt management features. + +## Project Structure + +Antdx components reside in the backend Python package, wrapped through a unified layout component base class, and mapped to the corresponding frontend component directories. Component export entry points are centralized in `antdx/components.py` for on-demand import. + +```mermaid +graph TB +subgraph "Python Backend" +A["components.py
Export Entry"] +B["bubble/*
Conversation Bubble Component Family"] +C["conversations/*
Conversation List Component Family"] +D["prompts/*
Prompts Component Family"] +end +A --> B +A --> C +A --> D +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +Section Sources + +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Core Components + +This section provides an overview of the three core component families and their responsibility boundaries: + +- Bubble Family: Responsible for rendering and interaction of individual messages or role-level bubbles, supporting typing animation, editability, variants, shapes, etc. +- BubbleList Family: Responsible for scrolling, role grouping, and item rendering in message lists, supporting auto-scroll and role configuration. +- Conversations Family: Responsible for conversation list management, selection state toggling, menu operations, and creation buttons. +- Prompts Family: Responsible for displaying preset prompts and click interactions, supporting vertical arrangement, fade-in effects, line wrapping, etc. + +Section Sources + +- [backend/modelscope_studio/components/antdx/bubble/**init**.py:13-135](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L13-L135) +- [backend/modelscope_studio/components/antdx/bubble/list/**init**.py:12-84](file://backend/modelscope_studio/components/antdx/bubble/list/__init__.py#L12-L84) +- [backend/modelscope_studio/components/antdx/conversations/**init**.py:11-109](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L11-L109) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) + +## Architecture Overview + +The diagram below shows the organization and dependency relationships of Antdx components at the Python layer: + +```mermaid +graph TB +subgraph "Antdx Components" +B1["AntdXBubble"] +B2["AntdXBubbleList"] +B3["AntdXBubbleListItem"] +B4["AntdXBubbleListRole"] +C1["AntdXConversations"] +C2["AntdXConversationsItem"] +P1["AntdXPrompts"] +P2["AntdXPromptsItem"] +end +E1["Event Binding
EventListener"] +S1["Slot Definition
SLOTS"] +B1 --> B2 +B2 --> B3 +B2 --> B4 +C1 --> C2 +P1 --> P2 +B1 --- E1 +B2 --- E1 +B3 --- E1 +B4 --- E1 +C1 --- E1 +P1 --- E1 +B1 --- S1 +B2 --- S1 +B3 --- S1 +B4 --- S1 +C1 --- S1 +P1 --- S1 +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/bubble/**init**.py:21-54](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L21-L54) +- [backend/modelscope_studio/components/antdx/bubble/list/**init**.py:19-30](file://backend/modelscope_studio/components/antdx/bubble/list/__init__.py#L19-L30) +- [backend/modelscope_studio/components/antdx/bubble/list/item/**init**.py:14-47](file://backend/modelscope_studio/components/antdx/bubble/list/item/__init__.py#L14-L47) +- [backend/modelscope_studio/components/antdx/bubble/list/role/**init**.py:14-46](file://backend/modelscope_studio/components/antdx/bubble/list/role/__init__.py#L14-L46) +- [backend/modelscope_studio/components/antdx/conversations/**init**.py:18-47](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L18-L47) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-26](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L26) + +## Detailed Component Analysis + +### Bubble Component + +- Component Purpose: Used to render a single conversation bubble, supports multiple appearance variants, shapes, typing animation, editability, avatar, header/footer, extra area, loading, and custom content rendering. +- Key Properties (constructor parameters) + - content: Bubble content text + - avatar: Avatar URL or placeholder + - extra: Additional elements + - footer/header: Footer/header content + - loading: Whether to show loading state + - placement: Alignment position (start/end) + - editable: Whether editable (boolean or dict) + - shape: Bubble shape (round/corner/default) + - typing: Typing animation (bool/dict/string) + - streaming: Streaming render toggle + - variant: Appearance variant (filled/borderless/outlined/shadow) + - footer_placement: Footer position (outside/inside-start/end) + - loading_render/content_render: Custom loading and content rendering + - class_names/styles/root_class_name: Style and class name control + - Other general properties: visible, elem_id, elem_classes, elem_style, render, etc. +- Events + - typing: Typing animation callback + - typing_complete: Typing complete callback; triggers immediately on render if typing is not set + - edit_confirm: Edit confirmation callback + - edit_cancel: Edit cancellation callback +- Slots + - avatar, editable.okText, editable.cancelText, content, footer, header, extra, loadingRender, contentRender +- Nested Sub-components + - List: Message list container + - System: System message bubble + - Divider: Divider line + +Section Sources + +- [backend/modelscope_studio/components/antdx/bubble/**init**.py:56-116](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L56-L116) +- [backend/modelscope_studio/components/antdx/bubble/**init**.py:21-54](file://backend/modelscope_studio/components/antdx/bubble/__init__.py#L21-L54) + +### BubbleList Component + +- Component Purpose: Message list container, responsible for scrolling, role grouping, and item rendering, supports auto-scroll and role configuration. +- Key Properties + - items: Message item array (dict) + - role: Role configuration (dict) + - auto_scroll: Whether to auto-scroll to the bottom + - class_names/styles/root_class_name: Style and class name control + - Other general properties: visible, elem_id, elem_classes, elem_style, render, etc. +- Events + - scroll: List scroll callback +- Slots + - items, role +- Nested Sub-components + - Item: Message item + - Role: Role identifier + +Section Sources + +- [backend/modelscope_studio/components/antdx/bubble/list/**init**.py:32-64](file://backend/modelscope_studio/components/antdx/bubble/list/__init__.py#L32-L64) +- [backend/modelscope_studio/components/antdx/bubble/list/**init**.py:19-30](file://backend/modelscope_studio/components/antdx/bubble/list/__init__.py#L19-L30) + +### BubbleListItem Component + +- Component Purpose: A single item in the message list, behaves essentially the same as Bubble but used as a list item. +- Key Properties + - content, avatar, extra, footer, header, loading, placement, editable, shape, typing, streaming, variant, footer_placement, loading_render, content_render, class_names/styles/root_class_name, etc. +- Events + - typing, typing_complete, edit_confirm, edit_cancel +- Slots + - avatar, editable.okText, editable.cancelText, content, footer, header, extra, loadingRender, contentRender + +Section Sources + +- [backend/modelscope_studio/components/antdx/bubble/list/item/**init**.py:49-108](file://backend/modelscope_studio/components/antdx/bubble/list/item/__init__.py#L49-L108) +- [backend/modelscope_studio/components/antdx/bubble/list/item/**init**.py:14-47](file://backend/modelscope_studio/components/antdx/bubble/list/item/__init__.py#L14-L47) + +### BubbleListRole Component + +- Component Purpose: Used to identify roles in lists, supports role avatar, header/footer, extra area, loading, and custom content rendering. +- Key Properties + - role: Role identifier text + - avatar, extra, footer, header, loading, placement, editable, shape, typing, streaming, variant, footer_placement, loading_render, content_render, class_names/styles/root_class_name, etc. +- Events + - typing, typing_complete, edit_confirm, edit_cancel +- Slots + - avatar, editable.okText, editable.cancelText, footer, header, extra, loadingRender, contentRender + +Section Sources + +- [backend/modelscope_studio/components/antdx/bubble/list/role/**init**.py:48-107](file://backend/modelscope_studio/components/antdx/bubble/list/role/__init__.py#L48-L107) +- [backend/modelscope_studio/components/antdx/bubble/list/role/**init**.py:14-46](file://backend/modelscope_studio/components/antdx/bubble/list/role/__init__.py#L14-L46) + +### Conversations Component + +- Component Purpose: For managing and viewing conversation lists, supports selection state toggling, menu operations, grouping, keyboard shortcuts, and creation buttons. +- Key Properties + - active_key/default_active_key: Current active item key + - items: Conversation item array (dict) + - menu: Menu configuration (string or dict) + - groupable: Whether groupable (boolean or dict) + - shortcut_keys: Keyboard shortcut mappings + - creation: Create button configuration (dict) + - styles/class_names/root_class_name: Style and class name control + - Other general properties: visible, elem_id, elem_classes, elem_style, render, etc. +- Events + - active_change: Selection change callback + - menu_click/menu_deselect/menu_open_change/menu_select: Menu-related callbacks + - groupable_expand: Group expand callback + - creation_click: Create button click callback +- Slots + - menu.expandIcon, menu.overflowedIndicator, menu.trigger, groupable.label, items, creation.icon, creation.label +- Nested Sub-components + - Item: Conversation item + +Section Sources + +- [backend/modelscope_studio/components/antdx/conversations/**init**.py:49-89](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L49-L89) +- [backend/modelscope_studio/components/antdx/conversations/**init**.py:18-47](file://backend/modelscope_studio/components/antdx/conversations/__init__.py#L18-L47) + +### ConversationsItem Component + +- Component Purpose: A single item in the conversation list, supports label, icon, type, group, disabled, dashed, etc. +- Key Properties + - label: Label text + - key: Unique key + - type: Type (e.g., divider) + - group: Belonging group + - icon: Icon + - disabled: Whether disabled + - dashed: Whether dashed + - additional_props/as_item/\_internal: Internal and extension properties + - Other general properties: visible, elem_id, elem_classes, elem_style, render, etc. + +Section Sources + +- [backend/modelscope_studio/components/antdx/conversations/item/**init**.py:21-55](file://backend/modelscope_studio/components/antdx/conversations/item/__init__.py#L21-L55) + +### Prompts Component + +- Component Purpose: For displaying preset prompts, supports title, vertical arrangement, fade-in effect, line wrapping, etc. +- Key Properties + - items: Prompt item array (dict) + - prefix_cls: Prefix class name + - title: Title + - vertical: Whether vertically arranged + - fade_in/fade_in_left: Fade-in effect (left/right) + - wrap: Whether to wrap + - styles/class_names/root_class_name: Style and class name control + - Other general properties: visible, elem_id, elem_classes, elem_style, render, etc. +- Events + - item_click: Prompt item click callback +- Slots + - title, items +- Nested Sub-components + - Item: Prompt item + +Section Sources + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:28-68](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L28-L68) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-26](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L26) + +### PromptsItem Component + +- Component Purpose: A single item in the prompt list, supports label, description, icon, disabled, and key. +- Key Properties + - label: Label text + - key: Unique key + - description: Description text + - icon: Icon + - disabled: Whether disabled + - additional_props/as_item/\_internal: Internal and extension properties + - Other general properties: visible, elem_id, elem_classes, elem_style, render, etc. + +Section Sources + +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:18-48](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L18-L48) + +## Dependency Analysis + +- Component Export: All antdx components are centrally exported through `components.py` for unified import and use. +- Component Hierarchy: The Bubble family (Bubble, BubbleList, BubbleListItem, BubbleListRole) forms a complete message rendering chain; the Conversations family and Prompts family handle conversation management and prompt management respectively. +- Events and Slots: Each component defines EVENTS and SLOTS lists to declare supported event callbacks and slot names, ensuring consistency between frontend and backend conventions. + +```mermaid +graph LR +A["components.py Export"] --> B["Bubble Family"] +A --> C["Conversations Family"] +A --> D["Prompts Family"] +B --> B1["Bubble"] +B --> B2["BubbleList"] +B2 --> B3["BubbleListItem"] +B2 --> B4["BubbleListRole"] +C --> C1["Conversations"] +C1 --> C2["ConversationsItem"] +D --> D1["Prompts"] +D1 --> D2["PromptsItem"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +Section Sources + +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Performance Considerations + +- Streaming Rendering and Typing Animation: Use streaming and typing parameters wisely to avoid stuttering when rendering large numbers of messages simultaneously. +- Auto-scroll: It is recommended to enable auto_scroll in BubbleList when messages are frequently updated to maintain the best user experience. +- Slots and Custom Rendering: Although loadingRender and contentRender are flexible, avoid heavy computations in rendering functions; cache results when necessary. +- Event Binding: Only enable relevant event bindings when needed (e.g., typing_complete) to reduce unnecessary callback overhead. +- Appearance and Shape: variant and shape affect rendering complexity; choose based on actual needs. + +## Troubleshooting Guide + +- Events Not Triggering + - Check that the binding names in EVENTS are correct, and confirm that the frontend has the corresponding `bind_*` events enabled. + - Confirm whether the visible and render states of the component affect event propagation. +- Slot Content Not Displaying + - Confirm that the slot name spelling matches the SLOTS list. + - Check whether the slot scope matches the slot content passed from the parent component. +- Style Issues + - Use class_names/styles/root_class_name for local overrides to avoid global style conflicts. +- Scroll Problems + - BubbleList's auto_scroll is related to the external container height setting; check container height and overflow settings. +- Typing Animation Not Working + - Confirm the type and value range of the typing parameter; avoid passing unsupported types. + +## Conclusion + +Antdx general components provide complete capabilities from message rendering and list management to conversation and prompt management. Through unified event and slot conventions, developers can quickly build conversational systems and prompt panels, and achieve high-performance, maintainable frontend experiences by combining style and interaction configurations. + +## Appendix + +### Typical Scenarios and Instantiation Paths + +- Conversation Bubble Basic Rendering and Typing Animation + - Reference path: [docs/components/antdx/bubble/README-zh_CN.md:7-12](file://docs/components/antdx/bubble/README-zh_CN.md#L7-L12) +- Message List and Auto-scroll + - Reference path: [docs/components/antdx/bubble/README-zh_CN.md:10-12](file://docs/components/antdx/bubble/README-zh_CN.md#L10-L12) +- Conversation List and Menu Operations + - Reference path: [docs/components/antdx/conversations/README-zh_CN.md:7-9](file://docs/components/antdx/conversations/README-zh_CN.md#L7-L9) +- Prompt Panel and Nested Usage + - Reference path: [docs/components/antdx/prompts/README-zh_CN.md:7-8](file://docs/components/antdx/prompts/README-zh_CN.md#L7-L8) + +### Data Formats and Field Descriptions (Summary) + +- Bubble/BubbleListItem/BubbleListRole + - content, avatar, extra, footer, header, loading, placement, editable, shape, typing, streaming, variant, footer_placement, loading_render, content_render, class_names, styles, root_class_name +- BubbleList + - items, role, auto_scroll, class_names, styles, root_class_name +- Conversations + - active_key, default_active_key, items, menu, groupable, shortcut_keys, creation, styles, class_names, root_class_name +- ConversationsItem + - label, key, type, group, icon, disabled, dashed, additional_props, as_item, \_internal +- Prompts + - items, prefix_cls, title, vertical, fade_in, fade_in_left, wrap, styles, class_names, root_class_name +- PromptsItem + - label, key, description, icon, disabled, additional_props, as_item, \_internal diff --git a/.wiki/en/API Reference/Python API/Antdx Components API/Utility Components API.md b/.wiki/en/API Reference/Python API/Antdx Components API/Utility Components API.md new file mode 100644 index 00000000..83a58798 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antdx Components API/Utility Components API.md @@ -0,0 +1,399 @@ +# Utility Components API + + +**Files Referenced in This Document** +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [code_highlighter/__init__.py](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py) +- [file_card/__init__.py](file://backend/modelscope_studio/components/antdx/file_card/__init__.py) +- [folder/__init__.py](file://backend/modelscope_studio/components/antdx/folder/__init__.py) +- [mermaid/__init__.py](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py) +- [sources/__init__.py](file://backend/modelscope_studio/components/antdx/sources/__init__.py) +- [think/__init__.py](file://backend/modelscope_studio/components/antdx/think/__init__.py) +- [x_provider/__init__.py](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document is the Python API reference for Antdx utility components, covering the complete API specifications and usage instructions for the following components: + +- CodeHighlighter: Code syntax highlighting +- FileCard: File card display (with List sub-component) +- Folder: Folder tree structure (with directory icon and tree node sub-components) +- Mermaid: Diagram rendering +- Sources: Source reference management (with item sub-component) +- Think: Thought annotation +- XProvider: Global configuration container + +The document systematically covers constructor parameters, property definitions, events and slots, data processing and formatting options, style and class name customization, as well as performance and rendering strategies, and provides standard usage examples and extension recommendations. + +## Project Structure + +Antdx components reside in the backend Python package, wrapped through a unified layout component base class for frontend components, with exported aliases for direct use. The core entry is in antdx's `__init__.py`, and `components.py` handles aggregated exports. + +```mermaid +graph TB +A["backend/modelscope_studio/components/antdx/components.py"] --> B["backend/modelscope_studio/components/antdx/__init__.py"] +B --> C1["CodeHighlighter"] +B --> C2["FileCard"] +B --> C3["Folder"] +B --> C4["Mermaid"] +B --> C5["Sources"] +B --> C6["Think"] +B --> C7["XProvider"] +``` + +Diagram Sources + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [**init**.py:14-41](file://backend/modelscope_studio/components/antdx/__init__.py#L14-L41) + +Section Sources + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [**init**.py:14-41](file://backend/modelscope_studio/components/antdx/__init__.py#L14-L41) + +## Core Components + +This section provides an overview of the responsibilities and general features of each component: + +- All inherit from the unified layout component base class, with general properties for visibility, element ID, class names, inline styles, and render toggle. +- Most components declare supported slots (SLOTS) and events (EVENTS) for frontend rendering and interaction binding. +- Most components set skip_api to True, indicating they do not participate in standard API serialization and are rendered directly by the frontend. + +Section Sources + +- [code_highlighter/**init**.py:6-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L6-L71) +- [file_card/**init**.py:11-112](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L11-L112) +- [folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) +- [mermaid/**init**.py:8-77](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L8-L77) +- [sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [x_provider/**init**.py:10-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L10-L101) + +## Architecture Overview + +The diagram below shows the encapsulation relationship and export paths of Python layer to frontend components: + +```mermaid +classDiagram +class AntdXCodeHighlighter { ++Constructor Parameters : value, lang, header, highlight_props, prism_light_mode, styles, class_names, additional_props, root_class_name, as_item, visible, elem_id, elem_classes, elem_style, render ++Properties : SLOTS, EVENTS, skip_api ++Methods : preprocess(), postprocess(), example_payload(), example_value() +} +class AntdXFileCard { ++Constructor Parameters : image_props, filename, byte, size, description, loading, type, src, mask, icon, video_props, audio_props, spin_props, styles, class_names, additional_props, as_item, visible, elem_id, elem_classes, elem_style, render ++Properties : SLOTS, EVENTS(List), skip_api ++Methods : preprocess(), postprocess(), example_payload(), example_value() +} +class AntdXFolder { ++Constructor Parameters : tree_data, selectable, selected_file, default_selected_file, directory_tree_width, empty_render, preview_render, expanded_paths, default_expanded_paths, default_expand_all, directory_title, preview_title, directory_icons, styles, class_names, additional_props, as_item, visible, elem_id, elem_classes, elem_style, render ++Properties : SLOTS, EVENTS, TreeNode, DirectoryIcon, skip_api ++Methods : preprocess(), postprocess(), example_payload(), example_value() +} +class AntdXMermaid { ++Constructor Parameters : value, highlight_props, config, actions, prefix_cls, styles, class_names, additional_props, root_class_name, as_item, visible, elem_id, elem_classes, elem_style, render ++Properties : SLOTS, EVENTS, skip_api ++Methods : preprocess(), postprocess(), example_payload(), example_value() +} +class AntdXSources { ++Constructor Parameters : title, items, expand_icon_position, default_expanded, expanded, inline, active_key, popover_overlay_width, styles, class_names, additional_props, as_item, visible, elem_id, elem_classes, elem_style, render ++Properties : SLOTS, EVENTS(Item), skip_api ++Methods : preprocess(), postprocess(), example_payload(), example_value() +} +class AntdXThink { ++Constructor Parameters : icon, styles, class_names, loading, title, root_class_name, default_expanded, expanded, blink, as_item, visible, elem_id, elem_classes, elem_style, render ++Properties : SLOTS, EVENTS, skip_api ++Methods : preprocess(), postprocess(), example_payload(), example_value() +} +class AntdXXProvider { ++Constructor Parameters : component_disabled, component_size, csp, direction, get_popup_container, get_target_container, icon_prefix_cls, locale, popup_match_select_width, popup_overflow, prefix_cls, render_empty, theme, theme_config, variant, virtual, warning, styles, class_names, additional_props, as_item, visible, elem_id, elem_classes, elem_style, render ++Properties : SLOTS, EVENTS, skip_api ++Methods : preprocess(), postprocess(), example_payload(), example_value() +} +``` + +Diagram Sources + +- [code_highlighter/**init**.py:6-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L6-L71) +- [file_card/**init**.py:11-112](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L11-L112) +- [folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) +- [mermaid/**init**.py:8-77](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L8-L77) +- [sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [x_provider/**init**.py:10-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L10-L101) + +## Detailed Component Analysis + +### CodeHighlighter (Code Syntax Highlighting) + +- Component Purpose: For highlighting code snippets, supports language and theme mode configurations. +- Key Parameters + - value: Code string to highlight + - lang: Language identifier + - header: Title or boolean control + - highlight_props: Highlight-related configuration + - prism_light_mode: Light mode toggle + - styles/class_names/additional_props/root_class_name/as_item: Style and class names, additional properties, root class name, as item + - visible/elem_id/elem_classes/elem_style/render: General layout properties +- Slots: header +- Events: None +- Data Processing: skip_api is True, not participating in standard API; preprocess/postprocess return original value +- Performance: Direct frontend rendering, avoids extra serialization overhead + +Section Sources + +- [code_highlighter/**init**.py:6-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L6-L71) + +### FileCard (File Card) + +- Component Purpose: Displays file information, supports multiple types including image, audio, video, and ordinary files, configurable size, loading state, mask, and media properties. +- Key Parameters + - image_props: Image preview related properties + - filename: File name + - byte: Byte count + - size: Size small/default + - description: Description text + - loading: Whether to show loading state + - type: Type image/file/audio/video or custom string + - src: Resource URL (supports string or dict containing path/url) + - mask: Mask text + - icon: Built-in icon category or custom string + - video_props/audio_props/spin_props: Video/audio/loading indicator configurations + - styles/class_names/additional_props/as_item/visible/elem_id/elem_classes/elem_style/render: General layout properties +- Slots: imageProps.placeholder, imageProps.preview.mask, imageProps.preview.closeIcon, imageProps.preview.toolbarRender, imageProps.preview.imageRender, description, icon, mask, spinProps.icon, spinProps.description, spinProps.indicator +- Events: click (bound to internal event) +- Data Processing: skip_api is True; preprocess/postprocess return original value; src supports static file service wrapping +- Performance: Direct frontend rendering; src field automatically handles static resource paths + +Section Sources + +- [file_card/**init**.py:11-112](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L11-L112) + +### Folder (Folder Tree Structure) + +- Component Purpose: Displays folder tree and selection/expansion behavior, supports preview rendering, empty state rendering, directory icons, etc. +- Key Parameters + - tree_data: Tree data + - selectable: Whether selectable + - selected_file/default_selected_file: Selected file list + - directory_tree_width: Directory tree width + - empty_render/preview_render: Empty state and preview rendering + - expanded_paths/default_expanded_paths/default_expand_all: Expansion path control + - directory_title/preview_title: Titles + - directory_icons: Directory icon mappings + - styles/class_names/additional_props/root_class_name/as_item/visible/elem_id/elem_classes/elem_style/render: General layout properties +- Sub-components: TreeNode, DirectoryIcon +- Slots: emptyRender, previewRender, directoryTitle, previewTitle, treeData, directoryIcons +- Events: file_click, folder_click, selected_file_change, expanded_paths_change, file_content_service_load_file_content (bound to internal events) +- Data Processing: skip_api is True; preprocess/postprocess return original value +- Performance: Direct frontend rendering; supports default expand all + +Section Sources + +- [folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) + +### Mermaid (Diagram Rendering) + +- Component Purpose: Renders diagrams based on Mermaid syntax, supports highlight configuration, theme configuration, and custom actions. +- Key Parameters + - value: Mermaid text + - highlight_props: Highlight configuration + - config: Global configuration + - actions: Custom actions + - prefix_cls: Prefix class name + - styles/class_names/additional_props/root_class_name/as_item/visible/elem_id/elem_classes/elem_style/render: General layout properties +- Slots: header, actions.customActions +- Events: render_type_change (bound to internal event) +- Data Processing: skip_api is True; preprocess/postprocess return original value +- Performance: Direct frontend rendering + +Section Sources + +- [mermaid/**init**.py:8-77](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L8-L77) + +### Sources (Source Reference Management) + +- Component Purpose: Manages source reference entries in a collapsible panel form, supports expansion position, active key, popover width, etc. +- Key Parameters + - title: Title + - items: Entry list + - expand_icon_position: Expansion icon position start/end + - default_expanded/expanded: Default/current expanded state + - inline: Whether inline + - active_key: Active key + - popover_overlay_width: Popover width + - styles/class_names/additional_props/root_class_name/as_item/visible/elem_id/elem_classes/elem_style/render: General layout properties +- Sub-components: Item +- Slots: items +- Events: expand, click (bound to internal events) +- Data Processing: skip_api is True; preprocess/postprocess return original value +- Performance: Direct frontend rendering + +Section Sources + +- [sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) + +### Think (Thought Annotation) + +- Component Purpose: Used to display thought processes or prompt information, supports loading state, title, blink, etc. +- Key Parameters + - icon: Icon + - styles/class_names/additional_props/root_class_name/as_item/visible/elem_id/elem_classes/elem_style/render: General layout properties + - loading: Loading state (string or boolean) + - title: Title + - default_expanded/expanded: Default/current expanded state + - blink: Blink toggle +- Slots: loading, icon, title +- Events: expand (bound to internal event) +- Data Processing: skip_api is True; preprocess/postprocess return original value +- Performance: Direct frontend rendering + +Section Sources + +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) + +### XProvider (Global Configuration) + +- Component Purpose: Global configuration container, passes theme, language, direction, variant, and other configurations to the sub-component tree. +- Key Parameters + - component_disabled: Disable component + - component_size: Component size small/middle/large + - csp: Content Security Policy + - direction: Direction ltr/rtl + - get_popup_container/get_target_container: Popup container selector + - icon_prefix_cls: Icon prefix class name + - locale: Locale environment + - popup_match_select_width: Popup matches select width + - popup_overflow: Popup overflow strategy viewport/scroll + - prefix_cls: Component prefix class name + - render_empty: Empty state rendering + - theme/theme_config: Theme and theme configuration (conflict warning exists) + - variant: Appearance outlined/filled/borderless + - virtual: Virtualization + - warning: Warning configuration + - styles/class_names/additional_props/as_item/visible/elem_id/elem_classes/elem_style/render: General layout properties +- Slots: renderEmpty +- Events: None +- Data Processing: skip_api is True; preprocess/postprocess return original value +- Performance: Direct frontend rendering; note the conflict warning between theme and theme_config + +Section Sources + +- [x_provider/**init**.py:10-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L10-L101) + +## Dependency Analysis + +- Export Relationships: `components.py` aggregates imports from all component modules under antdx; `__init__.py` exports component classes as user-friendly aliases. +- Component Relationships: Some components provide sub-components (e.g., FileCard.List, Folder.TreeNode/Folder.DirectoryIcon, Sources.Item, Think, etc.) for composing complex UIs. +- Event Binding: Most components update internal state flags through event listener callbacks, thereby triggering frontend event binding. + +```mermaid +graph LR +subgraph "Export Layer" +E1["components.py"] --> E2["__init__.py"] +end +subgraph "Component Layer" +F1["code_highlighter/__init__.py"] +F2["file_card/__init__.py"] +F3["folder/__init__.py"] +F4["mermaid/__init__.py"] +F5["sources/__init__.py"] +F6["think/__init__.py"] +F7["x_provider/__init__.py"] +end +E2 --> F1 +E2 --> F2 +E2 --> F3 +E2 --> F4 +E2 --> F5 +E2 --> F6 +E2 --> F7 +``` + +Diagram Sources + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [**init**.py:14-41](file://backend/modelscope_studio/components/antdx/__init__.py#L14-L41) + +Section Sources + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [**init**.py:14-41](file://backend/modelscope_studio/components/antdx/__init__.py#L14-L41) + +## Performance Considerations + +- Skip API Serialization: All components set skip_api to True, avoiding unnecessary Python-to-frontend data round trips and improving rendering efficiency. +- Direct Frontend Connection: Components point to frontend component directories via `resolve_frontend_dir`, reducing intermediate layer conversion costs. +- Static Resources: FileCard wraps src with static file service, reducing resource access latency. +- Default Expand All: Folder supports `default_expand_all`, which can expand everything at initialization to reduce user interaction steps. +- Theme and Variants: XProvider provides unified theme and appearance configuration, avoiding repeated computations and style switching overhead. + +## Troubleshooting Guide + +- Component Not Working + - Check whether visible and render are True + - Confirm that elem_id/elem_classes/elem_style are correctly passed in +- File Resources Cannot Load + - When FileCard's src is a dict, ensure it contains path or url; use static file service wrapping if necessary +- Events Not Triggering + - Confirm that event listener names match the EVENTS definitions of the component + - Check whether the frontend correctly binds the internal event flag +- Theme Conflicts + - The theme property in XProvider conflicts with Gradio presets; use theme_config instead +- Rendering Issues + - Slot content for Mermaid/CodeHighlighter/Sources/Think must be provided according to specifications to avoid frontend parsing errors + +Section Sources + +- [file_card/**init**.py:87-93](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L87-L93) +- [x_provider/**init**.py:74-78](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L74-L78) + +## Conclusion + +Antdx utility components provide a concise and powerful Python API through the unified layout component base class and direct frontend rendering strategy. Each component is organized around the pattern of "parameter-driven + slots + event binding", meeting common scenarios (code highlighting, file display, tree navigation, diagrams, source references, thought annotation, global configuration) while leaving ample room for extension and customization. In practice, it is recommended to prioritize using the sub-components and slots provided by each component, use XProvider for global style and theme management, and follow the best practices for static resources and event binding. + +## Appendix: Usage Examples and Best Practices + +- Code Highlighting + - Scenario: Display code snippets in conversations or documents + - Recommendations: Specify lang and highlight_props; enable prism_light_mode if necessary + - Reference path: [code_highlighter/**init**.py:15-52](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L15-L52) +- File Card + - Scenario: Upload or browse file lists + - Recommendations: Set icon based on type; wrap src with static file service; set size and loading appropriately + - Reference path: [file_card/**init**.py:32-94](file://backend/modelscope_studio/components/antdx/file_card/__init__.py#L32-L94) +- Folder Tree + - Scenario: File browsing and selection + - Recommendations: Keep tree_data structure clear; enable default_expand_all only with manageable data volume; use directory_icons for custom icons + - Reference path: [folder/**init**.py:43-96](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L43-L96) +- Diagram + - Scenario: Visualize algorithms or business processes + - Recommendations: Use standard Mermaid syntax for value; configure config and actions as needed + - Reference path: [mermaid/**init**.py:21-58](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L21-L58) +- Source References + - Scenario: Display reference sources and entries + - Recommendations: Standardize items structure; choose inline and expand_icon_position based on interface style + - Reference path: [sources/**init**.py:30-73](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L30-L73) +- Thought Annotation + - Scenario: Prompt users to focus on key points or loading state + - Recommendations: Express intent clearly with title and icon; use blink only for emphasis + - Reference path: [think/**init**.py:21-60](file://backend/modelscope_studio/components/antdx/think/__init__.py#L21-L60) +- Global Configuration + - Scenario: Unify theme, language, direction, and appearance + - Recommendations: Prefer theme_config; configure locale and direction by region; maintain consistency between prefix_cls and icon_prefix_cls + - Reference path: [x_provider/**init**.py:19-82](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L19-L82) diff --git a/.wiki/en/API Reference/Python API/Antdx Components API/Wake Components API.md b/.wiki/en/API Reference/Python API/Antdx Components API/Wake Components API.md new file mode 100644 index 00000000..fb4cbc6e --- /dev/null +++ b/.wiki/en/API Reference/Python API/Antdx Components API/Wake Components API.md @@ -0,0 +1,334 @@ +# Wake Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/welcome/__init__.py](file://backend/modelscope_studio/components/antdx/welcome/__init__.py) +- [backend/modelscope_studio/components/antdx/prompts/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/__init__.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) +- [docs/components/antdx/welcome/app.py](file://docs/components/antdx/welcome/app.py) +- [docs/components/antdx/prompts/app.py](file://docs/components/antdx/prompts/app.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for Antdx wake components, focusing on the following goals: + +- Document the welcome interface display, welcome message configuration, and user guidance flow of the Welcome component +- Explain the prompt set management, prompt template definition, and dynamic prompt generation mechanisms of the Prompts component +- Provide the message format, personalization configuration options, and multilingual support descriptions for the Welcome component +- Give standard usage examples for AI assistant startup, user guidance, and prompt activation scenarios +- Explain initialization parameters, callback function configurations, and user experience optimization strategies +- Describe integration approaches with conversational systems and state synchronization mechanisms + +## Project Structure + +Antdx components reside in the backend Python package, bridged through a unified layout component base class and frontend directory resolution mechanism. Both Welcome and Prompts components inherit from the general layout component base class and point to the corresponding frontend component directory via `resolve_frontend_dir`. + +```mermaid +graph TB +subgraph "Python Backend" +A["ModelScopeLayoutComponent
Component Base Class"] +B["AntdXWelcome
Welcome Component"] +C["AntdXPrompts
Prompts Component"] +D["AntdXPromptsItem
Prompt Item Component"] +E["resolve_frontend_dir
Frontend Directory Resolver"] +end +subgraph "Frontend Components" +F["welcome component directory"] +G["prompts component directory"] +H["prompts/item sub-component directory"] +end +A --> B +A --> C +C --> D +E --> F +E --> G +E --> H +B -.-> F +C -.-> G +D -.-> H +``` + +Diagram Sources + +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:55-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L55-L55) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:70-70](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L70-L70) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-16](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L16) + +Section Sources + +- [backend/modelscope_studio/components/antdx/components.py:24-39](file://backend/modelscope_studio/components/antdx/components.py#L24-L39) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) + +## Core Components + +- AntdXWelcome: For rendering a welcome interface, supports slot-based configuration for title, description, icon, extra content, and style and variant control. +- AntdXPrompts: For displaying a set of prompt word cards, supports title, vertical arrangement, fade-in animation, line wrapping, and other configurations; includes an item_click callback event to respond to click behavior. + +Section Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) + +## Architecture Overview + +Antdx components connect to the corresponding frontend component directory through a unified layout component base class and frontend directory resolver. Components set the frontend directory path during initialization and participate in layout updates and internal state passing through Gradio's BlockContext mechanism. + +```mermaid +sequenceDiagram +participant Py as "Python Component" +participant Base as "ModelScopeLayoutComponent" +participant Resolver as "resolve_frontend_dir" +participant FE as "Frontend Component Directory" +Py->>Base : Initialize component, set visibility/element properties +Py->>Resolver : Resolve frontend directory component name/sub-component/type +Resolver-->>Py : Return relative path +Py->>FE : Load corresponding frontend component resources +Py->>Base : Enter context to trigger layout update +``` + +Diagram Sources + +- [backend/modelscope_studio/utils/dev/component.py:24-26](file://backend/modelscope_studio/utils/dev/component.py#L24-L26) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-16](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L16) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:55-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L55-L55) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:70-70](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L70-L70) + +## Detailed Component Analysis + +### Welcome Component API + +- Component: AntdXWelcome +- Inheritance: ModelScopeLayoutComponent +- Slot Support: extra, icon, description, title +- Key Parameters + - extra: Extra content (string or None) + - icon: Icon resource path (processed through static file service) + - description: Description text + - title: Title text + - variant: Appearance variant (filled or borderless) + - styles/class_names/root_class_name: Style and class name configuration + - Element properties: elem_id, elem_classes, elem_style, visible, render, etc. +- Lifecycle and Preprocessing + - preprocess/postprocess/example_payload/example_value all return empty values, indicating this component does not perform data conversion or example value generation +- Events + - No public event bindings (EVENTS is empty) + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__enter__() ++__exit__() ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdXWelcome { ++additional_props ++extra ++icon ++styles ++class_names ++description ++variant ++title ++root_class_name ++FRONTEND_DIR ++skip_api ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +ModelScopeLayoutComponent <|-- AntdXWelcome +``` + +Diagram Sources + +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) + +Section Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:17-54](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L17-L54) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:57-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L57-L73) + +### Prompts Component API + +- Component: AntdXPrompts +- Inheritance: ModelScopeLayoutComponent +- Internal Items: AntdXPromptsItem (exposed via the Item property) +- Slot Support: title, items +- Key Parameters + - items: Prompt item list (list of dicts; specific fields are defined by the frontend convention) + - prefix_cls: Prefix class name (for style isolation) + - title: Prompt set title + - vertical: Whether to arrange vertically + - fade_in/fade_in_left: Fade-in animation toggles + - wrap: Whether to wrap + - styles/class_names/root_class_name/additional_props: Style and extension properties + - Element properties: elem_id, elem_classes, elem_style, visible, render, etc. +- Events + - item_click: Triggered when a prompt item is clicked; internally configured via `_internal.update(bind_itemClick_event=True)` for frontend event binding +- Lifecycle and Preprocessing + - preprocess/postprocess/example_payload/example_value all return empty values, indicating this component does not perform data conversion or example value generation + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__enter__() ++__exit__() ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdXPrompts { ++Item ++EVENTS ++SLOTS ++items ++prefix_cls ++title ++vertical ++fade_in ++fade_in_left ++wrap ++styles ++class_names ++root_class_name ++additional_props ++FRONTEND_DIR ++skip_api ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdXPromptsItem { ++... +} +ModelScopeLayoutComponent <|-- AntdXPrompts +AntdXPrompts o--> AntdXPromptsItem : "internal items" +``` + +Diagram Sources + +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) + +Section Sources + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:28-68](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L28-L68) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:72-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L72-L88) + +### Usage Examples and Best Practices + +- AI Assistant Startup and Welcome Page Display + - Render the Welcome component at application startup, set the title, description, and icon; add guidance buttons or action areas via the extra slot as needed + - Control appearance style via variant; achieve theme adaptation via styles/class_names/root_class_name +- User Guidance and Prompt Activation + - Use the Prompts component to display a set of prompt word cards, set title and items, and enable fade_in/fade_in_left for enhanced visual experience + - Monitor user selections via the item_click event; combined with the conversational system, inject the selected prompt into the input box or directly initiate a conversation +- Multilingual Support + - Title, description, and prompt text should come from localization resources; the text parameters of both Welcome and Prompts support string types, making it easy to replace with different language versions +- State Synchronization and Integration + - Components participate in layout updates via Gradio BlockContext; to integrate with a conversational system, trigger business logic in the item_click callback (e.g., write prompt content to the input field or send a request) and complete state rendering on the frontend + +Section Sources + +- [docs/components/antdx/welcome/app.py:1-7](file://docs/components/antdx/welcome/app.py#L1-L7) +- [docs/components/antdx/prompts/app.py:1-7](file://docs/components/antdx/prompts/app.py#L1-L7) + +## Dependency Analysis + +- Component Exports + - `antdx/__init__.py` exports Welcome and Prompts as aliases for easy named imports from outside + - `antdx/components.py` aggregates all sub-modules to ensure the complete import chain +- Base Class and Utilities + - ModelScopeLayoutComponent provides unified layout component capabilities and lifecycle hooks + - `resolve_frontend_dir` maps component names to frontend directories, supporting sub-components and multi-level directory concatenation + +```mermaid +graph LR +A["antdx/__init__.py"] --> B["Welcome Export"] +A --> C["Prompts Export"] +D["antdx/components.py"] --> E["Aggregated Import"] +E --> B +E --> C +F["utils/dev/component.py"] --> G["ModelScopeLayoutComponent"] +H["utils/dev/resolve_frontend_dir.py"] --> I["Frontend Directory Resolution"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:24-39](file://backend/modelscope_studio/components/antdx/components.py#L24-L39) +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-16](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L16) + +Section Sources + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:24-39](file://backend/modelscope_studio/components/antdx/components.py#L24-L39) + +## Performance Considerations + +- Component Skips API: Both components have skip_api returning True, meaning no additional API interface layer will be generated, reducing server-side overhead +- Preprocessing and Postprocessing: preprocess/postprocess return empty values, avoiding unnecessary data conversions and contributing to low-latency rendering +- Animation and Layout: Prompts' fade-in and line-wrap options only affect frontend rendering; exercise caution when enabling animations with large numbers of prompt items to balance smoothness and performance + +## Troubleshooting Guide + +- Component Not Displaying + - Check whether visible and render parameters are correctly set + - Confirm that elem_id/elem_classes/elem_style are not causing style overrides +- Icon or Resource Cannot Load + - Confirm that the icon path has been processed via the static file service (serve_static_file) +- Events Not Triggering + - Confirm that the item_click event was bound during initialization (internally triggered via `_internal.update(bind_itemClick_event=True)`) +- Frontend Directory Resolution Failed + - Check whether the component name and type in `resolve_frontend_dir` match the actual frontend directory structure + +Section Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:47-47](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L47-L47) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:20-22](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L20-L22) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-16](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L16) + +## Conclusion + +AntdXWelcome and AntdXPrompts achieve seamless connection with frontend components through the unified layout component base class and frontend directory resolution mechanism. Welcome focuses on the copywriting and style configuration of the welcome page, while Prompts specializes in the display and interaction of prompt sets. Both can integrate with conversational systems through Gradio's layout and event mechanisms to realize a complete user experience loop from "welcome guidance" to "prompt activation". + +## Appendix + +- Initialization Parameter Quick Reference + - Welcome: extra, icon, description, title, variant, styles, class_names, root_class_name, elem_id, elem_classes, elem_style, visible, render + - Prompts: items, prefix_cls, title, vertical, fade_in, fade_in_left, wrap, styles, class_names, root_class_name, additional_props, elem_id, elem_classes, elem_style, visible, render +- Event Quick Reference + - Prompts: item_click (triggered when a prompt item is clicked) diff --git a/.wiki/en/API Reference/Python API/Basic Components API.md b/.wiki/en/API Reference/Python API/Basic Components API.md new file mode 100644 index 00000000..6ef5d075 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Basic Components API.md @@ -0,0 +1,495 @@ +# Basic Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/components/base/application/__init__.py](file://backend/modelscope_studio/components/base/application/__init__.py) +- [backend/modelscope_studio/components/base/auto_loading/__init__.py](file://backend/modelscope_studio/components/base/auto_loading/__init__.py) +- [backend/modelscope_studio/components/base/slot/__init__.py](file://backend/modelscope_studio/components/base/slot/__init__.py) +- [backend/modelscope_studio/components/base/each/__init__.py](file://backend/modelscope_studio/components/base/each/__init__.py) +- [backend/modelscope_studio/components/base/filter/__init__.py](file://backend/modelscope_studio/components/base/filter/__init__.py) +- [backend/modelscope_studio/components/base/fragment/__init__.py](file://backend/modelscope_studio/components/base/fragment/__init__.py) +- [backend/modelscope_studio/components/base/div/__init__.py](file://backend/modelscope_studio/components/base/div/__init__.py) +- [backend/modelscope_studio/components/base/text/__init__.py](file://backend/modelscope_studio/components/base/text/__init__.py) +- [backend/modelscope_studio/components/base/span/__init__.py](file://backend/modelscope_studio/components/base/span/__init__.py) +- [backend/modelscope_studio/components/base/markdown/__init__.py](file://backend/modelscope_studio/components/base/markdown/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/app_context.py](file://backend/modelscope_studio/utils/dev/app_context.py) +- [docs/components/base/application/README.md](file://docs/components/base/application/README.md) +- [docs/components/base/each/README.md](file://docs/components/base/each/README.md) +- [docs/components/base/slot/README.md](file://docs/components/base/slot/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document is the Python API reference for the base component library, covering core components under `modelscope_studio.components.base.*`, including Application, AutoLoading, Slot, Each, Filter, Fragment, Layout components (represented by common layout components such as Div/Span/Markdown), Text, and others. The documentation is organized based on the repository source code and accompanying docs, focusing on: + +- Complete import paths and usage patterns +- Constructor parameters, property definitions, method signatures, and return types +- Component composition patterns (application containers, conditional rendering, list iteration) +- Lifecycle management, context passing, and slot system interfaces +- Performance optimization strategies, memory management, and error handling mechanisms +- Component inheritance patterns, extension development, and best practices + +## Project Structure + +Base components reside in the backend Python package `modelscope_studio/components/base`, aggregated through a unified export entry point; frontend resources are resolved by utility modules and bound to corresponding frontend directories. + +```mermaid +graph TB +subgraph "Python Backend" +BASE["backend/modelscope_studio/components/base/__init__.py"] +APP["application/__init__.py"] +AUTO["auto_loading/__init__.py"] +SLOT["slot/__init__.py"] +EACH["each/__init__.py"] +FILTER["filter/__init__.py"] +FRAG["fragment/__init__.py"] +DIV["div/__init__.py"] +TEXT["text/__init__.py"] +SPAN["span/__init__.py"] +MARK["markdown/__init__.py"] +DEV["utils/dev/component.py"] +CTX["utils/dev/app_context.py"] +end +BASE --> APP +BASE --> AUTO +BASE --> SLOT +BASE --> EACH +BASE --> FILTER +BASE --> FRAG +BASE --> DIV +BASE --> TEXT +BASE --> SPAN +BASE --> MARK +APP --> DEV +AUTO --> DEV +SLOT --> DEV +EACH --> DEV +FILTER --> DEV +FRAG --> DEV +DIV --> DEV +TEXT --> DEV +SPAN --> DEV +MARK --> DEV +APP --> CTX +DEV --> CTX +``` + +Diagram sources + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:8-65](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L8-L65) +- [backend/modelscope_studio/components/base/slot/**init**.py:8-50](file://backend/modelscope_studio/components/base/slot/__init__.py#L8-L50) +- [backend/modelscope_studio/components/base/each/**init**.py:17-73](file://backend/modelscope_studio/components/base/each/__init__.py#L17-L73) +- [backend/modelscope_studio/components/base/filter/**init**.py:8-45](file://backend/modelscope_studio/components/base/filter/__init__.py#L8-L45) +- [backend/modelscope_studio/components/base/fragment/**init**.py:8-49](file://backend/modelscope_studio/components/base/fragment/__init__.py#L8-L49) +- [backend/modelscope_studio/components/base/div/**init**.py:10-86](file://backend/modelscope_studio/components/base/div/__init__.py#L10-L86) +- [backend/modelscope_studio/components/base/text/**init**.py:8-57](file://backend/modelscope_studio/components/base/text/__init__.py#L8-L57) +- [backend/modelscope_studio/components/base/span/**init**.py:10-87](file://backend/modelscope_studio/components/base/span/__init__.py#L10-L87) +- [backend/modelscope_studio/components/base/markdown/**init**.py:11-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L11-L174) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) + +Section sources + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +## Core Components + +The following is an overview of import paths and key capabilities for each core base component (sorted alphabetically): + +- Application + - Import path: `from modelscope_studio.components.base import Application` + - Capabilities: Application root container; listens to page lifecycle events (mount, resize, unmount, custom); provides page environment data (screen size, language, theme, userAgent). + - Key notes: Must be used as the root container for all components; supports custom event bridging (`window.ms_globals.dispatch` → Python-side events). + +- AutoLoading + - Import path: `from modelscope_studio.components.base import AutoLoading` + - Capabilities: Auto-loading state wrapper; supports slots (render, errorRender, loadingText); controllable mask, timer, and error display. + +- Slot + - Import path: `from modelscope_studio.components.base import Slot` + - Capabilities: Slot placeholder component; used together with the target component's `SLOTS`; supports `params_mapping` for parameter mapping. + +- Each + - Import path: `from modelscope_studio.components.base import Each` + - Capabilities: List iteration rendering; injects context; supports `as_item` filtering and deep merge via `context_value`. + +- Filter + - Import path: `from modelscope_studio.components.base import Filter` + - Capabilities: Conditional filter component; determines whether to render a subtree based on parameter mapping. + +- Fragment + - Import path: `from modelscope_studio.components.base import Fragment` + - Capabilities: Grouping container; produces no additional DOM; suitable for logical grouping and slot mounting. + +- Div/Text/Span/Markdown + - Import path: `from modelscope_studio.components.base import Div, Text, Span, Markdown` + - Capabilities: Basic layout and text components; support additional properties, event binding, copy button, and other features. + +Section sources + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [docs/components/base/application/README.md:1-56](file://docs/components/base/application/README.md#L1-L56) +- [docs/components/base/each/README.md:1-32](file://docs/components/base/each/README.md#L1-L32) +- [docs/components/base/slot/README.md:1-17](file://docs/components/base/slot/README.md#L1-L17) + +## Architecture Overview + +The runtime architecture of base components revolves around "application context + component base classes + frontend resource resolution". Components assert the existence of an Application context during construction, and pass layout and index information to the frontend via the internal `_internal` dictionary; some components support slots and event binding, which are ultimately consumed by the frontend rendering engine. + +```mermaid +graph TB +APP["Application
Application Root Container"] --> CTX["AppContext
Global Context"] +CTX --> BASE["ModelScopeLayoutComponent / ModelScopeComponent
Component Base Class"] +BASE --> EACH["Each"] +BASE --> SLOT["Slot"] +BASE --> FILTER["Filter"] +BASE --> FRAG["Fragment"] +BASE --> LAYOUT["Div / Span / Markdown and other layout components"] +BASE --> AUTO["AutoLoading"] +BASE --> DATA["ModelScopeDataLayoutComponent
Layout Component with Data Model"] +DATA --> APPCOMP["Application"] +DATA --> MARK["Markdown"] +subgraph "Frontend Resource Resolution" +RESOLVE["resolve_frontend_dir(type='base')"] +end +BASE --> RESOLVE +DATA --> RESOLVE +AUTO --> RESOLVE +LAYOUT --> RESOLVE +``` + +Diagram sources + +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/components/base/markdown/**init**.py:11-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L11-L174) +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:8-65](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L8-L65) +- [backend/modelscope_studio/components/base/div/**init**.py:10-86](file://backend/modelscope_studio/components/base/div/__init__.py#L10-L86) +- [backend/modelscope_studio/components/base/slot/**init**.py:8-50](file://backend/modelscope_studio/components/base/slot/__init__.py#L8-L50) +- [backend/modelscope_studio/components/base/each/**init**.py:17-73](file://backend/modelscope_studio/components/base/each/__init__.py#L17-L73) +- [backend/modelscope_studio/components/base/filter/**init**.py:8-45](file://backend/modelscope_studio/components/base/filter/__init__.py#L8-L45) +- [backend/modelscope_studio/components/base/fragment/**init**.py:8-49](file://backend/modelscope_studio/components/base/fragment/__init__.py#L8-L49) + +## Detailed Component Analysis + +### Application + +- Import path: `from modelscope_studio.components.base import Application` +- Inheritance: `ModelScopeDataLayoutComponent` +- Events: + - `mount`: Page mounted + - `resize`: Window size changed + - `unmount`: Page unmounted + - `custom`: Custom event triggered via `window.ms_globals.dispatch` +- Data models: + - `ApplicationPageScreenData`: width, height, scrollX, scrollY + - `ApplicationPageData`: screen, language, theme, userAgent +- Key behavior: + - Sets `AppContext` during construction + - Supports `preprocess`/`postprocess` pass-through + - Provides `example_payload`/`example_value` + +Section sources + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [docs/components/base/application/README.md:1-56](file://docs/components/base/application/README.md#L1-L56) + +### AutoLoading + +- Import path: `from modelscope_studio.components.base import AutoLoading` +- Inheritance: `ModelScopeLayoutComponent` +- Slots: `render`, `errorRender`, `loadingText` +- Key properties: + - `generating`, `show_error`, `show_mask`, `show_timer`, `loading_text` +- Key behavior: + - `skip_api=True`, does not participate in the standard API flow + - `preprocess`/`postprocess` handles strings as pass-through + +Section sources + +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:8-65](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L8-L65) + +### Slot + +- Import path: `from modelscope_studio.components.base import Slot` +- Inheritance: `ModelScopeLayoutComponent` +- Key properties: + - `value`: Slot name + - `params_mapping`: JavaScript function string for parameter mapping +- Key behavior: + - When the parent is also a Slot, `value` is concatenated to form a hierarchical path + - `skip_api=True` + +Section sources + +- [backend/modelscope_studio/components/base/slot/**init**.py:8-50](file://backend/modelscope_studio/components/base/slot/__init__.py#L8-L50) +- [docs/components/base/slot/README.md:1-17](file://docs/components/base/slot/README.md#L1-L17) + +### Each + +- Import path: `from modelscope_studio.components.base import Each` +- Inheritance: `ModelScopeDataLayoutComponent` +- Data model: `ModelScopeEachData` (root: list) +- Key properties: + - `value`: `list[dict]` or `Callable` + - `context_value`: `dict`, used for deep merge into context + - `as_item`: string, for filtering context fields +- Key behavior: + - `preprocess` unpacks `ModelScopeEachData` into a list + - `postprocess` returns a list + - `skip_api=False`, participates in the API flow + +Section sources + +- [backend/modelscope_studio/components/base/each/**init**.py:17-73](file://backend/modelscope_studio/components/base/each/__init__.py#L17-L73) +- [docs/components/base/each/README.md:1-32](file://docs/components/base/each/README.md#L1-L32) + +### Filter + +- Import path: `from modelscope_studio.components.base import Filter` +- Inheritance: `ModelScopeLayoutComponent` +- Key properties: + - `params_mapping`: Parameter mapping string +- Key behavior: + - `skip_api=True`, does not participate in the API flow + +Section sources + +- [backend/modelscope_studio/components/base/filter/**init**.py:8-45](file://backend/modelscope_studio/components/base/filter/__init__.py#L8-L45) + +### Fragment + +- Import path: `from modelscope_studio.components.base import Fragment` +- Inheritance: `ModelScopeLayoutComponent` +- Key behavior: + - `skip_api=True`, does not participate in the API flow + - Suitable for logical grouping and slot mounting + +Section sources + +- [backend/modelscope_studio/components/base/fragment/**init**.py:8-49](file://backend/modelscope_studio/components/base/fragment/__init__.py#L8-L49) + +### Div + +- Import path: `from modelscope_studio.components.base import Div` +- Inheritance: `ModelScopeLayoutComponent` +- Events: `click`, `dblclick`, `mousedown`, `mouseup`, `mouseover`, `mouseout`, `mousemove`, `scroll` +- Key properties: + - `value`: string + - `additional_props`: dict, additional properties +- Key behavior: + - `skip_api=True` + +Section sources + +- [backend/modelscope_studio/components/base/div/**init**.py:10-86](file://backend/modelscope_studio/components/base/div/__init__.py#L10-L86) + +### Text + +- Import path: `from modelscope_studio.components.base import Text` +- Inheritance: `ModelScopeComponent` +- Key behavior: + - `skip_api=True` + +Section sources + +- [backend/modelscope_studio/components/base/text/**init**.py:8-57](file://backend/modelscope_studio/components/base/text/__init__.py#L8-L57) + +### Span + +- Import path: `from modelscope_studio.components.base import Span` +- Inheritance: `ModelScopeLayoutComponent` +- Events: `click`, `dblclick`, `mousedown`, `mouseup`, `mouseover`, `mouseout`, `mousemove`, `scroll` +- Key properties: + - `value`: string + - `additional_props`: dict, additional properties +- Key behavior: + - `skip_api=True` + +Section sources + +- [backend/modelscope_studio/components/base/span/**init**.py:10-87](file://backend/modelscope_studio/components/base/span/__init__.py#L10-L87) + +### Markdown + +- Import path: `from modelscope_studio.components.base import Markdown` +- Inheritance: `ModelScopeDataLayoutComponent` +- Events: `change`, `copy`, `click`, `dblclick`, `mousedown`, `mouseup`, `mouseover`, `mouseout`, `mousemove`, `scroll` +- Slots: `copyButtons` +- Key properties: + - `value`: string + - `rtl`, `latex_delimiters`, `sanitize_html`, `line_breaks`, `header_links`, `allow_tags`, `show_copy_button`, `copy_buttons`, `additional_props` +- Key behavior: + - `preprocess` returns as-is + - `postprocess` strips indentation and returns a string + - `api_info` returns `{"type": "string"}` + +Section sources + +- [backend/modelscope_studio/components/base/markdown/**init**.py:11-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L11-L174) + +## Dependency Analysis + +- Component base classes and context + - All base components depend on the base classes (`ModelScopeLayoutComponent`, `ModelScopeComponent`, `ModelScopeDataLayoutComponent`) defined in `utils/dev/component.py`, and assert the existence of `AppContext` during construction. + - `utils/dev/app_context.py` provides `set_app`/`assert_app`/`get_app` to ensure components are used within an Application root container. + +- Frontend resource resolution + - Each component resolves its frontend directory via `resolve_frontend_dir("xxx", type="base")`, ensuring consistency between frontend and backend resources. + +```mermaid +graph LR +CTX["AppContext"] --> |assert_app| BASE["Component Base Class"] +BASE --> |inherits| LCOMP["ModelScopeLayoutComponent"] +BASE --> |inherits| DCOMP["ModelScopeDataLayoutComponent"] +BASE --> |inherits| SCOMP["ModelScopeComponent"] +LCOMP --> |frontend| RES["resolve_frontend_dir('...')"] +DCOMP --> |frontend| RES +SCOMP --> |frontend| RES +``` + +Diagram sources + +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +Section sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) + +## Performance Considerations + +- Avoiding unnecessary API interactions + - Most base components have `skip_api=True` (e.g., AutoLoading, Slot, Filter, Fragment, Div/Span/Text/Markdown), meaning they do not participate in the standard API flow, reducing frontend-backend round-trip overhead. +- List rendering optimization + - `Each`'s `value` supports `Callable` for lazy evaluation in complex scenarios; combining `as_item`/`context_value` reduces redundant attribute passing and conflicts. +- Event binding + - Bind events only when necessary (e.g., mouse and scroll events for Div/Markdown) to avoid excessive bindings that could increase frontend pressure. +- Memory management + - Components uniformly mark `layout=True` in `__exit__`, ensuring the frontend correctly releases and rebuilds; avoid holding long-lived references within the component tree. +- HTML sanitization + - `Markdown`'s `postprocess` sanitizes content, reducing rendering jitter and abnormal character issues. + +## Troubleshooting Guide + +- Missing Application root container + - Symptom: Warning indicating no Application component found. + - Resolution: Ensure all components are wrapped inside an Application. + - Reference: Warning message from `AppContext.assert_app`. + +- Slot not taking effect + - Symptom: Slot fails to be inserted into the target component. + - Resolution: Confirm the target component's `SLOTS` supports the slot name; verify that `params_mapping` is correctly configured. + +- Each context conflict + - Symptom: Attribute conflicts or overrides when iterating multiple components. + - Resolution: Use `as_item` for field filtering; use `context_value` for deep merge to inject uniformly if necessary. + +- AutoLoading not displaying + - Symptom: loading/error/render slots not showing. + - Resolution: Confirm that `generating`/`show_error`/`show_mask` state matches the slot naming. + +Section sources + +- [backend/modelscope_studio/utils/dev/app_context.py:16-20](file://backend/modelscope_studio/utils/dev/app_context.py#L16-L20) +- [docs/components/base/slot/README.md:1-17](file://docs/components/base/slot/README.md#L1-L17) +- [docs/components/base/each/README.md:16-22](file://docs/components/base/each/README.md#L16-L22) +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:15-46](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L15-L46) + +## Conclusion + +The base component library provides a unified application root container, layout and text components, conditional and loop rendering helper components, and a slot system. Through strict context constraints and frontend resource resolution mechanisms, it ensures stable operation of components within the Gradio ecosystem. It is recommended to use `Each`'s `as_item` and `context_value` for context management, choose `skip_api` components appropriately to reduce API overhead, and leverage Application's lifecycle events and custom events for page behavior control when needed. + +## Appendix: Usage Examples and Best Practices + +### Application Container and Page Environment + +- Wrap the outermost layer of the application with Application, and listen to page lifecycle events. +- Obtain user language, theme, screen information, and UA from Application's `value`. + +Section sources + +- [docs/components/base/application/README.md:12-20](file://docs/components/base/application/README.md#L12-L20) +- [backend/modelscope_studio/components/base/application/**init**.py:30-54](file://backend/modelscope_studio/components/base/application/__init__.py#L30-L54) + +### Conditional Rendering (Filter) + +- Use Filter with `params_mapping` to determine whether to render a subtree. +- Suitable for dynamically hiding/showing parts of the content based on context parameters. + +Section sources + +- [backend/modelscope_studio/components/base/filter/**init**.py:13-25](file://backend/modelscope_studio/components/base/filter/__init__.py#L13-L25) + +### List Iteration (Each) + +- Each accepts a list or callable, injects context; supports `as_item` and `context_value`. +- Suitable for rendering lists of unknown length and injecting uniform attributes. + +Section sources + +- [docs/components/base/each/README.md:7-22](file://docs/components/base/each/README.md#L7-L22) +- [backend/modelscope_studio/components/base/each/**init**.py:23-52](file://backend/modelscope_studio/components/base/each/__init__.py#L23-L52) + +### Slot System (Slot) + +- Slot works with the target component's `SLOTS`; `params_mapping` supports parameter mapping. +- Suitable for complex layouts and pluggable content areas. + +Section sources + +- [docs/components/base/slot/README.md:1-17](file://docs/components/base/slot/README.md#L1-L17) +- [backend/modelscope_studio/components/base/slot/**init**.py:13-30](file://backend/modelscope_studio/components/base/slot/__init__.py#L13-L30) + +### Auto Loading (AutoLoading) + +- Wrap areas that may take time to load; use render/errorRender/loadingText slots. +- Control mask, timer, and error display to improve user experience. + +Section sources + +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:17-46](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L17-L46) + +### Layout and Text Components + +- Div/Span: For basic block-level/inline layout; support various mouse and scroll events. +- Text/Markdown: Text rendering; Markdown supports copy buttons and LaTeX expression configuration. + +Section sources + +- [backend/modelscope_studio/components/base/div/**init**.py:44-67](file://backend/modelscope_studio/components/base/div/__init__.py#L44-L67) +- [backend/modelscope_studio/components/base/span/**init**.py:44-67](file://backend/modelscope_studio/components/base/span/__init__.py#L44-L67) +- [backend/modelscope_studio/components/base/text/**init**.py:17-37](file://backend/modelscope_studio/components/base/text/__init__.py#L17-L37) +- [backend/modelscope_studio/components/base/markdown/**init**.py:54-141](file://backend/modelscope_studio/components/base/markdown/__init__.py#L54-L141) + +### Component Inheritance and Extension Development + +- New components are recommended to inherit the appropriate base class: + - Requires data model and layout: `ModelScopeDataLayoutComponent` + - Layout only: `ModelScopeLayoutComponent` + - Pure component: `ModelScopeComponent` +- Set `FRONTEND_DIR` in the constructor to ensure frontend resources are correctly resolved. +- If slots are needed, define `SLOTS` and document the supported slot names and their purposes. + +Section sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) diff --git a/.wiki/en/API Reference/Python API/Pro Components API.md b/.wiki/en/API Reference/Python API/Pro Components API.md new file mode 100644 index 00000000..ea03c438 --- /dev/null +++ b/.wiki/en/API Reference/Python API/Pro Components API.md @@ -0,0 +1,487 @@ +# Pro Components API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/pro/__init__.py](file://backend/modelscope_studio/components/pro/__init__.py) +- [backend/modelscope_studio/components/pro/components.py](file://backend/modelscope_studio/components/pro/components.py) +- [backend/modelscope_studio/components/pro/chatbot/__init__.py](file://backend/modelscope_studio/components/pro/chatbot/__init__.py) +- [backend/modelscope_studio/components/pro/multimodal_input/__init__.py](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py) +- [backend/modelscope_studio/components/pro/web_sandbox/__init__.py](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py) +- [backend/modelscope_studio/components/pro/monaco_editor/__init__.py](file://backend/modelscope_studio/components/pro/monaco_editor/__init__.py) +- [backend/modelscope_studio/components/pro/monaco_editor/diff_editor/__init__.py](file://backend/modelscope_studio/components/pro/monaco_editor/diff_editor/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) +- [backend/modelscope_studio/utils/dev/process_links.py](file://backend/modelscope_studio/utils/dev/process_links.py) +- [docs/demos/example.py](file://docs/demos/example.py) +- [docs/layout_templates/chatbot/app.py](file://docs/layout_templates/chatbot/app.py) +- [docs/layout_templates/chatbot/demos/basic.py](file://docs/layout_templates/chatbot/demos/basic.py) +- [docs/components/pro/chatbot/demos/chatbot_config.py](file://docs/components/pro/chatbot/demos/chatbot_config.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is the Python API reference for the pro component library (`modelscope_studio.components.pro`), covering the following AI application-specific components: + +- **Chatbot**: Conversational message container and rendering component; supports user/assistant messages, welcome prompts, suggested prompts, tool calls, file content, and other rich capabilities. +- **MultimodalInput**: Multimodal input component; supports text and attachment uploads, paste, drag-and-drop, voice, and other input modalities. +- **WebSandbox**: Web sandbox component; renders React/HTML templates in an isolated environment; supports compile and render error events. +- **MonacoEditor**: Code editor component; supports language highlighting, read-only mode, option configuration, mount/change/validate events; provides a DiffEditor subclass. + +This document records import paths, constructor parameters, property definitions, method signatures, and return types for each component. It provides standard instantiation and usage examples for complex AI applications, covering advanced use cases such as chatbot integration, multimodal input handling, and web sandbox isolation. It also explains event binding, data flow processing strategies, frontend/backend data conversion logic, and performance and concurrency considerations. + +## Project Structure + +Pro components reside in the backend Python package `modelscope_studio/components/pro`, divided into four submodules by function: chatbot, multimodal_input, web_sandbox, and monaco_editor, with a unified export entry and alias exports. + +```mermaid +graph TB +subgraph "Python Backend" +PRO["pro/__init__.py
Unified Exports"] +COMP["pro/components.py
Alias Exports"] +CHAT["pro/chatbot/__init__.py"] +MMI["pro/multimodal_input/__init__.py"] +WS["pro/web_sandbox/__init__.py"] +ME["pro/monaco_editor/__init__.py"] +MED["pro/monaco_editor/diff_editor/__init__.py"] +end +subgraph "Common Base Classes" +DEV["utils/dev/component.py
ModelScope*Component Family"] +RES["utils/dev/resolve_frontend_dir.py"] +LNK["utils/dev/process_links.py"] +end +PRO --> CHAT +PRO --> MMI +PRO --> WS +PRO --> ME +ME --> MED +COMP --> CHAT +COMP --> MMI +COMP --> WS +COMP --> ME +COMP --> MED +CHAT --> DEV +MMI --> DEV +WS --> DEV +ME --> DEV +MED --> DEV +CHAT --> RES +MMI --> RES +WS --> RES +ME --> RES +MED --> RES +CHAT --> LNK +``` + +Diagram sources + +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:82-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L82-L259) +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:15-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L15-L86) +- [backend/modelscope_studio/components/pro/monaco_editor/**init**.py:16-107](file://backend/modelscope_studio/components/pro/monaco_editor/__init__.py#L16-L107) +- [backend/modelscope_studio/components/pro/monaco_editor/diff_editor/**init**.py:10-106](file://backend/modelscope_studio/components/pro/monaco_editor/diff_editor/__init__.py#L10-L106) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L17) +- [backend/modelscope_studio/utils/dev/process_links.py:9-61](file://backend/modelscope_studio/utils/dev/process_links.py#L9-L61) + +Section sources + +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) + +## Core Components + +This section provides an overview of the responsibilities and typical use cases for the four pro components: + +- **Chatbot**: Used to build conversational interfaces; manages message lists, welcome prompts, suggested prompts, action buttons, Markdown rendering, file/tool content, and more. +- **MultimodalInput**: Used to receive multimodal input with text and attachments; supports upload, paste, drag-and-drop, preview, download, and other workflows. +- **WebSandbox**: Used to render templates (React/HTML) in an isolated environment; captures compile and render error events. +- **MonacoEditor**: Used to embed a code editor in the browser; supports language, read-only, options, mount/change/validate events; provides DiffEditor for diff view. + +Section sources + +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:82-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L82-L259) +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:15-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L15-L86) +- [backend/modelscope_studio/components/pro/monaco_editor/**init**.py:16-107](file://backend/modelscope_studio/components/pro/monaco_editor/__init__.py#L16-L107) + +## Architecture Overview + +Pro components extend the Gradio component system through unified base classes and frontend directory resolution to bridge frontend and backend. Components set `FRONTEND_DIR` during initialization, pointing to the corresponding frontend Svelte component directory; `preprocess`/`postprocess` handles frontend/backend data conversion; `EVENTS`/`SLOTS` provide event and slot extension points. + +```mermaid +sequenceDiagram +participant Py as "Python Component" +participant Base as "ModelScope*Component Base Class" +participant FE as "Frontend Component (Svelte)" +participant App as "Gradio App" +App->>Py : Instantiate component (pass value/config) +Py->>Base : Call parent constructor (inherit Gradio Component) +Py->>Py : Set FRONTEND_DIR / data model / events / SLOTS +Py->>FE : Pass config and data during rendering +FE-->>Py : Trigger event callbacks (e.g. change/copy/edit/delete/like/retry/suggestion_select/welcome_prompt_select) +Py-->>App : Return processed value (possibly via postprocess) +``` + +Diagram sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L17) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:82-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L82-L259) +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:15-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L15-L86) +- [backend/modelscope_studio/components/pro/monaco_editor/**init**.py:16-107](file://backend/modelscope_studio/components/pro/monaco_editor/__init__.py#L16-L107) + +## Detailed Component Analysis + +### Chatbot Component + +- Import paths + - Main class: `modelscope_studio.components.pro.Chatbot` + - Alias: `modelscope_studio.components.pro.ProChatbot` +- Purpose + - Manages conversational message lists; supports user/assistant messages, welcome prompts, suggested prompts, action buttons, Markdown rendering, file/tool content, and more. +- Key data models + - `ChatbotWelcomeConfig`, `ChatbotPromptsConfig`, `ChatbotPromptConfig`, `ChatbotMarkdownConfig`, `ChatbotUserConfig`, `ChatbotBotConfig`, `ChatbotDataMessageContent`, `ChatbotDataMessage`, `ChatbotDataMessages`, `ChatbotDataMeta` +- Constructor parameter highlights + - `value`: Can be a callback or message list/dict; supports message status `pending`/`done`, separators, metadata feedback, etc. + - Height and scrolling: `height`, `min_height`, `max_height`, `auto_scroll`, `show_scroll_to_bottom_button`, `scroll_to_bottom_button_offset` + - Welcome and Markdown: `welcome_config`, `markdown_config` + - User/assistant styles and actions: `user_config`, `bot_config` (includes `actions`/`disabled_actions`, `avatar`, `typing`, etc.) + - Others: `elem_id`, `elem_classes`, `elem_style`, `visible`, `render`, etc. +- Methods and behavior + - `preprocess`: Normalizes file paths in message content for frontend display + - `postprocess`: Converts file paths to `FileData` structures; supports local and remote URLs + - Events: `change`, `copy`, `edit`, `delete`, `like`, `retry`, `suggestion_select`, `welcome_prompt_select` + - Slots: `role` +- Usage examples (reference) + - Basic chat template app entry: [docs/layout_templates/chatbot/app.py:1-7](file://docs/layout_templates/chatbot/app.py#L1-L7) + - Chat config and event demo: [docs/components/pro/chatbot/demos/chatbot_config.py:1-40](file://docs/components/pro/chatbot/demos/chatbot_config.py#L1-L40) + +```mermaid +classDiagram +class ModelScopeProChatbot { ++EVENTS ++SLOTS ++FRONTEND_DIR ++data_model ++__init__(...) ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class ChatbotWelcomeConfig +class ChatbotPromptsConfig +class ChatbotPromptConfig +class ChatbotMarkdownConfig +class ChatbotUserConfig +class ChatbotBotConfig +class ChatbotDataMessageContent +class ChatbotDataMessage +class ChatbotDataMessages +class ChatbotDataMeta +ModelScopeProChatbot --> ChatbotWelcomeConfig : "uses" +ModelScopeProChatbot --> ChatbotPromptsConfig : "uses" +ModelScopeProChatbot --> ChatbotMarkdownConfig : "uses" +ModelScopeProChatbot --> ChatbotUserConfig : "uses" +ModelScopeProChatbot --> ChatbotBotConfig : "uses" +ModelScopeProChatbot --> ChatbotDataMessageContent : "uses" +ModelScopeProChatbot --> ChatbotDataMessage : "uses" +ModelScopeProChatbot --> ChatbotDataMessages : "uses" +ModelScopeProChatbot --> ChatbotDataMeta : "uses" +``` + +Diagram sources + +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:14-285](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L14-L285) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) + +Section sources + +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:14-285](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L14-L285) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) +- [docs/layout_templates/chatbot/app.py:1-7](file://docs/layout_templates/chatbot/app.py#L1-L7) +- [docs/components/pro/chatbot/demos/chatbot_config.py:1-40](file://docs/components/pro/chatbot/demos/chatbot_config.py#L1-L40) + +### MultimodalInput Component + +- Import paths + - Main class: `modelscope_studio.components.pro.MultimodalInput` + - Alias: `modelscope_studio.components.pro.ProMultimodalInput` +- Purpose + - Accepts multimodal input with text and attachments; supports upload, paste, drag-and-drop, preview, download, and other workflows. +- Key data models + - `MultimodalInputUploadConfig`: Upload behavior and UI configuration + - `MultimodalInputValue`: Input value containing `files` and `text` +- Constructor parameter highlights + - `value`: `MultimodalInputValue` or its dict form + - Mode and size: `mode`, `auto_size`, `footer`/`header`/`prefix`/`suffix`, `placeholder`, `submit_type` + - Upload config: `upload_config` (includes `fullscreen_drop`, `allow_upload`, `allow_paste_file`, `allow_speech`, `max_count`, `directory`, `multiple`, `overflow`, `title`, `image_props`, `placeholder`, etc.) + - Style and state: `disabled`, `read_only`, `loading`, `class_names`, `styles`, `root_class_name` + - Others: `elem_id`, `elem_classes`, `elem_style`, `visible`, `render`, etc. +- Methods and behavior + - `preprocess`: Converts uploaded files to cacheable named strings for subsequent processing + - `postprocess`: Downloads remote URLs to local cache and wraps them as `FileData` lists + - Events: `change`, `submit`, `cancel`, `key_down`/`key_press`, `focus`, `blur`, `upload`, `paste`, `paste_file`, `skill_closable_close`, `drop`, `download`, `preview`, `remove` + - Slots: `suffix`, `header`, `prefix`, `footer`, `skill.title`, `skill.toolTip.title`, `skill.closable.closeIcon` +- Usage examples (reference) + - Example app entry: [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) + +```mermaid +classDiagram +class ModelScopeProMultimodalInput { ++EVENTS ++SLOTS ++FRONTEND_DIR ++data_model ++__init__(...) ++preprocess(payload) ++postprocess(value) ++_process_single_file(f) ++_download_files(value) ++skip_api ++example_payload() ++example_value() +} +class MultimodalInputUploadConfig +class MultimodalInputValue +ModelScopeProMultimodalInput --> MultimodalInputUploadConfig : "uses" +ModelScopeProMultimodalInput --> MultimodalInputValue : "uses" +``` + +Diagram sources + +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:18-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L18-L259) +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:82-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L82-L259) + +Section sources + +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:18-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L18-L259) +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:82-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L82-L259) +- [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) + +### WebSandbox Component + +- Import paths + - Main class: `modelscope_studio.components.pro.WebSandbox` + - Alias: `modelscope_studio.components.pro.ProWebSandbox` +- Purpose + - Renders React/HTML templates in an isolated environment; supports compile and render error event monitoring. +- Key data models + - `SandboxFileData`: Template file structure (code, is_entry) +- Constructor parameter highlights + - `value`: dict where keys are file names and values are strings or `SandboxFileData` + - Template type: `template` (`'react'` | `'html'`) + - Error display: `show_render_error`, `show_compile_error`, `compile_error_render` + - External dependencies: `imports` (module mapping) + - Size: `height` + - Others: `elem_id`, `elem_classes`, `elem_style`, `visible`, `render`, etc. +- Methods and behavior + - `preprocess`/`postprocess`: Direct pass-through (`skip_api=True`) + - Events: `compile_success`, `compile_error`, `render_error`, `custom` + - Slots: `compileErrorRender` +- Usage examples (reference) + - Example app entry: [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) + +```mermaid +classDiagram +class ModelScopeProWebSandbox { ++EVENTS ++SLOTS ++FRONTEND_DIR ++__init__(...) ++preprocess(payload) ++postprocess(value) ++skip_api ++example_payload() ++example_value() +} +class SandboxFileData +ModelScopeProWebSandbox --> SandboxFileData : "uses" +``` + +Diagram sources + +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:10-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L10-L86) +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:15-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L15-L86) + +Section sources + +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:10-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L10-L86) +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:15-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L15-L86) +- [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) + +### MonacoEditor Component + +- Import paths + - Main class: `modelscope_studio.components.pro.MonacoEditor` + - Alias: `modelscope_studio.components.pro.ProMonacoEditor` + - DiffEditor: `modelscope_studio.components.pro.MonacoEditorDiffEditor` (as a subclass) +- Purpose + - Provides a code editor with language, read-only, options, mount/change/validate events; DiffEditor provides a diff view. +- Constructor parameter highlights + - `value`: Initial editing content + - Language and read-only: `language`, `read_only` + - Lifecycle hooks: `before_mount`, `after_mount` + - Service overrides: `override_services` + - Loading text: `loading` + - Editor options: `options` + - Line positioning: `line` + - Size: `height` + - Others: `elem_id`, `elem_classes`, `elem_style`, `visible`, `render`, etc. +- Methods and behavior + - `preprocess`/`postprocess`: Direct pass-through (`skip_api=False`) + - Events: `mount`, `change`, `validate` + - Slots: `loading` + - DiffEditor: Shares loader configuration with the main editor; supports `original`/`original_language`/`modified_language` +- Usage examples (reference) + - Example app entry: [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) + +```mermaid +classDiagram +class ModelScopeProMonacoEditor { ++EVENTS ++SLOTS ++LOADER ++FRONTEND_DIR ++__init__(...) ++preprocess(payload) ++postprocess(value) ++api_info() ++skip_api ++example_payload() ++example_value() +} +class ModelScopeProMonacoEditorDiffEditor { ++EVENTS ++SLOTS ++FRONTEND_DIR ++__init__(...) ++preprocess(payload) ++postprocess(value) ++api_info() ++skip_api ++example_payload() ++example_value() +} +ModelScopeProMonacoEditor <|-- ModelScopeProMonacoEditorDiffEditor : "subclass" +``` + +Diagram sources + +- [backend/modelscope_studio/components/pro/monaco_editor/**init**.py:16-107](file://backend/modelscope_studio/components/pro/monaco_editor/__init__.py#L16-L107) +- [backend/modelscope_studio/components/pro/monaco_editor/diff_editor/**init**.py:10-106](file://backend/modelscope_studio/components/pro/monaco_editor/diff_editor/__init__.py#L10-L106) + +Section sources + +- [backend/modelscope_studio/components/pro/monaco_editor/**init**.py:16-107](file://backend/modelscope_studio/components/pro/monaco_editor/__init__.py#L16-L107) +- [backend/modelscope_studio/components/pro/monaco_editor/diff_editor/**init**.py:10-106](file://backend/modelscope_studio/components/pro/monaco_editor/diff_editor/__init__.py#L10-L106) +- [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) + +## Dependency Analysis + +- Component base classes + - `ModelScopeLayoutComponent`: Layout component base class; suitable for container components that do not need data transfer (e.g., WebSandbox) + - `ModelScopeComponent`: Basic component base class; suitable for data-driven components (e.g., Chatbot/MultimodalInput/MonacoEditor) + - `ModelScopeDataLayoutComponent`: Combines data and layout capabilities; suitable for components that require frontend/backend data exchange (e.g., Chatbot/MultimodalInput/MonacoEditor) +- Frontend directory resolution + - `resolve_frontend_dir`: Generates relative paths based on component name and type (pro/antd/antdx/base) to ensure frontend resources load correctly +- Data link processing + - `process_links`: Converts links in HTML/Markdown, transforming local files into accessible cache URLs + +```mermaid +graph LR +A["ModelScopeLayoutComponent"] --> C["WebSandbox"] +B["ModelScopeComponent"] --> D["Chatbot"] +B --> E["MultimodalInput"] +B --> F["MonacoEditor"] +G["ModelScopeDataLayoutComponent"] --> D +G --> E +G --> F +H["resolve_frontend_dir"] --> C +H --> D +H --> E +H --> F +I["process_links"] --> D +``` + +Diagram sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L17) +- [backend/modelscope_studio/utils/dev/process_links.py:9-61](file://backend/modelscope_studio/utils/dev/process_links.py#L9-L61) + +Section sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L17) +- [backend/modelscope_studio/utils/dev/process_links.py:9-61](file://backend/modelscope_studio/utils/dev/process_links.py#L9-L61) + +## Performance Considerations + +- Data serialization and transmission + - Chatbot/MultimodalInput/MonacoEditor are data-driven components; `preprocess`/`postprocess` handles file path and `FileData` conversions, avoiding memory pressure from processing large files directly in the frontend. +- Frontend resource loading + - MonacoEditor supports local or CDN loader configuration; choosing appropriately can reduce initial load time; DiffEditor reuses the main editor's loader configuration. +- Event binding and updates + - Components dynamically bind events via `_internal.update`, avoiding unnecessary re-renders; WebSandbox's `skip_api=True` reduces API layer overhead. +- File processing + - MultimodalInput downloads remote URLs to the cache directory in `postprocess`, avoiding repeated network requests; `process_links` converts local resources to cache URLs, improving stability and performance. + +## Troubleshooting Guide + +- Editor loading failure + - Check MonacoEditor's `LOADER` configuration (mode/local/cdn); verify CDN reachability or switch to local loading. + - Check whether mount/change/validate events are triggered to locate the problem stage. +- Files cannot be displayed or download anomalies + - Chatbot's file content is converted to `FileData` in `postprocess`; check whether the path is a local file or a valid URL. + - MultimodalInput's `postprocess` downloads remote URLs to cache; verify cache directory permissions and network reachability. +- Sandbox compile/render errors + - WebSandbox provides `compile_error`/`render_error` events; combine with the `compileErrorRender` slot to locate errors. +- Broken links + - Use `process_links` to convert links in HTML/Markdown, ensuring local resources are correctly cached and accessible. + +Section sources + +- [backend/modelscope_studio/components/pro/monaco_editor/**init**.py:44-107](file://backend/modelscope_studio/components/pro/monaco_editor/__init__.py#L44-L107) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:475-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L475-L495) +- [backend/modelscope_studio/components/pro/multimodal_input/**init**.py:233-259](file://backend/modelscope_studio/components/pro/multimodal_input/__init__.py#L233-L259) +- [backend/modelscope_studio/components/pro/web_sandbox/**init**.py:19-86](file://backend/modelscope_studio/components/pro/web_sandbox/__init__.py#L19-L86) +- [backend/modelscope_studio/utils/dev/process_links.py:9-61](file://backend/modelscope_studio/utils/dev/process_links.py#L9-L61) + +## Conclusion + +The pro component library, centered around conversation, multimodal input, web sandbox, and code editing, provides a complete Python API and frontend integration solution. Through a unified base class system, flexible event and slot mechanisms, and comprehensive frontend/backend data conversion, it meets the development requirements of complex AI applications. It is recommended to combine examples and best practices in real projects, and to configure loaders, events, and data flows appropriately for a stable and high-performance user experience. + +## Appendix + +- Unified exports and aliases + - Main module exports: `Chatbot`, `MonacoEditor`, `MonacoEditorDiffEditor`, `MultimodalInput`, `WebSandbox` + - Alias exports: `ProChatbot`, `ProMonacoEditor`, `ProMonacoEditorDiffEditor`, `ProMultimodalInput`, `ProWebSandbox` +- Example entries + - Basic example: [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) + - Chat template app: [docs/layout_templates/chatbot/app.py:1-7](file://docs/layout_templates/chatbot/app.py#L1-L7) + - Chat config and event demo: [docs/components/pro/chatbot/demos/chatbot_config.py:1-40](file://docs/components/pro/chatbot/demos/chatbot_config.py#L1-L40) + +Section sources + +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [docs/demos/example.py:1-11](file://docs/demos/example.py#L1-L11) +- [docs/layout_templates/chatbot/app.py:1-7](file://docs/layout_templates/chatbot/app.py#L1-L7) +- [docs/components/pro/chatbot/demos/chatbot_config.py:1-40](file://docs/components/pro/chatbot/demos/chatbot_config.py#L1-L40) diff --git a/.wiki/en/API Reference/Python API/Python API.md b/.wiki/en/API Reference/Python API/Python API.md new file mode 100644 index 00000000..76686c9f --- /dev/null +++ b/.wiki/en/API Reference/Python API/Python API.md @@ -0,0 +1,433 @@ +# Python API + + +**Files Referenced in This Document** +- [backend/modelscope_studio/__init__.py](file://backend/modelscope_studio/__init__.py) +- [backend/modelscope_studio/components/__init__.py](file://backend/modelscope_studio/components/__init__.py) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/components/pro/__init__.py](file://backend/modelscope_studio/components/pro/__init__.py) +- [backend/modelscope_studio/components/pro/components.py](file://backend/modelscope_studio/components/pro/components.py) +- [backend/modelscope_studio/components/antd/button/__init__.py](file://backend/modelscope_studio/components/antd/button/__init__.py) +- [backend/modelscope_studio/components/antd/form/__init__.py](file://backend/modelscope_studio/components/antd/form/__init__.py) +- [backend/modelscope_studio/components/base/application/__init__.py](file://backend/modelscope_studio/components/base/application/__init__.py) +- [backend/modelscope_studio/components/pro/chatbot/__init__.py](file://backend/modelscope_studio/components/pro/chatbot/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: API Index and Usage Examples](#appendix-api-index-and-usage-examples) + +## Introduction + +This document is the Python API reference for ModelScope Studio, focusing on the component system and calling conventions of the backend Python package `modelscope_studio`. The document covers: + +- Component import paths and named export conventions (`modelscope_studio.components.antd.*`, `modelscope_studio.components.antdx.*`, `modelscope_studio.components.base.*`, `modelscope_studio.components.pro.*`) +- Constructor parameters, supported events, slots, data models, and preprocess/postprocess flows for key component classes +- Standard instantiation examples (basic usage and advanced configuration), and lifecycle and state management essentials +- Parameter validation and exception handling mechanism notes +- Version compatibility information and common issue troubleshooting + +## Project Structure + +The Python package is located at `backend/modelscope_studio`; the top level aggregates sub-modules via `__all__` exports; components are organized hierarchically in four sub-packages: `antd`, `antdx`, `base`, and `pro`. Each sub-package provides both `__init__.py` and `components.py` entries for different aggregation strategies. + +```mermaid +graph TB +A["backend/modelscope_studio/__init__.py"] --> B["backend/modelscope_studio/components/__init__.py"] +B --> C["antd Sub-Package"] +B --> D["antdx Sub-Package"] +B --> E["base Sub-Package"] +B --> F["pro Sub-Package"] +C --> C1["antd/__init__.py
Named exports of component classes"] +D --> D1["antdx/__init__.py
Named exports of component classes"] +E --> E1["base/__init__.py
Named exports of base component classes"] +F --> F1["pro/__init__.py
Named exports of pro component classes"] +``` + +**Diagram Sources** + +- [backend/modelscope_studio/**init**.py:1-3](file://backend/modelscope_studio/__init__.py#L1-L3) +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) + +**Section Sources** + +- [backend/modelscope_studio/**init**.py:1-3](file://backend/modelscope_studio/__init__.py#L1-L3) +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) + +## Core Components + +This section provides an overview of import paths and named exports for the four component families, and explains the responsibility boundaries and typical use cases of each family. + +- `modelscope_studio.components.antd.*` + - Responsibility: Python wrappers for the Ant Design component ecosystem, covering common UI components for layout, forms, feedback, navigation, and data entry. + - Typical components: Button, Form, Input, Select, Table, Modal, Message, Notification, etc. + - Import: `from modelscope_studio.components.antd import Button, Form, ...` + - Named exports: See [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) and [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) + +- `modelscope_studio.components.antdx.*` + - Responsibility: Ant Design X extended component set, designed for conversational interaction and knowledge work scenarios (e.g., message bubbles, conversation lists, prompt panels, etc.). + - Typical components: Bubble, Conversations, Prompts, Sender, ThoughtChain, Welcome, etc. + - Import: `from modelscope_studio.components.antdx import Bubble, Conversations, ...` + - Named exports: See [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) and [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +- `modelscope_studio.components.base.*` + - Responsibility: Base layout and container components providing general capabilities such as application-level containers, loop rendering, conditional filtering, placeholder text, etc. + - Typical components: Application, Each, Filter, Fragment, Markdown, Slot, Text, Div, etc. + - Import: `from modelscope_studio.components.base import Application, Each, ...` + - Named exports: See [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +- `modelscope_studio.components.pro.*` + - Responsibility: Professional domain components designed for specific business scenarios (e.g., chatbot, code editor, multimodal input, web sandbox, etc.). + - Typical components: Chatbot, MonacoEditor, MultimodalInput, WebSandbox. + - Import: `from modelscope_studio.components.pro import Chatbot, MonacoEditor, ...` + - Named exports: See [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) and [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) + +## Architecture Overview + +The diagram below shows the relationship between Python layer component classes and frontend directory resolution, and the key nodes of event binding and data flow. + +```mermaid +graph TB +subgraph "Python Layer" +P1["AntdButton.__init__()
Constructor params & event binding"] +P2["AntdForm.__init__()
Form config & event binding"] +P3["ModelScopeApplication.__init__()
App context & event binding"] +P4["ModelScopeProChatbot.__init__()
Message config & static resource handling"] +end +subgraph "Frontend Directory Resolution" +F1["resolve_frontend_dir('button')"] +F2["resolve_frontend_dir('form')"] +F3["resolve_frontend_dir('application', type='base')"] +F4["resolve_frontend_dir('chatbot', type='pro')"] +end +P1 --> F1 +P2 --> F2 +P3 --> F3 +P4 --> F4 +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) + +## Detailed Component Analysis + +### Component: AntdButton + +- Import Path: `from modelscope_studio.components.antd import Button` +- Purpose: Wraps the Ant Design button, supporting multiple types, sizes, shapes, loading state, danger state, ghost state, etc. +- Key Points: + - Supported events: `click` + - Slots: `icon`, `loading.icon` + - Preprocess/postprocess: Simple string-to-string conversion + - Frontend directory: `resolve_frontend_dir("button")` + +```mermaid +classDiagram +class AntdButton { ++Constructor params(...) ++EVENTS ++SLOTS ++FRONTEND_DIR ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) + +### Component: AntdForm and AntdFormItem + +- Import Path: `from modelscope_studio.components.antd import Form, Form.Item` +- Purpose: Wraps the Ant Design form, supporting events for field changes, submit, failure, value changes, etc., as well as form item rules and providers. +- Key Points: + - Supported events: `fields_change`, `finish`, `finish_failed`, `values_change` + - Data model: `AntdFormData` + - Preprocess/postprocess: Extracts the `root` field from the data model or passes through as-is + - Frontend directory: `resolve_frontend_dir("form")` + +```mermaid +classDiagram +class AntdForm { ++Item ++Provider ++data_model ++EVENTS ++FRONTEND_DIR ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdFormItem { ++Constructor params(...) ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdFormProvider { ++Constructor params(...) ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdFormData { ++root +} +AntdForm --> AntdFormItem : "Contains" +AntdForm --> AntdFormProvider : "Contains" +AntdForm --> AntdFormData : "Uses" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) + +### Component: ModelScopeApplication + +- Import Path: `from modelscope_studio.components.base import Application` +- Purpose: Application-level container providing page environment data (screen size, theme, language, etc.) and lifecycle events (mount, resize, unmount, custom). +- Key Points: + - Supported events: `custom`, `mount`, `resize`, `unmount` + - Data model: `ApplicationPageData` + - Preprocess/postprocess: Pass-through + - Frontend directory: `resolve_frontend_dir("application", type="base")` + +```mermaid +classDiagram +class ModelScopeApplication { ++EVENTS ++data_model ++FRONTEND_DIR ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class ApplicationPageData { ++screen ++language ++theme ++userAgent +} +ModelScopeApplication --> ApplicationPageData : "Uses" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) + +**Section Sources** + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) + +### Component: ModelScopeProChatbot + +- Import Path: `from modelscope_studio.components.pro import Chatbot` +- Purpose: Professional chatbot component supporting rich configurations including welcome messages, prompts, user/assistant messages, action buttons, file/tool/suggestion content, etc. +- Key Points: + - Supported events: `change`, `copy`, `edit`, `delete`, `like`, `retry`, `suggestion_select`, `welcome_prompt_select` + - Data model: `ChatbotDataMessages` (root is a message list) + - Preprocess/postprocess: Typed processing of message content (file to FileData, static resource path handling) + - Frontend directory: `resolve_frontend_dir("chatbot", type="pro")` + +```mermaid +classDiagram +class ModelScopeProChatbot { ++EVENTS ++data_model ++FRONTEND_DIR ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class ChatbotDataMessages { ++root +} +class ChatbotDataMessage { ++role ++status ++content ++meta +} +ModelScopeProChatbot --> ChatbotDataMessages : "Uses" +ChatbotDataMessages --> ChatbotDataMessage : "Contains" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) + +**Section Sources** + +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:286-495](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L286-L495) + +## Dependency Analysis + +- Component classes generally inherit from `ModelScopeDataLayoutComponent` or `ModelScopeLayoutComponent`, unifying the frontend directory resolution and event binding mechanism. +- The event system is based on `gradio.events.EventListener`, injecting event binding flags into the internal update logic via callbacks. +- Data models mostly adopt `GradioRootModel`/`GradioModel` for consistent data structures and serialization between frontend and backend. + +```mermaid +graph LR +A["AntdButton"] --> B["ModelScopeLayoutComponent"] +C["AntdForm"] --> D["ModelScopeDataLayoutComponent"] +E["ModelScopeApplication"] --> D +F["ModelScopeProChatbot"] --> D +B --> G["resolve_frontend_dir(...)"] +D --> G +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antd/button/**init**.py:7-8](file://backend/modelscope_studio/components/antd/button/__init__.py#L7-L8) +- [backend/modelscope_studio/components/antd/form/**init**.py:8-9](file://backend/modelscope_studio/components/antd/form/__init__.py#L8-L9) +- [backend/modelscope_studio/components/base/application/**init**.py:8-9](file://backend/modelscope_studio/components/base/application/__init__.py#L8-L9) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:11](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L11) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/button/**init**.py:7-8](file://backend/modelscope_studio/components/antd/button/__init__.py#L7-L8) +- [backend/modelscope_studio/components/antd/form/**init**.py:8-9](file://backend/modelscope_studio/components/antd/form/__init__.py#L8-L9) +- [backend/modelscope_studio/components/base/application/**init**.py:8-9](file://backend/modelscope_studio/components/base/application/__init__.py#L8-L9) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:11](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L11) + +## Performance Considerations + +- Keep component preprocess/postprocess lightweight; avoid heavy computations in the Python layer. +- For large file content (e.g., file messages in the chatbot), it is recommended to perform minimal wrapping during postprocessing (e.g., retaining only necessary metadata) to reduce transmission overhead. +- Set component height and scrolling behavior appropriately to avoid unnecessary reflow and repaints. + +## Troubleshooting Guide + +- Event Not Triggered + - Check that event listeners are correctly registered (e.g., Button's `click`, Form's `finish`), and confirm that the callback has injected the binding flag. + - Reference: [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46), [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) +- Frontend Directory Resolution Failure + - Confirm that the path returned by `resolve_frontend_dir` exists and is accessible. + - Reference: [backend/modelscope_studio/components/antd/button/**init**.py:139](file://backend/modelscope_studio/components/antd/button/__init__.py#L139), [backend/modelscope_studio/components/antd/form/**init**.py:114](file://backend/modelscope_studio/components/antd/form/__init__.py#L114) +- Data Model Mismatch + - Use `data_model` for preprocess/postprocess to ensure the payload/value structure is consistent with the model. + - Reference: [backend/modelscope_studio/components/antd/form/**init**.py:13-14](file://backend/modelscope_studio/components/antd/form/__init__.py#L13-L14), [backend/modelscope_studio/components/pro/chatbot/**init**.py:388](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L388) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) +- [backend/modelscope_studio/components/antd/form/**init**.py:13-14](file://backend/modelscope_studio/components/antd/form/__init__.py#L13-L14) +- [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) +- [backend/modelscope_studio/components/antd/button/**init**.py:139](file://backend/modelscope_studio/components/antd/button/__init__.py#L139) +- [backend/modelscope_studio/components/antd/form/**init**.py:114](file://backend/modelscope_studio/components/antd/form/__init__.py#L114) +- [backend/modelscope_studio/components/pro/chatbot/**init**.py:388](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L388) + +## Conclusion + +ModelScope Studio's Python API, with its clear component family divisions and unified event/data model design, provides a complete component system from basic layout to professional domains. Through clearly defined import paths and named exports, developers can quickly locate and use the components they need; meanwhile, the event binding and data preprocess/postprocess mechanisms ensure consistency and extensibility of frontend-backend collaboration. + +## Appendix: API Index and Usage Examples + +### API Index (by Component Family) + +- `modelscope_studio.components.antd.*` + - Button: `from modelscope_studio.components.antd import Button` + - Form: `from modelscope_studio.components.antd import Form` + - Form.Item: `from modelscope_studio.components.antd import Form.Item` + - More components: See [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) + +- `modelscope_studio.components.antdx.*` + - Actions, Bubble, Conversations, Prompts, Sender, ThoughtChain, Welcome, etc. + - Import example: `from modelscope_studio.components.antdx import Bubble, Conversations` + - See [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) + +- `modelscope_studio.components.base.*` + - Application, Each, Filter, Fragment, Markdown, Slot, Text, Div, etc. + - Import example: `from modelscope_studio.components.base import Application` + - See [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +- `modelscope_studio.components.pro.*` + - Chatbot, MonacoEditor, MultimodalInput, WebSandbox, etc. + - Import example: `from modelscope_studio.components.pro import Chatbot` + - See [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) + +### Usage Examples (Path References) + +- Basic Button (AntdButton) + - Example path: [backend/modelscope_studio/components/antd/button/**init**.py:51-87](file://backend/modelscope_studio/components/antd/button/__init__.py#L51-L87) +- Form (AntdForm) and Form Item (AntdFormItem) + - Example path: [backend/modelscope_studio/components/antd/form/**init**.py:43-80](file://backend/modelscope_studio/components/antd/form/__init__.py#L43-L80) +- Application Container (ModelScopeApplication) + - Example path: [backend/modelscope_studio/components/base/application/**init**.py:59-71](file://backend/modelscope_studio/components/base/application/__init__.py#L59-L71) +- Chatbot (ModelScopeProChatbot) + - Example path: [backend/modelscope_studio/components/pro/chatbot/**init**.py:319-343](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L319-L343) + +### Lifecycle and Event Callbacks + +- AntdButton + - Events: `click` + - Slots: `icon`, `loading.icon` + - Reference: [backend/modelscope_studio/components/antd/button/**init**.py:41-49](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L49) +- AntdForm + - Events: `fields_change`, `finish`, `finish_failed`, `values_change` + - Data model: `AntdFormData` + - Reference: [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) +- ModelScopeApplication + - Events: `custom`, `mount`, `resize`, `unmount` + - Data model: `ApplicationPageData` + - Reference: [backend/modelscope_studio/components/base/application/**init**.py:30-54](file://backend/modelscope_studio/components/base/application/__init__.py#L30-L54) +- ModelScopeProChatbot + - Events: `change`, `copy`, `edit`, `delete`, `like`, `retry`, `suggestion_select`, `welcome_prompt_select` + - Data model: `ChatbotDataMessages` + - Reference: [backend/modelscope_studio/components/pro/chatbot/**init**.py:289-314](file://backend/modelscope_studio/components/pro/chatbot/__init__.py#L289-L314) + +### Parameter Validation and Exception Handling + +- Parameter Validation + - Constructor parameters are mostly optional or have default values; type annotations cover common enums and dictionary structures. + - Reference: [backend/modelscope_studio/components/antd/button/**init**.py:51-87](file://backend/modelscope_studio/components/antd/button/__init__.py#L51-L87), [backend/modelscope_studio/components/antd/form/**init**.py:43-80](file://backend/modelscope_studio/components/antd/form/__init__.py#L43-L80) +- Exception Handling + - It is recommended to catch exceptions in event callbacks at the business layer and log the error context. + - When frontend directory resolution fails, check whether the path returned by `resolve_frontend_dir` exists. + +### Version Compatibility + +- Current version: 2.0.0-beta.1 + - Reference: [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) diff --git a/.wiki/en/Ant Design Components/Ant Design Components.md b/.wiki/en/Ant Design Components/Ant Design Components.md new file mode 100644 index 00000000..4b73b6df --- /dev/null +++ b/.wiki/en/Ant Design Components/Ant Design Components.md @@ -0,0 +1,531 @@ +# Ant Design Components + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [frontend/antd/package.json](file://frontend/antd/package.json) +- [frontend/antdx/package.json](file://frontend/antdx/package.json) +- [docs/app.py](file://docs/app.py) +- [docs/helper/Docs.py](file://docs/helper/Docs.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [README-zh_CN.md](file://README-zh_CN.md) +- [.changeset/pink-sails-itch.md](file://.changeset/pink-sails-itch.md) +- [.changeset/eleven-aliens-sell.md](file://.changeset/eleven-aliens-sell.md) +- [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py) +- [backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py](file://backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py) +- [backend/modelscope_studio/components/antdx/sender/header/__init__.py](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py) + + +## Update Summary + +**Changes made** + +- Updated version information reflecting major upgrades from Gradio 5.x to 6.0, Ant Design 5.x to 6.0, and Ant Design X 1.x to 2.0 +- Added complete feature introduction for Ant Design X component library, including new components like ThoughtChain, Folder, Sender, etc. +- Expanded component classification with new component groups and feature descriptions +- Updated architecture documentation to reflect the new component organization structure + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Ant Design X Component Library](#ant-design-x-component-library) +7. [Dependency Analysis](#dependency-analysis) +8. [Performance Considerations](#performance-considerations) +9. [Troubleshooting Guide](#troubleshooting-guide) +10. [Conclusion](#conclusion) +11. [Appendix](#appendix) + +## Introduction + +This document covers the Ant Design component library in ModelScope Studio, systematically organizing component classifications, features, and usage methods across six major categories: General Components, Layout Components, Navigation Components, Data Entry Components, Data Display Components, and Feedback Components. With the major upgrades to Gradio 6.0, Ant Design 6.0, and Ant Design X 2.0, the component library now supports richer interaction capabilities and a more modern design system. The documentation also provides property descriptions, event handling, style customization, responsive and internationalization support, performance optimization, and best practices, along with rich examples and scenario-based explanations to help developers get started quickly and achieve high-quality implementations. + +## Project Structure + +ModelScope Studio exports Ant Design components as a Python package and bridges them to Ant Design React components through frontend Svelte packages, forming a dual-layer architecture of "Python layer component definition + frontend rendering bridge". It now also integrates the Ant Design X component library, providing richer interactive components. The documentation site aggregates documentation and examples for each component through a unified entry point for easy browsing and comparison. + +```mermaid +graph TB +subgraph "Backend Python" +A["backend/modelscope_studio/components/antd/__init__.py
Export all Ant Design component classes"] +B["backend/modelscope_studio/components/antd/components.py
Centralized import and export"] +C["backend/modelscope_studio/components/antdx/__init__.py
Export all Ant Design X component classes"] +D["backend/modelscope_studio/components/antdx/components.py
Centralized import and export"] +E["backend/modelscope_studio/utils/dev/component.py
Component base class and context"] +end +subgraph "Frontend Svelte" +F["frontend/antd/package.json
Ant Design package metadata"] +G["frontend/antdx/package.json
Ant Design X package metadata"] +H["frontend/antd/button/Index.svelte
Button component bridge example"] +end +subgraph "Documentation and Site" +I["docs/app.py
Component classification and menu generation"] +J["docs/helper/Docs.py
Documentation parsing and example rendering"] +end +A --> H +C --> H +B --> H +D --> H +E --> A +F --> H +G --> H +I --> J +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-147](file://backend/modelscope_studio/components/antd/components.py#L1-L147) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/utils/dev/component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [docs/app.py:19-438](file://docs/app.py#L19-L438) +- [docs/helper/Docs.py:12-178](file://docs/helper/Docs.py#L12-L178) + +**Section Source** + +- [docs/app.py:19-438](file://docs/app.py#L19-L438) +- [docs/helper/Docs.py:12-178](file://docs/helper/Docs.py#L12-L178) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-147](file://backend/modelscope_studio/components/antd/components.py#L1-L147) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/utils/dev/component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + +## Core Components + +- Component Export and Naming: The backend uniformly exports Ant Design component classes through **init**.py and components.py, now including Ant Design X components, facilitating on-demand import and batch usage. +- Component Base Classes: ModelScopeComponent/ModelScopeLayoutComponent/ModelScopeDataLayoutComponent provide unified visibility, element ID, class name, inline style, slot, and lifecycle behaviors. +- Frontend Bridge: Svelte components dynamically load Ant Design React components through importComponent, uniformly handling props, slots, and style injection. +- Version Upgrade: Upgraded from Gradio 5.x to 6.0, supporting a more powerful event system and component lifecycle management. + +**Section Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-147](file://backend/modelscope_studio/components/antd/components.py#L1-L147) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/utils/dev/component.py:54-169](file://backend/modelscope_studio/utils/dev/component.py#L54-L169) +- [frontend/antd/button/Index.svelte:10-74](file://frontend/antd/button/Index.svelte#L10-L74) + +## Architecture Overview + +The diagram below shows the key flow from Python component invocation to frontend rendering, and how the documentation site organizes and presents component examples. It now includes support for Ant Design X components. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Py as "Python Component Layer
antd/__init__.py + antdx/__init__.py" +participant Bridge as "Svelte Bridge Layer
Index.svelte" +participant Antd as "Ant Design React Component" +participant Antdx as "Ant Design X Component" +participant Docs as "Documentation Site
docs/app.py + Docs" +Dev->>Py : Import and instantiate component +Py->>Bridge : Pass component properties and slots +Bridge->>Bridge : processProps/className/id/style processing +Bridge->>Antd : Dynamically load and render Ant Design component +Bridge->>Antdx : Dynamically load and render Ant Design X component +Antd-->>Dev : Render result +Antdx-->>Dev : Render result +Docs->>Py : Aggregate component documentation and examples +Docs->>Bridge : Render examples and code blocks +``` + +**Diagram Source** + +- [docs/app.py:19-438](file://docs/app.py#L19-L438) +- [docs/helper/Docs.py:82-178](file://docs/helper/Docs.py#L82-L178) +- [frontend/antd/button/Index.svelte:24-74](file://frontend/antd/button/Index.svelte#L24-L74) + +## Component Details + +### General Components + +- Button: Supports link navigation, icons, sizes, and theme variants; controls target behavior through href_target; supports slots and style customization. +- FloatButton: Supports back-to-top, grouping, and icons; can combine multiple floating actions. +- Icon: Supports icon font providers; can be used with other components. +- Typography: Supports semantic typography elements like headings, text, paragraphs, and links. + +Usage Tips + +- Property Mapping: The frontend uniformly passes through visible, elem_id, elem_classes, elem_style, value, etc. through processProps. +- Slots: The Svelte side gets the default slot through getSlots for rendering child nodes. +- Example: The button component bridge example demonstrates dynamic loading and style concatenation. + +**Section Source** + +- [frontend/antd/button/Index.svelte:24-74](file://frontend/antd/button/Index.svelte#L24-L74) +- [docs/app.py:198-209](file://docs/app.py#L198-L209) + +### Layout Components + +- Divider: Supports horizontal/vertical and dashed styles. +- Flex: Provides flexible flex container capabilities. +- Grid: Row and Col support responsive breakpoints and gutters. +- Layout: Contains Header, Sider, Content, Footer subcomponents, suitable for building page skeletons. +- Space: Supports compact mode and wrapping child items. +- Splitter: Supports panels and drag splitting. +- Masonry: Supports responsive column count and automatic item height adjustment. + +Usage Tips + +- Responsive: Grid and Flex provide multi-breakpoint configurations for mobile and desktop adaptation. +- Styling: elem_style can be applied directly to containers for positioning, dimensions, and margin control. + +**Section Source** + +- [docs/app.py:216-233](file://docs/app.py#L216-L233) + +### Navigation Components + +- Anchor: Supports scroll positioning and anchor items. +- Breadcrumb: Supports custom separators and route items. +- Dropdown: Supports button dropdowns and menu items. +- Menu: Supports multi-level menus and selected state. +- Pagination: Supports page switching and sizes. +- Steps: Supports step status and descriptions. + +Usage Tips + +- Events: Navigation components typically trigger page transitions or content updates through callbacks or state changes. +- Internationalization: Language environment can be set uniformly through ConfigProvider (see "Internationalization Support"). + +**Section Source** + +- [docs/app.py:240-257](file://docs/app.py#L240-L257) + +### Data Entry Components + +- AutoComplete: Supports options and backfill. +- Cascader: Supports multi-level linkage and lazy loading. +- Checkbox: Supports groups and options. +- ColorPicker: Supports presets and formatting. +- DatePicker: Supports range selection and preset shortcuts. +- Form: Supports field validation rules, dynamic add/remove, and Provider. +- Input: Supports password, search, textarea, and OTP. +- InputNumber: Supports step and precision. +- Mentions: Supports keyword mentions and options. +- Radio: Supports buttons and groups. +- Rate: Supports readonly and half-star. +- Select: Supports multi-select and search. +- Slider: Supports marks and range. +- Switch: Supports disabled and loading. +- TimePicker: Supports range selection. +- Transfer: Supports source and target lists. +- TreeSelect: Supports directory tree and nodes. +- Upload: Supports drag and drop and custom requests. + +Usage Tips + +- Validation: FormItemRule provides validation rule definitions; dynamic forms support conditional rendering and field add/remove. +- Events: Common events like onChange/onFocus/onBlur can be used for linkage and state management. +- Styling: elem_style/elem_classes are used for fine-tuning appearance and layout. + +**Section Source** + +- [docs/app.py:264-317](file://docs/app.py#L264-L317) + +### Data Display Components + +- Avatar: Supports avatar groups and badges. +- Badge: Supports ribbons and badges. +- Calendar: Supports month view and event markers. +- Card: Supports grid and meta information. +- Carousel: Supports auto-play and indicators. +- Collapse: Supports accordion and panel items. +- Descriptions: Supports key-value pair display. +- Empty: Supports custom images and actions. +- Image: Supports preview groups and lazy loading. +- List: Supports items and meta information. +- Popover: Supports triggers and content. +- QRCode: Supports colors and sizes. +- Segmented: Supports options and disabled. +- Statistic: Supports countdown and timer. +- Table: Supports columns, expansion, selection, and sorting. +- Tabs: Supports tab items and types. +- Tag: Supports checkable tags. +- Timeline: Supports nodes and directions. +- Tooltip: Supports triggers and positions. +- Tour: Supports steps and highlights. +- Tree: Supports directory tree and nodes. + +Usage Tips + +- Table: Supports fixed columns, sorting, filtering, and pagination; can combine with Segmented for dimension switching. +- Image: ImagePreviewGroup provides multi-image preview capability. +- Interaction: Popover/Tooltip/Tour improve information density and guidance efficiency. + +**Section Source** + +- [docs/app.py:324-386](file://docs/app.py#L324-L386) + +### Feedback Components + +- Alert: Supports multiple types and closable. +- Drawer: Supports positions and nested content. +- Message: Supports global messages and duration. +- Modal: Supports static dialogs and mask layers. +- Notification: Supports multiple notifications and closable. +- Popconfirm: Supports confirm and cancel callbacks. +- Progress: Supports circle and percentage. +- Result: Supports success/error/waiting status pages. +- Skeleton: Supports avatar, button, input, and image. +- Spin: Supports fullscreen and inline. +- Watermark: Supports text and image watermarks. + +Usage Tips + +- Global Components: Message/Notification/Modal/Drawer are typically invoked through APIs rather than direct rendering. +- Animation and Transitions: Progress/Spin/Skeleton improve loading experience and placeholder effects. +- Accessibility: It is recommended to provide keyboard-accessible and screen-reader-friendly cues for interactive components. + +**Section Source** + +- [docs/app.py:393-425](file://docs/app.py#L393-L425) + +### Other Components + +- Affix: Supports pinning and offset. +- ConfigProvider: Provides theme, language, and global style overrides. + +Usage Tips + +- Internationalization: ConfigProvider supports locales injection for Chinese/English switching. +- Theme: Override global theme variables through ConfigProvider for consistent style. + +**Section Source** + +- [docs/app.py:432-437](file://docs/app.py#L432-L437) + +## Ant Design X Component Library + +### New Component Overview + +Ant Design X is an extension component library of Ant Design, providing richer interactive components and solutions for professional application scenarios. This upgrade includes the following main components: + +#### Thought Chain Component + +- ThoughtChain: Thought chain container component, supports multi-step thought process display +- ThoughtChainItem: Thought chain item component, supports state management, collapsible, and blinking effects +- Supports pending, success, error, abort states +- Configurable content, description, footer, icon, and title + +#### File Management Components + +- Folder: Folder component, supports directory tree and file management +- FolderDirectoryIcon: Directory icon component, supports different file type icon display +- FileCard: File card component, supports file list display +- FileCardList: File list component, supports file item management + +#### Conversation Interaction Components + +- Bubble: Message bubble component, supports user and system message display +- BubbleList: Message list component, supports message items and role management +- Conversations: Conversation component, supports history conversation management +- Sender: Sender component, supports message sending and header management +- SenderHeader: Sender header component, supports expand state control + +#### Content Display Components + +- CodeHighlighter: Code highlighting component, supports multiple programming language syntax highlighting +- Mermaid: Chart component, supports Mermaid syntax chart rendering +- Prompts: Prompt component, supports prompt management and display +- Sources: Source component, supports content source display +- Suggestion: Suggestion component, supports smart suggestion display + +#### Interaction Tool Components + +- Actions: Action component, supports multiple action buttons +- Attachments: Attachment component, supports file attachment management +- Notification: Notification component, supports system notification display +- Welcome: Welcome component, supports welcome page display +- XProvider: Provider component, supports context provision + +Usage Tips + +- Slot System: Most components support named slots like content, description, footer, icon, title, etc. +- Event System: Supports event listening like open_change +- State Management: Supports state properties like open, closable, collapsible, etc. +- Style Customization: Supports styles and class_names properties for style customization + +**Section Source** + +- [backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/**init**.py:1-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L1-L81) +- [backend/modelscope_studio/components/antdx/folder/directory_icon/**init**.py:1-61](file://backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py#L1-L61) +- [backend/modelscope_studio/components/antdx/sender/header/**init**.py:1-74](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py#L1-L74) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Dependency Analysis + +- Python Layer Export: **init**.py and components.py centrally export Ant Design and Ant Design X component classes for unified import. +- Frontend Bridge: Svelte components dynamically load Ant Design React and Ant Design X components through importComponent, with processProps uniformly handling properties and styles. +- Documentation Site: docs/app.py aggregates component documentation and examples, Docs.py parses Markdown and renders examples and code blocks. + +```mermaid +graph LR +PyInit["backend/.../antd/__init__.py"] --> PyComp["backend/.../antd/components.py"] +PyInitX["backend/.../antdx/__init__.py"] --> PyCompX["backend/.../antdx/components.py"] +PyComp --> SvelteBtn["frontend/antd/button/Index.svelte"] +PyCompX --> SvelteBtn +DocsApp["docs/app.py"] --> DocsHelper["docs/helper/Docs.py"] +DocsHelper --> SvelteBtn +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-147](file://backend/modelscope_studio/components/antd/components.py#L1-L147) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [frontend/antd/button/Index.svelte:10-74](file://frontend/antd/button/Index.svelte#L10-L74) +- [docs/app.py:19-438](file://docs/app.py#L19-L438) +- [docs/helper/Docs.py:12-178](file://docs/helper/Docs.py#L12-L178) + +**Section Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-147](file://backend/modelscope_studio/components/antd/components.py#L1-L147) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [frontend/antd/button/Index.svelte:10-74](file://frontend/antd/button/Index.svelte#L10-L74) +- [docs/app.py:19-438](file://docs/app.py#L19-L438) +- [docs/helper/Docs.py:12-178](file://docs/helper/Docs.py#L12-L178) + +## Performance Considerations + +- Dynamic Loading: The frontend implements on-demand loading through importComponent, reducing initial bundle size and first-screen blocking. +- Property Pass-through: processProps uniformly handles properties and styles, avoiding repeated calculations and redundant rendering. +- Tables and Lists: Use virtualization and pagination reasonably to avoid rendering large numbers of nodes at once. +- Images and Skeleton: Use Skeleton and Image.lazy to reduce resource pressure and blank screen time. +- Global Components: Message/Notification/Modal etc. should limit concurrent quantity to avoid lag caused by frequent popups. +- Styling: elem_style/elem_classes should be reused as much as possible to avoid excessive inline styles causing repaints. +- Component Lazy Loading: Ant Design X components support lazy loading to improve application startup performance. + +## Troubleshooting Guide + +- Blank page or component not displaying + - Confirm that Application and ConfigProvider are wrapped in the outer layer. + - Enable ssr_mode=False when starting in Hugging Face Space. + - Check dependency version compatibility of Ant Design X components. +- Abnormal component styles + - Use elem_style/elem_classes to adjust container styles; avoid conflicts with global styles. + - Check whether theme and font resources are correctly imported. + - Confirm that Ant Design X component style files are correctly loaded. +- Internationalization not taking effect + - Inject locales through ConfigProvider; ensure language keys match Ant Design language packs. +- Examples not running + - Confirm that component documentation paths and example files exist in docs/app.py; check Docs.py example module loading logic. + - Check whether import paths for new components are correct. +- Version compatibility issues + - Ensure Gradio, Ant Design, and Ant Design X versions match. + - Check whether component properties are compatible with new versions. + +**Section Source** + +- [README-zh_CN.md:32-32](file://README-zh_CN.md#L32-L32) +- [docs/app.py:577-595](file://docs/app.py#L577-L595) +- [docs/helper/Docs.py:58-75](file://docs/helper/Docs.py#L58-L75) + +## Conclusion + +ModelScope Studio's Ant Design component library achieves seamless integration of Ant Design components in the Gradio ecosystem through a clear Python export layer and frontend bridge layer. With the major upgrades to Gradio 6.0, Ant Design 6.0, and Ant Design X 2.0, the component library now provides richer interaction capabilities and a more modern design system. With a unified base class system, slot mechanism, event system, and documentation site, developers can efficiently build beautiful and maintainable interfaces. It is recommended to combine responsive and internationalization strategies in actual projects, follow performance optimization and best practices to achieve a better user experience. + +## Appendix + +### Component Properties and Events Common Notes + +- Common Properties + - visible: Controls component visibility + - elem_id: Element ID + - elem_classes: Class name array or string + - elem_style: Inline style object + - value: Component value (if applicable) +- Events + - onChange/onFocus/onBlur: Common for input components + - onClick/onContextMenu: Common for button and interactive components + - onConfirm/onCancel: Common for confirmation components + - open_change: For state changes in expandable components +- Slots + - Default slot is used to render child nodes; some components support named slots like content, description, footer, icon, title, etc. + +**Section Source** + +- [backend/modelscope_studio/utils/dev/component.py:54-169](file://backend/modelscope_studio/utils/dev/component.py#L54-L169) +- [frontend/antd/button/Index.svelte:24-74](file://frontend/antd/button/Index.svelte#L24-L74) + +### Responsive Design and Internationalization Support + +- Responsive + - Grid and Flex provide multi-breakpoint configurations; it is recommended to set breakpoints and spacing separately for mobile and desktop. +- Internationalization + - Inject locales through ConfigProvider to achieve Chinese/English switching; note the correspondence between language packs and component text. + +**Section Source** + +- [docs/app.py:435-437](file://docs/app.py#L435-L437) + +### Code Examples and Scenario-based Applications + +- Example Organization + - The documentation site automatically scans the demos directory through Docs.py, rendering examples and code blocks; supports collapsible display and title annotation. +- Scenario Suggestions + - Forms: Use Form + FormItem + validation rules, combined with dynamic forms for conditional rendering. + - Data Tables: Combine Pagination and virtual scrolling to improve interaction smoothness with large data volumes. + - Navigation: Use Menu + Breadcrumb + Steps to build clear hierarchy and process guidance. + - Feedback: Use Message/Notification/Modal/Drawer to provide timely user feedback and operation confirmation. + - Thought Chain: Use ThoughtChain + ThoughtChainItem to build AI application thought process display. + - File Management: Use Folder + FileCard + Attachments to implement file management system. + +**Section Source** + +- [docs/helper/Docs.py:82-178](file://docs/helper/Docs.py#L82-L178) +- [docs/app.py:19-438](file://docs/app.py#L19-L438) + +### Parameter Mapping Supplementary Notes + +- Collapse Component Properties + - active_key: Currently expanded panel key + - default_active_key: Default expanded panel key + - accordion: Accordion mode + - bordered: Whether to have border + - collapsible: Collapsible trigger area + - destroy_inactive_panel: Destroy collapsed hidden panels + - expand_icon: Custom expand icon + - expand_icon_placement: Expand icon position, options are `start` or `end` + - ghost: Transparent borderless + - size: Size + +### Version Upgrade Notes + +- Gradio 6.0 Upgrade + - Supports new event system and component lifecycle management + - Improved component state management and data flow +- Ant Design 6.0 Upgrade + - More modern design system and visual specifications + - Enhanced accessibility support + - Improved theme customization capabilities +- Ant Design X 2.0 Upgrade + - Added rich interactive components + - Improved component API and slot system + - Enhanced TypeScript type support + +**Section Source** + +- [.changeset/pink-sails-itch.md:12-12](file://.changeset/pink-sails-itch.md#L12-L12) +- [.changeset/eleven-aliens-sell.md:12-12](file://.changeset/eleven-aliens-sell.md#L12-L12) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) diff --git a/.wiki/en/Ant Design Components/Components Overview.md b/.wiki/en/Ant Design Components/Components Overview.md new file mode 100644 index 00000000..1886a7a4 --- /dev/null +++ b/.wiki/en/Ant Design Components/Components Overview.md @@ -0,0 +1,384 @@ +# Components Overview + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [frontend/antd/package.json](file://frontend/antd/package.json) +- [docs/components/antd/overview/README.md](file://docs/components/antd/overview/README.md) +- [docs/README.md](file://docs/README.md) +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/components/pro/__init__.py](file://backend/modelscope_studio/components/pro/__init__.py) +- [docs/app.py](file://docs/app.py) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) +- [docs/components/antd/button/demos/basic.py](file://docs/components/antd/button/demos/basic.py) +- [docs/components/antd/form/demos/basic.py](file://docs/components/antd/form/demos/basic.py) +- [docs/components/antd/layout/demos/basic.py](file://docs/components/antd/layout/demos/basic.py) +- [frontend/svelte-preprocess-react/svelte-contexts/slot.svelte.ts](file://frontend/svelte-preprocess-react/svelte-contexts/slot.svelte.ts) +- [frontend/svelte-preprocess-react/component/import.ts](file://frontend/svelte-preprocess-react/component/import.ts) +- [frontend/svelte-preprocess-react/component/props.svelte.ts](file://frontend/svelte-preprocess-react/component/props.svelte.ts) +- [docs/components/base/fragment/README-zh_CN.md](file://docs/components/base/fragment/README-zh_CN.md) +- [CHANGELOG.md](file://CHANGELOG.md) +- [pnpm-lock.yaml](file://pnpm-lock.yaml) +- [package.json](file://package.json) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) + + +## Update Summary + +**Changes made** + +- Updated version information to reflect the upgrade from Ant Design 5.x to 6.3.5 +- Updated migration information from Gradio 5.x to 6.0 +- Updated component version compatibility notes +- Updated version-related information for theme customization and internationalization mechanisms + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Classification and Organization](#component-classification-and-organization) +6. [Usage Principles and Best Practices](#usage-principles-and-best-practices) +7. [Responsive Design and Internationalization](#responsive-design-and-internationalization) +8. [Theme Customization and Style System](#theme-customization-and-style-system) +9. [Typical Scenarios and Combined Usage](#typical-scenarios-and-combined-usage) +10. [Component Dependencies and Integration Patterns](#component-dependencies-and-integration-patterns) +11. [Performance Considerations](#performance-considerations) +12. [Troubleshooting Guide](#troubleshooting-guide) +13. [Conclusion](#conclusion) + +## Introduction + +This overview covers the overall presentation of the Ant Design component library in modelscope_studio, including features, design philosophy, overall architecture, component classification system, usage principles, responsive design and internationalization, theme customization, typical scenarios and combination methods, and inter-component dependencies and integration patterns. The component library is built on Gradio 6.0, providing richer page layouts and interaction capabilities, and adapts to Ant Design 6.3.5 styles and behaviors through a unified configuration container. + +**Update** The project has been upgraded from Gradio 5.x to 6.0, and Ant Design from 5.x to 6.3.5, bringing better performance and compatibility. + +**Version**: This document applies to ModelScope Studio 2.0+, supporting Gradio 6.0, Ant Design 6.3.5, and Ant Design X 2.0 + +## Project Structure + +- Backend Module Export: The Python layer exports all Ant Design components through module aggregation, facilitating direct on-demand import and usage. +- Frontend Implementation: Each Ant Design component is implemented in Svelte/React form, with typed properties and slot mechanism, achieving bridge with Gradio 6.0. +- Documentation and Examples: Accompanying documentation and demo scripts covering quick start, property constraints, event binding, slot rendering, function parameter passing, internationalization, and theme customization topics. + +```mermaid +graph TB +subgraph "Backend" +PY_INIT["backend/modelscope_studio/components/antd/__init__.py"] +PY_COMP["backend/modelscope_studio/components/antd/components.py"] +BASE_INIT["backend/modelscope_studio/components/base/__init__.py"] +PRO_INIT["backend/modelscope_studio/components/pro/__init__.py"] +VERSION["backend/modelscope_studio/version.py"] +end +subgraph "Frontend" +PKG["frontend/antd/package.json"] +CFG_TSX["frontend/antd/config-provider/config-provider.tsx"] +LOCALES["frontend/antd/config-provider/locales.ts"] +BUTTON_PKG["frontend/antd/button/package.json"] +FORM_PKG["frontend/antd/form/package.json"] +end +subgraph "Documentation and Examples" +OVERVIEW["docs/components/antd/overview/README.md"] +APP_PY["docs/app.py"] +DEMO_BTN["docs/components/antd/button/demos/basic.py"] +DEMO_FORM["docs/components/antd/form/demos/basic.py"] +DEMO_LAYOUT["docs/components/antd/layout/demos/basic.py"] +end +PY_INIT --> PY_COMP +PY_COMP --> PKG +PKG --> CFG_TSX +CFG_TSX --> LOCALES +PY_INIT --> OVERVIEW +APP_PY --> OVERVIEW +DEMO_BTN --> OVERVIEW +DEMO_FORM --> OVERVIEW +DEMO_LAYOUT --> OVERVIEW +BASE_INIT --> OVERVIEW +PRO_INIT --> OVERVIEW +VERSION --> OVERVIEW +BUTTON_PKG --> CFG_TSX +FORM_PKG --> CFG_TSX +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:313-465](file://frontend/antd/config-provider/locales.ts#L313-L465) +- [docs/components/antd/overview/README.md:1-75](file://docs/components/antd/overview/README.md#L1-L75) +- [docs/app.py:200-399](file://docs/app.py#L200-L399) +- [docs/components/antd/button/demos/basic.py:1-26](file://docs/components/antd/button/demos/basic.py#L1-L26) +- [docs/components/antd/form/demos/basic.py:1-94](file://docs/components/antd/form/demos/basic.py#L1-L94) +- [docs/components/antd/layout/demos/basic.py:1-88](file://docs/components/antd/layout/demos/basic.py#L1-L88) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/antd/button/package.json:1-15](file://frontend/antd/button/package.json#L1-L15) +- [frontend/antd/form/package.json:1-15](file://frontend/antd/form/package.json#L1-L15) + +**Section Source** + +- [docs/README.md:19-75](file://docs/README.md#L19-L75) +- [docs/components/antd/overview/README.md:1-75](file://docs/components/antd/overview/README.md#L1-L75) +- [docs/app.py:200-399](file://docs/app.py#L200-L399) +- [CHANGELOG.md:13](file://CHANGELOG.md#L13) + +## Core Components + +- Component Export: The backend exports all Ant Design components through module aggregation, forming a unified namespace for direct import and usage. +- Configuration Container: ConfigProvider provides global configuration for theme, language, popup container, etc., compatible with Ant Design 6.3.5 and injecting Gradio 6.0 style adaptation. +- Base Components: Application, AutoLoading, Fragment, and other base capabilities ensure correct component tree rendering and loading state feedback. +- Pro Components: Extended components for advanced scenarios (such as chatbot, editor, Web Sandbox, etc.). + +**Update** All components are now compatible with Ant Design 6.3.5 and Gradio 6.0 new features. + +**Section Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [pnpm-lock.yaml:2830](file://pnpm-lock.yaml#L2830-L2835) + +## Architecture Overview + +The overall architecture revolves around the closed loop of "backend component export + frontend bridge rendering + documentation and examples". The backend is responsible for component classes and property mapping, the frontend is responsible for converting properties and slots to React/JSX rendering, and injecting themes and internationalization through ConfigProvider; documentation and examples provide usage patterns and constraint explanations. + +**Update** The architecture is now fully adapted to Gradio 6.0's new event system and component lifecycle. + +```mermaid +graph TB +A["Backend Component Export
backend/modelscope_studio/components/antd/__init__.py"] --> B["Frontend Bridge Component
frontend/antd/*/*.tsx"] +B --> C["Configuration Container
frontend/antd/config-provider/config-provider.tsx"] +C --> D["Internationalization and Locale
frontend/antd/config-provider/locales.ts"] +E["Base Components
backend/modelscope_studio/components/base/__init__.py"] --> A +F["Pro Extension Components
backend/modelscope_studio/components/pro/__init__.py"] --> A +G["Documentation and Examples
docs/components/antd/*/demos/*.py"] --> A +G --> B +G --> C +H["Version Management
backend/modelscope_studio/version.py"] --> A +I["Dependency Lock
pnpm-lock.yaml"] --> B +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:313-465](file://frontend/antd/config-provider/locales.ts#L313-L465) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [docs/components/antd/button/demos/basic.py:1-26](file://docs/components/antd/button/demos/basic.py#L1-L26) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [pnpm-lock.yaml:2830](file://pnpm-lock.yaml#L2830-L2835) + +## Component Classification and Organization + +According to the navigation structure in the documentation, Ant Design components are divided into six major categories for easy retrieval and usage by functional domain: + +- General Components + - Includes: Button, Icon, Typography, etc. + - Examples: Button, Icon, Typography +- Layout Components + - Includes: Divider, Flex, Grid, Layout, Space, Splitter, etc. + - Examples: Grid, Flex, Splitter, Page Layout +- Navigation Components + - Includes: Anchor, Breadcrumb, Dropdown, Menu, Pagination, Steps, etc. + - Examples: Anchor, Breadcrumb, Dropdown, Navigation Menu, Pagination, Steps +- Data Entry Components + - Includes: AutoComplete, Cascader, Checkbox, ColorPicker, DatePicker, Form, Input, InputNumber, Mentions, Radio, Rate, Select, Slider, Switch, TimePicker, Transfer, TreeSelect, Upload, etc. + - Examples: Form, Input, Select, Time/Date, Switch, Slider, Upload +- Data Display Components + - Includes: Avatar, Badge, Calendar, Card, Carousel, Collapse, Descriptions, Empty, Image, List, Popover, QRCode, Segmented, Statistic, Table, Tabs, Tag, Timeline, Tooltip, Tour, Tree, etc. + - Examples: Card, Table, Tag, Timeline, Tree, Statistic +- Feedback Components + - Includes: Alert, Drawer, Message, Modal, Notification, etc. + - Examples: Alert, Drawer, Message, Modal, Notification + +**Update** All components have been adapted to Ant Design 6.3.5's new API and style specifications. + +The above classification and examples are from the documentation's navigation and example scripts, making it easy for developers to quickly locate components and reference usage. + +**Section Source** + +- [docs/app.py:200-399](file://docs/app.py#L200-L399) +- [docs/components/antd/button/demos/basic.py:1-26](file://docs/components/antd/button/demos/basic.py#L1-L26) +- [docs/components/antd/form/demos/basic.py:1-94](file://docs/components/antd/form/demos/basic.py#L1-L94) +- [docs/components/antd/layout/demos/basic.py:1-88](file://docs/components/antd/layout/demos/basic.py#L1-L88) + +## Usage Principles and Best Practices + +- Unified Entry: Import all components through the antd module to avoid scattered imports. +- Wrapper Container: All antd components must be placed between Application and ConfigProvider to ensure dependencies and styles work properly. +- Loading State Feedback: It is recommended to use AutoLoading to automatically display loading animations during requests to improve user experience. +- Event Binding: Events use Gradio 6.0's event binding form, with parameters stored in specific fields as arrays, note the destructure and handling. +- Slot Mechanism: Python cannot directly pass components as parameters; use Slot to wrap modules; if only strings or numbers, they can be passed directly as properties. +- Function Parameter Passing: Pass JS functions as strings, the frontend will automatically compile them into functions; functions returning ReactNode can be handled in two ways: rendered as regular nodes or generated through the global React object. +- Slot Compatibility: Some component slots only support modelscope_studio components; if you need to insert other Gradio components, wrap them with Fragment. + +**Update** The event system is fully adapted to Gradio 6.0's new event model, and the slot mechanism has been optimized accordingly. + +**Section Source** + +- [docs/components/antd/overview/README.md:13-75](file://docs/components/antd/overview/README.md#L13-L75) +- [docs/components/base/fragment/README-zh_CN.md:1-10](file://docs/components/base/fragment/README-zh_CN.md#L1-L10) + +## Responsive Design and Internationalization + +- Responsive Design: Components follow Ant Design 6.3.5's responsive specifications, combining Flex, Grid, and other layout components to achieve adaptive layouts. +- Internationalization: ConfigProvider supports multi-language switching, with built-in extensive language and region mapping, automatically loading corresponding language packs and date library languages to meet multi-language site requirements. + +```mermaid +sequenceDiagram +participant U as "User" +participant CFG as "ConfigProvider" +participant L as "locales.ts" +participant D as "dayjs" +U->>CFG : Set language identifier +CFG->>L : Parse language identifier and load corresponding language pack +L-->>CFG : Return Antd 6.3.5 language pack and dayjs language +CFG->>D : Set dayjs language +CFG-->>U : Apply language configuration +``` + +**Diagram Source** + +- [frontend/antd/config-provider/config-provider.tsx:85-105](file://frontend/antd/config-provider/config-provider.tsx#L85-L105) +- [frontend/antd/config-provider/locales.ts:313-465](file://frontend/antd/config-provider/locales.ts#L313-L465) + +**Section Source** + +- [frontend/antd/config-provider/config-provider.tsx:15-27](file://frontend/antd/config-provider/config-provider.tsx#L15-L27) +- [frontend/antd/config-provider/locales.ts:313-465](file://frontend/antd/config-provider/locales.ts#L313-L465) + +## Theme Customization and Style System + +- Theme Mode: Control dark/compact algorithms through ConfigProvider's themeMode, supporting dynamic switching. +- Theme Tokens: Support setting primary color and other tokens, combining with algorithms to achieve unified theme style. +- Style Injection: Use style provider to ensure component prefix and style isolation, avoiding conflicts. + +```mermaid +flowchart TD +Start(["Enter ConfigProvider"]) --> Parse["Parse themeMode and algorithm"] +Parse --> Merge["Merge algorithm and theme tokens"] +Merge --> Apply["Apply to Ant Design 6.3.5 theme"] +Apply --> Inject["Inject style provider"] +Inject --> End(["Complete theme rendering"]) +``` + +**Diagram Source** + +- [frontend/antd/config-provider/config-provider.tsx:88-143](file://frontend/antd/config-provider/config-provider.tsx#L88-L143) + +**Section Source** + +- [frontend/antd/config-provider/config-provider.tsx:53-151](file://frontend/antd/config-provider/config-provider.tsx#L53-L151) + +## Typical Scenarios and Combined Usage + +- Quick Start: Under Application and ConfigProvider wrapper, use Button, Icon, Typography, and other general components to build basic interfaces. +- Form Scenarios: Use Form and Form.Item combined with Input, Select, DatePicker, Upload, and other data entry components, combined with validation rules and submit callbacks. +- Page Layout: Use Layout, Grid, Flex, Space, and other layout components to build page skeletons, combined with Sider, Header, Content, Footer to achieve complex page structures. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant App as "Application" +participant Cfg as "ConfigProvider" +participant Btn as "Button" +participant Form as "Form" +participant Lay as "Layout" +Dev->>App : Create application context +App->>Cfg : Inject global configuration (theme/language) +Cfg->>Btn : Render button component +Cfg->>Form : Render form component +Cfg->>Lay : Render layout component +Btn-->>Dev : Trigger events and interactions +Form-->>Dev : Collect data and validate +Lay-->>Dev : Layout structure output +``` + +**Diagram Source** + +- [docs/components/antd/button/demos/basic.py:5-26](file://docs/components/antd/button/demos/basic.py#L5-L26) +- [docs/components/antd/form/demos/basic.py:16-94](file://docs/components/antd/form/demos/basic.py#L16-L94) +- [docs/components/antd/layout/demos/basic.py:42-88](file://docs/components/antd/layout/demos/basic.py#L42-L88) + +**Section Source** + +- [docs/components/antd/button/demos/basic.py:1-26](file://docs/components/antd/button/demos/basic.py#L1-L26) +- [docs/components/antd/form/demos/basic.py:1-94](file://docs/components/antd/form/demos/basic.py#L1-L94) +- [docs/components/antd/layout/demos/basic.py:1-88](file://docs/components/antd/layout/demos/basic.py#L1-L88) + +## Component Dependencies and Integration Patterns + +- Component Dependencies: Each component is exposed through backend export modules, with frontend managing versions and types as independent packages. +- Slots and Context: The frontend supports complex nesting and dynamic rendering through slot context and parameter mapping mechanisms. +- Initialization Flow: Before component loading, wait for initialization to complete to ensure global objects are available. +- Event and Property Mapping: The frontend uniformly maps properties and events to ensure consistency with Gradio 6.0's event model. + +**Update** Dependency relationships have been updated to reflect new version requirements for Gradio 6.0 and Ant Design 6.3.5. + +```mermaid +graph LR +PY["Backend Export Module"] --> FE["Frontend Component Implementation"] +FE --> CTX["Slot Context and Parameter Mapping"] +FE --> INIT["Initialization Flow"] +FE --> EVT["Event and Property Mapping"] +CTX --> REN["Render Pipeline"] +INIT --> REN +EVT --> REN +SUB["Sub-package Management"] --> FE +LOCK["Dependency Lock"] --> FE +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [frontend/svelte-preprocess-react/svelte-contexts/slot.svelte.ts:55-102](file://frontend/svelte-preprocess-react/svelte-contexts/slot.svelte.ts#L55-L102) +- [frontend/svelte-preprocess-react/component/import.ts:1-20](file://frontend/svelte-preprocess-react/component/import.ts#L1-L20) +- [frontend/svelte-preprocess-react/component/props.svelte.ts:258-312](file://frontend/svelte-preprocess-react/component/props.svelte.ts#L258-L312) +- [frontend/antd/button/package.json:1-15](file://frontend/antd/button/package.json#L1-L15) +- [pnpm-lock.yaml:2830](file://pnpm-lock.yaml#L2830-L2835) + +**Section Source** + +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/svelte-preprocess-react/svelte-contexts/slot.svelte.ts:55-102](file://frontend/svelte-preprocess-react/svelte-contexts/slot.svelte.ts#L55-L102) +- [frontend/svelte-preprocess-react/component/import.ts:1-20](file://frontend/svelte-preprocess-react/component/import.ts#L1-L20) +- [frontend/svelte-preprocess-react/component/props.svelte.ts:258-312](file://frontend/svelte-preprocess-react/component/props.svelte.ts#L258-L312) + +## Performance Considerations + +- On-demand Rendering: Reduce unnecessary component instantiation through slots and conditional rendering. +- Theme and Internationalization Lazy Loading: Language packs and theme algorithms are loaded on-demand, reducing initial overhead. +- Event and Property Mapping: Unified mapping reduces repeated calculations and DOM operations. +- Layout Component Optimization: Prefer modern layouts like Flex and Grid to reduce reflow and repaint. + +**Update** Performance optimization has been adjusted for Gradio 6.0's new architecture, providing better rendering performance. + +[This section is general guidance, no specific file references needed] + +## Troubleshooting Guide + +- Page preview unsuccessful: Confirm all components are wrapped in Application. +- Abnormal styles: Confirm ConfigProvider is correctly wrapped, and themeMode, locale settings are as expected. +- Events not responding: Check whether event binding uses Gradio 6.0 form, and whether parameters are correctly destructured. +- Slots not working: Confirm using Slot to wrap modules, or directly passing strings/numbers; if you need to insert other Gradio components, wrap with Fragment. +- Function parameter issues: Pass functions as strings, the frontend will automatically compile; functions returning ReactNode can choose slots or generate through global React object. + +**Update** Troubleshooting guide has been updated to reflect Gradio 6.0's new event system and component lifecycle changes. + +**Section Source** + +- [docs/components/antd/overview/README.md:13-75](file://docs/components/antd/overview/README.md#L13-L75) +- [docs/components/base/fragment/README-zh_CN.md:1-10](file://docs/components/base/fragment/README-zh_CN.md#L1-L10) + +## Conclusion + +modelscope_studio deeply integrates Ant Design 6.3.5 components with the Gradio 6.0 ecosystem, providing unified component export, configuration container, and documentation examples to help developers quickly build beautiful and maintainable interfaces. Through clear classification system, strict usage principles, and complete internationalization, theme, and slot mechanisms, the component library achieves a good balance between usability and extensibility. It is recommended to follow the "Application + ConfigProvider" wrapper principle in actual projects, make good use of slots and event mapping, and combine with layout components to achieve responsive and accessibility-friendly interfaces. + +**Update** The version upgrade brings better performance, more stable event system, and more modern theme support, providing developers with a better development experience. diff --git a/.wiki/en/Ant Design Components/Data Display Components/Avatar and Badge.md b/.wiki/en/Ant Design Components/Data Display Components/Avatar and Badge.md new file mode 100644 index 00000000..183344fe --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Avatar and Badge.md @@ -0,0 +1,328 @@ +# Avatar and Badge + + +**Files referenced in this document** +- [avatar.tsx](file://frontend/antd/avatar/avatar.tsx) +- [avatar group entry Index.svelte](file://frontend/antd/avatar/group/Index.svelte) +- [avatar.group.tsx](file://frontend/antd/avatar/group/avatar.group.tsx) +- [avatar.group.less](file://frontend/antd/avatar/group/avatar.group.less) +- [badge.tsx](file://frontend/antd/badge/badge.tsx) +- [badge ribbon entry Index.svelte](file://frontend/antd/badge/ribbon/Index.svelte) +- [ribbon.badge.tsx](file://frontend/antd/badge/ribbon/badge.ribbon.tsx) +- [avatar docs README.md](file://docs/components/antd/avatar/README.md) +- [badge docs README.md](file://docs/components/antd/badge/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the Avatar and Badge component families, systematically covering size control, shape settings, Avatar.Group stacking and masking, Badge count display and dot marking, Badge.Ribbon ribbon effects, and other capabilities. It also provides placeholder handling, threshold settings, custom style solutions, as well as responsive and multi-layout adaptation recommendations. The document is based on actual implementations in the repository, with visual diagrams to help readers quickly understand and correctly use the components. + +## Project Structure + +- Avatar components are located in frontend/antd/avatar, containing two sub-modules: single avatar and avatar group. The avatar group dynamically imports its internal implementation via a composite Svelte entry file. +- Badge components are located in frontend/antd/badge, containing two sub-modules: basic badge and ribbon badge. The ribbon badge is also dynamically imported via a composite Svelte entry file. +- Documentation examples are in docs/components/antd/avatar and docs/components/antd/badge, providing demo entries for basic and combined usage. + +```mermaid +graph TB +subgraph "Avatar Components" +AV["avatar.tsx"] +AGI["avatar/group/Index.svelte"] +AGC["avatar/group/avatar.group.tsx"] +AGL["avatar/group/avatar.group.less"] +end +subgraph "Badge Components" +BD["badge.tsx"] +RBDI["badge/ribbon/Index.svelte"] +RBD["badge/ribbon/badge.ribbon.tsx"] +end +AV --> |"Wrap Ant Design"| AV +AGI --> |"Dynamic import"| AGC +AGC --> |"Render"| AV +AGC --> |"Styles"| AGL +BD --> |"Wrap Ant Design"| BD +RBDI --> |"Dynamic import"| RBD +RBD --> |"Wrap content"| RBD +``` + +**Diagram Source** + +- [avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [avatar group entry Index.svelte:1-62](file://frontend/antd/avatar/group/Index.svelte#L1-L62) +- [avatar.group.tsx:1-52](file://frontend/antd/avatar/group/avatar.group.tsx#L1-L52) +- [avatar.group.less:1-12](file://frontend/antd/avatar/group/avatar.group.less#L1-L12) +- [badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) +- [badge ribbon entry Index.svelte:1-62](file://frontend/antd/badge/ribbon/Index.svelte#L1-L62) +- [ribbon.badge.tsx:1-22](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L1-L22) + +**Section Source** + +- [avatar docs README.md:1-9](file://docs/components/antd/avatar/README.md#L1-L9) +- [badge docs README.md:1-9](file://docs/components/antd/badge/README.md#L1-L9) + +## Core Components + +- Avatar + - Supports icon, image and character display, with size and shape configuration; supports dynamic injection of icon and src via slot mechanism. + - Provides placeholder handling: when no icon or image is provided, child nodes can serve as fallback content. +- Avatar.Group + - Implements avatar stacking and masking effects; supports maximum count threshold and popup tooltip; controls overlap spacing via less variables. + - Supports slot-based customization of the popup layer title and content for "overflowed count". +- Badge + - Supports numeric count and text marking; both count and text can inject custom content via slots. + - Supports dot marking and overflow threshold (shows n+ when exceeding the threshold). +- Badge.Ribbon + - Overlays a "ribbon"-style badge on a target element, supporting text slots; typically used to emphasize status or identify features. + +**Section Source** + +- [avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [avatar.group.tsx:1-52](file://frontend/antd/avatar/group/avatar.group.tsx#L1-L52) +- [avatar.group.less:1-12](file://frontend/antd/avatar/group/avatar.group.less#L1-L12) +- [badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) +- [ribbon.badge.tsx:1-22](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L1-L22) + +## Architecture Overview + +The diagram below shows the call chain from the Svelte entry to specific Ant Design components, as well as key paths for slot and property forwarding. + +```mermaid +sequenceDiagram +participant U as "User Code" +participant S as "Svelte Composite Entry (Index)" +participant C as "Internal Component (tsx)" +participant A as "Ant Design Component" +U->>S : Pass properties and slots +S->>C : Dynamically import and forward properties/slots +C->>A : Forward properties/slots +A-->>U : Render result +``` + +**Diagram Source** + +- [avatar group entry Index.svelte:48-61](file://frontend/antd/avatar/group/Index.svelte#L48-L61) +- [avatar.group.tsx:12-49](file://frontend/antd/avatar/group/avatar.group.tsx#L12-L49) +- [badge ribbon entry Index.svelte:48-61](file://frontend/antd/badge/ribbon/Index.svelte#L48-L61) +- [ribbon.badge.tsx:6-18](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L6-L18) + +## Detailed Component Analysis + +### Avatar + +- Wrapping approach + - Uses sveltify to wrap Ant Design's Avatar as a Svelte component, while preserving slot capabilities for icon and src. + - When slots exist, slot content takes priority; otherwise falls back to property values; child nodes serve as default content when no slots are provided. +- Placeholder handling + - Through hidden containers and conditional rendering, ensures child nodes can still be rendered as placeholder content when no icon or image is provided. +- Shape and size + - Shape (e.g., circle/square) and size (e.g., small/medium/large) are controlled via Ant Design native properties, following Antd specifications. + +```mermaid +flowchart TD +Start(["Enter Avatar render"]) --> CheckIconSrc["Check if icon or src slot exists"] +CheckIconSrc --> HasSlot{"Slot exists?"} +HasSlot --> |Yes| UseSlot["Use slot content as icon/image"] +HasSlot --> |No| UseProp["Use property value as icon/image"] +UseSlot --> Render["Render Ant Design Avatar"] +UseProp --> Render +Render --> End(["Done"]) +``` + +**Diagram Source** + +- [avatar.tsx:6-25](file://frontend/antd/avatar/avatar.tsx#L6-L25) + +**Section Source** + +- [avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) + +### Avatar.Group + +- Stacking and masking + - Internally uses Ant Design's Group capability for avatar stacking; controls the starting margin of adjacent avatars via less variables to create visual overlap and layering. +- Threshold and popup layer + - Supports setting max.count as the threshold; when exceeded, shows hints like "n more". + - The popup layer title and content can be overridden via slots; if no slots are provided, falls back to property configuration. +- Sub-item rendering + - Maps child items to ReactSlot via useTargets and ReactSlot, ensuring each child avatar renders in order. + +```mermaid +flowchart TD +Enter(["Enter Avatar.Group"]) --> ComputeMax["Calculate max config
including count and popover"] +ComputeMax --> OverLimit{"Exceeds threshold?"} +OverLimit --> |Yes| Popover["Show popup layer (title/content can use slots)"] +OverLimit --> |No| RenderList["Render child avatars one by one"] +Popover --> RenderList +RenderList --> Exit(["Done"]) +``` + +**Diagram Source** + +- [avatar.group.tsx:12-49](file://frontend/antd/avatar/group/avatar.group.tsx#L12-L49) +- [avatar.group.less:1-12](file://frontend/antd/avatar/group/avatar.group.less#L1-L12) + +**Section Source** + +- [avatar group entry Index.svelte:1-62](file://frontend/antd/avatar/group/Index.svelte#L1-L62) +- [avatar.group.tsx:1-52](file://frontend/antd/avatar/group/avatar.group.tsx#L1-L52) +- [avatar.group.less:1-12](file://frontend/antd/avatar/group/avatar.group.less#L1-L12) + +### Badge + +- Count and text + - Both count and text support slot injection, enabling placement of complex content (such as icons, custom text) inside the badge. +- Dot marking + - Implements dot marking via Ant Design native capability; displays a pure dot when count is 0 and numbers are not shown. +- Threshold setting + - Supports setting a maximum value; displays n+ when exceeding the threshold. This capability is provided by the underlying Antd component and the component layer directly forwards the property. + +```mermaid +flowchart TD +Start(["Enter Badge render"]) --> CheckCountText["Check count and text slots"] +CheckCountText --> HasCount{"count has slot?"} +HasCount --> |Yes| UseCountSlot["Use slot count"] +HasCount --> |No| UseCountProp["Use property count"] +CheckCountText --> HasText{"text has slot?"} +HasText --> |Yes| UseTextSlot["Use slot text"] +HasText --> |No| UseTextProp["Use property text"] +UseCountSlot --> Render["Render Ant Design Badge"] +UseCountProp --> Render +UseTextSlot --> Render +UseTextProp --> Render +Render --> End(["Done"]) +``` + +**Diagram Source** + +- [badge.tsx:6-17](file://frontend/antd/badge/badge.tsx#L6-L17) + +**Section Source** + +- [badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) + +### Badge.Ribbon + +- Special effect + - Ribbon draws a "ribbon"-style badge on the parent container, commonly used to highlight status or mark new features; text content can be customized via slots. +- Use cases + - Suitable for adding prominent markings on cards, buttons, list items, and other containers; be careful to avoid conflicts with existing decorations. + +```mermaid +sequenceDiagram +participant U as "User Code" +participant S as "Ribbon Composite Entry" +participant C as "Internal Ribbon Component" +participant A as "Ant Design Ribbon" +U->>S : Pass properties and slots (text) +S->>C : Dynamically import and forward properties/slots +C->>A : Forward properties/slots +A-->>U : Render ribbon badge on container +``` + +**Diagram Source** + +- [badge ribbon entry Index.svelte:48-61](file://frontend/antd/badge/ribbon/Index.svelte#L48-L61) +- [ribbon.badge.tsx:6-18](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L6-L18) + +**Section Source** + +- [badge ribbon entry Index.svelte:1-62](file://frontend/antd/badge/ribbon/Index.svelte#L1-L62) +- [ribbon.badge.tsx:1-22](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L1-L22) + +## Dependency Analysis + +- Component wrapping + - All components bridge Ant Design counterparts as Svelte components via sveltify, maintaining consistent property and event forwarding. +- Slot mechanism + - Converts Svelte slots to React Slot via ReactSlot, ensuring compatibility with Antd component slot conventions. +- Dynamic import + - Composite entries use importComponent and import to dynamically import internal implementations, reducing initial bundle size and improving on-demand loading efficiency. +- Style coupling + - Avatar group controls overlap spacing and other style details via less variables, avoiding hardcoding and facilitating unified theme management. + +```mermaid +graph LR +Svelte["Svelte Composite Entry"] --> Sveltify["sveltify Wrapper"] +Sveltify --> Antd["Ant Design Component"] +Svelte --> ReactSlot["ReactSlot Bridge"] +Svelte --> DynamicImport["Dynamic Import Internal Implementation"] +Antd --> Less["less variables control styles"] +``` + +**Diagram Source** + +- [avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [avatar.group.tsx:1-52](file://frontend/antd/avatar/group/avatar.group.tsx#L1-L52) +- [badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) +- [ribbon.badge.tsx:1-22](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L1-L22) + +**Section Source** + +- [avatar group entry Index.svelte:1-62](file://frontend/antd/avatar/group/Index.svelte#L1-L62) +- [avatar.group.tsx:1-52](file://frontend/antd/avatar/group/avatar.group.tsx#L1-L52) +- [badge ribbon entry Index.svelte:1-62](file://frontend/antd/badge/ribbon/Index.svelte#L1-L62) +- [ribbon.badge.tsx:1-22](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L1-L22) + +## Performance Considerations + +- On-demand loading + - Composite entries use dynamic import strategy, loading internal implementations only when needed, reducing initial bundle size and first-screen rendering pressure. +- Slot rendering + - Slot content is injected at the rendering stage, avoiding unnecessary pre-processing overhead. +- Style variables + - Manage style details such as overlap spacing centrally via less variables, reducing repeated computation and style jitter. + +[This section provides general performance recommendations and does not require specific file references] + +## Troubleshooting Guide + +- Avatar not showing icon or image + - Check whether the icon or src property is correctly passed in; if using slots, confirm that the slot name and type match. + - If no icon/image is provided, the component falls back to child nodes as placeholder content; confirm that the child nodes are visible. +- Avatar group threshold invalid or popup layer not showing + - Confirm that max.count is a numeric type; when count is a number, the internal code automatically adds one to compensate for its own occupation. + - The popup layer title and content can be overridden via slots; if no slots are provided, falls back to property configuration. +- Badge threshold not working + - Confirm whether the threshold property is correctly forwarded to the underlying component; Antd natively supports n+ display logic. +- Ribbon badge position incorrect + - Confirm that Ribbon's parent container has a positioning context; if necessary, manually set relative positioning on the container to ensure stable overlay effect. + +**Section Source** + +- [avatar.tsx:6-25](file://frontend/antd/avatar/avatar.tsx#L6-L25) +- [avatar.group.tsx:18-40](file://frontend/antd/avatar/group/avatar.group.tsx#L18-L40) +- [badge.tsx:6-17](file://frontend/antd/badge/badge.tsx#L6-L17) +- [ribbon.badge.tsx:6-18](file://frontend/antd/badge/ribbon/badge.ribbon.tsx#L6-L18) + +## Conclusion + +This component system is built on Ant Design, with Svelte wrapping and slot bridging providing flexible avatar and badge capabilities. Avatar group stacking/masking, badge count and threshold, and ribbon badge highlighting effects can all be highly customized without breaking semantics. It is recommended to manage sizes, spacing, and colors uniformly via theme variables and layout specifications in actual projects to achieve a consistent user experience. + +[This section is a summary and does not require specific file references] + +## Appendix + +- Example entries + - Avatar component examples can be found under the demo tab in the docs directory. + - Badge component examples can be found under the demo tab in the docs directory. +- Related documentation + - Avatar component documentation overview: [avatar docs README.md:1-9](file://docs/components/antd/avatar/README.md#L1-L9) + - Badge component documentation overview: [badge docs README.md:1-9](file://docs/components/antd/badge/README.md#L1-L9) + +**Section Source** + +- [avatar docs README.md:1-9](file://docs/components/antd/avatar/README.md#L1-L9) +- [badge docs README.md:1-9](file://docs/components/antd/badge/README.md#L1-L9) diff --git a/.wiki/en/Ant Design Components/Data Display Components/Calendar and Card.md b/.wiki/en/Ant Design Components/Data Display Components/Calendar and Card.md new file mode 100644 index 00000000..e6da0038 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Calendar and Card.md @@ -0,0 +1,359 @@ +# Calendar and Card + + +**Files referenced in this document** +- [frontend/antd/calendar/Index.svelte](file://frontend/antd/calendar/Index.svelte) +- [frontend/antd/calendar/calendar.tsx](file://frontend/antd/calendar/calendar.tsx) +- [frontend/antd/card/Index.svelte](file://frontend/antd/card/Index.svelte) +- [frontend/antd/card/card.tsx](file://frontend/antd/card/card.tsx) +- [frontend/antd/card/grid/Index.svelte](file://frontend/antd/card/grid/Index.svelte) +- [frontend/antd/card/grid/card.grid.tsx](file://frontend/antd/card/grid/card.grid.tsx) +- [frontend/antd/card/meta/Index.svelte](file://frontend/antd/card/meta/Index.svelte) +- [frontend/antd/card/meta/card.meta.tsx](file://frontend/antd/card/meta/card.meta.tsx) +- [frontend/antd/grid/col/col.tsx](file://frontend/antd/grid/col/col.tsx) +- [frontend/antd/grid/row/row.tsx](file://frontend/antd/grid/row/row.tsx) +- [frontend/antd/grid/context.ts](file://frontend/antd/grid/context.ts) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +This document covers Calendar and Card components, providing complete instructions from architecture to implementation details. Key topics include: + +- Calendar component: scheduling, event marking, date selection, panel switching, special features of notification calendars (extended via slots and callbacks) +- Card component: basic structure, responsive layout with Card.Grid, content organization with Card.Meta, implementation methods for custom card content +- Localization: multilingual support and date localization based on ConfigProvider +- Interactions and callbacks: event callback handling, value change propagation +- Adaptability: adaptation strategies for different screen sizes and dynamic update mechanisms + +## Project Structure + +Calendar and Card components are located in the frontend Ant Design ecosystem, using Svelte + React wrappers (sveltify) to bridge Svelte components with Ant Design's React implementation. Each component provides: + +- Svelte entry file (Index.svelte): responsible for property forwarding, visibility control, slot collection, and async loading of React implementation +- React wrapper (\*.tsx): uses sveltify to wrap Ant Design components for Svelte use, handling function-type callbacks, slot rendering, and value formatting + +```mermaid +graph TB +subgraph "Calendar Component" +C_Index["calendar/Index.svelte"] +C_Tsx["calendar/calendar.tsx"] +end +subgraph "Card Component" +K_Index["card/Index.svelte"] +K_Tsx["card/card.tsx"] +end +subgraph "Card Sub-components" +G_Index["card/grid/Index.svelte"] +G_Tsx["card/grid/card.grid.tsx"] +M_Index["card/meta/Index.svelte"] +M_Tsx["card/meta/card.meta.tsx"] +end +subgraph "Grid System" +R_Tsx["grid/row/row.tsx"] +C_Tsx2["grid/col/col.tsx"] +Ctx["grid/context.ts"] +end +subgraph "Localization" +CP_Tsx["config-provider/config-provider.tsx"] +Locales["config-provider/locales.ts"] +end +C_Index --> C_Tsx +K_Index --> K_Tsx +G_Index --> G_Tsx +M_Index --> M_Tsx +R_Tsx --> C_Tsx2 +Ctx --> R_Tsx +CP_Tsx --> Locales +``` + +**Diagram Source** + +- [frontend/antd/calendar/Index.svelte:1-85](file://frontend/antd/calendar/Index.svelte#L1-L85) +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/card/Index.svelte:1-68](file://frontend/antd/card/Index.svelte#L1-L68) +- [frontend/antd/card/card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) +- [frontend/antd/card/grid/Index.svelte:1-63](file://frontend/antd/card/grid/Index.svelte#L1-L63) +- [frontend/antd/card/grid/card.grid.tsx:1-7](file://frontend/antd/card/grid/card.grid.tsx#L1-L7) +- [frontend/antd/card/meta/Index.svelte:1-60](file://frontend/antd/card/meta/Index.svelte#L1-L60) +- [frontend/antd/card/meta/card.meta.tsx:1-32](file://frontend/antd/card/meta/card.meta.tsx#L1-L32) +- [frontend/antd/grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [frontend/antd/grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts:1-800](file://frontend/antd/config-provider/locales.ts#L1-L800) + +**Section Source** + +- [frontend/antd/calendar/Index.svelte:1-85](file://frontend/antd/calendar/Index.svelte#L1-L85) +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/card/Index.svelte:1-68](file://frontend/antd/card/Index.svelte#L1-L68) +- [frontend/antd/card/card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) +- [frontend/antd/card/grid/Index.svelte:1-63](file://frontend/antd/card/grid/Index.svelte#L1-L63) +- [frontend/antd/card/grid/card.grid.tsx:1-7](file://frontend/antd/card/grid/card.grid.tsx#L1-L7) +- [frontend/antd/card/meta/Index.svelte:1-60](file://frontend/antd/card/meta/Index.svelte#L1-L60) +- [frontend/antd/card/meta/card.meta.tsx:1-32](file://frontend/antd/card/meta/card.meta.tsx#L1-L32) +- [frontend/antd/grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [frontend/antd/grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts:1-800](file://frontend/antd/config-provider/locales.ts#L1-L800) + +## Core Components + +- Calendar + - Supports date value formatting (second-level timestamp and dayjs conversion), disabled date filtering, cell render slots (cellRender/fullCellRender/headerRender), panel switching and selection event callbacks + - Value changes are synced upward via onValueChange for easy integration with Gradio and similar frameworks +- Card + - Provides slot-based rendering for title, extra content, cover image, action area and other regions; supports tab list and tab bar extension (tabProps.\* slots) + - Internally collects child items via context and dynamically composes them into Ant Design's Card component +- Card.Grid + - Serves as a grid container inside the card for holding child content and participating in responsive layout +- Card.Meta + - Provides slot-based rendering for title, description, and avatar, enabling flexible customization of card metadata +- Grid System (Row/Col) + - Row collects column items via context and maps children to Ant Design's Row/Col structure for responsive layout + +**Section Source** + +- [frontend/antd/calendar/calendar.tsx:10-15](file://frontend/antd/calendar/calendar.tsx#L10-L15) +- [frontend/antd/calendar/calendar.tsx:58-98](file://frontend/antd/calendar/calendar.tsx#L58-L98) +- [frontend/antd/card/card.tsx:36-146](file://frontend/antd/card/card.tsx#L36-L146) +- [frontend/antd/card/grid/card.grid.tsx:1-7](file://frontend/antd/card/grid/card.grid.tsx#L1-L7) +- [frontend/antd/card/meta/card.meta.tsx:5-29](file://frontend/antd/card/meta/card.meta.tsx#L5-L29) +- [frontend/antd/grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [frontend/antd/grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) + +## Architecture Overview + +The diagram below shows the bridging relationship between Calendar and Card components in Svelte and Ant Design, as well as key flows for slots and callbacks. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Component
Index.svelte" +participant Wrapper as "React Wrapper
sveltify" +participant Antd as "Ant Design Component" +participant Util as "Utility Functions
useFunction/renderParamsSlot" +Svelte->>Wrapper : Forward properties/visibility/slots +Wrapper->>Util : useFunction wraps callbacks +Wrapper->>Util : renderParamsSlot renders slots +Wrapper->>Antd : Render Antd component and pass props +Antd-->>Wrapper : Callback triggers onChange/onPanelChange/onSelect +Wrapper-->>Svelte : onValueChange syncs value +``` + +**Diagram Source** + +- [frontend/antd/calendar/Index.svelte:65-84](file://frontend/antd/calendar/Index.svelte#L65-L84) +- [frontend/antd/calendar/calendar.tsx:43-98](file://frontend/antd/calendar/calendar.tsx#L43-L98) +- [frontend/antd/card/Index.svelte:53-67](file://frontend/antd/card/Index.svelte#L53-L67) +- [frontend/antd/card/card.tsx:39-146](file://frontend/antd/card/card.tsx#L39-L146) + +## Detailed Component Analysis + +### Calendar + +- Properties and callbacks + - Input value and default value: supports second-level timestamps and dayjs objects, internally unified to dayjs + - Valid range: validRange is also formatted + - Callbacks: onChange/onPanelChange/onSelect convert dates to second-level timestamps before returning + - Slots: cellRender/fullCellRender/headerRender can inject custom rendering via slots +- Event marking and notification calendar + - Inject custom marks or badges via cellRender/fullCellRender slots + - onPanelChange can monitor month/year switching, combined with business logic to implement "notification calendar" scenarios (e.g., highlighting specific dates) +- Date selection and value sync + - onValueChange returns the currently selected date as a second-level timestamp to the parent for state management and persistence + +```mermaid +flowchart TD +Start(["Enter Calendar component"]) --> ParseValue["Parse input value
second-level timestamp -> dayjs"] +ParseValue --> ParseRange["Parse valid range
array -> dayjs[]"] +ParseRange --> RenderCalendar["Render Antd Calendar"] +RenderCalendar --> OnChange{"User selects date?"} +OnChange --> |Yes| ConvertSec["Convert date to second-level timestamp"] +ConvertSec --> CallCb["Trigger onChange/onSelect"] +CallCb --> OnValueChange["Trigger onValueChange to sync value"] +OnValueChange --> End(["Done"]) +OnChange --> |No| End +``` + +**Diagram Source** + +- [frontend/antd/calendar/calendar.tsx:47-98](file://frontend/antd/calendar/calendar.tsx#L47-L98) + +**Section Source** + +- [frontend/antd/calendar/Index.svelte:13-84](file://frontend/antd/calendar/Index.svelte#L13-L84) +- [frontend/antd/calendar/calendar.tsx:10-15](file://frontend/antd/calendar/calendar.tsx#L10-L15) +- [frontend/antd/calendar/calendar.tsx:47-98](file://frontend/antd/calendar/calendar.tsx#L47-L98) + +### Card + +- Basic structure + - Title, extra content, cover image, and action area can all be injected via slots + - Supports tab list tabList and tab bar extension (tabProps.\* slots), including indicator size, more menu, and left/right extra content +- Dynamic content and context + - Collects child items via useTabsItems and useTargets, dynamically injecting tabList and actions + - When Grid child items exist, controls placeholder grid visibility via containsGrid to ensure correct layout +- Custom content implementation + - Uses ReactSlot to render slot content, supporting complex nesting and conditional rendering + - The actions area preferentially uses collected targets, falling back to native props.actions + +```mermaid +classDiagram +class CardWrapper { ++props : AntdCardProps ++slots : Record ++containsGrid : boolean ++tabList : Tab[] ++tabProps : TabProps ++render() +} +class TabsContext { ++useTabsItems(keys) : Items +} +class TargetsContext { ++useTargets(children, slotName) : Target[] +} +CardWrapper --> TabsContext : "get tabList" +CardWrapper --> TargetsContext : "generate actions" +``` + +**Diagram Source** + +- [frontend/antd/card/card.tsx:36-146](file://frontend/antd/card/card.tsx#L36-L146) + +**Section Source** + +- [frontend/antd/card/Index.svelte:12-67](file://frontend/antd/card/Index.svelte#L12-L67) +- [frontend/antd/card/card.tsx:36-146](file://frontend/antd/card/card.tsx#L36-L146) + +### Card.Grid + +- Role + - Acts as a grid container inside the card, holding child content and participating in responsive layout +- Implementation + - Directly wraps Ant Design's Card.Grid, maintaining consistent behavior with Antd + +**Section Source** + +- [frontend/antd/card/grid/Index.svelte:19-59](file://frontend/antd/card/grid/Index.svelte#L19-L59) +- [frontend/antd/card/grid/card.grid.tsx:1-7](file://frontend/antd/card/grid/card.grid.tsx#L1-L7) + +### Card.Meta + +- Content organization + - Title, description, and avatar can all be injected via slots for flexible content organization +- Rendering mechanism + - Renders slots via ReactSlot; falls back to native props if not provided + +**Section Source** + +- [frontend/antd/card/meta/Index.svelte:19-59](file://frontend/antd/card/meta/Index.svelte#L19-L59) +- [frontend/antd/card/meta/card.meta.tsx:5-29](file://frontend/antd/card/meta/card.meta.tsx#L5-L29) + +### Grid System (Row/Col) + +- Responsive layout + - Row collects Col column items via context and maps children to Ant Design's Row/Col structure + - Col acts as ItemHandler, receiving properties from context and rendering +- Context mechanism + - Uses createItemsContext to create items context; Row/Col cooperate via useItems and withItemsContextProvider + +**Section Source** + +- [frontend/antd/grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [frontend/antd/grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + +## Dependency Analysis + +- Component coupling + - Both Calendar and Card bridge Ant Design components to Svelte via sveltify, reducing direct coupling + - Slots and callbacks are decoupled via useFunction and renderParamsSlot for easy extension +- External dependencies + - dayjs for date formatting and localization + - Ant Design provides UI capabilities and theme/localization resources +- Circular dependencies + - No obvious circular dependencies between components; context is passed in one direction only + +```mermaid +graph LR +Svelte_Index["Svelte Index.svelte"] --> React_Wrapper["React Wrapper sveltify"] +React_Wrapper --> Antd["Ant Design Component"] +React_Wrapper --> Utils["Utility Functions useFunction/renderParamsSlot"] +Antd --> Dayjs["dayjs localization"] +``` + +**Diagram Source** + +- [frontend/antd/calendar/Index.svelte:65-84](file://frontend/antd/calendar/Index.svelte#L65-L84) +- [frontend/antd/calendar/calendar.tsx:3-6](file://frontend/antd/calendar/calendar.tsx#L3-L6) +- [frontend/antd/card/Index.svelte:53-67](file://frontend/antd/card/Index.svelte#L53-L67) +- [frontend/antd/card/card.tsx:2-8](file://frontend/antd/card/card.tsx#L2-L8) + +**Section Source** + +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/card/card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) + +## Performance Considerations + +- Async loading and lazy rendering + - Svelte Index.svelte asynchronously imports the React implementation to reduce initial bundle size and first-screen blocking +- Callback function optimization + - Use useFunction to wrap callbacks to avoid unnecessary re-renders +- Value computation caching + - Use useMemo to cache dayjs values and valid ranges, reducing repeated computation costs +- Slot rendering + - renderParamsSlot only renders slot content when needed, avoiding unnecessary DOM updates + +**Section Source** + +- [frontend/antd/calendar/Index.svelte:65-84](file://frontend/antd/calendar/Index.svelte#L65-L84) +- [frontend/antd/calendar/calendar.tsx:43-57](file://frontend/antd/calendar/calendar.tsx#L43-L57) +- [frontend/antd/card/card.tsx:105-112](file://frontend/antd/card/card.tsx#L105-L112) + +## Troubleshooting Guide + +- Date not displayed or displayed incorrectly + - Check whether the input value is a second-level timestamp or an object parseable by dayjs + - Confirm whether validRange is a valid dayjs array +- Event callback not triggered + - Confirm whether onChange/onPanelChange/onSelect are correctly bound + - If using slot rendering, ensure slots do not override default behavior +- Slot content not working + - Confirm that slot key names are consistent with the slots supported by the component (e.g., cellRender/fullCellRender/headerRender/title/extra/cover, etc.) +- Localization not working + - Check ConfigProvider's locale settings and browser language environment + - Confirm whether the corresponding language pack exists in locales.ts + +**Section Source** + +- [frontend/antd/calendar/calendar.tsx:47-98](file://frontend/antd/calendar/calendar.tsx#L47-L98) +- [frontend/antd/card/card.tsx:113-132](file://frontend/antd/card/card.tsx#L113-L132) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts:1-800](file://frontend/antd/config-provider/locales.ts#L1-L800) + +## Conclusion + +Calendar and Card components achieve highly extensible UI capabilities through a unified bridging pattern and slot system: + +- Calendar supports date formatting, event callbacks, and slot extension for scheduling and notification calendar scenarios +- Card provides flexible content organization and dynamic layout capabilities, combined with the grid system for responsive design +- Localization and utility functions further improve internationalization and performance + +It is recommended to make full use of slot and callback mechanisms in actual projects, combined with context and utility functions, to build stable and maintainable interfaces. diff --git a/.wiki/en/Ant Design Components/Data Display Components/Carousel and Collapse.md b/.wiki/en/Ant Design Components/Data Display Components/Carousel and Collapse.md new file mode 100644 index 00000000..29a0504e --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Carousel and Collapse.md @@ -0,0 +1,317 @@ +# Carousel and Collapse + + +**Files Referenced in This Document** +- [carousel.tsx](file://frontend/antd/carousel/carousel.tsx) +- [Index.svelte](file://frontend/antd/carousel/Index.svelte) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [useTargets.ts](file://frontend/utils/hooks/useTargets.ts) +- [renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [collapse.tsx](file://frontend/antd/collapse/collapse.tsx) +- [Index.svelte](file://frontend/antd/collapse/Index.svelte) +- [context.ts](file://frontend/antd/collapse/context.ts) +- [collapse.item/Index.svelte](file://frontend/antd/collapse/item/Index.svelte) +- [__init__.py (carousel backend)](file://backend/modelscope_studio/components/antd/carousel/__init__.py) +- [__init__.py (collapse backend)](file://backend/modelscope_studio/components/antd/collapse/__init__.py) +- [basic.py (carousel demo)](file://docs/components/antd/carousel/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides a systematic explanation of the Ant Design **Carousel** and **Collapse** components, covering architecture and implementation details. Key topics include: + +- Carousel: autoplay, transition animations, indicator controls, vertical carousel configuration; recommended approaches for touch swipe, keyboard navigation, and accessibility; and backend parameter mapping. +- Collapse: expand/collapse for individual panels, accordion effect, dynamic loading of panel content, and state persistence; controlled vs. uncontrolled modes, custom panel headers, and animation configuration. + +## Project Structure + +- The frontend Svelte wrapper handles prop processing, slot rendering, and conditional display. +- The React layer bridges Ant Design components to Svelte via sveltify. +- The utility layer provides general capabilities such as function wrapping, target node extraction, and slot rendering. +- The backend Python component handles parameter forwarding and frontend directory resolution. + +```mermaid +graph TB +subgraph "Frontend" +A["carousel/Index.svelte"] +B["carousel/carousel.tsx"] +C["collapse/Index.svelte"] +D["collapse/collapse.tsx"] +E["collapse/item/Index.svelte"] +F["hooks/useFunction.ts"] +G["hooks/useTargets.ts"] +H["utils/renderItems.tsx"] +I["utils/renderParamsSlot.tsx"] +end +subgraph "Backend" +J["backend/.../carousel/__init__.py"] +K["backend/.../collapse/__init__.py"] +end +A --> B +C --> D +E --> D +B --> F +B --> G +D --> F +D --> H +D --> I +J --> A +K --> C +``` + +**Diagram Source** + +- [Index.svelte:1-66](file://frontend/antd/carousel/Index.svelte#L1-L66) +- [carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [Index.svelte:1-66](file://frontend/antd/collapse/Index.svelte#L1-L66) +- [collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [collapse.item/Index.svelte:1-95](file://frontend/antd/collapse/item/Index.svelte#L1-L95) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [**init**.py (carousel backend):45-94](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L45-L94) +- [**init**.py (collapse backend):54-98](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L54-L98) + +**Section Source** + +- [Index.svelte:1-66](file://frontend/antd/carousel/Index.svelte#L1-L66) +- [carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [Index.svelte:1-66](file://frontend/antd/collapse/Index.svelte#L1-L66) +- [collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [collapse.item/Index.svelte:1-95](file://frontend/antd/collapse/item/Index.svelte#L1-L95) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [**init**.py (carousel backend):45-94](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L45-L94) +- [**init**.py (collapse backend):54-98](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L54-L98) + +## Core Components + +- Carousel + - Frontend wrapper: receives props and slots, invokes Ant Design's Carousel, and renders child items via ReactSlot. + - Key points: afterChange/beforeChange are wrapped with useFunction; child item order is extracted and sorted by useTargets. +- Collapse + - Frontend wrapper: injects the items context via withItemsContextProvider, uses renderItems to convert slots into Ant Design's items structure; supports expandIcon as a slot or function. + - Collapse.Item: responsible for cloning and forwarding label/extra/children slots to the underlying component. + +**Section Source** + +- [carousel.tsx:8-29](file://frontend/antd/carousel/carousel.tsx#L8-L29) +- [Index.svelte:48-61](file://frontend/antd/carousel/Index.svelte#L48-L61) +- [collapse.tsx:10-50](file://frontend/antd/collapse/collapse.tsx#L10-L50) +- [collapse.item/Index.svelte:60-88](file://frontend/antd/collapse/item/Index.svelte#L60-L88) + +## Architecture Overview + +The following diagram shows the call chain from the frontend Svelte layer to the React Ant Design component, and the role of key utility functions. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Component" +participant Wrapper as "sveltify Wrapper" +participant UtilF as "useFunction" +participant UtilT as "useTargets" +participant AD as "Ant Design Carousel" +Svelte->>Wrapper : "Render and pass props/slots" +Wrapper->>UtilF : "Wrap afterChange/beforeChange" +Wrapper->>UtilT : "Extract and sort child targets" +Wrapper->>AD : "Render with wrapped callbacks and children" +AD-->>Wrapper : "Trigger callback/transition event" +Wrapper-->>Svelte : "Return result if needed" +``` + +**Diagram Source** + +- [carousel.tsx:9-25](file://frontend/antd/carousel/carousel.tsx#L9-L25) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) + +## Detailed Component Analysis + +### Carousel Component + +- Autoplay and Transition Animation + - Supports autoplay, autoplaySpeed, speed, easing, effect (e.g., fade), wait_for_animate, and other parameters; see backend initialization parameters for the corresponding backend mappings. + - The afterChange and beforeChange callbacks are wrapped with useFunction to ensure stable execution in the React environment. +- Indicator Controls + - Supports dots, dotPosition, dotPlacement, and other configurations; indicator styles can be controlled via root_class_name or additional class names. +- Vertical Carousel + - Vertical scrolling can be achieved via effect or related layout configurations (depending on Ant Design support and styles). +- Touch Swipe, Keyboard Navigation, and Accessibility + - It is recommended to enable draggable for touch swipe support; keyboard navigation and accessibility labels can be implemented using Ant Design's default behavior combined with custom aria-\* attributes. +- Child Item Rendering + - Child items are extracted by useTargets and sorted by slotIndex/subSlotIndex, then cloned and rendered as ReactSlot, ensuring correct order and visibility. + +```mermaid +flowchart TD +Start(["Start rendering"]) --> Extract["Extract child items
useTargets(children)"] +Extract --> Sort["Sort by index
slotIndex/subSlotIndex"] +Sort --> WrapCallbacks["Wrap callbacks
useFunction(afterChange/beforeChange)"] +WrapCallbacks --> Render["Render Ant Design Carousel"] +Render --> Children["Clone children
ReactSlot"] +Children --> End(["Done"]) +``` + +**Diagram Source** + +- [carousel.tsx:9-25](file://frontend/antd/carousel/carousel.tsx#L9-L25) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) + +**Section Source** + +- [carousel.tsx:8-29](file://frontend/antd/carousel/carousel.tsx#L8-L29) +- [Index.svelte:48-61](file://frontend/antd/carousel/Index.svelte#L48-L61) +- [**init**.py (carousel backend):45-94](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L45-L94) +- [basic.py (carousel demo):40-73](file://docs/components/antd/carousel/demos/basic.py#L40-L73) + +### Collapse Component + +- Single Panel and Accordion + - Use accordion to enable/disable accordion mode; activeKey/defaultActiveKey controls currently expanded panels (supports multiple or single selection). +- Dynamic Panel Content Loading + - Use the items context and renderItems to convert slots into items; destroy_on_hidden/destroy_inactive_panel can control panel destruction when hidden to save resources. +- Collapse State Persistence + - State persistence is implemented via the controlled prop activeKey; the onChange callback can be used to record state changes. +- Controlled and Uncontrolled Modes + - Uncontrolled: use defaultActiveKey; controlled: use activeKey and listen to onChange for updates. +- Custom Panel Header + - The label slot is used for custom headers; the extra slot is used for additional actions on the right; the expandIcon slot or function can customize the expand icon. +- Animation Configuration + - Appearance props such as size, bordered, and ghost can be combined with animation and transition effects; specific animation behavior follows Ant Design's default implementation. + +```mermaid +sequenceDiagram +participant S as "Svelte Collapse" +participant P as "withItemsContextProvider" +participant R as "renderItems" +participant RP as "renderParamsSlot" +participant C as "Ant Design Collapse" +S->>P : "Inject items context" +P->>R : "Convert slots to items" +S->>RP : "Render expandIcon slot" +S->>C : "Pass items, onChange, expandIcon" +C-->>S : "Trigger onChange(key)" +S-->>S : "Update controlled state/persist" +``` + +**Diagram Source** + +- [collapse.tsx:11-49](file://frontend/antd/collapse/collapse.tsx#L11-L49) +- [context.ts:1-7](file://frontend/antd/collapse/context.ts#L1-L7) +- [renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) +- [renderParamsSlot.tsx:5-49](file://frontend/utils/renderParamsSlot.tsx#L5-L49) + +**Section Source** + +- [collapse.tsx:10-50](file://frontend/antd/collapse/collapse.tsx#L10-L50) +- [collapse.item/Index.svelte:60-88](file://frontend/antd/collapse/item/Index.svelte#L60-L88) +- [context.ts:1-7](file://frontend/antd/collapse/context.ts#L1-L7) +- [**init**.py (collapse backend):54-98](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L54-L98) + +## Dependency Analysis + +- Carousel + - carousel.tsx depends on useFunction and useTargets; Index.svelte handles props and visibility. +- Collapse + - collapse.tsx depends on useFunction, renderItems, renderParamsSlot, and the items context; collapse.item/Index.svelte handles slot cloning and forwarding. +- Backend Mapping + - The backend Python components map parameters to frontend components, avoiding duplicated API definitions. + +```mermaid +graph LR +CF["carousel.tsx"] --> UF["useFunction.ts"] +CF --> UT["useTargets.ts"] +CI["Index.svelte(Carousel)"] --> CF +DF["collapse.tsx"] --> UF +DF --> RI["renderItems.tsx"] +DF --> RPS["renderParamsSlot.tsx"] +DI["Index.svelte(Collapse)"] --> DF +DII["collapse.item/Index.svelte"] --> DF +``` + +**Diagram Source** + +- [carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [Index.svelte:1-66](file://frontend/antd/carousel/Index.svelte#L1-L66) +- [Index.svelte:1-66](file://frontend/antd/collapse/Index.svelte#L1-L66) +- [collapse.item/Index.svelte:1-95](file://frontend/antd/collapse/item/Index.svelte#L1-L95) + +**Section Source** + +- [carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [Index.svelte:1-66](file://frontend/antd/carousel/Index.svelte#L1-L66) +- [Index.svelte:1-66](file://frontend/antd/collapse/Index.svelte#L1-L66) +- [collapse.item/Index.svelte:1-95](file://frontend/antd/collapse/item/Index.svelte#L1-L95) + +## Performance Considerations + +- Carousel + - Child item sorting and target extraction are performed inside useMemo to avoid unnecessary re-renders. + - ReactSlot is used for cloning and rendering; be mindful of the number and complexity of child items. +- Collapse + - Use destroy_on_hidden/destroy_inactive_panel to control panel destruction and reduce memory usage. + - renderItems performs recursive rendering of nested slots; avoid excessively deep nesting. +- General + - useFunction wraps callbacks to ensure stable function references and reduce side effects. + +[This section provides general guidance and does not directly analyze specific files; therefore no "Section Source" is included.] + +## Troubleshooting Guide + +- Carousel children not displayed + - Check that children are passed correctly; verify the useTargets filter logic and slotIndex configuration. +- Carousel callbacks not triggered + - Confirm that afterChange/beforeChange are wrapped with useFunction; check Ant Design version compatibility. +- Collapse items not taking effect + - Confirm that items are injected via slots or passed explicitly; check renderItems key generation and slot key names. +- Expand icon not displayed + - If using the expandIcon slot, ensure the slot exists and renderParamsSlot renders correctly; otherwise check that the expandIcon function is passed in. + +**Section Source** + +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) +- [renderParamsSlot.tsx:5-49](file://frontend/utils/renderParamsSlot.tsx#L5-L49) + +## Conclusion + +- Both Carousel and Collapse follow a unified architecture of "Svelte wrapper + Ant Design component + utility functions", offering good extensibility and maintainability. +- Carousel focuses on autoplay, transition animations, and indicator configuration; Collapse emphasizes controlled/uncontrolled modes, dynamic loading, and state persistence. +- It is recommended to combine demo scripts and backend parameter mappings to quickly implement feature requirements in real projects. + +[This section is a summary and does not directly analyze specific files; therefore no "Section Source" is included.] + +## Appendix + +- Parameter Reference + - Carousel: autoplay, autoplaySpeed, adaptiveHeight, dotPosition, dotPlacement, dots, draggable, fade, infinite, speed, easing, effect, afterChange, beforeChange, wait_for_animate, root_class_name. + - Collapse: accordion, activeKey/defaultActiveKey, bordered, collapsible, destroy_on_hidden, destroy_inactive_panel, expand_icon, expand_icon_position, expand_icon_placement, ghost, items, size, root_class_name. + +**Section Source** + +- [**init**.py (carousel backend):45-94](file://backend/modelscope_studio/components/antd/carousel/__init__.py#L45-L94) +- [**init**.py (collapse backend):54-98](file://backend/modelscope_studio/components/antd/collapse/__init__.py#L54-L98) +- [basic.py (carousel demo):40-73](file://docs/components/antd/carousel/demos/basic.py#L40-L73) diff --git a/.wiki/en/Ant Design Components/Data Display Components/Data Display Components.md b/.wiki/en/Ant Design Components/Data Display Components/Data Display Components.md new file mode 100644 index 00000000..9f05e7d7 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Data Display Components.md @@ -0,0 +1,664 @@ +# Data Display Components + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [frontend/antd/package.json](file://frontend/antd/package.json) +- [frontend/antd/avatar/avatar.tsx](file://frontend/antd/avatar/avatar.tsx) +- [frontend/antd/badge/badge.tsx](file://frontend/antd/badge/badge.tsx) +- [frontend/antd/calendar/calendar.tsx](file://frontend/antd/calendar/calendar.tsx) +- [frontend/antd/card/card.tsx](file://frontend/antd/card/card.tsx) +- [frontend/antd/carousel/carousel.tsx](file://frontend/antd/carousel/carousel.tsx) +- [frontend/antd/collapse/collapse.tsx](file://frontend/antd/collapse/collapse.tsx) +- [frontend/antd/descriptions/descriptions.tsx](file://frontend/antd/descriptions/descriptions.tsx) +- [frontend/antd/empty/empty.tsx](file://frontend/antd/empty/empty.tsx) +- [frontend/antd/image/image.tsx](file://frontend/antd/image/image.tsx) +- [frontend/antd/list/list.tsx](file://frontend/antd/list/list.tsx) +- [frontend/antd/popover/popover.tsx](file://frontend/antd/popover/popover.tsx) +- [frontend/antd/qr_code/qr-code.tsx](file://frontend/antd/qr_code/qr-code.tsx) +- [frontend/antd/segmented/segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [frontend/antd/statistic/statistic.tsx](file://frontend/antd/statistic/statistic.tsx) +- [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) +- [frontend/antd/tabs/tabs.tsx](file://frontend/antd/tabs/tabs.tsx) +- [frontend/antd/tag/tag.tsx](file://frontend/antd/tag/tag.tsx) +- [frontend/antd/timeline/timeline.tsx](file://frontend/antd/timeline/timeline.tsx) +- [frontend/antd/tooltip/tooltip.tsx](file://frontend/antd/tooltip/tooltip.tsx) +- [frontend/antd/tour/tour.tsx](file://frontend/antd/tour/tour.tsx) +- [frontend/antd/tree/tree.tsx](file://frontend/antd/tree/tree.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document covers Ant Design data display components, systematically covering Avatar, Badge, Calendar, Card, Carousel, Collapse, Descriptions, Empty, Image, List, Popover, QRCode, Segmented, Statistic, Table, Tabs, Tag, Timeline, Tooltip, Tour, and Tree components and their implementation and usage in this repository. Key topics include: + +- Data rendering: how to map child nodes to Ant Design component children/items via slots and items. +- Interaction behavior: unified handling of event callbacks (such as onChange/onSelect) and function wrapping (useFunction). +- Animation effects: provided by Ant Design natively; the component layer does not add additional animation wrapping. +- Large data optimization: recommended to adopt virtual scrolling, pagination, lazy loading, and other strategies, combined with component extensibility for secondary wrapping. +- Theme customization and style overrides: achieved through Ant Design's theme variable and CSS variable system. +- Responsive and mobile adaptation: follows Ant Design's grid and breakpoint strategies, combined with Svelte component size control. + +## Project Structure + +This repository uses a dual-layer wrapping pattern of "backend Python module + frontend Svelte package": + +- The backend module is responsible for exporting each component class for unified reference in a Python environment. +- The frontend Svelte package bridges Ant Design React components as Svelte components via sveltify, supporting declarative rendering of slots and items. + +```mermaid +graph TB +subgraph "Backend" +PY_API["Python Export Module
__init__.py / components.py"] +end +subgraph "Frontend" +PKG["Svelte Package
package.json"] +AVATAR["Avatar
avatar.tsx"] +BADGE["Badge
badge.tsx"] +CALENDAR["Calendar
calendar.tsx"] +CARD["Card
card.tsx"] +CAROUSEL["Carousel
carousel.tsx"] +COLLAPSE["Collapse
collapse.tsx"] +DESC["Descriptions
descriptions.tsx"] +EMPTY["Empty
empty.tsx"] +IMAGE["Image
image.tsx"] +LIST["List
list.tsx"] +POPOVER["Popover
popover.tsx"] +QRCODE["QRCode
qr-code.tsx"] +SEG["Segmented
segmented.tsx"] +STAT["Statistic
statistic.tsx"] +TABLE["Table
table.tsx"] +TABS["Tabs
tabs.tsx"] +TAG["Tag
tag.tsx"] +TIME["Timeline
timeline.tsx"] +TT["Tooltip
tooltip.tsx"] +TOUR["Tour
tour.tsx"] +TREE["Tree
tree.tsx"] +end +PY_API --> AVATAR +PY_API --> BADGE +PY_API --> CALENDAR +PY_API --> CARD +PY_API --> CAROUSEL +PY_API --> COLLAPSE +PY_API --> DESC +PY_API --> EMPTY +PY_API --> IMAGE +PY_API --> LIST +PY_API --> POPOVER +PY_API --> QRCODE +PY_API --> SEG +PY_API --> STAT +PY_API --> TABLE +PY_API --> TABS +PY_API --> TAG +PY_API --> TIME +PY_API --> TT +PY_API --> TOUR +PY_API --> TREE +PKG --> AVATAR +PKG --> BADGE +PKG --> CALENDAR +PKG --> CARD +PKG --> CAROUSEL +PKG --> COLLAPSE +PKG --> DESC +PKG --> EMPTY +PKG --> IMAGE +PKG --> LIST +PKG --> POPOVER +PKG --> QRCODE +PKG --> SEG +PKG --> STAT +PKG --> TABLE +PKG --> TABS +PKG --> TAG +PKG --> TIME +PKG --> TT +PKG --> TOUR +PKG --> TREE +``` + +Diagram Source + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) + +Section Source + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) + +## Core Components + +This section outlines the bridging approach and key features of each component on the frontend: + +- Unified bridging: all components wrap Ant Design React components as Svelte components via sveltify, supporting declarative rendering of slots and items. +- Function callbacks: use useFunction to wrap callbacks such as onChange/onSelect to ensure correct execution in the Svelte context. +- Date and range: format and convert date-type props to ensure consistency with timestamps passed in from the parent. +- Sub-item rendering: achieve unified mapping of items and children via renderItems and useTargets. + +Section Source + +- [frontend/antd/avatar/avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [frontend/antd/badge/badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/card/card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) +- [frontend/antd/carousel/carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [frontend/antd/collapse/collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) + +## Architecture Overview + +The diagram below shows the overall flow from backend export to frontend component bridging, as well as utility functions and contexts shared between components. + +```mermaid +sequenceDiagram +participant Py as "Backend Export Module" +participant Svelte as "Svelte Component" +participant AD as "Ant Design React" +participant Util as "Utility Functions" +Py->>Svelte : Export component class +Svelte->>Util : useFunction/useTargets/renderItems +Svelte->>AD : sveltify wrapping and pass props/slots +AD-->>Svelte : Render result and callback triggers +Svelte-->>Py : Complete data display via slots/items +``` + +Diagram Source + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [frontend/antd/avatar/avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/card/card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) +- [frontend/antd/carousel/carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [frontend/antd/collapse/collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) + +## Detailed Component Analysis + +### Avatar + +- Data rendering: supports rendering icon and src via slots; if not provided, falls back to children. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design; component layer does not add additional wrapping. + +```mermaid +flowchart TD +Start(["Enter Avatar"]) --> CheckSlots["Check slots: icon / src"] +CheckSlots --> HasSlots{"Slots exist?"} +HasSlots --> |Yes| RenderSlots["Render slot content"] +HasSlots --> |No| Fallback["Fall back to children"] +RenderSlots --> Render["Render Ant Design Avatar"] +Fallback --> Render +Render --> End(["Done"]) +``` + +Diagram Source + +- [frontend/antd/avatar/avatar.tsx:6-25](file://frontend/antd/avatar/avatar.tsx#L6-L25) + +Section Source + +- [frontend/antd/avatar/avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) + +### Badge + +- Data rendering: count and text support custom slots. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +```mermaid +flowchart TD +Start(["Enter Badge"]) --> CountSlot["count has slot?"] +CountSlot --> |Yes| RenderCount["Render count slot"] +CountSlot --> |No| UseCount["Use props.count"] +TextSlot["text has slot?"] +TextSlot --> |Yes| RenderText["Render text slot"] +TextSlot --> |No| UseText["Use props.text"] +RenderCount --> Render["Render Ant Design Badge"] +UseCount --> Render +RenderText --> Render +UseText --> Render +Render --> End(["Done"]) +``` + +Diagram Source + +- [frontend/antd/badge/badge.tsx:6-18](file://frontend/antd/badge/badge.tsx#L6-L18) + +Section Source + +- [frontend/antd/badge/badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) + +### Calendar + +- Data rendering: value/defaultValue/validRange are formatted with dayjs; cellRender/fullCellRender/headerRender support slots. +- Interaction behavior: onChange/onPanelChange/onSelect callbacks are uniformly wrapped via useFunction; internally converts dates to second-level timestamps before returning to the parent. +- Animation effects: provided by Ant Design. + +```mermaid +sequenceDiagram +participant UI as "User Interface" +participant Comp as "Calendar Component" +participant Util as "useFunction/formatDayjs" +participant AD as "Ant Design Calendar" +UI->>Comp : Pass value/defaultValue/validRange +Comp->>Util : Format date +Comp->>AD : Render and bind callbacks +AD-->>Comp : onChange/onPanelChange/onSelect triggered +Comp->>UI : Convert to second-level timestamp and callback +``` + +Diagram Source + +- [frontend/antd/calendar/calendar.tsx:17-99](file://frontend/antd/calendar/calendar.tsx#L17-L99) + +Section Source + +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) + +### Card + +- Data rendering: title/extra/cover/tabBarExtraContent support slots; actions are auto-collected via useTargets; tabList is rendered via renderItems. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +```mermaid +flowchart TD +Start(["Enter Card"]) --> Actions["Collect actions slots"] +Actions --> Tabs["Parse tabList and tabProps"] +Tabs --> Slots["Parse title/extra/cover and other slots"] +Slots --> Render["Render Ant Design Card"] +Render --> End(["Done"]) +``` + +Diagram Source + +- [frontend/antd/card/card.tsx:37-147](file://frontend/antd/card/card.tsx#L37-L147) + +Section Source + +- [frontend/antd/card/card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) + +### Carousel + +- Data rendering: children are collected via useTargets, then cloned and rendered as ReactSlot. +- Interaction behavior: afterChange/beforeChange are wrapped via useFunction. +- Animation effects: provided by Ant Design. + +```mermaid +sequenceDiagram +participant Comp as "Carousel Component" +participant Util as "useTargets/useFunction" +participant AD as "Ant Design Carousel" +Comp->>Util : Collect children and clone +Comp->>AD : Render and bind callbacks +AD-->>Comp : Before/after switch callbacks +Comp-->>Comp : Execute wrapped callbacks +``` + +Diagram Source + +- [frontend/antd/carousel/carousel.tsx:8-29](file://frontend/antd/carousel/carousel.tsx#L8-L29) + +Section Source + +- [frontend/antd/carousel/carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) + +### Collapse + +- Data rendering: items are rendered via renderItems; expandIcon supports slots. +- Interaction behavior: onChange is wrapped via useFunction. +- Animation effects: provided by Ant Design. + +```mermaid +flowchart TD +Start(["Enter Collapse"]) --> Items["Parse items or slots.default/items"] +Items --> ExpandIcon["expandIcon has slot?"] +ExpandIcon --> |Yes| RenderIcon["Render slot"] +ExpandIcon --> |No| UseIcon["Use props.expandIcon"] +RenderIcon --> Render["Render Ant Design Collapse"] +UseIcon --> Render +Render --> End(["Done"]) +``` + +Diagram Source + +- [frontend/antd/collapse/collapse.tsx:11-50](file://frontend/antd/collapse/collapse.tsx#L11-L50) + +Section Source + +- [frontend/antd/collapse/collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) + +### Descriptions + +- Data rendering: title/extra support slots; items are rendered via renderItems. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +```mermaid +flowchart TD +Start(["Enter Descriptions"]) --> Resolve["Resolve items or slots.default/items"] +Resolve --> Render["Render Ant Design Descriptions"] +Render --> End(["Done"]) +``` + +Diagram Source + +- [frontend/antd/descriptions/descriptions.tsx:10-38](file://frontend/antd/descriptions/descriptions.tsx#L10-L38) + +Section Source + +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) + +### Empty + +- Data rendering: description/image support slots; image supports default value and custom. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +```mermaid +flowchart TD +Start(["Enter Empty"]) --> Desc["description has slot?"] +Desc --> |Yes| RenderDesc["Render slot"] +Desc --> |No| UseDesc["Use props.description"] +Image["image has slot?"] +Image --> |Yes| RenderImg["Render slot"] +Image --> |No| CheckDefault["Determine default or custom"] +RenderDesc --> Render["Render Ant Design Empty"] +UseDesc --> Render +RenderImg --> Render +CheckDefault --> Render +Render --> End(["Done"]) +``` + +Diagram Source + +- [frontend/antd/empty/empty.tsx:6-49](file://frontend/antd/empty/empty.tsx#L6-L49) + +Section Source + +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) + +### Image + +- Data rendering: supports preview group and slots. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/image/image.tsx:1-200](file://frontend/antd/image/image.tsx#L1-L200) + +### List + +- Data rendering: supports custom item rendering and action areas. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/list/list.tsx:1-200](file://frontend/antd/list/list.tsx#L1-L200) + +### Popover + +- Data rendering: supports slots for trigger and content areas. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/popover/popover.tsx:1-200](file://frontend/antd/popover/popover.tsx#L1-L200) + +### QRCode + +- Data rendering: supports content and style configuration. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/qr_code/qr-code.tsx:1-200](file://frontend/antd/qr_code/qr-code.tsx#L1-L200) + +### Segmented + +- Data rendering: supports options and slots. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/segmented/segmented.tsx:1-200](file://frontend/antd/segmented/segmented.tsx#L1-L200) + +### Statistic + +- Data rendering: supports custom titles and values. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/statistic/statistic.tsx:1-200](file://frontend/antd/statistic/statistic.tsx#L1-L200) + +### Table + +- Data rendering: supports complex structures including column definitions, expandable rows, and row selection. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/table/table.tsx:1-200](file://frontend/antd/table/table.tsx#L1-L200) + +### Tabs + +- Data rendering: supports slots for tab items and extra content. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/tabs/tabs.tsx:1-200](file://frontend/antd/tabs/tabs.tsx#L1-L200) + +### Tag + +- Data rendering: supports checkable tags and slots. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/tag/tag.tsx:1-200](file://frontend/antd/tag/tag.tsx#L1-L200) + +### Timeline + +- Data rendering: supports timeline items and slots. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/timeline/timeline.tsx:1-200](file://frontend/antd/timeline/timeline.tsx#L1-L200) + +### Tooltip + +- Data rendering: supports slots for trigger and content areas. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/tooltip/tooltip.tsx:1-200](file://frontend/antd/tooltip/tooltip.tsx#L1-L200) + +### Tour + +- Data rendering: supports steps and slots. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/tour/tour.tsx:1-200](file://frontend/antd/tour/tour.tsx#L1-L200) + +### Tree + +- Data rendering: supports directory tree and node rendering. +- Interaction behavior: no interaction events. +- Animation effects: provided by Ant Design. + +Section Source + +- [frontend/antd/tree/tree.tsx:1-200](file://frontend/antd/tree/tree.tsx#L1-L200) + +## Dependency Analysis + +- Component coupling: all components depend on Ant Design React version; unified wrapping via sveltify reduces the complexity of directly using React. +- Utility functions: tools such as useFunction/useTargets/renderItems/renderParamsSlot run throughout multiple components, improving reusability and consistency. +- Context: some components (such as Collapse/Descriptions/Tabs) introduce an items context for unified declaration and rendering of items. + +```mermaid +graph LR +Util["Utility Functions
useFunction/useTargets/renderItems"] --> AV["Avatar"] +Util --> BG["Badge"] +Util --> CA["Calendar"] +Util --> CR["Card"] +Util --> CL["Carousel"] +Util --> CP["Collapse"] +Util --> DS["Descriptions"] +Util --> EM["Empty"] +Util --> IM["Image"] +Util --> LI["List"] +Util --> PP["Popover"] +Util --> QC["QRCode"] +Util --> SG["Segmented"] +Util --> ST["Statistic"] +Util --> TB["Table"] +Util --> TS["Tabs"] +Util --> TG["Tag"] +Util --> TM["Timeline"] +Util --> TT["Tooltip"] +Util --> TR["Tree"] +``` + +Diagram Source + +- [frontend/antd/avatar/avatar.tsx:1-28](file://frontend/antd/avatar/avatar.tsx#L1-L28) +- [frontend/antd/badge/badge.tsx:1-21](file://frontend/antd/badge/badge.tsx#L1-L21) +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/card/card.tsx:1-150](file://frontend/antd/card/card.tsx#L1-L150) +- [frontend/antd/carousel/carousel.tsx:1-32](file://frontend/antd/carousel/carousel.tsx#L1-L32) +- [frontend/antd/collapse/collapse.tsx:1-53](file://frontend/antd/collapse/collapse.tsx#L1-L53) +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) +- [frontend/antd/image/image.tsx:1-200](file://frontend/antd/image/image.tsx#L1-L200) +- [frontend/antd/list/list.tsx:1-200](file://frontend/antd/list/list.tsx#L1-L200) +- [frontend/antd/popover/popover.tsx:1-200](file://frontend/antd/popover/popover.tsx#L1-L200) +- [frontend/antd/qr_code/qr-code.tsx:1-200](file://frontend/antd/qr_code/qr-code.tsx#L1-L200) +- [frontend/antd/segmented/segmented.tsx:1-200](file://frontend/antd/segmented/segmented.tsx#L1-L200) +- [frontend/antd/statistic/statistic.tsx:1-200](file://frontend/antd/statistic/statistic.tsx#L1-L200) +- [frontend/antd/table/table.tsx:1-200](file://frontend/antd/table/table.tsx#L1-L200) +- [frontend/antd/tabs/tabs.tsx:1-200](file://frontend/antd/tabs/tabs.tsx#L1-L200) +- [frontend/antd/tag/tag.tsx:1-200](file://frontend/antd/tag/tag.tsx#L1-L200) +- [frontend/antd/timeline/timeline.tsx:1-200](file://frontend/antd/timeline/timeline.tsx#L1-L200) +- [frontend/antd/tooltip/tooltip.tsx:1-200](file://frontend/antd/tooltip/tooltip.tsx#L1-L200) +- [frontend/antd/tree/tree.tsx:1-200](file://frontend/antd/tree/tree.tsx#L1-L200) + +Section Source + +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) + +## Performance Considerations + +- Large data display recommendations + - Virtual scrolling: prioritize container components with virtual scrolling capabilities (such as List/Table), rendering only visible area elements. + - Pagination and lazy loading: use pagination or scroll-to-bottom loading for long lists to reduce one-time rendering pressure. + - Event throttling: use throttle/debounce for high-frequency interactions (such as scrolling, zooming) to avoid frequent re-renders. + - Rendering optimization: move complex computations to the backend or cache them; the frontend only does lightweight rendering. +- Animation and transitions + - Ant Design components have built-in smooth transitions; the component layer does not add additional animations to avoid performance degradation from overlapping. +- Theming and styles + - Use Ant Design's theme variables and CSS variable system to reduce repeated style computations. + - Avoid dynamically generating large amounts of inline styles within components; prefer class names and CSS Modules. + +## Troubleshooting Guide + +- Date parameter anomaly + - Symptom: calendar component date display or callback timestamp is inconsistent. + - Diagnosis: confirm whether value/defaultValue/validRange passed in are valid timestamps or values parseable by dayjs; check whether the formatting logic is effective. +- Callback not triggered + - Symptom: callbacks such as onChange/onSelect are not executed. + - Diagnosis: confirm whether useFunction correctly wraps the callback; check the priority relationship between slots and props. +- Slots not working + - Symptom: title/extra/actions, etc. are not rendered as expected. + - Diagnosis: confirm that slot names are consistent with component conventions; check whether renderItems and useTargets are used correctly. +- Style override not working + - Symptom: custom styles do not take effect. + - Diagnosis: confirm CSS scope and !important usage; prefer theme variables and controlled style objects. + +Section Source + +- [frontend/antd/calendar/calendar.tsx:17-99](file://frontend/antd/calendar/calendar.tsx#L17-L99) +- [frontend/antd/card/card.tsx:37-147](file://frontend/antd/card/card.tsx#L37-L147) +- [frontend/antd/carousel/carousel.tsx:8-29](file://frontend/antd/carousel/carousel.tsx#L8-L29) +- [frontend/antd/collapse/collapse.tsx:11-50](file://frontend/antd/collapse/collapse.tsx#L11-L50) +- [frontend/antd/descriptions/descriptions.tsx:10-38](file://frontend/antd/descriptions/descriptions.tsx#L10-L38) +- [frontend/antd/empty/empty.tsx:6-49](file://frontend/antd/empty/empty.tsx#L6-L49) + +## Conclusion + +This repository seamlessly integrates Ant Design React components into the Svelte ecosystem through unified sveltify bridging and utility functions, achieving: + +- Declarative data rendering (slots/items) +- Consistent interaction callbacks (useFunction) +- Easy-to-extend theming and style overrides +- Good performance and maintainability + +For large data scenarios, it is recommended to combine virtual scrolling, pagination, and lazy loading strategies to further improve user experience and performance. + +## Appendix + +- Component list and corresponding file paths + - Avatar: [frontend/antd/avatar/avatar.tsx](file://frontend/antd/avatar/avatar.tsx) + - Badge: [frontend/antd/badge/badge.tsx](file://frontend/antd/badge/badge.tsx) + - Calendar: [frontend/antd/calendar/calendar.tsx](file://frontend/antd/calendar/calendar.tsx) + - Card: [frontend/antd/card/card.tsx](file://frontend/antd/card/card.tsx) + - Carousel: [frontend/antd/carousel/carousel.tsx](file://frontend/antd/carousel/carousel.tsx) + - Collapse: [frontend/antd/collapse/collapse.tsx](file://frontend/antd/collapse/collapse.tsx) + - Descriptions: [frontend/antd/descriptions/descriptions.tsx](file://frontend/antd/descriptions/descriptions.tsx) + - Empty: [frontend/antd/empty/empty.tsx](file://frontend/antd/empty/empty.tsx) + - Image: [frontend/antd/image/image.tsx](file://frontend/antd/image/image.tsx) + - List: [frontend/antd/list/list.tsx](file://frontend/antd/list/list.tsx) + - Popover: [frontend/antd/popover/popover.tsx](file://frontend/antd/popover/popover.tsx) + - QRCode: [frontend/antd/qr_code/qr-code.tsx](file://frontend/antd/qr_code/qr-code.tsx) + - Segmented: [frontend/antd/segmented/segmented.tsx](file://frontend/antd/segmented/segmented.tsx) + - Statistic: [frontend/antd/statistic/statistic.tsx](file://frontend/antd/statistic/statistic.tsx) + - Table: [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) + - Tabs: [frontend/antd/tabs/tabs.tsx](file://frontend/antd/tabs/tabs.tsx) + - Tag: [frontend/antd/tag/tag.tsx](file://frontend/antd/tag/tag.tsx) + - Timeline: [frontend/antd/timeline/timeline.tsx](file://frontend/antd/timeline/timeline.tsx) + - Tooltip: [frontend/antd/tooltip/tooltip.tsx](file://frontend/antd/tooltip/tooltip.tsx) + - Tour: [frontend/antd/tour/tour.tsx](file://frontend/antd/tour/tour.tsx) + - Tree: [frontend/antd/tree/tree.tsx](file://frontend/antd/tree/tree.tsx) +- Backend exports + - [backend/modelscope_studio/components/antd/**init**.py](file://backend/modelscope_studio/components/antd/__init__.py) + - [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- Frontend package info + - [frontend/antd/package.json](file://frontend/antd/package.json) diff --git a/.wiki/en/Ant Design Components/Data Display Components/Descriptions and Empty.md b/.wiki/en/Ant Design Components/Data Display Components/Descriptions and Empty.md new file mode 100644 index 00000000..79aced65 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Descriptions and Empty.md @@ -0,0 +1,350 @@ +# Descriptions and Empty + + +**Files Referenced in This Document** +- [frontend/antd/descriptions/descriptions.tsx](file://frontend/antd/descriptions/descriptions.tsx) +- [frontend/antd/descriptions/item/Index.svelte](file://frontend/antd/descriptions/item/Index.svelte) +- [frontend/antd/descriptions/context.ts](file://frontend/antd/descriptions/context.ts) +- [frontend/antd/empty/empty.tsx](file://frontend/antd/empty/empty.tsx) +- [frontend/antd/grid/row/row.tsx](file://frontend/antd/grid/row/row.tsx) +- [frontend/antd/grid/col/col.tsx](file://frontend/antd/grid/col/col.tsx) +- [frontend/antd/grid/context.ts](file://frontend/antd/grid/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) +- [docs/components/antd/descriptions/README.md](file://docs/components/antd/descriptions/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on two commonly used UI components: **Descriptions** and **Empty**. It provides an in-depth analysis from the perspectives of system architecture, component relationships, data flow and processing logic, integration points and error handling, and performance characteristics. Based on the existing implementation in the repository, it also provides actionable usage recommendations and best practices. Topics covered include: + +- Descriptions: key-value pair display, responsive layout, label alignment, and custom configuration of description items +- Empty: default icons, custom icons, helper text, and combining action buttons +- Descriptions in form detail pages, multi-language support for labels, and internationalization of empty state +- Grid-based layout for Descriptions and user experience optimization with Empty during data load failures + +## Project Structure + +This project uses a layered and component-based frontend structure. Descriptions and Empty are located under the antd frontend component directory, and use common utilities and context mechanisms to enable flexible slot and child item management. + +```mermaid +graph TB +subgraph "Descriptions" +DRoot["descriptions.tsx"] +DItem["item/Index.svelte"] +DContext["context.ts"] +end +subgraph "Empty" +ERoot["empty.tsx"] +end +subgraph "Grid System" +GRow["grid/row/row.tsx"] +GCol["grid/col/col.tsx"] +GContext["grid/context.ts"] +end +subgraph "Common Utilities" +Ctx["utils/createItemsContext.tsx"] +Locales["config-provider/locales.ts"] +end +DRoot --> DContext +DItem --> DContext +DContext --> Ctx +GRow --> GContext +GCol --> GContext +GContext --> Ctx +ERoot --> Locales +``` + +Diagram Source + +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [frontend/antd/descriptions/item/Index.svelte:1-83](file://frontend/antd/descriptions/item/Index.svelte#L1-L83) +- [frontend/antd/descriptions/context.ts:1-7](file://frontend/antd/descriptions/context.ts#L1-L7) +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) +- [frontend/antd/grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [frontend/antd/grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) + +Section Source + +- [docs/components/antd/descriptions/README.md:1-9](file://docs/components/antd/descriptions/README.md#L1-L9) + +## Core Components + +- Descriptions + - Responsible for displaying a set of key-value pairs in a read-only grouped format, with support for titles, extra areas, and slot-based content injection. + - Collects internal description items via context and item handlers, and ultimately renders them as an Ant Design Descriptions component. +- Descriptions.Item + - A child item of Descriptions, responsible for receiving visibility, style, ID, class name, and other props, and passing child content to the underlying component via slots. +- Empty + - Provides an empty state placeholder with default, simple, or custom icons; supports custom description text and style functions to improve the experience when data is empty or fails to load. +- Grid System (Grid.Row/Col) + - Uses a context mechanism to collect column children and map them to Ant Design's Row/Col, enabling a grid-based layout for Descriptions. + +Section Source + +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [frontend/antd/descriptions/item/Index.svelte:1-83](file://frontend/antd/descriptions/item/Index.svelte#L1-L83) +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) +- [frontend/antd/grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [frontend/antd/grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +## Architecture Overview + +Both Descriptions and Empty work based on a unified "slot and child item context" mechanism: + +- The context provider is responsible for collecting structured information (props, slots, elements, etc.) from child items and transforming them into the data structures required by Ant Design during the rendering phase. +- Slots allow users to inject custom content in the form of ReactSlot or Svelte Slot, such as titles, extra areas, and description item content. +- When rendering, the Empty component selects the appropriate icon based on the passed image type or slot, and merges style functions with inline styles. + +```mermaid +sequenceDiagram +participant U as "User Code" +participant D as "Descriptions(React)" +participant Ctx as "ItemsContextProvider" +participant Item as "Descriptions.Item(Svelte)" +participant AD as "Antd.Descriptions" +U->>D : Render Descriptions and pass props/slots +D->>Ctx : Wrap with context provider +U->>Item : Place multiple Items inside Descriptions +Item->>Ctx : Register child items via ItemHandler +Ctx-->>D : Aggregate items list +D->>AD : Pass items, title, extra to Antd.Descriptions +AD-->>U : Rendering complete +``` + +Diagram Source + +- [frontend/antd/descriptions/descriptions.tsx:10-38](file://frontend/antd/descriptions/descriptions.tsx#L10-L38) +- [frontend/antd/descriptions/context.ts:1-7](file://frontend/antd/descriptions/context.ts#L1-L7) +- [frontend/antd/descriptions/item/Index.svelte:56-76](file://frontend/antd/descriptions/item/Index.svelte#L56-L76) +- [frontend/utils/createItemsContext.tsx:171-184](file://frontend/utils/createItemsContext.tsx#L171-L184) + +## Detailed Component Analysis + +### Descriptions Component + +- Key-Value Pair Display + - Child items are collected via context and ultimately generate the items array required by Ant Design Descriptions; supports directly passing items or auto-aggregating from child items. +- Responsive Layout + - Can be combined with the Grid System (Grid.Row/Col) for responsive layout; column children inside a Row are mapped to Antd Col for adaptive arrangement at breakpoints. +- Label Alignment + - The component itself does not directly control label alignment, but can pass through props for Antd Descriptions to handle; alignment is transparently forwarded at the Svelte layer. +- Custom Configuration of Description Items + - Supports visible for controlling display, elem_id/elem_classes/elem_style for setting DOM attributes and styles, additionalProps for additional attributes, and as_item for custom render types. +- Slots, Title, and Extra Area + - Supports title and extra slots for injecting custom titles and extra action areas; falls back to props if not provided. + +```mermaid +classDiagram +class Descriptions { ++props : "Antd Descriptions Props" ++slots : "title, extra, default" ++items : "Array or child item collection" ++render() +} +class DescriptionsItem { ++visible : "Visibility flag" ++elem_id : "DOM ID" ++elem_classes : "CSS classes" ++elem_style : "Inline styles" ++additionalProps : "Additional props" ++as_item : "Render type" ++slots : "children etc." ++itemIndex : "Index" ++itemSlotKey : "Slot key" +} +class ItemsContext { ++items : "Child items grouped by slot" ++setItem() ++initial : "Initialization flag" +} +Descriptions --> ItemsContext : "uses" +DescriptionsItem --> ItemsContext : "registers/collects" +``` + +Diagram Source + +- [frontend/antd/descriptions/descriptions.tsx:10-38](file://frontend/antd/descriptions/descriptions.tsx#L10-L38) +- [frontend/antd/descriptions/item/Index.svelte:18-76](file://frontend/antd/descriptions/item/Index.svelte#L18-L76) +- [frontend/antd/descriptions/context.ts:1-7](file://frontend/antd/descriptions/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:40-95](file://frontend/utils/createItemsContext.tsx#L40-L95) + +Section Source + +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [frontend/antd/descriptions/item/Index.svelte:1-83](file://frontend/antd/descriptions/item/Index.svelte#L1-L83) +- [frontend/antd/descriptions/context.ts:1-7](file://frontend/antd/descriptions/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +### Empty Component + +- Default and Custom Icons + - Supports three built-in icon types as well as custom images; the image slot takes priority when present. +- Helper Text + - The description slot has higher priority than props.description, making it easy to dynamically render localized text or complex content. +- Style and Layout + - Supports passing style functions or objects; internally sets the image style to inline-block to ensure consistent alignment of icons and text. +- Combining Action Buttons + - Interactive elements such as buttons can be combined within the description slot to create a complete "empty state + action" flow. + +```mermaid +flowchart TD +Start(["Enter Empty render"]) --> CheckImage["Check if image slot exists"] +CheckImage --> |Yes| UseSlotImage["Use slot image"] +CheckImage --> |No| SwitchImage["Select type based on props.image"] +SwitchImage --> |Built-in constant| UseAntdDefault["Use Antd default icon"] +SwitchImage --> |Simple built-in| UseAntdSimple["Use Antd simple icon"] +SwitchImage --> |Other| UseCustom["Use custom image"] +UseSlotImage --> RenderDesc["Render description slot or props.description"] +UseAntdDefault --> RenderDesc +UseAntdSimple --> RenderDesc +UseCustom --> RenderDesc +RenderDesc --> MergeStyles["Merge style function and object
ensure icon is inline-block"] +MergeStyles --> End(["Rendering complete"]) +``` + +Diagram Source + +- [frontend/antd/empty/empty.tsx:9-49](file://frontend/antd/empty/empty.tsx#L9-L49) + +Section Source + +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) + +### Grid-Based Layout (Grid.Row/Col) + +- Row maps collected column children to Antd Col and renders them inside the Row to achieve responsive grid layout. +- Col receives column props and slots via ItemHandler and forwards them to Antd Col. +- When combined with Descriptions, description items can be nested inside Row/Col to form a "grid-based Descriptions". + +```mermaid +sequenceDiagram +participant U as "User Code" +participant R as "Grid.Row(React)" +participant Ctx as "Grid ItemsContext" +participant C as "Grid.Col(React)" +participant AD as "Antd.Row/Col" +U->>R : Render Row +R->>Ctx : Use context provider +U->>C : Place multiple Col inside Row +C->>Ctx : Register column children via ItemHandler +Ctx-->>R : Aggregate column items +R->>AD : Render Row and map Col +AD-->>U : Grid layout complete +``` + +Diagram Source + +- [frontend/antd/grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [frontend/antd/grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:171-184](file://frontend/utils/createItemsContext.tsx#L171-L184) + +Section Source + +- [frontend/antd/grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [frontend/antd/grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + +## Dependency Analysis + +- Descriptions Dependencies + - Uses the context capability provided by createItemsContext to bridge Svelte slots and React components, enabling items collection and rendering. + - Wraps the component with withItemsContextProvider to ensure child item registration and updates. +- Empty Dependencies + - Depends on Ant Design's Empty component and built-in icon constants; style function and object merging ensures consistent alignment of icons and text. +- Internationalization Dependencies + - Provides multi-language environments through the config-provider's locales, supporting localization switching for both Antd and dayjs. + +```mermaid +graph LR +D["Descriptions"] --> Ctx["createItemsContext"] +DItem["Descriptions.Item"] --> Ctx +E["Empty"] --> AD["Antd.Empty"] +E --> Locales["locales.ts"] +subgraph "Context Utilities" +Ctx +end +subgraph "Antd Components" +AD +end +subgraph "Internationalization" +Locales +end +``` + +Diagram Source + +- [frontend/antd/descriptions/descriptions.tsx:1-10](file://frontend/antd/descriptions/descriptions.tsx#L1-L10) +- [frontend/antd/descriptions/item/Index.svelte:1-15](file://frontend/antd/descriptions/item/Index.svelte#L1-L15) +- [frontend/antd/empty/empty.tsx:1-9](file://frontend/antd/empty/empty.tsx#L1-L9) +- [frontend/antd/config-provider/locales.ts:1-10](file://frontend/antd/config-provider/locales.ts#L1-L10) + +Section Source + +- [frontend/antd/descriptions/descriptions.tsx:1-41](file://frontend/antd/descriptions/descriptions.tsx#L1-L41) +- [frontend/antd/empty/empty.tsx:1-52](file://frontend/antd/empty/empty.tsx#L1-L52) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) + +## Performance Considerations + +- Child Item Collection and Rendering + - Both Descriptions and the Grid System collect child items via context, avoiding unnecessary re-renders; only the corresponding component's recalculation is triggered when items update. +- Slots and Styles + - Slot content is rendered lazily, mounting only when visible; style function and object merging occurs at render time — it is recommended to reuse style objects as much as possible to reduce overhead. +- Icons and Descriptions + - Icon selection and style merging logic for the Empty component is simple with low performance overhead; it is recommended to use built-in icons in scenarios with many empty states to reduce resource loading. + +## Troubleshooting Guide + +- Descriptions shows no content + - Check whether withItemsContextProvider is correctly wrapping Descriptions, and that Descriptions.Item is placed inside it. + - Confirm that child items have been registered via ItemHandler and that the items list is not empty. +- Description items not taking effect + - Check whether visible, elem_id, elem_classes, elem_style, additionalProps, and other props are passed correctly. + - Confirm that the children slot is correctly bound and rendered. +- Empty state icon not displayed + - If passing an image slot, ensure the slot content is valid; otherwise check whether props.image is a built-in constant or a valid custom value. + - Confirm that the object returned by the style function contains the correct image styles. +- Grid layout issues + - Check whether Grid.Row/Col children are correctly registered; confirm that column props and slots are properly forwarded. + +Section Source + +- [frontend/antd/descriptions/descriptions.tsx:10-38](file://frontend/antd/descriptions/descriptions.tsx#L10-L38) +- [frontend/antd/descriptions/item/Index.svelte:56-76](file://frontend/antd/descriptions/item/Index.svelte#L56-L76) +- [frontend/antd/empty/empty.tsx:9-49](file://frontend/antd/empty/empty.tsx#L9-L49) +- [frontend/antd/grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [frontend/antd/grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) + +## Conclusion + +The Descriptions and Empty components achieve flexible content injection and rendering through a unified context and slot mechanism. Descriptions supports key-value pair display and grid-based layout; Empty provides placeholder solutions with both default and custom icons, and can be combined with action buttons to optimize user experience. Combined with internationalization tools, both can operate stably in multi-language environments. It is recommended to prioritize using Descriptions for displaying read-only information in form detail pages, and to use the Empty component to improve usability when data is empty or fails to load. + +## Appendix + +- Usage Scenario Recommendations + - Form detail pages: Use Descriptions to display read-only fields, optionally combined with the Grid System for responsive layout. + - Data load failures: Use the Empty component to display prompts and retry buttons to improve user confidence. +- Multi-language Support + - Switch Antd and dayjs localization through the config-provider's locales to ensure text and formatting in Descriptions and Empty match the target language. +- Best Practices + - Use slots and props appropriately; avoid creating new objects frequently in render functions. + - For scenarios with many empty states, prefer built-in icons to reduce resource overhead. + - In grid-based layouts, divide column widths and breakpoints carefully to ensure readability across different devices. diff --git a/.wiki/en/Ant Design Components/Data Display Components/Image and List.md b/.wiki/en/Ant Design Components/Data Display Components/Image and List.md new file mode 100644 index 00000000..a1dac268 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Image and List.md @@ -0,0 +1,324 @@ +# Image and List + + +**Files Referenced in This Document** +- [frontend/antd/image/image.tsx](file://frontend/antd/image/image.tsx) +- [frontend/antd/image/preview-group/image.preview-group.tsx](file://frontend/antd/image/preview-group/image.preview-group.tsx) +- [frontend/antd/image/preview-group/Index.svelte](file://frontend/antd/image/preview-group/Index.svelte) +- [frontend/antd/list/list.tsx](file://frontend/antd/list/list.tsx) +- [frontend/antd/list/item/list.item.tsx](file://frontend/antd/list/item/list.item.tsx) +- [frontend/antd/list/item/Index.svelte](file://frontend/antd/list/item/Index.svelte) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/hooks/useTargets.ts](file://frontend/utils/hooks/useTargets.ts) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the **Image** and **List** component families, systematically reviewing their encapsulation approach at the frontend layer, capability boundaries, and extension points. Based on the existing repository implementation, it provides actionable usage recommendations and best practices. Key topics include: + +- Image component: batch viewing via preview groups, lazy loading, error handling, and the availability and limitations of image cropping; current state and extension paths for zoom controls, rotation, and download support. +- List component: basic list structure, list item metadata (meta), vertical list layout, and dynamic data binding; current state and extension paths for virtual scrolling, infinite loading, and data filtering; adaptive display and responsive layout design across different devices. + +## Project Structure + +The frontend uses a Svelte + Ant Design combination pattern for Image and List components: + +- Component entry points are exported via Svelte files, with sveltify internally bridging Ant Design's React components into a Svelte-compatible form. +- Preview groups and list items are lazy-loaded via importComponent, combined with the slots mechanism for flexible rendering extensions. +- Utility functions and hooks provide general capabilities: function wrapping, parameterized slot rendering, and target node extraction. + +```mermaid +graph TB +subgraph "Image Component" +IMG_TS["image.tsx
Wraps Ant Design Image"] +PG_IDX["preview-group/Index.svelte
Preview group entry"] +PG_IMPL["preview-group/image.preview-group.tsx
Preview group implementation"] +end +subgraph "List Component" +LIST_TS["list.tsx
Wraps Ant Design List"] +ITEM_IDX["item/Index.svelte
List item entry"] +ITEM_IMPL["item/list.item.tsx
List item implementation"] +end +subgraph "Utilities and Hooks" +USE_FN["useFunction.ts
Function wrapping"] +USE_TGT["useTargets.ts
Target node extraction"] +RENDER_SLOT["renderParamsSlot.tsx
Parameterized slot rendering"] +end +IMG_TS --> PG_IMPL +PG_IDX --> PG_IMPL +LIST_TS --> ITEM_IMPL +ITEM_IDX --> ITEM_IMPL +IMG_TS --> USE_FN +PG_IMPL --> USE_FN +LIST_TS --> USE_FN +ITEM_IMPL --> USE_FN +LIST_TS --> RENDER_SLOT +ITEM_IMPL --> RENDER_SLOT +ITEM_IMPL --> USE_TGT +``` + +**Diagram Source** + +- [frontend/antd/image/image.tsx:1-89](file://frontend/antd/image/image.tsx#L1-L89) +- [frontend/antd/image/preview-group/Index.svelte:1-72](file://frontend/antd/image/preview-group/Index.svelte#L1-L72) +- [frontend/antd/image/preview-group/image.preview-group.tsx:1-55](file://frontend/antd/image/preview-group/image.preview-group.tsx#L1-L55) +- [frontend/antd/list/list.tsx:1-36](file://frontend/antd/list/list.tsx#L1-L36) +- [frontend/antd/list/item/Index.svelte:1-60](file://frontend/antd/list/item/Index.svelte#L1-L60) +- [frontend/antd/list/item/list.item.tsx:1-29](file://frontend/antd/list/item/list.item.tsx#L1-L29) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/hooks/useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +**Section Source** + +- [frontend/antd/image/image.tsx:1-89](file://frontend/antd/image/image.tsx#L1-L89) +- [frontend/antd/image/preview-group/Index.svelte:1-72](file://frontend/antd/image/preview-group/Index.svelte#L1-L72) +- [frontend/antd/image/preview-group/image.preview-group.tsx:1-55](file://frontend/antd/image/preview-group/image.preview-group.tsx#L1-L55) +- [frontend/antd/list/list.tsx:1-36](file://frontend/antd/list/list.tsx#L1-L36) +- [frontend/antd/list/item/Index.svelte:1-60](file://frontend/antd/list/item/Index.svelte#L1-L60) +- [frontend/antd/list/item/list.item.tsx:1-29](file://frontend/antd/list/item/list.item.tsx#L1-L29) + +## Core Components + +- Image: Wraps Ant Design's Image component via sveltify, supporting placeholders, preview configuration, and slot extensions. The preview group provides batch viewing capability, with support for custom masks, close icons, and toolbars. +- List: Wraps Ant Design's List component via sveltify, supporting headers/footers, load-more, and custom render items. List items support extra areas and action collections, with useTargets automatically extracting child nodes carrying specific slotKeys. + +**Section Source** + +- [frontend/antd/image/image.tsx:14-86](file://frontend/antd/image/image.tsx#L14-L86) +- [frontend/antd/image/preview-group/image.preview-group.tsx:13-52](file://frontend/antd/image/preview-group/image.preview-group.tsx#L13-L52) +- [frontend/antd/list/list.tsx:8-33](file://frontend/antd/list/list.tsx#L8-L33) +- [frontend/antd/list/item/list.item.tsx:6-26](file://frontend/antd/list/item/list.item.tsx#L6-L26) + +## Architecture Overview + +The following diagram shows the call chain and slot extension points of the Image and List components at the frontend layer: + +```mermaid +sequenceDiagram +participant U as "User" +participant IMG as "Image Component
image.tsx" +participant PG as "Preview Group
image.preview-group.tsx" +participant LIST as "List Component
list.tsx" +participant ITEM as "ListItem Component
list.item.tsx" +U->>IMG : "Click image" +IMG->>PG : "Trigger preview group" +PG-->>U : "Batch view / toolbar / mask" +U->>LIST : "Render list" +LIST->>ITEM : "Render each item" +ITEM-->>U : "Extra area / action collection" +``` + +**Diagram Source** + +- [frontend/antd/image/image.tsx:24-85](file://frontend/antd/image/image.tsx#L24-L85) +- [frontend/antd/image/preview-group/image.preview-group.tsx:18-51](file://frontend/antd/image/preview-group/image.preview-group.tsx#L18-L51) +- [frontend/antd/list/list.tsx:11-32](file://frontend/antd/list/list.tsx#L11-L32) +- [frontend/antd/list/item/list.item.tsx:9-25](file://frontend/antd/list/item/list.item.tsx#L9-L25) + +## Detailed Component Analysis + +### Image Component + +- Batch Viewing (Preview Group) + - The preview group achieves on-demand loading via lazy imports and conditional rendering, reducing the initial load burden. + - Supports custom masks, close icons, and toolbars; toolbar and image rendering can be injected via slots or function callbacks. + - The mount location of the preview container can be customized via getContainer, making it easy to embed in a specific DOM container. +- Lazy Loading and Error Handling + - The current implementation does not explicitly declare lazy loading and error handling logic; if needed, these can be enhanced at the business layer using native browser attributes or third-party libraries. +- Image Cropping + - This implementation does not expose cropping-related parameters; if cropping is needed, resources can be pre-processed at the business layer or a dedicated cropping library can be introduced. +- Zoom Controls, Rotation, and Download Support + - The current implementation does not have built-in zoom, rotation, or download buttons; corresponding controls can be added via the custom toolbar slot in combination with external libraries. +- Slots and Function Wrapping + - useFunction is used to stabilize passed-in functions; renderParamsSlot supports passing parameters to slot render functions, improving flexibility. + +```mermaid +flowchart TD +Start(["Enter Image render"]) --> CheckPreview["Detect if preview is enabled"] +CheckPreview --> |Yes| BuildPreview["Build preview config
merge slots and functions"] +CheckPreview --> |No| SkipPreview["Disable preview"] +BuildPreview --> SlotsCheck{"Custom slots present?"} +SlotsCheck --> |Yes| RenderSlots["Render custom slots"] +SlotsCheck --> |No| UseDefault["Use default preview behavior"] +RenderSlots --> End(["Done"]) +UseDefault --> End +SkipPreview --> End +``` + +**Diagram Source** + +- [frontend/antd/image/image.tsx:24-85](file://frontend/antd/image/image.tsx#L24-L85) +- [frontend/antd/image/preview-group/image.preview-group.tsx:18-51](file://frontend/antd/image/preview-group/image.preview-group.tsx#L18-L51) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/renderParamsSlot.tsx:5-50](file://frontend/utils/renderParamsSlot.tsx#L5-L50) + +**Section Source** + +- [frontend/antd/image/image.tsx:14-86](file://frontend/antd/image/image.tsx#L14-L86) +- [frontend/antd/image/preview-group/image.preview-group.tsx:13-52](file://frontend/antd/image/preview-group/image.preview-group.tsx#L13-L52) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +### List Component + +- Basic List Structure and Dynamic Data Binding + - Wraps Ant Design List via sveltify, supporting headers/footers, load-more, and custom render items. + - Render items can be passed via slots or injected as functions, enabling flexible data binding and view rendering. +- List Item and Metadata (meta) + - List items support "extra areas" and "action collections"; action collections are automatically extracted from child nodes carrying specific slotKeys using useTargets, ensuring controllable order and indexing. +- Vertical List Layout + - Uses Ant Design's default vertical layout strategy, suitable for most scenarios; for horizontal or grid layouts, use styles or layout components at the business layer. + +```mermaid +classDiagram +class List_tsx { ++slots : footer/header/loadMore/renderItem ++render() : ReactNode +} +class ListItem_tsx { ++slots : extra/actions ++useTargets(children, slotKey) ++render() : ReactNode +} +List_tsx --> ListItem_tsx : "Renders each item" +``` + +**Diagram Source** + +- [frontend/antd/list/list.tsx:8-33](file://frontend/antd/list/list.tsx#L8-L33) +- [frontend/antd/list/item/list.item.tsx:6-26](file://frontend/antd/list/item/list.item.tsx#L6-L26) +- [frontend/utils/hooks/useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) + +**Section Source** + +- [frontend/antd/list/list.tsx:8-33](file://frontend/antd/list/list.tsx#L8-L33) +- [frontend/antd/list/item/list.item.tsx:6-26](file://frontend/antd/list/item/list.item.tsx#L6-L26) +- [frontend/utils/hooks/useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) + +### Preview Group + +- Batch Viewing and Visibility Control + - The preview group entry uses Svelte lazy imports and visibility checks to render the actual component only when needed, reducing initial overhead. + - Supports controlling preview visibility change events via props, enabling synchronization with parent state. +- Slots and Container Mounting + - Supports custom masks and close icons; container mounting location is customized via getContainer, making it easy to embed in a specified container. + +```mermaid +sequenceDiagram +participant IDX as "Preview Group Entry
Index.svelte" +participant CMP as "Preview Group Implementation
image.preview-group.tsx" +IDX->>IDX : "Check visibility" +IDX->>CMP : "Lazy import and render" +CMP-->>IDX : "Output preview group" +``` + +**Diagram Source** + +- [frontend/antd/image/preview-group/Index.svelte:55-71](file://frontend/antd/image/preview-group/Index.svelte#L55-L71) +- [frontend/antd/image/preview-group/image.preview-group.tsx:18-51](file://frontend/antd/image/preview-group/image.preview-group.tsx#L18-L51) + +**Section Source** + +- [frontend/antd/image/preview-group/Index.svelte:14-71](file://frontend/antd/image/preview-group/Index.svelte#L14-L71) +- [frontend/antd/image/preview-group/image.preview-group.tsx:18-52](file://frontend/antd/image/preview-group/image.preview-group.tsx#L18-L52) + +## Dependency Analysis + +- Components and Utility Functions + - Both Image and List components depend on useFunction for function stabilization, ensuring callbacks are not recreated when props change. + - List items depend on useTargets to extract child nodes with specific slotKeys, enabling automatic assembly of action collections. + - renderParamsSlot provides parameterized slot rendering, supporting parameter passing to slots with forced cloning to ensure rendering consistency across multiple renders. +- Inter-Component Coupling + - Image preview group and Image component are decoupled: the preview group exists as an independent component and collaborates with the Image component via props and slots. + - List items and the List component are decoupled: list items use lazy imports and slots for independent rendering, reducing coupling. + +```mermaid +graph LR +IMG["image.tsx"] --> UF["useFunction.ts"] +PG["image.preview-group.tsx"] --> UF +LIST["list.tsx"] --> UF +ITEM["list.item.tsx"] --> UF +ITEM --> UT["useTargets.ts"] +LIST --> RS["renderParamsSlot.tsx"] +ITEM --> RS +``` + +**Diagram Source** + +- [frontend/antd/image/image.tsx:3-4](file://frontend/antd/image/image.tsx#L3-L4) +- [frontend/antd/image/preview-group/image.preview-group.tsx:3-4](file://frontend/antd/image/preview-group/image.preview-group.tsx#L3-L4) +- [frontend/antd/list/list.tsx:4-5](file://frontend/antd/list/list.tsx#L4-L5) +- [frontend/antd/list/item/list.item.tsx:3-4](file://frontend/antd/list/item/list.item.tsx#L3-L4) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/hooks/useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +**Section Source** + +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/hooks/useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +## Performance Considerations + +- On-Demand Loading and Lazy Imports + - Both preview groups and list items use lazy import strategies, rendering only when visible, which helps reduce initial load and memory usage. +- Function Stabilization + - useFunction memoizes callbacks to avoid recreation due to prop changes, reducing re-render costs. +- Slot Rendering Optimization + - renderParamsSlot enforces cloning and parameter forwarding, ensuring deterministic and reusable slot rendering while reducing unnecessary repeated computation. + +**Section Source** + +- [frontend/antd/image/preview-group/Index.svelte:55-71](file://frontend/antd/image/preview-group/Index.svelte#L55-L71) +- [frontend/antd/list/item/Index.svelte:46-59](file://frontend/antd/list/item/Index.svelte#L46-L59) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/renderParamsSlot.tsx:23-49](file://frontend/utils/renderParamsSlot.tsx#L23-L49) + +## Troubleshooting Guide + +- Preview group not displayed + - Check the visibility props and the entry component's visibility logic to confirm that the preview group has been lazy-loaded and rendered. + - If using a custom mask or close icon, confirm that the slot is correctly passed in and has not been overridden. +- Toolbar/image rendering not working + - Confirm that passed-in functions are wrapped with useFunction to prevent failures due to function reference changes. + - If using slots, confirm that parameter passing to renderParamsSlot is correct. +- List item action collection is empty + - Check whether child nodes carry the correct slotKey and index information to ensure useTargets can extract them correctly. +- Performance issues + - If frequent re-renders occur, check whether callbacks or slot content are being changed frequently in the parent component; it is recommended to use useFunction or stabilization strategies. + +**Section Source** + +- [frontend/antd/image/preview-group/Index.svelte:55-71](file://frontend/antd/image/preview-group/Index.svelte#L55-L71) +- [frontend/antd/image/preview-group/image.preview-group.tsx:18-51](file://frontend/antd/image/preview-group/image.preview-group.tsx#L18-L51) +- [frontend/antd/list/item/list.item.tsx:10-21](file://frontend/antd/list/item/list.item.tsx#L10-L21) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/renderParamsSlot.tsx:23-49](file://frontend/utils/renderParamsSlot.tsx#L23-L49) + +## Conclusion + +- The Image component achieves batch viewing and flexible slot extensions via the preview group; the current implementation does not have built-in lazy loading, error handling, cropping, zoom, rotation, or download features, but offers good extensibility. +- The List component provides basic structure and dynamic binding capabilities; list item action collections are automatically assembled via useTargets, making it suitable for combining with styles and layout at the business layer to achieve responsive and adaptive display. +- In terms of performance, components generally adopt lazy import and function stabilization strategies, helping to maintain good runtime efficiency in complex scenarios. + +## Appendix + +- Extension Recommendations + - Image: Introduce lazy loading and error handling strategies at the business layer; for cropping, zoom, rotation, and download, combine external libraries with custom toolbar slots. + - List: Introduce virtual scrolling and infinite loading at the business layer; data filtering can be achieved through external state and render conditions; responsive layout can be adapted for multiple devices via style and breakpoint strategies. diff --git a/.wiki/en/Ant Design Components/Data Display Components/Popover and QRCode.md b/.wiki/en/Ant Design Components/Data Display Components/Popover and QRCode.md new file mode 100644 index 00000000..33d4eecc --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Popover and QRCode.md @@ -0,0 +1,332 @@ +# Popover and QRCode + + +**Files Referenced in This Document** +- [popover.tsx](file://frontend/antd/popover/popover.tsx) +- [Index.svelte (Popover)](file://frontend/antd/popover/Index.svelte) +- [__init__.py (AntdPopover)](file://backend/modelscope_studio/components/antd/popover/__init__.py) +- [README-zh_CN.md (Popover docs)](file://docs/components/antd/popover/README-zh_CN.md) +- [README.md (Popover docs)](file://docs/components/antd/popover/README.md) +- [qr-code.tsx](file://frontend/antd/qr-code/qr-code.tsx) +- [Index.svelte (QRCode)](file://frontend/antd/qr-code/Index.svelte) +- [__init__.py (AntdQRCode)](file://backend/modelscope_studio/components/antd/qr_code/__init__.py) +- [README-zh_CN.md (QRCode docs)](file://docs/components/antd/qr_code/README-zh_CN.md) +- [README.md (QRCode docs)](file://docs/components/antd/qr_code/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides a comprehensive explanation of the **Popover** and **QRCode** components, from underlying implementation to usage at the application layer. Topics covered include: + +- Popover: trigger modes, position control, content customization, animation integration, nested usage, delayed display, accessibility support, and more +- QRCode: encoded content, size and margin, color and background, error correction level, icon overlay, dynamic refresh, custom styles, and print optimization +- Complex layout positioning strategies and mobile scanning experience recommendations + +## Project Structure + +Both components follow a unified layered design of "backend component class + frontend Svelte wrapper + React encapsulation": + +- The backend component class handles parameter validation, event binding, example values, and render switches +- The frontend Svelte layer handles prop forwarding, slot processing, and visibility control +- The React encapsulation layer bridges with Ant Design components and supports slot and function callback conversion + +```mermaid +graph TB +subgraph "Backend" +BPY["AntdPopover.__init__"] +BQRY["AntdQRCode.__init__"] +end +subgraph "Frontend Svelte" +PIdx["Popover/Index.svelte"] +QIdx["QRCode/Index.svelte"] +end +subgraph "React Encapsulation" +PR["Popover/popover.tsx"] +QR["QRCode/qr-code.tsx"] +end +subgraph "Ant Design" +ADPop["antd.Popover"] +ADQR["antd.QRCode"] +end +BPY --> PIdx +BQRY --> QIdx +PIdx --> PR +QIdx --> QR +PR --> ADPop +QR --> ADQR +``` + +Diagram Source + +- [**init**.py (AntdPopover):10-124](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L124) +- [Index.svelte (Popover):10-72](file://frontend/antd/popover/Index.svelte#L10-L72) +- [popover.tsx:7-34](file://frontend/antd/popover/popover.tsx#L7-L34) +- [**init**.py (AntdQRCode):10-96](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L10-L96) +- [Index.svelte (QRCode):10-63](file://frontend/antd/qr-code/Index.svelte#L10-L63) +- [qr-code.tsx:6-20](file://frontend/antd/qr-code/qr-code.tsx#L6-L20) + +Section Source + +- [**init**.py (AntdPopover):10-124](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L124) +- [Index.svelte (Popover):10-72](file://frontend/antd/popover/Index.svelte#L10-L72) +- [popover.tsx:7-34](file://frontend/antd/popover/popover.tsx#L7-L34) +- [**init**.py (AntdQRCode):10-96](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L10-L96) +- [Index.svelte (QRCode):10-63](file://frontend/antd/qr-code/Index.svelte#L10-L63) +- [qr-code.tsx:6-20](file://frontend/antd/qr-code/qr-code.tsx#L6-L20) + +## Core Components + +- Popover + - Supports multiple trigger modes: hover, focus, click, context menu + - Supports 12 placement positions: top/bottom/left/right and four corners + - Supports title and content slots for injecting arbitrary content + - Supports open state change event binding + - Supports custom container mount point and delayed display control +- QRCode + - Supports canvas/svg output types + - Supports foreground color, background color, border, icon overlay, and margin + - Supports four error correction levels: L/M/Q/H + - Supports status render slot and refresh event binding + +Section Source + +- [**init**.py (AntdPopover):43-59](file://backend/modelscope_studio/components/antd/popover/__init__.py#L43-L59) +- [**init**.py (AntdQRCode):29-40](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L29-L40) + +## Architecture Overview + +The following diagram shows the call chain from the backend component class to the frontend Svelte wrapper, then to the React encapsulation layer and Ant Design. + +```mermaid +sequenceDiagram +participant Backend as "Backend Component Class" +participant Svelte as "Svelte Wrapper" +participant ReactWrap as "React Encapsulation" +participant AntD as "Ant Design" +Backend->>Svelte : Pass parameters and events +Svelte->>ReactWrap : Forward props/slots/visibility +ReactWrap->>AntD : Render and bind events +AntD-->>ReactWrap : Interaction results/state changes +ReactWrap-->>Svelte : Return callbacks/state +Svelte-->>Backend : Trigger events/update state +``` + +Diagram Source + +- [**init**.py (AntdPopover):14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) +- [Index.svelte (Popover):24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- [popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) +- [**init**.py (AntdQRCode):15-19](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L15-L19) +- [Index.svelte (QRCode):22-45](file://frontend/antd/qr-code/Index.svelte#L22-L45) +- [qr-code.tsx:6-20](file://frontend/antd/qr-code/qr-code.tsx#L6-L20) + +## Detailed Component Analysis + +### Popover Component + +- Trigger Modes + - Supports hover/focus/click/contextMenu and their combinations + - Entry/leave delays can be controlled via delay parameters +- Position Control + - Supports top/left/right/bottom and all nine grid positions + - Supports overflow auto-adjustment and arrow configuration +- Content Customization + - Supports title/content slots for rendering arbitrary content + - Supports overlay style and inner style +- Animation and Events + - Provides the open_change event for listening to open state changes + - Supports custom container mount points for precise positioning in complex layouts +- Nested Usage + - Avoid z-index conflicts by customizing the container mount point + - Be careful to avoid focus issues caused by multiple layered popovers activating simultaneously +- Delayed Display + - Control the display timing using entry/leave delay parameters +- Accessibility Support + - Recommended to combine with aria-\* attributes and keyboard navigation + - Pay attention to semantic labels and description text in nested scenarios + +```mermaid +classDiagram +class AntdPopover { ++EVENTS ++SLOTS ++placement ++trigger ++mouse_enter_delay ++mouse_leave_delay ++overlay_style ++overlay_inner_style ++get_popup_container ++open_change +} +class PopoverWrapper { ++slots ++afterOpenChange ++getPopupContainer ++children +} +AntdPopover --> PopoverWrapper : "prop forwarding" +``` + +Diagram Source + +- [**init**.py (AntdPopover):14-105](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L105) +- [popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) + +Section Source + +- [**init**.py (AntdPopover):23-105](file://backend/modelscope_studio/components/antd/popover/__init__.py#L23-L105) +- [Index.svelte (Popover):24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- [popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) +- [README-zh_CN.md (Popover docs):1-8](file://docs/components/antd/popover/README-zh_CN.md#L1-L8) +- [README.md (Popover docs):1-8](file://docs/components/antd/popover/README.md#L1-L8) + +### QRCode Component + +- Encoded Content and Size + - value: the encoded content of the QR code + - size: overall size; margin_size: outer margin; bordered: whether to show a border +- Color and Style + - color: foreground color; bg_color: background color; type: canvas/svg output +- Error Correction and Enhancement + - error_level: four correction levels L/M/Q/H + - boost_level: enhance recognition capability (boolean) +- Icon Overlay and Status + - icon: center icon URL; icon_size: icon size or size configuration + - status: active/expired/loading/scanned states + - statusRender: status render slot +- Dynamic Updates and Events + - refresh event: used to trigger QR code regeneration +- Custom Styles and Print Optimization + - Theme adaptation via styles and class names + - For print scenarios, it is recommended to use fixed sizes and high-contrast colors + +```mermaid +classDiagram +class AntdQRCode { ++EVENTS ++SLOTS ++value ++size ++color ++bg_color ++type ++bordered ++error_level ++boost_level ++icon ++icon_size ++margin_size ++status ++statusRender ++refresh +} +class QRWrapper { ++slots ++statusRender ++value +} +AntdQRCode --> QRWrapper : "prop forwarding" +``` + +Diagram Source + +- [**init**.py (AntdQRCode):15-77](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L15-L77) +- [qr-code.tsx:6-20](file://frontend/antd/qr-code/qr-code.tsx#L6-L20) + +Section Source + +- [**init**.py (AntdQRCode):24-77](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L24-L77) +- [Index.svelte (QRCode):22-45](file://frontend/antd/qr-code/Index.svelte#L22-L45) +- [qr-code.tsx:6-20](file://frontend/antd/qr-code/qr-code.tsx#L6-L20) +- [README-zh_CN.md (QRCode docs):1-8](file://docs/components/antd/qr_code/README-zh_CN.md#L1-L8) +- [README.md (QRCode docs):1-8](file://docs/components/antd/qr_code/README.md#L1-L8) + +## Dependency Analysis + +- Backend Component Class and Frontend Wrapper + - The backend class defines parameters and events; the frontend Svelte layer is responsible for the final assembly of props and slots +- React Encapsulation and Ant Design + - The React encapsulation layer converts slots into renderable nodes and safely passes callback functions to Ant Design components +- Event Binding + - Popover: open_change + - QRCode: refresh + +```mermaid +graph LR +BE["Backend Component Class"] --> FE["Svelte Wrapper"] +FE --> WR["React Encapsulation"] +WR --> AD["Ant Design Component"] +``` + +Diagram Source + +- [**init**.py (AntdPopover):14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) +- [Index.svelte (Popover):24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- [popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) +- [**init**.py (AntdQRCode):15-19](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L15-L19) +- [Index.svelte (QRCode):22-45](file://frontend/antd/qr-code/Index.svelte#L22-L45) +- [qr-code.tsx:6-20](file://frontend/antd/qr-code/qr-code.tsx#L6-L20) + +Section Source + +- [**init**.py (AntdPopover):14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) +- [Index.svelte (Popover):24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- [popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) +- [**init**.py (AntdQRCode):15-19](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L15-L19) +- [Index.svelte (QRCode):22-45](file://frontend/antd/qr-code/Index.svelte#L22-L45) +- [qr-code.tsx:6-20](file://frontend/antd/qr-code/qr-code.tsx#L6-L20) + +## Performance Considerations + +- Popover + - Set trigger modes and delays appropriately to avoid frequent re-renders + - For complex content, consider lazy loading or on-demand rendering + - The container mount point should be as close to the target element as possible to reduce DOM nesting depth +- QRCode + - Canvas output may create memory pressure at large sizes; consider using svg or reducing the size if necessary + - Icon overlay increases rendering overhead; lightweight icons are recommended + - The status render slot should only be enabled when needed to avoid unnecessary computation + +## Troubleshooting Guide + +- Popover + - Open state not taking effect: check open_change event binding and the open parameter + - Content not displayed: confirm that the title/content slots are correctly passed + - Positioning issues: check whether get_popup_container returns a valid container +- QRCode + - Cannot refresh: confirm that the refresh event is successfully bound + - Styles not taking effect: check whether color/bg_color and type settings are correct + - Scanning difficulties: increase error_level or enable boost_level + +Section Source + +- [**init**.py (AntdPopover):14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) +- [Index.svelte (Popover):24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- [**init**.py (AntdQRCode):15-19](file://backend/modelscope_studio/components/antd/qr_code/__init__.py#L15-L19) +- [Index.svelte (QRCode):22-45](file://frontend/antd/qr-code/Index.svelte#L22-L45) + +## Conclusion + +- Both Popover and QRCode follow a consistent three-layer encapsulation pattern, offering good extensibility and controllability +- Popover focuses on interaction and layout; QRCode focuses on data encoding and visual presentation +- It is recommended to combine the strategies and notes in this document when optimizing for complex layouts and mobile scenarios + +## Appendix + +- Demo Entry References + - Popover demo: [README-zh_CN.md (Popover docs)](file://docs/components/antd/popover/README-zh_CN.md#L7) + - QRCode demo: [README-zh_CN.md (QRCode docs)](file://docs/components/antd/qr_code/README-zh_CN.md#L7) diff --git a/.wiki/en/Ant Design Components/Data Display Components/Segmented and Statistic.md b/.wiki/en/Ant Design Components/Data Display Components/Segmented and Statistic.md new file mode 100644 index 00000000..6ff7a19b --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Segmented and Statistic.md @@ -0,0 +1,312 @@ +# Segmented and Statistic + + +**Files Referenced in This Document** +- [frontend/antd/segmented/segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js](file://backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js) +- [backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js](file://backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js) +- [frontend/antd/statistic/statistic.tsx](file://frontend/antd/statistic/statistic.tsx) +- [backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js](file://backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx](file://frontend/antd/statistic/countdown/statistic.countdown.tsx) +- [frontend/antd/statistic/timer/statistic.timer.tsx](file://frontend/antd/statistic/timer/statistic.timer.tsx) +- [docs/components/antd/segmented/README-zh_CN.md](file://docs/components/antd/segmented/README-zh_CN.md) +- [docs/components/antd/statistic/README-zh_CN.md](file://docs/components/antd/statistic/README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on two frontend components: **Segmented** and **Statistic**. The former is used for selecting among multiple mutually exclusive options; the latter is used for displaying numeric values, titles, prefixes/suffixes, and supports countdown and timer functionality. This document systematically explains the design and usage of these two components from the perspectives of architecture, data flow, processing logic, integration points, error handling, and performance characteristics, with visual diagrams for better understanding. + +## Project Structure + +- Components are composed of a frontend adaptation layer (React wrapper + Svelte pre-processing) and a backend template rendering layer (Svelte runtime bridge). +- Segmented injects option collections via context, supporting combined use with "option" groups; the Statistic component supports flexible extension through slots and function-based formatters. +- The documentation side provides basic demo entry points for quick onboarding. + +```mermaid +graph TB +subgraph "Frontend Adaptation Layer" +S_Tsx["segmented.tsx
React wrapper + render options"] +ST_Tsx["statistic.tsx
React wrapper + slots/formatter"] +CD_Tsx["countdown.tsx
React wrapper + countdown"] +TM_Tsx["timer.tsx
React wrapper + timer"] +end +subgraph "Backend Template Rendering Layer" +S_JS["segmented-Ds7q4Ezu.js
Svelte runtime bridge"] +SO_JS["segmented.option-CS0TqVwO.js
Option item implementation"] +ST_JS["statistic-DvxTRiyV.js
Svelte runtime bridge"] +end +subgraph "External Dependencies" +Antd["Ant Design Component Library"] +end +S_Tsx --> S_JS +ST_Tsx --> ST_JS +CD_Tsx --> Antd +TM_Tsx --> Antd +SO_JS --> S_JS +``` + +**Diagram Source** + +- [frontend/antd/segmented/segmented.tsx:1-47](file://frontend/antd/segmented/segmented.tsx#L1-L47) +- [backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js:695-719](file://backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js#L695-L719) +- [backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js:441-447](file://backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js#L441-L447) +- [frontend/antd/statistic/statistic.tsx:1-34](file://frontend/antd/statistic/statistic.tsx#L1-L34) +- [backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js:685-715](file://backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js#L685-L715) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:1-27](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L1-L27) +- [frontend/antd/statistic/timer/statistic.timer.tsx:1-29](file://frontend/antd/statistic/timer/statistic.timer.tsx#L1-L29) + +**Section Source** + +- [docs/components/antd/segmented/README-zh_CN.md:1-8](file://docs/components/antd/segmented/README-zh_CN.md#L1-L8) +- [docs/components/antd/statistic/README-zh_CN.md:1-9](file://docs/components/antd/statistic/README-zh_CN.md#L1-L9) + +## Core Components + +- Segmented + - Supports passing an options array via props or injecting option collections via "option" slots. + - Provides a combination of the onValueChange callback and the native onChange event. + - Supports disabled state and block-level display (achieved by hiding children). +- Statistic + - Supports combined use of title, prefix, suffix, and formatter as both slots and props. + - Supports custom formatter functions and ReactSlot slot rendering. +- Statistic Sub-components + - Countdown: accepts timestamps or millisecond values and automatically converts them to milliseconds. + - Timer: a timer display based on the current time. + +**Section Source** + +- [frontend/antd/segmented/segmented.tsx:10-44](file://frontend/antd/segmented/segmented.tsx#L10-L44) +- [frontend/antd/statistic/statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:6-24](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L6-L24) +- [frontend/antd/statistic/timer/statistic.timer.tsx:10-26](file://frontend/antd/statistic/timer/statistic.timer.tsx#L10-L26) + +## Architecture Overview + +The following diagram shows the complete call chain from the Svelte template to the React wrapper and then to the Ant Design component, and how slots and context participate in rendering. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Template" +participant Bridge as "Svelte Runtime Bridge" +participant ReactWrap as "React Wrapper Layer" +participant Antd as "Ant Design Component" +Svelte->>Bridge : "Generate nodes/slot mappings" +Bridge->>ReactWrap : "Create React elements and inject context/slots" +ReactWrap->>Antd : "Pass props/slots/event callbacks" +Antd-->>ReactWrap : "Render result" +ReactWrap-->>Bridge : "Bridge DOM/Portal" +Bridge-->>Svelte : "Complete mount/update" +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js:695-719](file://backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js#L695-L719) +- [backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js:685-715](file://backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js#L685-L715) +- [backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js:441-447](file://backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js#L441-L447) + +## Detailed Component Analysis + +### Segmented Analysis + +- Option Configuration and "Option Group" Combination + - Injects "options/default" slot groups via context; options takes priority, falling back to default. + - Uses useMemo to cache the option list and avoid unnecessary re-renders. +- Controlled and Uncontrolled Modes + - Externally, value/onChange can be passed directly for controlled mode; onValueChange is also provided as an internal value change callback. +- Disabled State and Block-Level Display + - Structural consistency is maintained by hiding children, without affecting the outer layout. +- Dynamic Updates and Style Customization + - Option items achieve dynamic slot and context injection via the bridge runtime, with style and event forwarding support. + +```mermaid +flowchart TD +Start(["Enter Segmented render"]) --> CheckSlots["Check slots: options vs default"] +CheckSlots --> HasOptions{"Has options?"} +HasOptions --> |Yes| UseOptions["Use options option set"] +HasOptions --> |No| UseDefault["Use default option set"] +UseOptions --> Resolve["Render as Antd options array"] +UseDefault --> Resolve +Resolve --> Wrap["Wrap as Antd Segmented and bind onChange/onValueChange"] +Wrap --> End(["Rendering complete"]) +``` + +**Diagram Source** + +- [frontend/antd/segmented/segmented.tsx:15-44](file://frontend/antd/segmented/segmented.tsx#L15-L44) +- [backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js:695-719](file://backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js#L695-L719) + +**Section Source** + +- [frontend/antd/segmented/segmented.tsx:10-44](file://frontend/antd/segmented/segmented.tsx#L10-L44) +- [backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js:695-719](file://backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js#L695-L719) +- [backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js:441-447](file://backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js#L441-L447) + +### Statistic Analysis + +- Value Display, Unit Settings, and Formatting + - Supports dual-channel (slot + prop) for title/prefix/suffix; formatter supports both function and slot forms. +- Countdown and Timer + - Both countdown and timer convert value to milliseconds to ensure consistency with what the Antd component expects. +- Combining Slots and Function-Based Formatters + - When slots.formatter is present, the slot render takes priority; otherwise it falls back to the function-based formatter. + +```mermaid +sequenceDiagram +participant User as "User Code" +participant Stat as "Statistic Wrapper Layer" +participant Slots as "Slot System" +participant Antd as "Antd Statistic" +User->>Stat : "Pass value/title/prefix/suffix/formatter" +Stat->>Slots : "Detect slots.formatter/title/prefix/suffix" +alt slots.formatter exists +Slots-->>Stat : "Return slot render function" +else slots.formatter does not exist +Stat-->>Stat : "Use formatter function" +end +Stat->>Antd : "Pass props and render functions" +Antd-->>User : "Render statistic value" +``` + +**Diagram Source** + +- [frontend/antd/statistic/statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) +- [backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js:685-715](file://backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js#L685-L715) + +**Section Source** + +- [frontend/antd/statistic/statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:6-24](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L6-L24) +- [frontend/antd/statistic/timer/statistic.timer.tsx:10-26](file://frontend/antd/statistic/timer/statistic.timer.tsx#L10-L26) + +### Component Class Relationship Diagram (Code Level) + +```mermaid +classDiagram +class SegmentedWrapper { ++props : GetProps ++slots : any ++onValueChange(value) ++onChange(v) +} +class StatisticWrapper { ++props : GetProps ++slots : any ++formatter() +} +class StatisticCountdownWrapper { ++props : GetProps ++slots : any +} +class StatisticTimerWrapper { ++props : GetProps ++slots : any +} +SegmentedWrapper --> "uses" ASegmented : "Antd" +StatisticWrapper --> "uses" AStatistic : "Antd" +StatisticCountdownWrapper --> "uses" AStatistic.Countdown : "Antd" +StatisticTimerWrapper --> "uses" AStatistic.Timer : "Antd" +``` + +**Diagram Source** + +- [frontend/antd/segmented/segmented.tsx:10-44](file://frontend/antd/segmented/segmented.tsx#L10-L44) +- [frontend/antd/statistic/statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:6-24](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L6-L24) +- [frontend/antd/statistic/timer/statistic.timer.tsx:10-26](file://frontend/antd/statistic/timer/statistic.timer.tsx#L10-L26) + +## Dependency Analysis + +- Inter-Component Coupling + - Segmented and option items establish a loosely-coupled relationship via context; option items do not directly depend on the controller but are uniformly scheduled by the bridge layer. + - The Statistic component and its sub-components (countdown/timer) share the same bridge and slot mechanism. +- External Dependencies + - All components depend on the Ant Design component library to ensure consistent UI behavior and styling. +- Potential Circular Dependencies + - The current structure uses a unidirectional dependency of "bridge layer → React wrapper layer → Antd"; no signs of circular dependencies have been observed. + +```mermaid +graph LR +Segmented["Segmented Wrapper Layer"] --> BridgeS["Segmented Bridge Runtime"] +OptionItem["Option Item Implementation"] --> BridgeS +Statistic["Statistic Wrapper Layer"] --> BridgeSt["Statistic Bridge Runtime"] +Countdown["Countdown Wrapper Layer"] --> AntdCD["Antd Countdown"] +Timer["Timer Wrapper Layer"] --> AntdTM["Antd Timer"] +BridgeS --> AntdSeg["Antd Segmented"] +BridgeSt --> AntdSt["Antd Statistic"] +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js:695-719](file://backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js#L695-L719) +- [backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js:441-447](file://backend/modelscope_studio/components/antd/segmented/option/templates/component/segmented.option-CS0TqVwO.js#L441-L447) +- [backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js:685-715](file://backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js#L685-L715) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:15-21](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L15-L21) +- [frontend/antd/statistic/timer/statistic.timer.tsx:17-23](file://frontend/antd/statistic/timer/statistic.timer.tsx#L17-L23) + +**Section Source** + +- [backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js:695-719](file://backend/modelscope_studio/components/antd/segmented/templates/component/segmented-Ds7q4Ezu.js#L695-L719) +- [backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js:685-715](file://backend/modelscope_studio/components/antd/statistic/templates/component/statistic-DvxTRiyV.js#L685-L715) + +## Performance Considerations + +- Rendering Optimization + - Segmented uses useMemo to cache the options array, reducing unnecessary re-renders. + - The Statistic component uses slot render functions when slots.formatter is present, avoiding extra prop passing overhead. +- DOM Display Strategy + - By setting children to invisible (display: none) and inserting the actual nodes in the bridge layer using "contents", layout jitter risk is reduced. +- Time Parameter Conversion + - Countdown and Timer uniformly convert input values to milliseconds, avoiding performance fluctuations caused by different units from external callers. + +**Section Source** + +- [frontend/antd/segmented/segmented.tsx:30-38](file://frontend/antd/segmented/segmented.tsx#L30-L38) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:17-17](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L17-L17) +- [frontend/antd/statistic/timer/statistic.timer.tsx:19-19](file://frontend/antd/statistic/timer/statistic.timer.tsx#L19-L19) + +## Troubleshooting Guide + +- Options not displayed or not taking effect + - Confirm that the "option group" slots (options/default) are correctly used and that slot elements are properly mounted. + - Check that both onValueChange and onChange are bound to ensure the complete value change event chain. +- Slot content not rendered + - Confirm that slots.formatter/title/prefix/suffix are correctly passed in and that the bridge layer has enabled the corresponding slot rendering. +- Countdown/Timer value anomalies + - Confirm whether the input value unit is in seconds (internally converted to milliseconds) to avoid multiplying by 1000 twice. +- Style or event forwarding issues + - Check the bridge layer context merge logic to confirm that styles and events are not being dropped during the bridge phase. + +**Section Source** + +- [frontend/antd/segmented/segmented.tsx:26-29](file://frontend/antd/segmented/segmented.tsx#L26-L29) +- [frontend/antd/statistic/statistic.tsx:18-28](file://frontend/antd/statistic/statistic.tsx#L18-L28) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:17-20](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L17-L20) +- [frontend/antd/statistic/timer/statistic.timer.tsx:19-22](file://frontend/antd/statistic/timer/statistic.timer.tsx#L19-L22) + +## Conclusion + +The Segmented and Statistic components achieve high consistency with Ant Design components and flexible extensibility through a unified bridge and slot mechanism. Segmented emphasizes dynamic option injection and event callback combinations; Statistic provides powerful flexibility in formatting and slot rendering. With the architecture diagrams and flowcharts in this document, developers can more efficiently apply these two components in form and dashboard scenarios. + +## Appendix + +- Demo Entry Points + - Basic demos for Segmented and Statistic can be found in the documentation, making it easy to quickly verify component behavior. + +**Section Source** + +- [docs/components/antd/segmented/README-zh_CN.md:5-8](file://docs/components/antd/segmented/README-zh_CN.md#L5-L8) +- [docs/components/antd/statistic/README-zh_CN.md:7-9](file://docs/components/antd/statistic/README-zh_CN.md#L7-L9) diff --git a/.wiki/en/Ant Design Components/Data Display Components/Table and Tabs.md b/.wiki/en/Ant Design Components/Data Display Components/Table and Tabs.md new file mode 100644 index 00000000..9fb01c29 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Table and Tabs.md @@ -0,0 +1,345 @@ +# Table and Tabs + + +**Files Referenced in This Document** +- [table.tsx](file://frontend/antd/table/table.tsx) +- [context.ts](file://frontend/antd/table/context.ts) +- [table.column.tsx](file://frontend/antd/table/column/table.column.tsx) +- [table.column-group.tsx](file://frontend/antd/table/column-group/table.column-group.tsx) +- [table.expandable.tsx](file://frontend/antd/table/expandable/table.expandable.tsx) +- [table.row-selection.tsx](file://frontend/antd/table/row-selection/table.row-selection.tsx) +- [tabs.tsx](file://frontend/antd/tabs/tabs.tsx) +- [tabs.context.ts](file://frontend/antd/tabs/context.ts) +- [tabs.item.tsx](file://frontend/antd/tabs/item/tabs.item.tsx) + + +## Table of Contents + +- [Table and Tabs](#table-and-tabs) + - [Table of Contents](#table-of-contents) + - [Introduction](#introduction) + - [Project Structure](#project-structure) + - [Core Components](#core-components) + - [Architecture Overview](#architecture-overview) + - [Detailed Component Analysis](#detailed-component-analysis) + - [Table Component](#table-component) + - [Tabs Component](#tabs-component) + - [Navigation Strategies in Complex Layouts](#navigation-strategies-in-complex-layouts) + - [Dependency Analysis](#dependency-analysis) + - [Performance Considerations](#performance-considerations) + - [Troubleshooting Guide](#troubleshooting-guide) + - [Conclusion](#conclusion) + - [Appendix](#appendix) + +## Introduction + +This document provides a systematic review of the **Table** and **Tabs** component systems, covering their advanced capabilities and engineering implementation. Key topics include: Table's column definitions (column), column groups (column_group), expandable rows (expandable), and row selection (row_selection); Tabs' tab items, position control, disabled state, and dynamic addition/removal. It also provides practical recommendations for large dataset handling, virtual scrolling, sorting, filtering, and pagination integration; as well as extension ideas for Tabs' lazy content loading, tab icons, close buttons, and drag-to-reorder. Finally, it covers navigation strategies for responsive design and complex layouts. + +## Project Structure + +Both components use a layered design of "container component + item handler": + +- The container component handles prop forwarding, slot rendering, context merging, and function wrapping; +- Item handlers (such as TableColumn, TabsItem, etc.) are responsible for injecting child elements into the container and enhancing configuration where necessary (such as menus, dropdowns, icons, etc.). + +```mermaid +graph TB +subgraph "Table Component" +T["Table Container
frontend/antd/table/table.tsx"] +CtxT["Table Context
frontend/antd/table/context.ts"] +Col["Column Handler
frontend/antd/table/column/table.column.tsx"] +ColG["Column Group Handler
frontend/antd/table/column-group/table.column-group.tsx"] +Exp["Expandable Handler
frontend/antd/table/expandable/table.expandable.tsx"] +RSel["Row Selection Handler
frontend/antd/table/row-selection/table.row-selection.tsx"] +end +subgraph "Tabs Component" +Tabs["Tabs Container
frontend/antd/tabs/tabs.tsx"] +CtxTabs["Tabs Context
frontend/antd/tabs/context.ts"] +TabsItem["Tab Item Handler
frontend/antd/tabs/item/tabs.item.tsx"] +end +T --> CtxT +T --> Col +T --> ColG +T --> Exp +T --> RSel +Tabs --> CtxTabs +Tabs --> TabsItem +``` + +**Diagram Source** + +- [table.tsx:28-276](file://frontend/antd/table/table.tsx#L28-L276) +- [context.ts](file://frontend/antd/table/context.ts) +- [table.column.tsx:20-97](file://frontend/antd/table/column/table.column.tsx#L20-L97) +- [table.column-group.tsx:7-19](file://frontend/antd/table/column-group/table.column-group.tsx#L7-L19) +- [table.expandable.tsx:7-11](file://frontend/antd/table/expandable/table.expandable.tsx#L7-L11) +- [table.row-selection.tsx:13-35](file://frontend/antd/table/row-selection/table.row-selection.tsx#L13-L35) +- [tabs.tsx:12-118](file://frontend/antd/tabs/tabs.tsx#L12-L118) +- [tabs.context.ts](file://frontend/antd/tabs/context.ts) +- [tabs.item.tsx:7-11](file://frontend/antd/tabs/item/tabs.item.tsx#L7-L11) + +**Section Source** + +- [table.tsx:28-276](file://frontend/antd/table/table.tsx#L28-L276) +- [tabs.tsx:12-118](file://frontend/antd/tabs/tabs.tsx#L12-L118) + +## Core Components + +- Table Container: handles unified processing and slot rendering for columns, rowSelection, expandable, sticky, showSorterTooltip, pagination, loading, footer, title, and other props. +- Column Handler: enhances column configuration with support for filter dropdown menus, custom popup rendering, menu expand icons, and overflow indicators. +- Column Group Handler: groups a set of columns as a logical unit, facilitating header merging and style control. +- Expandable Handler: injects expandable configuration into the table. +- Row Selection Handler: injects custom selection items (e.g., "Select All", "Invert Selection") into rowSelection. +- Tabs Container: handles unified processing and slot rendering for items, indicator, renderTabBar, more, tabBarExtraContent, addIcon, removeIcon, and other props. +- Tab Item Handler: injects individual tab items into Tabs' items. + +**Section Source** + +- [table.tsx:28-276](file://frontend/antd/table/table.tsx#L28-L276) +- [table.column.tsx:20-97](file://frontend/antd/table/column/table.column.tsx#L20-L97) +- [table.column-group.tsx:7-19](file://frontend/antd/table/column-group/table.column-group.tsx#L7-L19) +- [table.expandable.tsx:7-11](file://frontend/antd/table/expandable/table.expandable.tsx#L7-L11) +- [table.row-selection.tsx:13-35](file://frontend/antd/table/row-selection/table.row-selection.tsx#L13-L35) +- [tabs.tsx:12-118](file://frontend/antd/tabs/tabs.tsx#L12-L118) +- [tabs.item.tsx:7-11](file://frontend/antd/tabs/item/tabs.item.tsx#L7-L11) + +## Architecture Overview + +The following diagram shows the dependency relationships and division of responsibilities between the Table and Tabs containers and their item handlers. + +```mermaid +classDiagram +class Table { ++props : columns,rowSelection,expandable,sticky,showSorterTooltip,pagination,loading,footer,title ++slots : title,footer,loading.tip,loading.indicator,pagination.showQuickJumper.goButton,pagination.itemRender,showSorterTooltip.title,summary +} +class TableColumn { ++enhancement : filterDropdownProps.menu +} +class TableColumnGroup +class TableExpandable +class TableRowSelection +class Tabs { ++props : items,indicator,more,renderTabBar,tabBarExtraContent,addIcon,removeIcon ++slots : renderTabBar,tabBarExtraContent.left,right,more.icon +} +class TabsItem +Table --> TableColumn : "uses" +Table --> TableColumnGroup : "uses" +Table --> TableExpandable : "uses" +Table --> TableRowSelection : "uses" +Tabs --> TabsItem : "uses" +``` + +**Diagram Source** + +- [table.tsx:28-276](file://frontend/antd/table/table.tsx#L28-L276) +- [table.column.tsx:20-97](file://frontend/antd/table/column/table.column.tsx#L20-L97) +- [table.column-group.tsx:7-19](file://frontend/antd/table/column-group/table.column-group.tsx#L7-L19) +- [table.expandable.tsx:7-11](file://frontend/antd/table/expandable/table.expandable.tsx#L7-L11) +- [table.row-selection.tsx:13-35](file://frontend/antd/table/row-selection/table.row-selection.tsx#L13-L35) +- [tabs.tsx:12-118](file://frontend/antd/tabs/tabs.tsx#L12-L118) +- [tabs.item.tsx:7-11](file://frontend/antd/tabs/item/tabs.item.tsx#L7-L11) + +## Detailed Component Analysis + +### Table Component + +- Column Definition (column) + - Supports directly passing columns or injecting via TableColumn; + - Recognizes and converts special placeholders (such as EXPAND_COLUMN, SELECTION_COLUMN); + - Enhances filterDropdownProps with support for menu items, dropdown rendering, popup rendering, menu expand icons, and overflow indicators. +- Column Group (column_group) + - Groups a set of columns as a logical unit for header merging and style control; + - Only the default slot is allowed. +- Expandable Rows (expandable) + - Injects expandable configuration via TableExpandable; + - Supports custom rendering of expanded content. +- Row Selection (row_selection) + - Injects rowSelection via TableRowSelection; + - Supports custom selection items via selections (e.g., "Select All", "Invert Selection"). +- Sorting, Filtering, and Pagination + - Supports slot-based title for showSorterTooltip; + - Supports slot-based jump button and page item rendering for pagination; + - Supports tip and indicator slots for loading; + - Supports container getter function for sticky; + - Supports slot-based rendering for footer and summary. +- Large Datasets and Virtual Scrolling + - It is recommended to combine external virtual scrolling solutions (e.g., fixed height + scrollable container) to reduce DOM node count; + - Use onScroll with pagination/infinite scrolling to avoid rendering large numbers of rows at once. +- Responsive Design + - Use sticky and column width settings to prioritize key columns on small screens; + - Use the column's responsive configuration or a custom breakpoint strategy. + +```mermaid +sequenceDiagram +participant U as "User" +participant T as "Table Container" +participant C as "Column/Expandable/RowSelection Handler" +participant R as "Ant Design Table" +U->>T : Provide columns/rowSelection/expandable/pagination props +T->>C : Inject child items and enhance configuration +C-->>T : Return enhanced configuration +T->>R : Forward props and render slots +R-->>U : Render table UI +``` + +**Diagram Source** + +- [table.tsx:66-271](file://frontend/antd/table/table.tsx#L66-L271) +- [table.column.tsx:28-93](file://frontend/antd/table/column/table.column.tsx#L28-L93) +- [table.expandable.tsx:9-10](file://frontend/antd/table/expandable/table.expandable.tsx#L9-L10) +- [table.row-selection.tsx:21-32](file://frontend/antd/table/row-selection/table.row-selection.tsx#L21-L32) + +**Section Source** + +- [table.tsx:28-276](file://frontend/antd/table/table.tsx#L28-L276) +- [table.column.tsx:20-97](file://frontend/antd/table/column/table.column.tsx#L20-L97) +- [table.column-group.tsx:7-19](file://frontend/antd/table/column-group/table.column-group.tsx#L7-L19) +- [table.expandable.tsx:7-11](file://frontend/antd/table/expandable/table.expandable.tsx#L7-L11) +- [table.row-selection.tsx:13-35](file://frontend/antd/table/row-selection/table.row-selection.tsx#L13-L35) + +### Tabs Component + +- Tab Items + - Inject individual tab items via TabsItem; + - Supports basic props such as disabled, closable, and closeIcon. +- Position Control and Dynamic Add/Remove + - Control tab addition/removal via the dynamic items array; + - indicator controls the bottom bar style with size function support; + - addIcon/removeIcon support slot-based icons. +- Lazy Content Loading + - It is recommended to render only the active panel's content on activation, avoiding rendering all panels at once; + - Load data and components on demand in the onChange event. +- Tab Icons and Close Button + - Customize icons via addIcon/removeIcon slots; + - closable and closeIcon control whether tabs can be closed and the close icon appearance. +- Drag-to-Reorder + - Can be implemented using an external drag library combined with onChange; + - Be careful to maintain consistency between items order and activeKey. +- More Menu and Extra Content + - more.icon supports a slot-based icon; + - tabBarExtraContent supports slot-based content on both the left and right sides. + +```mermaid +sequenceDiagram +participant U as "User" +participant Tabs as "Tabs Container" +participant Item as "TabsItem Handler" +participant AD as "Ant Design Tabs" +U->>Tabs : Provide items/addIcon/removeIcon/more/tabBarExtraContent +Tabs->>Item : Inject tab items and enhance configuration +Item-->>Tabs : Return enhanced tab items +Tabs->>AD : Forward props and render slots +AD-->>U : Render tabs UI +``` + +**Diagram Source** + +- [tabs.tsx:26-115](file://frontend/antd/tabs/tabs.tsx#L26-L115) +- [tabs.item.tsx:9-10](file://frontend/antd/tabs/item/tabs.item.tsx#L9-L10) + +**Section Source** + +- [tabs.tsx:12-118](file://frontend/antd/tabs/tabs.tsx#L12-L118) +- [tabs.item.tsx:7-11](file://frontend/antd/tabs/item/tabs.item.tsx#L7-L11) + +### Navigation Strategies in Complex Layouts + +- Responsive Navigation + - On narrow screens, enable the Tabs more menu to move less-used tabs into a dropdown; + - Use sticky or fixed headers to keep navigation always visible. +- Nested Usage + - When nesting child tabs or subtables inside tabs, be mindful of hierarchy and interaction conflicts; + - Use independent contexts and namespaces to avoid event bubbling and state pollution. +- Navigation Consistency + - Use onChange and activeKey uniformly to manage the current active state; + - For asynchronously loaded data, display a skeleton screen first, then switch to real content. + +## Dependency Analysis + +- Table Side + - The Table container depends on context providers (Column, Expandable, RowSelection) to collect child items; + - TableColumn enhances filterDropdownProps and reuses the menu context; + - TableRowSelection injects selections. +- Tabs Side + - The Tabs container relies on the Items context to collect tab items; + - TabsItem injects individual tab items. + +```mermaid +graph LR +subgraph "Table Dependencies" +CTX["Table Context"] +COL["Column Handler"] +COLG["Column Group Handler"] +EXP["Expandable Handler"] +SEL["Row Selection Handler"] +TBL["Table Container"] +TBL --> CTX +TBL --> COL +TBL --> COLG +TBL --> EXP +TBL --> SEL +end +subgraph "Tabs Dependencies" +CTXS["Tabs Context"] +ITEM["Tab Item Handler"] +TABS["Tabs Container"] +TABS --> CTXS +TABS --> ITEM +end +``` + +**Diagram Source** + +- [context.ts](file://frontend/antd/table/context.ts) +- [table.tsx:41-275](file://frontend/antd/table/table.tsx#L41-L275) +- [tabs.context.ts](file://frontend/antd/tabs/context.ts) +- [tabs.tsx:24-117](file://frontend/antd/tabs/tabs.tsx#L24-L117) + +**Section Source** + +- [table.tsx:41-275](file://frontend/antd/table/table.tsx#L41-L275) +- [tabs.tsx:24-117](file://frontend/antd/tabs/tabs.tsx#L24-L117) + +## Performance Considerations + +- Table + - Large datasets: use fixed height + virtual scrolling (e.g., external library) to reduce DOM node count; + - Pagination/infinite scrolling: combine with backend pagination to avoid rendering everything at once; + - Column rendering: only render necessary columns, hide non-critical ones; + - Event binding: use throttle/debounce for onRow/onHeaderRow. +- Tabs + - Lazy content loading: only render on activation; + - Dynamic add/remove: batch update items to avoid frequent re-renders; + - Icons and slots: use lightweight components and avoid complex computations. + +## Troubleshooting Guide + +- Slots not taking effect + - Confirm that slot key names match container declarations (such as pagination.showQuickJumper.goButton, more.icon, etc.); + - Check that slots are correctly wrapped inside child items. +- Props not taking effect + - Confirm that function-type props are wrapped with useFunction; + - Check that object-type props (such as sticky, showSorterTooltip, pagination) are correctly merged. +- Style anomalies + - Check whether getPopupContainer/getContainer returns the correct mount node; + - Confirm that the ReactSlot render target container inside slots exists and is visible. + +**Section Source** + +- [table.tsx:76-108](file://frontend/antd/table/table.tsx#L76-L108) +- [tabs.tsx:36-39](file://frontend/antd/tabs/tabs.tsx#L36-L39) + +## Conclusion + +This document systematically reviews the capability boundaries and extension points of the Table and Tabs components from an architectural and implementation perspective. Through the collaboration of container components and item handlers, prop forwarding, slot rendering, and configuration enhancement are achieved. Combined with large dataset handling, virtual scrolling, lazy loading, and responsive strategies, they can provide a stable and maintainable navigation experience in complex layouts. + +## Appendix + +- Key Implementation Points + - Table: slotting and function wrapping for columns, rowSelection, expandable, sticky, showSorterTooltip, pagination, loading, footer, and title; + - Tabs: slotting and function wrapping for items, indicator, renderTabBar, more, tabBarExtraContent, addIcon, and removeIcon. +- Extension Recommendations + - Table: introduce virtual scrolling with pagination integration; customize column groups and expandable content based on business scenarios; + - Tabs: combine with routing and state management to implement dynamic add/remove and persistence; support drag-to-reorder and the more menu. diff --git a/.wiki/en/Ant Design Components/Data Display Components/Tag and Timeline.md b/.wiki/en/Ant Design Components/Data Display Components/Tag and Timeline.md new file mode 100644 index 00000000..1e987675 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Tag and Timeline.md @@ -0,0 +1,438 @@ +# Tag and Timeline + + +**Files Referenced in This Document** +- [frontend/antd/tag/tag.tsx](file://frontend/antd/tag/tag.tsx) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx) +- [frontend/antd/tag/checkable-tag/Index.svelte](file://frontend/antd/tag/checkable-tag/Index.svelte) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx) +- [frontend/antd/tag/checkable-tag-group/Index.svelte](file://frontend/antd/tag/checkable-tag-group/Index.svelte) +- [frontend/antd/tag/checkable-tag-group/context.ts](file://frontend/antd/tag/checkable-tag-group/context.ts) +- [frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx](file://frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx) +- [frontend/antd/tag/checkable-tag-group/option/Index.svelte](file://frontend/antd/tag/checkable-tag-group/option/Index.svelte) +- [frontend/antd/timeline/timeline.tsx](file://frontend/antd/timeline/timeline.tsx) +- [frontend/antd/timeline/item/Index.svelte](file://frontend/antd/timeline/item/Index.svelte) +- [frontend/antd/timeline/context.ts](file://frontend/antd/timeline/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/hooks/useTargets.ts](file://frontend/utils/hooks/useTargets.ts) +- [docs/components/antd/tag/demos/checkable_tag.py](file://docs/components/antd/tag/demos/checkable_tag.py) +- [docs/components/antd/timeline/demos/basic.py](file://docs/components/antd/timeline/demos/basic.py) + + +## Update Summary + +**Changes Made** + +- Added the CheckableTagGroup component system, including the CheckableTagGroup main component and CheckableTagGroupOption child component +- Updated Timeline component documentation to reflect the simplified implementation of the Timeline.Item component +- Enhanced batch operation capabilities and dynamic option management for tag groups +- Improved context management and option handling mechanisms for CheckableTagGroup + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the **Tag** and **Timeline** components, systematically explaining their design philosophy, data flow, interaction behavior, and extensibility. Key topics include: + +- Tag: interaction states for regular and checkable tags, color configuration, dynamic tag management, click events, delete functionality, and batch operation recommendations. +- **New**: CheckableTagGroup component system supporting batch tag selection, dynamic option management, and grouped operations. +- Timeline: time nodes (Items), direction control, node customization, and style customization; as well as implementation paths for reversed display, custom icons, and line style adjustments. + +## Project Structure + +- The component layer uses a pattern of "frontend Svelte wrapper + backend Python component bridge"; the frontend adapts Ant Design's React components into Svelte components via sveltify, and introduces the Items context and slot rendering mechanism where necessary. +- The utility layer provides general capabilities such as items context, slot rendering, and target element resolution, supporting dynamic item management for complex container components (such as Timeline). + +```mermaid +graph TB +subgraph "Tag Component" +TAG["Tag
frontend/antd/tag/tag.tsx"] +CTAG["CheckableTag
frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx"] +CTAG_IDX["CheckableTag Wrapper
frontend/antd/tag/checkable-tag/Index.svelte"] +CTAG_GROUP["CheckableTagGroup
frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx"] +CTAG_GROUP_IDX["CheckableTagGroup Wrapper
frontend/antd/tag/checkable-tag-group/Index.svelte"] +CTAG_OPTION["CheckableTagGroupOption
frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx"] +CTAG_OPTION_IDX["CheckableTagGroupOption Wrapper
frontend/antd/tag/checkable-tag-group/option/Index.svelte"] +end +subgraph "Timeline Component" +TL["Timeline
frontend/antd/timeline/timeline.tsx"] +TL_ITEM["Timeline.Item
frontend/antd/timeline/item/Index.svelte"] +TL_CTX["Timeline Context
frontend/antd/timeline/context.ts"] +end +subgraph "Utility Library" +CREATE_ITEMS["createItemsContext
frontend/utils/createItemsContext.tsx"] +RENDER_ITEMS["renderItems
frontend/utils/renderItems.tsx"] +USE_TARGETS["useTargets
frontend/utils/hooks/useTargets.ts"] +end +TAG --> USE_TARGETS +CTAG --> USE_TARGETS +CTAG_GROUP --> CTAG_GROUP_IDX +CTAG_GROUP_IDX --> CTAG_GROUP +CTAG_OPTION --> CTAG_OPTION_IDX +CTAG_OPTION_IDX --> CTAG_OPTION +TL --> TL_CTX +TL_CTX --> CREATE_ITEMS +TL --> RENDER_ITEMS +TL_ITEM --> TL_CTX +``` + +**Diagram Source** + +- [frontend/antd/tag/tag.tsx:1-35](file://frontend/antd/tag/tag.tsx#L1-L35) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:1-35](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L1-L35) +- [frontend/antd/tag/checkable-tag/Index.svelte:1-77](file://frontend/antd/tag/checkable-tag/Index.svelte#L1-L77) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:1-51](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L1-L51) +- [frontend/antd/tag/checkable-tag-group/Index.svelte:1-79](file://frontend/antd/tag/checkable-tag-group/Index.svelte#L1-L79) +- [frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx:1-14](file://frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx#L1-L14) +- [frontend/antd/tag/checkable-tag-group/option/Index.svelte:1-74](file://frontend/antd/tag/checkable-tag-group/option/Index.svelte#L1-L74) +- [frontend/antd/timeline/timeline.tsx:1-50](file://frontend/antd/timeline/timeline.tsx#L1-L50) +- [frontend/antd/timeline/item/Index.svelte:1-65](file://frontend/antd/timeline/item/Index.svelte#L1-L65) +- [frontend/antd/timeline/context.ts:1-7](file://frontend/antd/timeline/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/hooks/useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) + +**Section Source** + +- [frontend/antd/tag/tag.tsx:1-35](file://frontend/antd/tag/tag.tsx#L1-L35) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:1-35](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L1-L35) +- [frontend/antd/tag/checkable-tag/Index.svelte:1-77](file://frontend/antd/tag/checkable-tag/Index.svelte#L1-L77) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:1-51](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L1-L51) +- [frontend/antd/tag/checkable-tag-group/Index.svelte:1-79](file://frontend/antd/tag/checkable-tag-group/Index.svelte#L1-L79) +- [frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx:1-14](file://frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx#L1-L14) +- [frontend/antd/tag/checkable-tag-group/option/Index.svelte:1-74](file://frontend/antd/tag/checkable-tag-group/option/Index.svelte#L1-L74) +- [frontend/antd/timeline/timeline.tsx:1-50](file://frontend/antd/timeline/timeline.tsx#L1-L50) +- [frontend/antd/timeline/item/Index.svelte:1-65](file://frontend/antd/timeline/item/Index.svelte#L1-L65) +- [frontend/antd/timeline/context.ts:1-7](file://frontend/antd/timeline/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/hooks/useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) + +## Core Components + +- Tag + - Regular tag: supports text and icons, closeIcon slot, and value field fallback rendering. + - CheckableTag: two-way binding for checked state, supports label text fallback, icon slot, and change callback. + - **New**: CheckableTagGroup: supports batch tag selection, dynamic option management, and grouped operations. +- Timeline + - Supports dynamic items injection and default slot fallback; supports pending/pendingDot slots; internally collects child items via the Items context and renders them. + +**Section Source** + +- [frontend/antd/tag/tag.tsx:7-32](file://frontend/antd/tag/tag.tsx#L7-L32) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:7-32](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L7-L32) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:8-48](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L8-L48) +- [frontend/antd/timeline/timeline.tsx:9-47](file://frontend/antd/timeline/timeline.tsx#L9-L47) + +## Architecture Overview + +Both Tag and Timeline bridge Ant Design's React components into the Svelte ecosystem via sveltify, while leveraging slots and context to achieve flexible dynamic rendering and prop forwarding. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Svelte as "Svelte Wrapper Layer" +participant Utils as "Utility Library" +participant Antd as "Ant Design Component" +Dev->>Svelte : Pass props and slots +Svelte->>Utils : Parse slots/target elements/context +Utils-->>Svelte : Return processed props and render functions +Svelte->>Antd : Render final component tree +Antd-->>Dev : Output UI result +``` + +**Diagram Source** + +- [frontend/antd/tag/tag.tsx:12-32](file://frontend/antd/tag/tag.tsx#L12-L32) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:13-32](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L13-L32) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:14-46](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L14-L46) +- [frontend/antd/timeline/timeline.tsx:15-46](file://frontend/antd/timeline/timeline.tsx#L15-L46) + +## Detailed Component Analysis + +### Tag Component + +- Regular Tag + - Key points: supports icon/closeIcon slots; when target child nodes are present, child nodes take rendering priority over the children + value fallback. + - Use cases: category labels, status badges, closable temporary tags. +- CheckableTag + - Key points: supports checked/value props and onValueChange callback; supports label text fallback; onChange is triggered in the callback chain. + - Use cases: multi-select filtering, preference settings, category checkboxes. +- **New**: CheckableTagGroup + - Key points: supports an options array or default slot fallback; injects context via ItemHandler, recording each child item's props, slots, and nested children. + - Use cases: batch tag selection, category filtering, multi-option group management. + +```mermaid +classDiagram +class Tag { ++props : All Ant Design Tag supported props ++slots : icon, closeIcon ++value? : string +} +class CheckableTag { ++props : Ant Design Tag.CheckableTag props ++slots : icon ++onValueChange(checked) ++label? : string +} +class CheckableTagGroup { ++props : Ant Design Tag.CheckableTagGroup props ++slots : options, default ++onValueChange(value) ++options? : array +} +class CheckableTagGroupOption { ++props : Single tag option props ++slots : default ++itemIndex : number ++itemSlotKey : string +} +Tag --> "uses" useTargets +CheckableTag --> "uses" useTargets +CheckableTagGroup --> "uses" createItemsContext +CheckableTagGroupOption --> "uses" ItemHandler +``` + +**Diagram Source** + +- [frontend/antd/tag/tag.tsx:7-32](file://frontend/antd/tag/tag.tsx#L7-L32) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:7-32](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L7-L32) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:8-48](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L8-L48) +- [frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx:7-13](file://frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx#L7-L13) +- [frontend/utils/hooks/useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [frontend/antd/tag/checkable-tag-group/context.ts:3-4](file://frontend/antd/tag/checkable-tag-group/context.ts#L3-L4) + +**Section Source** + +- [frontend/antd/tag/tag.tsx:7-32](file://frontend/antd/tag/tag.tsx#L7-L32) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:7-32](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L7-L32) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:8-48](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L8-L48) +- [frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx:7-13](file://frontend/antd/tag/checkable-tag-group/option/checkable-tag-group.option.tsx#L7-L13) +- [frontend/utils/hooks/useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [frontend/antd/tag/checkable-tag-group/context.ts:3-4](file://frontend/antd/tag/checkable-tag-group/context.ts#L3-L4) + +#### Interaction and State + +- Regular Tag + - Click events: handled by Antd native events; onClick and other events can be forwarded via props. + - Delete: achievable by combining the closeIcon slot with the closeIcon prop. +- CheckableTag + - Checked state: two-way binding via value/checked; onValueChange callback for state synchronization. + - Batch operations: manage the value of multiple CheckableTags in a parent container and update them in bulk. +- **New**: CheckableTagGroup + - Checked state: supports single-select and multi-select modes; onValueChange returns a selected value array or a single value. + - Dynamic options: dynamically add/remove tag options via the options prop or default slot. + - Group management: supports nested tag groups and batch operations at the group level. + +**Section Source** + +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:23-26](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L23-L26) +- [frontend/antd/tag/checkable-tag/Index.svelte:69-71](file://frontend/antd/tag/checkable-tag/Index.svelte#L69-L71) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:39-42](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L39-L42) +- [frontend/antd/tag/checkable-tag-group/Index.svelte:71-73](file://frontend/antd/tag/checkable-tag-group/Index.svelte#L71-L73) + +#### Color Configuration and Dynamic Management + +- Color: supports preset color palettes and custom hex values via the color prop. +- Dynamic: combining backend component bridging and frontend prop forwarding enables runtime dynamic switching of colors and text. +- **New**: Tag group color: supports setting a unified color theme for the entire tag group while preserving per-tag color overrides. + +**Section Source** + +- [docs/components/antd/tag/demos/checkable_tag.py:10-15](file://docs/components/antd/tag/demos/checkable_tag.py#L10-L15) + +#### Application in Search Results + +- Recommendation: add Tags to search result entries as category/status identifiers; use CheckableTag for multi-dimensional filtering; use closeIcon to remove filter conditions in one click. +- **New**: Use CheckableTagGroup for advanced filtering: supports multi-dimensional tag combination filtering, batch operations, and saving filter conditions. + +### Timeline Component + +- Timeline Body + - Supports an items array or default slot fallback; pending/pendingDot slots can customize the "in progress" state. + - Internally collects child items via the Items context, then uses renderItems to convert them into the data structure required by Antd. +- **Updated**: Timeline Item (Timeline.Item) + - **Simplified implementation**: removed complex prop handling logic, directly forwarding all props and slots. + - Injects context via ItemHandler, recording each child item's props, slots, and nested children. + - Supports a custom dot slot to replace the timeline node icon. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant TL as "Timeline" +participant Ctx as "Items Context" +participant Item as "Timeline.Item" +participant Render as "renderItems" +Dev->>TL : Set items or fill default slot +TL->>Ctx : Wrap with withItemsContextProvider +TL->>Item : Render child items and inject context +Item->>Ctx : ItemHandler records props/slots/children +TL->>Render : Use renderItems to convert to Antd data structure +Render-->>TL : Return items array +TL-->>Dev : Render timeline +``` + +**Diagram Source** + +- [frontend/antd/timeline/timeline.tsx:13-46](file://frontend/antd/timeline/timeline.tsx#L13-L46) +- [frontend/antd/timeline/context.ts:3-4](file://frontend/antd/timeline/context.ts#L3-L4) +- [frontend/utils/createItemsContext.tsx:171-184](file://frontend/utils/createItemsContext.tsx#L171-L184) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) +- [frontend/antd/timeline/item/Index.svelte:49-64](file://frontend/antd/timeline/item/Index.svelte#L49-L64) + +**Section Source** + +- [frontend/antd/timeline/timeline.tsx:13-46](file://frontend/antd/timeline/timeline.tsx#L13-L46) +- [frontend/antd/timeline/context.ts:3-4](file://frontend/antd/timeline/context.ts#L3-L4) +- [frontend/utils/createItemsContext.tsx:171-184](file://frontend/utils/createItemsContext.tsx#L171-L184) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) +- [frontend/antd/timeline/item/Index.svelte:49-64](file://frontend/antd/timeline/item/Index.svelte#L49-L64) + +#### Direction Control and Style Customization + +- Direction control: use the mode prop (such as alternate) to control alternating display of timeline nodes. +- Style customization: supports the color prop for node coloring; the dot slot allows custom node icons; pending/pendingDot slots customize the "in progress" state. + +**Section Source** + +- [docs/components/antd/timeline/demos/basic.py:18-38](file://docs/components/antd/timeline/demos/basic.py#L18-L38) + +#### Reversed Display and Timeline Style Adjustments + +- Reversed display: reverse order can be achieved via mode or external layout; for complete reversal, reverse the items array before passing it in at the parent layer. +- Line styles: Antd Timeline's default styles can be adjusted via theme variables or overriding class names; custom styles can also be wrapped in a parent container. + +#### Custom Node Icons + +- Custom icons: inject any icon component via the dot slot in Timeline.Item to achieve personalized visual node expression. + +**Section Source** + +- [docs/components/antd/timeline/demos/basic.py:27-37](file://docs/components/antd/timeline/demos/basic.py#L27-L37) + +#### Visualization in Project Progress + +- Recommendations: express milestones, task nodes, version releases, and other events as Timeline.Items; use color to mark priority/status; use dot slot for status icons; use pending/pendingDot slots to highlight the current phase. + +## Dependency Analysis + +- Tag Component + - useTargets: resolves target elements among child nodes to determine whether to fall back to children + value. + - **New**: createItemsContext: provides context support for tag groups to manage option lists and state. +- Timeline Component + - createItemsContext: provides the Items context responsible for collecting and merging child items. + - renderItems: converts the Item structure in context into the items array required by Antd. + - useItems: reads the collected items in Timeline and passes them to Antd Timeline. + +```mermaid +graph LR +USE_TARGETS["useTargets"] --> TAG["Tag"] +USE_TARGETS --> CTAG["CheckableTag"] +CREATE_ITEMS["createItemsContext"] --> CTAG_GROUP["CheckableTagGroup"] +CREATE_ITEMS --> TL["Timeline"] +TL --> RENDER_ITEMS["renderItems"] +TL --> TL_ITEM["Timeline.Item"] +CTAG_GROUP --> CTAG_OPTION["CheckableTagGroupOption"] +CTAG_OPTION --> CREATE_ITEMS +TL_ITEM --> CREATE_ITEMS +``` + +**Diagram Source** + +- [frontend/utils/hooks/useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [frontend/antd/tag/tag.tsx:12-32](file://frontend/antd/tag/tag.tsx#L12-L32) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:13-32](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L13-L32) +- [frontend/antd/tag/checkable-tag-group/context.ts:1-7](file://frontend/antd/tag/checkable-tag-group/context.ts#L1-L7) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:6-6](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L6-L6) +- [frontend/antd/timeline/timeline.tsx:7-7](file://frontend/antd/timeline/timeline.tsx#L7-L7) +- [frontend/utils/createItemsContext.tsx:97-106](file://frontend/utils/createItemsContext.tsx#L97-L106) +- [frontend/antd/timeline/item/Index.svelte:13-13](file://frontend/antd/timeline/item/Index.svelte#L13-L13) + +**Section Source** + +- [frontend/utils/hooks/useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [frontend/antd/tag/tag.tsx:12-32](file://frontend/antd/tag/tag.tsx#L12-L32) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:13-32](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L13-L32) +- [frontend/antd/tag/checkable-tag-group/context.ts:1-7](file://frontend/antd/tag/checkable-tag-group/context.ts#L1-L7) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:6-6](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L6-L6) +- [frontend/antd/timeline/timeline.tsx:7-7](file://frontend/antd/timeline/timeline.tsx#L7-L7) +- [frontend/utils/createItemsContext.tsx:97-106](file://frontend/utils/createItemsContext.tsx#L97-L106) +- [frontend/antd/timeline/item/Index.svelte:13-13](file://frontend/antd/timeline/item/Index.svelte#L13-L13) + +## Performance Considerations + +- Rendering Optimization + - useTargets only recalculates sorting and filtering of child nodes when children change, avoiding unnecessary re-renders. + - renderItems controls context update frequency via memoizedEqualValue and useMemoizedFn. + - **New**: CheckableTagGroup ensures option cloning via clone: true parameter to avoid state pollution. +- Context Stability + - withItemsContextProvider and useItems keep context references stable via useMemo and useRef, reducing subtree re-renders. + - **New**: Tag group context provides stable option management via createItemsContext. +- Slot Clone Strategy + - renderItems supports clone/forceClone parameters to control node cloning on demand, balancing performance with scope isolation. + +**Section Source** + +- [frontend/utils/hooks/useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [frontend/utils/createItemsContext.tsx:113-156](file://frontend/utils/createItemsContext.tsx#L113-L156) +- [frontend/utils/renderItems.tsx:62-94](file://frontend/utils/renderItems.tsx#L62-L94) +- [frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx:33-36](file://frontend/antd/tag/checkable-tag-group/tag.checkable-tag-group.tsx#L33-L36) + +## Troubleshooting Guide + +- Tag not displaying value + - Check whether children contain recognizable target nodes; if target nodes are present, they will take rendering priority over the value fallback. + - Reference path: [frontend/antd/tag/tag.tsx:22-29](file://frontend/antd/tag/tag.tsx#L22-L29) +- CheckableTag not triggering onValueChange + - Confirm that onValueChange is correctly passed; onChange is triggered before onValueChange, ensure the callback chain is complete. + - Reference path: [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:23-26](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L23-L26) +- **New**: CheckableTagGroup options not displayed + - Confirm that CheckableTagGroupOption is correctly used and content is injected via slots; check that the tag group context is active. + - Reference path: [frontend/antd/tag/checkable-tag-group/option/Index.svelte:55-73](file://frontend/antd/tag/checkable-tag-group/option/Index.svelte#L55-L73) +- **New**: Tag group value not updating + - Confirm that the onValueChange callback correctly handles the return value; check the tag group's value prop binding. + - Reference path: [frontend/antd/tag/checkable-tag-group/Index.svelte:71-73](file://frontend/antd/tag/checkable-tag-group/Index.svelte#L71-L73) +- Timeline not displaying any nodes + - Confirm that Timeline.Item is correctly used and content is injected via slots; check that the Items context is active. + - Reference path: [frontend/antd/timeline/item/Index.svelte:49-64](file://frontend/antd/timeline/item/Index.svelte#L49-L64) +- Custom dot not taking effect + - Ensure the dot slot is correctly declared inside Timeline.Item; check that slotKey matches the context. + - Reference path: [frontend/antd/timeline/item/Index.svelte:58-63](file://frontend/antd/timeline/item/Index.svelte#L58-L63) + +**Section Source** + +- [frontend/antd/tag/tag.tsx:22-29](file://frontend/antd/tag/tag.tsx#L22-L29) +- [frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx:23-26](file://frontend/antd/tag/checkable-tag/tag.checkable-tag.tsx#L23-L26) +- [frontend/antd/tag/checkable-tag-group/option/Index.svelte:55-73](file://frontend/antd/tag/checkable-tag-group/option/Index.svelte#L55-L73) +- [frontend/antd/tag/checkable-tag-group/Index.svelte:71-73](file://frontend/antd/tag/checkable-tag-group/Index.svelte#L71-L73) +- [frontend/antd/timeline/item/Index.svelte:49-64](file://frontend/antd/timeline/item/Index.svelte#L49-L64) +- [frontend/antd/timeline/item/Index.svelte:58-63](file://frontend/antd/timeline/item/Index.svelte#L58-L63) + +## Conclusion + +- The Tag component achieves flexible content fallback and icon extension through slot and target element resolution; CheckableTag provides a concise two-way binding and callback mechanism, suitable for multi-select and filtering scenarios. +- **New**: CheckableTagGroup provides powerful batch tag selection capabilities through a complete context system and option management, suitable for complex filtering and grouping scenarios. +- The Timeline component uses the Items context and renderItems to convert complex nested structures into the array form required by Antd, offering good extensibility and customization capabilities. +- In real business scenarios, combining backend component bridging and frontend prop forwarding can achieve linked display of dynamic tags and progress timelines. + +## Appendix + +- Example References + - CheckableTag demo: [docs/components/antd/tag/demos/checkable_tag.py:1-19](file://docs/components/antd/tag/demos/checkable_tag.py#L1-L19) + - Timeline basic demo: [docs/components/antd/timeline/demos/basic.py:1-41](file://docs/components/antd/timeline/demos/basic.py#L1-L41) +- **New**: CheckableTagGroup Examples + - Tag group basic usage: supports options array and dynamic option management + - Tag group batch operations: supports multi-select mode and batch state management + - Tag group nested usage: supports integrating tag group components in forms and filters diff --git a/.wiki/en/Ant Design Components/Data Display Components/Tooltip and Tour.md b/.wiki/en/Ant Design Components/Data Display Components/Tooltip and Tour.md new file mode 100644 index 00000000..1c61e6cf --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Tooltip and Tour.md @@ -0,0 +1,304 @@ +# Tooltip and Tour + + +**Files Referenced in This Document** +- [tooltip.tsx](file://frontend/antd/tooltip/tooltip.tsx) +- [tour.tsx](file://frontend/antd/tour/tour.tsx) +- [context.ts](file://frontend/antd/tour/context.ts) +- [Index.svelte (Tour)](file://frontend/antd/tour/Index.svelte) +- [Index.svelte (Tour Step)](file://frontend/antd/tour/step/Index.svelte) +- [tour.step.tsx](file://frontend/antd/tour/step/tour.step.tsx) +- [README.md (Tooltip docs)](file://docs/components/antd/tooltip/README.md) +- [README.md (Tour docs)](file://docs/components/antd/tour/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document covers the encapsulation and usage of the **Tooltip** and **Tour** Ant Design components in this repository. Key topics include: + +- Tooltip: trigger modes, position offset, delayed display, multi-line text support, nested usage, HTML content support, and accessibility optimization +- Tour: step configuration, path planning, focus areas, user interaction control, conditional logic, user preference memory, and guided flow customization + +## Project Structure + +This project uses Svelte + React preprocessing (svelte-preprocess-react) to expose Ant Design's React components to the Svelte ecosystem as Svelte components. Tooltip and Tour encapsulations are located under frontend/antd, and Tour's Step subcomponent is located at frontend/antd/tour/step. + +```mermaid +graph TB +subgraph "Ant Design Encapsulation Layer" +T["Tooltip
tooltip.tsx"] +TR["Tour
tour.tsx"] +TS["Tour Step
step/tour.step.tsx"] +end +subgraph "Svelte Wrapper Layer" +TI["Tour Wrapper
tour/Index.svelte"] +TSI["Tour Step Wrapper
step/Index.svelte"] +end +subgraph "Context and Utilities" +CTX["Items Context
tour/context.ts"] +U1["useFunction hook"] +U2["renderItems / renderParamsSlot utilities"] +end +T --> |"calls Antd Tooltip"| T +TR --> |"calls Antd Tour"| TR +TR --> CTX +TR --> U1 +TR --> U2 +TI --> TR +TSI --> TS +``` + +Diagram Source + +- [tooltip.tsx:1-29](file://frontend/antd/tooltip/tooltip.tsx#L1-L29) +- [tour.tsx:1-87](file://frontend/antd/tour/tour.tsx#L1-L87) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) +- [Index.svelte (Tour):1-60](file://frontend/antd/tour/Index.svelte#L1-L60) +- [Index.svelte (Tour Step):1-82](file://frontend/antd/tour/step/Index.svelte#L1-L82) +- [tour.step.tsx:1-14](file://frontend/antd/tour/step/tour.step.tsx#L1-L14) + +Section Source + +- [tooltip.tsx:1-29](file://frontend/antd/tooltip/tooltip.tsx#L1-L29) +- [tour.tsx:1-87](file://frontend/antd/tour/tour.tsx#L1-L87) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) +- [Index.svelte (Tour):1-60](file://frontend/antd/tour/Index.svelte#L1-L60) +- [Index.svelte (Tour Step):1-82](file://frontend/antd/tour/step/Index.svelte#L1-L82) +- [tour.step.tsx:1-14](file://frontend/antd/tour/step/tour.step.tsx#L1-L14) + +## Core Components + +- Tooltip: a lightweight wrapper for Ant Design Tooltip that preserves the title prop and slot-based title rendering capability, and safely injects callback functions into the React component via useFunction. +- Tour: an enhanced wrapper for Ant Design Tour that supports injecting steps, close icons, indicators, and action areas via slots; internally uses the Items context and render utilities to parse the step list; and provides onChange/onClose callback bridging. + +Section Source + +- [tooltip.tsx:7-26](file://frontend/antd/tooltip/tooltip.tsx#L7-L26) +- [tour.tsx:11-84](file://frontend/antd/tour/tour.tsx#L11-L84) + +## Architecture Overview + +The following diagram shows the call chain and data flow for Tooltip and Tour in this repository: + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant SvelteUI as "Svelte Component Wrapper Layer" +participant TourComp as "Tour Component" +participant TourStep as "Tour Step Component" +participant Ctx as "Items Context" +participant Antd as "Ant Design Tour/Tooltip" +Dev->>SvelteUI : Render Tour or Tooltip +SvelteUI->>TourComp : Pass props and slots +TourComp->>Ctx : Read steps/default slot items +TourComp->>Antd : Render Tour and pass steps and callbacks +TourComp->>TourStep : Render each step item +TourStep->>Antd : Render individual TourStep +Dev->>TourComp : Trigger onChange/onClose +TourComp-->>Dev : Callback notification +``` + +Diagram Source + +- [tour.tsx:17-83](file://frontend/antd/tour/tour.tsx#L17-L83) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) +- [Index.svelte (Tour):46-59](file://frontend/antd/tour/Index.svelte#L46-L59) +- [Index.svelte (Tour Step):61-81](file://frontend/antd/tour/step/Index.svelte#L61-L81) +- [tour.step.tsx:7-11](file://frontend/antd/tour/step/tour.step.tsx#L7-L11) + +## Detailed Component Analysis + +### Tooltip Component + +- Trigger Modes + - Supports standard mouse-hover triggering via Ant Design Tooltip's native behavior. + - Dynamic content rendering can be achieved via slot-based titles, making it easy to embed HTML structures or complex components in the title. +- Position Offset + - Fine-tuned using Ant Design Tooltip's native offset parameters to meet different layout requirements. +- Delayed Display + - Use Ant Design Tooltip's delay parameters to avoid flickering or accidental triggers from frequent interactions. +- Multi-line Text Support + - Naturally supports multi-line text and rich text via the slot-based title and Ant Design Tooltip's line-break mechanism. +- Nested Usage + - Other interactive elements (such as buttons or links) can be nested inside Tooltip to achieve composite interactions. +- HTML Content Support + - HTML fragments can be rendered in Tooltip by injecting React nodes into the title via a slot. +- Accessibility Optimization + - Maintain native semantic tags and keyboard reachability; ensure that the title content is readable and understandable. + +```mermaid +flowchart TD +Start(["Enter Tooltip render"]) --> CheckSlot["Check if title slot exists"] +CheckSlot --> |Yes| RenderSlot["Render slot content as title"] +CheckSlot --> |No| UseProp["Use title prop as title"] +RenderSlot --> PassProps["Forward to Antd Tooltip"] +UseProp --> PassProps +PassProps --> End(["Rendering complete"]) +``` + +Diagram Source + +- [tooltip.tsx:17-19](file://frontend/antd/tooltip/tooltip.tsx#L17-L19) + +Section Source + +- [tooltip.tsx:7-26](file://frontend/antd/tooltip/tooltip.tsx#L7-L26) + +### Tour Component + +- Step Configuration + - Supports directly passing a steps array, or injecting steps/default items via slots; internally, render utilities uniformly parse them into the step format required by Ant Design Tour. +- Path Planning + - Step navigation is implemented via Ant Design Tour's built-in navigation logic; the current step index can be obtained via onChange, and combined with business logic to implement conditional decisions and path changes. +- Focus Areas + - Each step can bind a target element selector or function for locating the focus area; dynamic target element computation is supported. +- User Interaction Control + - Provides closeIcon, indicatorsRender, and actionsRender slots for customizing the close icon, indicators, and action area. + - Use the onClose callback to perform cleanup or record user preferences on close. +- Conditional Logic + - In onChange, determine whether to allow the next step or skip certain steps based on the current step and business state. +- User Preference Memory + - Persist user preferences (e.g., "don't show again") in onClose, and decide whether to show the Tour on next initialization based on preferences. +- Guided Flow Customization + - Combine slots and callbacks to implement custom guide text, styles, and interaction behavior. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Tour as "Tour Component" +participant Steps as "Steps List" +participant Ctx as "Items Context" +participant Antd as "Antd Tour" +Dev->>Tour : Pass steps or slot items +Tour->>Ctx : Read steps/default +Tour->>Steps : Use render utilities to parse into Antd steps +Tour->>Antd : Render Tour and pass step list +Dev->>Tour : Trigger onChange/onClose +Tour-->>Dev : Return current step index/close event +``` + +Diagram Source + +- [tour.tsx:33-48](file://frontend/antd/tour/tour.tsx#L33-L48) +- [tour.tsx:49-78](file://frontend/antd/tour/tour.tsx#L49-L78) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) + +Section Source + +- [tour.tsx:11-84](file://frontend/antd/tour/tour.tsx#L11-L84) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) + +#### Tour Step Component + +- Role + - Serves as the container for a single step, responsible for mapping externally passed props and slots to Ant Design TourStep. +- Key Points + - Supports target functions or selectors for locating focus areas. + - Supports bridging interactive props such as next_button_click/prev_button_click. + - Integrates with the Items context via ItemHandler for step item registration and management. + +```mermaid +classDiagram +class TourStep { ++props : TourStepProps ++target : string|function ++itemIndex : number ++slots : object +} +class ItemHandler { ++register(item) ++unregister(id) +} +TourStep --> ItemHandler : "register/manage step items" +``` + +Diagram Source + +- [tour.step.tsx:7-11](file://frontend/antd/tour/step/tour.step.tsx#L7-L11) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) + +Section Source + +- [Index.svelte (Tour Step):1-82](file://frontend/antd/tour/step/Index.svelte#L1-L82) +- [tour.step.tsx:1-14](file://frontend/antd/tour/step/tour.step.tsx#L1-L14) + +## Dependency Analysis + +- Tooltip depends on Ant Design Tooltip, adapted from React component to Svelte via sveltify. +- Tour depends on Ant Design Tour, and also introduces the Items context and render utilities to convert slots into step arrays. +- The Svelte wrapper layer handles prop and slot forwarding, class name and visibility control, and async loading of the underlying component. + +```mermaid +graph LR +A["tooltip.tsx"] --> AD1["Antd Tooltip"] +B["tour.tsx"] --> AD2["Antd Tour"] +B --> C["context.ts"] +D["tour/Index.svelte"] --> B +E["step/Index.svelte"] --> F["step/tour.step.tsx"] +``` + +Diagram Source + +- [tooltip.tsx:1-29](file://frontend/antd/tooltip/tooltip.tsx#L1-L29) +- [tour.tsx:1-87](file://frontend/antd/tour/tour.tsx#L1-L87) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) +- [Index.svelte (Tour):1-60](file://frontend/antd/tour/Index.svelte#L1-L60) +- [Index.svelte (Tour Step):1-82](file://frontend/antd/tour/step/Index.svelte#L1-L82) +- [tour.step.tsx:1-14](file://frontend/antd/tour/step/tour.step.tsx#L1-L14) + +Section Source + +- [tooltip.tsx:1-29](file://frontend/antd/tooltip/tooltip.tsx#L1-L29) +- [tour.tsx:1-87](file://frontend/antd/tour/tour.tsx#L1-L87) +- [context.ts:1-7](file://frontend/antd/tour/context.ts#L1-L7) +- [Index.svelte (Tour):1-60](file://frontend/antd/tour/Index.svelte#L1-L60) +- [Index.svelte (Tour Step):1-82](file://frontend/antd/tour/step/Index.svelte#L1-L82) +- [tour.step.tsx:1-14](file://frontend/antd/tour/step/tour.step.tsx#L1-L14) + +## Performance Considerations + +- Use useMemo to cache the step array and avoid unnecessary re-renders. +- Render Tour and Step only when visible to reduce DOM overhead. +- Use slots and dynamic rendering judiciously to avoid rendering too many complex nodes at once. +- In onChange/onClose, avoid heavy synchronous operations; use async processing where necessary. + +## Troubleshooting Guide + +- Title not displayed or empty + - Check whether title is correctly passed or whether the title slot is used; confirm that the slot content has been correctly rendered. +- Steps not taking effect + - Confirm that the steps or slot items are correctly injected; check whether the Items context is correctly provided. +- Target element cannot be focused + - Check the target selector or function return value; ensure the element is rendered on the page and accessible. +- Callbacks not triggered + - Confirm that onChange/onClose are correctly passed; check whether useFunction is correctly wrapping the callbacks. + +Section Source + +- [tour.tsx:33-48](file://frontend/antd/tour/tour.tsx#L33-L48) +- [tour.tsx:49-78](file://frontend/antd/tour/tour.tsx#L49-L78) +- [Index.svelte (Tour):46-59](file://frontend/antd/tour/Index.svelte#L46-L59) +- [Index.svelte (Tour Step):69-73](file://frontend/antd/tour/step/Index.svelte#L69-L73) + +## Conclusion + +The encapsulation of Tooltip and Tour in this repository follows the principles of "lightweight, extensible, and easy to integrate": while preserving Ant Design's native capabilities, it enhances step configuration, interaction customization, and rendering flexibility through slots and context mechanisms. In practice, it is recommended to configure step paths, target areas, and user preferences based on business scenarios to achieve a better user experience. + +## Appendix + +- Demo and Documentation Entry Points + - Tooltip documentation demo entry: [Tooltip docs:1-8](file://docs/components/antd/tooltip/README.md#L1-L8) + - Tour documentation demo entry: [Tour docs:1-8](file://docs/components/antd/tour/README.md#L1-L8) diff --git a/.wiki/en/Ant Design Components/Data Display Components/Tree.md b/.wiki/en/Ant Design Components/Data Display Components/Tree.md new file mode 100644 index 00000000..7d277088 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Display Components/Tree.md @@ -0,0 +1,348 @@ +# Tree + + +**Files Referenced in This Document** +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [Index.svelte](file://frontend/antd/tree/Index.svelte) +- [context.ts](file://frontend/antd/tree/context.ts) +- [tree.tree-node.tsx](file://frontend/antd/tree/tree-node/tree.tree-node.tsx) +- [directory-tree/Index.svelte](file://frontend/antd/tree/directory-tree/Index.svelte) +- [folder.tsx](file://frontend/antdx/folder/folder.tsx) +- [context.ts (folder context)](file://frontend/antdx/folder/context.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically reviews the design and implementation of the **Tree** component, covering its basic structure, node expand/collapse, DirectoryTree special capabilities, asynchronous data source loading, selection modes and multi-select/half-select, disabled configuration, search filtering, node dragging, right-click context menu, batch operations, virtual scrolling and large dataset optimization, dynamic CRUD operations, as well as typical applications and performance strategies in file management, organizational structures, and classification systems. + +## Project Structure + +The Tree component is composed of a Svelte frontend wrapper layer and a React component bridge layer, and supports declarative nesting and data injection for tree nodes via an "item context" mechanism. DirectoryTree, as a specialized form of Tree, reuses the same bridge layer and enables the directory tree component. + +```mermaid +graph TB +subgraph "Frontend Wrapper Layer" +T_Index["Tree/Index.svelte"] +DT_Index["DirectoryTree/Index.svelte"] +TN_Node["TreeNode/tree.tree-node.tsx"] +end +subgraph "Bridge and Context" +Bridge["Tree/tree.tsx"] +Ctx["Tree/context.ts"] +end +subgraph "External Dependencies" +AntD["Ant Design Tree/DirectoryTree"] +end +T_Index --> Bridge +DT_Index --> Bridge +TN_Node --> Ctx +Bridge --> AntD +``` + +Diagram Source + +- [Index.svelte:1-80](file://frontend/antd/tree/Index.svelte#L1-L80) +- [directory-tree/Index.svelte:1-83](file://frontend/antd/tree/directory-tree/Index.svelte#L1-L83) +- [tree.tree-node.tsx:1-22](file://frontend/antd/tree/tree-node/tree.tree-node.tsx#L1-L22) +- [tree.tsx:1-150](file://frontend/antd/tree/tree.tsx#L1-L150) +- [context.ts:1-7](file://frontend/antd/tree/context.ts#L1-L7) + +Section Source + +- [Index.svelte:1-80](file://frontend/antd/tree/Index.svelte#L1-L80) +- [directory-tree/Index.svelte:1-83](file://frontend/antd/tree/directory-tree/Index.svelte#L1-L83) +- [tree.tsx:1-150](file://frontend/antd/tree/tree.tsx#L1-L150) +- [context.ts:1-7](file://frontend/antd/tree/context.ts#L1-L7) + +## Core Components + +- Tree Wrapper: responsible for bridging Ant Design's Tree/DirectoryTree to the Svelte ecosystem, supporting slot extension, event forwarding, async loading, dragging, and title rendering. +- Tree Node: injects child nodes via ItemHandler as "default" slots, forming a tree structure. +- DirectoryTree: enables directory tree mode on top of Tree, providing folder-style interaction and behavior. +- Item Context: uniformly manages the collection and injection of "items" such as tree nodes and directory icons. + +Section Source + +- [tree.tsx:14-148](file://frontend/antd/tree/tree.tsx#L14-L148) +- [tree.tree-node.tsx:7-18](file://frontend/antd/tree/tree-node/tree.tree-node.tsx#L7-L18) +- [directory-tree/Index.svelte:65-82](file://frontend/antd/tree/directory-tree/Index.svelte#L65-L82) +- [context.ts:3-4](file://frontend/antd/tree/context.ts#L3-L4) + +## Architecture Overview + +The following diagram shows the call chain from Svelte to React, as well as the switching logic between DirectoryTree and regular Tree. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Wrapper Layer" +participant Bridge as "Tree Bridge Layer" +participant AntD as "Ant Design Component Library" +Svelte->>Bridge : Pass props and slots +Bridge->>Bridge : Parse treeData/slots/events +alt Directory Tree Mode +Bridge->>AntD : Use DirectoryTree +else Regular Tree Mode +Bridge->>AntD : Use Tree +end +AntD-->>Bridge : Render results and callbacks +Bridge-->>Svelte : Event forwarding/data return +``` + +Diagram Source + +- [tree.tsx:52-115](file://frontend/antd/tree/tree.tsx#L52-L115) +- [Index.svelte:67-78](file://frontend/antd/tree/Index.svelte#L67-L78) +- [directory-tree/Index.svelte:66-81](file://frontend/antd/tree/directory-tree/Index.svelte#L66-L81) + +## Detailed Component Analysis + +### Basic Structure and Data Model + +- Data Source Origins + - Explicit treeData: directly pass the tree node array required by AntD. + - Slot treeData/default: collect child nodes via item context, automatically converting to treeData. +- Key Fields + - Identification and hierarchy: key/value/title etc. used for identification and display. + - Expanded state: expandedKeys controls initial expansion; onExpand callback responds to user actions. + - Selection and checking: selectedKeys/checkedKeys support single/multi-select; half-select is calculated via internal algorithm. + - Disabled: disabled field disables node interaction. +- Slot Extensions + - switcherIcon/switcherLoadingIcon: custom expand/loading icons. + - showLine.showLeafIcon: custom connection line leaf icon. + - icon: node icon. + - draggable.icon/nodeDraggable: drag icon and node-level draggable toggle. + - titleRender: custom title render function. + +Section Source + +- [tree.tsx:56-126](file://frontend/antd/tree/tree.tsx#L56-L126) +- [context.ts:3-4](file://frontend/antd/tree/context.ts#L3-L4) + +### Expand/Collapse and Async Loading + +- Expand/Collapse + - Get the current expanded set via onExpand, and implement hierarchical expansion combined with treeData's children. +- Async Loading + - Provide lazy loading hooks via loadData/onLoadData, requesting child node data on demand. + - DirectoryTree mode also supports async loading, suitable for large directory scenarios. + +```mermaid +flowchart TD +Start(["User clicks expand"]) --> CheckLoaded{"Child nodes already loaded?"} +CheckLoaded --> |No| Load["Trigger onLoadData/loadData request"] +Load --> Update["Update treeData child nodes"] +CheckLoaded --> |Yes| Render["Render child nodes directly"] +Update --> Render +Render --> End(["Done"]) +``` + +Diagram Source + +- [tree.tsx:114-114](file://frontend/antd/tree/tree.tsx#L114-L114) +- [tree.tsx:137-139](file://frontend/antd/tree/tree.tsx#L137-L139) + +Section Source + +- [tree.tsx:38-42](file://frontend/antd/tree/tree.tsx#L38-L42) +- [tree.tsx:114-114](file://frontend/antd/tree/tree.tsx#L114-L114) + +### DirectoryTree Special Features + +- Mode Switching + - Toggle between Tree and DirectoryTree via the directory prop. +- Event Mapping + - dragStart/dragEnter/dragOver/dragLeave/dragEnd: drag lifecycle events. + - rightClick: right-click context menu trigger. + - loadData: directory tree specific lazy loading hook. +- Folder Style + - More aligned with file system browsing experience, supporting directory hierarchy and icon mapping. + +Section Source + +- [tree.tsx:52-52](file://frontend/antd/tree/tree.tsx#L52-L52) +- [directory-tree/Index.svelte:18-25](file://frontend/antd/tree/directory-tree/Index.svelte#L18-L25) +- [directory-tree/Index.svelte:50-58](file://frontend/antd/tree/directory-tree/Index.svelte#L50-L58) + +### Selection Modes, Multi-select and Half-select + +- Single-select/Multi-select + - Implement single or multi-select via selectedKeys/onChange. +- Multi-select Linkage + - Checking parent nodes affects child nodes; unchecking affects parent node state. +- Half-select State + - When some child nodes are checked, the parent node shows a half-selected state for quick identification of partial selection. +- Disabled Nodes + - The disabled field prevents nodes from being selected or checked. + +Section Source + +- [tree.tsx:134-142](file://frontend/antd/tree/tree.tsx#L134-L142) + +### Search Filtering + +- Filter Function + - filterTreeNode accepts a node and input value, returning a boolean to decide whether to display. +- Practical Recommendations + - Combine expanded state and highlight matching items to improve discoverability. + +Section Source + +- [tree.tsx:132-132](file://frontend/antd/tree/tree.tsx#L132-L132) + +### Node Dragging + +- Drag Toggle + - draggable can be a boolean or object; nodeDraggable supports node-level draggable control. +- Icon Customization + - draggable.icon customizes the drag handle icon. +- Event Forwarding + - dragStart/dragEnd etc. events are triggered by the underlying component for business layer integration. + +Section Source + +- [tree.tsx:102-112](file://frontend/antd/tree/tree.tsx#L102-L112) +- [tree.tsx:48-50](file://frontend/antd/tree/tree.tsx#L48-L50) + +### Right-click Context Menu and Batch Operations + +- Right-click Context Menu + - rightClick event can be used to pop up a context menu. +- Batch Operations + - Combine multi-select and right-click context menu for batch actions like copy, move, and delete. +- Safety + - Intercept disabled nodes to prevent accidental operations. + +Section Source + +- [directory-tree/Index.svelte:23-23](file://frontend/antd/tree/directory-tree/Index.svelte#L23-L23) +- [tree.tsx:134-142](file://frontend/antd/tree/tree.tsx#L134-L142) + +### Dynamic CRUD Operations + +- Add/Modify + - Update treeData or maintain selectedKeys/checkedKeys in controlled mode. +- Delete + - Remove the corresponding node and synchronize cleanup of selection state. +- Query + - Link filterTreeNode with search input for instant filtering. + +Section Source + +- [tree.tsx:59-79](file://frontend/antd/tree/tree.tsx#L59-L79) + +### Virtual Scrolling and Large Dataset Optimization + +- Virtual Scrolling + - Enabling virtual scrolling in super-large trees can significantly reduce DOM count and improve rendering performance. +- Other Optimizations + - Lazy loading (loadData/onLoadData) renders only visible levels. + - Use disabled and hidden nodes judiciously to reduce rendering burden. + - Avoid frequent recalculation of treeData; use shallow comparison and caching where possible. + +Section Source + +- [tree.tsx:114-114](file://frontend/antd/tree/tree.tsx#L114-L114) + +### Application Scenarios and Best Practices + +- File Management + - DirectoryTree + dragging + right-click context menu + async loading to build a file browser-like experience. +- Organizational Structure + - Departments/teams as nodes, supporting collapse and search for easy navigation. +- Classification Systems + - Multi-level classification tree, combined with half-select and batch operations to improve editing efficiency. + +Section Source + +- [directory-tree/Index.svelte:65-82](file://frontend/antd/tree/directory-tree/Index.svelte#L65-L82) +- [tree.tsx:52-52](file://frontend/antd/tree/tree.tsx#L52-L52) + +## Dependency Analysis + +- Component Coupling + - Tree/Index.svelte and DirectoryTree/Index.svelte both depend on the Tree bridge layer. + - Tree nodes inject into the context via ItemHandler, forming a tree structure. +- External Dependencies + - Ant Design Tree/DirectoryTree provides core interaction and rendering. +- Slots and Events + - High customizability is achieved through slots and event forwarding. + +```mermaid +graph LR +T_Index["Tree/Index.svelte"] --> Bridge["Tree/tree.tsx"] +DT_Index["DirectoryTree/Index.svelte"] --> Bridge +TN_Node["TreeNode/tree.tree-node.tsx"] --> Ctx["Tree/context.ts"] +Bridge --> AntD["Ant Design Tree/DirectoryTree"] +``` + +Diagram Source + +- [Index.svelte:10-10](file://frontend/antd/tree/Index.svelte#L10-L10) +- [directory-tree/Index.svelte:10-10](file://frontend/antd/tree/directory-tree/Index.svelte#L10-L10) +- [tree.tsx:1-11](file://frontend/antd/tree/tree.tsx#L1-L11) +- [tree.tree-node.tsx:5-5](file://frontend/antd/tree/tree-node/tree.tree-node.tsx#L5-L5) +- [context.ts:3-4](file://frontend/antd/tree/context.ts#L3-L4) + +Section Source + +- [Index.svelte:1-80](file://frontend/antd/tree/Index.svelte#L1-L80) +- [directory-tree/Index.svelte:1-83](file://frontend/antd/tree/directory-tree/Index.svelte#L1-L83) +- [tree.tsx:1-150](file://frontend/antd/tree/tree.tsx#L1-L150) +- [tree.tree-node.tsx:1-22](file://frontend/antd/tree/tree-node/tree.tree-node.tsx#L1-L22) +- [context.ts:1-7](file://frontend/antd/tree/context.ts#L1-L7) + +## Performance Considerations + +- Rendering Optimization + - Use virtual scrolling and lazy loading to avoid rendering a large number of nodes at once. +- Data Structure + - Keep treeData flat and stable in reference to reduce unnecessary re-renders. +- Event Throttling + - Throttle/debounce high-frequency events (such as drag and scroll). +- Selection and Half-select + - Use checkedKeys and half-select state judiciously to avoid recursive calculations layer by layer. + +## Troubleshooting Guide + +- Cannot expand nodes + - Check whether treeData's children are correctly set or whether async loading is implemented. +- Drag not working + - Confirm that draggable is an object and includes nodeDraggable or that draggable.icon is correctly injected. +- Right-click context menu not appearing + - Confirm that the rightClick event is bound and works in directory tree mode. +- Selection state anomaly + - Check whether selectedKeys/checkedKeys are updated synchronously with treeData. + +Section Source + +- [tree.tsx:102-112](file://frontend/antd/tree/tree.tsx#L102-L112) +- [tree.tsx:134-142](file://frontend/antd/tree/tree.tsx#L134-L142) +- [directory-tree/Index.svelte:23-23](file://frontend/antd/tree/directory-tree/Index.svelte#L23-L23) + +## Conclusion + +This Tree component provides complete encapsulation of Ant Design Tree/DirectoryTree through the combination of a Svelte wrapper layer and React bridge layer, with good extensibility and customizability. Combined with async loading, virtual scrolling, and rich interaction capabilities, it is suitable for complex scenarios such as file management, organizational structures, and classification systems. + +## Appendix + +- Relationship Between DirectoryTree and Folder Component + - DirectoryTree is used for the directory mode of the tree; the folder component (antdx/folder) provides richer file system capabilities (such as icon mapping and content services), and the two can be used complementarily. + +Section Source + +- [directory-tree/Index.svelte:65-82](file://frontend/antd/tree/directory-tree/Index.svelte#L65-L82) +- [folder.tsx:48-86](file://frontend/antdx/folder/folder.tsx#L48-L86) +- [context.ts (folder context):3-13](file://frontend/antdx/folder/context.ts#L3-L13) diff --git a/.wiki/en/Ant Design Components/Data Entry Components/Color and File Components.md b/.wiki/en/Ant Design Components/Data Entry Components/Color and File Components.md new file mode 100644 index 00000000..d9f7205d --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Entry Components/Color and File Components.md @@ -0,0 +1,364 @@ +# Color and File Components + + +**Files referenced in this document** +- [color-picker.tsx](file://frontend/antd/color-picker/color-picker.tsx) +- [context.ts (ColorPicker)](file://frontend/antd/color-picker/context.ts) +- [upload.tsx](file://frontend/antd/upload/upload.tsx) +- [upload.ts (utility functions)](file://frontend/utils/upload.ts) +- [slider.tsx](file://frontend/antd/slider/slider.tsx) +- [context.ts (Slider)](file://frontend/antd/slider/context.ts) +- [form.tsx](file://frontend/antd/form/form.tsx) +- [README.md (ColorPicker docs)](file://docs/components/antd/color_picker/README.md) +- [README.md (Upload docs)](file://docs/components/antd/upload/README.md) +- [README.md (Slider docs)](file://docs/components/antd/slider/README.md) +- [README.md (Form docs)](file://docs/components/antd/form/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on color, file, and advanced input components: ColorPicker, Upload, Slider, and Form. Content covers: + +- Color format conversion (RGB, HEX, HSB), gradient color handling and preset palettes +- Upload configuration, drag-and-drop upload, file preview, progress display and error handling +- Overall form design patterns, field validation, dynamic forms and nested forms +- Accessibility and keyboard navigation support +- Performance optimization strategies such as large file handling, concurrent uploads, and error retry +- Data flow management and best practices for complex form scenarios + +## Project Structure + +These components are located in the frontend Svelte + Ant Design ecosystem, bridging Ant Design components for Svelte use via sveltify, and encapsulating state and callbacks where necessary to adapt to the Gradio data domain. + +```mermaid +graph TB +subgraph "Antd Component Layer" +CP["ColorPicker"] +UP["Upload"] +SL["Slider"] +FM["Form"] +end +subgraph "Utilities and Context" +CTX_CP["ColorPicker Context"] +CTX_SL["Slider Context"] +UT["Upload Utility Functions
URL Parsing and Assembly"] +end +CP --> CTX_CP +SL --> CTX_SL +UP --> UT +``` + +Diagram Source + +- [color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [upload.tsx:1-282](file://frontend/antd/upload/upload.tsx#L1-L282) +- [slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +Section Source + +- [color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [upload.tsx:1-282](file://frontend/antd/upload/upload.tsx#L1-L282) +- [slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +## Core Components + +- ColorPicker + - Supports RGB/HEX/HSB three color format outputs + - Gradient color parsing and multi-point color mapping + - Preset palette rendering and custom panel/text slots +- Upload + - Custom request hook and progress formatting + - File list normalization, maximum count control + - Drag-and-drop/click upload, preview and icon rendering slots +- Slider + - Tick mark rendering (supports label slots) + - Step and tooltip container customization +- Form + - Value domain binding and change notification + - Manually trigger reset/submit/validate actions + - Required mark and feedback icon slots + +Section Source + +- [color-picker.tsx:11-103](file://frontend/antd/color-picker/color-picker.tsx#L11-L103) +- [upload.tsx:21-279](file://frontend/antd/upload/upload.tsx#L21-L279) +- [slider.tsx:37-94](file://frontend/antd/slider/slider.tsx#L37-L94) +- [form.tsx:15-76](file://frontend/antd/form/form.tsx#L15-L76) + +## Architecture Overview + +Components use a "bridge + decoration" architecture: with Ant Design native components as the core, wrapped via sveltify and injected with value change callbacks, slot rendering, and context injection to achieve seamless integration with the Gradio data domain. + +```mermaid +sequenceDiagram +participant U as "User" +participant C as "ColorPicker" +participant A as "Antd ColorPicker" +participant F as "Format Conversion Logic" +U->>C : Select color/drag gradient +C->>A : Trigger onChange(...) +A-->>C : Return color object/gradient info +C->>F : Convert to RGB/HEX/HSB according to value_format +F-->>C : Output unified format array or string +C-->>U : Callback onValueChange(...) +``` + +Diagram Source + +- [color-picker.tsx:71-95](file://frontend/antd/color-picker/color-picker.tsx#L71-L95) + +Section Source + +- [color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) + +## Detailed Component Analysis + +### ColorPicker + +- Key features + - Color format conversion: one of RGB/HEX/HSB, output according to value_format + - Gradient color handling: iterate through gradient points, convert each to the specified format and return as array + - Preset palette: supports passing presets or injecting via context + - Slot extension: slot-based rendering for panelRender and showText +- Key flow + +```mermaid +flowchart TD +Start(["Start"]) --> IsGrad{"Is gradient color?"} +IsGrad --> |Yes| Iterate["Iterate through gradient points"] +Iterate --> Convert["Convert color according to value_format"] +Convert --> EmitGrad["Callback onValueChange(array)"] +IsGrad --> |No| Single["Single color conversion"] +Single --> EmitSingle["Callback onValueChange(string)"] +EmitGrad --> End(["End"]) +EmitSingle --> End +``` + +Diagram Source + +- [color-picker.tsx:71-95](file://frontend/antd/color-picker/color-picker.tsx#L71-L95) + +- Context and preset palette + - Inject marks/presets and other item sets via createItemsContext + - Preset palette prefers externally passed values; otherwise renders from context + +- Accessibility and keyboard navigation + - Based on Ant Design native component, follows its accessibility specifications + - Recommended to supplement aria-label, aria-describedby and other attributes on the business side + +Section Source + +- [color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [context.ts (ColorPicker):1-7](file://frontend/antd/color-picker/context.ts#L1-L7) +- [README.md (ColorPicker docs):1-9](file://docs/components/antd/color_picker/README.md#L1-L9) + +### Upload + +- Key features + - Custom upload: upload(files) -> Promise + - File list normalization: converts non-UploadFile forms to UploadFile structure + - Maximum count control: when maxCount=1, replace; otherwise append + - Progress and icons: supports custom progress formatting and icon rendering slots + - Preview and image recognition: custom previewFile/isImageUrl +- Key flow + +```mermaid +sequenceDiagram +participant U as "User" +participant UI as "Upload" +participant CU as "customRequest/upload" +participant SV as "Server" +U->>UI : Select/drag file +UI->>UI : beforeUpload validation +UI->>UI : Set temporary uploading state and temporary file list +UI->>CU : Call upload(validFiles) +CU->>SV : Send file +SV-->>CU : Return FileData[] +CU-->>UI : Return result +UI->>UI : Merge file list and callback onValueChange/onChange +``` + +Diagram Source + +- [upload.tsx:147-227](file://frontend/antd/upload/upload.tsx#L147-L227) + +- Utility functions: URL retrieval + - getFetchableUrl: concatenates relative paths to accessible URLs + - getFileUrl: returns a usable URL based on FileData/string/other types + +- Performance and reliability + - Disables interaction during upload to avoid repeated triggering + - Temporary file list improves user experience, replaced by real results after completion + - Restores uploading state after error capture + +Section Source + +- [upload.tsx:1-282](file://frontend/antd/upload/upload.tsx#L1-L282) +- [upload.ts (utility functions):1-45](file://frontend/utils/upload.ts#L1-L45) +- [README.md (Upload docs):1-9](file://docs/components/antd/upload/README.md#L1-L9) + +### Slider + +- Key features + - Tick mark rendering: supports label/children slots and property forwarding + - Tooltip container and formatting: tooltip.formatter and getPopupContainer + - Step control: explicitly pass null for step when not set +- Key flow + +```mermaid +flowchart TD +Start(["Start"]) --> RenderMarks["Render tick marks"] +RenderMarks --> SetTooltip["Configure tooltip.formatter/getPopupContainer"] +SetTooltip --> BindStep["step=null if not set"] +BindStep --> OnChange["onChange callback onValueChange(...)"] +OnChange --> End(["End"]) +``` + +Diagram Source + +- [slider.tsx:68-89](file://frontend/antd/slider/slider.tsx#L68-L89) + +Section Source + +- [slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [context.ts (Slider):1-7](file://frontend/antd/slider/context.ts#L1-L7) +- [README.md (Slider docs):1-9](file://docs/components/antd/slider/README.md#L1-L9) + +### Form + +- Key features + - Value domain binding: value -> setFieldsValue; onValuesChange -> onValueChange + - Form actions: trigger corresponding behavior via formAction='reset'|'submit'|'validate' + - Slots: requiredMark, feedbackIcons +- Key flow + +```mermaid +sequenceDiagram +participant V as "External value" +participant F as "Form" +participant AF as "Antd Form Instance" +V->>F : Pass value +F->>AF : setFieldsValue(value) +AF-->>F : onValuesChange(values) +F-->>V : onValueChange(values) +Note over F : Monitor formAction +F->>AF : reset/submit/validate +AF-->>F : Reset formAction after completion +``` + +Diagram Source + +- [form.tsx:32-45](file://frontend/antd/form/form.tsx#L32-L45) + +Section Source + +- [form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [README.md (Form docs):1-14](file://docs/components/antd/form/README.md#L1-L14) + +## Dependency Analysis + +- Inter-component coupling + - ColorPicker/Slider inject item sets via their respective Items contexts, reducing coupling with external data + - Upload relies on utility functions for URL parsing, avoiding scattered logic within the component + - Form only handles bridging and action dispatching, without directly processing business data +- External dependencies + - Ant Design native components as the base UI + - Gradio client types (FileData) for the upload data domain + +```mermaid +graph LR +CP["ColorPicker"] --> CTX_CP["ColorPicker Context"] +SL["Slider"] --> CTX_SL["Slider Context"] +UP["Upload"] --> UT["Upload Utility Functions"] +FM["Form"] --> AF["Antd Form Instance"] +``` + +Diagram Source + +- [color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [upload.tsx:1-282](file://frontend/antd/upload/upload.tsx#L1-L282) +- [form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +Section Source + +- [color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [upload.tsx:1-282](file://frontend/antd/upload/upload.tsx#L1-L282) +- [form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +## Performance Considerations + +- ColorPicker + - Gradient color conversion is completed in onChange to avoid additional rendering overhead + - Preset palette caches rendering results via useMemo +- Upload + - Temporary file list reduces UI jitter + - Disables interaction during upload to prevent concurrent submissions + - Supports custom progress formatting to avoid frequent redraws +- Slider + - Tick marks are rendered on demand to reduce DOM nodes + - step is explicitly passed as null to avoid invalid computation +- Form + - Value changes are only called back in onValuesChange to avoid full synchronization + +[This section provides general performance recommendations and does not require specific file references] + +## Troubleshooting Guide + +- ColorPicker + - If gradient colors are not correctly converted, check whether value_format is consistent with the expectation + - If the preset palette is not displayed, confirm whether context injection or presets property is correctly passed in +- Upload + - Cannot upload: confirm that the upload function's return value is consistent with the FileData structure + - Progress not updating: check whether progress.format is correctly passed in + - Icon/preview anomaly: verify iconRender/itemRender slots and custom functions +- Slider + - Tick marks not displayed: confirm whether marks or context items are correctly injected + - Step invalid: ensure step has not been overridden to undefined +- Form + - Values not syncing: confirm whether two-way binding of value and onValueChange is effective + - Action invalid: check whether formAction has been reset to null + +Section Source + +- [color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [upload.tsx:1-282](file://frontend/antd/upload/upload.tsx#L1-L282) +- [slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +## Conclusion + +The above components are built on Ant Design, combined with context injection and utility functions, to achieve high-performance, extensible and maintainable advanced input capabilities. Through a unified value change callback and slot mechanism, they can meet the needs of complex forms and file handling scenarios. It is recommended to combine error boundaries, loading states, and accessibility attributes in actual projects to further improve stability and user experience. + +[This section is a summary and does not require specific file references] + +## Appendix + +- Examples and documentation entry points + - ColorPicker: see examples and descriptions in the docs directory + - Upload: see examples and descriptions in the docs directory + - Slider: see examples and descriptions in the docs directory + - Form: see examples and descriptions in the docs directory + +Section Source + +- [README.md (ColorPicker docs):1-9](file://docs/components/antd/color_picker/README.md#L1-L9) +- [README.md (Upload docs):1-9](file://docs/components/antd/upload/README.md#L1-L9) +- [README.md (Slider docs):1-9](file://docs/components/antd/slider/README.md#L1-L9) +- [README.md (Form docs):1-14](file://docs/components/antd/form/README.md#L1-L14) diff --git a/.wiki/en/Ant Design Components/Data Entry Components/Data Entry Components.md b/.wiki/en/Ant Design Components/Data Entry Components/Data Entry Components.md new file mode 100644 index 00000000..87a53bc1 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Entry Components/Data Entry Components.md @@ -0,0 +1,520 @@ +# Data Entry Components + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [frontend/antd/auto-complete/auto-complete.tsx](file://frontend/antd/auto-complete/auto-complete.tsx) +- [frontend/antd/cascader/cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [frontend/antd/checkbox/checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [frontend/antd/color-picker/color-picker.tsx](file://frontend/antd/color-picker/color-picker.tsx) +- [frontend/antd/date-picker/date-picker.tsx](file://frontend/antd/date-picker/date-picker.tsx) +- [frontend/antd/radio/radio.tsx](file://frontend/antd/radio/radio.tsx) +- [frontend/antd/rate/rate.tsx](file://frontend/antd/rate/rate.tsx) +- [frontend/antd/slider/slider.tsx](file://frontend/antd/slider/slider.tsx) +- [frontend/antd/switch/switch.tsx](file://frontend/antd/switch/switch.tsx) +- [frontend/antd/time-picker/time-picker.tsx](file://frontend/antd/time-picker/time-picker.tsx) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/form/item/form.item.tsx](file://frontend/antd/form/item/form.item.tsx) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) +- [frontend/antd/form/provider/form.provider.tsx](file://frontend/antd/form/provider/form.provider.tsx) +- [frontend/antd/input/input.tsx](file://frontend/antd/input/input.tsx) +- [frontend/antd/input/otp/input.otp.tsx](file://frontend/antd/input/otp/input.otp.tsx) +- [frontend/antd/input/password/input.password.tsx](file://frontend/antd/input/password/input.password.tsx) +- [frontend/antd/input/search/input.search.tsx](file://frontend/antd/input/search/input.search.tsx) +- [frontend/antd/input/textarea/input.textarea.tsx](file://frontend/antd/input/textarea/input.textarea.tsx) +- [frontend/antd/input-number/input-number.tsx](file://frontend/antd/input-number/input-number.tsx) +- [frontend/antd/select/select.tsx](file://frontend/antd/select/select.tsx) +- [frontend/antd/select/option/select.option.tsx](file://frontend/antd/select/option/select.option.tsx) +- [frontend/antd/transfer/transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [frontend/antd/tree-select/tree-select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [frontend/antd/upload/upload.tsx](file://frontend/antd/upload/upload.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Large Data Optimization](#performance-and-large-data-optimization) +8. [Accessibility and Keyboard Navigation](#accessibility-and-keyboard-navigation) +9. [Complex Form Design Patterns and Data Flow](#complex-form-design-patterns-and-data-flow) +10. [Troubleshooting Guide](#troubleshooting-guide) +11. [Conclusion](#conclusion) + +## Introduction + +This document is intended for scenarios where Ant Design components are used for data entry in the frontend. It systematically covers the wrapping and usage of AutoComplete, Cascader, Checkbox, ColorPicker, DatePicker, Form, Input, InputNumber, Mentions, Radio, Rate, Select, Slider, Switch, TimePicker, Transfer, TreeSelect, Upload, and other components. Key areas covered include: + +- Data binding: how to implement controlled/uncontrolled two-way binding via onValueChange +- Validation rules: combining Form.Item with FormItem.Rule +- Formatting options: internal format conversion and unified external output for date/time components +- Complex form design patterns: multi-step, linked fields, dynamic fields, conditional rendering +- Accessibility and keyboard navigation: semantic labels, focus management, keyboard navigation +- Performance optimization: virtual scrolling, lazy loading, debounce/throttle, batch updates + +## Project Structure + +This project uses a dual-layer architecture of "backend component export + frontend Svelte/React wrapping": + +- The backend layer exports Ant Design components as Python classes, enabling unified invocation and documentation generation within the Python ecosystem +- The frontend layer is based on Svelte/React wrapping, providing slot injection, context injection, function hooks, value change bridging, and other capabilities to achieve a consistent API experience with the backend + +```mermaid +graph TB +subgraph "Backend" +A["backend/modelscope_studio/components/antd/__init__.py
Exports Antd* component aliases"] +end +subgraph "Frontend" +B["frontend/antd/*/*.tsx
Component wrappers: sveltify + hooks"] +C["frontend/antd/form/*
Form/FormItem/Rule/Provider"] +D["utils/*
hooks/renderItems/renderParamsSlot etc."] +end +A --> B +B --> D +C --> B +``` + +Diagram Source + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [frontend/antd/auto-complete/auto-complete.tsx:1-151](file://frontend/antd/auto-complete/auto-complete.tsx#L1-L151) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/form/item/form.item.tsx](file://frontend/antd/form/item/form.item.tsx) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) +- [frontend/antd/form/provider/form.provider.tsx](file://frontend/antd/form/provider/form.provider.tsx) + +Section Source + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) + +## Core Components + +This section gives an overview of the components covered in this document and their responsibilities: + +- Form system: Form, FormItem, FormItem.Rule, FormProvider +- Input types: Input, Input.TextArea, Input.Search, Input.Password, Input.OTP, InputNumber +- Selection types: Select, Select.Option, Cascader, TreeSelect, Transfer +- Date/time types: DatePicker, TimePicker +- Slider and rating: Slider, Rate +- Toggle and selection: Switch, Radio, Checkbox +- Color: ColorPicker +- Mentions: Mentions (supports keyword mentions and dynamic rendering of options, including the Option sub-component) + +Section Source + +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/form/item/form.item.tsx](file://frontend/antd/form/item/form.item.tsx) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) +- [frontend/antd/form/provider/form.provider.tsx](file://frontend/antd/form/provider/form.provider.tsx) +- [frontend/antd/input/input.tsx](file://frontend/antd/input/input.tsx) +- [frontend/antd/input/otp/input.otp.tsx](file://frontend/antd/input/otp/input.otp.tsx) +- [frontend/antd/input/password/input.password.tsx](file://frontend/antd/input/password/input.password.tsx) +- [frontend/antd/input/search/input.search.tsx](file://frontend/antd/input/search/input.search.tsx) +- [frontend/antd/input/textarea/input.textarea.tsx](file://frontend/antd/input/textarea/input.textarea.tsx) +- [frontend/antd/input-number/input-number.tsx](file://frontend/antd/input-number/input-number.tsx) +- [frontend/antd/select/select.tsx](file://frontend/antd/select/select.tsx) +- [frontend/antd/select/option/select.option.tsx](file://frontend/antd/select/option/select.option.tsx) +- [frontend/antd/cascader/cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [frontend/antd/tree-select/tree-select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [frontend/antd/transfer/transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [frontend/antd/date-picker/date-picker.tsx](file://frontend/antd/date-picker/date-picker.tsx) +- [frontend/antd/time-picker/time-picker.tsx](file://frontend/antd/time-picker/time-picker.tsx) +- [frontend/antd/slider/slider.tsx](file://frontend/antd/slider/slider.tsx) +- [frontend/antd/rate/rate.tsx](file://frontend/antd/rate/rate.tsx) +- [frontend/antd/switch/switch.tsx](file://frontend/antd/switch/switch.tsx) +- [frontend/antd/radio/radio.tsx](file://frontend/antd/radio/radio.tsx) +- [frontend/antd/checkbox/checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [frontend/antd/color-picker/color-picker.tsx](file://frontend/antd/color-picker/color-picker.tsx) + +## Architecture Overview + +Frontend components universally use sveltify to wrap Ant Design native components, and complete the following via hooks: + +- Value change bridging: useValueChange bridges onChange and onValueChange to ensure the external side consistently receives value +- Function parameterization: useFunction wraps incoming functions as stable references to avoid closure traps +- Slot rendering: renderItems/renderParamsSlot support flexible combinations of children and slots +- Context injection: withItemsContextProvider injects items into child components (such as Option/Marks/Preset) + +```mermaid +sequenceDiagram +participant U as "User" +participant C as "Wrapped Component (e.g. AutoComplete)" +participant R as "React/antd Component" +participant H as "hooks(onValueChange/useFunction)" +participant P as "Parent Component (Form/Page)" +U->>C : Trigger interaction +C->>R : Call native component event +R-->>C : Callback value +C->>H : onValueChange(value) +H-->>C : Update internal state +C-->>P : onValueChange(value) +Note over C,P : Parent component can combine Form/FormItem for validation and linked fields +``` + +Diagram Source + +- [frontend/antd/auto-complete/auto-complete.tsx:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) +- [frontend/antd/cascader/cascader.tsx:39-204](file://frontend/antd/cascader/cascader.tsx#L39-L204) +- [frontend/antd/checkbox/checkbox.tsx:4-19](file://frontend/antd/checkbox/checkbox.tsx#L4-L19) +- [frontend/antd/color-picker/color-picker.tsx:24-103](file://frontend/antd/color-picker/color-picker.tsx#L24-L103) +- [frontend/antd/date-picker/date-picker.tsx:40-231](file://frontend/antd/date-picker/date-picker.tsx#L40-L231) +- [frontend/antd/radio/radio.tsx:6-29](file://frontend/antd/radio/radio.tsx#L6-L29) +- [frontend/antd/rate/rate.tsx:12-42](file://frontend/antd/rate/rate.tsx#L12-L42) +- [frontend/antd/slider/slider.tsx:37-94](file://frontend/antd/slider/slider.tsx#L37-L94) +- [frontend/antd/switch/switch.tsx:6-39](file://frontend/antd/switch/switch.tsx#L6-L39) +- [frontend/antd/time-picker/time-picker.tsx:37-198](file://frontend/antd/time-picker/time-picker.tsx#L37-L198) + +## Component Details + +### AutoComplete + +- Data binding: receives string value via onValueChange; onChange passes through native callback +- Slots: supports children, dropdownRender, popupRender, notFoundContent, allowClear.clearIcon +- Options: supports rendering via options or slots.children +- Filtering: filterOption can customize filter logic or use default behavior + +```mermaid +flowchart TD +Start(["Start"]) --> Bind["Bind onValueChange"] +Bind --> Render["Render options/slots"] +Render --> UserInput["User input"] +UserInput --> Filter{"Custom filter?"} +Filter -- Yes --> UseFn["Use filterOption function"] +Filter -- No --> Default["Default filtering"] +UseFn --> Change["Trigger onChange and update value"] +Default --> Change +Change --> End(["End"]) +``` + +Diagram Source + +- [frontend/antd/auto-complete/auto-complete.tsx:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) + +Section Source + +- [frontend/antd/auto-complete/auto-complete.tsx:1-151](file://frontend/antd/auto-complete/auto-complete.tsx#L1-L151) + +### Cascader + +- Data binding: onValueChange receives an array (path value); onChange passes through +- Slots: suffixIcon, prefix, removeIcon, expandIcon, displayRender, tagRender, dropdownRender, popupRender, showSearch.render, maxTagPlaceholder +- Search: showSearch supports object configuration and slot rendering +- Dynamic loading: onLoadData corresponds to native loadData + +```mermaid +sequenceDiagram +participant U as "User" +participant C as "Cascader" +participant R as "Antd Cascader" +U->>C : Expand/select node +C->>R : Render panel/search +R-->>C : Return selected value +C-->>U : onValueChange(path array) +``` + +Diagram Source + +- [frontend/antd/cascader/cascader.tsx:19-204](file://frontend/antd/cascader/cascader.tsx#L19-L204) + +Section Source + +- [frontend/antd/cascader/cascader.tsx:1-207](file://frontend/antd/cascader/cascader.tsx#L1-L207) + +### Checkbox + +- Data binding: onValueChange receives a boolean value +- Events: onChange passes through native event + +Section Source + +- [frontend/antd/checkbox/checkbox.tsx:1-22](file://frontend/antd/checkbox/checkbox.tsx#L1-L22) + +### ColorPicker + +- Data binding: onValueChange receives a string or gradient color array; value_format controls the output format (rgb/hex/hsb) +- Slots: panelRender, showText +- Gradient: when isGradient(), outputs each color segment according to value_format + +Section Source + +- [frontend/antd/color-picker/color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) + +### DatePicker + +- Data binding: onValueChange receives a second-level timestamp (including array scenario); onChange/onPanelChange passes through +- Internal format: unified dayjs conversion, external output as second-level timestamp +- Slots: renderExtraFooter, cellRender, panelRender, prevIcon/prefix/nextIcon/suffixIcon/superNextIcon/superPrevIcon, allowClear.clearIcon +- Presets: presets are rendered via renderItems + +```mermaid +flowchart TD +In(["Input date"]) --> Parse["dayjs parse"] +Parse --> Normalize["Normalize to second-level timestamp"] +Normalize --> Emit["onValueChange/onChange"] +Emit --> Out(["Output to parent component"]) +``` + +Diagram Source + +- [frontend/antd/date-picker/date-picker.tsx:14-38](file://frontend/antd/date-picker/date-picker.tsx#L14-L38) +- [frontend/antd/date-picker/date-picker.tsx:126-170](file://frontend/antd/date-picker/date-picker.tsx#L126-L170) + +Section Source + +- [frontend/antd/date-picker/date-picker.tsx:1-234](file://frontend/antd/date-picker/date-picker.tsx#L1-L234) + +### Form / FormItem / FormItem.Rule / FormProvider + +- Form: container that provides Provider injection and layout capability +- FormItem: field container holding label, help, required, validateStatus, etc. +- FormItem.Rule: validation rules supporting required, regex, custom functions, async validation +- FormProvider: global configuration and context + +```mermaid +classDiagram +class Form { ++provider() ++submit() ++resetFields() +} +class FormItem { ++label ++help ++required ++validateStatus +} +class FormItemRule { ++rules ++trigger +} +class FormProvider { ++config +} +Form --> FormItem : "contains" +FormItem --> FormItemRule : "uses" +Form --> FormProvider : "injects" +``` + +Diagram Source + +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/form/item/form.item.tsx](file://frontend/antd/form/item/form.item.tsx) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) +- [frontend/antd/form/provider/form.provider.tsx](file://frontend/antd/form/provider/form.provider.tsx) + +Section Source + +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/form/item/form.item.tsx](file://frontend/antd/form/item/form.item.tsx) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) +- [frontend/antd/form/provider/form.provider.tsx](file://frontend/antd/form/provider/form.provider.tsx) + +### Input / TextArea / Search / Password / OTP + +- Unified pattern: all receive the latest value via onValueChange; onChange passes through native event +- Extensions: Search, Password, OTP each provide specific behavior and styles + +Section Source + +- [frontend/antd/input/input.tsx](file://frontend/antd/input/input.tsx) +- [frontend/antd/input/otp/input.otp.tsx](file://frontend/antd/input/otp/input.otp.tsx) +- [frontend/antd/input/password/input.password.tsx](file://frontend/antd/input/password/input.password.tsx) +- [frontend/antd/input/search/input.search.tsx](file://frontend/antd/input/search/input.search.tsx) +- [frontend/antd/input/textarea/input.textarea.tsx](file://frontend/antd/input/textarea/input.textarea.tsx) + +### InputNumber + +- Data binding: onValueChange receives a numeric value; onChange passes through +- Use cases: step control, range, precision control + +Section Source + +- [frontend/antd/input-number/input-number.tsx](file://frontend/antd/input-number/input-number.tsx) + +### Select / Option + +- Data binding: onValueChange receives string/number/array; onChange passes through +- Sub-items: Option is injected via renderItems, supporting disabled, grouping, etc. + +Section Source + +- [frontend/antd/select/select.tsx](file://frontend/antd/select/select.tsx) +- [frontend/antd/select/option/select.option.tsx](file://frontend/antd/select/option/select.option.tsx) + +### Slider / Marks + +- Data binding: onValueChange receives number or number[]; onChange passes through +- Marks: rendered via slots.children or slots.label + +Section Source + +- [frontend/antd/slider/slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) + +### Radio + +- Data binding: onValueChange receives a boolean value; onChange passes through +- Theme: style variables injected via token.lineWidth + +Section Source + +- [frontend/antd/radio/radio.tsx:1-32](file://frontend/antd/radio/radio.tsx#L1-L32) + +### Rate + +- Data binding: onValueChange receives a numeric value; onChange passes through +- Slots: character supports custom rating icons + +Section Source + +- [frontend/antd/rate/rate.tsx:1-45](file://frontend/antd/rate/rate.tsx#L1-L45) + +### Switch + +- Data binding: onValueChange receives a boolean value; onChange passes through +- Slots: checkedChildren, unCheckedChildren + +Section Source + +- [frontend/antd/switch/switch.tsx:1-42](file://frontend/antd/switch/switch.tsx#L1-L42) + +### TimePicker + +- Data binding: onValueChange receives a second-level timestamp; onChange/onPanelChange/onCalendarChange passes through +- Internal format: unified dayjs conversion + +Section Source + +- [frontend/antd/time-picker/time-picker.tsx:1-201](file://frontend/antd/time-picker/time-picker.tsx#L1-L201) + +### Transfer + +- Data binding: onValueChange receives target list key values; onChange passes through +- Use cases: multi-select move, sorting, search + +Section Source + +- [frontend/antd/transfer/transfer.tsx](file://frontend/antd/transfer/transfer.tsx) + +### TreeSelect + +- Data binding: onValueChange receives string/array; onChange passes through +- Sub-items: TreeNode is injected via renderItems + +Section Source + +- [frontend/antd/tree-select/tree-select.tsx](file://frontend/antd/tree-select/tree-select.tsx) + +### Upload + +- Data binding: onValueChange receives a file list; onChange passes through +- Use cases: drag and drop, preview, size/type restrictions + +Section Source + +- [frontend/antd/upload/upload.tsx](file://frontend/antd/upload/upload.tsx) + +## Dependency Analysis + +- Inter-component coupling: most components are decoupled through hooks and utility functions, reducing coupling to specific implementations +- Slots and context: withItemsContextProvider and renderItems allow child components to be uniformly injected and rendered +- Event bridging: useValueChange aligns onChange with onValueChange, ensuring parent components subscribe consistently + +```mermaid +graph LR +Utils["utils/*
hooks/renderItems/renderParamsSlot"] --> Auto["AutoComplete"] +Utils --> Cascader +Utils --> ColorPicker +Utils --> DatePicker +Utils --> Slider +Utils --> TimePicker +Form["Form/FormItem/Rule/Provider"] --> Auto +Form --> Cascader +Form --> DatePicker +Form --> TimePicker +``` + +Diagram Source + +- [frontend/antd/auto-complete/auto-complete.tsx:1-151](file://frontend/antd/auto-complete/auto-complete.tsx#L1-L151) +- [frontend/antd/cascader/cascader.tsx:1-207](file://frontend/antd/cascader/cascader.tsx#L1-L207) +- [frontend/antd/color-picker/color-picker.tsx:1-106](file://frontend/antd/color-picker/color-picker.tsx#L1-L106) +- [frontend/antd/date-picker/date-picker.tsx:1-234](file://frontend/antd/date-picker/date-picker.tsx#L1-L234) +- [frontend/antd/slider/slider.tsx:1-97](file://frontend/antd/slider/slider.tsx#L1-L97) +- [frontend/antd/time-picker/time-picker.tsx:1-201](file://frontend/antd/time-picker/time-picker.tsx#L1-L201) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/form/item/form.item.tsx](file://frontend/antd/form/item/form.item.tsx) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) +- [frontend/antd/form/provider/form.provider.tsx](file://frontend/antd/form/provider/form.provider.tsx) + +## Performance and Large Data Optimization + +- List rendering + - Use virtual scrolling: in Select/Cascader/TreeSelect, prioritize virtualization solutions to reduce the number of DOM nodes + - Lazy loading: Cascader's onLoadData only requests data when expanded, avoiding loading everything at once +- Input performance + - Debounce/throttle: add debounce to AutoComplete's filterOption or search-type inputs + - Batch updates: use batch submission in Form to reduce re-render counts +- Date and time + - Use dayjs internally, output second-level timestamps externally to avoid repeated parsing + - Render presets and panels with memoization to reduce unnecessary recalculations +- Graphics and colors + - ColorPicker computes output in gradient scenarios according to value_format, avoiding repeated formatting + +## Accessibility and Keyboard Navigation + +- Semantic labels: Radio/Checkbox/Switch, etc. provide clear aria attributes and label associations +- Keyboard navigation: DatePicker/TimePicker/Select/Slider support standard operations such as Tab/Enter/arrow keys +- Focus management: getPopupContainer mounts the overlay inside a container to avoid focus loss +- Screen readers: FormItem provides help/status text to assist in describing errors and prompt information + +## Complex Form Design Patterns and Data Flow + +- Multi-step forms: use FormProvider global configuration combined with onPanelChange and linked fields +- Conditional rendering: dynamically show/hide sections based on field values, combined with FormItem's required and Rule +- Dynamic fields: inject Option/TreeNode/Mark via renderItems to implement dynamic add/edit/delete +- Linked fields and computation: trigger side effects in onValueChange (such as calculating total price, filling in address), and update other fields via Form.setFieldsValue + +```mermaid +sequenceDiagram +participant F as "Form" +participant I1 as "FormItem A" +participant I2 as "FormItem B" +F->>I1 : User input +I1-->>F : onValueChange(newValueA) +F->>I2 : setFieldsValue(linked field) +I2-->>F : onValueChange(newValueB) +F-->>F : Validate and submit +``` + +Diagram Source + +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/antd/form/item/form.item.tsx](file://frontend/antd/form/item/form.item.tsx) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) + +## Troubleshooting Guide + +- Event not triggered + - Check whether onValueChange is passed in correctly; confirm whether onChange has been overridden +- Value not updating + - In controlled mode, confirm whether the parent component calls setState in time; check the dependencies of useValueChange +- Slot not working + - Confirm whether slots.key is consistent with the component's contract; check renderParamsSlot's key +- Validation not working + - Check FormItem.Rule's trigger and rules configuration; confirm the timing of Form.validateFields call +- Date anomaly + - Confirm that the input is a second-level timestamp; check the dayjs conversion chain and defaultValue/defaultPickerValue + +Section Source + +- [frontend/antd/auto-complete/auto-complete.tsx:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) +- [frontend/antd/date-picker/date-picker.tsx:126-170](file://frontend/antd/date-picker/date-picker.tsx#L126-L170) +- [frontend/antd/time-picker/time-picker.tsx:109-143](file://frontend/antd/time-picker/time-picker.tsx#L109-L143) +- [frontend/antd/form/item/rule/form.item.rule.tsx](file://frontend/antd/form/item/rule/form.item.rule.tsx) + +## Conclusion + +This project achieves high consistency and strong extensibility for Ant Design components on the frontend through unified wrapping patterns and hooks utilities. With a clear practical path centered on data binding, validation rules, formatting options, and complex form design, it is recommended to combine virtual scrolling, lazy loading, and debounce strategies in actual business scenarios to continuously optimize performance, while improving accessibility and keyboard navigation to enhance the user experience. diff --git a/.wiki/en/Ant Design Components/Data Entry Components/DateTime Components.md b/.wiki/en/Ant Design Components/Data Entry Components/DateTime Components.md new file mode 100644 index 00000000..e599c10b --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Entry Components/DateTime Components.md @@ -0,0 +1,463 @@ +# DateTime Components + + +**Files referenced in this document** +- [frontend/antd/date-picker/date-picker.tsx](file://frontend/antd/date-picker/date-picker.tsx) +- [frontend/antd/date-picker/context.ts](file://frontend/antd/date-picker/context.ts) +- [frontend/antd/date-picker/preset/date-picker.preset.tsx](file://frontend/antd/date-picker/preset/date-picker.preset.tsx) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx) +- [frontend/antd/time-picker/time-picker.tsx](file://frontend/antd/time-picker/time-picker.tsx) +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx) +- [frontend/antd/calendar/calendar.tsx](file://frontend/antd/calendar/calendar.tsx) +- [frontend/antd/statistic/statistic.tsx](file://frontend/antd/statistic/statistic.tsx) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx](file://frontend/antd/statistic/countdown/statistic.countdown.tsx) +- [frontend/antd/statistic/timer/statistic.timer.tsx](file://frontend/antd/statistic/timer/statistic.timer.tsx) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically covers the "date and time" related components and capabilities in the ModelScope Studio frontend, including: + +- DatePicker and DateRangePicker +- TimePicker and TimeRangePicker +- Calendar +- Countdown and Timer within Statistic +- Date formatting, timezone and time unit conversion, range selection, quick options (presets), and disabled date/time +- Localization (ConfigProvider) and internationalization configuration (locales) +- Validation rules and business scenario applications +- Accessibility and keyboard navigation +- Handling patterns and best practices for complex date/time scenarios + +## Project Structure + +The frontend implementation around date/time components is primarily located in the antd-prefixed directory, using Svelte + React wrapping (sveltify) to bridge Ant Design components, with ConfigProvider providing unified theming and internationalization. + +```mermaid +graph TB +subgraph "Date/Time Components" +DP["DatePicker"] +DRP["DateRangePicker"] +TP["TimePicker"] +TRP["TimeRangePicker"] +CAL["Calendar"] +STAT["Statistic"] +CD["Statistic.Countdown"] +TM["Statistic.Timer"] +end +subgraph "Bridge Layer" +Sveltify["sveltify Wrapper"] +Slots["Slot Rendering
renderParamsSlot/ReactSlot"] +Hooks["Utility Hooks
useFunction/useMemo"] +end +subgraph "Internationalization and Theming" +CP["ConfigProvider
Theme/Popup Container/Empty State"] +LOCALES["locales.ts
Multilingual Mapping and On-demand Loading"] +end +DP --> Sveltify +DRP --> Sveltify +TP --> Sveltify +TRP --> Sveltify +CAL --> Sveltify +STAT --> Sveltify +CD --> Sveltify +TM --> Sveltify +Sveltify --> Slots +Sveltify --> Hooks +CP --> LOCALES +CP --> Sveltify +``` + +Diagram Source + +- [frontend/antd/date-picker/date-picker.tsx:40-231](file://frontend/antd/date-picker/date-picker.tsx#L40-L231) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:29-245](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L29-L245) +- [frontend/antd/time-picker/time-picker.tsx:37-198](file://frontend/antd/time-picker/time-picker.tsx#L37-L198) +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx:26-207](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx#L26-L207) +- [frontend/antd/calendar/calendar.tsx:17-99](file://frontend/antd/calendar/calendar.tsx#L17-L99) +- [frontend/antd/statistic/statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:6-24](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L6-L24) +- [frontend/antd/statistic/timer/statistic.timer.tsx:10-26](file://frontend/antd/statistic/timer/statistic.timer.tsx#L10-L26) +- [frontend/antd/config-provider/config-provider.tsx:53-151](file://frontend/antd/config-provider/config-provider.tsx#L53-L151) +- [frontend/antd/config-provider/locales.ts:89-863](file://frontend/antd/config-provider/locales.ts#L89-L863) + +Section Source + +- [frontend/antd/date-picker/date-picker.tsx:1-234](file://frontend/antd/date-picker/date-picker.tsx#L1-L234) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:1-248](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L1-L248) +- [frontend/antd/time-picker/time-picker.tsx:1-201](file://frontend/antd/time-picker/time-picker.tsx#L1-L201) +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx:1-211](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx#L1-L211) +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/statistic/statistic.tsx:1-34](file://frontend/antd/statistic/statistic.tsx#L1-L34) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:1-27](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L1-L27) +- [frontend/antd/statistic/timer/statistic.timer.tsx:1-29](file://frontend/antd/statistic/timer/statistic.timer.tsx#L1-L29) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) + +## Core Components + +- DatePicker: supports date and time selection, range selection, preset shortcuts, disabled date/time, panel switch callbacks, custom popup containers, etc. +- TimePicker: supports time selection, range selection, disabled time, panel switching, and calendar linked callbacks. +- Calendar: provides a full month view, supports custom cell rendering, header rendering, and valid range restriction. +- Statistic: basic statistic display; both Countdown and Timer accept values in seconds and internally auto-convert to milliseconds to pass to the underlying component. + +Section Source + +- [frontend/antd/date-picker/date-picker.tsx:40-170](file://frontend/antd/date-picker/date-picker.tsx#L40-L170) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:29-177](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L29-L177) +- [frontend/antd/time-picker/time-picker.tsx:37-143](file://frontend/antd/time-picker/time-picker.tsx#L37-L143) +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx:26-146](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx#L26-L146) +- [frontend/antd/calendar/calendar.tsx:17-94](file://frontend/antd/calendar/calendar.tsx#L17-L94) +- [frontend/antd/statistic/statistic.tsx:8-31](file://frontend/antd/statistic/statistic.tsx#L8-L31) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:6-21](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L6-L21) +- [frontend/antd/statistic/timer/statistic.timer.tsx:10-23](file://frontend/antd/statistic/timer/statistic.timer.tsx#L10-L23) + +## Architecture Overview + +Components are uniformly wrapped through sveltify around Ant Design components, using dayjs for date parsing and formatting. They expose a unified second-level timestamp interface externally, then internally convert to milliseconds to pass to the underlying component. ConfigProvider handles theme algorithms, popup containers, empty state rendering, and internationalization (Antd language packs and dayjs language packs). + +```mermaid +sequenceDiagram +participant U as "User" +participant C as "Component (e.g. DatePicker)" +participant F as "Formatting function (formatDayjs/formatDate)" +participant D as "dayjs" +participant A as "Antd Component" +U->>C : Select date/time +C->>F : Input value (may be seconds/milliseconds/string) +F->>D : Parse to dayjs object +D-->>F : dayjs instance +F-->>C : Format to second-level timestamp +C->>A : Pass millisecond value and callback parameters +A-->>C : Callback triggered (onChange/onPanelChange) +C-->>U : Trigger onValueChange/onChange (second-level timestamp) +``` + +Diagram Source + +- [frontend/antd/date-picker/date-picker.tsx:14-38](file://frontend/antd/date-picker/date-picker.tsx#L14-L38) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:14-27](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L14-L27) +- [frontend/antd/time-picker/time-picker.tsx:11-35](file://frontend/antd/time-picker/time-picker.tsx#L11-L35) +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx:11-24](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx#L11-L24) + +## Detailed Component Analysis + +### DatePicker + +- Data flow and formatting + - Input supports number (seconds), string, dayjs objects; internally unified to dayjs. + - Output is uniformly a second-level timestamp for easy backend or cross-component passing. +- Key capabilities + - showTime supports object form, and defaultValue will also be formatted. + - disabledDate/disabledTime customize disabled logic. + - presets shortcuts: injected via context, supports dynamic rendering and formatting. + - cellRender/panelRender slot-based rendering. + - getPopupContainer customizes popup container. +- Event callbacks + - onValueChange: unified value change callback (second-level). + - onChange/onPanelChange: both native callback and secondary wrapped callback are available. + +```mermaid +flowchart TD +Start(["Start"]) --> Parse["Parse input to dayjs"] +Parse --> ShowTime{"Time enabled?"} +ShowTime --> |Yes| FormatST["Format default time"] +ShowTime --> |No| SkipST["Skip default time"] +FormatST --> Presets["Merge/format preset items"] +SkipST --> Presets +Presets --> Render["Render component and bind callbacks"] +Render --> End(["End"]) +``` + +Diagram Source + +- [frontend/antd/date-picker/date-picker.tsx:91-161](file://frontend/antd/date-picker/date-picker.tsx#L91-L161) + +Section Source + +- [frontend/antd/date-picker/date-picker.tsx:1-234](file://frontend/antd/date-picker/date-picker.tsx#L1-L234) +- [frontend/antd/date-picker/context.ts:1-7](file://frontend/antd/date-picker/context.ts#L1-L7) +- [frontend/antd/date-picker/preset/date-picker.preset.tsx:1-14](file://frontend/antd/date-picker/preset/date-picker.preset.tsx#L1-L14) + +### DateRangePicker + +- Data flow + - Input/output are both two-element arrays [start, end], with elements as second-level timestamps. + - Default value, current value, and panel value are all formatted and mapped as arrays using dayjs. +- Key capabilities + - showTime's defaultValue supports array mapping. + - presets also support array formatting. + - separator supports slot-based separator. +- Event callbacks + - onValueChange, onChange, onPanelChange, onCalendarChange all return second-level arrays. + +```mermaid +sequenceDiagram +participant U as "User" +participant RP as "DateRangePicker" +participant F as "formatDates" +participant A as "Antd.RangePicker" +U->>RP : Select start and end dates +RP->>F : Input [start, end] (may be dayjs/seconds) +F-->>RP : Return [start, end] (seconds) +RP->>A : Pass millisecond values and callbacks +A-->>RP : Callback triggered +RP-->>U : onValueChange/onChange (second-level array) +``` + +Diagram Source + +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:21-27](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L21-L27) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:165-177](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L165-L177) + +Section Source + +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:1-248](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L1-L248) + +### TimePicker + +- Data flow + - Input supports number (seconds), string, dayjs; uniformly formatted to dayjs. + - Output is a second-level value (number or string), ensuring consistency via onValueChange. +- Key capabilities + - disabledTime/disabledDate controls available time slots. + - cellRender/panelRender supports slots. + - onCalendarChange and onPanelChange. +- Event callbacks + - onValueChange receives second-level values; onChange/onPanelChange are also formatted before callback. + +```mermaid +flowchart TD +S(["Start"]) --> V["Validate/format input to dayjs"] +V --> DT{"Disabled time?"} +DT --> |Yes| Block["Block selection"] +DT --> |No| RenderT["Render TimePicker"] +RenderT --> Evt["Trigger onChange/onPanelChange/onCalendarChange"] +Evt --> Out["Format to seconds and callback onValueChange"] +Out --> End(["End"]) +``` + +Diagram Source + +- [frontend/antd/time-picker/time-picker.tsx:88-143](file://frontend/antd/time-picker/time-picker.tsx#L88-L143) + +Section Source + +- [frontend/antd/time-picker/time-picker.tsx:1-201](file://frontend/antd/time-picker/time-picker.tsx#L1-L201) + +### TimeRangePicker + +- Data flow + - Input/output are [start, end] arrays with elements as second-level timestamps. + - Default value, current value, and panel value are all formatted as array mappings. +- Key capabilities + - disabledTime/disabledDate controls available time slots. + - separator supports slot-based separator. +- Event callbacks + - onValueChange, onChange, onPanelChange, onCalendarChange all return second-level arrays. + +Section Source + +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx:1-211](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx#L1-L211) + +### Calendar + +- Data flow + - Input/output are uniformly second-level timestamps; internally converted to milliseconds for Antd Calendar. +- Key capabilities + - validRange restricts the valid range. + - cellRender/fullCellRender/headerRender support slots. + - onSelect/onPanelChange/onChange uniformly callback second-level values. +- Note + - disabledDate is not directly exposed; it can be controlled by passing values from external logic. + +Section Source + +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) + +### Statistic / Countdown / Timer + +- Statistic + - Supports slot-based title/prefix/suffix/formatter. +- Statistic.Countdown + - Input value supports seconds or milliseconds; internally converts seconds to milliseconds. + - Supports slot-based title/prefix/suffix. +- Statistic.Timer + - Input value supports seconds or milliseconds; internally converts seconds to milliseconds. + - Supports slot-based title/prefix/suffix. + +```mermaid +sequenceDiagram +participant U as "User" +participant CD as "Countdown" +participant TM as "Timer" +participant A as "Antd.Statistic" +U->>CD : Set target time (seconds) +CD->>CD : Convert seconds to milliseconds +CD->>A : Render countdown +A-->>U : Display remaining time +U->>TM : Set initial value (seconds) +TM->>TM : Convert seconds to milliseconds +TM->>A : Render timer +A-->>U : Display elapsed time +``` + +Diagram Source + +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:11-21](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L11-L21) +- [frontend/antd/statistic/timer/statistic.timer.tsx:13-23](file://frontend/antd/statistic/timer/statistic.timer.tsx#L13-L23) + +Section Source + +- [frontend/antd/statistic/statistic.tsx:1-34](file://frontend/antd/statistic/statistic.tsx#L1-L34) +- [frontend/antd/statistic/countdown/statistic.countdown.tsx:1-27](file://frontend/antd/statistic/countdown/statistic.countdown.tsx#L1-L27) +- [frontend/antd/statistic/timer/statistic.timer.tsx:1-29](file://frontend/antd/statistic/timer/statistic.timer.tsx#L1-L29) + +## Dependency Analysis + +- Components to utilities + - Uses dayjs for date parsing and formatting. + - Uses useFunction/useMemo to stabilize callbacks and computations. + - Uses renderParamsSlot/ReactSlot for slot-based rendering. +- Components to context + - DatePicker presets are injected and consumed via createItemsContext. +- Internationalization and theming + - ConfigProvider is responsible for: + - Theme algorithms (dark/compact). + - Popup containers and target container functions. + - Empty state rendering. + - Internationalization: Antd language packs and dayjs language packs loaded on demand. + - locales.ts provides mapping from language codes to language packs with async loading. + +```mermaid +graph LR +DP["DatePicker"] --> Dayjs["dayjs"] +DRP["DateRangePicker"] --> Dayjs +TP["TimePicker"] --> Dayjs +TRP["TimeRangePicker"] --> Dayjs +CAL["Calendar"] --> Dayjs +DP --> Hooks["useFunction/useMemo"] +DRP --> Hooks +TP --> Hooks +TRP --> Hooks +CAL --> Hooks +DP --> Slots["renderParamsSlot/ReactSlot"] +DRP --> Slots +TP --> Slots +TRP --> Slots +CAL --> Slots +CP["ConfigProvider"] --> LOCALES["locales.ts"] +CP --> Theme["Theme Algorithm/Container/Empty State"] +``` + +Diagram Source + +- [frontend/antd/date-picker/date-picker.tsx:1-11](file://frontend/antd/date-picker/date-picker.tsx#L1-L11) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:1-7](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L1-L7) +- [frontend/antd/time-picker/time-picker.tsx:1-6](file://frontend/antd/time-picker/time-picker.tsx#L1-L6) +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx:1-6](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx#L1-L6) +- [frontend/antd/calendar/calendar.tsx:1-6](file://frontend/antd/calendar/calendar.tsx#L1-L6) +- [frontend/antd/config-provider/config-provider.tsx:1-11](file://frontend/antd/config-provider/config-provider.tsx#L1-L11) +- [frontend/antd/config-provider/locales.ts:1-10](file://frontend/antd/config-provider/locales.ts#L1-L10) + +Section Source + +- [frontend/antd/date-picker/date-picker.tsx:1-234](file://frontend/antd/date-picker/date-picker.tsx#L1-L234) +- [frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx:1-248](file://frontend/antd/date-picker/range-picker/date-picker.range-picker.tsx#L1-L248) +- [frontend/antd/time-picker/time-picker.tsx:1-201](file://frontend/antd/time-picker/time-picker.tsx#L1-L201) +- [frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx:1-211](file://frontend/antd/time-picker/range-picker/time-picker.range-picker.tsx#L1-L211) +- [frontend/antd/calendar/calendar.tsx:1-102](file://frontend/antd/calendar/calendar.tsx#L1-L102) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) + +## Performance Considerations + +- Formatting and caching + - Use useMemo to cache formatted dayjs values to avoid repeated computation. + - useFunction stabilizes callback references to reduce unnecessary re-renders. +- On-demand loading + - ConfigProvider async-loads Antd and dayjs language resources when locale changes, reducing initial bundle size. +- Rendering optimization + - Slot-based rendering only mounts when needed, reducing irrelevant node overhead. +- Recommendations + - For wide range selection or frequent updates, apply throttle/debounce at the parent level as much as possible. + - When there are many preset items, consider lazy loading and virtualized rendering. + +## Troubleshooting Guide + +- Date not displayed or displayed incorrectly + - Check whether the input is a second-level timestamp; the component internally converts it to milliseconds. + - Confirm that the dayjs language has been correctly set (ConfigProvider sets it automatically). +- Internationalization not taking effect + - Confirm that the locale parameter format conforms to the specification (e.g., zh_CN, en_US); locales.ts contains the corresponding mapping. + - If the language pack fails to load, check network and build configuration. +- Preset items not displayed + - Confirm that preset items have been injected via context, and ensure the value format is dayjs. +- Disabled logic not working + - disabledDate/disabledTime should be functions; ensure stable references by wrapping with useFunction. +- Callback not triggered + - Confirm that using onValueChange and onChange simultaneously does not cause state inconsistency. + - Check whether getPopupContainer correctly returns the container. + +Section Source + +- [frontend/antd/config-provider/config-provider.tsx:96-105](file://frontend/antd/config-provider/config-provider.tsx#L96-L105) +- [frontend/antd/date-picker/date-picker.tsx:86-90](file://frontend/antd/date-picker/date-picker.tsx#L86-L90) +- [frontend/antd/time-picker/time-picker.tsx:83-87](file://frontend/antd/time-picker/time-picker.tsx#L83-L87) + +## Conclusion + +This date/time component system is built on Ant Design and provides complete capabilities from dates and times to calendar, countdown, and timer through a unified formatting and slot-based mechanism. With ConfigProvider's theming and internationalization support, it can meet complex business requirements in multi-language and multi-theme scenarios. It is recommended to follow the "unified second-level timestamp" data contract in actual use, combined with useMemo/useFunction for performance optimization, and extend UI expressiveness through slot-based customization. + +## Appendix + +### Localization and Internationalization Configuration + +- ConfigProvider + - Supports themeMode to switch dark/compact algorithms. + - Supports getPopupContainer/getTargetContainer to customize containers. + - Supports renderEmpty for custom empty state. + - The locale parameter supports language codes; locales.ts provides mapping and async loading. +- locales.ts + - Provides 80+ language code mappings with on-demand loading of Antd and dayjs language packs. + - Default language is en_US; dayjs default language is en. + +Section Source + +- [frontend/antd/config-provider/config-provider.tsx:53-151](file://frontend/antd/config-provider/config-provider.tsx#L53-L151) +- [frontend/antd/config-provider/locales.ts:89-863](file://frontend/antd/config-provider/locales.ts#L89-L863) + +### Accessibility and Keyboard Navigation + +- Recommendations + - Use standard semantic labels and native interactions to ensure keyboard accessibility. + - Mount popup layers inside focusable containers via getPopupContainer. + - Preserve focus management and accessibility attributes in custom cellRender/headerRender. + - For countdown/timer, provide clear titles and unit hints for screen reader recognition. + +### Complex Scenario Handling Patterns and Best Practices + +- Cross-timezone scenarios + - Recommended to uniformly store and transmit UTC second-level timestamps, and perform localized display in the presentation layer based on ConfigProvider's dayjs language and locale settings. +- Range selection + - Use DateRangePicker/TimeRangePicker and validate start/end order and validity at the parent level. +- Preset shortcuts + - Inject preset items via DatePickerPreset, ensure values are in dayjs format to avoid display anomalies from format inconsistencies. +- Validation rules + - Combine disabledDate/disabledTime with min/max date restrictions to form a "disable + validate" dual safeguard. +- Performance + - In large list/high-frequency update scenarios, prioritize useMemo/useCallback to stabilize props and callbacks to reduce re-renders. diff --git a/.wiki/en/Ant Design Components/Data Entry Components/Input Components.md b/.wiki/en/Ant Design Components/Data Entry Components/Input Components.md new file mode 100644 index 00000000..a19ce6e3 --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Entry Components/Input Components.md @@ -0,0 +1,516 @@ +# Input Components + + +**Files referenced in this document** +- [input.tsx](file://frontend/antd/input/input.tsx) +- [input-number.tsx](file://frontend/antd/input-number/input-number.tsx) +- [auto-complete.tsx](file://frontend/antd/auto-complete/auto-complete.tsx) +- [mentions.tsx](file://frontend/antd/mentions/mentions.tsx) +- [input.password.tsx](file://frontend/antd/input/password/input.password.tsx) +- [input.search.tsx](file://frontend/antd/input/search/input.search.tsx) +- [input.textarea.tsx](file://frontend/antd/input/textarea/input.textarea.tsx) +- [input.otp.tsx](file://frontend/antd/input/otp/input.otp.tsx) +- [context.ts](file://frontend/antd/auto-complete/context.ts) +- [hooks/useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [renderItems.ts](file://frontend/utils/renderItems.ts) +- [renderParamsSlot.ts](file://frontend/utils/renderParamsSlot.ts) +- [omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +This section covers the usage and extension of "input-type data entry components", including: Input, InputNumber, AutoComplete, Mentions, InputPassword, InputSearch, InputTextarea, and InputOTP. The document focuses on: + +- How input validation, formatting, debounce, and character limiting are implemented within components, and best practices +- Accessibility and keyboard navigation support +- Integration patterns with form validation +- Performance optimization strategies for large-scale data input scenarios + +## Project Structure + +Input components are all located in the frontend Ant Design wrapper layer, using a unified pattern of "sveltify wrapping + React Slot + Hooks value synchronization" to ensure alignment with Ant Design component properties while providing more flexible slot-based and functional callback capabilities. + +```mermaid +graph TB +subgraph "Antd Input Component Wrappers" +A["Input
Text Input"] +B["InputNumber
Numeric Input"] +C["AutoComplete
Auto Complete"] +D["Mentions
Mentions"] +E["InputPassword
Password Input"] +F["InputSearch
Search Input"] +G["InputTextarea
Multiline Textarea"] +H["InputOTP
One-Time Password Input"] +end +subgraph "Common Utilities and Hooks" +U1["useValueChange
Value Change Sync"] +U2["useFunction
Function Wrapping"] +U3["renderItems
Option Rendering"] +U4["renderParamsSlot
Parameterized Slots"] +U5["omitUndefinedProps
Property Trimming"] +end +A --> U1 +A --> U2 +A --> U4 +A --> U5 +B --> U1 +B --> U2 +B --> U4 +C --> U1 +C --> U2 +C --> U3 +C --> U4 +C --> U5 +C -.-> X["AutoComplete Context"] +D --> U1 +D --> U2 +D --> U3 +D --> U4 +D --> U5 +E --> U1 +E --> U2 +E --> U4 +E --> U5 +F --> U1 +F --> U2 +F --> U4 +F --> U5 +G --> U1 +G --> U2 +G --> U4 +G --> U5 +H --> U1 +H --> U2 +H --> U4 +``` + +Diagram Source + +- [input.tsx:10-116](file://frontend/antd/input/input.tsx#L10-L116) +- [input-number.tsx:7-89](file://frontend/antd/input-number/input-number.tsx#L7-L89) +- [auto-complete.tsx:32-148](file://frontend/antd/auto-complete/auto-complete.tsx#L32-L148) +- [mentions.tsx:11-77](file://frontend/antd/mentions/mentions.tsx#L11-L77) +- [input.password.tsx:10-126](file://frontend/antd/input/password/input.password.tsx#L10-L126) +- [input.search.tsx:10-123](file://frontend/antd/input/search/input.search.tsx#L10-L123) +- [input.textarea.tsx:10-88](file://frontend/antd/input/textarea/input.textarea.tsx#L10-L88) +- [input.otp.tsx:7-54](file://frontend/antd/input/otp/input.otp.tsx#L7-L54) +- [context.ts](file://frontend/antd/auto-complete/context.ts) +- [hooks/useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [renderItems.ts](file://frontend/utils/renderItems.ts) +- [renderParamsSlot.ts](file://frontend/utils/renderParamsSlot.ts) +- [omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +Section Source + +- [input.tsx:1-119](file://frontend/antd/input/input.tsx#L1-L119) +- [input-number.tsx:1-92](file://frontend/antd/input-number/input-number.tsx#L1-L92) +- [auto-complete.tsx:1-151](file://frontend/antd/auto-complete/auto-complete.tsx#L1-L151) +- [mentions.tsx:1-80](file://frontend/antd/mentions/mentions.tsx#L1-L80) +- [input.password.tsx:1-129](file://frontend/antd/input/password/input.password.tsx#L1-L129) +- [input.search.tsx:1-126](file://frontend/antd/input/search/input.search.tsx#L1-L126) +- [input.textarea.tsx:1-91](file://frontend/antd/input/textarea/input.textarea.tsx#L1-L91) +- [input.otp.tsx:1-57](file://frontend/antd/input/otp/input.otp.tsx#L1-L57) + +## Core Components + +This section outlines the key responsibilities and common design of each component: + +- Value synchronization and callbacks: through the unified useValueChange hook, the controlled value is decoupled from the onValueChange callback, ensuring consistent updates between input events and external state. +- Function wrapping: useFunction converts incoming functions (such as formatter, parser, filterOption) into stable references, avoiding unnecessary re-renders. +- Slot system: ReactSlot and renderParamsSlot support slot-based custom rendering (such as prefix/suffix, clear icon, dropdown items, separators, etc.) and allow parameter passing. +- Property trimming: omitUndefinedProps only passes valid configuration, preventing undefined properties from affecting rendering or behavior. +- Option rendering: renderItems converts option nodes from slots into the options array required by Ant Design, supporting both default and custom option sets. + +Section Source + +- [input.tsx:39-42](file://frontend/antd/input/input.tsx#L39-L42) +- [input-number.tsx:32-35](file://frontend/antd/input-number/input-number.tsx#L32-L35) +- [auto-complete.tsx:63-66](file://frontend/antd/auto-complete/auto-complete.tsx#L63-L66) +- [mentions.tsx:34-37](file://frontend/antd/mentions/mentions.tsx#L34-L37) +- [hooks/useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [renderItems.ts](file://frontend/utils/renderItems.ts) +- [renderParamsSlot.ts](file://frontend/utils/renderParamsSlot.ts) +- [omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +## Architecture Overview + +The unified architecture of input components consists of "wrapper layer + utility layer + AntD native components", forming clear responsibility boundaries and reuse paths. + +```mermaid +sequenceDiagram +participant U as "User" +participant S as "Svelte Component (Wrapper)" +participant H as "Hooks/Utilities" +participant R as "AntD Native Component" +U->>S : Input/select/keypress +S->>H : Trigger value sync/function wrapping/slot rendering +H-->>S : Return stable value/function/render result +S->>R : Render native component (with value/callbacks/slots) +R-->>S : Trigger onChange/callback +S->>H : Update controlled value (onValueChange) +H-->>S : Complete sync +S-->>U : UI update +``` + +Diagram Source + +- [input.tsx:47-54](file://frontend/antd/input/input.tsx#L47-L54) +- [input-number.tsx:39-46](file://frontend/antd/input-number/input-number.tsx#L39-L46) +- [auto-complete.tsx:76-104](file://frontend/antd/auto-complete/auto-complete.tsx#L76-L104) +- [mentions.tsx:44-61](file://frontend/antd/mentions/mentions.tsx#L44-L61) +- [hooks/useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) + +## Detailed Component Analysis + +### Input + +- Key features + - Controlled value: synchronizes props.value with internal state via useValueChange; triggers onValueChange on onChange. + - Character counting: showCount supports functional formatter; count supports combined configuration of strategy/exceedFormatter/show, using useMemo and omitUndefinedProps to trim invalid fields. + - Slot-based decoration: addonBefore/After, prefix/suffix, allowClear.clearIcon can inject custom nodes via slots. +- Input validation and formatting + - No built-in regex validation; recommended to combine with form validators or perform validation within onValueChange. + - formatter/parser are passed in from the parent; not covered here. +- Debounce and character limits + - No built-in debounce; throttle/debounce can be self-implemented in onValueChange. + - maxLength is natively supported by AntD and used together with showCount. +- Accessibility and keyboard navigation + - Preserves native input behavior, following browser default keyboard interactions. +- Integration with form validation + - Recommended to perform real-time validation in onValueChange and update state via setFieldError/setFieldValue exposed by the form context. +- Performance optimization + - Use useMemo to cache count configuration to reduce re-renders. + - Only render the corresponding decoration node when slots exist, avoiding empty branch overhead. + +Section Source + +- [input.tsx:39-84](file://frontend/antd/input/input.tsx#L39-L84) +- [input.tsx:85-112](file://frontend/antd/input/input.tsx#L85-L112) + +### InputNumber + +- Key features + - Controlled value and callbacks: same as above, using useValueChange to sync values. + - Formatting/parsing: formatter/parser are passed in as functions, wrapped with useFunction for stable references. + - Control icons: controls.upIcon/controls.downIcon support slot injection. + - Decoration and prefix/suffix: addonBefore/After, prefix/suffix support slots. +- Input validation and formatting + - No built-in validation; recommended to perform range and format validation in onChange or onValueChange. + - formatter/parser are used for display and parsing to prevent users from entering non-numeric characters. +- Debounce and character limits + - No built-in debounce; can be implemented in onValueChange. +- Accessibility and keyboard navigation + - Preserves native numeric input behavior, supports up/down arrows to increment/decrement. +- Integration with form validation + - Perform numeric range and precision validation in onValueChange and sync form state. +- Performance optimization + - formatter/parser and control icons are rendered on demand, reducing unnecessary overhead. + +Section Source + +- [input-number.tsx:32-35](file://frontend/antd/input-number/input-number.tsx#L32-L35) +- [input-number.tsx:47-64](file://frontend/antd/input-number/input-number.tsx#L47-L64) +- [input-number.tsx:79-84](file://frontend/antd/input-number/input-number.tsx#L79-L84) + +### AutoComplete + +- Key features + - Value sync: useValueChange syncs value with onValueChange. + - Option rendering: prefers passed-in options; otherwise extracts from slots and converts using renderItems. + - Dropdown rendering: dropdownRender/popupRender support both slot and function forms. + - Filter logic: filterOption supports functions or boolean values; getPopupContainer specifies the popup container. + - Clear and decoration: allowClear.clearIcon, notFoundContent, addonBefore/After, prefix/suffix support slots. +- Input validation and formatting + - No built-in validation; control candidate set via filterOption and validateSearch. + - Recommended to perform secondary validation in onChange/onValueChange. +- Debounce and character limits + - No built-in debounce; can be implemented in onValueChange. +- Accessibility and keyboard navigation + - Supports keyboard up/down selection, Enter to confirm, Tab to switch. +- Integration with form validation + - Use the form context to set error messages in onValueChange. +- Performance optimization + - Use useMemo to cache options; only render decoration nodes when slots exist. + +```mermaid +flowchart TD +Start(["Input event"]) --> Filter["Apply filterOption/validateSearch"] +Filter --> HasOptions{"Matching items?"} +HasOptions -- Yes --> RenderList["Render candidate list
dropdownRender/popupRender"] +HasOptions -- No --> NotFound["Render notFoundContent"] +RenderList --> Select["User selects/Enter to confirm"] +NotFound --> Select +Select --> Sync["useValueChange syncs value"] +Sync --> End(["Done"]) +``` + +Diagram Source + +- [auto-complete.tsx:89-100](file://frontend/antd/auto-complete/auto-complete.tsx#L89-L100) +- [auto-complete.tsx:114-135](file://frontend/antd/auto-complete/auto-complete.tsx#L114-L135) +- [mentions.tsx:48-57](file://frontend/antd/mentions/mentions.tsx#L48-L57) + +Section Source + +- [auto-complete.tsx:63-66](file://frontend/antd/auto-complete/auto-complete.tsx#L63-L66) +- [auto-complete.tsx:89-100](file://frontend/antd/auto-complete/auto-complete.tsx#L89-L100) +- [auto-complete.tsx:114-135](file://frontend/antd/auto-complete/auto-complete.tsx#L114-L135) +- [context.ts](file://frontend/antd/auto-complete/context.ts) + +### Mentions + +- Key features + - Value sync: useValueChange syncs value with onValueChange. + - Option rendering: prefers options; otherwise uses slot renderItems. + - Filter and validation: filterOption, validateSearch support functional forms. + - Popup container: getPopupContainer specifies the container. + - Clear and placeholder: allowClear.clearIcon, notFoundContent support slots. +- Input validation and formatting + - No built-in validation; control input and candidates via validateSearch and filterOption. +- Debounce and character limits + - No built-in debounce; can be implemented in onValueChange. +- Accessibility and keyboard navigation + - Supports keyboard selection and confirmation. +- Integration with form validation + - Perform format and content validation in onValueChange. +- Performance optimization + - useMemo caches options; renders decoration nodes on demand. + +Section Source + +- [mentions.tsx:34-37](file://frontend/antd/mentions/mentions.tsx#L34-L37) +- [mentions.tsx:48-57](file://frontend/antd/mentions/mentions.tsx#L48-L57) +- [mentions.tsx:62-71](file://frontend/antd/mentions/mentions.tsx#L62-L71) + +### InputPassword + +- Key features + - Controlled value: useValueChange syncs value with onValueChange. + - Show/hide toggle: iconRender supports slots and functions. + - Character counting: showCount/formatter and count configuration support functional forms and trimming. + - Decoration and clear: addonBefore/After, prefix/suffix, allowClear.clearIcon support slots. +- Input validation and formatting + - No built-in validation; recommended to perform strength and length validation in onValueChange. +- Debounce and character limits + - No built-in debounce; can be implemented in onValueChange. +- Accessibility and keyboard navigation + - Preserves native password input behavior. +- Integration with form validation + - Perform password policy validation in onValueChange. +- Performance optimization + - Use useMemo to cache count configuration and iconRender. + +Section Source + +- [input.password.tsx:42-45](file://frontend/antd/input/password/input.password.tsx#L42-L45) +- [input.password.tsx:65-79](file://frontend/antd/input/password/input.password.tsx#L65-L79) +- [input.password.tsx:80-94](file://frontend/antd/input/password/input.password.tsx#L80-L94) +- [input.password.tsx:95-122](file://frontend/antd/input/password/input.password.tsx#L95-L122) + +### InputSearch + +- Key features + - Controlled value: useValueChange syncs value with onValueChange. + - Character counting: showCount/formatter and count configuration support functional forms and trimming. + - Search button: enterButton supports slots and text. + - Decoration and clear: addonBefore/After, prefix/suffix, allowClear.clearIcon support slots. +- Input validation and formatting + - No built-in validation; recommended to perform length and content validation in onValueChange. +- Debounce and character limits + - No built-in debounce; can be implemented in onValueChange. +- Accessibility and keyboard navigation + - Supports Enter to trigger search. +- Integration with form validation + - Perform search term validation in onValueChange. +- Performance optimization + - Use useMemo to cache count configuration and enterButton. + +Section Source + +- [input.search.tsx:40-43](file://frontend/antd/input/search/input.search.tsx#L40-L43) +- [input.search.tsx:70-78](file://frontend/antd/input/search/input.search.tsx#L70-L78) +- [input.search.tsx:85-91](file://frontend/antd/input/search/input.search.tsx#L85-L91) +- [input.search.tsx:92-118](file://frontend/antd/input/search/input.search.tsx#L92-L118) + +### InputTextarea + +- Key features + - Controlled value: useValueChange syncs value with onValueChange. + - Character counting: showCount/formatter and count configuration support functional forms and trimming. + - Clear: allowClear.clearIcon supports slots. +- Input validation and formatting + - No built-in validation; recommended to perform length and content validation in onValueChange. +- Debounce and character limits + - No built-in debounce; can be implemented in onValueChange. +- Accessibility and keyboard navigation + - Supports multiline input and scrolling. +- Integration with form validation + - Perform content and length validation in onValueChange. +- Performance optimization + - Use useMemo to cache count configuration. + +Section Source + +- [input.textarea.tsx:32-35](file://frontend/antd/input/textarea/input.textarea.tsx#L32-L35) +- [input.textarea.tsx:62-76](file://frontend/antd/input/textarea/input.textarea.tsx#L62-L76) +- [input.textarea.tsx:77-83](file://frontend/antd/input/textarea/input.textarea.tsx#L77-L83) + +### InputOTP + +- Key features + - Controlled value: useValueChange syncs value with onValueChange. + - Separator: separator supports slots and functions. + - Formatting: formatter supports functions. +- Input validation and formatting + - No built-in validation; recommended to perform length and character type validation in onValueChange. +- Debounce and character limits + - No built-in debounce; can be implemented in onValueChange. +- Accessibility and keyboard navigation + - Supports cell-by-cell input and automatic focus movement. +- Integration with form validation + - Perform OTP validation in onValueChange. +- Performance optimization + - Use useMemo to cache formatter and separator. + +Section Source + +- [input.otp.tsx:25-28](file://frontend/antd/input/otp/input.otp.tsx#L25-L28) +- [input.otp.tsx:38-44](file://frontend/antd/input/otp/input.otp.tsx#L38-L44) +- [input.otp.tsx:46-49](file://frontend/antd/input/otp/input.otp.tsx#L46-L49) + +## Dependency Analysis + +- Component to utility layer + - All input components depend on useValueChange for controlled value synchronization. + - useFunction is used for stable function references to avoid re-renders. + - renderItems/renderParamsSlot are used for slot options and parameterized rendering. + - omitUndefinedProps is used to trim invalid properties. +- Differences between components + - AutoComplete/Mentions rely on context and slot option rendering. + - InputNumber/InputPassword/InputSearch/InputTextarea/InputOTP functionalize and cache configurations such as showCount/count/formatter. + +```mermaid +graph LR +subgraph "Components" +I["Input"] +N["InputNumber"] +AC["AutoComplete"] +M["Mentions"] +P["InputPassword"] +S["InputSearch"] +T["InputTextarea"] +O["InputOTP"] +end +subgraph "Utilities" +V["useValueChange"] +F["useFunction"] +RI["renderItems"] +RP["renderParamsSlot"] +OD["omitUndefinedProps"] +end +I --> V +I --> F +I --> RP +I --> OD +N --> V +N --> F +N --> RP +AC --> V +AC --> F +AC --> RI +AC --> RP +AC --> OD +M --> V +M --> F +M --> RI +M --> RP +M --> OD +P --> V +P --> F +P --> RP +P --> OD +S --> V +S --> F +S --> RP +S --> OD +T --> V +T --> F +T --> RP +T --> OD +O --> V +O --> F +O --> RP +``` + +Diagram Source + +- [input.tsx:39-84](file://frontend/antd/input/input.tsx#L39-L84) +- [input-number.tsx:32-84](file://frontend/antd/input-number/input-number.tsx#L32-L84) +- [auto-complete.tsx:63-100](file://frontend/antd/auto-complete/auto-complete.tsx#L63-L100) +- [mentions.tsx:34-57](file://frontend/antd/mentions/mentions.tsx#L34-L57) +- [input.password.tsx:42-94](file://frontend/antd/input/password/input.password.tsx#L42-L94) +- [input.search.tsx:40-84](file://frontend/antd/input/search/input.search.tsx#L40-L84) +- [input.textarea.tsx:32-76](file://frontend/antd/input/textarea/input.textarea.tsx#L32-L76) +- [input.otp.tsx:25-44](file://frontend/antd/input/otp/input.otp.tsx#L25-L44) +- [hooks/useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [renderItems.ts](file://frontend/utils/renderItems.ts) +- [renderParamsSlot.ts](file://frontend/utils/renderParamsSlot.ts) +- [omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +## Performance Considerations + +- Controlled value synchronization + - Use useValueChange to uniformly manage the controlled value, avoiding redundant renders caused by inconsistencies between external and internal state. +- Function reference stabilization + - useFunction wraps incoming functions to reduce re-renders caused by prop changes. +- Slot rendering optimization + - Only render the corresponding node when slots exist, avoiding empty branch overhead. +- Configuration caching + - Use useMemo to cache configurations such as showCount/count/formatter to reduce rendering cost. +- Large data input handling + - Avoid heavy computation in onValueChange; if necessary, split into microtasks or use Web Worker. + - For high-frequency inputs (such as search, auto-complete), it is recommended to add debounce/throttle strategies upstream. + - For long text input, prefer TextArea and enable necessary character limits and counting hints. + +## Troubleshooting Guide + +- Input value not syncing + - Check whether onValueChange is correctly passed in and has not been overridden. + - Confirm whether the value in useValueChange is consistent with props.value. +- Slot not working + - Confirm that the slot key name matches the slots supported by the component (such as allowClear.clearIcon, prefix, suffix, enterButton, separator, etc.). + - Check whether the renderParamsSlot key is correct. +- Options not displayed + - AutoComplete/Mentions require providing options or providing options via slots; check the children name and structure in renderItems. +- Formatting anomaly + - Functions such as formatter/parser/filterOption must return the expected type; use useFunction to wrap them for stable references. +- Count configuration invalid + - Confirm that when showCount is an object, provide formatter; use omitUndefinedProps to trim invalid fields in count configuration. + +Section Source + +- [hooks/useValueChange.ts](file://frontend/utils/hooks/useValueChange.ts) +- [hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [renderItems.ts](file://frontend/utils/renderItems.ts) +- [renderParamsSlot.ts](file://frontend/utils/renderParamsSlot.ts) +- [omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +## Conclusion + +Input components achieve deep compatibility with Ant Design and flexible extensibility through a unified wrapping pattern. With the help of tools such as useValueChange, useFunction, renderItems, renderParamsSlot, and omitUndefinedProps, the components provide powerful slot-based and functional capabilities while ensuring performance. In actual business scenarios, it is recommended to combine with the form validation system to implement input validation, formatting, and debounce strategies in onValueChange, and to employ caching and asynchronous processing for large-scale data input scenarios, to achieve better user experience and stability. diff --git a/.wiki/en/Ant Design Components/Data Entry Components/Selection Components.md b/.wiki/en/Ant Design Components/Data Entry Components/Selection Components.md new file mode 100644 index 00000000..21a22c7a --- /dev/null +++ b/.wiki/en/Ant Design Components/Data Entry Components/Selection Components.md @@ -0,0 +1,673 @@ +# Selection Components + + +**Files referenced in this document** +- [select.tsx](file://frontend/antd/select/select.tsx) +- [option.tsx](file://frontend/antd/select/option/option.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [group.tsx](file://frontend/antd/checkbox/group/checkbox.group.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [radio.group.tsx](file://frontend/antd/radio/group/radio.group.tsx) +- [switch.tsx](file://frontend/antd/switch/switch.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [option.tsx](file://frontend/antd/segmented/option/segmented.option.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [tree.node.tsx](file://frontend/antd/tree/tree-node/tree.node.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [tree.node.tsx](file://frontend/antd/tree-select/tree-node/tree.node.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [panel.tsx](file://frontend/antd/cascader/panel/panel.tsx) +- [option.tsx](file://frontend/antd/cascader/option/option.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) +- [context.ts](file://frontend/antd/select/context.ts) +- [context.ts](file://frontend/antd/checkbox/context.ts) +- [context.ts](file://frontend/antd/radio/context.ts) +- [context.ts](file://frontend/antd/segmented/context.ts) +- [context.ts](file://frontend/antd/tree/context.ts) +- [context.ts](file://frontend/antd/tree-select/context.ts) +- [context.ts](file://frontend/antd/cascader/context.ts) +- [context.ts](file://frontend/antd/rate/context.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Virtual Scrolling](#performance-and-virtual-scrolling) +8. [Accessibility and Keyboard Navigation](#accessibility-and-keyboard-navigation) +9. [Troubleshooting Guide](#troubleshooting-guide) +10. [Conclusion](#conclusion) + +## Introduction + +This document systematically covers the "selection-type" components in the frontend component library: Select, Checkbox, Radio, Switch, Segmented, TreeSelect, Cascader, Transfer, Tree, and Rate. The document covers data binding, option configuration, multi-select mode, and disabled state, combined with design patterns and data flow management for complex scenarios. It also provides accessibility and keyboard navigation recommendations, as well as virtual scrolling and performance optimization strategies for large option sets. + +## Project Structure + +Selection components are primarily located in the frontend Ant Design component directory, organized by functional module: each component is stored in its own directory containing the entry component file and sub-components (such as Option, Group, Panel, etc.), with shared state and configuration managed uniformly through a context file (context.ts). + +```mermaid +graph TB +subgraph "Selection Component Directory" +S["select.tsx"] +C["checkbox.tsx"] +R["radio.tsx"] +SW["switch.tsx"] +SG["segmented.tsx"] +TS["tree-select.tsx"] +CA["cascader.tsx"] +T["tree.tsx"] +TR["transfer.tsx"] +RA["rate.tsx"] +end +subgraph "Sub-components" +SO["option.tsx (select)"] +CO["checkbox.group.tsx"] +RO["radio.group.tsx"] +SGO["segmented.option.tsx"] +TSN["tree.node.tsx (tree-select)"] +TN["tree.node.tsx (tree)"] +CAP["panel.tsx (cascader)"] +CAO["option.tsx (cascader)"] +end +subgraph "Context" +SC["context.ts (select)"] +CC["context.ts (checkbox)"] +RC["context.ts (radio)"] +SGC["context.ts (segmented)"] +TSC["context.ts (tree-select)"] +CAC["context.ts (cascader)"] +TC["context.ts (tree)"] +RAC["context.ts (rate)"] +end +S --> SO +S --> SC +C --> CO +C --> CC +R --> RO +R --> RC +SG --> SGO +SG --> SGC +TS --> TSN +TS --> TSC +T --> TN +T --> TC +CA --> CAP +CA --> CAO +CA --> CAC +TR --> TR +RA --> RAC +``` + +Diagram Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [switch.tsx](file://frontend/antd/switch/switch.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) + +Section Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [switch.tsx](file://frontend/antd/switch/switch.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) + +## Core Components + +This section outlines the key capabilities and common features of each component: + +- Data binding: controlled/uncontrolled modes, linked to external state via properties such as value/checked. +- Option configuration: declaratively define option sets through child item components (Option/Segmented.Option/Tree.Node, etc.). +- Multi-select mode: Checkbox supports multi-select; Select/Cascader/TreeSelect can be configured for multi-select; Transfer provides a left-right list interaction. +- Disabled state: supports both global disable and per-item disable, ensuring unavailable options do not respond to interaction. +- Controlled updates: onChange callback returns the current selected value, driving upstream state synchronization. + +Section Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [switch.tsx](file://frontend/antd/switch/switch.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) + +## Architecture Overview + +Selection components follow a unified "container-item-context" architecture: + +- Container components are responsible for rendering, state management, and event dispatching; +- Item components carry the display and interaction of specific options; +- Context files centrally handle shared logic such as default values, disabled states, and multi-select strategies. + +```mermaid +classDiagram +class Select { ++value ++mode ++disabled ++onChange() +} +class Option { ++label ++value ++disabled +} +class Checkbox { ++checked ++disabled ++onChange() +} +class CheckboxGroup { ++options[] ++value[] ++disabled ++onChange() +} +class Radio { ++checked ++disabled ++onChange() +} +class RadioGroup { ++options[] ++value ++disabled ++onChange() +} +class Switch { ++checked ++disabled ++onChange() +} +class Segmented { ++value ++disabled ++onChange() +} +class SegmentedOption { ++label ++value ++disabled +} +class Tree { ++treeData[] ++expandedKeys[] ++selectedKeys[] ++multiple ++onChange() +} +class TreeNode { ++title ++key ++disabled +} +class TreeSelect { ++treeData[] ++value ++treeDefaultExpandAll ++onChange() +} +class Cascader { ++options[] ++value[] ++onChange() +} +class CascaderPanel { ++options[] ++onChange() +} +class Transfer { ++dataSource[] ++targetKeys[] ++onChange() +} +class Rate { ++value ++allowHalf ++disabled ++onChange() +} +Select --> Option : "contains" +Checkbox --> CheckboxGroup : "combines" +Radio --> RadioGroup : "combines" +Segmented --> SegmentedOption : "contains" +Tree --> TreeNode : "contains" +TreeSelect --> TreeNode : "contains" +Cascader --> CascaderPanel : "contains" +``` + +Diagram Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [option.tsx](file://frontend/antd/select/option/option.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [group.tsx](file://frontend/antd/checkbox/group/checkbox.group.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [radio.group.tsx](file://frontend/antd/radio/group/radio.group.tsx) +- [switch.tsx](file://frontend/antd/switch/switch.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [option.tsx](file://frontend/antd/segmented/option/segmented.option.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [tree.node.tsx](file://frontend/antd/tree/tree-node/tree.node.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [tree.node.tsx](file://frontend/antd/tree-select/tree-node/tree.node.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [panel.tsx](file://frontend/antd/cascader/panel/panel.tsx) +- [option.tsx](file://frontend/antd/cascader/option/option.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) + +## Detailed Component Analysis + +### Select + +- Data binding: supports controlled value and uncontrolled default value; onChange returns the selected value or value array (multi-select). +- Option configuration: declare label/value/disabled via Option child items; supports search filtering and tag backfilling. +- Multi-select mode: when multi-select is enabled, supports tag-style display and clearing individual tags. +- Disabled state: both container and individual items can be disabled; when disabled, cannot be expanded or toggled. +- Context: context.ts centrally handles default values, disabled states, multi-select strategies, and controlled validation. + +```mermaid +sequenceDiagram +participant U as "User" +participant S as "Select" +participant O as "Option" +participant C as "Context" +U->>S : Expand dropdown +S->>C : Read default value/disabled state +U->>O : Click an option +O-->>S : Trigger selection callback +S->>S : Update internal state +S-->>U : Close dropdown and display selected item +S->>C : Trigger onChange(value) +``` + +Diagram Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [option.tsx](file://frontend/antd/select/option/option.tsx) +- [context.ts](file://frontend/antd/select/context.ts) + +Section Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [option.tsx](file://frontend/antd/select/option/option.tsx) +- [context.ts](file://frontend/antd/select/context.ts) + +### Checkbox + +- Data binding: single Checkbox is a controlled checked value; Checkbox.Group receives value[] and syncs via onChange. +- Option configuration: Group's options[] supports passing label/value/disabled directly; child Checkbox items can also be used. +- Multi-select mode: Group defaults to multi-select; supports select all/deselect all and indeterminate state. +- Disabled state: Group-level disable affects all child items; child items can also be individually disabled. +- Context: context.ts is responsible for default values, disabled states, and multi-select strategies. + +```mermaid +flowchart TD +Start(["Enter Checkbox.Group"]) --> LoadOptions["Load options[] or child items"] +LoadOptions --> Render["Render child Checkboxes"] +Render --> Interact{"User interaction?"} +Interact --> |Check/Uncheck| UpdateValue["Update value[]"] +UpdateValue --> Callback["Trigger onChange(value[])"] +Callback --> End(["Done"]) +``` + +Diagram Source + +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [group.tsx](file://frontend/antd/checkbox/group/checkbox.group.tsx) +- [context.ts](file://frontend/antd/checkbox/context.ts) + +Section Source + +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [group.tsx](file://frontend/antd/checkbox/group/checkbox.group.tsx) +- [context.ts](file://frontend/antd/checkbox/context.ts) + +### Radio + +- Data binding: single Radio is a controlled checked value; Radio.Group receives value and syncs via onChange. +- Option configuration: Group's options[] supports label/value/disabled; child Radio items can also be used. +- Multi-select mode: Group is single-select; supports clear and disable. +- Disabled state: Group-level disable affects all child items; child items can also be individually disabled. +- Context: context.ts is responsible for default values, disabled states, and single-select strategies. + +```mermaid +sequenceDiagram +participant U as "User" +participant RG as "Radio.Group" +participant R as "Radio" +participant C as "Context" +U->>R : Click option +R-->>RG : Trigger selection callback +RG->>C : Apply default value/disabled state +RG-->>U : Update selected state and callback onChange(value) +``` + +Diagram Source + +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [radio.group.tsx](file://frontend/antd/radio/group/radio.group.tsx) +- [context.ts](file://frontend/antd/radio/context.ts) + +Section Source + +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [radio.group.tsx](file://frontend/antd/radio/group/radio.group.tsx) +- [context.ts](file://frontend/antd/radio/context.ts) + +### Switch + +- Data binding: controlled checked value; onChange returns the new boolean value. +- Disabled state: disabled disables interaction; supports loading state. +- Use case: suitable for binary selection, such as "enable/disable" or "yes/no". + +Section Source + +- [switch.tsx](file://frontend/antd/switch/switch.tsx) + +### Segmented + +- Data binding: controlled value; onChange returns the selected value. +- Option configuration: supports options[] or child Segmented.Option items; can disable individual items. +- Use case: a compact alternative to Radio.Group, suitable for a small number of discrete options. + +```mermaid +classDiagram +class Segmented { ++value ++options[] ++disabled ++onChange() +} +class SegmentedOption { ++label ++value ++disabled +} +Segmented --> SegmentedOption : "contains" +``` + +Diagram Source + +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [option.tsx](file://frontend/antd/segmented/option/segmented.option.tsx) +- [context.ts](file://frontend/antd/segmented/context.ts) + +Section Source + +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [option.tsx](file://frontend/antd/segmented/option/segmented.option.tsx) +- [context.ts](file://frontend/antd/segmented/context.ts) + +### Tree + +- Data binding: controlled selectedKeys/expandedKeys; onChange returns the selected key set. +- Option configuration: treeData[] supports title/key/children/disabled; supports drag-and-drop, search, and batch selection. +- Multi-select mode: when multiple=true, multi-select is supported; supports both controlled and uncontrolled modes. +- Disabled state: node-level disabled; supports batch disable. + +```mermaid +sequenceDiagram +participant U as "User" +participant T as "Tree" +participant TN as "TreeNode" +participant C as "Context" +U->>TN : Click node +TN-->>T : Trigger selection/expansion +T->>C : Apply multi-select/disable strategy +T-->>U : Update selectedKeys/expandedKeys and callback +``` + +Diagram Source + +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [tree.node.tsx](file://frontend/antd/tree/tree-node/tree.node.tsx) +- [context.ts](file://frontend/antd/tree/context.ts) + +Section Source + +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [tree.node.tsx](file://frontend/antd/tree/tree-node/tree.node.tsx) +- [context.ts](file://frontend/antd/tree/context.ts) + +### TreeSelect + +- Data binding: controlled value; onChange returns the selected key. +- Option configuration: treeData[] with option declaration similar to Select; supports search filtering and tag backfilling. +- Multi-select mode: supports multi-select and parent-child linkage strategies (e.g., leaves only). +- Disabled state: supports global and node-level disable. + +```mermaid +flowchart TD +Open["Expand TreeSelect"] --> Filter["Enter search keyword"] +Filter --> List["Render matching nodes"] +List --> Select["Click node to select"] +Select --> Update["Update value and close panel"] +Update --> Callback["Trigger onChange(value)"] +``` + +Diagram Source + +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [tree.node.tsx](file://frontend/antd/tree-select/tree-node/tree.node.tsx) +- [context.ts](file://frontend/antd/tree-select/context.ts) + +Section Source + +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [tree.node.tsx](file://frontend/antd/tree-select/tree-node/tree.node.tsx) +- [context.ts](file://frontend/antd/tree-select/context.ts) + +### Cascader + +- Data binding: controlled value[]; onChange returns the full path value array. +- Option configuration: options[] supports label/value/children; supports async loading of child levels. +- Multi-select mode: typically single path selection; multiple path selection can be achieved through extensions. +- Disabled state: supports disabling the entire tree and node-level disable. + +```mermaid +sequenceDiagram +participant U as "User" +participant C as "Cascader" +participant P as "CascaderPanel" +participant O as "Option" +participant Ctx as "Context" +U->>C : Open cascade +C->>Ctx : Read default value/disabled state +U->>P : Select level 1 +P-->>C : Notify change +U->>P : Select level 2... +P-->>C : Notify change +C-->>U : Complete path selection and callback onChange(value[]) +``` + +Diagram Source + +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [panel.tsx](file://frontend/antd/cascader/panel/panel.tsx) +- [option.tsx](file://frontend/antd/cascader/option/option.tsx) +- [context.ts](file://frontend/antd/cascader/context.ts) + +Section Source + +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [panel.tsx](file://frontend/antd/cascader/panel/panel.tsx) +- [option.tsx](file://frontend/antd/cascader/option/option.tsx) +- [context.ts](file://frontend/antd/cascader/context.ts) + +### Transfer + +- Data binding: controlled targetKeys[]; onChange returns the target list key set. +- Option configuration: dataSource[] supports title/key; supports search filtering and batch operations. +- Multi-select mode: bidirectional movement from left to right; supports select all/deselect all. +- Disabled state: supports global disable and button disable. + +```mermaid +flowchart TD +Start(["Open Transfer"]) --> SearchLeft["Left side search"] +SearchLeft --> Move["Click move button"] +Move --> UpdateTarget["Update targetKeys[]"] +UpdateTarget --> Callback["Trigger onChange(targetKeys)"] +Callback --> End(["Done"]) +``` + +Diagram Source + +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) + +Section Source + +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) + +### Rate + +- Data binding: controlled value; onChange returns the rating value. +- Option configuration: supports allowHalf half-star, count total, tooltips text. +- Disabled state: disabled disables interaction; supports read-only mode. +- Use case: quick expression of satisfaction or level rating. + +```mermaid +sequenceDiagram +participant U as "User" +participant RA as "Rate" +participant C as "Context" +U->>RA : Mouse hover/click +RA->>C : Apply disabled/read-only strategy +RA-->>U : Update value and callback onChange(value) +``` + +Diagram Source + +- [rate.tsx](file://frontend/antd/rate/rate.tsx) +- [context.ts](file://frontend/antd/rate/context.ts) + +Section Source + +- [rate.tsx](file://frontend/antd/rate/rate.tsx) +- [context.ts](file://frontend/antd/rate/context.ts) + +## Dependency Analysis + +- Low inter-component coupling: container components combine declaratively with child item components, avoiding tight coupling. +- Centralized context: each component's context.ts aggregates default values, disabled states, and multi-select strategies, reducing duplicate logic. +- Clear event chain: from user interaction to container update to callback, forming a stable data flow. + +```mermaid +graph LR +Select["Select"] --> Option["Option"] +Checkbox["Checkbox"] --> CheckboxGroup["Checkbox.Group"] +Radio["Radio"] --> RadioGroup["Radio.Group"] +Segmented["Segmented"] --> SegmentedOption["Segmented.Option"] +Tree["Tree"] --> TreeNode["TreeNode"] +TreeSelect["TreeSelect"] --> TreeNode +Cascader["Cascader"] --> Panel["Cascader.Panel"] +Cascader --> Option +Transfer["Transfer"] +Rate["Rate"] +``` + +Diagram Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) + +Section Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) + +## Performance and Virtual Scrolling + +- Recommendations for large option sets: + - Use virtual scrolling: for long lists (such as Select/Tree/Transfer), use virtual scroll rendering to only render visible area nodes, significantly reducing DOM count and reflow cost. + - Lazy loading and pagination: for TreeSelect/Cascader, support async loading of child nodes to reduce initial rendering pressure. + - Caching and debounce: debounce search filtering and onChange callbacks to avoid frequent redraws. + - Controlled update optimization: merge multiple state changes in the parent form to reduce unnecessary re-renders. +- Specific implementation points: + - Select: enable virtual scrolling and search filtering for the Option list. + - Tree/TreeSelect: enable virtual scrolling and lazy loading for node rendering. + - Transfer: enable virtual scrolling and batch operation optimization for left and right lists. + +[This section provides general performance guidance and does not require specific file references] + +## Accessibility and Keyboard Navigation + +- Keyboard support: + - Use Tab/Shift+Tab to navigate between options; + - Use Enter/Space to confirm selection; + - Use arrow keys to move among multiple options (such as Tree/Select/Cascader). +- Screen reader friendly: + - Provide semantic labels for each option; + - Disabled and error states provide aria-\* attributes and hint text; + - Provide value reading and tooltips for Rate. +- Recommendations: + - Provide aria-expanded/aria-controls for container components; + - Provide aria-disabled for disabled options; + - Provide aria-required for required fields. + +[This section provides general accessibility guidance and does not require specific file references] + +## Troubleshooting Guide + +- Common issues and diagnosis: + - Selected value not updated: check whether the controlled value and onChange are correctly passed in; confirm consistency of value/checked between container and child items. + - Multi-select not working: confirm the structure of Group's options[] and the type of value[]; check disabled state and indeterminate state. + - Disable not working: verify the disabled attribute hierarchy (container vs. child items); check the disable strategy in context. + - Performance stuttering: enable virtual scrolling for long lists; reduce unnecessary re-renders and deep nesting. +- Debugging recommendations: + - Print the current value in onChange to verify data flow; + - Use browser developer tools to observe DOM count and reflow; + - For TreeSelect/Cascader, check whether async loading is correctly triggered. + +Section Source + +- [select.tsx](file://frontend/antd/select/select.tsx) +- [checkbox.tsx](file://frontend/antd/checkbox/checkbox.tsx) +- [radio.tsx](file://frontend/antd/radio/radio.tsx) +- [segmented.tsx](file://frontend/antd/segmented/segmented.tsx) +- [tree.tsx](file://frontend/antd/tree/tree.tsx) +- [tree.select.tsx](file://frontend/antd/tree-select/tree-select.tsx) +- [cascader.tsx](file://frontend/antd/cascader/cascader.tsx) +- [transfer.tsx](file://frontend/antd/transfer/transfer.tsx) +- [rate.tsx](file://frontend/antd/rate/rate.tsx) + +## Conclusion + +Selection components in this project implement a unified container-item-context architecture with good extensibility and maintainability. Through controlled data binding, clear option configuration, and comprehensive disable strategies, they can meet diverse needs ranging from simple binary selection to complex tree/cascading selection. Combined with virtual scrolling and accessibility design, they can maintain a good experience in large-scale data and accessible scenarios. diff --git a/.wiki/en/Ant Design Components/Feedback Components/Alert.md b/.wiki/en/Ant Design Components/Feedback Components/Alert.md new file mode 100644 index 00000000..162b23f6 --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Alert.md @@ -0,0 +1,287 @@ +# Alert + + +**Files referenced in this document** +- [frontend/antd/alert/alert.tsx](file://frontend/antd/alert/alert.tsx) +- [frontend/antd/alert/Index.svelte](file://frontend/antd/alert/Index.svelte) +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx) +- [frontend/antd/alert/error-boundary/Index.svelte](file://frontend/antd/alert/error-boundary/Index.svelte) +- [backend/modelscope_studio/components/antd/alert/__init__.py](file://backend/modelscope_studio/components/antd/alert/__init__.py) +- [backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py) +- [frontend/antd/alert/package.json](file://frontend/antd/alert/package.json) +- [docs/components/antd/alert/README-zh_CN.md](file://docs/components/antd/alert/README-zh_CN.md) +- [docs/components/antd/alert/README.md](file://docs/components/antd/alert/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Alert component is used to convey information or status feedback that requires user attention, commonly used in form validation hints, operation result feedback, system notifications, and similar scenarios. This component is a wrapper around Ant Design's Alert, providing typed variants (success, info, warning, error), closability, icon and description slots, and error boundary wrapping, ensuring stable presentation even in complex rendering scenarios. + +## Project Structure + +The Alert component is composed of a frontend Svelte wrapper layer and a backend Gradio component layer, with a standalone error boundary version provided to enhance stability. + +```mermaid +graph TB +subgraph "Frontend" +A_Index["frontend/antd/alert/Index.svelte"] +A_Alert["frontend/antd/alert/alert.tsx"] +EB_Index["frontend/antd/alert/error-boundary/Index.svelte"] +EB_Boundary["frontend/antd/alert/error-boundary/alert.error-boundary.tsx"] +Pkg["frontend/antd/alert/package.json"] +end +subgraph "Backend" +Py_Component["backend/modelscope_studio/components/antd/alert/__init__.py"] +Py_EB["backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py"] +end +A_Index --> A_Alert +EB_Index --> EB_Boundary +A_Index --> Py_Component +EB_Index --> Py_EB +Pkg --> A_Index +Pkg --> EB_Index +``` + +Diagram sources + +- [frontend/antd/alert/Index.svelte:10-47](file://frontend/antd/alert/Index.svelte#L10-L47) +- [frontend/antd/alert/alert.tsx:7-43](file://frontend/antd/alert/alert.tsx#L7-L43) +- [frontend/antd/alert/error-boundary/Index.svelte:10-47](file://frontend/antd/alert/error-boundary/Index.svelte#L10-L47) +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx:6-32](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx#L6-L32) +- [backend/modelscope_studio/components/antd/alert/**init**.py:11-71](file://backend/modelscope_studio/components/antd/alert/__init__.py#L11-L71) +- [backend/modelscope_studio/components/antd/alert/error_boundary/**init**.py:10-55](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py#L10-L55) +- [frontend/antd/alert/package.json:1-15](file://frontend/antd/alert/package.json#L1-L15) + +Section sources + +- [frontend/antd/alert/Index.svelte:1-66](file://frontend/antd/alert/Index.svelte#L1-L66) +- [frontend/antd/alert/alert.tsx:1-46](file://frontend/antd/alert/alert.tsx#L1-L46) +- [frontend/antd/alert/error-boundary/Index.svelte:1-70](file://frontend/antd/alert/error-boundary/Index.svelte#L1-L70) +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx:1-35](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx#L1-L35) +- [backend/modelscope_studio/components/antd/alert/**init**.py:1-89](file://backend/modelscope_studio/components/antd/alert/__init__.py#L1-L89) +- [backend/modelscope_studio/components/antd/alert/error_boundary/**init**.py:1-73](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py#L1-L73) +- [frontend/antd/alert/package.json:1-15](file://frontend/antd/alert/package.json#L1-L15) + +## Core Components + +- Frontend main component: Responsible for wrapping Ant Design's Alert into a Svelte-consumable form, supporting slots (action, closable.closeIcon, description, icon, message), and passing through props and event callbacks. +- Error boundary component: Wraps Alert with an error boundary to ensure that exceptions in the subtree do not crash the entire interface, while retaining slot capabilities for message and description. +- Backend Gradio component: Provides typed parameters (type), slot mapping, event binding (close), and style/class injection capabilities; the error boundary version likewise provides corresponding events and slots. + +Section sources + +- [frontend/antd/alert/alert.tsx:7-43](file://frontend/antd/alert/alert.tsx#L7-L43) +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx:6-32](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx#L6-L32) +- [backend/modelscope_studio/components/antd/alert/**init**.py:11-71](file://backend/modelscope_studio/components/antd/alert/__init__.py#L11-L71) +- [backend/modelscope_studio/components/antd/alert/error_boundary/**init**.py:10-55](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py#L10-L55) + +## Architecture Overview + +The following sequence diagram illustrates the call chain from the backend Gradio component through the frontend Svelte wrapper layer to the Ant Design component, including the error boundary wrapping path. + +```mermaid +sequenceDiagram +participant Py as "Backend Component
AntdAlert/AntdAlertErrorBoundary" +participant Svelte as "Frontend Wrapper
Index.svelte" +participant ReactComp as "React Component
alert.tsx / alert.error-boundary.tsx" +participant AntD as "Ant Design Alert" +Py->>Svelte : Render request with props + slots +Svelte->>ReactComp : Pass props and slots +ReactComp->>AntD : Render Alert or ErrorBoundary-wrapped Alert +AntD-->>ReactComp : Visual presentation and interactions (close button, action buttons, etc.) +ReactComp-->>Svelte : Callback afterClose and other events +Svelte-->>Py : Event report (e.g., close) +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/alert/**init**.py:11-71](file://backend/modelscope_studio/components/antd/alert/__init__.py#L11-L71) +- [frontend/antd/alert/Index.svelte:10-47](file://frontend/antd/alert/Index.svelte#L10-L47) +- [frontend/antd/alert/alert.tsx:12-42](file://frontend/antd/alert/alert.tsx#L12-L42) +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx:17-29](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx#L17-L29) + +## Detailed Component Analysis + +### Types and Semantics + +- Supported types (type): success, info, warning, error. Each corresponds to a different visual emphasis and semantic meaning, helping users quickly identify the status. +- Semantic guidelines: + - success: Positive feedback for completed operations or finished workflows + - info: General hints or supplementary notes + - warning: Potential issues or operations requiring attention + - error: Failures, exceptions, or issues requiring immediate action + +Section sources + +- [backend/modelscope_studio/components/antd/alert/**init**.py:37-37](file://backend/modelscope_studio/components/antd/alert/__init__.py#L37-L37) + +### Slots and Customization Points + +- Supported slots: + - action: Custom action area (e.g., a "View Details" button) + - closable.closeIcon: Custom close icon + - description: Auxiliary description text / rich content + - icon: Custom icon + - message: Title / main message body +- Prop passthrough: All other props are passed directly to Ant Design Alert, including closable, show_icon, banner, after_close, etc. + +Section sources + +- [backend/modelscope_studio/components/antd/alert/**init**.py:22-23](file://backend/modelscope_studio/components/antd/alert/__init__.py#L22-L23) +- [frontend/antd/alert/alert.tsx:11-43](file://frontend/antd/alert/alert.tsx#L11-L43) + +### Events and Interactions + +- close event: Fired when the user clicks the close button; the backend can bind handling logic via an event listener. +- after_close callback: Fired after the animation ends; can be used to clean up resources or switch states. +- Keyboard operation: Follows Ant Design behavior by default — typically Tab to navigate to the close button, Enter/Space to trigger closing. + +Section sources + +- [backend/modelscope_studio/components/antd/alert/**init**.py:16-20](file://backend/modelscope_studio/components/antd/alert/__init__.py#L16-L20) +- [frontend/antd/alert/alert.tsx:13-13](file://frontend/antd/alert/alert.tsx#L13-L13) + +### Error Boundary + +- Purpose: Captures errors in the Alert subtree to prevent a single slot or content rendering exception from crashing the entire page. +- Use case: When the message/description slots contain dynamic rendering or external data, it is recommended to use the error boundary version. +- Events: Also supports the close event for unified handling of close behavior. + +```mermaid +flowchart TD +Start(["Enter Alert Error Boundary"]) --> RenderMsg["Render message slot"] +RenderMsg --> MsgOK{"Render successful?"} +MsgOK --> |Yes| RenderDesc["Render description slot"] +MsgOK --> |No| Fallback["Display fallback content / empty state"] +RenderDesc --> DescOK{"Render successful?"} +DescOK --> |Yes| Ready["Display normally"] +DescOK --> |No| Fallback +Fallback --> End(["End"]) +Ready --> End +``` + +Diagram sources + +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx:17-29](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx#L17-L29) + +Section sources + +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx:6-32](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx#L6-L32) +- [backend/modelscope_studio/components/antd/alert/error_boundary/**init**.py:10-55](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py#L10-L55) + +### Styles and Class Names + +- Supports injecting base styles and identifiers via elem_id, elem_classes, elem_style. +- Primary class name prefixes: + - ms-gr-antd-alert: Main Alert component + - ms-gr-antd-alert-error-boundary: Error boundary version +- Can be combined with Ant Design's own type, show_icon, closable, and other props to control appearance. + +Section sources + +- [frontend/antd/alert/Index.svelte:53-53](file://frontend/antd/alert/Index.svelte#L53-L53) +- [frontend/antd/alert/error-boundary/Index.svelte:56-56](file://frontend/antd/alert/error-boundary/Index.svelte#L56-L56) + +### Accessibility and Keyboard Support + +- Accessibility: Follows Ant Design's default accessibility design to ensure screen readers can read the message and description. +- Keyboard: Tab to navigate to the close button, Enter/Space to close; it is recommended to provide explicit accessible names in the action slot. + +Section sources + +- [frontend/antd/alert/alert.tsx:17-40](file://frontend/antd/alert/alert.tsx#L17-L40) + +### Typical Use Cases + +- Form validation hints: Use info/warning/error types, provide specific error information in the description, and offer a "View Details" action. +- Operation feedback: After a successful operation, use the success type to show a brief message with an icon. +- System notifications: Use banner mode with closable to improve visibility and controllability. +- Dynamic content: When message/description comes from external data or async rendering, prefer the error boundary version. + +Section sources + +- [docs/components/antd/alert/README-zh_CN.md:1-8](file://docs/components/antd/alert/README-zh_CN.md#L1-L8) +- [docs/components/antd/alert/README.md:1-8](file://docs/components/antd/alert/README.md#L1-L8) + +## Dependency Analysis + +- Frontend export: package.json points both the Gradio and default entries to Index.svelte, ensuring the backend loads it as expected. +- Component coupling: The frontend wrapper is tightly coupled to the Ant Design component, but maintains high extensibility through slots and prop passthrough. +- Backend integration: The backend component resolves the frontend directory via resolve_frontend_dir; events and slots are declared in the Python layer and executed at runtime by the frontend. + +```mermaid +graph LR +PyMain["Python Component
AntdAlert"] --> FEIndex["Svelte Wrapper
Index.svelte"] +PyEB["Python Component
AntdAlertErrorBoundary"] --> FEIndexEB["Svelte Wrapper
error-boundary/Index.svelte"] +FEIndex --> ReactComp["React Component
alert.tsx"] +FEIndexEB --> ReactCompEB["React Component
alert.error-boundary.tsx"] +ReactComp --> AntD["Ant Design Alert"] +ReactCompEB --> AntDEB["Ant Design ErrorBoundary(Alert)"] +``` + +Diagram sources + +- [frontend/antd/alert/package.json:4-12](file://frontend/antd/alert/package.json#L4-L12) +- [backend/modelscope_studio/components/antd/alert/**init**.py:71-71](file://backend/modelscope_studio/components/antd/alert/__init__.py#L71-L71) +- [backend/modelscope_studio/components/antd/alert/error_boundary/**init**.py:55-55](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py#L55-L55) + +Section sources + +- [frontend/antd/alert/package.json:1-15](file://frontend/antd/alert/package.json#L1-L15) +- [backend/modelscope_studio/components/antd/alert/**init**.py:71-71](file://backend/modelscope_studio/components/antd/alert/__init__.py#L71-L71) +- [backend/modelscope_studio/components/antd/alert/error_boundary/**init**.py:55-55](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py#L55-L55) + +## Performance Considerations + +- Avoid frequent re-renders: Use stable values for message/description/icon and other slots; cache computed results in the parent layer when necessary. +- Control slot complexity: Split complex subtrees into components and use them inside the error boundary to reduce overall rendering pressure. +- Use banner judiciously: Banner mode takes up more space; enable it only for critical alerts. +- Event throttling: Avoid heavy synchronous operations in after_close and close event callbacks; use microtasks or debouncing when necessary. + +## Troubleshooting Guide + +- Slots not working + - Check that slot names are correct (action, closable.closeIcon, description, icon, message). + - Confirm the frontend wrapper has passed slots through to the React component. +- Close event not fired + - Confirm the backend event listener has registered the close event. + - When closable is an object containing a closeIcon slot, check that it is correctly passed through. +- Error boundary not catching exceptions + - Confirm the error boundary version of the component is being used. + - Check that exceptions in the message/description slots are properly wrapped. +- Styles not applied + - Check that elem_id, elem_classes, elem_style are correctly passed in. + - Confirm the class name prefix ms-gr-antd-alert or ms-gr-antd-alert-error-boundary has been applied. + +Section sources + +- [frontend/antd/alert/alert.tsx:11-43](file://frontend/antd/alert/alert.tsx#L11-L43) +- [frontend/antd/alert/error-boundary/alert.error-boundary.tsx:12-29](file://frontend/antd/alert/error-boundary/alert.error-boundary.tsx#L12-L29) +- [backend/modelscope_studio/components/antd/alert/**init**.py:16-23](file://backend/modelscope_studio/components/antd/alert/__init__.py#L16-L23) +- [backend/modelscope_studio/components/antd/alert/error_boundary/**init**.py:14-21](file://backend/modelscope_studio/components/antd/alert/error_boundary/__init__.py#L14-L21) + +## Conclusion + +The Alert component in this project provides a complete set of capabilities: typed variants, slot support, closability, and error boundary protection. Through a clear separation of responsibilities between the frontend and backend, and a stable export convention, it satisfies both standard alerting needs and maintains robustness in complex rendering scenarios. When dynamic or external content is involved, it is recommended to use the error boundary version and combine the event and style system to deliver a consistent user experience. + +## Appendix + +- Example entry reference: The demo provided in the documentation is named `basic`; the demonstration effect can be viewed on the corresponding documentation page. + +Section sources + +- [docs/components/antd/alert/README-zh_CN.md:5-7](file://docs/components/antd/alert/README-zh_CN.md#L5-L7) +- [docs/components/antd/alert/README.md:5-7](file://docs/components/antd/alert/README.md#L5-L7) diff --git a/.wiki/en/Ant Design Components/Feedback Components/Drawer.md b/.wiki/en/Ant Design Components/Feedback Components/Drawer.md new file mode 100644 index 00000000..2a458f3c --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Drawer.md @@ -0,0 +1,348 @@ +# Drawer + + +**Files referenced in this document** +- [frontend/antd/drawer/drawer.tsx](file://frontend/antd/drawer/drawer.tsx) +- [frontend/antd/drawer/Index.svelte](file://frontend/antd/drawer/Index.svelte) +- [backend/modelscope_studio/components/antd/drawer/__init__.py](file://backend/modelscope_studio/components/antd/drawer/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [docs/components/antd/drawer/README.md](file://docs/components/antd/drawer/README.md) +- [docs/components/antd/drawer/README-zh_CN.md](file://docs/components/antd/drawer/README-zh_CN.md) +- [docs/components/antd/watermark/demos/modal_or_drawer.py](file://docs/components/antd/watermark/demos/modal_or_drawer.py) +- [frontend/antd/layout/layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +Drawer is a panel that slides out from the edge of the screen, commonly used for sidebar navigation, detail panels, settings panels, and similar scenarios. This component is implemented based on Ant Design Drawer and bridged through the Gradio ecosystem, supporting position configuration (left, right, top, bottom), size control, mask behavior, keyboard interaction, and rich slot extension capabilities. This document systematically describes its layout design, interaction patterns, use cases, and best practices, with directly referenceable example paths. + +## Project Structure + +The Drawer component consists of a Svelte frontend wrapper and a Python backend component, working together through Gradio's bridging mechanism. The overall structure is as follows: + +```mermaid +graph TB +subgraph "Backend" +PyInit["AntdDrawer Initialization
Parameter and Event Definitions"] +PySlots["Supported Slot List"] +PyEntry["Register to Component Entry"] +end +subgraph "Frontend" +SvelteIndex["Index.svelte
Conditional Rendering and Prop Passthrough"] +ReactWrapper["drawer.tsx
sveltify Wrapper and Slot Handling"] +AntdDrawer["Ant Design Drawer
Native Component"] +end +PyInit --> PySlots +PyInit --> PyEntry +SvelteIndex --> ReactWrapper +ReactWrapper --> AntdDrawer +``` + +Diagram sources + +- [frontend/antd/drawer/Index.svelte:10-61](file://frontend/antd/drawer/Index.svelte#L10-L61) +- [frontend/antd/drawer/drawer.tsx:14-57](file://frontend/antd/drawer/drawer.tsx#L14-L57) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:10-108](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L10-L108) +- [backend/modelscope_studio/components/antd/components.py:38](file://backend/modelscope_studio/components/antd/components.py#L38) + +Section sources + +- [frontend/antd/drawer/Index.svelte:1-65](file://frontend/antd/drawer/Index.svelte#L1-L65) +- [frontend/antd/drawer/drawer.tsx:1-60](file://frontend/antd/drawer/drawer.tsx#L1-L60) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:1-126](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L1-L126) +- [backend/modelscope_studio/components/antd/components.py:38](file://backend/modelscope_studio/components/antd/components.py#L38) + +## Core Components + +- Backend component: AntdDrawer (Python) + - Supported parameters cover key behaviors such as position, size, mask, keyboard, push, and rendering strategy + - Defines the close event binding mechanism + - Exposes multiple slots to support custom title, footer, extra actions, close icon, etc. +- Frontend wrapper: Index.svelte and drawer.tsx + - Conditional rendering: Loads and mounts the Drawer only when `visible` is true + - Prop passthrough: Merges Gradio props and additional props and passes them to the underlying component + - Slot handling: Supports closeIcon, closable.closeIcon, extra, footer, title, drawerRender slots +- Base layout component: Base (layout.base.tsx) + - Provides the base wrapper for Ant Design Layout, making it easy to build page layouts in conjunction with Drawer + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:10-108](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L10-L108) +- [frontend/antd/drawer/Index.svelte:13-42](file://frontend/antd/drawer/Index.svelte#L13-L42) +- [frontend/antd/drawer/drawer.tsx:14-57](file://frontend/antd/drawer/drawer.tsx#L14-L57) +- [frontend/antd/layout/layout.base.tsx:6-37](file://frontend/antd/layout/layout.base.tsx#L6-L37) + +## Architecture Overview + +The Drawer call chain starts from the backend AntdDrawer, goes through the conditional rendering in the frontend Index.svelte, then uses sveltify in drawer.tsx to bridge the React component to the Svelte environment, and finally renders as an Ant Design Drawer. This flow ensures two-way binding of props and events while preserving all capabilities of Ant Design Drawer. + +```mermaid +sequenceDiagram +participant User as "User" +participant Backend as "AntdDrawer (Backend)" +participant FrontIndex as "Index.svelte (Frontend)" +participant Wrapper as "drawer.tsx (Bridge)" +participant AD as "Antd Drawer (React)" +User->>Backend : Set open/visible and other parameters +Backend->>FrontIndex : Render request +FrontIndex->>FrontIndex : Check visible +FrontIndex->>Wrapper : Pass props and slots +Wrapper->>AD : sveltify wrapper and render +AD-->>User : Display drawer and fire event callbacks +``` + +Diagram sources + +- [frontend/antd/drawer/Index.svelte:48-61](file://frontend/antd/drawer/Index.svelte#L48-L61) +- [frontend/antd/drawer/drawer.tsx:24-56](file://frontend/antd/drawer/drawer.tsx#L24-L56) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:14-18](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L14-L18) + +## Detailed Component Analysis + +### Parameters and Slots Overview + +- Key parameters (excerpt) + - Position and size: placement (left/right/top/bottom), width, height, size (default/large) + - Behavior control: open, keyboard, mask, maskClosable, closable, destroyOnClose, destroyOnHidden, forceRender + - Layout and rendering: getContainer, push, resizable, drawerRender, as_item, visible, elem_id/elem_classes/elem_style +- Slots + - closeIcon, closable.closeIcon, extra, footer, title, drawerRender + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:26-107](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L26-L107) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:20-24](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L20-L24) +- [frontend/antd/drawer/drawer.tsx:14-57](file://frontend/antd/drawer/drawer.tsx#L14-L57) + +### Open/Close Mechanism and Events + +- Visibility control: Index.svelte controls whether the Drawer is rendered via `visible` +- Event binding: The backend defines the close event listener for updating state on close +- Callback functions: Callbacks such as afterOpenChange are converted into safely passable functions via useFunction + +```mermaid +flowchart TD +Start(["Start"]) --> CheckVisible["Check visible"] +CheckVisible --> |false| Skip["Do not render"] +CheckVisible --> |true| Render["Render Drawer component"] +Render --> BindEvents["Bind close and other events"] +BindEvents --> Open["Display drawer"] +Open --> UserAction{"User action?"} +UserAction --> |Click mask / Press ESC| Close["Trigger close"] +Close --> UpdateState["Update open/visible state"] +UpdateState --> Destroy{"Destroy strategy?"} +Destroy --> |Yes| Unmount["Unmount component"] +Destroy --> |No| Hide["Hide but keep DOM"] +Unmount --> End(["End"]) +Hide --> End +Skip --> End +``` + +Diagram sources + +- [frontend/antd/drawer/Index.svelte:48-61](file://frontend/antd/drawer/Index.svelte#L48-L61) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:14-18](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L14-L18) +- [frontend/antd/drawer/drawer.tsx:24-26](file://frontend/antd/drawer/drawer.tsx#L24-L26) + +### Position Configuration and Size Control + +- Position: placement supports left, right, top, bottom +- Size: width/height or size (default/large) controls the drawer dimensions +- Push and container: push can be used with a layout to push content; getContainer specifies the mount container + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:47-50](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L47-L50) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:42-56](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L42-L56) +- [frontend/antd/drawer/drawer.tsx:52-54](file://frontend/antd/drawer/drawer.tsx#L52-L54) + +### Mask Behavior and Keyboard Interaction + +- Mask: `mask` controls whether the mask is displayed; `maskClosable` controls whether clicking the mask closes the drawer +- Keyboard: `keyboard` controls whether ESC closes the drawer +- Auto focus: `autoFocus` can automatically focus the drawer on open + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:44-46](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L44-L46) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:31-32](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L31-L32) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:91](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L91) + +### Animation and Rendering Strategy + +- Animation: Driven by Ant Design Drawer's built-in animation; no additional configuration needed +- Rendering strategy: destroyOnClose, destroyOnHidden, forceRender control the destruction timing and forced rendering + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:36-39](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L36-L39) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:87-89](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L87-L89) + +### Slot and Style Customization + +- Slot mapping: closeIcon, closable.closeIcon, extra, footer, title, drawerRender +- Styles: elem_id, elem_classes, elem_style, styles, class_names, root_style, root_class_name +- Custom rendering: drawerRender can receive parameters and return custom rendered content + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:20-24](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L20-L24) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:33-35](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L33-L35) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:57-60](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L57-L60) +- [frontend/antd/drawer/drawer.tsx:41-51](file://frontend/antd/drawer/drawer.tsx#L41-L51) + +### Coordination with Page Layout and Responsive Adaptation + +- Layout collaboration: Can be combined with Ant Design Layout (Header/Footer/Content/Sider) +- Responsive: Combined with Flex/Grid and other layout components, adjust drawer width or switch placement based on screen size + +Section sources + +- [frontend/antd/layout/layout.base.tsx:6-37](file://frontend/antd/layout/layout.base.tsx#L6-L37) + +### Accessibility and Mobile Optimization + +- Accessibility: The keyboard and focus strategies should be combined with auto-focus and semantic labeling +- Mobile: On small-screen devices, prefer using `bottom` or a smaller `width` to avoid covering main content + +Section sources + +- [backend/modelscope_studio/components/antd/drawer/**init**.py:91](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L91) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:31-32](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L31-L32) + +### Common Use Cases and Example Paths + +- Sidebar navigation: Place menu items in the left drawer; update routes or data when a menu item is clicked +- Detail panel: Display detailed content in the right drawer, supporting scrolling and a bottom action area +- Settings panel: Provide settings in the top or bottom drawer, supporting quick toggling and saving +- Example references: + - Drawer basic usage and extra actions: [docs/components/antd/drawer/README.md](file://docs/components/antd/drawer/README.md) + - Drawer vs. Modal comparison demo: [docs/components/antd/watermark/demos/modal_or_drawer.py](file://docs/components/antd/watermark/demos/modal_or_drawer.py) + +Section sources + +- [docs/components/antd/drawer/README.md:1-9](file://docs/components/antd/drawer/README.md#L1-L9) +- [docs/components/antd/watermark/demos/modal_or_drawer.py:19-26](file://docs/components/antd/watermark/demos/modal_or_drawer.py#L19-L26) + +## Dependency Analysis + +- Component inheritance and context + - AntdDrawer inherits from ModelScopeLayoutComponent, with the general characteristics of a layout component + - AppContext is used to ensure the application context is available +- Component registration + - AntdDrawer is exported from the component entry for unified import and usage + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++bool visible ++str elem_id ++any elem_classes ++dict elem_style ++bool skip_api +} +class AntdDrawer { ++dict additional_props ++str after_open_change ++bool auto_focus ++dict body_style ++str close_icon ++any class_names ++any closable ++bool destroy_on_close ++bool destroy_on_hidden ++bool draggable ++str extra ++str footer ++bool force_render ++any get_container ++num height ++bool keyboard ++bool mask ++bool mask_closable ++str placement ++any push ++bool resizable ++str size ++any styles ++str title ++bool loading ++bool open ++num width ++int z_index ++str drawer_render ++dict root_style ++str root_class_name ++str as_item ++dict _internal ++bool visible ++str elem_id ++any elem_classes ++dict elem_style ++bool render +} +ModelScopeLayoutComponent <|-- AntdDrawer +``` + +Diagram sources + +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:10-108](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L10-L108) + +Section sources + +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [backend/modelscope_studio/components/antd/components.py:38](file://backend/modelscope_studio/components/antd/components.py#L38) + +## Performance Considerations + +- Conditional rendering: Render the Drawer only when `visible` is true to reduce unnecessary DOM overhead +- Rendering strategy: Use destroyOnClose/destroyOnHidden appropriately to balance memory usage and interaction smoothness +- Slots and custom rendering: Avoid heavy computations in drawerRender; use caching or async processing when necessary + +## Troubleshooting Guide + +- Drawer not showing + - Check if visible/open is true + - Confirm the conditional rendering logic in Index.svelte +- Slots not working + - Confirm slot names are correct (closeIcon, closable.closeIcon, extra, footer, title, drawerRender) + - Confirm the slot mapping logic in drawer.tsx +- Close event not fired + - Check the backend event binding and callback function passing +- Mask not working or clicking does not close + - Check mask and maskClosable configuration +- Keyboard close not working + - Check keyboard configuration and auto-focus strategy + +Section sources + +- [frontend/antd/drawer/Index.svelte:48-61](file://frontend/antd/drawer/Index.svelte#L48-L61) +- [frontend/antd/drawer/drawer.tsx:41-51](file://frontend/antd/drawer/drawer.tsx#L41-L51) +- [backend/modelscope_studio/components/antd/drawer/**init**.py:14-18](file://backend/modelscope_studio/components/antd/drawer/__init__.py#L14-L18) + +## Conclusion + +The Drawer component, through its integrated frontend-backend design, preserves the native capabilities of Ant Design Drawer while providing more flexible parameter and slot extensions. With conditional rendering and event binding mechanisms, it can efficiently adapt to various interaction scenarios, including sidebar navigation, detail panels, and settings panels. At the layout level, it can work in conjunction with Ant Design Layout; for accessibility and mobile experience, it is recommended to combine keyboard and size strategies to enhance the user experience. + +## Appendix + +- Example references + - Drawer basic usage and extra actions: [docs/components/antd/drawer/README.md](file://docs/components/antd/drawer/README.md) + - Drawer vs. Modal comparison demo: [docs/components/antd/watermark/demos/modal_or_drawer.py](file://docs/components/antd/watermark/demos/modal_or_drawer.py) +- Related documentation + - Ant Design Drawer official documentation: [Ant Design Drawer](https://ant.design/components/drawer/) diff --git a/.wiki/en/Ant Design Components/Feedback Components/Feedback Components.md b/.wiki/en/Ant Design Components/Feedback Components/Feedback Components.md new file mode 100644 index 00000000..6fa5d009 --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Feedback Components.md @@ -0,0 +1,437 @@ +# Feedback Components + + +**Files referenced in this document** +- [alert.tsx](file://frontend/antd/alert/alert.tsx) +- [drawer.tsx](file://frontend/antd/drawer/drawer.tsx) +- [message.tsx](file://frontend/antd/message/message.tsx) +- [modal.tsx](file://frontend/antd/modal/modal.tsx) +- [notification.tsx](file://frontend/antd/notification/notification.tsx) +- [popconfirm.tsx](file://frontend/antd/popconfirm/popconfirm.tsx) +- [progress.tsx](file://frontend/antd/progress/progress.tsx) +- [result.tsx](file://frontend/antd/result/result.tsx) +- [skeleton.tsx](file://frontend/antd/skeleton/skeleton.tsx) +- [spin.tsx](file://frontend/antd/spin/spin.tsx) +- [watermark.tsx](file://frontend/antd/watermark/watermark.tsx) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [useTargets.ts](file://frontend/utils/hooks/useTargets.ts) +- [renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically covers the frontend wrappers and usage of Ant Design feedback components, including: Alert, Drawer, Message, Modal, Notification, Popconfirm, Progress, Result, Skeleton, Spin, and Watermark. It focuses on each component's trigger mechanism, display timing, interaction logic, animation and transition state management, error and exception handling strategies, accessibility and keyboard operation support, as well as feedback design patterns for complex interaction scenarios. + +## Project Structure + +All feedback components reside in the frontend directory and follow a unified wrapping pattern: bridging native Ant Design components to Svelte-style components via `sveltify`; implementing slot-based rendering via ReactSlot and renderParamsSlot; and ensuring correct propagation and ordering of callbacks and slot targets through utility hooks such as useFunction and useTargets. + +```mermaid +graph TB +subgraph "Ant Design Feedback Components" +A1["Alert
frontend/antd/alert/alert.tsx"] +A2["Drawer
frontend/antd/drawer/drawer.tsx"] +A3["Message
frontend/antd/message/message.tsx"] +A4["Modal
frontend/antd/modal/modal.tsx"] +A5["Notification
frontend/antd/notification/notification.tsx"] +A6["Popconfirm
frontend/antd/popconfirm/popconfirm.tsx"] +A7["Progress
frontend/antd/progress/progress.tsx"] +A8["Result
frontend/antd/result/result.tsx"] +A9["Skeleton
frontend/antd/skeleton/skeleton.tsx"] +A10["Spin
frontend/antd/spin/spin.tsx"] +A11["Watermark
frontend/antd/watermark/watermark.tsx"] +end +subgraph "Utilities and Hooks" +U1["useFunction
frontend/utils/hooks/useFunction.ts"] +U2["useTargets
frontend/utils/hooks/useTargets.ts"] +U3["renderParamsSlot
frontend/utils/renderParamsSlot.tsx"] +end +A1 --> U1 +A2 --> U1 +A3 --> U1 +A4 --> U1 +A5 --> U1 +A6 --> U1 +A7 --> U1 +A8 --> U2 +A9 --> U1 +A10 --> U2 +A11 --> U1 +A2 --> U3 +A4 --> U3 +``` + +Diagram sources + +- [alert.tsx:1-46](file://frontend/antd/alert/alert.tsx#L1-L46) +- [drawer.tsx:1-60](file://frontend/antd/drawer/drawer.tsx#L1-L60) +- [message.tsx:1-79](file://frontend/antd/message/message.tsx#L1-L79) +- [modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) +- [notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [popconfirm.tsx:1-65](file://frontend/antd/popconfirm/popconfirm.tsx#L1-L65) +- [progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) +- [skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +Section sources + +- [alert.tsx:1-46](file://frontend/antd/alert/alert.tsx#L1-L46) +- [drawer.tsx:1-60](file://frontend/antd/drawer/drawer.tsx#L1-L60) +- [message.tsx:1-79](file://frontend/antd/message/message.tsx#L1-L79) +- [modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) +- [notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) +- [popconfirm.tsx:1-65](file://frontend/antd/popconfirm/popconfirm.tsx#L1-L65) +- [progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) +- [skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +## Core Components + +- Unified wrapping: All feedback components wrap native Ant Design components via `sveltify`, preserving their APIs while extending slot capabilities. +- Slot system: ReactSlot renders named slots (e.g., title, description, icon, footer), with some components supporting parameterized slot rendering (renderParamsSlot). +- Callback adaptation: useFunction wraps incoming functions as stable references, avoiding side effects or duplicate subscriptions caused by re-rendering. +- Target selection: useTargets extracts deliverable target nodes from children, supporting complex layouts and conditional rendering. +- Context holder: Message/Notification obtain context holders via useMessage/useNotification, enabling mounting and destruction of global messages and notifications. + +Section sources + +- [alert.tsx:7-43](file://frontend/antd/alert/alert.tsx#L7-L43) +- [drawer.tsx:14-57](file://frontend/antd/drawer/drawer.tsx#L14-L57) +- [message.tsx:9-76](file://frontend/antd/message/message.tsx#L9-L76) +- [modal.tsx:8-104](file://frontend/antd/modal/modal.tsx#L8-L104) +- [notification.tsx:8-103](file://frontend/antd/notification/notification.tsx#L8-L103) +- [popconfirm.tsx:7-62](file://frontend/antd/popconfirm/popconfirm.tsx#L7-L62) +- [progress.tsx:5-21](file://frontend/antd/progress/progress.tsx#L5-L21) +- [result.tsx:7-30](file://frontend/antd/result/result.tsx#L7-L30) +- [skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [spin.tsx:7-35](file://frontend/antd/spin/spin.tsx#L7-L35) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [renderParamsSlot.tsx:5-50](file://frontend/utils/renderParamsSlot.tsx#L5-L50) + +## Architecture Overview + +The runtime architecture of feedback components revolves around "prop passthrough + slot rendering + callback adaptation". For components that need global mounting (Message/Notification), context holders are obtained via useMessage/useNotification and injected into the DOM upon component mount. For container-type components (Drawer/Modal), the mount target is determined via getContainer or a string selector. For content-type components (Alert/Result/Spin), slots control the title, description, icon, extra content, and more. + +```mermaid +graph TB +C["Application-layer Component"] --> F1["useFunction
Stable Function Reference"] +C --> F2["useTargets
Resolve Slot Targets"] +C --> F3["renderParamsSlot
Parameterized Slot Rendering"] +subgraph "Global Feedback" +M["Message
useMessage"] --> D1["DOM Mount Point"] +N["Notification
useNotification"] --> D2["DOM Mount Point"] +end +subgraph "Container Feedback" +DR["Drawer"] --> G1["getContainer / String"] +MD["Modal"] --> G2["getContainer / String"] +end +subgraph "Content Feedback" +AL["Alert"] +RS["Result"] +SP["Spin"] +end +``` + +Diagram sources + +- [message.tsx:30-33](file://frontend/antd/message/message.tsx#L30-L33) +- [notification.tsx:31-36](file://frontend/antd/notification/notification.tsx#L31-L36) +- [drawer.tsx:52-54](file://frontend/antd/drawer/drawer.tsx#L52-L54) +- [modal.tsx:96-98](file://frontend/antd/modal/modal.tsx#L96-L98) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [renderParamsSlot.tsx:5-50](file://frontend/utils/renderParamsSlot.tsx#L5-L50) + +## Component Details + +### Alert + +- Trigger mechanism: Triggered by business state changes or user actions; can be closed via `closable`, which fires the `afterClose` callback. +- Display timing: Shown or hidden based on the data source after page initialization; supports dynamic switching of message/description/icon/action slots. +- Interaction logic: Clicking the close button triggers an animated collapse; the `afterClose` callback can be used for resource cleanup or navigation. +- Animation & transitions: Built-in Ant Design animations; slots allow custom icons and action buttons. +- Error handling: Falls back to prop-provided content when slot content is empty; releases resources after closing. +- Accessibility & keyboard: Follows Ant Design default accessibility; it is recommended to provide explicit ARIA labels for the close button. + +Section sources + +- [alert.tsx:7-43](file://frontend/antd/alert/alert.tsx#L7-L43) + +### Drawer + +- Trigger mechanism: Triggered by a button click or route change via `visible`; supports `afterOpenChange` to manage state after opening/closing. +- Display timing: Animates in on first open; animates out on close. +- Interaction logic: Supports custom `closeIcon`, `extra`, `footer`, `title`; `closable.closeIcon` can replace the default close icon. +- Animation & transitions: Controlled by Ant Design's slide-in/slide-out animation; `drawerRender` supports custom rendering logic. +- Error handling: When `getContainer` is a string, it is wrapped via `useFunction`; falls back to the default container on exception. +- Accessibility & keyboard: Maintains native focus order; it is recommended to provide explicit action buttons in the footer. + +Section sources + +- [drawer.tsx:8-57](file://frontend/antd/drawer/drawer.tsx#L8-L57) + +### Message + +- Trigger mechanism: Controlled by the `visible` prop; internally uses `messageApi.open` to open the message. +- Display timing: An effect watches for `visible=true` to open the message; `onClose` is triggered when the `duration` expires or the message is manually closed. +- Interaction logic: `onVisible(false)` and `onClose` are synchronized callbacks; supports deduplication via `key` and `destroy`. +- Animation & transitions: Built-in Ant Design animations; content/icon slots can customize content and icons. +- Error handling: The effect cleanup phase calls `destroy`; ensures the message is only opened once on exception. +- Accessibility & keyboard: Automatically mounted to the context holder; it is recommended to provide readable text and concise descriptions. + +Section sources + +- [message.tsx:19-76](file://frontend/antd/message/message.tsx#L19-L76) + +### Modal + +- Trigger mechanism: `visible` controls display; `afterOpenChange`/`afterClose` manage lifecycle after opening/closing. +- Display timing: Animates in on first open; animates out on close. +- Interaction logic: ok/cancel text and icons can all be customized via slots; `footer` supports a function or a default value. +- Animation & transitions: Built-in Ant Design animations; `modalRender` supports custom rendering. +- Error handling: When `getContainer` is a string, it is wrapped as a function; when `footer` equals `DEFAULT_FOOTER`, it falls back to `undefined`. +- Accessibility & keyboard: Maintains default focus and ESC closing; it is recommended to provide clear confirm/cancel semantics. + +Section sources + +- [modal.tsx:22-104](file://frontend/antd/modal/modal.tsx#L22-L104) + +### Notification + +- Trigger mechanism: `visible` controls display; `open`/`destroy` returned by `useNotification` control the message lifecycle. +- Display timing: An effect watches for `visible=true` to open; `onClose` is triggered when `duration` expires or the notification is manually closed. +- Interaction logic: `onVisible(false)`/`onClose` are synchronized callbacks; supports `placement`, `stack`, `top`/`bottom` positioning. +- Animation & transitions: Built-in Ant Design animations; supports description/icon/actions/btn slots. +- Error handling: The effect cleanup phase calls `destroy`; ensures the notification is only opened once on exception. +- Accessibility & keyboard: It is recommended to provide readable titles and descriptions; supports hover-to-pause and progress bar. + +Section sources + +- [notification.tsx:18-103](file://frontend/antd/notification/notification.tsx#L18-L103) + +### Popconfirm + +- Trigger mechanism: A user click triggers the bubble popup; `afterOpenChange` manages the popup open state. +- Display timing: Pops up immediately after clicking the target element; closes after confirm/cancel. +- Interaction logic: ok/cancel text and icons can all be customized via slots; title/description supports clone rendering. +- Animation & transitions: Bubble animation controlled by Ant Design; `getPopupContainer` supports specifying a mount container. +- Error handling: Falls back to props when slot content is empty; keeps interaction available on exception. +- Accessibility & keyboard: Maintains default focus and ESC closing; it is recommended to provide clear confirm/cancel semantics. + +Section sources + +- [popconfirm.tsx:7-62](file://frontend/antd/popconfirm/popconfirm.tsx#L7-L62) + +### Progress + +- Trigger mechanism: Value changes drive progress updates; `format` and `rounding` support custom formatting. +- Display timing: Value changes are reflected immediately; supports both static and dynamic modes. +- Interaction logic: `format` and `rounding` are wrapped as stable references via `useFunction`. +- Animation & transitions: Built-in Ant Design animations; supports percentage, status, and custom text. +- Error handling: Out-of-bounds values are handled by Ant Design; keeps the component stable on exception. +- Accessibility & keyboard: No interactive input; it is recommended to provide readable text. + +Section sources + +- [progress.tsx:5-21](file://frontend/antd/progress/progress.tsx#L5-L21) + +### Result + +- Trigger mechanism: Displayed after a business operation completes; supports title/subTitle/icon/extra slots. +- Display timing: Rendered immediately once data is ready; children serve as additional content. +- Interaction logic: useTargets resolves slot targets; falls back to children when no slots are provided. +- Animation & transitions: Built-in Ant Design animations; supports multiple status icons and text. +- Error handling: Falls back to props when slot content is empty; keeps content visible on exception. +- Accessibility & keyboard: It is recommended to provide readable titles and descriptions. + +Section sources + +- [result.tsx:7-30](file://frontend/antd/result/result.tsx#L7-L30) + +### Skeleton + +- Trigger mechanism: Displays a skeleton before data loads; switches to real content once loading is complete. +- Display timing: Shown immediately on component mount; switches automatically when real content is ready. +- Interaction logic: No interaction; supports animation and shape configuration. +- Animation & transitions: Built-in Ant Design skeleton animation. +- Error handling: Keeps the skeleton stable on exception; it is recommended to provide a timeout fallback. +- Accessibility & keyboard: No interaction; it is recommended to provide ARIA hints for the loading state. + +Section sources + +- [skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) + +### Spin + +- Trigger mechanism: Shown when an async task starts; hidden when the task ends. +- Display timing: Shown immediately on component mount; wraps real content when children are empty. +- Interaction logic: useTargets resolves slot targets; tip/indicator supports slots. +- Animation & transitions: Built-in Ant Design spinning animation; supports custom indicator and tip text. +- Error handling: Falls back to props when slot content is empty; keeps the loading state on exception. +- Accessibility & keyboard: It is recommended to provide an ARIA label and loading state hint. + +Section sources + +- [spin.tsx:7-35](file://frontend/antd/spin/spin.tsx#L7-L35) + +### Watermark + +- Trigger mechanism: Watermark is generated after page load; supports dynamic updates to text and size. +- Display timing: Takes effect immediately on component mount; suitable for full-screen or localized watermarks. +- Interaction logic: No interaction; supports multi-line text and opacity configuration. +- Animation & transitions: No animation; suitable as a background decoration. +- Error handling: Keeps the watermark stable on exception; it is recommended to provide a fallback solution. +- Accessibility & keyboard: No interaction; does not affect accessibility. + +Section sources + +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) + +## Dependency Analysis + +- Inter-component coupling: Feedback components are independent of one another, sharing only utility hooks. Container-type components share getContainer and renderParamsSlot; global-type components share the context holder. +- External dependencies: Native Ant Design components and styles; React Slot rendering; Svelte Preprocess React bridge. +- Circular dependencies: No circular dependencies found; utility hooks are pure functional wrappers. +- Interface contracts: All components maintain compatibility with the Ant Design API via `sveltify`; slot key names and rendering strategies are consistent. + +```mermaid +graph LR +subgraph "Utility Layer" +UF["useFunction"] +UT["useTargets"] +RPS["renderParamsSlot"] +end +subgraph "Feedback Components" +MSG["Message"] +NOTI["Notification"] +MOD["Modal"] +DRW["Drawer"] +ALERT["Alert"] +POP["Popconfirm"] +PROG["Progress"] +RES["Result"] +SKEL["Skeleton"] +SPIN["Spin"] +WM["Watermark"] +end +UF --> MSG +UF --> NOTI +UF --> MOD +UF --> DRW +UF --> ALERT +UF --> POP +UF --> PROG +UT --> RES +UT --> SPIN +RPS --> MOD +RPS --> DRW +``` + +Diagram sources + +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [renderParamsSlot.tsx:5-50](file://frontend/utils/renderParamsSlot.tsx#L5-L50) +- [message.tsx:29-33](file://frontend/antd/message/message.tsx#L29-L33) +- [notification.tsx:31-36](file://frontend/antd/notification/notification.tsx#L31-L36) +- [modal.tsx:34-35](file://frontend/antd/modal/modal.tsx#L34-L35) +- [drawer.tsx:27-28](file://frontend/antd/drawer/drawer.tsx#L27-L28) +- [alert.tsx:13-20](file://frontend/antd/alert/alert.tsx#L13-L20) +- [popconfirm.tsx:18-20](file://frontend/antd/popconfirm/popconfirm.tsx#L18-L20) +- [progress.tsx:10-12](file://frontend/antd/progress/progress.tsx#L10-L12) +- [result.tsx:11-12](file://frontend/antd/result/result.tsx#L11-L12) +- [spin.tsx:13-14](file://frontend/antd/spin/spin.tsx#L13-L14) + +Section sources + +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [renderParamsSlot.tsx:5-50](file://frontend/utils/renderParamsSlot.tsx#L5-L50) +- [message.tsx:29-33](file://frontend/antd/message/message.tsx#L29-L33) +- [notification.tsx:31-36](file://frontend/antd/notification/notification.tsx#L31-L36) +- [modal.tsx:34-35](file://frontend/antd/modal/modal.tsx#L34-L35) +- [drawer.tsx:27-28](file://frontend/antd/drawer/drawer.tsx#L27-L28) +- [alert.tsx:13-20](file://frontend/antd/alert/alert.tsx#L13-L20) +- [popconfirm.tsx:18-20](file://frontend/antd/popconfirm/popconfirm.tsx#L18-L20) +- [progress.tsx:10-12](file://frontend/antd/progress/progress.tsx#L10-L12) +- [result.tsx:11-12](file://frontend/antd/result/result.tsx#L11-L12) +- [spin.tsx:13-14](file://frontend/antd/spin/spin.tsx#L13-L14) + +## Performance Considerations + +- Stable function references: useFunction wraps callbacks as useMemo references, reducing unnecessary re-renders and side effects. +- Slot rendering optimization: ReactSlot and renderParamsSlot clone and render only when necessary, avoiding full re-layouts. +- Lifecycle management: Message/Notification proactively call `destroy` in the effect cleanup phase to prevent memory leaks. +- Container mounting: When `getContainer` for Drawer/Modal is a string, a wrapper function is used to avoid repeated bindings. +- Conditional rendering: Spin/Result use useTargets and conditional branches to render real content only when slots are present, reducing DOM overhead. + +## Troubleshooting Guide + +- Slots not working + - Check that slot key names match the component declarations; confirm that ReactSlot is correctly wrapping them. + - Reference paths: [alert.tsx:17-40](file://frontend/antd/alert/alert.tsx#L17-L40), [result.tsx:17-27](file://frontend/antd/result/result.tsx#L17-L27), [spin.tsx:20-32](file://frontend/antd/spin/spin.tsx#L20-L32) +- Callbacks not fired or firing repeatedly + - Use useFunction to wrap callbacks to ensure stable references; check the effect dependency array. + - Reference paths: [message.tsx:35-68](file://frontend/antd/message/message.tsx#L35-L68), [notification.tsx:38-95](file://frontend/antd/notification/notification.tsx#L38-L95) +- Global message not displayed + - Confirm the context holder has been rendered; verify that `visible` and `key` are configured correctly; set a reasonable `duration`. + - Reference paths: [message.tsx:30-33](file://frontend/antd/message/message.tsx#L30-L33), [notification.tsx:31-36](file://frontend/antd/notification/notification.tsx#L31-L36) +- Container mount exception + - When `getContainer` is a string, ensure it is wrapped as a function; check selector validity. + - Reference paths: [drawer.tsx:52-54](file://frontend/antd/drawer/drawer.tsx#L52-L54), [modal.tsx:96-98](file://frontend/antd/modal/modal.tsx#L96-L98) +- Animation stuttering or flickering + - Check if slot content is changing frequently; avoid heavy DOM operations during animations. + - Reference paths: [progress.tsx:10-12](file://frontend/antd/progress/progress.tsx#L10-L12), [spin.tsx:13-14](file://frontend/antd/spin/spin.tsx#L13-L14) + +Section sources + +- [alert.tsx:17-40](file://frontend/antd/alert/alert.tsx#L17-L40) +- [result.tsx:17-27](file://frontend/antd/result/result.tsx#L17-L27) +- [spin.tsx:20-32](file://frontend/antd/spin/spin.tsx#L20-L32) +- [message.tsx:30-33](file://frontend/antd/message/message.tsx#L30-L33) +- [notification.tsx:31-36](file://frontend/antd/notification/notification.tsx#L31-L36) +- [drawer.tsx:52-54](file://frontend/antd/drawer/drawer.tsx#L52-L54) +- [modal.tsx:96-98](file://frontend/antd/modal/modal.tsx#L96-L98) +- [progress.tsx:10-12](file://frontend/antd/progress/progress.tsx#L10-L12) + +## Conclusion + +This repository provides a systematic wrapper for Ant Design feedback components, unifying slot rendering, callback adaptation, and lifecycle management. Through stable function references, conditional rendering, and context holders, it achieves a highly available and maintainable feedback system. It is recommended to select the appropriate component and trigger strategy based on your business scenario in practice, and to pay attention to accessibility and performance details. + +## Appendix + +- Best practices + - Use `visible` and `key` to manage the uniqueness and lifecycle of global messages. + - Provide clear confirm/cancel semantics and keyboard support for important operations. + - In complex layouts, prefer renderParamsSlot and useTargets to manage slot targets. + - Provide clear text and visual cues for loading states and error states. +- Complex interaction scenarios + - Multi-step flows: Use Result to display the final state; Progress to show progress; Spin to wrap critical areas. + - Global notifications: Place Notification in the top-right or bottom-right corner, supporting stacking and pause-on-hover. + - Modal confirmation: Use Modal/Popconfirm for critical deletions and dangerous operations to provide a second confirmation. + - Drawer navigation: Use Drawer as a secondary panel for long lists or settings pages; pay attention to getContainer and z-index management. diff --git a/.wiki/en/Ant Design Components/Feedback Components/Interactive Feedback.md b/.wiki/en/Ant Design Components/Feedback Components/Interactive Feedback.md new file mode 100644 index 00000000..a711d684 --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Interactive Feedback.md @@ -0,0 +1,301 @@ +# Interactive Feedback + + +**Files referenced in this document** +- [frontend/antd/popconfirm/popconfirm.tsx](file://frontend/antd/popconfirm/popconfirm.tsx) +- [frontend/antd/popover/popover.tsx](file://frontend/antd/popover/popover.tsx) +- [frontend/antd/popconfirm/Index.svelte](file://frontend/antd/popconfirm/Index.svelte) +- [frontend/antd/popover/Index.svelte](file://frontend/antd/popover/Index.svelte) +- [backend/modelscope_studio/components/antd/popconfirm/__init__.py](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py) +- [backend/modelscope_studio/components/antd/popover/__init__.py](file://backend/modelscope_studio/components/antd/popover/__init__.py) +- [docs/components/antd/popconfirm/README-zh_CN.md](file://docs/components/antd/popconfirm/README-zh_CN.md) +- [docs/components/antd/popover/README-zh_CN.md](file://docs/components/antd/popover/README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on two types of components in the interactive feedback component group: Popconfirm (Bubble Confirmation) and Popover (Bubble Card). It provides a systematic explanation from design philosophy, interaction patterns, confirmation flow, content delivery, trigger and positioning strategies, props and events, style customization, and common use cases, along with source-traceable reference paths to help developers quickly understand and correctly use these components. + +## Project Structure + +These two components use a "Svelte wrapper layer + React component library bridge" pattern on the frontend, with the backend exposing a Python API through Gradio component wrapping. Their organization is as follows: + +- Frontend layer: Svelte components handle prop passthrough, slot rendering, and event mapping; the TypeScript bridge layer adapts Ant Design's React components for use in Svelte. +- Backend layer: Python component classes define props, events, slots, and default values, and declare frontend directory mappings so the runtime can load the corresponding frontend components. + +```mermaid +graph TB +subgraph "Frontend" +IDX_PCF["Index.svelte
popconfirm"] --> BRG_PCF["popconfirm.tsx
Bridge Layer"] +IDX_POV["Index.svelte
popover"] --> BRG_POV["popover.tsx
Bridge Layer"] +end +subgraph "Backend" +PY_PCF["AntdPopconfirm
Python Component"] --> FE_DIR_PCF["resolve_frontend_dir('popconfirm')"] +PY_POV["AntdPopover
Python Component"] --> FE_DIR_POV["resolve_frontend_dir('popover')"] +end +BRG_PCF --> ANT_PCF["Ant Design Popconfirm"] +BRG_POV --> ANT_POV["Ant Design Popover"] +PY_PCF --> IDX_PCF +PY_POV --> IDX_POV +``` + +Diagram sources + +- [frontend/antd/popconfirm/Index.svelte:1-76](file://frontend/antd/popconfirm/Index.svelte#L1-L76) +- [frontend/antd/popover/Index.svelte:1-76](file://frontend/antd/popover/Index.svelte#L1-L76) +- [frontend/antd/popconfirm/popconfirm.tsx:1-65](file://frontend/antd/popconfirm/popconfirm.tsx#L1-L65) +- [frontend/antd/popover/popover.tsx:1-37](file://frontend/antd/popover/popover.tsx#L1-L37) +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:138-138](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L138-L138) +- [backend/modelscope_studio/components/antd/popover/**init**.py:106-106](file://backend/modelscope_studio/components/antd/popover/__init__.py#L106-L106) + +Section sources + +- [frontend/antd/popconfirm/Index.svelte:1-76](file://frontend/antd/popconfirm/Index.svelte#L1-L76) +- [frontend/antd/popover/Index.svelte:1-76](file://frontend/antd/popover/Index.svelte#L1-L76) +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:138-138](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L138-L138) +- [backend/modelscope_studio/components/antd/popover/**init**.py:106-106](file://backend/modelscope_studio/components/antd/popover/__init__.py#L106-L106) + +## Core Components + +- Popconfirm + - Design philosophy: Provides a second confirmation for dangerous or irreversible operations to reduce accidental operation risk. + - Key interactions: Supports hover/focus/click/contextMenu triggers; provides confirm/cancel dual buttons with text/icon slots. + - Confirmation flow: Clicking confirm fires the callback; cancel closes the popup; supports controlled `open` state and controlled event callbacks. +- Popover + - Design philosophy: Provides contextual information hints or lightweight action entry points for target elements without changing the page layout. + - Key interactions: Supports hover/focus/click/contextMenu triggers; title and content can be slotted, with automatic collision avoidance and positioning. + +Section sources + +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:10-27](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L10-L27) +- [backend/modelscope_studio/components/antd/popover/**init**.py:10-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L18) + +## Architecture Overview + +The following diagram shows the call chain and data flow from the frontend Svelte to the backend Python component. + +```mermaid +sequenceDiagram +participant Py as "Python Component
AntdPopconfirm/AntdPopover" +participant Idx as "Svelte Wrapper Layer
Index.svelte" +participant Br as "Bridge Layer
popconfirm.tsx / popover.tsx" +participant AD as "Ant Design Component" +Py->>Idx : "Instantiate and pass props/events/slots" +Idx->>Br : "Render bridge component, pass through props and slots" +Br->>AD : "Call Ant Design component, inject events and container" +AD-->>Br : "State change (openChange)" +Br-->>Idx : "Callback fired" +Idx-->>Py : "Event report (e.g., open_change/popup_click)" +``` + +Diagram sources + +- [frontend/antd/popconfirm/Index.svelte:24-55](file://frontend/antd/popconfirm/Index.svelte#L24-L55) +- [frontend/antd/popover/Index.svelte:24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- [frontend/antd/popconfirm/popconfirm.tsx:17-62](file://frontend/antd/popconfirm/popconfirm.tsx#L17-L62) +- [frontend/antd/popover/popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:14-27](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L14-L27) +- [backend/modelscope_studio/components/antd/popover/**init**.py:14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) + +## Detailed Component Analysis + +### Popconfirm + +- Design philosophy and interaction pattern + - Targeting "high-risk operations", reduces accidental trigger cost through a second confirmation. + - Supports multiple trigger modes; the popup provides confirm/cancel buttons with an optional icon. +- Props and events + - Key props: title, description, confirm text/button props, cancel text/button props, trigger type, positioning and collision avoidance, container mount point, delay, z-index, etc. + - Key events: open_change, cancel, confirm, popup_click. + - Key slots: title, description, okText, okButtonProps.icon, cancelText, cancelButtonProps.icon. +- Callbacks and state + - Get open/close state changes via `afterOpenChange`. + - Customize the mount container via `getPopupContainer` for positioning and z-index control in complex layouts. +- Use cases + - Delete confirmation, edit confirmation, batch operation confirmation, etc. + +```mermaid +flowchart TD +Start(["User trigger"]) --> Trigger{"Trigger type"} +Trigger --> |click/hover/focus/contextMenu| Open["Open confirmation popup"] +Open --> Action{"User choice"} +Action --> |Confirm| Confirm["Fire confirm callback"] +Action --> |Cancel| Cancel["Fire cancel callback"] +Confirm --> Close["Close popup"] +Cancel --> Close +Close --> End(["End"]) +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:14-27](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L14-L27) +- [frontend/antd/popconfirm/popconfirm.tsx:17-62](file://frontend/antd/popconfirm/popconfirm.tsx#L17-L62) + +Section sources + +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:10-137](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L10-L137) +- [frontend/antd/popconfirm/popconfirm.tsx:7-62](file://frontend/antd/popconfirm/popconfirm.tsx#L7-L62) +- [frontend/antd/popconfirm/Index.svelte:24-75](file://frontend/antd/popconfirm/Index.svelte#L24-L75) + +### Popover + +- Design philosophy and interaction pattern + - Provides non-intrusive information display and lightweight action entry points. + - Supports title and content slots, with automatic collision avoidance and multi-directional positioning. +- Props and events + - Key props: title, content, trigger type, placement, arrow, color, container mount point, delay, z-index, etc. + - Key events: open_change. + - Key slots: title, content. +- Use cases + - Information hints, action menus, supplementary explanations, etc. + +```mermaid +sequenceDiagram +participant U as "User" +participant P as "Popover" +participant C as "Content Slot" +participant D as "Positioning and Collision Avoidance" +U->>P : "Trigger (click/hover/focus/right-click)" +P->>D : "Calculate optimal position and collision avoidance" +P->>C : "Render title/content slots" +P-->>U : "Display floating layer" +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/popover/**init**.py:14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) +- [frontend/antd/popover/popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) + +Section sources + +- [backend/modelscope_studio/components/antd/popover/**init**.py:10-104](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L104) +- [frontend/antd/popover/popover.tsx:7-34](file://frontend/antd/popover/popover.tsx#L7-L34) +- [frontend/antd/popover/Index.svelte:24-72](file://frontend/antd/popover/Index.svelte#L24-L72) + +### Component Classes and Bridge Layer Relationships + +```mermaid +classDiagram +class AntdPopconfirm { ++EVENTS ++SLOTS ++props and methods... +} +class PopconfirmBridge { ++slots : title, description, okText, okButtonProps.icon, cancelText, cancelButtonProps.icon ++afterOpenChange() ++getPopupContainer() +} +class AntdPopover { ++EVENTS ++SLOTS ++props and methods... +} +class PopoverBridge { ++slots : title, content ++afterOpenChange() ++getPopupContainer() +} +AntdPopconfirm --> PopconfirmBridge : "Instantiate and render" +AntdPopover --> PopoverBridge : "Instantiate and render" +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:10-37](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L10-L37) +- [frontend/antd/popconfirm/popconfirm.tsx:7-17](file://frontend/antd/popconfirm/popconfirm.tsx#L7-L17) +- [backend/modelscope_studio/components/antd/popover/**init**.py:10-21](file://backend/modelscope_studio/components/antd/popover/__init__.py#L10-L21) +- [frontend/antd/popover/popover.tsx:7-12](file://frontend/antd/popover/popover.tsx#L7-L12) + +## Dependency Analysis + +- Frontend dependencies + - The Svelte wrapper layer depends on the bridge layer; the bridge layer depends on the Ant Design React component library. + - Events and slots are passed across frameworks through function wrapping and ReactSlot rendering. +- Backend dependencies + - Python component classes map the component name to the frontend directory via resolve_frontend_dir, ensuring the runtime can load it. +- Coupling and cohesion + - Component responsibilities are clear: Python handles prop/event/slot definitions, Svelte handles prop passthrough and event mapping, and the TS bridge layer handles slot rendering and callback wrapping. + +```mermaid +graph LR +PY_PCF["Python: AntdPopconfirm"] --> IDX_PCF["Svelte: popconfirm/Index.svelte"] +IDX_PCF --> BRG_PCF["TS: popconfirm.tsx"] +BRG_PCF --> AD_PCF["Ant Design Popconfirm"] +PY_POV["Python: AntdPopover"] --> IDX_POV["Svelte: popover/Index.svelte"] +IDX_POV --> BRG_POV["TS: popover.tsx"] +BRG_POV --> AD_POV["Ant Design Popover"] +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:138-138](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L138-L138) +- [frontend/antd/popconfirm/Index.svelte:10-10](file://frontend/antd/popconfirm/Index.svelte#L10-L10) +- [frontend/antd/popconfirm/popconfirm.tsx:1-5](file://frontend/antd/popconfirm/popconfirm.tsx#L1-L5) +- [backend/modelscope_studio/components/antd/popover/**init**.py:106-106](file://backend/modelscope_studio/components/antd/popover/__init__.py#L106-L106) +- [frontend/antd/popover/Index.svelte:10-10](file://frontend/antd/popover/Index.svelte#L10-L10) +- [frontend/antd/popover/popover.tsx:1-5](file://frontend/antd/popover/popover.tsx#L1-L5) + +Section sources + +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:138-138](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L138-L138) +- [backend/modelscope_studio/components/antd/popover/**init**.py:106-106](file://backend/modelscope_studio/components/antd/popover/__init__.py#L106-L106) +- [frontend/antd/popconfirm/Index.svelte:10-10](file://frontend/antd/popconfirm/Index.svelte#L10-L10) +- [frontend/antd/popover/Index.svelte:10-10](file://frontend/antd/popover/Index.svelte#L10-L10) +- [frontend/antd/popconfirm/popconfirm.tsx:1-5](file://frontend/antd/popconfirm/popconfirm.tsx#L1-L5) +- [frontend/antd/popover/popover.tsx:1-5](file://frontend/antd/popover/popover.tsx#L1-L5) + +## Performance Considerations + +- Lazy loading and lazy rendering + - The Svelte wrapper layer uses dynamic component imports to avoid an oversized initial bundle. +- Slot rendering optimization + - Slot content is rendered only when needed, reducing unnecessary virtual DOM updates. +- Container mounting and z-index management + - Mount the popup to an appropriate container via `getPopupContainer` to avoid z-index conflicts and reflows. +- Delay and destruction strategy + - Set appropriate mouse enter/leave delays to avoid frequent flickering; choose hide-then-destroy strategy based on the scenario to save memory. + +## Troubleshooting Guide + +- Cannot open/close + - Check that the trigger type and `open` state are consistent; confirm `open_change` event is correctly bound. + - Reference paths: [frontend/antd/popconfirm/Index.svelte:24-55](file://frontend/antd/popconfirm/Index.svelte#L24-L55), [frontend/antd/popover/Index.svelte:24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- Content not displayed or misaligned + - Confirm slot names and rendering logic; check if getPopupContainer returns a valid container. + - Reference paths: [frontend/antd/popconfirm/popconfirm.tsx:17-62](file://frontend/antd/popconfirm/popconfirm.tsx#L17-L62), [frontend/antd/popover/popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) +- Events not fired + - Confirm backend event listeners match frontend event mapping; check that callback function wrapping is effective. + - Reference paths: [backend/modelscope_studio/components/antd/popconfirm/**init**.py:14-27](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L14-L27), [backend/modelscope_studio/components/antd/popover/**init**.py:14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) + +Section sources + +- [frontend/antd/popconfirm/Index.svelte:24-55](file://frontend/antd/popconfirm/Index.svelte#L24-L55) +- [frontend/antd/popover/Index.svelte:24-52](file://frontend/antd/popover/Index.svelte#L24-L52) +- [frontend/antd/popconfirm/popconfirm.tsx:17-62](file://frontend/antd/popconfirm/popconfirm.tsx#L17-L62) +- [frontend/antd/popover/popover.tsx:10-34](file://frontend/antd/popover/popover.tsx#L10-L34) +- [backend/modelscope_studio/components/antd/popconfirm/**init**.py:14-27](file://backend/modelscope_studio/components/antd/popconfirm/__init__.py#L14-L27) +- [backend/modelscope_studio/components/antd/popover/**init**.py:14-18](file://backend/modelscope_studio/components/antd/popover/__init__.py#L14-L18) + +## Conclusion + +Popconfirm and Popover are implemented in this project through a unified architecture of "Python component + Svelte wrapper + TS bridge + Ant Design component", ensuring behavioral consistency with Ant Design while providing flexible slot and event extension capabilities. By making proper use of triggers, positioning, container mounting, and event callbacks, stable and user-friendly interaction experiences can be achieved in complex interfaces. + +## Appendix + +- Example entries + - Popconfirm example entry: [docs/components/antd/popconfirm/README-zh_CN.md:5-8](file://docs/components/antd/popconfirm/README-zh_CN.md#L5-L8) + - Popover example entry: [docs/components/antd/popover/README-zh_CN.md:5-8](file://docs/components/antd/popover/README-zh_CN.md#L5-L8) diff --git a/.wiki/en/Ant Design Components/Feedback Components/Message and Notification.md b/.wiki/en/Ant Design Components/Feedback Components/Message and Notification.md new file mode 100644 index 00000000..58757a54 --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Message and Notification.md @@ -0,0 +1,332 @@ +# Message and Notification + + +**Files referenced in this document** +- [frontend/antd/message/message.tsx](file://frontend/antd/message/message.tsx) +- [frontend/antd/notification/notification.tsx](file://frontend/antd/notification/notification.tsx) +- [frontend/antd/message/Index.svelte](file://frontend/antd/message/Index.svelte) +- [frontend/antd/notification/Index.svelte](file://frontend/antd/notification/Index.svelte) +- [backend/modelscope_studio/components/antd/message/__init__.py](file://backend/modelscope_studio/components/antd/message/__init__.py) +- [backend/modelscope_studio/components/antd/notification/__init__.py](file://backend/modelscope_studio/components/antd/notification/__init__.py) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/antd/message/package.json](file://frontend/antd/message/package.json) +- [frontend/antd/notification/package.json](file://frontend/antd/notification/package.json) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Memory Management](#performance-and-memory-management) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document systematically covers the message notification component group, focusing on two types of global feedback components: Message and Notification. It provides a complete explanation covering design philosophy, use cases, comparison of differences, configuration options and dynamic behavior, lifecycle and memory cleanup, accessibility and experience optimization, along with source-traceable path references to help developers get started quickly and use the components correctly. + +## Project Structure + +The message notification components are built from three layers: "backend Python component + frontend Svelte wrapper + React/antd implementation": + +- The backend component is responsible for parameter validation, event binding, rendering control, and frontend package export declarations. +- The frontend Svelte layer is responsible for prop passthrough, slot mapping, and visibility state synchronization. +- The React layer implements the specific message popup, stacking, and destruction logic based on the antd message/notification API. + +```mermaid +graph TB +subgraph "Backend" +PY_MSG["AntdMessage
Python Component"] +PY_NOTI["AntdNotification
Python Component"] +end +subgraph "Frontend Svelte" +SV_MSG["message/Index.svelte"] +SV_NOTI["notification/Index.svelte"] +end +subgraph "React/antd" +TSX_MSG["message.tsx
useMessage-driven"] +TSX_NOTI["notification.tsx
useNotification-driven"] +end +PY_MSG --> SV_MSG --> TSX_MSG +PY_NOTI --> SV_NOTI --> TSX_NOTI +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/message/**init**.py:10-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L10-L91) +- [backend/modelscope_studio/components/antd/notification/**init**.py:10-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L10-L109) +- [frontend/antd/message/Index.svelte:10-78](file://frontend/antd/message/Index.svelte#L10-L78) +- [frontend/antd/notification/Index.svelte:10-80](file://frontend/antd/notification/Index.svelte#L10-L80) +- [frontend/antd/message/message.tsx:9-79](file://frontend/antd/message/message.tsx#L9-L79) +- [frontend/antd/notification/notification.tsx:8-106](file://frontend/antd/notification/notification.tsx#L8-L106) + +Section sources + +- [frontend/antd/message/package.json:1-15](file://frontend/antd/message/package.json#L1-L15) +- [frontend/antd/notification/package.json:1-15](file://frontend/antd/notification/package.json#L1-L15) + +## Core Components + +- Message + - Design goal: Provide immediate, concise feedback for user actions, commonly used for submit success/failure, warning, or loading hints. + - Key features: Lightweight, no mask, auto-dismiss, configurable duration, key-based uniqueness and override control. +- Notification + - Design goal: Pop up richer content in a page corner, suitable for reminders that need to carry a title, description, buttons, actions, etc. + - Key features: Supports multiple placement positions (top/bottom/left/right), stacking management, progress bar, hover-to-pause, customizable buttons and actions. + +Section sources + +- [backend/modelscope_studio/components/antd/message/**init**.py:10-91](file://backend/modelscope_studio/components/antd/message/__init__.py#L10-L91) +- [backend/modelscope_studio/components/antd/notification/**init**.py:10-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L10-L109) + +## Architecture Overview + +The message component call chain is: backend component instantiation → frontend Svelte rendering → React/antd executes open/destroy → lifecycle callbacks trigger state propagation back. + +```mermaid +sequenceDiagram +participant Py as "Backend Component" +participant S as "Svelte Wrapper" +participant R as "React/antd" +participant UI as "Browser Interface" +Py->>S : Pass props and slots +S->>R : Pass through props and slots +R->>R : Initialize useMessage/useNotification +alt Visible and open +R->>UI : open({key, content, duration, ...}) +else Close or destroy +R->>UI : destroy(key) +end +UI-->>R : User interaction (click/close) +R-->>S : Fire onVisible(false) callback +S-->>Py : Update visible state +``` + +Diagram sources + +- [frontend/antd/message/message.tsx:30-68](file://frontend/antd/message/message.tsx#L30-L68) +- [frontend/antd/notification/notification.tsx:31-95](file://frontend/antd/notification/notification.tsx#L31-L95) +- [frontend/antd/message/Index.svelte:58-77](file://frontend/antd/message/Index.svelte#L58-L77) +- [frontend/antd/notification/Index.svelte:59-79](file://frontend/antd/notification/Index.svelte#L59-L79) + +## Detailed Component Analysis + +### Message Component + +- Responsibilities and behavior + - Provides global message capabilities based on antd's `message.useMessage`; + - Supports controlling visibility via `visible` and uniqueness via `messageKey`; + - Supports `slots.content` and `slots.icon` for custom content and icons; + - Fires `onVisible(false)` on close and destroys the corresponding key when the component unmounts. +- Key configuration options (excerpt) + - Content and type: content, type (success/info/warning/error/loading) + - Display duration: duration (seconds) + - Container mount point: getContainer (function) + - Text and styles: className, style, rootClassName + - Key and visibility: messageKey, visible +- Dynamic updates and batch operations + - Use messageKey to override and update the same message position; + - Multiple messages can coexist without interfering with each other; + - Use `destroy(key)` or `destroyAll()` for batch cleanup. +- Lifecycle and memory + - Registered on open; destroyed on close/unmount; avoids residual DOM and event listeners. + +```mermaid +flowchart TD +Start(["Enter Effect"]) --> CheckVisible{"visible is true?"} +CheckVisible -- No --> Destroy["destroy(key) and return"] +CheckVisible -- Yes --> Open["messageApi.open({...})"] +Open --> OnClose["onClose callback fires onVisible(false)"] +OnClose --> End(["End"]) +Destroy --> End +``` + +Diagram sources + +- [frontend/antd/message/message.tsx:35-68](file://frontend/antd/message/message.tsx#L35-L68) + +Section sources + +- [frontend/antd/message/message.tsx:9-79](file://frontend/antd/message/message.tsx#L9-L79) +- [frontend/antd/message/Index.svelte:19-77](file://frontend/antd/message/Index.svelte#L19-L77) +- [backend/modelscope_studio/components/antd/message/**init**.py:26-72](file://backend/modelscope_studio/components/antd/message/__init__.py#L26-L72) + +### Notification Component + +- Responsibilities and behavior + - Provides global notification capabilities based on antd's `notification.useNotification`; + - Supports multiple positions (top/bottom/left/right and combinations) and stacking management; + - Supports rich slots: slots.message/description/icon/actions/btn/closeIcon; + - Fires `onVisible(false)` on close and destroys the corresponding key on unmount. +- Key configuration options (excerpt) + - Position and stacking: placement, stack, top, bottom, rtl + - Content and interaction: message, description, btn, actions, closeIcon, icon + - Behavior and experience: duration, showProgress, pauseOnHover, role (alert/status) + - Key and visibility: notificationKey, visible +- Dynamic updates and batch operations + - Use notificationKey to override the same notification; + - Supports `destroyAll()` for batch cleanup; + - In stacking mode, controls the arrangement and override strategy for new and old notifications. +- Lifecycle and memory + - Registered on open; destroyed on close/unmount; avoids memory leaks. + +```mermaid +sequenceDiagram +participant S as "Svelte Wrapper" +participant R as "React/antd" +participant N as "notificationApi" +participant U as "User" +S->>R : visible=true and pass props +R->>N : open({key, message, description, actions, ...}) +U-->>N : Click/close +N-->>R : onClose callback +R-->>S : onVisible(false) +S-->>S : updateProps({visible : false}) +R->>N : destroy(key) or destroyAll() +``` + +Diagram sources + +- [frontend/antd/notification/notification.tsx:38-95](file://frontend/antd/notification/notification.tsx#L38-L95) +- [frontend/antd/notification/Index.svelte:59-79](file://frontend/antd/notification/Index.svelte#L59-L79) + +Section sources + +- [frontend/antd/notification/notification.tsx:8-106](file://frontend/antd/notification/notification.tsx#L8-L106) +- [frontend/antd/notification/Index.svelte:19-79](file://frontend/antd/notification/Index.svelte#L19-L79) +- [backend/modelscope_studio/components/antd/notification/**init**.py:26-90](file://backend/modelscope_studio/components/antd/notification/__init__.py#L26-L90) + +### Differences and Use Cases + +- Use cases + - Message: Lightweight feedback, short text hints, no need for complex interaction; + - Notification: Requires a title/description/buttons/actions, multiple position display, emphasizes important information. +- Display position and stacking + - Message: Appears at the top of the container or in a specified container by default; does not support multiple positions; + - Notification: Supports top/bottom/left/right and combinations, with stacking management and progress bar. +- Interaction and accessibility + - Notification: Supports `role` (alert/status) for screen reader identification; + - Message: More oriented toward one-time hints with minimal interaction. +- Dynamic and batch operations + - Both support key-based uniqueness and override; Notification makes it easier to implement batch cleanup and stacking strategies. + +Section sources + +- [backend/modelscope_studio/components/antd/message/**init**.py:26-72](file://backend/modelscope_studio/components/antd/message/__init__.py#L26-L72) +- [backend/modelscope_studio/components/antd/notification/**init**.py:26-90](file://backend/modelscope_studio/components/antd/notification/__init__.py#L26-L90) + +## Dependency Analysis + +- Component export and entry + - Both message and notification expose Gradio-compatible entry points via package.json; +- Frontend bridge + - The Svelte wrapper handles prop and slot passthrough, and writes back the `visible` state; + - The React layer safely injects functions like getContainer into the antd API via useFunction; +- Events and slots + - The backend declares click/close events; the Svelte side binds them via the `_internal` flag; + - Slot mapping: Message (content/icon), Notification (actions/btn/closeIcon/description/icon/message/title). + +```mermaid +graph LR +PkgMsg["message/package.json"] --> SMsg["message/Index.svelte"] +PkgNoti["notification/package.json"] --> SNoti["notification/Index.svelte"] +SMsg --> TMsg["message.tsx"] +SNoti --> TNoti["notification.tsx"] +TMsg --> Hook["useFunction.ts"] +TNoti --> Hook +``` + +Diagram sources + +- [frontend/antd/message/package.json:1-15](file://frontend/antd/message/package.json#L1-L15) +- [frontend/antd/notification/package.json:1-15](file://frontend/antd/notification/package.json#L1-L15) +- [frontend/antd/message/Index.svelte:10](file://frontend/antd/message/Index.svelte#L10) +- [frontend/antd/notification/Index.svelte:10](file://frontend/antd/notification/Index.svelte#L10) +- [frontend/antd/message/message.tsx:29](file://frontend/antd/message/message.tsx#L29) +- [frontend/antd/notification/notification.tsx:31](file://frontend/antd/notification/notification.tsx#L31) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) + +Section sources + +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) + +## Performance and Memory Management + +- Performance characteristics + - Message: Lightweight, no mask, small DOM count — suitable for high-frequency hints; + - Notification: Supports stacking and progress bar with stronger visual feedback, but DOM count may increase. +- Memory cleanup strategy + - Uniformly call `destroy(key)`/`destroyAll()` on close and unmount; + - Use key to precisely control resource reclamation, avoiding duplicate rendering and event accumulation; + - Use getContainer to mount messages to the minimum necessary container, reducing reflow and repaint. +- Best practices + - Set a unique key for each independent message; + - Set a reasonable `duration` to avoid too many messages persisting for too long; + - Use `destroyAll()` in batch operations to clean up expired messages; + - For frequently triggered operations, prefer Message; introduce Notification only when necessary. + +Section sources + +- [frontend/antd/message/message.tsx:51-58](file://frontend/antd/message/message.tsx#L51-L58) +- [frontend/antd/notification/notification.tsx:74-77](file://frontend/antd/notification/notification.tsx#L74-L77) + +## Troubleshooting Guide + +- Common issues + - Message not displayed: Check if `visible` is true and that `messageKey` is correctly passed in; + - Cannot be closed: Confirm the `onClose` callback has not been overridden; ensure the `onVisible` callback chain is functioning correctly; + - Duplicate messages: Set a unique key for each message to avoid being overridden by subsequent `open` calls; + - Position is wrong: Confirm the mount node returned by `getContainer` exists and is visible. +- Debugging steps + - Print props and visible state in the Svelte layer; + - Confirm messageApi/notificationApi has been initialized in the React layer; + - Use `destroyAll()` to quickly clear the slate and verify whether any DOM remains; + - Check that the getContainer function consistently returns the same node. + +Section sources + +- [frontend/antd/message/message.tsx:35-68](file://frontend/antd/message/message.tsx#L35-L68) +- [frontend/antd/notification/notification.tsx:38-95](file://frontend/antd/notification/notification.tsx#L38-L95) + +## Conclusion + +The message notification component group implements highly available and extensible global feedback capabilities through a layered design of "backend parameters + frontend bridge + React/antd driver". Message is suitable for lightweight hints; Notification is suitable for rich notifications. By applying reasonable key strategies, duration configuration, and destruction mechanisms, excellent performance and memory health can be maintained while ensuring a great user experience. + +## Appendix: Usage Examples and Best Practices + +- Success hint (Message) + - Set `type` to `success`, use an appropriate `duration`, and make `messageKey` unique; + - Toggle display via `visible`; synchronize visible state with `onClose`. + - Example path reference: [frontend/antd/message/message.tsx:35-50](file://frontend/antd/message/message.tsx#L35-L50) +- Error alert (Notification) + - Set `type` to `error`, enrich content with `message`/`description`, and provide operations via `actions`; + - Use `destroyAll()` to clean up historical error messages and prevent accumulation. + - Example path reference: [frontend/antd/notification/notification.tsx:38-69](file://frontend/antd/notification/notification.tsx#L38-L69) +- Info notification (Notification) + - Use `placement` to specify position (e.g., topRight); set `role` to `status`; + - Control stacking with `stack`; improve readability with `pauseOnHover`. + - Example path reference: [frontend/antd/notification/notification.tsx:31-36](file://frontend/antd/notification/notification.tsx#L31-L36) +- Manual close + - Proactively close via `onVisible(false)`, or call `destroy(key)` externally; + - Example path reference: [frontend/antd/message/message.tsx:46-50](file://frontend/antd/message/message.tsx#L46-L50), [frontend/antd/notification/notification.tsx:65-69](file://frontend/antd/notification/notification.tsx#L65-L69) +- Dynamic updates and batch operations + - Use `messageKey` to override an existing message; + - Use `destroyAll()` for batch cleanup to avoid memory leaks. + - Example path reference: [frontend/antd/message/message.tsx:51-58](file://frontend/antd/message/message.tsx#L51-L58), [frontend/antd/notification/notification.tsx:74-77](file://frontend/antd/notification/notification.tsx#L74-L77) + +Accessibility and experience optimization recommendations + +- Set `role` (alert/status) on Notification to improve accessibility; +- Set a reasonable `duration` to avoid interrupting user tasks; +- Provide clear feedback text and action buttons for key operations; +- In dark themes or high-contrast environments, ensure message colors and icons are clearly distinguishable. + +Section sources + +- [backend/modelscope_studio/components/antd/notification/**init**.py:40-44](file://backend/modelscope_studio/components/antd/notification/__init__.py#L40-L44) +- [frontend/antd/notification/notification.tsx:65-69](file://frontend/antd/notification/notification.tsx#L65-L69) diff --git a/.wiki/en/Ant Design Components/Feedback Components/Modal.md b/.wiki/en/Ant Design Components/Feedback Components/Modal.md new file mode 100644 index 00000000..1492d5e7 --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Modal.md @@ -0,0 +1,322 @@ +# Modal + + +**Files referenced in this document** +- [frontend/antd/modal/modal.tsx](file://frontend/antd/modal/modal.tsx) +- [frontend/antd/modal/static/modal.static.tsx](file://frontend/antd/modal/static/modal.static.tsx) +- [backend/modelscope_studio/components/antd/modal/__init__.py](file://backend/modelscope_studio/components/antd/modal/__init__.py) +- [backend/modelscope_studio/components/antd/modal/static/__init__.py](file://backend/modelscope_studio/components/antd/modal/static/__init__.py) +- [frontend/antd/modal/static/Index.svelte](file://frontend/antd/modal/static/Index.svelte) +- [docs/components/antd/modal/README.md](file://docs/components/antd/modal/README.md) +- [docs/components/antd/modal/demos/basic.py](file://docs/components/antd/modal/demos/basic.py) +- [docs/components/antd/modal/demos/custom_footer.py](file://docs/components/antd/modal/demos/custom_footer.py) +- [docs/components/antd/modal/demos/static.py](file://docs/components/antd/modal/demos/static.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Animation](#performance-and-animation) +8. [Accessibility and Keyboard Interaction](#accessibility-and-keyboard-interaction) +9. [Troubleshooting](#troubleshooting) +10. [Conclusion](#conclusion) +11. [Appendix: Common Scenario Examples](#appendix-common-scenario-examples) + +## Introduction + +This document systematically covers the "Modal" component group, including the design principles, use cases, z-index management, focus control, keyboard interaction, event and style customization, animation and transitions, performance optimization, and accessibility support for both regular Modal and Static Modal. The document also provides practical guidance based on repository examples to help developers efficiently integrate and extend the components in the Gradio/ModelScope ecosystem. + +## Project Structure + +This component is positioned between the frontend Ant Design wrapper layer and the backend Python component bridge layer, using a layered design of "Frontend Svelte + React Slot + Backend LayoutComponent": + +- Frontend layer: Wraps Ant Design's Modal as a slottable component via `sveltify`; the static modal dynamically renders via the useModal API. +- Backend layer: Python components encapsulate AntdModal/AntdModalStatic, exposing a unified property and event interface and declaring supported slots. +- Documentation and examples: Provides three types of examples — basic, custom footer, and static call — for quick onboarding. + +```mermaid +graph TB +subgraph "Backend" +PY_API["AntdModal
AntdModalStatic"] +end +subgraph "Frontend" +F_Svelte["Index.svelte
Static Wrapper"] +F_Modal["Modal.tsx
Regular Dialog"] +F_Static["ModalStatic.tsx
Static Dialog"] +end +subgraph "Third-party" +AntD["Ant Design Modal"] +end +PY_API --> F_Svelte +F_Svelte --> F_Modal +F_Svelte --> F_Static +F_Modal --> AntD +F_Static --> AntD +``` + +Diagram sources + +- [frontend/antd/modal/modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) +- [frontend/antd/modal/static/modal.static.tsx:1-132](file://frontend/antd/modal/static/modal.static.tsx#L1-L132) +- [frontend/antd/modal/static/Index.svelte:1-69](file://frontend/antd/modal/static/Index.svelte#L1-L69) +- [backend/modelscope_studio/components/antd/modal/**init**.py:1-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L1-L136) +- [backend/modelscope_studio/components/antd/modal/static/**init**.py:1-133](file://backend/modelscope_studio/components/antd/modal/static/__init__.py#L1-L133) + +Section sources + +- [docs/components/antd/modal/README.md:1-13](file://docs/components/antd/modal/README.md#L1-L13) + +## Core Components + +- Regular Modal (AntdModal) + - Design positioning: Rendered directly as a component, suitable for scenarios that need to explicitly manage the lifecycle and z-index in the layout tree. + - Key capabilities: Supports slottable title, footer, button icons and text, close icon, custom renderer, container mount point, keyboard and mask behavior, etc. +- Static Modal (AntdModalStatic) + - Design positioning: Dynamically triggered via useModal without needing to be declared in the layout tree, suitable for one-time dialogs such as message hints and confirmation flows. + - Key capabilities: Supports info/success/error/warning/confirm types, auto-focus buttons, controlled visibility, onOk/onCancel callback linkage. + +Section sources + +- [backend/modelscope_studio/components/antd/modal/**init**.py:11-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L11-L136) +- [backend/modelscope_studio/components/antd/modal/static/**init**.py:10-133](file://backend/modelscope_studio/components/antd/modal/static/__init__.py#L10-L133) + +## Architecture Overview + +The following diagram shows the key call chain from user trigger to dialog presentation, including both regular and static modes: + +```mermaid +sequenceDiagram +participant U as "User" +participant PY as "Backend Component (AntdModal/Static)" +participant FE as "Frontend Wrapper (Index.svelte)" +participant MOD as "Modal/ModalStatic" +participant ANT as "Ant Design Modal" +U->>PY : Trigger display (e.g., click a button) +PY->>FE : Pass props and visibility +alt Regular mode +FE->>MOD : Render Modal component +MOD->>ANT : Render regular dialog +else Static mode +FE->>MOD : Pass visible/type etc. +MOD->>ANT : Call useModal(type) to create instance +end +ANT-->>U : Display dialog and respond to interactions +``` + +Diagram sources + +- [frontend/antd/modal/static/Index.svelte:54-68](file://frontend/antd/modal/static/Index.svelte#L54-L68) +- [frontend/antd/modal/modal.tsx:36-102](file://frontend/antd/modal/modal.tsx#L36-L102) +- [frontend/antd/modal/static/modal.static.tsx:46-128](file://frontend/antd/modal/static/modal.static.tsx#L46-L128) + +## Component Details + +### Regular Modal + +- Slot and prop mapping + - Supported slots: okText, okButtonProps.icon, cancelText, cancelButtonProps.icon, closable.closeIcon, closeIcon, footer, title, modalRender. + - Prop passthrough: afterOpenChange, afterClose, getContainer, keyboard, mask, maskClosable, width, zIndex, wrapClassName, etc. +- Event binding + - ok/cancel events are bound via event listeners to trigger callbacks or update visibility. +- Container mount and z-index + - getContainer can specify the mount node to avoid the z-index being blocked by a local container; defaults to mounting to body. +- Focus and keyboard + - `keyboard` controls whether Esc is allowed to close; `autoFocusButton` and similar props affect the initial focus. +- Custom rendering + - `modalRender` can replace the entire rendering logic; `footer` supports function-based slots for complex footer layouts. + +```mermaid +flowchart TD +Start(["Enter render"]) --> CheckSlots["Check if slots exist"] +CheckSlots --> |Exist| RenderSlot["Render slot content"] +CheckSlots --> |Do not exist| UseProp["Use prop value"] +RenderSlot --> Combine["Merge into final props"] +UseProp --> Combine +Combine --> Mount["Mount to target container"] +Mount --> Focus["Set focus/keyboard behavior based on config"] +Focus --> End(["Complete"]) +``` + +Diagram sources + +- [frontend/antd/modal/modal.tsx:36-99](file://frontend/antd/modal/modal.tsx#L36-L99) + +Section sources + +- [frontend/antd/modal/modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) +- [backend/modelscope_studio/components/antd/modal/**init**.py:18-32](file://backend/modelscope_studio/components/antd/modal/__init__.py#L18-L32) + +### Static Modal + +- Dynamic creation and destruction + - Obtains the API via `useModal`; creates the corresponding type instance when `visible` is true, otherwise destroys the current instance. + - Auto-focus on buttons is disabled by default unless explicitly passed in. +- Event and visibility linkage + - onOk/onCancel internally synchronize `onVisible(false)`, implementing the consistent behavior of "confirm/cancel = close". +- Slots and props + - Supports title, content, footer, okText, okButtonProps.icon, cancelText, cancelButtonProps.icon, closable.closeIcon, closeIcon, modalRender, etc. +- Usage restrictions + - Not declared in the layout tree; driven only by props such as visible/type; suitable for one-time hints and confirmation flows. + +```mermaid +sequenceDiagram +participant C as "Caller" +participant MS as "ModalStatic" +participant API as "useModal" +participant D as "Dialog Instance" +C->>MS : visible=true, type=info/success/... +MS->>API : Call corresponding type method (type) +API-->>MS : Return instance reference +MS->>D : Render and apply slots/props +D-->>MS : User action (confirm/cancel) +MS->>C : Fire onVisible(false) +MS->>API : Destroy instance +``` + +Diagram sources + +- [frontend/antd/modal/static/modal.static.tsx:46-128](file://frontend/antd/modal/static/modal.static.tsx#L46-L128) + +Section sources + +- [frontend/antd/modal/static/modal.static.tsx:1-132](file://frontend/antd/modal/static/modal.static.tsx#L1-L132) +- [backend/modelscope_studio/components/antd/modal/static/**init**.py:14-28](file://backend/modelscope_studio/components/antd/modal/static/__init__.py#L14-L28) + +### Component Relationships and Inheritance + +- The backend component classes AntdModal and AntdModalStatic both inherit from ModelScopeLayoutComponent, which unifies event, slot, prop, and lifecycle handling. +- The frontend Index.svelte serves as the dynamic loading entry point, responsible for passing props and slots to Modal or ModalStatic. + +```mermaid +classDiagram +class ModelScopeLayoutComponent +class AntdModal { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class AntdModalStatic { ++EVENTS ++SLOTS ++FRONTEND_DIR +} +class Modal_tsx +class ModalStatic_tsx +class Index_svelte +ModelScopeLayoutComponent <|-- AntdModal +ModelScopeLayoutComponent <|-- AntdModalStatic +Index_svelte --> Modal_tsx : "Render regular" +Index_svelte --> ModalStatic_tsx : "Render static" +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/modal/**init**.py:11-16](file://backend/modelscope_studio/components/antd/modal/__init__.py#L11-L16) +- [backend/modelscope_studio/components/antd/modal/static/**init**.py:10-13](file://backend/modelscope_studio/components/antd/modal/static/__init__.py#L10-L13) +- [frontend/antd/modal/static/Index.svelte:10-68](file://frontend/antd/modal/static/Index.svelte#L10-L68) + +## Dependency Analysis + +- Frontend dependencies + - sveltify: Bridges React components to Svelte. + - useFunction: Stabilizes callback functions to avoid side effects from repeated rendering. + - renderParamsSlot: Supports slot rendering with parameters. + - Ant Design Modal: Core UI behavior and styles. +- Backend dependencies + - Gradio event system: Binds ok/cancel via event listeners. + - Component base class ModelScopeLayoutComponent: Unifies lifecycle and prop handling. + +```mermaid +graph LR +A["Modal.tsx"] --> B["Ant Design Modal"] +C["ModalStatic.tsx"] --> B +D["Index.svelte"] --> A +D --> C +E["AntdModal"] --> D +F["AntdModalStatic"] --> D +``` + +Diagram sources + +- [frontend/antd/modal/modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) +- [frontend/antd/modal/static/modal.static.tsx:1-132](file://frontend/antd/modal/static/modal.static.tsx#L1-L132) +- [frontend/antd/modal/static/Index.svelte:1-69](file://frontend/antd/modal/static/Index.svelte#L1-L69) +- [backend/modelscope_studio/components/antd/modal/**init**.py:1-136](file://backend/modelscope_studio/components/antd/modal/__init__.py#L1-L136) +- [backend/modelscope_studio/components/antd/modal/static/**init**.py:1-133](file://backend/modelscope_studio/components/antd/modal/static/__init__.py#L1-L133) + +## Performance and Animation + +- Rendering strategy + - Regular mode: Rendered on demand; when open=false, use destroyOnClose/destroyOnHidden to reduce memory usage. + - Static mode: Instances are dynamically created/destroyed when visible toggles, avoiding persistent DOM. +- Animation and transitions + - Ant Design Modal provides open/close animations and mask transitions; visual z-index and size can be adjusted via width, zIndex, wrapClassName, etc. +- Performance recommendations + - For scenarios with many dialogs, prefer the static mode to reduce the number of nodes in the layout tree. + - For frequently toggled dialogs, set getContainer appropriately to avoid unnecessary reflows. + - When using modalRender for custom rendering, minimize deep nesting and expensive computations. + +[This section provides general guidance and does not directly analyze specific files] + +## Accessibility and Keyboard Interaction + +- Keyboard interaction + - `keyboard` controls whether Esc is allowed to close; `maskClosable` controls whether clicking the mask closes the dialog. + - Static mode disables auto-focus on buttons by default to avoid interrupting user actions; can be explicitly specified via `autoFocusButton`. +- Focus management + - After opening, focus should move to the first interactive element (e.g., the confirm button); after closing, focus should return to the trigger source (`focusTriggerAfterClose`). +- Screen readers + - Provide clear title and content; supplement semantics with aria-\* attributes when necessary. + - Avoid hints in modalRender that rely solely on color; ensure text is readable. + +[This section provides general guidance and does not directly analyze specific files] + +## Troubleshooting + +- Issue: Dialog not displayed + - Check that visible/open is correctly passed in; for static mode, ensure visible switches from false to true. + - Confirm getContainer points to a valid node that is not clipped by a parent. +- Issue: Clicking the mask does not close + - Check maskClosable and keyboard settings; confirm no external events are intercepting. +- Issue: Static dialog does not disappear + - Ensure onOk/onCancel callbacks call `onVisible(false)`; or directly update visible to false. +- Issue: Slots not working + - Confirm slot names match the component's supported list; regular mode uses slots, static mode is driven by visible/type. + +Section sources + +- [frontend/antd/modal/static/modal.static.tsx:107-114](file://frontend/antd/modal/static/modal.static.tsx#L107-L114) +- [backend/modelscope_studio/components/antd/modal/**init**.py:18-32](file://backend/modelscope_studio/components/antd/modal/__init__.py#L18-L32) + +## Conclusion + +- Regular Modal is suitable for scenarios requiring fine-grained lifecycle and z-index control in the layout tree; Static Modal is suitable for one-time hints and confirmation flows. +- Through flexible combination of slots and props, rich interaction and style customization can be achieved; combining useModal with the event system enables a consistent user experience. +- For performance and accessibility, it is recommended to prefer static mode for high-frequency dialogs, set focus and keyboard behavior appropriately, and ensure content is screen-reader-friendly. + +[This section is a summary and does not directly analyze specific files] + +## Appendix: Common Scenario Examples + +The following examples come from the repository documentation and demos, showcasing different usage patterns and typical scenarios. + +- Basic dialog + - Scenario: Open/close, confirm/cancel. + - Example path: [docs/components/antd/modal/demos/basic.py:1-19](file://docs/components/antd/modal/demos/basic.py#L1-L19) +- Custom footer + - Scenario: Custom bottom buttons, link navigation, combined interactions. + - Example path: [docs/components/antd/modal/demos/custom_footer.py:1-31](file://docs/components/antd/modal/demos/custom_footer.py#L1-L31) +- Static dialog (info/success/error/warning/confirm) + - Scenario: Message hints, confirmation dialogs. + - Example path: [docs/components/antd/modal/demos/static.py:1-74](file://docs/components/antd/modal/demos/static.py#L1-L74) + +Section sources + +- [docs/components/antd/modal/demos/basic.py:1-19](file://docs/components/antd/modal/demos/basic.py#L1-L19) +- [docs/components/antd/modal/demos/custom_footer.py:1-31](file://docs/components/antd/modal/demos/custom_footer.py#L1-L31) +- [docs/components/antd/modal/demos/static.py:1-74](file://docs/components/antd/modal/demos/static.py#L1-L74) diff --git a/.wiki/en/Ant Design Components/Feedback Components/Progress and Result.md b/.wiki/en/Ant Design Components/Feedback Components/Progress and Result.md new file mode 100644 index 00000000..c37ef21f --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Progress and Result.md @@ -0,0 +1,289 @@ +# Progress and Result + + +**Files referenced in this document** +- [frontend/antd/progress/progress.tsx](file://frontend/antd/progress/progress.tsx) +- [frontend/antd/progress/Index.svelte](file://frontend/antd/progress/Index.svelte) +- [docs/components/antd/progress/README.md](file://docs/components/antd/progress/README.md) +- [docs/components/antd/progress/demos/basic.py](file://docs/components/antd/progress/demos/basic.py) +- [frontend/antd/result/result.tsx](file://frontend/antd/result/result.tsx) +- [frontend/antd/result/Index.svelte](file://frontend/antd/result/Index.svelte) +- [docs/components/antd/result/README.md](file://docs/components/antd/result/README.md) +- [docs/components/antd/result/demos/basic.py](file://docs/components/antd/result/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the progress and result component group, systematically covering the functional characteristics, shape variants, status semantics, property configuration, animation and style customization methods for both the Progress and Result components, combined with demo examples from the repository to provide practical recommendations for typical application scenarios such as file upload progress, task execution status, and operation result feedback. It also covers key points for user experience optimization and accessibility support, helping developers use progress and result components efficiently and consistently in the Gradio ecosystem. + +## Project Structure + +- Component implementations reside in the frontend layer: each component has a Svelte entry file for property handling and slot rendering, and a TypeScript wrapper for interfacing with the native Ant Design component. +- Documentation and demos reside under docs/components/antd, providing component descriptions and runnable examples. +- The relationship between component entries and wrappers is shown in the following diagram: + +```mermaid +graph TB +subgraph "Frontend Implementation" +PIndex["progress/Index.svelte"] +PWrap["progress/progress.tsx"] +RIndex["result/Index.svelte"] +RWrap["result/result.tsx"] +end +subgraph "Third-party Library" +AntD["Ant Design Progress/Result"] +end +PIndex --> PWrap +RIndex --> RWrap +PWrap --> AntD +RWrap --> AntD +``` + +Diagram sources + +- [frontend/antd/progress/Index.svelte:1-64](file://frontend/antd/progress/Index.svelte#L1-L64) +- [frontend/antd/progress/progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [frontend/antd/result/Index.svelte:1-64](file://frontend/antd/result/Index.svelte#L1-L64) +- [frontend/antd/result/result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) + +Section sources + +- [frontend/antd/progress/Index.svelte:1-64](file://frontend/antd/progress/Index.svelte#L1-L64) +- [frontend/antd/progress/progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [frontend/antd/result/Index.svelte:1-64](file://frontend/antd/result/Index.svelte#L1-L64) +- [frontend/antd/result/result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) + +## Core Components + +- Progress + - Supports three shapes — line, circle, and dashboard (controlled via `type`) — and can add step segments (`steps`), info display toggle (`show_info`), and status color (`stroke_color`). + - Provides a percentage value (`percent`) and a format callback (`format`) for flexible text display control; supports a custom rounding function (`rounding`). + - Common statuses: default, active (`status='active'`), exception (`status='exception'`), success (`status='success'`). +- Result + - Used to display the final result of a series of operations, supporting success, info, warning, and error statuses. + - Supports title, sub_title, icon, and extra slots for extending buttons, links, or complex content. + +Section sources + +- [docs/components/antd/progress/README.md:1-8](file://docs/components/antd/progress/README.md#L1-L8) +- [docs/components/antd/result/README.md:1-8](file://docs/components/antd/result/README.md#L1-L8) +- [docs/components/antd/progress/demos/basic.py:1-39](file://docs/components/antd/progress/demos/basic.py#L1-L39) +- [docs/components/antd/result/demos/basic.py:1-57](file://docs/components/antd/result/demos/basic.py#L1-L57) + +## Architecture Overview + +The following diagram shows the call chain and slot passing mechanism from the Svelte entry to the native Ant Design component: + +```mermaid +sequenceDiagram +participant UI as "Page/Layout" +participant PIdx as "progress/Index.svelte" +participant PWrap as "progress/progress.tsx" +participant RIdx as "result/Index.svelte" +participant RWrap as "result/result.tsx" +participant Ant as "Ant Design Component" +UI->>PIdx : Pass props and slots +PIdx->>PIdx : Handle visibility/styles/additional props +PIdx->>PWrap : Render wrapper and pass through props +PWrap->>Ant : Call Ant Design Progress +Ant-->>UI : Render progress bar +UI->>RIdx : Pass props and slots +RIdx->>RIdx : Handle visibility/styles/additional props +RIdx->>RWrap : Render wrapper and pass through slots +RWrap->>Ant : Call Ant Design Result +Ant-->>UI : Render result panel +``` + +Diagram sources + +- [frontend/antd/progress/Index.svelte:10-61](file://frontend/antd/progress/Index.svelte#L10-L61) +- [frontend/antd/progress/progress.tsx:5-21](file://frontend/antd/progress/progress.tsx#L5-L21) +- [frontend/antd/result/Index.svelte:10-59](file://frontend/antd/result/Index.svelte#L10-L59) +- [frontend/antd/result/result.tsx:7-30](file://frontend/antd/result/result.tsx#L7-L30) + +## Detailed Component Analysis + +### Progress Component + +- Shapes and behavior + - Line progress bar: Default type, suitable for long-running tasks. + - Circle progress bar: `type="circle"`, suitable for emphasizing completion rate or as a card-level metric. + - Dashboard progress bar: `type="dashboard"`, suitable for threshold judgment and interval visualization. + - Step segments: The `steps` parameter splits the progress into multiple stages, commonly used for multi-stage tasks. +- Value display and formatting + - `percent` is the percentage input; `show_info` controls whether the number or status icon is displayed. + - The `format` callback can customize text content, such as showing "Done" text on completion. + - `rounding` allows customizing the rounding strategy for the percentage. +- Color and status + - `stroke_color` supports a single color or gradient array, coloring by step or overall. + - `status` controls the status color and animation: default, active, exception, success. +- Props and slots + - Props: percent, type, steps, stroke_color, status, show_info, format, rounding, etc. + - Slots: No built-in slots; text is mainly customized via `format`. +- Use cases + - File upload progress: Line progress bar showing real-time percentage, switching to success status on completion. + - Task execution status: Circle progress bar as a card-level metric; dashboard for threshold reminders. + - Multi-step flow: `steps` breaks down complex flows into multiple stages to improve perceived progress. + +```mermaid +flowchart TD +Start(["Start"]) --> SetType["Set type
type=linear/circle/dashboard"] +SetType --> SetPercent["Set percentage
percent"] +SetPercent --> ShowInfo{"Show info?"} +ShowInfo --> |Yes| FormatText["Format text
format callback"] +ShowInfo --> |No| SkipFormat["Skip text display"] +FormatText --> Color["Set color
stroke_color/status"] +SkipFormat --> Color +Color --> Steps{"Use steps?"} +Steps --> |Yes| StepSeg["Draw by step
steps"] +Steps --> |No| SingleSeg["Draw as whole"] +StepSeg --> Render["Render progress bar"] +SingleSeg --> Render +Render --> End(["End"]) +``` + +Diagram sources + +- [frontend/antd/progress/progress.tsx:5-21](file://frontend/antd/progress/progress.tsx#L5-L21) +- [docs/components/antd/progress/demos/basic.py:9-35](file://docs/components/antd/progress/demos/basic.py#L9-L35) + +Section sources + +- [frontend/antd/progress/progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [frontend/antd/progress/Index.svelte:10-61](file://frontend/antd/progress/Index.svelte#L10-L61) +- [docs/components/antd/progress/README.md:1-8](file://docs/components/antd/progress/README.md#L1-L8) +- [docs/components/antd/progress/demos/basic.py:1-39](file://docs/components/antd/progress/demos/basic.py#L1-L39) + +### Result Component + +- Status and semantics + - success: The operation completed successfully; encourage the user to proceed to the next step. + - info: Provides a neutral hint; guides the user to view details. + - warning: A risk or issue requiring attention; recommend the user confirm. + - error: The operation failed; the user needs to correct the issue and retry. +- Visual and content + - A title and sub_title clearly convey the result and context. + - The icon can be customized, combined with status colors to enhance recognition. + - The extra slot places action buttons, links, or supplementary notes. +- Props and slots + - Props: status, title, sub_title, icon, extra, etc. + - Slots: extra, icon, subTitle, title. +- Use cases + - Operation result feedback: A unified feedback interface after submitting a form or purchasing a service. + - Error diagnosis: Displaying the specific issue and repair guidance in an error state. + - Conversion guidance: Providing actions such as "Go to Console" or "Buy Again" after a success. + +```mermaid +sequenceDiagram +participant App as "Application" +participant R as "Result Component" +participant Slot as "Slot Content" +participant Ant as "Ant Design Result" +App->>R : Pass status/title/subTitle/icon +App->>Slot : Provide extra/icon/subTitle/title slots +R->>R : Parse slots and pass through to wrapper +R->>Ant : Render Result +Ant-->>App : Display result panel and action area +``` + +Diagram sources + +- [frontend/antd/result/result.tsx:7-30](file://frontend/antd/result/result.tsx#L7-L30) +- [frontend/antd/result/Index.svelte:10-59](file://frontend/antd/result/Index.svelte#L10-L59) + +Section sources + +- [frontend/antd/result/result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) +- [frontend/antd/result/Index.svelte:1-64](file://frontend/antd/result/Index.svelte#L1-L64) +- [docs/components/antd/result/README.md:1-8](file://docs/components/antd/result/README.md#L1-L8) +- [docs/components/antd/result/demos/basic.py:1-57](file://docs/components/antd/result/demos/basic.py#L1-L57) + +## Dependency Analysis + +- Component coupling and responsibilities + - The Svelte entry handles prop collection, visibility control, style concatenation, and slot parsing. + - The TypeScript wrapper interfaces with the Ant Design component, passing through props and callbacks (format, rounding). + - The slot system is implemented via ReactSlot and useTargets, ensuring dynamic rendering and fallback of slots. +- External dependencies + - Ant Design Progress/Result: Provides core UI and interaction behavior. + - @svelte-preprocess-react: Bridges React components with the Svelte context. + - @utils/hooks: Provides utility functions such as useFunction and useTargets. + +```mermaid +graph LR +PIdx["progress/Index.svelte"] --> PWrap["progress/progress.tsx"] +RIdx["result/Index.svelte"] --> RWrap["result/result.tsx"] +PWrap --> AntD["Ant Design Progress"] +RWrap --> AntD2["Ant Design Result"] +PWrap --> Hooks["@utils/hooks"] +RWrap --> Hooks +``` + +Diagram sources + +- [frontend/antd/progress/Index.svelte:1-64](file://frontend/antd/progress/Index.svelte#L1-L64) +- [frontend/antd/progress/progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [frontend/antd/result/Index.svelte:1-64](file://frontend/antd/result/Index.svelte#L1-L64) +- [frontend/antd/result/result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) + +Section sources + +- [frontend/antd/progress/progress.tsx:1-24](file://frontend/antd/progress/progress.tsx#L1-L24) +- [frontend/antd/result/result.tsx:1-33](file://frontend/antd/result/result.tsx#L1-L33) + +## Performance Considerations + +- Rendering overhead + - Progress bar: Line and circle rendering costs are similar; step segments (`steps`) increase path drawing times; it is recommended to reduce unnecessary re-renders in high-frequency update scenarios. + - Result: Content is relatively static; slot rendering is only triggered when content changes. +- Animation and smoothness + - Avoid complex computations when using the `format` callback; try to return lightweight strings. + - Circle/dashboard progress bars may impose GPU pressure at high refresh rates; use large circular progress bars with caution on mobile. +- Styles and theming + - When injecting styles via elem_style/elem_classes, prefer atomic classes or theme variables to reduce inline style jitter. + +## Troubleshooting Guide + +- Slots not working + - Confirm slot names are correct (extra, icon, subTitle, title), and that slots are explicitly passed through in the wrapper. + - If no slot content is provided, the wrapper will fall back to the corresponding prop field. +- Percentage not updating + - Ensure the `percent` prop updates as data changes; avoid expensive computations in `format` that cause lag. + - If custom rounding is needed, check the input/output types and boundary values of the `rounding` function. +- Status color anomaly + - When `status` and `stroke_color` are used simultaneously, note the status priority and color override order. + - When `steps` is an array, ensure its length matches the number of stages to avoid out-of-bounds errors. +- Accessibility + - Provide semantic labels and screen-reader-friendly text for key states (success/error). + - Provide alternative descriptions for invisible text in circle progress bars to ensure assistive technologies can understand the progress meaning. + +Section sources + +- [frontend/antd/result/result.tsx:10-30](file://frontend/antd/result/result.tsx#L10-L30) +- [frontend/antd/progress/progress.tsx:9-21](file://frontend/antd/progress/progress.tsx#L9-L21) + +## Conclusion + +The Progress and Result components in the Gradio ecosystem fulfill the dual responsibilities of "process visibility" and "result feedback". Through Ant Design's mature capabilities and this project's Svelte wrapper, developers can obtain a consistent, extensible, and customizable progress and result experience at minimal cost. It is recommended to choose the appropriate shape and status based on your business scenario in practice, and to follow accessibility and performance best practices to improve user satisfaction and maintainability. + +## Appendix + +- Example references + - Progress basic demo: [docs/components/antd/progress/demos/basic.py:1-39](file://docs/components/antd/progress/demos/basic.py#L1-L39) + - Result basic demo: [docs/components/antd/result/demos/basic.py:1-57](file://docs/components/antd/result/demos/basic.py#L1-L57) +- Component documentation + - Progress documentation: [docs/components/antd/progress/README.md:1-8](file://docs/components/antd/progress/README.md#L1-L8) + - Result documentation: [docs/components/antd/result/README.md:1-8](file://docs/components/antd/result/README.md#L1-L8) diff --git a/.wiki/en/Ant Design Components/Feedback Components/Spin and Skeleton.md b/.wiki/en/Ant Design Components/Feedback Components/Spin and Skeleton.md new file mode 100644 index 00000000..42e492a3 --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Spin and Skeleton.md @@ -0,0 +1,327 @@ +# Spin and Skeleton + + +**Files referenced in this document** +- [frontend/antd/skeleton/skeleton.tsx](file://frontend/antd/skeleton/skeleton.tsx) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx) +- [frontend/antd/skeleton/button/skeleton.button.tsx](file://frontend/antd/skeleton/button/skeleton.button.tsx) +- [frontend/antd/skeleton/image/skeleton.image.tsx](file://frontend/antd/skeleton/image/skeleton.image.tsx) +- [frontend/antd/skeleton/input/skeleton.input.tsx](file://frontend/antd/skeleton/input/skeleton.input.tsx) +- [frontend/antd/skeleton/node/skeleton.node.tsx](file://frontend/antd/skeleton/node/skeleton.node.tsx) +- [frontend/antd/spin/spin.tsx](file://frontend/antd/spin/spin.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Common Use Cases and Best Practices](#appendix-common-use-cases-and-best-practices) + +## Introduction + +This document focuses on the loading skeleton component group, systematically explaining the implementation patterns, usage strategies, and UX design considerations for Skeleton and Spin in this repository. Topics covered include: + +- Skeleton placeholder types, animation effects, and content layout simulation +- Spin loading indicator size variations and state management +- Component property configuration, custom animations, and style customization +- Practical recommendations for common scenarios such as list loading, image placeholders, form loading, and page transitions +- Timing and transition effects for switching between skeleton and real content +- Performance optimization recommendations and network condition adaptation strategies + +## Project Structure + +The loading skeleton component group resides in the frontend Ant Design component layer, following a unified "adapter" wrapping pattern that bridges Ant Design's React components to the Svelte ecosystem via preprocessing tools, ensuring a consistent invocation experience within this project's component system. + +```mermaid +graph TB +subgraph "Antd Skeleton Sub-components" +SA["Skeleton.Avatar
avatar/skeleton.avatar.tsx"] +SB["Skeleton.Button
button/skeleton.button.tsx"] +SI["Skeleton.Image
image/skeleton.image.tsx"] +SIN["Skeleton.Input
input/skeleton.input.tsx"] +SN["Skeleton.Node
node/skeleton.node.tsx"] +end +SMain["Skeleton
skeleton.tsx"] +subgraph "Antd Loading Indicator" +SP["Spin
spin.tsx"] +end +SMain --> SA +SMain --> SB +SMain --> SI +SMain --> SIN +SMain --> SN +``` + +Diagram sources + +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) +- [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) +- [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) +- [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) +- [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) + +Section sources + +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) +- [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) +- [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) +- [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) +- [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) + +## Core Components + +- Skeleton + - Main entry: Bridges Ant Design's Skeleton component to the Svelte environment in a unified way + - Sub-components: Avatar, Button, Image, Input, Node — each corresponding to a placeholder skeleton for a different element type +- Spin + - Main entry: Bridges Ant Design's Spin component to the Svelte environment in a unified way, with support for slottable `tip` and `indicator` customization + +Section sources + +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) +- [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) +- [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) +- [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) +- [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) + +## Architecture Overview + +The overall architecture uses a combination of "adapter + slots": + +- Adapter: The unified `sveltify` tool bridges Ant Design's React components as Svelte-usable components +- Slottable: Spin supports `tip` and `indicator` slots for custom tip text and indicator styles +- Target selection: Spin internally converts children into a locatable set of targets via a target selection hook, ensuring correct wrapping logic + +```mermaid +sequenceDiagram +participant U as "User Code" +participant S as "Spin Component" +participant Hook as "useTargets Hook" +participant AD as "Antd Spin" +U->>S : Pass children and props +S->>Hook : useTargets(children) +Hook-->>S : Return target set +S->>AD : Render Antd Spin(props, slots) +AD-->>U : Display loading indicator (with optional custom tip/indicator) +``` + +Diagram sources + +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) + +Section sources + +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) + +## Detailed Component Analysis + +### Skeleton Component Family + +- Design goals + - Provide stable content layout placeholders before data is ready, avoiding page jumps and layout jitter + - Improve perceived speed and usability by simulating real content with appropriate animations and shapes +- Placeholder types + - Avatar: Avatar placeholder + - Button: Button placeholder + - Image: Image placeholder + - Input: Input field placeholder + - Node: General-purpose node placeholder +- Animation and layout + - Based on Ant Design's Skeleton animation mechanism, typically manifests as a shimmer (gradient flash) effect + - Simulate complex layouts such as text, cards, and lists by setting different shapes (circle/square/rectangle) and row counts +- Usage recommendations + - List loading: Prefer Node or multiple Input rows to simulate list items + - Image placeholders: Use Image with dimensions matching the real image + - Form loading: Use Input/Button to simulate fields and action areas + - Page transitions: Wrap the container with Skeleton during route transitions to reduce the perception of a white screen + +```mermaid +classDiagram +class Skeleton { ++Main Entry +} +class SkeletonAvatar { ++Avatar Placeholder +} +class SkeletonButton { ++Button Placeholder +} +class SkeletonImage { ++Image Placeholder +} +class SkeletonInput { ++Input Placeholder +} +class SkeletonNode { ++General Node Placeholder +} +Skeleton --> SkeletonAvatar : "Contains" +Skeleton --> SkeletonButton : "Contains" +Skeleton --> SkeletonImage : "Contains" +Skeleton --> SkeletonInput : "Contains" +Skeleton --> SkeletonNode : "Contains" +``` + +Diagram sources + +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) +- [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) +- [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) +- [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) +- [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) + +Section sources + +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) +- [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) +- [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) +- [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) +- [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) + +### Spin Component + +- Design goals + - Provide clear feedback during async operations to prevent users from thinking the page is unresponsive + - Supports custom tip text and indicator to meet the visual needs of different scenarios +- Key features + - Slottable: Supports `tip` and `indicator` slots for injecting custom text and icons + - Target selection: Internally converts children into a target set via a target selection hook, ensuring correct wrapping logic + - Prop passthrough: All props are passed directly to Ant Design's Spin except for additional extensions +- Usage recommendations + - List loading: Use Spin as the list container with children as list items; `tip` indicates "Loading" + - Image placeholder: Wrap images with Spin before they finish loading; use a simple rotating icon for `indicator` + - Form submission: Disable interactions and display Spin during submission; `tip` indicates "Submitting" + - Page transitions: Wrap the entire page with Spin during route transitions to provide global loading feedback + +```mermaid +flowchart TD +Start(["Enter Spin render"]) --> Targets["useTargets(children)
Resolve target set"] +Targets --> HasTargets{"Targets exist?"} +HasTargets --> |No| HideChildren["Hide children (render placeholder only)"] +HasTargets --> |Yes| ShowChildren["Show children"] +HideChildren --> RenderAD["Render Antd Spin(props, slots)"] +ShowChildren --> RenderAD +RenderAD --> End(["End"]) +``` + +Diagram sources + +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) + +Section sources + +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) + +## Dependency Analysis + +- Component coupling + - The Skeleton family all depend on Ant Design's Skeleton implementation, bridged via sveltify + - Spin depends on Ant Design's Spin implementation, and introduces a target selection hook and ReactSlot slot mechanism +- External dependencies + - @svelte-preprocess-react: Provides sveltify and ReactSlot capabilities + - Ant Design: Provides the concrete implementations of Skeleton and Spin +- Potential issues + - Slot names and prop naming must be consistent with Ant Design to avoid runtime errors + - Target selection logic must ensure the children structure is reasonable to avoid wrapping anomalies + +```mermaid +graph LR +Spin["Spin Component"] --> AD_Spin["Antd Spin"] +Spin --> RS["ReactSlot"] +Spin --> UT["useTargets Hook"] +Skeleton["Skeleton Component"] --> AD_Skeleton["Antd Skeleton"] +Skeleton --> SA["Skeleton.Avatar"] +Skeleton --> SB["Skeleton.Button"] +Skeleton --> SI["Skeleton.Image"] +Skeleton --> SIN["Skeleton.Input"] +Skeleton --> SN["Skeleton.Node"] +``` + +Diagram sources + +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) +- [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) +- [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) +- [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) +- [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) + +Section sources + +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) + +## Performance Considerations + +- Skeleton rendering cost + - The number and depth of skeleton placeholder elements should approximate the real content to avoid excessive rendering causing lag + - For long lists, use Skeleton.Node or a small number of input rows as placeholders to reduce DOM count +- Loading indicator feedback + - Spin's `tip` and `indicator` should be as lightweight as possible to avoid additional repaints and reflows + - In high-frequency refresh scenarios, it is recommended to use throttling or debouncing to control the frequency of loading state transitions +- Network condition adaptation + - For poor network conditions, it is recommended to extend the Skeleton display time threshold to avoid frequent flickering + - For high-latency scenarios, Spin's `tip` text should clearly inform the user why they are waiting (e.g., "Connecting to server") + +## Troubleshooting Guide + +- Issue: Spin cannot correctly wrap children + - Debug: Confirm whether children have a recognizable target structure; check the return value of useTargets + - Reference implementation: [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- Issue: tip/indicator slots not working + - Debug: Confirm slot names are `tip` and `indicator`; ensure the slots object has the corresponding keys + - Reference implementation: [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- Issue: Skeleton sub-component style anomalies + - Debug: Confirm sub-components are correctly importing the corresponding Ant Design modules; check theme and style overrides + - Reference implementations: + - [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) + - [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) + - [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) + - [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) + - [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) + - [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) + +Section sources + +- [frontend/antd/spin/spin.tsx:1-38](file://frontend/antd/spin/spin.tsx#L1-L38) +- [frontend/antd/skeleton/skeleton.tsx:1-7](file://frontend/antd/skeleton/skeleton.tsx#L1-L7) +- [frontend/antd/skeleton/avatar/skeleton.avatar.tsx:1-9](file://frontend/antd/skeleton/avatar/skeleton.avatar.tsx#L1-L9) +- [frontend/antd/skeleton/button/skeleton.button.tsx:1-9](file://frontend/antd/skeleton/button/skeleton.button.tsx#L1-L9) +- [frontend/antd/skeleton/image/skeleton.image.tsx:1-9](file://frontend/antd/skeleton/image/skeleton.image.tsx#L1-L9) +- [frontend/antd/skeleton/input/skeleton.input.tsx:1-9](file://frontend/antd/skeleton/input/skeleton.input.tsx#L1-L9) +- [frontend/antd/skeleton/node/skeleton.node.tsx:1-9](file://frontend/antd/skeleton/node/skeleton.node.tsx#L1-L9) + +## Conclusion + +The loading skeleton component group in this repository achieves seamless integration of Ant Design Skeleton and Spin through a unified adapter and slottable design. In practice, the appropriate skeleton type and loading indicator form should be chosen based on the business scenario, and props and slots should be used for customization to meet branding and interaction needs. At the same time, pay attention to rendering performance and network condition adaptation to ensure a consistent, smooth user experience across different devices and environments. + +## Appendix: Common Use Cases and Best Practices + +- List loading + - Use Skeleton.Node or multiple Input rows to simulate list item placeholders + - Wrap the list container with Spin; `tip` indicates "Loading", `indicator` uses the default spinning icon +- Image placeholder + - Use Skeleton.Image to simulate image dimensions and placeholders + - When an image fails to load, switch to a skeleton placeholder or error hint +- Form loading + - Use Skeleton.Input and Skeleton.Button to simulate input fields and action areas + - Disable interactions and display Spin during submission; `tip` indicates "Submitting" +- Page transitions + - During route transitions, wrap the page body with Skeleton to reduce the perception of a white screen + - For high-latency scenarios, Spin's `tip` text should clearly inform the user why they are waiting diff --git a/.wiki/en/Ant Design Components/Feedback Components/Watermark.md b/.wiki/en/Ant Design Components/Feedback Components/Watermark.md new file mode 100644 index 00000000..c4429c60 --- /dev/null +++ b/.wiki/en/Ant Design Components/Feedback Components/Watermark.md @@ -0,0 +1,434 @@ +# Watermark + + +**Files referenced in this document** +- [watermark.tsx](file://frontend/antd/watermark/watermark.tsx) +- [Index.svelte](file://frontend/antd/watermark/Index.svelte) +- [__init__.py](file://backend/modelscope_studio/components/antd/watermark/__init__.py) +- [watermark-wBOVRUhz.js](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js) +- [basic.py](file://docs/components/antd/watermark/demos/basic.py) +- [modal_or_drawer.py](file://docs/components/antd/watermark/demos/modal_or_drawer.py) +- [README.md](file://docs/components/antd/watermark/README.md) +- [README-zh_CN.md](file://docs/components/antd/watermark/README-zh_CN.md) +- [app.py](file://docs/components/antd/watermark/app.py) +- [component.py](file://backend/modelscope_studio/utils/dev/component.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Watermark component is used to overlay text or image watermarks on a page or container, commonly used for copyright protection, version identification, customer differentiation, and similar scenarios. The Watermark component in this repository is based on Ant Design's Watermark implementation and is used within the Gradio ecosystem through a Svelte/React bridge layer. + +- Features + - Text watermark: Supports single-line or multi-line text watermarks. + - Image watermark: Supports a custom image as the watermark source. + - Position and layout: Controls repetition and arrangement through width, height, gap, and offset parameters. + - Rotation and scaling: Supports rotation angle and scale configuration. + - Opacity and z-index: Supports opacity and z-index control. + - Embedded usage: Can wrap any child element and automatically takes effect as the container changes. + - Event binding: Supports removal event binding for dynamic control. + +- Application scenarios + - Copyright protection: Add a "Copyright Protected" watermark to preview images or reports. + - Version identification: Add a "DEVELOPMENT" or "TEST" watermark in development/test environments. + - Customer differentiation: Add a dedicated watermark per customer or tenant for identification and auditing. + - Sensitive data protection: Add a watermark on export or display interfaces to reduce the risk of inadvertent propagation. + +- Implementation principles + - Frontend bridge: Wraps Ant Design's Watermark component as a Svelte-usable component via `sveltify`. + - Prop passthrough: Merges Gradio props (such as elem_id, elem_classes, elem_style, visible) with additional props and passes them to the underlying component. + - Render control: Controls whether to render based on `visible`; supports slots and children. + - Backend encapsulation: The Python layer provides the AntdWatermark class, carrying props and declaring the frontend directory mapping, while also declaring event listeners. + +- Usage notes + - Text and image: Set via `content` or `image` parameters; multi-line text can use array form. + - Repeat pattern: Control repetition and offset via width, height, gap, and offset. + - Rotation and scaling: `rotate` controls the angle; `z_index` controls the z-index. + - Dynamic updates: Watermark content and styles can be dynamically switched via Gradio's update mechanism. + - Style customization: Extend styles via elem_style, elem_classes, and additional props. + +**Section sources** + +- [README.md:1-9](file://docs/components/antd/watermark/README.md#L1-L9) +- [README-zh_CN.md:1-9](file://docs/components/antd/watermark/README-zh_CN.md#L1-L9) + +## Project Structure + +The organization of the Watermark component in the repository is as follows: + +- Frontend + - Svelte wrapper layer: Index.svelte handles prop processing, visibility control, and child node rendering. + - React bridge layer: watermark.tsx wraps Ant Design's Watermark as a Svelte component using `sveltify`. + - Runtime template: watermark-wBOVRUhz.js is the component runtime template, responsible for React component mounting and bridging logic. +- Backend + - Python encapsulation: The AntdWatermark class carries props and events, and declares the frontend directory mapping. +- Examples and documentation + - Basic example: basic.py demonstrates the basic usage of text and image watermarks. + - Dialog example: modal_or_drawer.py demonstrates how to use watermarks inside Modal/Drawer. + - Documentation pages: README/README-zh_CN.md provides example placeholders and links. + +```mermaid +graph TB +subgraph "Frontend" +IDX["Index.svelte
Prop handling and render control"] +WRAP["watermark.tsx
sveltify wrapper"] +RT["watermark-wBOVRUhz.js
Runtime template and bridge"] +end +subgraph "Backend" +PY["__init__.py
AntdWatermark class and props"] +DEV["component.py
ModelScopeLayoutComponent base class"] +end +subgraph "Examples and Documentation" +DEMO1["basic.py"] +DEMO2["modal_or_drawer.py"] +DOC["README.md / README-zh_CN.md"] +end +IDX --> WRAP --> RT +PY --> IDX +PY --> WRAP +PY --> RT +DEV --> PY +DEMO1 --> PY +DEMO2 --> PY +DOC --> DEMO1 +DOC --> DEMO2 +``` + +**Diagram sources** + +- [Index.svelte:1-64](file://frontend/antd/watermark/Index.svelte#L1-L64) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [watermark-wBOVRUhz.js:1-442](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js#L1-L442) +- [**init**.py:1-83](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L1-L83) +- [component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) +- [basic.py:1-23](file://docs/components/antd/watermark/demos/basic.py#L1-L23) +- [modal_or_drawer.py:1-30](file://docs/components/antd/watermark/demos/modal_or_drawer.py#L1-L30) +- [README.md:1-9](file://docs/components/antd/watermark/README.md#L1-L9) +- [README-zh_CN.md:1-9](file://docs/components/antd/watermark/README-zh_CN.md#L1-L9) + +**Section sources** + +- [Index.svelte:1-64](file://frontend/antd/watermark/Index.svelte#L1-L64) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [watermark-wBOVRUhz.js:1-442](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js#L1-L442) +- [**init**.py:1-83](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L1-L83) +- [component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) +- [README.md:1-9](file://docs/components/antd/watermark/README.md#L1-L9) +- [README-zh_CN.md:1-9](file://docs/components/antd/watermark/README-zh_CN.md#L1-L9) + +## Core Components + +- AntdWatermark (Backend) + - Responsibility: Carries the watermark component's props and events, declares the frontend directory mapping, and skips API calls. + - Key props (from constructor): content, width, height, inherit, rotate, z_index, image, font, gap, offset, root_class_name, etc. + - Events: remove (binds the removal event). + - Other: `skip_api` returns True, indicating this component does not participate in the standard API flow. + +- Watermark (Frontend Bridge) + - Responsibility: Wraps Ant Design's Watermark component as a Svelte component via `sveltify` for use in Gradio. + - Behavior: Directly exports Watermark as the default export. + +- Index.svelte (Frontend Wrapper) + - Responsibility: Handles Gradio props (elem_id, elem_classes, elem_style, visible), merges additional props, and controls visibility and child node rendering. + - Behavior: When `visible` is true, asynchronously loads Watermark and renders it; supports slots and children. + +- Runtime template (watermark-wBOVRUhz.js) + - Responsibility: Provides React component bridging, context merging, Portal rendering, and effect registration to ensure the component is correctly mounted and updated in the browser environment. + +**Section sources** + +- [**init**.py:8-83](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L8-L83) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [Index.svelte:1-64](file://frontend/antd/watermark/Index.svelte#L1-L64) +- [watermark-wBOVRUhz.js:330-442](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js#L330-L442) + +## Architecture Overview + +The following diagram shows the overall call chain and responsibilities from Python to the frontend and then to the runtime: + +```mermaid +sequenceDiagram +participant Py as "Python Backend
AntdWatermark" +participant Wrap as "Frontend Wrapper
Index.svelte" +participant Bridge as "Bridge Layer
watermark.tsx" +participant Runtime as "Runtime Template
watermark-wBOVRUhz.js" +Py->>Wrap : "Declare component and props" +Wrap->>Bridge : "Import and wrap Watermark" +Bridge->>Runtime : "Create React component instance" +Runtime-->>Wrap : "Return renderable React component" +Wrap-->>Py : "Render or hide based on visible" +``` + +**Diagram sources** + +- [**init**.py:66-66](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L66-L66) +- [Index.svelte:10-63](file://frontend/antd/watermark/Index.svelte#L10-L63) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [watermark-wBOVRUhz.js:330-442](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js#L330-L442) + +## Detailed Component Analysis + +### Props and Configuration + +- Text watermark + - content: A string or array of strings for setting watermark text; supports multi-line text. + - font: Font-related configuration (e.g., color, font size), supported by the underlying Ant Design. +- Image watermark + - image: An image URL for setting the image watermark source. +- Repetition and layout + - width, height: The width and height of the watermark unit. + - gap: The horizontal and vertical spacing between watermarks. + - offset: The initial offset of the watermark (typically used to control the starting position). +- Rotation and scaling + - rotate: Watermark rotation angle. + - inherit: Whether to inherit parent styles. +- Z-index and opacity + - z_index: Watermark z-index. + - Other styles: Control opacity, background, etc. via elem_style and elem_classes. +- Other + - root_class_name: Root node class name prefix. + - additional_props: Extra prop passthrough. + +- Dynamic updates and style customization + - visible: Controls whether the component is rendered. + - elem_id, elem_classes, elem_style: Used for positioning and style customization. + - slots and children: Supports slot and child node rendering. + +**Section sources** + +- [**init**.py:50-64](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L50-L64) +- [Index.svelte:21-44](file://frontend/antd/watermark/Index.svelte#L21-L44) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) + +### Usage Flow and Examples + +- Basic text watermark + - Nest Watermark inside a container and set `content` to a string or array. + - Reference example: basic.py. +- Image watermark + - Set `image` to an image URL; use width and height to control watermark dimensions. + - Reference example: basic.py. +- Usage inside dialogs/drawers + - Wrap Modal/Drawer with Watermark to achieve watermark coverage inside the dialog. + - Reference example: modal_or_drawer.py. + +```mermaid +sequenceDiagram +participant Demo as "Example Script
basic.py / modal_or_drawer.py" +participant Py as "AntdWatermark
Backend" +participant Wrap as "Index.svelte" +participant Bridge as "watermark.tsx" +participant RT as "watermark-wBOVRUhz.js" +Demo->>Py : "Create Watermark component and pass props" +Py->>Wrap : "Declare component and props" +Wrap->>Bridge : "Import and wrap" +Bridge->>RT : "Create React instance" +RT-->>Wrap : "Return renderable component" +Wrap-->>Demo : "Render result" +``` + +**Diagram sources** + +- [basic.py:1-23](file://docs/components/antd/watermark/demos/basic.py#L1-L23) +- [modal_or_drawer.py:1-30](file://docs/components/antd/watermark/demos/modal_or_drawer.py#L1-L30) +- [**init**.py:8-83](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L8-L83) +- [Index.svelte:50-63](file://frontend/antd/watermark/Index.svelte#L50-L63) +- [watermark.tsx:1-6](file://frontend/antd/watermark/watermark.tsx#L1-L6) +- [watermark-wBOVRUhz.js:330-442](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js#L330-L442) + +**Section sources** + +- [basic.py:1-23](file://docs/components/antd/watermark/demos/basic.py#L1-L23) +- [modal_or_drawer.py:1-30](file://docs/components/antd/watermark/demos/modal_or_drawer.py#L1-L30) + +### Events and Lifecycle + +- remove event + - Bound via event listeners; can be used to remove the watermark when needed. + - The event callback updates internal state to enable the removal behavior. + +**Section sources** + +- [**init**.py:12-16](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L12-L16) + +### Class Relationship Diagram + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__init__() ++__exit__() +} +class AntdWatermark { ++EVENTS ++content ++width ++height ++inherit ++rotate ++z_index ++image ++font ++gap ++offset ++root_class_name ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +ModelScopeLayoutComponent <|-- AntdWatermark +``` + +**Diagram sources** + +- [component.py:11-127](file://backend/modelscope_studio/utils/dev/component.py#L11-L127) +- [**init**.py:8-83](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L8-L83) + +## Dependency Analysis + +- Component coupling + - AntdWatermark depends on the frontend directory mapping and runtime template to ensure correct rendering in the browser. + - Index.svelte depends on the wrapper layer and runtime template, responsible for prop processing and visibility control. + - watermark.tsx is responsible only for bridging, with low coupling, making it easy to maintain. +- External dependencies + - Ant Design Watermark: Underlying implementation. + - Svelte/React bridge tools: sveltify, @svelte-preprocess-react, etc. +- Potential issues + - If FRONTEND_DIR is not set correctly, it may cause frontend resources to fail to load. + - When `visible` is false, the component is not rendered; be aware of side effects when dynamically toggling. + +```mermaid +graph LR +PY["AntdWatermark
Backend"] --> IDX["Index.svelte
Frontend Wrapper"] +IDX --> WRAP["watermark.tsx
Bridge"] +WRAP --> RT["watermark-wBOVRUhz.js
Runtime Template"] +PY --> AD["Ant Design Watermark
External Dependency"] +``` + +**Diagram sources** + +- [**init**.py:66-66](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L66-L66) +- [Index.svelte:10-10](file://frontend/antd/watermark/Index.svelte#L10-L10) +- [watermark.tsx:1-1](file://frontend/antd/watermark/watermark.tsx#L1-L1) +- [watermark-wBOVRUhz.js:330-330](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js#L330-L330) + +**Section sources** + +- [**init**.py:66-66](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L66-L66) +- [Index.svelte:10-10](file://frontend/antd/watermark/Index.svelte#L10-L10) +- [watermark.tsx:1-1](file://frontend/antd/watermark/watermark.tsx#L1-L1) +- [watermark-wBOVRUhz.js:330-330](file://backend/modelscope_studio/components/antd/watermark/templates/component/watermark-wBOVRUhz.js#L330-L330) + +## Performance Considerations + +- Rendering overhead + - Watermarks are essentially a background layer overlaid on a container, with minimal impact on the rendering of main content; however, a large number of repeating units may increase painting costs. +- Repaint and reflow + - Frequently changing props such as content, image, rotate, and z_index may trigger repaints; it is recommended to batch updates or reduce change frequency. +- Image watermark + - Image loading and decoding incur additional overhead; use appropriately sized and formatted images to avoid large images causing lag. +- Visibility control + - Controlling render timing via `visible` can effectively reduce unnecessary overhead. +- Recommendations + - Set width, height, and gap reasonably to avoid overly dense repetition. + - For frequently toggled scenarios, prioritize caching and throttling strategies. + - When using inside dialogs/drawers, pay attention to the rendering timing during dialog open/close. + +[This section provides general performance recommendations and does not require specific file sources] + +## Troubleshooting Guide + +- Watermark not displayed + - Check if `visible` is true; confirm props are correctly passed through to the component. + - Confirm FRONTEND_DIR correctly points to the frontend directory. +- Image watermark not displayed + - Check if the `image` URL is accessible; confirm image dimensions and format are reasonable. + - Adjust width and height to fit the container. +- Rotation or z-index anomaly + - Check that `rotate` and `z_index` settings match expectations; confirm no other styles are overriding them. +- Dynamic updates not working + - Confirm the update logic is correct; use a re-render strategy if necessary. +- Events not working + - Confirm the `remove` event has been bound; check that the event callback is executing correctly. + +**Section sources** + +- [Index.svelte:50-63](file://frontend/antd/watermark/Index.svelte#L50-L63) +- [**init**.py:66-66](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L66-L66) + +## Conclusion + +The Watermark component provides flexible watermarking capabilities in the Gradio ecosystem through a concise prop system and a stable bridging mechanism. It supports text and image watermarks, repeat layouts, rotation and scaling, and z-index control, applicable to a variety of scenarios including copyright protection, version identification, and customer differentiation. Combined with visibility control and event binding, a dynamic and maintainable watermarking solution can be achieved. + +[This section is a summary and does not require specific file sources] + +## Appendix + +### Common Use Case Example Paths + +- Copyright protection: Add a "Copyright Protected" text or image watermark to preview image or report containers. +- Version identification: Add a "DEVELOPMENT" or "TEST" watermark in development/test environments. +- Customer differentiation: Add a dedicated watermark per customer or tenant for identification and auditing. +- Export protection: Add a watermark on export interfaces or print preview to reduce the risk of inadvertent propagation. + +**Section sources** + +- [basic.py:1-23](file://docs/components/antd/watermark/demos/basic.py#L1-L23) +- [modal_or_drawer.py:1-30](file://docs/components/antd/watermark/demos/modal_or_drawer.py#L1-L30) + +### Quick Reference for Props + +- Text watermark: content (string or array), font +- Image watermark: image, width, height +- Repetition and layout: gap, offset +- Rotation and z-index: rotate, z_index +- Styles and visibility: elem_style, elem_classes, elem_id, visible +- Other: root_class_name, additional_props + +**Section sources** + +- [**init**.py:50-64](file://backend/modelscope_studio/components/antd/watermark/__init__.py#L50-L64) +- [Index.svelte:21-44](file://frontend/antd/watermark/Index.svelte#L21-L44) + +### Security and Anti-tampering Recommendations + +- Trustworthy content sources: Ensure content and image come from trusted sources to avoid injecting malicious content. +- Access control: Restrict modification permissions for the watermark component to prevent it from being bypassed or removed. +- Audit logging: Record watermark change logs for tracking and auditing. +- Principle of least privilege: Grant only the necessary watermark configuration permissions to avoid over-authorization. + +[This section provides general security recommendations and does not require specific file sources] + +### Accessibility and Screen Reader Compatibility + +- Text watermark + - Ensure text semantics are clear; avoid using decorative text. + - Provide alternative text or titles for key information. +- Image watermark + - Provide descriptive alt text for image watermarks to help screen readers identify them. +- Interaction and focus + - Watermarks should not interfere with user operations; ensure focusable elements are not obscured. +- Styles and contrast + - Ensure the watermark has sufficient contrast with the background to avoid affecting readability. +- Accessibility testing + - Test with screen readers and keyboard navigation to verify the accessibility experience. + +[This section provides general accessibility recommendations and does not require specific file sources] diff --git a/.wiki/en/Ant Design Components/General Components/Button.md b/.wiki/en/Ant Design Components/General Components/Button.md new file mode 100644 index 00000000..140f9ce8 --- /dev/null +++ b/.wiki/en/Ant Design Components/General Components/Button.md @@ -0,0 +1,312 @@ +# Button + + +**Files referenced in this document** +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/button/group/button.group.tsx](file://frontend/antd/button/group/button.group.tsx) +- [frontend/antd/button/group/Index.svelte](file://frontend/antd/button/group/Index.svelte) +- [backend/modelscope_studio/components/antd/button/__init__.py](file://backend/modelscope_studio/components/antd/button/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [docs/components/antd/button/README-zh_CN.md](file://docs/components/antd/button/README-zh_CN.md) +- [docs/components/antd/button/demos/basic.py](file://docs/components/antd/button/demos/basic.py) +- [docs/components/antd/button/app.py](file://docs/components/antd/button/app.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically introduces the Button component, covering its core functionality, property configuration, and event handling mechanism. It focuses on explaining configuration items such as type (variant), size, and state; explains the usage and layout control of button groups; provides example paths for various scenarios (such as basic buttons, icon buttons, ghost buttons, dashed buttons, etc.); elaborates on handling special states like disabled, loading, and danger; explains style customization, theme adaptation, and responsive design points; and provides best practice recommendations for accessibility and keyboard navigation. + +## Project Structure + +The Button component consists of backend Python component class and frontend Svelte/React wrapper layer, following Gradio ecosystem's "component as context" pattern, supporting custom rendering of icons and loading state icons through the Slot mechanism. + +```mermaid +graph TB +subgraph "Backend" +PY_BTN["AntdButton
Python Component Class"] +PY_GROUP["AntdButtonGroup
Python Component Class"] +end +subgraph "Frontend" +IDX["Index.svelte
Component Entry"] +BTN["button.tsx
React Wrapper"] +SLOT["Slot Processing
icon / loading.icon"] +GROUP_IDX["group/Index.svelte
Button Group Entry"] +GROUP_BTN["group/button.group.tsx
Antd Button.Group Wrapper"] +end +PY_BTN --> IDX +PY_GROUP --> GROUP_IDX +IDX --> BTN +GROUP_IDX --> GROUP_BTN +BTN --> SLOT +``` + +Diagram Source + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-138](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L138) +- [frontend/antd/button/Index.svelte:10-73](file://frontend/antd/button/Index.svelte#L10-L73) +- [frontend/antd/button/button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) +- [frontend/antd/button/group/Index.svelte:10-61](file://frontend/antd/button/group/Index.svelte#L10-L61) +- [frontend/antd/button/group/button.group.tsx:6-24](file://frontend/antd/button/group/button.group.tsx#L6-L24) + +Section Source + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-138](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L138) +- [frontend/antd/button/Index.svelte:10-73](file://frontend/antd/button/Index.svelte#L10-L73) +- [frontend/antd/button/button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) +- [frontend/antd/button/group/Index.svelte:10-61](file://frontend/antd/button/group/Index.svelte#L10-L61) +- [frontend/antd/button/group/button.group.tsx:6-24](file://frontend/antd/button/group/button.group.tsx#L6-L24) + +## Core Components + +- Backend Component Class: AntdButton provides all property and event definitions for buttons, supporting type, variant, size, color, shape, state, and other configurations, and declares supported slots (icon, loading.icon). +- Frontend Wrapper Layer: Index.svelte maps Python properties to React components, injecting styles and IDs; button.tsx uses sveltify to wrap Ant Design's Button, parsing and passing slots. +- Button Group: AntdButtonGroup corresponds to the frontend Button.Group wrapper, supporting group-level styles and theme variable injection. + +Section Source + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-138](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L138) +- [frontend/antd/button/Index.svelte:10-73](file://frontend/antd/button/Index.svelte#L10-L73) +- [frontend/antd/button/button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) +- [frontend/antd/button/group/Index.svelte:10-61](file://frontend/antd/button/group/Index.svelte#L10-L61) +- [frontend/antd/button/group/button.group.tsx:6-24](file://frontend/antd/button/group/button.group.tsx#L6-L24) + +## Architecture Overview + +The diagram below shows the call chain from Python component to frontend rendering, and the processing flow of Slot in loading state and icon state. + +```mermaid +sequenceDiagram +participant Py as "Python : AntdButton" +participant Svelte as "Svelte : Index.svelte" +participant Wrap as "React : button.tsx" +participant AD as "Antd : Button" +participant Slot as "Slot Resolution" +Py->>Svelte : Pass properties and values +Svelte->>Wrap : Render React wrapper component +Wrap->>AD : Pass props including icon, loading +Wrap->>Slot : Parse slots.icon / slots["loading.icon"] +Slot-->>Wrap : Return React node +Wrap-->>AD : Inject icon/loading icon +AD-->>Svelte : Render final button +``` + +Diagram Source + +- [frontend/antd/button/button.tsx:11-36](file://frontend/antd/button/button.tsx#L11-L36) +- [frontend/antd/button/Index.svelte:59-73](file://frontend/antd/button/Index.svelte#L59-L73) +- [backend/modelscope_studio/components/antd/button/**init**.py:41-49](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L49) + +## Detailed Component Analysis + +### Properties and Configuration + +- Type and Variant + - type: Supports primary, dashed, link, text, default + - variant: Supports outlined, dashed, solid, filled, text, link + - color: Supports default, primary, danger and a set of preset color names +- Size and Shape + - size: large, middle, small + - shape: default, circle, round +- State and Behavior + - disabled: Disabled state + - danger: Danger state + - ghost: Ghost button (transparent background) + - loading: Boolean or loading object with delay + - block: Block-level width + - html_type: button, submit, reset + - href/target: Link button and jump target +- Icon and Slots + - icon: Icon name or node + - loading.icon: Loading state custom icon +- Style and Identity + - elem_id, elem_classes, elem_style + - class_names, styles, root_class_name + +Section Source + +- [backend/modelscope_studio/components/antd/button/**init**.py:51-138](file://backend/modelscope_studio/components/antd/button/__init__.py#L51-L138) +- [frontend/antd/button/button.tsx:18-30](file://frontend/antd/button/button.tsx#L18-L30) + +### Event Handling Mechanism + +- click event: Bound through event listener, when triggered can update internal state to drive UI changes. +- Typical Usage: In the example, register click callback for button to output logs or trigger business logic. + +Section Source + +- [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) +- [docs/components/antd/button/demos/basic.py:9-10](file://docs/components/antd/button/demos/basic.py#L9-L10) + +### Slots and Icon Processing + +- Slot Definition: icon, loading.icon +- Rendering Strategy: + - If slots.icon exists, render with ReactSlot and clone + - When loading.icon exists, use that node as loading icon and preserve loading.delay value (when loading is an object) + - If no slot, fall back to props.icon or props.loading + +```mermaid +flowchart TD +Start(["Enter rendering"]) --> HasIcon{"Does slots.icon exist?"} +HasIcon --> |Yes| RenderIcon["Render slots.icon (cloned)"] +HasIcon --> |No| UseIcon["Use props.icon"] +RenderIcon --> Next1["Continue processing loading"] +UseIcon --> Next1 +Next1 --> HasLoadIcon{"Does slots['loading.icon'] exist?"} +HasLoadIcon --> |Yes| BuildLoadObj["Build loading object
containing icon and delay"] +HasLoadIcon --> |No| UseLoad["Use props.loading"] +BuildLoadObj --> End(["Complete"]) +UseLoad --> End +``` + +Diagram Source + +- [frontend/antd/button/button.tsx:18-30](file://frontend/antd/button/button.tsx#L18-L30) + +Section Source + +- [frontend/antd/button/button.tsx:11-36](file://frontend/antd/button/button.tsx#L11-L36) + +### Button Group (Button.Group) + +- Component Entry: group/Index.svelte +- Wrapper Implementation: group/button.group.tsx +- Theme Adaptation: Injects CSS variables through Ant Design's theme.token.lineWidth, unifying in-group borders and spacing +- Applicable Scenarios: Multiple buttons combined arrangement, sharing the same theme style + +```mermaid +sequenceDiagram +participant Py as "Python : AntdButtonGroup" +participant Svelte as "Svelte : group/Index.svelte" +participant Wrap as "React : group/button.group.tsx" +participant AD as "Antd : Button.Group" +Py->>Svelte : Pass properties +Svelte->>Wrap : Render wrapper component +Wrap->>AD : Pass props and inject theme variables +AD-->>Svelte : Render button group +``` + +Diagram Source + +- [frontend/antd/button/group/Index.svelte:48-61](file://frontend/antd/button/group/Index.svelte#L48-L61) +- [frontend/antd/button/group/button.group.tsx:10-24](file://frontend/antd/button/group/button.group.tsx#L10-L24) + +Section Source + +- [frontend/antd/button/group/Index.svelte:10-61](file://frontend/antd/button/group/Index.svelte#L10-L61) +- [frontend/antd/button/group/button.group.tsx:6-24](file://frontend/antd/button/group/button.group.tsx#L6-L24) + +### Examples and Usage Scenarios + +The following examples are from documentation demo scripts, demonstrating button usage with different variants and states: + +- Basic Buttons: Primary button, default button, dashed button, text button, link button +- Variants and Colors: Filled variant combined with default/danger color +- Loading State and Icons: Setting icon slot in loading state +- Block Buttons: block=True makes button fill container width + +Example Path + +- [docs/components/antd/button/demos/basic.py:9-22](file://docs/components/antd/button/demos/basic.py#L9-L22) + +Section Source + +- [docs/components/antd/button/demos/basic.py:5-25](file://docs/components/antd/button/demos/basic.py#L5-L25) + +### Style Customization, Theme Adaptation and Responsive Design + +- Style Injection: Add custom styles for individual buttons or button groups through elem_id, elem_classes, elem_style +- Theme Variables: Button groups inject CSS variables through Ant Design theme tokens, ensuring consistent in-group borders +- Responsive: Combined with Flex/Space and other layout components, buttons can automatically wrap and align under different screen sizes + +Section Source + +- [frontend/antd/button/group/button.group.tsx:10-24](file://frontend/antd/button/group/button.group.tsx#L10-L24) +- [docs/components/antd/button/demos/basic.py](file://docs/components/antd/button/demos/basic.py#L8) + +### Accessibility and Keyboard Navigation + +- Keyboard Accessibility: Buttons natively support Enter/Space triggering, recommend providing clear focus indicators in complex interactions +- Text and Icons: Provide readable text alternatives for icon buttons (aria-label), avoid relying solely on icons to convey critical information +- Disabled and Loading States: Disabled and loading states should maintain visual consistency, ensuring users perceive the current non-interactive state +- Combined Buttons: In button groups, recommend providing clear grouping semantics, adding titles or dividers when necessary + +## Dependency Analysis + +- Component Registration: AntdButton and AntdButtonGroup are centrally exported in backend component collection, facilitating unified import and usage +- Component Base Class: ModelScopeLayoutComponent provides common layout capabilities and event hooks +- Frontend Bridge: Bridges Ant Design's React components to Svelte environment through sveltify while preserving Slot capabilities + +```mermaid +graph LR +Export["components.py Export"] --> Btn["AntdButton"] +Export --> BtnGroup["AntdButtonGroup"] +Btn --> Base["ModelScopeLayoutComponent"] +BtnGroup --> Base +``` + +Diagram Source + +- [backend/modelscope_studio/components/antd/components.py:14-15](file://backend/modelscope_studio/components/antd/components.py#L14-L15) +- [backend/modelscope_studio/utils/dev/component.py:11-27](file://backend/modelscope_studio/utils/dev/component.py#L11-L27) + +Section Source + +- [backend/modelscope_studio/components/antd/components.py:14-15](file://backend/modelscope_studio/components/antd/components.py#L14-L15) +- [backend/modelscope_studio/utils/dev/component.py:11-27](file://backend/modelscope_studio/utils/dev/component.py#L11-L27) + +## Performance Considerations + +- Button Group Theme Variable Injection: Token is calculated only once during group component initialization, avoiding repeated calculation overhead +- Slot Rendering: Prioritize using slots.icon and slots["loading.icon"], reducing unnecessary props passing +- Delayed Loading: loading object supports delay field, avoiding flicker caused by frequent switching + +Section Source + +- [frontend/antd/button/group/button.group.tsx:10-24](file://frontend/antd/button/group/button.group.tsx#L10-L24) +- [frontend/antd/button/button.tsx:21-29](file://frontend/antd/button/button.tsx#L21-L29) + +## Troubleshooting Guide + +- Slot Not Working + - Check whether ms.Slot("icon") or ms.Slot("loading.icon") is correctly used to wrap icon component + - Confirm slots are correctly passed in frontend +- Loading Icon Not Displaying + - Ensure slots["loading.icon"] exists and is a valid node + - When loading is an object, confirm whether delay field is set as expected +- Button Group Style Abnormal + - Check whether theme token is available, confirm CSS variables are injected +- Event Not Triggered + - Confirm click event listener is bound and callback function is executable + +Section Source + +- [frontend/antd/button/button.tsx:18-30](file://frontend/antd/button/button.tsx#L18-L30) +- [frontend/antd/button/group/button.group.tsx:10-24](file://frontend/antd/button/group/button.group.tsx#L10-L24) +- [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) + +## Conclusion + +The Button component in this project achieves complete wrapping of Ant Design, with rich type, variant, size, and state configurations, while flexibly supporting icon and loading state customization through the Slot mechanism. Button groups provide good extensibility in theme adaptation and layout control. Combined with example scripts and best practices, developers can quickly build button interactions that meet design specifications and accessibility requirements. + +## Appendix + +- Documentation Entry and Examples + - [docs/components/antd/button/README-zh_CN.md:1-8](file://docs/components/antd/button/README-zh_CN.md#L1-L8) + - [docs/components/antd/button/demos/basic.py:1-26](file://docs/components/antd/button/demos/basic.py#L1-L26) + - [docs/components/antd/button/app.py:1-7](file://docs/components/antd/button/app.py#L1-L7) diff --git a/.wiki/en/Ant Design Components/General Components/FloatButton.md b/.wiki/en/Ant Design Components/General Components/FloatButton.md new file mode 100644 index 00000000..cfaff72f --- /dev/null +++ b/.wiki/en/Ant Design Components/General Components/FloatButton.md @@ -0,0 +1,351 @@ +# FloatButton + + +**Files referenced in this document** +- [Index.svelte](file://frontend/antd/float-button/Index.svelte) +- [float-button.tsx](file://frontend/antd/float-button/float-button.tsx) +- [group/Index.svelte](file://frontend/antd/float-button/group/Index.svelte) +- [group/float-button.group.tsx](file://frontend/antd/float-button/group/float-button.group.tsx) +- [back-top/Index.svelte](file://frontend/antd/float-button/back-top/Index.svelte) +- [back-top/float-button.back-top.tsx](file://frontend/antd/float-button/back-top/float-button.back-top.tsx) +- [__init__.py](file://backend/modelscope_studio/components/antd/float_button/__init__.py) +- [README-zh_CN.md](file://docs/components/antd/float_button/README-zh_CN.md) +- [app.py](file://docs/components/antd/float_button/app.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +FloatButton is a "floating button" component used to provide globally accessible function entries at any position on the page. It is implemented based on Ant Design's FloatButton and presented as a unified component form in the model domain through Gradio frontend bridge layer. This component supports extension capabilities such as icons, description text, tooltip popups, and badge count; meanwhile, it provides two enhanced sub-features: "FloatButton Group" and "Back to Top", used for combining multiple actions and quickly returning to the top of the page respectively. + +Design Goals: + +- Remain visible at any scroll state on the page, improving user accessibility +- Provide flexible layout position and size control, meeting different page styles +- Support slot-based extensions (such as custom icons, descriptions, tooltips, badges) +- Collaborate with scroll containers and content areas to avoid blocking critical information +- Cover mobile and responsive scenarios, ensuring consistent interaction experience + +## Project Structure + +FloatButton component consists of backend Python component class and frontend Svelte/React wrapper layer, with documentation examples demonstrated through the docs layer. + +```mermaid +graph TB +subgraph "Backend" +PY["AntdFloatButton.__init__.py"] +end +subgraph "Frontend" +IDX["float-button/Index.svelte"] +CMP["float-button.tsx"] +GRP_IDX["float-button/group/Index.svelte"] +GRP_CMP["float-button/group/float-button.group.tsx"] +BT_IDX["float-button/back-top/Index.svelte"] +BT_CMP["float-button/back-top/float-button.back-top.tsx"] +end +subgraph "Documentation" +DOC_README["docs/.../float_button/README-zh_CN.md"] +DOC_APP["docs/.../float_button/app.py"] +end +PY --> IDX +PY --> GRP_IDX +PY --> BT_IDX +IDX --> CMP +GRP_IDX --> GRP_CMP +BT_IDX --> BT_CMP +DOC_README --> DOC_APP +``` + +Diagram Source + +- [**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [Index.svelte:1-70](file://frontend/antd/float-button/Index.svelte#L1-L70) +- [float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [group/Index.svelte:1-72](file://frontend/antd/float-button/group/Index.svelte#L1-L72) +- [group/float-button.group.tsx:1-70](file://frontend/antd/float-button/group/float-button.group.tsx#L1-L70) +- [back-top/Index.svelte:1-73](file://frontend/antd/float-button/back-top/Index.svelte#L1-L73) +- [back-top/float-button.back-top.tsx:1-47](file://frontend/antd/float-button/back-top/float-button.back-top.tsx#L1-L47) +- [README-zh_CN.md:1-8](file://docs/components/antd/float_button/README-zh_CN.md#L1-L8) +- [app.py:1-7](file://docs/components/antd/float_button/app.py#L1-L7) + +Section Source + +- [**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [README-zh_CN.md:1-8](file://docs/components/antd/float_button/README-zh_CN.md#L1-L8) +- [app.py:1-7](file://docs/components/antd/float_button/app.py#L1-L7) + +## Core Components + +- AntdFloatButton: Backend component class, declares events, slots, and properties, responsible for mapping frontend components to Gradio ecosystem. +- FloatButton: Frontend wrapper, interfaces with Ant Design's FloatButton, supporting slot injection and function-type callback handling. +- FloatButton.Group: Frontend wrapper, used to combine multiple floating buttons, supporting close icon, shape, theme variables, etc. +- FloatButton.BackTop: Frontend wrapper, provides "back to top" capability, supporting custom scroll container retrieval logic. + +Section Source + +- [**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [float-button.tsx:14-75](file://frontend/antd/float-button/float-button.tsx#L14-L75) +- [group/float-button.group.tsx:10-70](file://frontend/antd/float-button/group/float-button.group.tsx#L10-L70) +- [back-top/float-button.back-top.tsx:7-47](file://frontend/antd/float-button/back-top/float-button.back-top.tsx#L7-L47) + +## Architecture Overview + +The diagram below shows the overall call chain from backend component class to frontend wrapper and then to Ant Design component. + +```mermaid +sequenceDiagram +participant Py as "Backend AntdFloatButton" +participant Svelte as "Svelte Entry Index.svelte" +participant Wrap as "React Wrapper float-button.tsx" +participant AD as "Ant Design FloatButton" +Py->>Svelte : Render component and pass properties/slots +Svelte->>Wrap : Dynamic import and pass props +Wrap->>AD : Inject icon/description/tooltip/badge slots +AD-->>Wrap : Return render result +Wrap-->>Svelte : Rendering complete +Svelte-->>Py : Component mounted +``` + +Diagram Source + +- [**init**.py:92-96](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L92-L96) +- [Index.svelte:10-69](file://frontend/antd/float-button/Index.svelte#L10-L69) +- [float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) + +## Detailed Component Analysis + +### Component 1: FloatButton + +- Design Concept + - As a global page entry, ensuring clickable trigger at any scroll position + - Supports extensions like icons, descriptions, tooltips, and badges through slot system +- Key Features + - Slot Support: icon, description, tooltip, tooltip.title, badge.count + - Callback Function Safety Handling: Wraps function-type properties like tooltip.afterOpenChange, tooltip.getPopupContainer + - Visibility Control: Controls rendering through visible +- Usage Scenarios + - Quick action entries (like "Back to Top", "Share", "Feedback") + - Entry buttons for multi-state switching or conditional display +- Configuration Points + - Icon and Shape: icon, shape + - Type and Style: type, root_class_name, class_names, styles + - Link and Native Properties: href, href_target, html_type + - Badge and Tooltip: badge, tooltip +- Interaction Behavior + - Supports click event binding + - Tooltip supports delayed open/close callbacks and popup container selection + +```mermaid +classDiagram +class AntdFloatButton { ++EVENTS ++SLOTS ++__init__(...) ++FRONTEND_DIR +} +class FloatButton { ++Slots : icon, description, tooltip, tooltip.title, badge.count ++Function Wrapping : afterOpenChange, getPopupContainer +} +AntdFloatButton --> FloatButton : "Backend drives frontend" +``` + +Diagram Source + +- [**init**.py:12-32](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L32) +- [float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) + +Section Source + +- [**init**.py:12-110](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L12-L110) +- [Index.svelte:13-51](file://frontend/antd/float-button/Index.svelte#L13-L51) +- [float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) + +### Component 2: FloatButton.Group + +- Design Concept + - Combines multiple floating buttons into one group, forming a compound entry, reducing page element count + - Supports close icon, shape (circle/square), and theme variable injection +- Key Features + - Slot Support: icon, closeIcon, description, tooltip, badge.count + - Shape and Style: shape, className, inline style overriding theme variables + - Child Item Rendering: Separates slots from regular child nodes through useSlotsChildren +- Usage Scenarios + - Multi-function entry aggregation (like "Edit/Favorite/Share/More") + - Expandable/collapsible compound action areas +- Configuration Points + - Group Shape: shape (circle/square) + - Theme Variables: Inject border radius, etc. through CSS variables + - Slot-based Icons and Tooltips: Supports independent configuration for each child item + +```mermaid +classDiagram +class FloatButtonGroup { ++Slots : icon, closeIcon, description, tooltip, badge.count ++Properties : shape, className, style ++Theme : useToken() ++Children : useSlotsChildren() +} +``` + +Diagram Source + +- [group/float-button.group.tsx:10-67](file://frontend/antd/float-button/group/float-button.group.tsx#L10-L67) + +Section Source + +- [group/Index.svelte:14-50](file://frontend/antd/float-button/group/Index.svelte#L14-L50) +- [group/float-button.group.tsx:10-67](file://frontend/antd/float-button/group/float-button.group.tsx#L10-L67) + +### Component 3: FloatButton.BackTop + +- Design Concept + - Provides one-click back to top capability in long pages, improving navigation efficiency + - Supports custom scroll container retrieval logic, adapting to complex layouts +- Key Features + - Slot Support: icon, description, tooltip, badge.count + - Custom Target Container: target function wrapping, supports dynamic selection of scroll container +- Usage Scenarios + - Long content pages like content pages, list pages, detail pages + - Scenarios requiring frequent up/down scrolling +- Configuration Points + - Icon and Tooltip: icon, tooltip + - Badge and Description: badge, description + - Scroll Container: target (function), returns scroll container DOM node + +```mermaid +sequenceDiagram +participant User as "User" +participant BackTop as "BackTop Component" +participant Target as "target function" +participant Scroll as "Scroll Container" +User->>BackTop : Click "Back to Top" +BackTop->>Target : Get scroll container +Target-->>BackTop : Return DOM node +BackTop->>Scroll : Smooth scroll to top +Scroll-->>User : Page returns to top +``` + +Diagram Source + +- [back-top/float-button.back-top.tsx:7-44](file://frontend/antd/float-button/back-top/float-button.back-top.tsx#L7-L44) + +Section Source + +- [back-top/Index.svelte:14-50](file://frontend/antd/float-button/back-top/Index.svelte#L14-L50) +- [back-top/float-button.back-top.tsx:7-44](file://frontend/antd/float-button/back-top/float-button.back-top.tsx#L7-L44) + +### Component 4: Backend Bridge and Event Binding + +- Backend Component Class + - Defines events: click (binds internal event handler) + - Defines slots: icon, description, tooltip, tooltip.title, badge.count + - Frontend directory mapping: resolve_frontend_dir("float-button") +- Documentation and Examples + - README contains basic example placeholder + - app.py used to start documentation site + +Section Source + +- [**init**.py:22-32](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L22-L32) +- [**init**.py:92-96](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L92-L96) +- [README-zh_CN.md:1-8](file://docs/components/antd/float_button/README-zh_CN.md#L1-L8) +- [app.py:1-7](file://docs/components/antd/float_button/app.py#L1-L7) + +## Dependency Analysis + +- Component Coupling + - Backend AntdFloatButton only handles property and event declaration, does not directly render, reducing coupling + - Frontend achieves on-demand loading and decoupling through Svelte dynamic import wrapper +- Slots and Themes + - Group component introduces Ant Design theme token, injecting CSS variables to adapt border radius, etc. +- Function-type Properties + - Wraps tooltip callbacks and target through useFunction, ensuring stable operation in React/Svelte environments + +```mermaid +graph LR +PY["Backend AntdFloatButton"] --> IDX["Svelte Entry"] +IDX --> WRAP["React Wrapper"] +WRAP --> AD["Ant Design Component"] +WRAP --> THEME["Theme Token Injection"] +WRAP --> FN["useFunction Wrapped Callback"] +``` + +Diagram Source + +- [**init**.py:92-96](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L92-L96) +- [Index.svelte:10-69](file://frontend/antd/float-button/Index.svelte#L10-L69) +- [float-button.tsx:20-28](file://frontend/antd/float-button/float-button.tsx#L20-L28) +- [group/float-button.group.tsx:16-31](file://frontend/antd/float-button/group/float-button.group.tsx#L16-L31) +- [back-top/float-button.back-top.tsx:11](file://frontend/antd/float-button/back-top/float-button.back-top.tsx#L11) + +Section Source + +- [**init**.py:92-96](file://backend/modelscope_studio/components/antd/float_button/__init__.py#L92-L96) +- [float-button.tsx:20-28](file://frontend/antd/float-button/float-button.tsx#L20-L28) +- [group/float-button.group.tsx:16-31](file://frontend/antd/float-button/group/float-button.group.tsx#L16-L31) +- [back-top/float-button.back-top.tsx:11](file://frontend/antd/float-button/back-top/float-button.back-top.tsx#L11) + +## Performance Considerations + +- On-demand Loading + - Svelte avoids initial bundle bloat through dynamic import wrapper +- Rendering Overhead + - Slot content is hidden by default, only injected into Ant Design component when needed +- Callback Functions + - Use useFunction to wrap function-type properties, reducing unnecessary re-renders +- Theme Injection + - Group component injects theme tokens through CSS variables, avoiding repeated style calculations + +Section Source + +- [Index.svelte:10-10](file://frontend/antd/float-button/Index.svelte#L10-L10) +- [float-button.tsx:30-71](file://frontend/antd/float-button/float-button.tsx#L30-L71) +- [group/float-button.group.tsx:16-31](file://frontend/antd/float-button/group/float-button.group.tsx#L16-L31) + +## Troubleshooting Guide + +- FloatButton Not Displaying + - Check whether visible is true + - Confirm FRONTEND_DIR mapping is correct +- Slot Not Working + - Ensure slot names match the component support list (icon, description, tooltip, tooltip.title, badge.count) + - Group component additionally supports closeIcon, badge.count +- Back to Top Not Working + - Check whether target function returns a valid scroll container DOM node +- Tooltip Callback Not Triggered + - Confirm tooltip.afterOpenChange, tooltip.getPopupContainer are wrapped through useFunction + +Section Source + +- [Index.svelte:56-69](file://frontend/antd/float-button/Index.svelte#L56-L69) +- [float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) +- [group/float-button.group.tsx:10-67](file://frontend/antd/float-button/group/float-button.group.tsx#L10-L67) +- [back-top/float-button.back-top.tsx:7-44](file://frontend/antd/float-button/back-top/float-button.back-top.tsx#L7-L44) + +## Conclusion + +The FloatButton component achieves seamless integration and extension with Ant Design through the collaboration of backend bridge and frontend wrapper. Its slot-based design, theme injection, and function-type property wrapping maintain good maintainability and extensibility even in complex page layouts. Combined with the enhanced capabilities of "FloatButton Group" and "Back to Top", it can cover various common interaction scenarios, improving user experience and development efficiency. + +## Appendix + +- Examples and Documentation + - Documentation example entry: docs/components/antd/float_button/README-zh_CN.md + - Documentation site startup: docs/components/antd/float_button/app.py + +Section Source + +- [README-zh_CN.md:1-8](file://docs/components/antd/float_button/README-zh_CN.md#L1-L8) +- [app.py:1-7](file://docs/components/antd/float_button/app.py#L1-L7) diff --git a/.wiki/en/Ant Design Components/General Components/General Components.md b/.wiki/en/Ant Design Components/General Components/General Components.md new file mode 100644 index 00000000..05e30fd1 --- /dev/null +++ b/.wiki/en/Ant Design Components/General Components/General Components.md @@ -0,0 +1,375 @@ +# General Components + + +**Files referenced in this document** +- [button.tsx](file://frontend/antd/button/button.tsx) +- [float-button.tsx](file://frontend/antd/float-button/float-button.tsx) +- [icon.tsx](file://frontend/antd/icon/icon.tsx) +- [typography.base.tsx](file://frontend/antd/typography/typography.base.tsx) +- [basic.py (Button)](file://docs/components/antd/button/demos/basic.py) +- [basic.py (FloatButton)](file://docs/components/antd/float_button/demos/basic.py) +- [basic.py (Icon)](file://docs/components/antd/icon/demos/basic.py) +- [basic.py (Typography)](file://docs/components/antd/typography/demos/basic.py) +- [README-zh_CN.md (Button)](file://docs/components/antd/button/README-zh_CN.md) +- [README-zh_CN.md (FloatButton)](file://docs/components/antd/float_button/README-zh_CN.md) +- [README-zh_CN.md (Icon)](file://docs/components/antd/icon/README-zh_CN.md) +- [README-zh_CN.md (Typography)](file://docs/components/antd/typography/README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This chapter covers the implementation and usage of Ant Design general components in this repository, focusing on the following basic general components: Button, FloatButton, Icon, and Typography. The documentation provides in-depth analysis from aspects including system architecture, component responsibilities, data and event flow, accessibility and keyboard navigation, style and theme customization, best practices for combined usage, and performance optimization, with example paths to guide readers in getting started quickly. + +## Project Structure + +This project uses an organization of "frontend Svelte component wrapping + backend Gradio example demonstration": + +- Frontend components are located under frontend/antd, where each component consists of a svelte file and a tsx wrapper layer. The tsx layer is responsible for bridging Ant Design's React components to the Svelte ecosystem, and extending child content like icons, tooltips, and badges through the slots mechanism. +- Documentation examples are located under docs/components/antd, where each component provides multiple demo scripts (basic.py, etc.) to demonstrate different properties and interaction scenarios. + +```mermaid +graph TB +subgraph "Frontend Components" +BTN["Button
button.tsx"] +FBTN["FloatButton
float-button.tsx"] +ICON["Icon
icon.tsx"] +TYPO["Typography.Base
typography.base.tsx"] +end +subgraph "Documentation Examples" +DEMO_BTN["Button Example
button/demos/basic.py"] +DEMO_FBTN["FloatButton Example
float_button/demos/basic.py"] +DEMO_ICON["Icon Example
icon/demos/basic.py"] +DEMO_TYPO["Typography Example
typography/demos/basic.py"] +end +BTN --> DEMO_BTN +FBTN --> DEMO_FBTN +ICON --> DEMO_ICON +TYPO --> DEMO_TYPO +``` + +Diagram Source + +- [button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [typography.base.tsx:1-170](file://frontend/antd/typography/typography.base.tsx#L1-L170) +- [basic.py (Button):1-26](file://docs/components/antd/button/demos/basic.py#L1-L26) +- [basic.py (FloatButton):1-30](file://docs/components/antd/float_button/demos/basic.py#L1-L30) +- [basic.py (Icon):1-24](file://docs/components/antd/icon/demos/basic.py#L1-L24) +- [basic.py (Typography):1-23](file://docs/components/antd/typography/demos/basic.py#L1-L23) + +Section Source + +- [README-zh_CN.md (Button):1-8](file://docs/components/antd/button/README-zh_CN.md#L1-L8) +- [README-zh_CN.md (FloatButton):1-8](file://docs/components/antd/float_button/README-zh_CN.md#L1-L8) +- [README-zh_CN.md (Icon):1-10](file://docs/components/antd/icon/README-zh_CN.md#L1-L10) +- [README-zh_CN.md (Typography):1-8](file://docs/components/antd/typography/README-zh_CN.md#L1-L8) + +## Core Components + +- Button + - Responsibility: Wraps Ant Design's Button, supports injecting icon and custom loading icon through slots; supports dual entry rendering via value and children. + - Key Points: Uses useTargets to extract slot targets, dynamically determining render content; conditionally merges loading configuration, compatible with both objects and booleans. +- FloatButton + - Responsibility: Wraps Ant Design's FloatButton, supports slot-based configuration for icon, description, tooltip, badge, etc.; wraps function-type configuration items with useFunction to maintain reactivity. + - Key Points: tooltip supports title and overall configuration object; badge supports count slot; description supports slot. +- Icon + - Responsibility: Supports Ant Design built-in icon name mapping and IconFont rendering; supports custom component slot as SVG component. + - Key Points: slots.component has highest priority; otherwise maps to built-in icon by value; finally falls back to IconFont type. +- Typography.Base + - Responsibility: Unifies and aggregates four typography component types: Title, Text, Paragraph, Link, supporting slot-based configuration for copyable, editable, and ellipsis. + - Key Points: Dynamically selects specific Typography sub-component based on component; processes multiple slots with useTargets and renderParamsSlot, ensuring flexibility and extensibility. + +Section Source + +- [button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [typography.base.tsx:1-170](file://frontend/antd/typography/typography.base.tsx#L1-L170) + +## Architecture Overview + +The diagram below shows the call chain for general components: documentation examples start through Gradio application, internally use ConfigProvider for global theme configuration, then render each component; components internally bridge Ant Design's React components to Svelte components through sveltify, and inject icons, tooltips, badges, etc. using the slots mechanism. + +```mermaid +sequenceDiagram +participant Demo as "Example Script" +participant App as "Gradio Application" +participant Provider as "ConfigProvider" +participant Comp as "Component Wrapper Layer" +participant Antd as "Ant Design Component" +Demo->>App : "Build Blocks and start" +App->>Provider : "Apply global configuration" +App->>Comp : "Render component instance" +Comp->>Antd : "Pass properties and slots" +Antd-->>Comp : "Render result" +Comp-->>App : "Return Svelte wrapped node" +App-->>Demo : "Complete one render" +``` + +Diagram Source + +- [basic.py (Button):5-25](file://docs/components/antd/button/demos/basic.py#L5-L25) +- [basic.py (FloatButton):5-29](file://docs/components/antd/float_button/demos/basic.py#L5-L29) +- [basic.py (Icon):5-23](file://docs/components/antd/icon/demos/basic.py#L5-L23) +- [basic.py (Typography):10-22](file://docs/components/antd/typography/demos/basic.py#L10-L22) +- [button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) +- [float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) +- [icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- [typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) + +## Detailed Component Analysis + +### Button + +- Design Points + - Supports multiple types and variants: such as primary, dashed, text, link, filled, etc.; supports block layout and size control. + - Slot Capabilities: Inject icons through slots.icon; inject loading state icons through slots.loading.icon, supporting delay configuration. + - Content Entry: Supports directly passing text (children) or value field; when slots exist, slot content is rendered first. +- Events and Interaction + - click event: The example demonstrates click callback binding. + - Loading State: Can be configured via loading=true or passing an object to configure delay time. +- Styles and Themes + - Global theme takes effect through ConfigProvider; supports color and variant combinations. +- Usage Examples (Reference Path) + - Basic usage and variants: [basic.py (Button):8-22](file://docs/components/antd/button/demos/basic.py#L8-L22) + - Slot icons and loading state: [basic.py (Button):18-22](file://docs/components/antd/button/demos/basic.py#L18-L22) + +```mermaid +sequenceDiagram +participant U as "User" +participant Btn as "Button Wrapper Layer" +participant RBtn as "Antd Button" +U->>Btn : "Click triggers click event" +Btn->>RBtn : "Forward click event" +RBtn-->>U : "Execute callback and update interface" +Note over Btn,RBtn : "Slots icon/ loading.icon injected by slots" +``` + +Diagram Source + +- [button.tsx:11-36](file://frontend/antd/button/button.tsx#L11-L36) +- [basic.py (Button):10-10](file://docs/components/antd/button/demos/basic.py#L10-L10) + +Section Source + +- [button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) +- [basic.py (Button):8-22](file://docs/components/antd/button/demos/basic.py#L8-L22) + +### FloatButton + +- Design Points + - Supports sub-components like Group and BackTop; supports slot-based configuration for icon, description, tooltip, badge, etc. + - tooltip supports title and overall configuration object; badge supports count slot; description supports slot. + - Uses useFunction to wrap function-type configuration items (like afterOpenChange, getPopupContainer), ensuring reactive updates. +- Events and Interaction + - Supports click, visibility control (BackTop's visibility_height), etc. +- Styles and Themes + - Customize position and layout through elem_style; combine with Group to implement multi-button grouping. +- Usage Examples (Reference Path) + - Basic usage and grouping: [basic.py (FloatButton):8-13](file://docs/components/antd/float_button/demos/basic.py#L8-L13) + - Badge and icon: [basic.py (FloatButton):10-12](file://docs/components/antd/float_button/demos/basic.py#L10-L12) + - BackTop and Tooltip slots: [basic.py (FloatButton):13-13](file://docs/components/antd/float_button/demos/basic.py#L13-L13), [basic.py (FloatButton):23-27](file://docs/components/antd/float_button/demos/basic.py#L23-L27) + +```mermaid +sequenceDiagram +participant U as "User" +participant F as "FloatButton Wrapper Layer" +participant FB as "Antd FloatButton" +U->>F : "Click float button" +F->>FB : "Forward click event" +FB-->>U : "Execute callback and show/hide" +Note over F,FB : "tooltip.title/tooltip slot and badge.count slot injected by slots" +``` + +Diagram Source + +- [float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) +- [basic.py (FloatButton):13-13](file://docs/components/antd/float_button/demos/basic.py#L13-L13) +- [basic.py (FloatButton):23-27](file://docs/components/antd/float_button/demos/basic.py#L23-L27) + +Section Source + +- [float-button.tsx:7-72](file://frontend/antd/float-button/float-button.tsx#L7-L72) +- [basic.py (FloatButton):8-27](file://docs/components/antd/float_button/demos/basic.py#L8-L27) + +### Icon + +- Design Points + - Supports built-in icon name mapping (like HomeOutlined, SettingFilled, etc.); supports spin, rotate, twoTone, etc. properties. + - Supports IconFont fallback rendering; supports slots.component to inject custom SVG components. +- Events and Interaction + - The example demonstrates click event binding. +- Styles and Themes + - Supports style controls like color, rotation angle, two-tone icons, etc. +- Usage Examples (Reference Path) + - Basic icons and two-tone icons: [basic.py (Icon):9-16](file://docs/components/antd/icon/demos/basic.py#L9-L16) + - Custom component slots: [basic.py (Icon):19-21](file://docs/components/antd/icon/demos/basic.py#L19-L21) + +```mermaid +flowchart TD +Start(["Enter Icon rendering"]) --> CheckSlot["Check if slots.component exists"] +CheckSlot --> |Yes| RenderCustom["Render custom component"] +CheckSlot --> |No| CheckValue["Look up built-in icon by value"] +CheckValue --> Found{"Found built-in icon?"} +Found --> |Yes| RenderBuiltIn["Render built-in icon"] +Found --> |No| CheckIconFont["Check IconFont context"] +CheckIconFont --> HasFont{"Has IconFont?"} +HasFont --> |Yes| RenderIconFont["Render using IconFont"] +HasFont --> |No| Empty["Do not render empty"] +RenderCustom --> End(["End"]) +RenderBuiltIn --> End +RenderIconFont --> End +Empty --> End +``` + +Diagram Source + +- [icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- [basic.py (Icon):9-16](file://docs/components/antd/icon/demos/basic.py#L9-L16) +- [basic.py (Icon):19-21](file://docs/components/antd/icon/demos/basic.py#L19-L21) + +Section Source + +- [icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- [basic.py (Icon):9-21](file://docs/components/antd/icon/demos/basic.py#L9-L21) + +### Typography.Base + +- Design Points + - Unifies and aggregates four component types: Title, Text, Paragraph, Link, switching via component parameter. + - Supports slot-based configuration for copyable, editable, and ellipsis, enhancing customizability. + - Uses useSlotsChildren and useTargets to separate slot content from regular children, avoiding duplicate rendering. +- Events and Interaction + - editable_change event: The example demonstrates binding for edit change event and output update. +- Styles and Themes + - Generates class names through className and component name prefix, facilitating theme override. +- Usage Examples (Reference Path) + - Basic titles and text: [basic.py (Typography):13-15](file://docs/components/antd/typography/demos/basic.py#L13-L15) + - Copyable paragraphs and edit events: [basic.py (Typography):16-19](file://docs/components/antd/typography/demos/basic.py#L16-L19) + +```mermaid +sequenceDiagram +participant U as "User" +participant T as "Typography.Base" +participant TT as "Antd Typography.*" +U->>T : "Start editing" +T->>TT : "Trigger editable event" +TT-->>T : "Return edit result" +T-->>U : "Update content and close edit" +Note over T,TT : "copyable/ editable/ ellipsis slots injected by slots" +``` + +Diagram Source + +- [typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) +- [basic.py (Typography):16-19](file://docs/components/antd/typography/demos/basic.py#L16-L19) + +Section Source + +- [typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) +- [basic.py (Typography):13-19](file://docs/components/antd/typography/demos/basic.py#L13-L19) + +## Dependency Analysis + +- Inter-component Coupling + - Button, FloatButton, Icon, and Typography.Base all bridge Ant Design's React components to Svelte through sveltify, independent of each other with low coupling. + - The slot mechanism (slots) runs through all components, used to inject child content like icons, tooltips, badges, etc., enhancing extensibility. +- External Dependencies + - Ant Design React component library: Provides basic UI capabilities. + - @svelte-preprocess-react: Provides sveltify and ReactSlot, implementing Svelte and React interoperability. + - lodash-es: Provides utility functions (like isObject). + - @utils/\*: Provides useTargets, useFunction, renderParamsSlot, and other utilities, enhancing slot and event handling capabilities. +- Potential Circular Dependencies + - No circular dependencies found in the current structure; components all collaborate through utility functions and contexts, maintaining one-way dependencies. + +```mermaid +graph LR +BTN["Button.tsx"] --> AD["Ant Design Button"] +FBTN["FloatButton.tsx"] --> AD_FB["Ant Design FloatButton"] +ICON["Icon.tsx"] --> AD_Icons["Ant Design Icons"] +TYPO["Typography.Base.tsx"] --> AD_Typo["Ant Design Typography"] +BTN --> Utils["@utils/*"] +FBTN --> Utils +ICON --> Utils +TYPO --> Utils +Utils --> SveltePreprocess["@svelte-preprocess-react"] +AD --> React["React"] +AD_FB --> React +AD_Icons --> React +AD_Typo --> React +``` + +Diagram Source + +- [button.tsx:1-6](file://frontend/antd/button/button.tsx#L1-L6) +- [float-button.tsx:1-5](file://frontend/antd/float-button/float-button.tsx#L1-L5) +- [icon.tsx:1-6](file://frontend/antd/icon/icon.tsx#L1-L6) +- [typography.base.tsx:1-10](file://frontend/antd/typography/typography.base.tsx#L1-L10) + +Section Source + +- [button.tsx:1-6](file://frontend/antd/button/button.tsx#L1-L6) +- [float-button.tsx:1-5](file://frontend/antd/float-button/float-button.tsx#L1-L5) +- [icon.tsx:1-6](file://frontend/antd/icon/icon.tsx#L1-L6) +- [typography.base.tsx:1-10](file://frontend/antd/typography/typography.base.tsx#L1-L10) + +## Performance Considerations + +- Slot Rendering Optimization + - Uses useTargets and useSlotsChildren to separate slots from regular children, reducing unnecessary rendering overhead. + - Conditionally injects loading.icon, copyable.icon, editable.icon, etc., avoiding useless node mounting. +- Function-type Configuration Wrapping + - Uses useFunction to wrap function-type configurations for tooltip (like afterOpenChange, getPopupContainer), ensuring reactive updates without closure jitter. +- Conditional Merging + - Merges copyable, editable, ellipsis, etc. configurations through getConfig and omitUndefinedProps, only enabling corresponding capabilities when needed, reducing runtime burden. +- Theme and Styles + - Unifies theme through ConfigProvider, avoiding repeated calculations and style conflicts; reasonably uses className prefix for precise override. + +## Troubleshooting Guide + +- Slot Not Working + - Confirm whether slot names are correct (like icon, loading.icon, copyable.icon, editable.icon, ellipsis.symbol, etc.). + - Confirm slots.component has higher priority than built-in icon mapping; if provided, it will override default behavior. +- Tooltip Cannot Open or Callback Invalid + - Check whether tooltip is an object configuration; ensure function-type configuration items are wrapped through useFunction. +- Icon Not Displaying + - If slots.component is not provided, confirm whether value is a built-in icon name; otherwise, need to correctly configure IconFont context. +- Edit/Copy/Ellipsis Configuration Not Working + - Confirm that editable, copyable, or ellipsis enable corresponding capability if any exists; if it's an object configuration, ensure fields are complete. + +Section Source + +- [float-button.tsx:14-72](file://frontend/antd/float-button/float-button.tsx#L14-L72) +- [icon.tsx:12-52](file://frontend/antd/icon/icon.tsx#L12-L52) +- [typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) + +## Conclusion + +This repository seamlessly integrates Ant Design's React components into the Svelte/Gradio ecosystem through unified sveltify wrapping and slot mechanism, achieving high customizability and ease of use for general components like Button, FloatButton, Icon, and Typography. With ConfigProvider, slots, and utility functions, developers can flexibly implement style customization, interaction extension, and accessibility requirements. It is recommended to follow slot naming conventions, reasonably use function-type configuration wrapping and conditional rendering strategies in actual projects for better performance and maintainability. + +## Appendix + +- Quick Example Paths + - Button: [basic.py (Button):8-22](file://docs/components/antd/button/demos/basic.py#L8-L22) + - FloatButton: [basic.py (FloatButton):8-27](file://docs/components/antd/float_button/demos/basic.py#L8-L27) + - Icon: [basic.py (Icon):9-21](file://docs/components/antd/icon/demos/basic.py#L9-L21) + - Typography: [basic.py (Typography):13-19](file://docs/components/antd/typography/demos/basic.py#L13-L19) +- Component Documentation Entry + - Button: [README-zh_CN.md (Button):1-8](file://docs/components/antd/button/README-zh_CN.md#L1-L8) + - FloatButton: [README-zh_CN.md (FloatButton):1-8](file://docs/components/antd/float_button/README-zh_CN.md#L1-L8) + - Icon: [README-zh_CN.md (Icon):1-10](file://docs/components/antd/icon/README-zh_CN.md#L1-L10) + - Typography: [README-zh_CN.md (Typography):1-8](file://docs/components/antd/typography/README-zh_CN.md#L1-L8) diff --git a/.wiki/en/Ant Design Components/General Components/Icon.md b/.wiki/en/Ant Design Components/General Components/Icon.md new file mode 100644 index 00000000..db7c8238 --- /dev/null +++ b/.wiki/en/Ant Design Components/General Components/Icon.md @@ -0,0 +1,360 @@ +# Icon + + +**Files referenced in this document** +- [frontend/antd/icon/Index.svelte](file://frontend/antd/icon/Index.svelte) +- [frontend/antd/icon/icon.tsx](file://frontend/antd/icon/icon.tsx) +- [frontend/antd/icon/iconfont-provider/Index.svelte](file://frontend/antd/icon/iconfont-provider/Index.svelte) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx) +- [backend/modelscope_studio/components/antd/icon/__init__.py](file://backend/modelscope_studio/components/antd/icon/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [docs/components/antd/icon/README-zh_CN.md](file://docs/components/antd/icon/README-zh_CN.md) +- [docs/components/antd/icon/demos/basic.py](file://docs/components/antd/icon/demos/basic.py) +- [docs/components/antd/icon/demos/iconfont.py](file://docs/components/antd/icon/demos/iconfont.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Optimization](#performance-and-optimization) +8. [Accessibility](#accessibility) +9. [Troubleshooting](#troubleshooting) +10. [Conclusion](#conclusion) +11. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document systematically introduces the Icon component in ModelScope Studio's frontend ecosystem, covering: + +- Usage guidelines and common scenarios (inline icons, button icons, navigation icons) +- Supported icon libraries and icon font integration (Ant Design built-in icons, iconfont.cn) +- Size, color, style, and other configuration options +- IconFontProvider configuration and usage +- Performance optimization, lazy loading, and caching strategies +- Accessibility, semantic markup, and screen reader compatibility +- Custom icon library integration solutions and best practices + +## Project Structure + +The Icon component consists of "backend Gradio component layer" and "frontend Svelte/React presentation layer", and supports custom rendering through the Slot mechanism. + +```mermaid +graph TB +subgraph "Backend" +PY_ICON["AntdIcon
Python Component"] +PY_PROVIDER["AntdIconIconfontProvider
Python Component"] +end +subgraph "Frontend" +SV_INDEX["Index.svelte
Component Entry (Svelte)"] +TS_ICON["icon.tsx
React Implementation (Ant Design Icons)"] +SV_PROVIDER_INDEX["iconfont-provider/Index.svelte
Provider Entry (Svelte)"] +TS_PROVIDER["iconfont-provider.tsx
React Provider (IconFont)"] +end +PY_ICON --> SV_INDEX +PY_PROVIDER --> SV_PROVIDER_INDEX +SV_INDEX --> TS_ICON +SV_PROVIDER_INDEX --> TS_PROVIDER +``` + +Diagram Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) +- [frontend/antd/icon/icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [frontend/antd/icon/iconfont-provider/Index.svelte:1-53](file://frontend/antd/icon/iconfont-provider/Index.svelte#L1-L53) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:1-44](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L1-L44) + +Section Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) +- [frontend/antd/icon/icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [frontend/antd/icon/iconfont-provider/Index.svelte:1-53](file://frontend/antd/icon/iconfont-provider/Index.svelte#L1-L53) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:1-44](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L1-L44) + +## Core Components + +- AntdIcon (Backend): Provides properties such as value, spin, rotate, twoToneColor, component, etc.; supports click event binding; supports a Slot named "component" to inject custom rendering. +- AntdIconIconfontProvider (Backend): Provides IconFont context, used to render icons by type in icon font libraries like iconfont.cn. +- Frontend Svelte Entry: Responsible for forwarding backend-passed properties and Slots to React implementation. +- Frontend React Implementation: Selects built-in Ant Design icons based on value or renders custom icon types through IconFont context. + +Section Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:9-88](file://backend/modelscope_studio/components/antd/icon/__init__.py#L9-L88) +- [frontend/antd/icon/Index.svelte:1-67](file://frontend/antd/icon/Index.svelte#L1-L67) +- [frontend/antd/icon/icon.tsx:1-55](file://frontend/antd/icon/icon.tsx#L1-L55) +- [frontend/antd/icon/iconfont-provider/Index.svelte:1-53](file://frontend/antd/icon/iconfont-provider/Index.svelte#L1-L53) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:1-44](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L1-L44) + +## Architecture Overview + +The diagram below shows the key call chain from backend to frontend and then to icon rendering: + +```mermaid +sequenceDiagram +participant Py as "Backend AntdIcon" +participant S as "Frontend Index.svelte" +participant R as "React Icon Implementation" +participant Ctx as "IconFont Context" +Py->>S : Pass value/props/Slots +S->>R : Render Icon and pass through properties +alt Using custom component Slot +R->>R : Render using custom component +else Using built-in or IconFont +R->>Ctx : Read IconFont context +alt IconFont exists +R->>Ctx : Call IconFont(type, props) +else Not exists +R->>R : Render Ant Design built-in icon +end +end +``` + +Diagram Source + +- [frontend/antd/icon/Index.svelte:52-66](file://frontend/antd/icon/Index.svelte#L52-L66) +- [frontend/antd/icon/icon.tsx:17-52](file://frontend/antd/icon/icon.tsx#L17-L52) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:36-41](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L36-L41) + +## Component Details + +### AntdIcon (Backend) + +- Supported Properties + - value: String, specifies icon name (like built-in icon name or IconFont type name) + - spin: Boolean, whether to rotate animation + - rotate: Numeric angle, icon rotation angle + - twoToneColor: Two-tone icon primary color + - component: Root node component placeholder (used to replace default container) + - Element-level styles and class names: elem_style, elem_classes + - Visibility and rendering: visible, render +- Events + - click: Bind click event +- Slot + - component: Used to inject custom rendering (such as text emoticons, SVG components) + +Section Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:27-68](file://backend/modelscope_studio/components/antd/icon/__init__.py#L27-L68) +- [backend/modelscope_studio/components/antd/icon/**init**.py:18-22](file://backend/modelscope_studio/components/antd/icon/__init__.py#L18-L22) + +### Frontend Svelte Entry (Index.svelte) + +- Passes backend-provided value, additionalProps, elem\_\*, and other properties to React Icon +- Gets and forwards to React Icon through Slot +- Conditional rendering: Only renders when visible is true + +Section Source + +- [frontend/antd/icon/Index.svelte:13-66](file://frontend/antd/icon/Index.svelte#L13-L66) + +### React Implementation (icon.tsx) + +- Key Logic Points + - Prioritizes custom component injected through "component" Slot for rendering + - Otherwise, if built-in icon name exists, renders corresponding Ant Design icon + - If no built-in icon and IconFont context exists, renders through IconFont(type, props) +- Key Context + - useIconFontContext: Gets IconFont context instance + +Section Source + +- [frontend/antd/icon/icon.tsx:17-52](file://frontend/antd/icon/icon.tsx#L17-L52) + +### AntdIconIconfontProvider (Backend) + +- Provides IconFont context, enabling child-level Icons to render custom icon fonts by type +- Common Usage: Wraps a set of icons that need to use iconfont.cn + +Section Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:16-16](file://backend/modelscope_studio/components/antd/icon/__init__.py#L16-L16) + +### Frontend Provider (iconfont-provider.tsx) + +- Functionality + - Creates IconFont instance based on createFromIconfontCN + - Instance Caching: Reuses same instance when scriptUrl and extraCommonProps are unchanged + - Exposes to subtree through IconFontContext.Provider +- Parameters + - scriptUrl: Icon font script address (can be an array) + - extraCommonProps: Extra common properties (like color, fontSize, etc.) + +Section Source + +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:12-41](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L12-L41) + +### Provider Frontend Entry (iconfont-provider/Index.svelte) + +- Passes backend-provided Provider properties to React Provider component +- Acts as parent context container for Icons + +Section Source + +- [frontend/antd/icon/iconfont-provider/Index.svelte:42-52](file://frontend/antd/icon/iconfont-provider/Index.svelte#L42-L52) + +## Dependency Analysis + +- Component Coupling + - AntdIcon and AntdIconIconfontProvider are associated through classes in backend + - Frontend Svelte entry and React implementation are decoupled, communicating through properties and Slots + - React Icon depends on Ant Design Icons and IconFont context +- External Dependencies + - @ant-design/icons: Built-in icon library + - lodash-es isEqual: Used for Provider instance cache comparison + +```mermaid +graph LR +PY_ICON["Backend AntdIcon"] --> SV_ICON["Svelte Entry"] +PY_PROVIDER["Backend IconFontProvider"] --> SV_PROVIDER["Svelte Provider Entry"] +SV_ICON --> REACT_ICON["React Icon Implementation"] +SV_PROVIDER --> REACT_PROVIDER["React Provider Implementation"] +REACT_ICON --> AD["@ant-design/icons"] +REACT_PROVIDER --> ADIF["createFromIconfontCN"] +``` + +Diagram Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:5-6](file://backend/modelscope_studio/components/antd/icon/__init__.py#L5-L6) +- [frontend/antd/icon/icon.tsx:5-5](file://frontend/antd/icon/icon.tsx#L5-L5) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:4-6](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L4-L6) + +Section Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:5-6](file://backend/modelscope_studio/components/antd/icon/__init__.py#L5-L6) +- [frontend/antd/icon/icon.tsx:5-5](file://frontend/antd/icon/icon.tsx#L5-L5) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:4-6](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L4-L6) + +## Performance and Optimization + +- Lazy Loading and Async Rendering + - Svelte entry uses async import for Icon and Provider, avoiding first-screen blocking +- Instance Caching + - Provider internally caches IconFont instances based on scriptUrl and extraCommonProps equality, reducing repeated initialization +- Render Path Short-circuit + - When custom Slot exists, directly renders custom component, skipping built-in icon resolution +- Recommendations + - For pages with many icons, prioritize using IconFont and centrally managing scriptUrl + - Reasonably set extraCommonProps to avoid frequent instance rebuilding + - Avoid mixing too many different script sources under the same Provider, reducing context switching cost + +Section Source + +- [frontend/antd/icon/Index.svelte:10-10](file://frontend/antd/icon/Index.svelte#L10-L10) +- [frontend/antd/icon/iconfont-provider/Index.svelte:8-9](file://frontend/antd/icon/iconfont-provider/Index.svelte#L8-L9) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:18-35](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L18-L35) + +## Accessibility + +- Semantic Recommendations + - If the icon carries interactive semantics (like "delete", "search"), it should be accompanied by readable text or aria-label + - For decorative icons, use aria-hidden or add no extra semantics +- Screen Readers + - Keep icons with alternative text (for example, through adjacent text or title attribute) + - Avoid relying solely on color to convey information +- Styles and Focus + - Click-type icons need to ensure focusable and keyboard accessible + - Rotation/animation should not affect accessibility experience + +[This section provides general guidance, no specific file references needed] + +## Troubleshooting + +- Icon Not Displaying + - Check whether value is a valid built-in icon name or IconFont type name + - If using Provider, confirm scriptUrl is correct and network accessible +- Custom Component Not Working + - Confirm that custom rendering is correctly injected using "component" Slot + - Check Slot name case and passing path +- Repeated Requests or Instance Jitter + - Frequent changes to Provider's extraCommonProps or scriptUrl will cause instance rebuilding + - Recommend fixing parameters or merging multiple script sources + +Section Source + +- [frontend/antd/icon/icon.tsx:32-51](file://frontend/antd/icon/icon.tsx#L32-L51) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:18-35](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L18-L35) + +## Conclusion + +This component uses a "backend component + frontend async rendering" pattern, balancing unified access to both Ant Design built-in icons and custom icon fonts like iconfont.cn. Through Slot mechanism and context caching, it satisfies both flexible extension and ensures performance and maintainability. It is recommended to centrally manage icon font resources and style parameters in projects, combining with accessibility guidelines to improve user experience. + +[This section is a summary, no specific file references needed] + +## Appendix: Usage Examples and Best Practices + +### Basic Usage and Built-in Icons + +- Scenarios: Inline icons, button icons, status icons +- Example Reference + - [docs/components/antd/icon/demos/basic.py:9-17](file://docs/components/antd/icon/demos/basic.py#L9-L17) + +Best Practices + +- Provide click callbacks and readable text for interactive icons +- Use twoToneColor to control two-tone icon primary color, maintaining brand consistency + +Section Source + +- [docs/components/antd/icon/demos/basic.py:9-17](file://docs/components/antd/icon/demos/basic.py#L9-L17) + +### Using iconfont.cn + +- Scenarios: Enterprise icon libraries, third-party icon fonts +- Example Reference + - [docs/components/antd/icon/demos/iconfont.py:9-18](file://docs/components/antd/icon/demos/iconfont.py#L9-L18) + +Best Practices + +- Merge multiple script sources into an array to reduce request count +- Set common properties like color, fontSize uniformly through extraCommonProps +- Wrap the set of icons that need to use the font outside the Provider + +Section Source + +- [docs/components/antd/icon/demos/iconfont.py:9-18](file://docs/components/antd/icon/demos/iconfont.py#L9-L18) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:29-33](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L29-L33) + +### Custom Icon Library Integration + +- Option 1: Use "component" Slot to inject any custom rendering (text, SVG, components) + - Example Reference + - [docs/components/antd/icon/demos/basic.py:19-21](file://docs/components/antd/icon/demos/basic.py#L19-L21) +- Option 2: Connect custom fonts through IconFontProvider + - Example Reference + - [docs/components/antd/icon/demos/iconfont.py:9-18](file://docs/components/antd/icon/demos/iconfont.py#L9-L18) + +Best Practices + +- Keep Slot rendering lightweight, avoid executing complex logic on icons +- Prefer localizing font resources or using stable CDN to reduce loading failure risk + +Section Source + +- [docs/components/antd/icon/demos/basic.py:19-21](file://docs/components/antd/icon/demos/basic.py#L19-L21) +- [docs/components/antd/icon/demos/iconfont.py:9-18](file://docs/components/antd/icon/demos/iconfont.py#L9-L18) + +### Configuration Quick Reference + +- AntdIcon (Backend) + - value: Icon name + - spin: Rotation animation + - rotate: Rotation angle + - twoToneColor: Two-tone primary color + - component: Root node component placeholder + - elem_style/elem_classes: Element styles and class names + - visible/render: Visibility and rendering control +- AntdIconIconfontProvider (Backend) + - script_url: Icon font script address (array) + - extra_common_props: Common properties (like color, fontSize) + +Section Source + +- [backend/modelscope_studio/components/antd/icon/**init**.py:27-68](file://backend/modelscope_studio/components/antd/icon/__init__.py#L27-L68) +- [frontend/antd/icon/iconfont-provider/iconfont-provider.tsx:12-12](file://frontend/antd/icon/iconfont-provider/iconfont-provider.tsx#L12-L12) diff --git a/.wiki/en/Ant Design Components/General Components/Typography.md b/.wiki/en/Ant Design Components/General Components/Typography.md new file mode 100644 index 00000000..3fef6aa3 --- /dev/null +++ b/.wiki/en/Ant Design Components/General Components/Typography.md @@ -0,0 +1,251 @@ +# Typography + + +**Files referenced in this document** +- [frontend/antd/typography/Base.svelte](file://frontend/antd/typography/Base.svelte) +- [frontend/antd/typography/typography.base.tsx](file://frontend/antd/typography/typography.base.tsx) +- [frontend/antd/typography/title/Index.svelte](file://frontend/antd/typography/title/Index.svelte) +- [frontend/antd/typography/paragraph/Index.svelte](file://frontend/antd/typography/paragraph/Index.svelte) +- [frontend/antd/typography/text/Index.svelte](file://frontend/antd/typography/text/Index.svelte) +- [frontend/antd/typography/link/Index.svelte](file://frontend/antd/typography/link/Index.svelte) +- [docs/components/antd/typography/README.md](file://docs/components/antd/typography/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Typography component is used to present text content such as headings, paragraphs, inline text, and links in the interface, unifying text hierarchy, readability, and consistency in the design system. This component is wrapped based on Ant Design's Typography capabilities, providing interactive features such as copyable, editable, and ellipsis, and integrates with Gradio through the Svelte component system, supporting dynamic values and slot-based extensions. + +## Project Structure + +Typography uses an organization of "sub-components + base bridge layer" on the frontend side: + +- Base.svelte: Svelte layer entry, responsible for property processing, slot pass-through, and rendering condition control +- typography.base.tsx: React bridge layer, uniformly scheduling Ant Design Typography component types, and injecting advanced capabilities like copyable/editable/ellipsis +- title/paragraph/text/link: Four specific semantic sub-components, mapping to Ant Design's Title/Paragraph/Text/Link respectively + +```mermaid +graph TB +subgraph "Svelte Layer" +Base["Base.svelte"] +Title["title/Index.svelte"] +Paragraph["paragraph/Index.svelte"] +Text["text/Index.svelte"] +Link["link/Index.svelte"] +end +subgraph "React Bridge Layer" +Bridge["typography.base.tsx"] +end +subgraph "Ant Design" +ADT["Typography.Title/Paragraph/Text/Link"] +end +Title --> Base +Paragraph --> Base +Text --> Base +Link --> Base +Base --> Bridge +Bridge --> ADT +``` + +Diagram Source + +- [frontend/antd/typography/Base.svelte:11-84](file://frontend/antd/typography/Base.svelte#L11-L84) +- [frontend/antd/typography/typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) + +Section Source + +- [frontend/antd/typography/Base.svelte:1-85](file://frontend/antd/typography/Base.svelte#L1-L85) +- [frontend/antd/typography/typography.base.tsx:1-170](file://frontend/antd/typography/typography.base.tsx#L1-L170) + +## Core Components + +- Base.svelte: Responsible for extracting from Gradio properties and converting to React-consumable props; handling visibility, DOM ID/class names, extra properties, and slots; rendering base bridge layer on demand +- typography.base.tsx: Selects corresponding Ant Design component based on component type; uniformly handles copyable, editable, and ellipsis configuration and slots; injects component instance and style class names to output +- Four semantic sub-components: title, paragraph, text, link, all using Base as carrier, only needing to specify component + +Section Source + +- [frontend/antd/typography/Base.svelte:15-62](file://frontend/antd/typography/Base.svelte#L15-L62) +- [frontend/antd/typography/typography.base.tsx:19-80](file://frontend/antd/typography/typography.base.tsx#L19-L80) +- [frontend/antd/typography/title/Index.svelte:1-12](file://frontend/antd/typography/title/Index.svelte#L1-L12) +- [frontend/antd/typography/paragraph/Index.svelte:1-12](file://frontend/antd/typography/paragraph/Index.svelte#L1-L12) +- [frontend/antd/typography/text/Index.svelte:1-12](file://frontend/antd/typography/text/Index.svelte#L1-L12) +- [frontend/antd/typography/link/Index.svelte:1-12](file://frontend/antd/typography/link/Index.svelte#L1-L12) + +## Architecture Overview + +The diagram below shows the call chain from Svelte to React and then to Ant Design Typography, as well as the assembly process of copyable/editable/ellipsis. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Sub-component
title/paragraph/text/link" +participant Base as "Base.svelte" +participant Bridge as "typography.base.tsx" +participant AD as "Ant Design Typography" +Svelte->>Base : Pass props + slots +Base->>Bridge : Convert and merge props +Bridge->>Bridge : Parse copyable/editable/ellipsis config and slots +Bridge->>AD : Render corresponding component (Title/Paragraph/Text/Link) +AD-->>Bridge : Return component with assembled interactive capabilities +Bridge-->>Base : Output final node +Base-->>Svelte : Render result +``` + +Diagram Source + +- [frontend/antd/typography/Base.svelte:65-84](file://frontend/antd/typography/Base.svelte#L65-L84) +- [frontend/antd/typography/typography.base.tsx:69-163](file://frontend/antd/typography/typography.base.tsx#L69-L163) + +## Detailed Component Analysis + +### Base Bridge Layer (typography.base.tsx) + +- Component Selection Logic: Switches among Title/Paragraph/Text/Link based on component value +- Capability Assembly: + - Copy (copyable): Supports custom icons, tooltips, or injection through slots + - Edit (editable): Supports edit icon, tooltip, and enter icon slot-based replacement + - Ellipsis (ellipsis): Supports ellipsis symbol and tooltip slot-based replacement; has special toggle behavior for link component +- Slot and Target Resolution: Uses useTargets to identify targets with specific slot markers in children, then renders with ReactSlot +- Class Name and Style: Appends namespace class name on top of original className, facilitating theme and override + +```mermaid +flowchart TD +Start(["Enter bridge layer"]) --> Choose["Select Ant Design component based on component"] +Choose --> Copyable{"Enable copy capability?"} +Copyable --> |Yes| BuildCopy["Merge config and inject icon/tooltip slots"] +Copyable --> |No| SkipCopy["Skip copy config"] +Choose --> Editable{"Enable edit capability?"} +Editable --> |Yes| BuildEdit["Inject edit icon/tooltip/enter icon slots"] +Editable --> |No| SkipEdit["Skip edit config"] +Choose --> Ellipsis{"Enable ellipsis capability?"} +Ellipsis --> |Yes| BuildEllipsis["Inject ellipsis symbol/tooltip slots"] +Ellipsis --> |No| SkipEllipsis["Skip ellipsis config"] +BuildCopy --> Render["Render final component"] +BuildEdit --> Render +BuildEllipsis --> Render +SkipCopy --> Render +SkipEdit --> Render +SkipEllipsis --> Render +Render --> End(["Return render result"]) +``` + +Diagram Source + +- [frontend/antd/typography/typography.base.tsx:40-167](file://frontend/antd/typography/typography.base.tsx#L40-L167) + +Section Source + +- [frontend/antd/typography/typography.base.tsx:19-167](file://frontend/antd/typography/typography.base.tsx#L19-L167) + +### Svelte Entry (Base.svelte) + +- Property Processing: Gets component properties from Gradio, filters internal fields, preserves externally available props +- Slot Processing: Collects and passes through slots, while distinguishing value and children for rendering +- Conditional Rendering: Controls display based on visible; supports directly rendering children in layout mode +- DOM Properties: Injects elem_id, elem_classes, elem_style, etc. + +Section Source + +- [frontend/antd/typography/Base.svelte:15-62](file://frontend/antd/typography/Base.svelte#L15-L62) +- [frontend/antd/typography/Base.svelte:65-84](file://frontend/antd/typography/Base.svelte#L65-L84) + +### Semantic Sub-components (title/paragraph/text/link) + +- All render through Base.svelte, only needing to set component to switch semantics and hierarchy +- Support both children slot and value dynamic value as content sources +- Have independent toggle logic for link component's ellipsis behavior + +Section Source + +- [frontend/antd/typography/title/Index.svelte:1-12](file://frontend/antd/typography/title/Index.svelte#L1-L12) +- [frontend/antd/typography/paragraph/Index.svelte:1-12](file://frontend/antd/typography/paragraph/Index.svelte#L1-L12) +- [frontend/antd/typography/text/Index.svelte:1-12](file://frontend/antd/typography/text/Index.svelte#L1-L12) +- [frontend/antd/typography/link/Index.svelte:1-12](file://frontend/antd/typography/link/Index.svelte#L1-L12) + +## Dependency Analysis + +- Component Coupling + - Sub-components only depend on Base.svelte, maintaining low coupling and high cohesion + - Base.svelte depends on bridge layer, responsible for cross-framework (Svelte → React) adaptation + - Bridge layer depends on Ant Design Typography, centrally handling interactive capabilities +- Slot and Target Resolution + - Uses useTargets and ReactSlot to implement slot-based capability injection, avoiding hardcoding +- External Dependencies + - Ant Design Typography: Provides basic capabilities for headings, paragraphs, text, and links + - Gradio/Svelte preprocessing tools: Provide property processing, slot context, and async component loading + +```mermaid +graph LR +Title["title/Index.svelte"] --> Base["Base.svelte"] +Paragraph["paragraph/Index.svelte"] --> Base +Text["text/Index.svelte"] --> Base +Link["link/Index.svelte"] --> Base +Base --> Bridge["typography.base.tsx"] +Bridge --> AD["Ant Design Typography"] +``` + +Diagram Source + +- [frontend/antd/typography/title/Index.svelte:9](file://frontend/antd/typography/title/Index.svelte#L9) +- [frontend/antd/typography/paragraph/Index.svelte:9](file://frontend/antd/typography/paragraph/Index.svelte#L9) +- [frontend/antd/typography/text/Index.svelte:9](file://frontend/antd/typography/text/Index.svelte#L9) +- [frontend/antd/typography/link/Index.svelte:9](file://frontend/antd/typography/link/Index.svelte#L9) +- [frontend/antd/typography/Base.svelte:11-13](file://frontend/antd/typography/Base.svelte#L11-L13) +- [frontend/antd/typography/typography.base.tsx:8](file://frontend/antd/typography/typography.base.tsx#L8) + +Section Source + +- [frontend/antd/typography/Base.svelte:11-13](file://frontend/antd/typography/Base.svelte#L11-L13) +- [frontend/antd/typography/typography.base.tsx:8](file://frontend/antd/typography/typography.base.tsx#L8) + +## Performance Considerations + +- Async Component Loading: Base.svelte loads bridge layer lazily through importComponent, reducing first-screen size +- Conditional Rendering: Only renders when visible is true; assembles ellipsis tooltip on demand, reducing unnecessary overhead +- Slot Rendering: Through useTargets and ReactSlot, only renders actually matched slot content, avoiding full traversal + +Section Source + +- [frontend/antd/typography/Base.svelte:11-13](file://frontend/antd/typography/Base.svelte#L11-L13) +- [frontend/antd/typography/typography.base.tsx:51-64](file://frontend/antd/typography/typography.base.tsx#L51-L64) + +## Troubleshooting Guide + +- Text Not Displaying + - Check whether Base.svelte's visible field is true + - Confirm whether children or value is correctly passed in +- Copy/Edit/Ellipsis Button Not Working + - Confirm whether copyable/editable/ellipsis configuration object or slots are correctly passed in + - For link component, confirm ellipsis enable condition +- Slot Icon/Tooltip Not Appearing + - Check whether slot key names match (like copyable.icon, copyable.tooltips, editable.icon, etc.) + - Confirm useTargets can correctly identify slot markers in children +- Style Abnormal + - Confirm whether elem_classes and elem_style are correctly injected + - Check whether namespace class names are overridden + +Section Source + +- [frontend/antd/typography/Base.svelte:30-62](file://frontend/antd/typography/Base.svelte#L30-L62) +- [frontend/antd/typography/typography.base.tsx:40-167](file://frontend/antd/typography/typography.base.tsx#L40-L167) + +## Conclusion + +The Typography component effectively connects Svelte with Ant Design capabilities through clear layered design, ensuring both semantics and maintainability, while providing rich interactive capabilities like copy, edit, and ellipsis. Its slot-based and conditional assembly mechanism enables good extensibility and performance in different scenarios. + +## Appendix + +- Usage examples and instructions can be found in the documentation page's example placeholder + - [docs/components/antd/typography/README.md:5-8](file://docs/components/antd/typography/README.md#L5-L8) diff --git a/.wiki/en/Ant Design Components/Layout Components/Divider.md b/.wiki/en/Ant Design Components/Layout Components/Divider.md new file mode 100644 index 00000000..5bcfcfde --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Divider.md @@ -0,0 +1,291 @@ +# Divider + + +**Files referenced in this document** +- [divider.tsx](file://frontend/antd/divider/divider.tsx) +- [Index.svelte](file://frontend/antd/divider/Index.svelte) +- [__init__.py](file://backend/modelscope_studio/components/antd/divider/__init__.py) +- [components.py](file://backend/modelscope_studio/components/antd/components.py) +- [README.md](file://docs/components/antd/divider/README.md) +- [README-zh_CN.md](file://docs/components/antd/divider/README-zh_CN.md) +- [basic.py](file://docs/components/antd/divider/demos/basic.py) +- [basic.py (form)](file://docs/components/antd/form/demos/basic.py) +- [basic.py (layout)](file://docs/components/antd/layout/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Accessibility](#performance-and-accessibility) +8. [Usage Scenarios and Examples](#usage-scenarios-and-examples) +9. [Troubleshooting](#troubleshooting) +10. [Conclusion](#conclusion) + +## Introduction + +The Divider component creates visual separation between content sections, helping users quickly identify information blocks. Based on Ant Design's Divider, it supports horizontal and vertical orientations, multiple line styles (solid, dashed, dotted), centered and left/right-aligned title text, plain text style, and provides a flexible style override interface for consistent styling across different layouts and themes. + +## Project Structure + +The Divider component consists of a backend Python component class and a frontend Svelte wrapper. Props are passed in a Gradio-style through to the Ant Design React component, which is ultimately rendered as a visible divider in the browser. + +```mermaid +graph TB +subgraph "Backend" +PY_INIT["AntdDivider.__init__()
Python component class"] +PY_EXPORT["components.py export"] +end +subgraph "Frontend" +SVELTE_INDEX["Index.svelte
Prop handling and rendering"] +TS_WRAPPER["divider.tsx
sveltify wrapper"] +ANTD_REACT["antd.Divider
Ant Design React component"] +end +PY_INIT --> PY_EXPORT +PY_EXPORT --> SVELTE_INDEX +SVELTE_INDEX --> TS_WRAPPER +TS_WRAPPER --> ANTD_REACT +``` + +Diagram sources + +- [**init**.py:1-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L1-L95) +- [components.py:37-37](file://backend/modelscope_studio/components/antd/components.py#L37-L37) +- [Index.svelte:1-75](file://frontend/antd/divider/Index.svelte#L1-L75) +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) + +Section sources + +- [**init**.py:1-95](file://backend/modelscope_studio/components/antd/divider/__init__.py#L1-L95) +- [components.py:37-37](file://backend/modelscope_studio/components/antd/components.py#L37-L37) +- [Index.svelte:1-75](file://frontend/antd/divider/Index.svelte#L1-L75) +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) + +## Core Components + +- Backend component class: `AntdDivider`, responsible for defining props, default values, styles, and rendering strategy, and declaring frontend resource paths. +- Frontend wrapper: `Index.svelte` handles prop merging, style injection, and conditional rendering. `divider.tsx` uses `sveltify` to bridge Ant Design's React Divider as a Svelte-compatible component. + +Key responsibilities + +- Prop mapping: Maps Python-layer props (`dashed`, `variant`, `orientation`, `orientation_margin`, `plain`, `type`, `size`, `value`, `elem_style`, `elem_classes`, etc.) to the React Divider. +- Rendering branch: Determines whether to render a divider with text or a plain line based on whether `children` or `value` is provided. +- Style injection: Injects custom styles and class names via `elem_style` and `elem_classes`. + +Section sources + +- [**init**.py:21-76](file://backend/modelscope_studio/components/antd/divider/__init__.py#L21-L76) +- [Index.svelte:23-57](file://frontend/antd/divider/Index.svelte#L23-L57) +- [divider.tsx:5-12](file://frontend/antd/divider/divider.tsx#L5-L12) + +## Architecture Overview + +The diagram below shows the call chain and data flow from the Python component to the browser rendering. + +```mermaid +sequenceDiagram +participant Py as "Python Backend
AntdDivider" +participant Svelte as "Frontend
Index.svelte" +participant Wrapper as "Wrapper
divider.tsx" +participant AD as "Ant Design React
Divider" +Py->>Svelte : Pass props and value +Svelte->>Svelte : Process visible, styles, additional props +Svelte->>Wrapper : Render React Divider +Wrapper->>AD : Pass props including children/value +AD-->>Wrapper : Render DOM +Wrapper-->>Svelte : Return node +Svelte-->>Py : Complete one render +``` + +Diagram sources + +- [**init**.py:77-77](file://backend/modelscope_studio/components/antd/divider/__init__.py#L77-L77) +- [Index.svelte:60-74](file://frontend/antd/divider/Index.svelte#L60-L74) +- [divider.tsx:5-12](file://frontend/antd/divider/divider.tsx#L5-L12) + +## Detailed Component Analysis + +### Props and Configuration + +- Type and orientation + - `type`: horizontal | vertical — controls horizontal or vertical divider. + - `size`: small | middle | large (horizontal only) — affects the overall visual size. +- Line style + - `variant`: dashed | dotted | solid — controls the line style. + - `dashed`: boolean toggle (legacy compatibility), equivalent to `variant=dashed`. +- Text and alignment + - `value` or slot content: text displayed on the divider. + - `orientation`: left | right | center | start | end — controls text position. + - `orientation_margin`: number or string (parsed with unit if provided, as px otherwise) — sets the margin between text and edge. + - `plain`: whether to display text in plain style. +- Style and appearance + - `elem_style`: inject inline styles (e.g., `borderColor`). + - `elem_classes`: inject additional CSS classes. + - `root_class_name`: root element class name (passed by parent container). + - `additional_props`: other passthrough props. +- Layout and visibility + - `visible`: controls whether the component is rendered. + - `as_item`, `_internal`, `render`, etc.: framework-internal props that affect rendering context. + +Section sources + +- [**init**.py:21-76](file://backend/modelscope_studio/components/antd/divider/__init__.py#L21-L76) +- [Index.svelte:13-57](file://frontend/antd/divider/Index.svelte#L13-L57) + +### Rendering Logic and Branches + +- When children or `value` is present, renders a divider with text. +- Otherwise renders a plain line divider. +- Supports direct child node rendering in inner layout mode. + +```mermaid +flowchart TD +Start(["Enter render"]) --> CheckVisible{"visible is true?"} +CheckVisible --> |No| EndHidden["Do not render"] +CheckVisible --> |Yes| CheckInternal{"Inner layout mode?"} +CheckInternal --> |Yes| RenderWithChildren["Render Divider with children"] +CheckInternal --> |No| CheckValue{"Has value?"} +CheckValue --> |Yes| RenderWithValue["Render Divider with value"] +CheckValue --> |No| RenderPlain["Render plain line Divider"] +RenderWithChildren --> End(["Done"]) +RenderWithValue --> End +RenderPlain --> End +EndHidden --> End +``` + +Diagram sources + +- [Index.svelte:60-74](file://frontend/antd/divider/Index.svelte#L60-L74) + +### Text Centering and Alignment + +- Use `orientation=center` (or equivalent `start`/`end`) to center text. +- Use `orientation=left`/`right` or `orientation=start`/`end` combined with `orientation_margin` to control the spacing between text and edge. +- With `plain=True`, text is rendered in a lighter style, suitable for smaller font sizes or subtle hints. + +Section sources + +- [**init**.py:27-32](file://backend/modelscope_studio/components/antd/divider/__init__.py#L27-L32) +- [basic.py:11-26](file://docs/components/antd/divider/demos/basic.py#L11-L26) + +### Style Customization and Color Configuration + +- Inject `borderColor`, `borderWidth`, and other styles via `elem_style` for color and thickness customization. +- Inject custom CSS classes via `elem_classes` for complex theming needs. +- `variant` and `dashed` provide line style switching (solid/dashed/dotted). + +Section sources + +- [basic.py:11-26](file://docs/components/antd/divider/demos/basic.py#L11-L26) +- [**init**.py:26-32](file://backend/modelscope_studio/components/antd/divider/__init__.py#L26-L32) + +### Responsive Behavior and Screen Adaptation + +- The component does not have built-in media query logic, but responsive behavior can be achieved through `elem_style` and layout containers (such as Flex and Layout). +- In horizontal layouts, `size` can subtly adjust the overall visual size; in vertical layouts, `size` has no effect. +- On narrow screens, adjust `orientation` and margin in combination with container width and text length to avoid text truncation. + +Section sources + +- [**init**.py:32-34](file://backend/modelscope_studio/components/antd/divider/__init__.py#L32-L34) +- [basic.py (layout):42-88](file://docs/components/antd/layout/demos/basic.py#L42-L88) + +## Dependency Analysis + +- Backend export: `AntdDivider` is exported in the antd component collection for modular usage. +- Frontend bridging: `Index.svelte` dynamically loads `divider.tsx` via `importComponent`. The latter uses `sveltify` to wrap Ant Design's React Divider as a Svelte component. +- Prop passthrough: All props except framework-reserved fields are passed through to the React Divider, maintaining consistency with the Ant Design API. + +```mermaid +graph LR +A["components.py"] --> B["AntdDivider.__init__"] +B --> C["FRONTEND_DIR=resolve_frontend_dir('divider')"] +C --> D["Index.svelte"] +D --> E["divider.tsx"] +E --> F["antd.Divider"] +``` + +Diagram sources + +- [components.py:37-37](file://backend/modelscope_studio/components/antd/components.py#L37-L37) +- [**init**.py:77-77](file://backend/modelscope_studio/components/antd/divider/__init__.py#L77-L77) +- [Index.svelte:10-10](file://frontend/antd/divider/Index.svelte#L10-L10) +- [divider.tsx:3-3](file://frontend/antd/divider/divider.tsx#L3-L3) + +Section sources + +- [components.py:37-37](file://backend/modelscope_studio/components/antd/components.py#L37-L37) +- [**init**.py:77-77](file://backend/modelscope_studio/components/antd/divider/__init__.py#L77-L77) +- [Index.svelte:10-10](file://frontend/antd/divider/Index.svelte#L10-L10) +- [divider.tsx:3-3](file://frontend/antd/divider/divider.tsx#L3-L3) + +## Performance and Accessibility + +- Rendering overhead: The component is a lightweight pure display element. Dynamic import and conditional rendering avoid unnecessary repaints. +- Accessibility: Text content is rendered with semantic tags. For important dividers, providing a short description (e.g., `aria-label`) is recommended to improve screen reader experience. +- Theme consistency: Unify styles via `elem_style` and `elem_classes` to reduce redundant computations and style conflicts. + +[This section contains general recommendations and does not require specific file references] + +## Usage Scenarios and Examples + +### Form Grouping + +- Use dividers to group different business domains within a form, improving readability. +- Example reference: The form demo shows dividers used between form controls. + +Section sources + +- [basic.py (form):16-90](file://docs/components/antd/form/demos/basic.py#L16-L90) + +### Content Area Separation + +- Use horizontal dividers in articles or pages to separate paragraphs. Use `orientation=center` for title-style separators. +- Example reference: The basic demo shows different variants and dividers with text. + +Section sources + +- [basic.py:5-29](file://docs/components/antd/divider/demos/basic.py#L5-L29) + +### Navigation Menu Separation + +- Use vertical or horizontal dividers to separate menu items in navigation lists. On narrow screens, adjust `orientation` and margin to avoid text overflow. +- Recommendation: Prefer vertical dividers for side navigation and horizontal dividers for top or bottom navigation. + +[This subsection is conceptual; no specific file references required] + +### Behavior in Responsive Layouts + +- Use layout components like Flex and Layout to adjust divider orientation and text length at different screen sizes. +- Recommendation: On mobile, prefer horizontal dividers with shorter text. If necessary, hide the text and keep only the line. + +Section sources + +- [basic.py (layout):42-88](file://docs/components/antd/layout/demos/basic.py#L42-L88) + +## Troubleshooting + +- Text not displayed + - Check whether `value` or child content has been passed. If not, the component renders a plain line. + - Confirm that `visible` is `True`. +- Text position incorrect + - When `orientation` is set to left/right/start/end, use `orientation_margin` to adjust spacing. + - `plain` affects the visual weight of the text. Remove it if stronger separation is needed. +- Line style not applied + - `dashed` and `variant=dashed` are equivalent. Ensure no conflicting props are set simultaneously. + - `borderColor`, `borderWidth`, and other styles in `elem_style` must be compatible with the target platform. +- Vertical divider size not working + - `size` only applies to horizontal dividers. For vertical dividers, control the visual size via container width and border properties. + +Section sources + +- [Index.svelte:60-74](file://frontend/antd/divider/Index.svelte#L60-L74) +- [**init**.py:26-34](file://backend/modelscope_studio/components/antd/divider/__init__.py#L26-L34) + +## Conclusion + +The Divider component provides rich visual expression through a clean API, capable of both basic line separation and title-style dividers with text. Through multi-dimensional configuration of type, line style, alignment, and styling, it reliably implements information hierarchy and spatial separation across different layouts and themes. In practice, it is recommended to combine layout containers with responsive strategies, choose `orientation` and `size` appropriately, and use `elem_style`/`elem_classes` for brand and theme customization. diff --git a/.wiki/en/Ant Design Components/Layout Components/Flex.md b/.wiki/en/Ant Design Components/Layout Components/Flex.md new file mode 100644 index 00000000..8bb5cf98 --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Flex.md @@ -0,0 +1,291 @@ +# Flex + + +**Files referenced in this document** +- [frontend/antd/flex/flex.tsx](file://frontend/antd/flex/flex.tsx) +- [frontend/antd/flex/Index.svelte](file://frontend/antd/flex/Index.svelte) +- [backend/modelscope_studio/components/antd/flex/__init__.py](file://backend/modelscope_studio/components/antd/flex/__init__.py) +- [docs/components/antd/flex/README.md](file://docs/components/antd/flex/README.md) +- [docs/components/antd/flex/demos/basic.py](file://docs/components/antd/flex/demos/basic.py) +- [docs/components/antd/flex/demos/align.py](file://docs/components/antd/flex/demos/align.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides a systematic description of the Flex layout component and its implementation and usage in ModelScope Studio. The Flex component is based on Ant Design's Flex container, offering main axis and cross axis alignment, layout direction, wrapping control, spacing configuration, and is bridged between frontend and backend via the Gradio ecosystem. The document covers the following topics from concept to practice: + +- Core concepts: main axis/cross axis, and correspondence to justify-content, align-items, align-content +- Key props: orientation/vertical, wrap, justify, align, flex, gap +- Practical scenarios: button group alignment, content area distribution, responsive card layouts +- Complex nested layouts and best practices +- Compatibility and cross-browser considerations + +## Project Structure + +The Flex component in this repository uses a layered design of "backend Python component + frontend Svelte wrapper + Ant Design Flex container": + +- Backend: Python class responsible for parameter validation, rendering strategy, and frontend resource location +- Frontend: Svelte component responsible for dynamic import, prop passthrough, and style concatenation +- Dependencies: React/Ant Design components are bridged to Svelte via `svelte-preprocess-react` + +```mermaid +graph TB +subgraph "Backend" +PY["AntdFlex
Python component"] +DEV["ModelScopeLayoutComponent
Base layout component"] +end +subgraph "Frontend" +IDX["Index.svelte
Dynamic import wrapper"] +FLEX_TS["flex.tsx
sveltify wrapper"] +ANTDFLEX["Ant Design Flex
Container"] +end +subgraph "Docs and Examples" +DOC["README.md"] +DEMO1["basic.py example"] +DEMO2["align.py example"] +end +PY --> IDX +DEV --> PY +IDX --> FLEX_TS +FLEX_TS --> ANTDFLEX +DOC --> DEMO1 +DOC --> DEMO2 +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:8-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L8-L98) +- [frontend/antd/flex/Index.svelte:10-61](file://frontend/antd/flex/Index.svelte#L10-L61) +- [frontend/antd/flex/flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [docs/components/antd/flex/README.md:1-9](file://docs/components/antd/flex/README.md#L1-L9) + +Section sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:8-98](file://backend/modelscope_studio/components/antd/flex/__init__.py#L8-L98) +- [frontend/antd/flex/Index.svelte:1-62](file://frontend/antd/flex/Index.svelte#L1-L62) +- [frontend/antd/flex/flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [docs/components/antd/flex/README.md:1-9](file://docs/components/antd/flex/README.md#L1-L9) + +## Core Components + +- AntdFlex (backend) + - Receives and validates all Flex-related parameters (direction, wrapping, main axis/cross axis alignment, flex shorthand, gap, etc.) and maps them to frontend-consumable props. + - Provides `FRONTEND_DIR` pointing to the frontend flex directory, ensuring the frontend component is loaded correctly at runtime. + - Follows the layout semantics of `ModelScopeLayoutComponent` and participates in the application-level layout context. + +- Index.svelte (frontend wrapper) + - Dynamically imports the frontend flex component via `importComponent`, avoiding first-screen blocking. + - Retrieves and processes component props via `getProps`/`processProps`, supporting additional prop passthrough and visibility control. + - Injects generic props like `elem_id`, `elem_classes`, and `elem_style` into the final render node. + +- flex.tsx (Svelte wrapper) + - Uses `sveltify` to convert Ant Design's Flex container into a Svelte-compatible component, passing props and children through directly. + +- Docs and examples + - `README.md` provides basic description and example placeholders. + - `basic.py` and `align.py` demonstrate interactive examples for vertical/horizontal direction switching and main axis/cross axis alignment. + +Section sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:21-79](file://backend/modelscope_studio/components/antd/flex/__init__.py#L21-L79) +- [frontend/antd/flex/Index.svelte:13-42](file://frontend/antd/flex/Index.svelte#L13-L42) +- [frontend/antd/flex/flex.tsx:4-8](file://frontend/antd/flex/flex.tsx#L4-L8) +- [docs/components/antd/flex/README.md:1-9](file://docs/components/antd/flex/README.md#L1-L9) +- [docs/components/antd/flex/demos/basic.py:8-23](file://docs/components/antd/flex/demos/basic.py#L8-L23) +- [docs/components/antd/flex/demos/align.py:8-41](file://docs/components/antd/flex/demos/align.py#L8-L41) + +## Architecture Overview + +The diagram below shows the call chain from user code to the final render, illustrating the collaboration between the Flex component's frontend and backend: + +```mermaid +sequenceDiagram +participant U as "User code" +participant PY as "AntdFlex (backend)" +participant IDX as "Index.svelte (frontend wrapper)" +participant F as "flex.tsx (Svelte wrapper)" +participant AD as "Ant Design Flex" +U->>PY : Create AntdFlex and pass params +PY->>IDX : Resolve FRONTEND_DIR and render +IDX->>F : Dynamically import Antd Flex component +F->>AD : Pass through props and children +AD-->>U : Rendered flexible layout container +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:81-81](file://backend/modelscope_studio/components/antd/flex/__init__.py#L81-L81) +- [frontend/antd/flex/Index.svelte:10-10](file://frontend/antd/flex/Index.svelte#L10-L10) +- [frontend/antd/flex/flex.tsx:4-8](file://frontend/antd/flex/flex.tsx#L4-L8) + +## Detailed Component Analysis + +### Backend Class: AntdFlex Props and Behavior + +- Key props + - `orientation`/`vertical`: controls layout direction (horizontal/vertical) + - `wrap`: controls single-line or multi-line display + - `justify`: main axis alignment (start/end/center/flex-start/flex-end/space-\* etc.) + - `align`: cross axis alignment (start/end/center/flex-start/flex-end/baseline/stretch etc.) + - `flex`: flex shorthand property + - `gap`: element spacing (small/middle/large or numeric value) + - `component`/`root_class_name`/`class_names`/`styles`/`as_item`/`_internal`: generic props and style injection + - Visibility and DOM injection: `elem_id`/`elem_classes`/`elem_style`/`visible`/`render` + +- Behavioral characteristics + - `skip_api=True`: not exposed as a standard API component; suitable for internal layout use + - `FRONTEND_DIR` points to the frontend flex directory, ensuring component availability at runtime + - Inherits from `ModelScopeLayoutComponent`, providing layout context capabilities + +Section sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:21-79](file://backend/modelscope_studio/components/antd/flex/__init__.py#L21-L79) +- [backend/modelscope_studio/utils/dev/component.py:11-52](file://backend/modelscope_studio/utils/dev/component.py#L11-L52) + +### Frontend Wrapper: Index.svelte + +- Dynamic import: lazy-loads `flex.tsx` via `importComponent`, reducing first-screen overhead +- Prop processing: `getProps`/`processProps` extracts and merges component props, additional props, visibility, and DOM injection +- Style concatenation: `elem_classes` combined with fixed class names; `elem_id`/`elem_style` injected into the root node +- Conditional rendering: controls rendering based on `visible` + +Section sources + +- [frontend/antd/flex/Index.svelte:13-42](file://frontend/antd/flex/Index.svelte#L13-L42) +- [frontend/antd/flex/Index.svelte:48-61](file://frontend/antd/flex/Index.svelte#L48-L61) + +### Svelte Wrapper: flex.tsx + +- Uses `sveltify` to bridge Ant Design's Flex container as a Svelte component +- Passes props and children through directly, maintaining consistent semantics with Antd Flex + +Section sources + +- [frontend/antd/flex/flex.tsx:4-8](file://frontend/antd/flex/flex.tsx#L4-L8) + +### Examples: Basic and Alignment + +- `basic.py`: demonstrates vertical/horizontal direction switching and spacing configuration +- `align.py`: demonstrates main axis/cross axis alignment options and interactive updates + +Section sources + +- [docs/components/antd/flex/demos/basic.py:8-23](file://docs/components/antd/flex/demos/basic.py#L8-L23) +- [docs/components/antd/flex/demos/align.py:8-41](file://docs/components/antd/flex/demos/align.py#L8-L41) + +### Key Props and CSS Flex Correspondence + +- Main axis and cross axis + - Main axis: determined by layout direction (horizontal/vertical corresponds to row/column) + - Cross axis: perpendicular to the main axis +- Alignment mapping + - `justify-content` ↔ `justify` (main axis alignment) + - `align-items` ↔ `align` (cross axis alignment) + - `align-content` ↔ cross axis distribution for multi-line (effective when `wrap` is `wrap`/`wrap-reverse`) + +Section sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:52-58](file://backend/modelscope_studio/components/antd/flex/__init__.py#L52-L58) + +### Practical Application Scenarios + +- Button group alignment: use `justify`/`align` to quickly achieve horizontal or vertical centering, space-between, etc. +- Content area distribution: use `gap` and `wrap` for responsive grids with wrapping +- Responsive card layouts: combine `orientation`/`vertical` with `justify`/`align` for card flow arrangement + +Section sources + +- [docs/components/antd/flex/demos/basic.py:8-23](file://docs/components/antd/flex/demos/basic.py#L8-L23) +- [docs/components/antd/flex/demos/align.py:8-41](file://docs/components/antd/flex/demos/align.py#L8-L41) + +### Complex Nested Layouts and Best Practices + +- Nesting strategy + - Outer containers set main axis alignment and wrapping; inner containers focus on cross axis alignment + - Use `gap` to control spacing between levels, avoiding hard-coded margin/padding +- Best practices + - First use `vertical`/`orientation` to control direction, then fine-tune with `justify`/`align` + - In multi-line scenarios, choose `wrap` and `align-content` combinations carefully + - Combine with interactive components (such as Segmented) to dynamically switch alignment, improving discoverability + +Section sources + +- [docs/components/antd/flex/demos/align.py:8-41](file://docs/components/antd/flex/demos/align.py#L8-L41) + +## Dependency Analysis + +- Component coupling + - `AntdFlex` only depends on the frontend flex directory, resolved via `FRONTEND_DIR`, reducing coupling + - `Index.svelte` and `flex.tsx` are loosely coupled; the former handles runtime loading, the latter handles bridging +- External dependencies + - Ant Design Flex: provides core layout capability + - svelte-preprocess-react: provides `sveltify` and dynamic import utilities +- Potential circular dependencies + - No obvious circular dependencies in the current structure. Avoid inter-referencing backend components if extending in the future. + +```mermaid +graph LR +PY["AntdFlex (backend)"] --> |FRONTEND_DIR| FE["flex frontend directory"] +IDX["Index.svelte"] --> |dynamic import| FLEX_TS["flex.tsx"] +FLEX_TS --> |sveltify| AD["Ant Design Flex"] +``` + +Diagram sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:81-81](file://backend/modelscope_studio/components/antd/flex/__init__.py#L81-L81) +- [frontend/antd/flex/Index.svelte:10-10](file://frontend/antd/flex/Index.svelte#L10-L10) +- [frontend/antd/flex/flex.tsx:4-8](file://frontend/antd/flex/flex.tsx#L4-L8) + +Section sources + +- [backend/modelscope_studio/components/antd/flex/**init**.py:81-81](file://backend/modelscope_studio/components/antd/flex/__init__.py#L81-L81) +- [frontend/antd/flex/Index.svelte:10-10](file://frontend/antd/flex/Index.svelte#L10-L10) +- [frontend/antd/flex/flex.tsx:4-8](file://frontend/antd/flex/flex.tsx#L4-L8) + +## Performance Considerations + +- Dynamic import optimization: `Index.svelte` uses `importComponent` for lazy loading, reducing first-screen bundle size and render time +- Minimal prop passthrough: only necessary props are passed, avoiding redundant computation and reflow +- Spacing and wrapping: use `gap` and `wrap` appropriately to avoid complex layout reflows caused by excessive nesting + +## Troubleshooting Guide + +- Component not visible + - Check if `visible` is `true` + - Confirm that `elem_style`/`elem_classes` are not causing overflow or hidden behavior +- Direction and alignment issues + - Confirm that the combination of `orientation`/`vertical` and `justify`/`align` matches expectations + - In multi-line scenarios, check the effect of `wrap` and `align-content` +- Runtime load failure + - Confirm that `FRONTEND_DIR` points to the correct location and the frontend package is built + - Check for errors in the dynamic import (`{#await}` branch in `Index.svelte`) + +Section sources + +- [frontend/antd/flex/Index.svelte:48-61](file://frontend/antd/flex/Index.svelte#L48-L61) +- [backend/modelscope_studio/components/antd/flex/**init**.py:81-81](file://backend/modelscope_studio/components/antd/flex/__init__.py#L81-L81) + +## Conclusion + +The Flex layout component in ModelScope Studio is implemented as "backend params + frontend wrapper + Antd Flex container", maintaining semantic consistency with CSS Flex while providing good configurability and maintainability. Through key props such as `orientation`/`vertical`, `wrap`, `justify`, `align`, `flex`, and `gap`, it efficiently covers common scenarios including button group alignment, content area distribution, and responsive card layouts. Combined with dynamic import and prop passthrough mechanisms, it balances performance and flexibility. + +## Appendix + +- Example entry points + - Basic example: [basic.py:1-26](file://docs/components/antd/flex/demos/basic.py#L1-L26) + - Alignment example: [align.py:1-45](file://docs/components/antd/flex/demos/align.py#L1-L45) +- Documentation: [README.md:1-9](file://docs/components/antd/flex/README.md#L1-L9) diff --git a/.wiki/en/Ant Design Components/Layout Components/Grid.md b/.wiki/en/Ant Design Components/Layout Components/Grid.md new file mode 100644 index 00000000..51992779 --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Grid.md @@ -0,0 +1,348 @@ +# Grid + + +**Files referenced in this document** +- [frontend/antd/grid/row/Index.svelte](file://frontend/antd/grid/row/Index.svelte) +- [frontend/antd/grid/row/row.tsx](file://frontend/antd/grid/row/row.tsx) +- [frontend/antd/grid/col/Index.svelte](file://frontend/antd/grid/col/Index.svelte) +- [frontend/antd/grid/col/col.tsx](file://frontend/antd/grid/col/col.tsx) +- [frontend/antd/grid/context.ts](file://frontend/antd/grid/context.ts) +- [backend/modelscope_studio/components/antd/grid/row/__init__.py](file://backend/modelscope_studio/components/antd/grid/row/__init__.py) +- [backend/modelscope_studio/components/antd/grid/col/__init__.py](file://backend/modelscope_studio/components/antd/grid/col/__init__.py) +- [docs/components/antd/grid/README.md](file://docs/components/antd/grid/README.md) +- [docs/components/antd/grid/demos/basic.py](file://docs/components/antd/grid/demos/basic.py) +- [docs/components/antd/grid/demos/playground.py](file://docs/components/antd/grid/demos/playground.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides a systematic description of the Grid component, covering its design principles, the 24-column grid system, and responsive breakpoint configuration. It explains how to use Row and Col in depth (including grid offset, ordering, nesting rules, and alignment), provides application ideas for common scenarios such as dashboard layouts, product display pages, and form layouts, and includes responsive behavior descriptions and performance optimization recommendations. + +## Project Structure + +The Grid component is built through collaboration between a frontend Svelte wrapper layer and a backend Python component layer: the frontend handles rendering and context passing, while the backend handles parameter passthrough and lifecycle management. The docs side provides examples and explanations. + +```mermaid +graph TB +subgraph "Backend Components" +PY_ROW["Python Row component
backend/modelscope_studio/components/antd/grid/row/__init__.py"] +PY_COL["Python Col component
backend/modelscope_studio/components/antd/grid/col/__init__.py"] +end +subgraph "Frontend Wrapper" +IDX_ROW["Row wrapper entry
frontend/antd/grid/row/Index.svelte"] +ROW_IMPL["Row implementation
frontend/antd/grid/row/row.tsx"] +IDX_COL["Col wrapper entry
frontend/antd/grid/col/Index.svelte"] +COL_IMPL["Col implementation
frontend/antd/grid/col/col.tsx"] +CTX["Grid context
frontend/antd/grid/context.ts"] +end +PY_ROW --> IDX_ROW --> ROW_IMPL +PY_COL --> IDX_COL --> COL_IMPL +ROW_IMPL --> CTX +COL_IMPL --> CTX +``` + +**Diagram sources** + +- [frontend/antd/grid/row/Index.svelte:1-61](file://frontend/antd/grid/row/Index.svelte#L1-L61) +- [frontend/antd/grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [frontend/antd/grid/col/Index.svelte:1-77](file://frontend/antd/grid/col/Index.svelte#L1-L77) +- [frontend/antd/grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:1-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L1-L94) +- [backend/modelscope_studio/components/antd/grid/col/**init**.py:1-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L1-L114) + +**Section sources** + +- [frontend/antd/grid/row/Index.svelte:1-61](file://frontend/antd/grid/row/Index.svelte#L1-L61) +- [frontend/antd/grid/col/Index.svelte:1-77](file://frontend/antd/grid/col/Index.svelte#L1-L77) +- [frontend/antd/grid/row/row.tsx:1-34](file://frontend/antd/grid/row/row.tsx#L1-L34) +- [frontend/antd/grid/col/col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:1-94](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L1-L94) +- [backend/modelscope_studio/components/antd/grid/col/**init**.py:1-114](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L1-L114) + +## Core Components + +- Row component + - Supports alignment, gutter, wrapping, and other props for holding multiple columns and managing layout direction and distribution. + - Key props: `align`, `justify`, `gutter`, `wrap`, etc. +- Col component + - Supports span, offset, ordering, left/right pushing, and responsive breakpoints for specific content blocks. + - Key props: `span`, `offset`, `order`, `pull`, `push`, `xs`/`sm`/`md`/`lg`/`xl`/`xxl`, etc. + +All of the above props are explicitly declared with default values in the backend component, making them directly usable from the Python layer. + +**Section sources** + +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:30-76](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L30-L76) +- [backend/modelscope_studio/components/antd/grid/col/**init**.py:30-95](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L30-L95) + +## Architecture Overview + +The runtime flow of Grid is as follows: the backend Python component receives params and renders the frontend wrapper; the frontend wrapper then calls the Ant Design Row/Col implementation and collects Col children via context, ultimately assembling the standard grid layout. + +```mermaid +sequenceDiagram +participant PyRow as "Backend Row component" +participant IdxRow as "Row wrapper entry" +participant RowImpl as "Row implementation" +participant Ctx as "Grid context" +participant PyCol as "Backend Col component" +participant IdxCol as "Col wrapper entry" +participant ColImpl as "Col implementation" +PyRow->>IdxRow : Render row wrapper +IdxRow->>RowImpl : Pass row params +PyCol->>IdxCol : Render col wrapper +IdxCol->>ColImpl : Pass col params +ColImpl->>Ctx : Register col item +RowImpl->>Ctx : Consume col items and render +RowImpl-->>IdxRow : Output Row container +IdxRow-->>PyRow : Return render result +``` + +**Diagram sources** + +- [frontend/antd/grid/row/Index.svelte:10-44](file://frontend/antd/grid/row/Index.svelte#L10-L44) +- [frontend/antd/grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [frontend/antd/grid/col/Index.svelte:10-47](file://frontend/antd/grid/col/Index.svelte#L10-L47) +- [frontend/antd/grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [frontend/antd/grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) + +## Detailed Component Analysis + +### Row Component Analysis + +- Design notes + - Based on Ant Design Row, supports horizontal alignment (`justify`), vertical alignment (`align`), gutter, and auto-wrapping (`wrap`). + - Collects Col children via context and renders them uniformly, avoiding hard-coded child elements in Row. +- Usage recommendations + - In complex layouts, set `gutter` first to ensure consistency across breakpoints. + - Use `wrap` appropriately to avoid horizontal scrolling from long lists. +- Key props + - `align`: top/middle/bottom/stretch + - `justify`: start/end/center/space-between/space-around/space-evenly + - `gutter`: number or object (with breakpoints) or array [horizontal, vertical] + - `wrap`: boolean + +```mermaid +classDiagram +class Row { ++align ++justify ++gutter ++wrap ++render() +} +class Context { ++register(item) ++collect() +} +Row --> Context : "consume col items" +``` + +**Diagram sources** + +- [frontend/antd/grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [frontend/antd/grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) + +**Section sources** + +- [frontend/antd/grid/row/Index.svelte:12-42](file://frontend/antd/grid/row/Index.svelte#L12-L42) +- [frontend/antd/grid/row/row.tsx:7-31](file://frontend/antd/grid/row/row.tsx#L7-L31) +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:30-76](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L30-L76) + +### Col Component Analysis + +- Design notes + - Based on Ant Design Col, supports `span`, `offset`, `order`, `pull`, `push`, and other basic capabilities. + - Supports responsive breakpoints xs/sm/md/lg/xl/xxl; each can specify a span value or a full attribute object. + - Registers itself via context for Row to dispatch uniformly. +- Usage recommendations + - Plan each row so total span does not exceed 24; overflowing columns will wrap automatically. + - Use `offset`/`push`/`pull` for visual offset and reordering, but be mindful of accessibility and semantics. + - On mobile, prioritize `xs`; use larger breakpoints on desktop for consistent device experience. +- Key props + - `span`: number of grid cells occupied (0 means not displayed) + - `offset`/`push`/`pull`: offset/left-shift/right-shift + - `order`: ordering + - `xs`/`sm`/`md`/`lg`/`xl`/`xxl`: breakpoint-level configuration + +```mermaid +classDiagram +class Col { ++span ++offset ++order ++pull ++push ++xs/sm/md/lg/xl/xxl ++render() +} +class Context { ++register(item) ++collect() +} +Col --> Context : "register to context" +``` + +**Diagram sources** + +- [frontend/antd/grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [frontend/antd/grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) +- [backend/modelscope_studio/components/antd/grid/col/**init**.py:30-95](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L30-L95) + +**Section sources** + +- [frontend/antd/grid/col/Index.svelte:23-47](file://frontend/antd/grid/col/Index.svelte#L23-L47) +- [frontend/antd/grid/col/col.tsx:7-11](file://frontend/antd/grid/col/col.tsx#L7-L11) +- [backend/modelscope_studio/components/antd/grid/col/**init**.py:30-95](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L30-L95) + +### Responsive Breakpoints and Behavior + +- Breakpoint definitions + - xs: screen width less than 576px, also the default breakpoint + - sm: ≥ 576px + - md: ≥ 768px + - lg: ≥ 992px + - xl: ≥ 1200px + - xxl: ≥ 1600px +- Configuration methods + - Can pass an integer span directly, or pass an object to configure span and other props (such as offset, order) per breakpoint. +- Behavioral notes + - When the total span of all columns in a row exceeds 24, the overflowing columns will wrap to the next line. + - `gutter` supports breakpoint-level configuration, enabling different spacing at different screen sizes. + +**Section sources** + +- [backend/modelscope_studio/components/antd/grid/col/**init**.py:58-72](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L58-L72) +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:54-60](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L54-L60) + +### Nesting Rules and Alignment + +- Nesting rules + - Only place Col inside Row; Col can continue to nest Row to form nested grids. + - Avoid excessively deep nesting to prevent styling and maintainability issues. +- Alignment + - Row provides horizontal (`justify`) and vertical (`align`) alignment. Combined with `gutter`, stable layouts are achieved. + - Vertical alignment supports `stretch`, which allows column heights to adapt to the container height. + +**Section sources** + +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:34-40](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L34-L40) +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:56-59](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L56-L59) + +### Practical Application Cases + +- Dashboard layout + - Use Row's `gutter` and `wrap` to control card spacing and wrapping. Col's `span` and responsive breakpoints adapt to multiple screen sizes. + - Reduce columns on narrow screens and increase on wide screens to maintain information density and readability. +- Product display page + - Hero image area uses a single full-width column; product list uses equal-width columns; sidebar uses a fixed span, main content adapts. + - Use xs/sm/md/lg/xl/xxl to configure different column counts and spacing for each breakpoint. +- Form layout + - Small form fields use smaller spans; composite fields use larger spans. On xs, merge into a single column to improve mobile usability. + - Use `offset` for fine-tuning, but avoid excessive offset that affects reading order. + +(The above are general layout strategy descriptions; see examples for specific implementations.) + +**Section sources** + +- [docs/components/antd/grid/README.md:1-9](file://docs/components/antd/grid/README.md#L1-L9) +- [docs/components/antd/grid/demos/basic.py:7-24](file://docs/components/antd/grid/demos/basic.py#L7-L24) +- [docs/components/antd/grid/demos/playground.py:17-90](file://docs/components/antd/grid/demos/playground.py#L17-L90) + +## Dependency Analysis + +- Component coupling + - Col registers itself via context; Row collects and renders from context, reducing direct coupling. + - Frontend wrapper components are only responsible for prop passthrough and rendering; logic is concentrated in the Row/Col implementations and context. +- External dependencies + - Depends on Ant Design's Row/Col components, reusing their mature grid system. + - Uses the Svelte Preprocess React toolchain for bridging and slot handling. + +```mermaid +graph LR +PY_ROW["Backend Row component"] --> IDX_ROW["Row wrapper entry"] +IDX_ROW --> ROW_IMPL["Row implementation"] +PY_COL["Backend Col component"] --> IDX_COL["Col wrapper entry"] +IDX_COL --> COL_IMPL["Col implementation"] +ROW_IMPL --> CTX["Grid context"] +COL_IMPL --> CTX +ROW_IMPL --> ANTDESIGN["Ant Design Row/Col"] +COL_IMPL --> ANTDESIGN +``` + +**Diagram sources** + +- [frontend/antd/grid/row/Index.svelte:10-18](file://frontend/antd/grid/row/Index.svelte#L10-L18) +- [frontend/antd/grid/col/Index.svelte:10-21](file://frontend/antd/grid/col/Index.svelte#L10-L21) +- [frontend/antd/grid/row/row.tsx:3-5](file://frontend/antd/grid/row/row.tsx#L3-L5) +- [frontend/antd/grid/col/col.tsx:3-5](file://frontend/antd/grid/col/col.tsx#L3-L5) +- [frontend/antd/grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) + +**Section sources** + +- [frontend/antd/grid/row/Index.svelte:10-44](file://frontend/antd/grid/row/Index.svelte#L10-L44) +- [frontend/antd/grid/col/Index.svelte:10-47](file://frontend/antd/grid/col/Index.svelte#L10-L47) +- [frontend/antd/grid/row/row.tsx:3-5](file://frontend/antd/grid/row/row.tsx#L3-L5) +- [frontend/antd/grid/col/col.tsx:3-5](file://frontend/antd/grid/col/col.tsx#L3-L5) +- [frontend/antd/grid/context.ts:3-4](file://frontend/antd/grid/context.ts#L3-L4) + +## Performance Considerations + +- Reduce unnecessary re-renders + - Split sub-components appropriately to avoid frequent full-row updates. Statically define Col responsive breakpoint configurations as much as possible to reduce dynamic computation. +- Limit nesting depth + - Deeper nesting increases style computation and layout costs. It is recommended not to exceed three levels of nesting. +- Use gutter wisely + - Many small gaps may trigger frequent reflows. Set `gutter` on the Row level rather than on individual Cols. +- Choose appropriate breakpoints + - Enable responsive configuration only at necessary breakpoints to avoid rendering overhead from too many conditional branches. +- Use span and wrap + - Reasonable span allocation and wrapping reduce complex computation and extra DOM structures. + +(This section contains general optimization recommendations and does not involve specific file analysis.) + +## Troubleshooting Guide + +- Col not showing or misaligned + - Check whether the total span per row exceeds 24; overflowing columns will wrap. + - Check for conflicts in xs/sm/md/lg/xl/xxl breakpoint configurations. +- Offset/ordering not working + - Confirm that Col's `offset`/`push`/`pull`/`order` are taking effect at the correct breakpoint. + - Ensure Row's `justify`/`align` is not overriding the expected visual result. +- Responsive not working + - Confirm that breakpoint param types are objects containing the correct attributes (e.g., span, offset). + - Confirm that the parent Row's `gutter`/`justify`/`align` is not conflicting with the breakpoint configuration. +- Performance issues + - Check for deep nesting and excessive dynamic computation; simplify the layout structure if needed. + - Avoid setting the same spacing and styles on each Col repeatedly; configure at the Row level instead. + +**Section sources** + +- [backend/modelscope_studio/components/antd/grid/col/**init**.py:58-72](file://backend/modelscope_studio/components/antd/grid/col/__init__.py#L58-L72) +- [backend/modelscope_studio/components/antd/grid/row/**init**.py:54-60](file://backend/modelscope_studio/components/antd/grid/row/__init__.py#L54-L60) + +## Conclusion + +The Grid component, through collaboration between backend params and frontend wrappers, provides grid capabilities consistent with Ant Design, while enhancing responsive breakpoints and context-based collection mechanisms. Using Row/Col's alignment, gutter, nesting, and breakpoint configuration appropriately enables stable, maintainable layout solutions to be built quickly across multiple scenarios. + +## Appendix + +- Example entry points + - Basic example: [docs/components/antd/grid/demos/basic.py:7-24](file://docs/components/antd/grid/demos/basic.py#L7-L24) + - Playground example: [docs/components/antd/grid/demos/playground.py:17-90](file://docs/components/antd/grid/demos/playground.py#L17-L90) +- Documentation: [docs/components/antd/grid/README.md:1-9](file://docs/components/antd/grid/README.md#L1-L9) diff --git a/.wiki/en/Ant Design Components/Layout Components/Layout Components.md b/.wiki/en/Ant Design Components/Layout Components/Layout Components.md new file mode 100644 index 00000000..ee16aecc --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Layout Components.md @@ -0,0 +1,385 @@ +# Layout Components + + +**Files referenced in this document** +- [divider.tsx](file://frontend/antd/divider/divider.tsx) +- [flex.tsx](file://frontend/antd/flex/flex.tsx) +- [layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) +- [space.tsx](file://frontend/antd/space/space.tsx) +- [splitter.tsx](file://frontend/antd/splitter/splitter.tsx) +- [context.ts](file://frontend/antd/grid/context.ts) +- [col.tsx](file://frontend/antd/grid/col/col.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Responsive Behavior](#performance-and-responsive-behavior) +8. [Mobile and Screen Adaptation](#mobile-and-screen-adaptation) +9. [Troubleshooting](#troubleshooting) +10. [Conclusion](#conclusion) +11. [Appendix: Complex Page Layout Examples and Best Practices](#appendix-complex-page-layout-examples-and-best-practices) + +## Introduction + +This chapter is intended for developers using Ant Design layout components. It systematically covers the implementation and usage of Divider, Flex, Grid, Layout, Space, Splitter, and Masonry components in this repository. The documentation focuses on the layout algorithm concepts, responsive behavior, nesting rules, and composition patterns of each component, along with recommendations for mobile adaptation and screen size compatibility. + +## Project Structure + +These layout components reside in the `antd` submodule of the frontend directory. They adopt a unified "Svelte wrapping React components" strategy (bridging Ant Design React components to Svelte via `sveltify`), and in some cases introduce context and utility functions to support more complex layout capabilities (such as grid column collection and splitter panel item rendering). + +```mermaid +graph TB +subgraph "Antd Layout Components" +D["Divider"] +F["Flex"] +L["Layout.Base"] +S["Space"] +SP["Splitter"] +G["Grid.Context"] +GC["Grid.Col"] +end +D --> |"uses Ant Design"| D +F --> |"uses Ant Design"| F +L --> |"uses Ant Design"| L +S --> |"uses Ant Design"| S +SP --> |"uses Ant Design"| SP +GC --> |"consumes context"| G +``` + +Diagram sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +Section sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +## Core Components + +- **Divider**: A lightweight wrapper around Ant Design's Divider. Renders an empty divider when no children are present, or a divider with content when children are provided. +- **Flex**: A simple wrapper around Ant Design's Flex that passes through all props and children directly. +- **Layout.Base**: Dynamically selects between Header, Footer, Content, or Layout based on the `component` prop, and injects CSS class names to distinguish layout regions. +- **Space**: Extends Ant Design's Space with slot rendering and `split` slot support. Internally uses `useTargets` to map children to a target collection. +- **Splitter**: Extends Ant Design's Splitter with context-based default panel collection, passing each panel's element and props through to `Panel`. +- **Grid**: Collects columns (Col) via context and injects them into Row/Col rendering logic. The Col component registers itself into the context via `ItemHandler`. +- **Masonry**: Based on Ant Design's Masonry component, supports responsive column count configuration and automatic item height adjustment. Ideal for image walls, card streams, and other unequal-height layout scenarios. Refer to [Masonry](file://.qoder/repowiki/en/content/Ant%20Design%20Components/Layout%20Components/Masonry.md) for details. + +Section sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +## Architecture Overview + +The diagram below shows the dependency and collaboration relationships among the layout components: Space and Splitter resolve child nodes and establish target mappings before rendering; Layout.Base dynamically selects the specific layout sub-component; Grid collects Col instances via context and participates in grid layout rendering. + +```mermaid +graph LR +A["Space"] --> B["ReactSlot Rendering"] +C["Splitter"] --> D["Panel List Rendering"] +E["Layout.Base"] --> F["Header/Footer/Content/Layout"] +G["Grid.Col"] --> H["Grid.Context Collection"] +H --> I["Row/Col Rendering"] +``` + +Diagram sources + +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +## Component Details + +### Divider + +- Implementation notes + - Wraps Ant Design's Divider using `sveltify`. + - Renders a divider with children when children are present; otherwise renders an empty divider. +- Nesting rules + - Used as a separator; can be placed inside any container without affecting the parent's layout mode. +- Responsive behavior + - Determined by Ant Design; no breakpoint control by default. +- Typical usage + - Insert dividers between list items, form sections, or cards to enhance visual hierarchy. + +Section sources + +- [divider.tsx:1-15](file://frontend/antd/divider/divider.tsx#L1-L15) + +### Flex + +- Implementation notes + - Wraps Ant Design's Flex using `sveltify`, passing all props and children through directly. +- Layout algorithm + - Follows the Flexbox specification, supporting main axis, cross axis, wrapping, alignment, and other common properties. +- Nesting rules + - Flex can nest other Flex, Grid, Space, and layout components to form composite layouts. +- Responsive behavior + - Flex properties can change at breakpoints to achieve adaptive layouts using Ant Design's breakpoint configuration. +- Typical usage + - Header navigation, card groups, button groups, and other scenarios requiring flexible alignment and distribution. + +Section sources + +- [flex.tsx:1-11](file://frontend/antd/flex/flex.tsx#L1-L11) + +### Layout.Base + +- Implementation notes + - Dynamically selects between rendering Header, Footer, Content, or Layout based on the `component` prop. + - Injects CSS class names for non-layout sub-components to facilitate styling and debugging. +- Layout algorithm + - Implements page frame layout using Ant Design's Layout family of components. +- Nesting rules + - Header/Footer/Content must be direct children of Layout; Sider and other sub-components can be nested inside. +- Responsive behavior + - Achieves a responsive sidebar by combining Sider collapse/expand behavior with breakpoint strategies. +- Typical usage + - Overall page framework: top navigation + side menu + main content + footer. + +```mermaid +flowchart TD +Start(["Enter Layout.Base"]) --> CheckComp{"component type"} +CheckComp --> |header| RenderHeader["Render Header"] +CheckComp --> |footer| RenderFooter["Render Footer"] +CheckComp --> |content| RenderContent["Render Content"] +CheckComp --> |layout| RenderLayout["Render Layout"] +RenderHeader --> End(["Done"]) +RenderFooter --> End +RenderContent --> End +RenderLayout --> End +``` + +Diagram sources + +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +Section sources + +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +### Space + +- Implementation notes + - Uses Ant Design's Space and extends it with slot rendering and `split` slot support. + - Internally maps children to a target collection via `useTargets`, then renders them through `ReactSlot`. +- Layout algorithm + - Calculates spacing between elements based on direction and size, supporting wrapping and compact composition modes. +- Nesting rules + - Can nest any component; the `split` slot is used to render separators. +- Responsive behavior + - Spacing values can change at breakpoints to optimize spacing for different screen sizes. +- Typical usage + - Navigation button groups, action button groups, compact arrangement between form items. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant S as "Space" +participant T as "useTargets" +participant R as "ReactSlot" +U->>S : Pass children and slots +S->>T : Parse children into targets +S->>R : Render targets +S->>R : Render split slot (if present) +R-->>U : Output layout with spacing +``` + +Diagram sources + +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) + +Section sources + +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) + +### Splitter + +- Implementation notes + - Uses Ant Design's Splitter and collects default panel list via context. + - Passes each panel's element and props through to Panel for flexible multi-panel layout. +- Layout algorithm + - Split layout based on drag or fixed proportions, supporting horizontal and vertical directions. +- Nesting rules + - Sub-panels register via context; each panel independently renders its own content. +- Responsive behavior + - Can adjust initial proportions and minimum sizes at breakpoints to ensure mobile usability. +- Typical usage + - Code editor + preview area, left/right content comparison, multi-view side-by-side display. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant P as "Splitter" +participant Ctx as "Items Context" +participant Panel as "Panel" +U->>P : Provide panel slots +P->>Ctx : Get default panel list +loop Iterate panels +P->>Panel : Pass props and render +Panel-->>P : Return panel content +end +P-->>U : Output split panel layout +``` + +Diagram sources + +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) + +Section sources + +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) + +### Grid (Col and Context) + +- Implementation notes + - Col registers itself into a context named `antd-grid-cols` via `ItemHandler`. + - The context provides `withItemsContextProvider` and `useItems` for collecting and consuming column definitions. +- Layout algorithm + - Based on a 24-column grid system. Col props such as `span`, `offset`, `order`, and `gutter` determine column width and order. +- Nesting rules + - Col must be placed within a Row/Col context; responsive behavior can be configured via breakpoints. +- Responsive behavior + - Supports breakpoints: xs/sm/md/lg/xl. Different `span`/`offset` values can be set per breakpoint. +- Typical usage + - Form grids, card grids, image walls, etc. + +```mermaid +flowchart TD +A["Col component"] --> B["Register to context
key: antd-grid-cols"] +B --> C["Row/Col reads context during render"] +C --> D["Calculate layout by span/offset/order"] +D --> E["Output grid column"] +``` + +Diagram sources + +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +Section sources + +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +## Dependency Analysis + +- Inter-component coupling + - Space and Splitter directly depend on ReactSlot and context for slot and child item rendering. + - Layout.Base depends on Ant Design's Layout family components and dynamically selects sub-component types. + - Grid uses context to collect and consume Col instances, reducing coupling between Row and Col. +- External dependencies + - All components depend on their corresponding Ant Design components; layout algorithms and styles are provided by Ant Design. +- Potential circular dependencies + - No direct circular dependencies found; context is only used for data passing and does not reverse-depend on components. + +```mermaid +graph TB +Space["Space"] --> ReactSlot["ReactSlot"] +Splitter["Splitter"] --> ItemsCtx["Items Context"] +LayoutBase["Layout.Base"] --> ADLayout["Ant Design Layout"] +GridCol["Grid.Col"] --> GridCtx["Grid Context"] +``` + +Diagram sources + +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +Section sources + +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +## Performance and Responsive Behavior + +- Performance characteristics + - Components use lightweight wrappers to avoid additional state management overhead. Space's `useTargets` performs mapping only once during initialization. + - Layout.Base uses `useMemo` to cache component types, reducing unnecessary re-renders. +- Responsive behavior + - The responsiveness of Flex, Space, Grid, and Splitter is primarily driven by Ant Design's breakpoints and props. Layout parameters for different screen sizes can be configured individually in the breakpoint configuration. + - It is recommended to define breakpoint thresholds and column counts clearly during the design phase to avoid frequent reflows. + +## Mobile and Screen Adaptation + +- General strategies + - Use breakpoint configuration (e.g., xs/sm/md/lg/xl) to adjust column widths, spacing, and layout direction for small screens. + - Use compact mode and appropriate spacing in Space to avoid horizontal scrolling on mobile. + - Set minimum panel sizes and initial proportions in Splitter to ensure touch usability. +- Layout containers + - On small screens, prefer vertical layouts (Flex direction column). Hide secondary areas or use a drawer-style sidebar if necessary. +- Grid system + - Configure `offset` and `order` appropriately to maintain readability and clickability on small screens. + +## Troubleshooting + +- Children not rendering correctly + - Space hides children internally and renders targets via ReactSlot. Verify that slots are being used correctly. +- Splitter panels are empty + - Splitter relies on the default panel list provided by context. If panels are empty, nothing is rendered. Check slot naming and context registration. +- Grid columns not taking effect + - Confirm that Col is registered within a Row/Col context. Check breakpoint configuration and whether `span`/`offset` values are reasonable. +- Layout container type error + - Layout.Base only supports four types: header/footer/content/layout. Passing any other value will fall back to Layout. + +Section sources + +- [space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [col.tsx:1-14](file://frontend/antd/grid/col/col.tsx#L1-L14) + +## Conclusion + +The layout components in this repository are designed around a "lightweight wrapper + context" core philosophy. They reuse Ant Design's mature layout algorithms and styling system, while providing extensibility through slot rendering, dynamic component selection, and context collection. Through breakpoint configuration and appropriate nesting rules, high-quality page layouts that work well on both desktop and mobile can be built. + +## Appendix: Complex Page Layout Examples and Best Practices + +- Example 1: Dashboard page + - Use Layout.Base to build a header + sidebar + main body. Use Flex and Space inside the main body to organize cards and action areas. Use Divider at the bottom for separation. + - Breakpoint strategy: On small screens, collapse the action area into cards or use a drawer. +- Example 2: Content editing page + - Use Splitter to split the left directory tree from the right editor. Use Grid for form layout inside the editor. Use Space for action buttons at the bottom. + - Breakpoint strategy: On small screens, hide the directory tree and display the editor at full width. +- Example 3: Comparison display page + - Use Splitter to place two content blocks side by side. Inside each block, use Flex and Space for title, description, and action alignment. + - Breakpoint strategy: On small screens, switch to vertical stacking to preserve readability. + +Best practices + +- Prefer Flex and Space for simple layouts; introduce Splitter only for complex scenarios. +- Unify breakpoint configuration in the grid system to avoid multiple breakpoint strategies on the same page. +- Inject semantic class names into layout containers to facilitate style overrides and debugging. +- On mobile, prioritize touch interaction and adequate tap target sizes by increasing spacing and font size appropriately. diff --git a/.wiki/en/Ant Design Components/Layout Components/Layout.md b/.wiki/en/Ant Design Components/Layout Components/Layout.md new file mode 100644 index 00000000..94a9fd9b --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Layout.md @@ -0,0 +1,295 @@ +# Layout + + +**Files referenced in this document** +- [frontend/antd/layout/Index.svelte](file://frontend/antd/layout/Index.svelte) +- [frontend/antd/layout/Base.svelte](file://frontend/antd/layout/Base.svelte) +- [frontend/antd/layout/layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) +- [frontend/antd/layout/content/Index.svelte](file://frontend/antd/layout/content/Index.svelte) +- [frontend/antd/layout/footer/Index.svelte](file://frontend/antd/layout/footer/Index.svelte) +- [frontend/antd/layout/header/Index.svelte](file://frontend/antd/layout/header/Index.svelte) +- [frontend/antd/layout/sider/Index.svelte](file://frontend/antd/layout/sider/Index.svelte) +- [frontend/antd/layout/sider/layout.sider.tsx](file://frontend/antd/layout/sider/layout.sider.tsx) +- [docs/components/antd/layout/README.md](file://docs/components/antd/layout/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides a systematic introduction to the overall architecture and usage of the Layout component, covering the combination and nesting rules of layout regions including Header, Sider, Content, and Footer. It explains responsive behavior and fixed positioning strategies, provides ideas for classic page templates such as sidebar layouts, top navigation layouts, and hybrid layouts, and describes integration with the grid system and adaptive behavior at different screen sizes. It also provides practical recommendations for style customization, theme switching, and animation effects. + +## Project Structure + +The Layout component adopts a "unified base + regional sub-components" layered design: + +- Base layer: `Index.svelte` serves as the entry point. `Base.svelte` handles prop processing and rendering. `layout.base.tsx` wraps the specific Ant Design components (Header/Footer/Content/Layout). +- Region layer: header, footer, content, and sider each specify a `component` type via their own `Index.svelte`, reusing the `Base.svelte` rendering logic. +- Special region: sider provides its own `layout.sider.tsx` to support a `trigger` slot for the collapse trigger. + +```mermaid +graph TB +subgraph "Layout Component Layer" +L["Index.svelte
Unified entry"] +HB["Base.svelte
Common base"] +C["content/Index.svelte"] +F["footer/Index.svelte"] +H["header/Index.svelte"] +S["sider/Index.svelte"] +end +subgraph "Underlying Implementation Layer" +LB["layout.base.tsx
Ant Design component wrapper"] +LS["layout.sider.tsx
Sider implementation with trigger slot"] +end +L --> HB +C --> HB +F --> HB +H --> HB +S --> HB +HB --> LB +S --> LS +``` + +Diagram sources + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +Section sources + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/content/Index.svelte:1-15](file://frontend/antd/layout/content/Index.svelte#L1-L15) +- [frontend/antd/layout/footer/Index.svelte:1-15](file://frontend/antd/layout/footer/Index.svelte#L1-L15) +- [frontend/antd/layout/header/Index.svelte:1-15](file://frontend/antd/layout/header/Index.svelte#L1-L15) +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +## Core Components + +- Layout (overall container) + - Entry: `Index.svelte` passes props to `Base.svelte` and specifies `component` as `layout`. + - Base: `Base.svelte` reuses common prop handling logic; `layout.base.tsx` ultimately decides to render Ant Design's Layout container. +- Header (top area) + - Entry: `header/Index.svelte` specifies `component` as `header`, reusing `Base.svelte` to render Ant Design's Header. +- Footer (bottom area) + - Entry: `footer/Index.svelte` specifies `component` as `footer`, reusing `Base.svelte` to render Ant Design's Footer. +- Content (content area) + - Entry: `content/Index.svelte` specifies `component` as `content`, reusing `Base.svelte` to render Ant Design's Content. +- Sider (sidebar) + - Entry: `sider/Index.svelte` asynchronously loads `layout.sider.tsx` to implement Ant Design's Sider with `trigger` slot support. + +Section sources + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/header/Index.svelte:1-15](file://frontend/antd/layout/header/Index.svelte#L1-L15) +- [frontend/antd/layout/footer/Index.svelte:1-15](file://frontend/antd/layout/footer/Index.svelte#L1-L15) +- [frontend/antd/layout/content/Index.svelte:1-15](file://frontend/antd/layout/content/Index.svelte#L1-L15) +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +## Architecture Overview + +The diagram below shows the render chain from Svelte to Ant Design, as well as the Sider trigger slot mechanism: + +```mermaid +sequenceDiagram +participant U as "User code" +participant L as "Layout/Index.svelte" +participant B as "Base.svelte" +participant LB as "layout.base.tsx" +participant AD as "Ant Design Layout" +U->>L : Pass props such as children +L->>B : Pass through props and set component="layout" +B->>LB : Compute and select component type +LB->>AD : Render Ant Design Layout +AD-->>U : Layout container render complete +``` + +Diagram sources + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +Section sources + +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +## Detailed Component Analysis + +### Layout Nesting and Region Composition + +- Nesting rules + - Layout is the root container and can directly contain Header, Sider, Content, and Footer. + - Sider is usually placed on the left side of Layout, Content on the right, Header at the top, and Footer at the bottom. + - More fine-grained layouts or grid systems can be further nested inside Content. +- Responsive and fixed positioning + - Implement mobile responsiveness by combining Sider's collapse props with breakpoint configuration. + - When Header/Footer has a fixed height, ensure Content height calculation is not interfered with to avoid scroll conflicts. +- Trigger and interaction + - Sider supports a custom `trigger` slot for implementing a collapse button with icon switching. + +```mermaid +flowchart TD +Start(["Start"]) --> Root["Layout root container"] +Root --> Hdr["Header top area"] +Root --> Sider["Sider sidebar"] +Root --> Cnt["Content main area"] +Root --> Ftr["Footer bottom area"] +Sider --> Trigger["trigger slot (optional)"] +Cnt --> Inner["Inner nested grids/cards/lists etc."] +Hdr --> End(["End"]) +Ftr --> End +``` + +Diagram sources + +- [frontend/antd/layout/header/Index.svelte:1-15](file://frontend/antd/layout/header/Index.svelte#L1-L15) +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/content/Index.svelte:1-15](file://frontend/antd/layout/content/Index.svelte#L1-L15) +- [frontend/antd/layout/footer/Index.svelte:1-15](file://frontend/antd/layout/footer/Index.svelte#L1-L15) + +Section sources + +- [frontend/antd/layout/header/Index.svelte:1-15](file://frontend/antd/layout/header/Index.svelte#L1-L15) +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/content/Index.svelte:1-15](file://frontend/antd/layout/content/Index.svelte#L1-L15) +- [frontend/antd/layout/footer/Index.svelte:1-15](file://frontend/antd/layout/footer/Index.svelte#L1-L15) + +### Sider Component and Trigger Slot + +- Trigger mechanism + - If a `trigger` slot is provided, that slot content takes priority. If no slot is provided and `trigger` is the default value, the default trigger is rendered. Otherwise, the rendered state is determined by the passed `trigger` value. +- Collapse state management + - Use Sider's `collapsed` state together with trigger behavior to implement click-toggle expand/collapse. + +```mermaid +flowchart TD +A["Enter Sider render"] --> B{"trigger slot provided?"} +B -- Yes --> C["Render slot content as trigger"] +B -- No --> D{"trigger is default value?"} +D -- Yes --> E["Render default trigger"] +D -- No --> F{"trigger is null/undefined?"} +F -- Yes --> G["Do not render trigger"] +F -- No --> H["Render passed trigger content"] +C --> I["Done"] +E --> I +G --> I +H --> I +``` + +Diagram sources + +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +Section sources + +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +### Classic Page Layout Templates + +- Sidebar layout + - Use Layout + Header + Sider + Content + Footer. Sider has a fixed width and is collapsible on mobile. +- Top navigation layout + - Use Layout + Header (top navigation only) + Content. Sider can be omitted or hidden. +- Hybrid layout + - Nest a grid system inside Content to implement multi-column content with a side information panel. + +Section sources + +- [docs/components/antd/layout/README.md:1-8](file://docs/components/antd/layout/README.md#L1-L8) + +### Integration with the Grid System + +- Use Row/Col in Content for column division, combined with responsive breakpoints for adaptive layouts. +- Note: When Header/Footer has a fixed height, Content height calculation must account for the remaining visible area to avoid overflow or scroll anomalies. + +## Dependency Analysis + +- Component coupling + - All region components depend on `Base.svelte`'s prop handling and rendering process, reducing duplicate code and improving consistency. + - Sider independently implements `layout.sider.tsx` to avoid coupling with the common Base process, enhancing extensibility. +- External dependencies + - Ant Design's Layout, Header, Footer, Content, and Sider components as render targets. + - Svelte Slot and React Slot bridging for slot passing and cloning. + +```mermaid +graph LR +Base["Base.svelte"] --> Wrap["layout.base.tsx"] +Wrap --> ADL["Ant Design Layout"] +Wrap --> ADH["Ant Design Header"] +Wrap --> ADF["Ant Design Footer"] +Wrap --> ADC["Ant Design Content"] +SBase["sider/Index.svelte"] --> SWrap["layout.sider.tsx"] +SWrap --> ADS["Ant Design Sider"] +``` + +Diagram sources + +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +Section sources + +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +## Performance Considerations + +- Async loading + - Sider is asynchronously loaded via `importComponent`, reducing initial bundle size and first-screen blocking. +- Prop passthrough and derivation + - `Base.svelte` handles and derives props in a unified manner, avoiding unnecessary re-renders. +- Class names + - Class names are conditionally concatenated, avoiding excessive runtime string concatenation overhead. + +Section sources + +- [frontend/antd/layout/sider/Index.svelte:1-62](file://frontend/antd/layout/sider/Index.svelte#L1-L62) +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) + +## Troubleshooting Guide + +- No content rendered + - Check if the `visible` prop has been set to `false`. Confirm the visibility check logic in `Base.svelte`. +- Sider trigger not showing + - Confirm whether a `trigger` slot has been provided. Check if the `trigger` value is `null`/`undefined` or the default value. +- Style anomalies + - Confirm that class names are correctly concatenated. Check if external styles are causing layout misalignment. + +Section sources + +- [frontend/antd/layout/Base.svelte:1-71](file://frontend/antd/layout/Base.svelte#L1-L71) +- [frontend/antd/layout/sider/layout.sider.tsx:1-26](file://frontend/antd/layout/sider/layout.sider.tsx#L1-L26) + +## Conclusion + +The Layout component achieves complete encapsulation of Ant Design's layout system through a unified base and regionalized decomposition. With the Sider trigger slot and async loading mechanism, it ensures both flexibility and performance. Combined with the grid system and responsive breakpoints, a variety of classic page layout templates can be quickly assembled, while style and theme customization meets the needs of complex business scenarios. + +## Appendix + +- Example entry reference: [docs/components/antd/layout/README.md:1-8](file://docs/components/antd/layout/README.md#L1-L8) diff --git a/.wiki/en/Ant Design Components/Layout Components/Masonry.md b/.wiki/en/Ant Design Components/Layout Components/Masonry.md new file mode 100644 index 00000000..8b818970 --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Masonry.md @@ -0,0 +1,464 @@ +# Masonry + + +**Files referenced in this document** +- [frontend/antd/masonry/masonry.tsx](file://frontend/antd/masonry/masonry.tsx) +- [frontend/antd/masonry/context.ts](file://frontend/antd/masonry/context.ts) +- [frontend/antd/masonry/Index.svelte](file://frontend/antd/masonry/Index.svelte) +- [frontend/antd/masonry/package.json](file://frontend/antd/masonry/package.json) +- [backend/modelscope_studio/components/antd/masonry/__init__.py](file://backend/modelscope_studio/components/antd/masonry/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [docs/components/antd/masonry/README.md](file://docs/components/antd/masonry/README.md) +- [docs/components/antd/masonry/README-zh_CN.md](file://docs/components/antd/masonry/README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +Masonry is an important layout component in ModelScope Studio, implemented based on Ant Design's Masonry component. This component is specifically designed to display content of varying heights, such as images and cards, and automatically creates a waterfall/masonry effect that distributes content evenly across multiple columns. + +The masonry layout is particularly well-suited for the following scenarios: + +- Displaying images or cards with irregular heights +- Distributing content evenly between columns +- Layout requirements that need responsive column count adjustment + +## Project Structure + +ModelScope Studio adopts a frontend-backend separated architecture. The Masonry component is organized as follows: + +```mermaid +graph TB +subgraph "Frontend Layer" +A[frontend/antd/masonry/] --> A1[masonry.tsx] +A --> A2[Index.svelte] +A --> A3[context.ts] +A --> A4[package.json] +subgraph "utils/" +B[frontend/utils/] --> B1[createItemsContext.tsx] +B --> B2[renderItems.tsx] +B --> B3[renderParamsSlot.tsx] +end +end +subgraph "Backend Layer" +C[backend/modelscope_studio/] --> C1[components/antd/masonry/] +C --> C2[components/antd/components.py] +C1 --> C3[__init__.py] +end +subgraph "Docs Layer" +D[docs/components/antd/masonry/] --> D1[README.md] +D --> D2[README-zh_CN.md] +end +A1 --> B1 +A1 --> B2 +A1 --> B3 +C3 --> A2 +``` + +**Diagram sources** + +- [frontend/antd/masonry/masonry.tsx:1-52](file://frontend/antd/masonry/masonry.tsx#L1-L52) +- [frontend/antd/masonry/Index.svelte:1-64](file://frontend/antd/masonry/Index.svelte#L1-L64) +- [backend/modelscope_studio/components/antd/masonry/**init**.py:1-83](file://backend/modelscope_studio/components/antd/masonry/__init__.py#L1-L83) + +**Section sources** + +- [frontend/antd/masonry/masonry.tsx:1-52](file://frontend/antd/masonry/masonry.tsx#L1-L52) +- [frontend/antd/masonry/Index.svelte:1-64](file://frontend/antd/masonry/Index.svelte#L1-L64) +- [backend/modelscope_studio/components/antd/masonry/**init**.py:1-83](file://backend/modelscope_studio/components/antd/masonry/__init__.py#L1-L83) + +## Core Components + +### Frontend Core Components + +The core implementation of the Masonry component resides in `frontend/antd/masonry/masonry.tsx`. It uses React and Ant Design's Masonry component and integrates with ModelScope Studio's component system. + +Main features include: + +- **React wrapper**: uses `sveltify` to wrap Svelte components as React components +- **Context management**: integrates `createItemsContext` for data sharing between components +- **Slot rendering**: supports custom slot rendering +- **Dynamic content**: supports dynamic content updates and re-rendering + +### Backend Integration Component + +The backend component is located at `backend/modelscope_studio/components/antd/masonry/__init__.py` and provides a Python interface bridging to the frontend component. + +Key props and methods: + +- **EVENTS**: defines the `layout_change` event listener +- **SLOTS**: supports `items` and `itemRender` slots +- **PROPS**: provides configuration options such as `columns`, `gutter`, and `fresh` + +**Section sources** + +- [frontend/antd/masonry/masonry.tsx:10-49](file://frontend/antd/masonry/masonry.tsx#L10-L49) +- [backend/modelscope_studio/components/antd/masonry/**init**.py:10-65](file://backend/modelscope_studio/components/antd/masonry/__init__.py#L10-L65) + +## Architecture Overview + +The overall architecture of the Masonry component uses a layered design to ensure good maintainability and extensibility: + +```mermaid +graph TD +subgraph "UI Layer" +UI[Masonry Component] +end +subgraph "Frontend Logic Layer" +FC[Function Component] +CTX[Context Provider] +SL[Slot Handling] +end +subgraph "Utility Layer" +CIC[createItemsContext] +RI[renderItems] +RPS[renderParamsSlot] +end +subgraph "Ant Design Layer" +AD[Antd Masonry] +end +subgraph "Backend Integration Layer" +BC[Backend Component] +PC[Python Interface] +end +UI --> FC +FC --> CTX +FC --> SL +FC --> AD +CTX --> CIC +SL --> RI +SL --> RPS +BC --> PC +BC --> UI +``` + +**Diagram sources** + +- [frontend/antd/masonry/masonry.tsx:1-52](file://frontend/antd/masonry/masonry.tsx#L1-L52) +- [frontend/utils/createItemsContext.tsx:97-184](file://frontend/utils/createItemsContext.tsx#L97-L184) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +## Detailed Component Analysis + +### Masonry Component Implementation + +The core implementation of the Masonry component includes the following key parts: + +#### Component Wrapping and Prop Handling + +The component uses the `sveltify` function to wrap Svelte components as React components, supporting prop passing and event handling: + +```mermaid +sequenceDiagram +participant User as User +participant Masonry as Masonry Component +participant Context as Context Provider +participant Utils as Utility Functions +User->>Masonry : Pass props and children +Masonry->>Context : withItemsContextProvider wrapping +Context->>Utils : useItems to get data +Utils->>Utils : renderItems processes slots +Utils->>Masonry : Return processed data +Masonry->>Masonry : useMemo optimizes rendering +Masonry->>User : Render final result +``` + +**Diagram sources** + +- [frontend/antd/masonry/masonry.tsx:16-48](file://frontend/antd/masonry/masonry.tsx#L16-L48) +- [frontend/antd/masonry/context.ts:3-4](file://frontend/antd/masonry/context.ts#L3-L4) + +#### Data Flow Handling Mechanism + +The component manages data flow via `createItemsContext`: + +```mermaid +flowchart TD +Start([Component initialization]) --> GetItems[Get useItems context] +GetItems --> CheckSlots{Check slot type} +CheckSlots --> |has items| UseItems[Use items prop] +CheckSlots --> |no items| UseSlots[Use slot data] +UseSlots --> ResolveSlot[Resolve slot data] +ResolveSlot --> RenderItems[Call renderItems] +UseItems --> RenderItems +RenderItems --> MemoOptimize[useMemo optimization] +MemoOptimize --> FinalRender[Final render] +FinalRender --> End([Done]) +``` + +**Diagram sources** + +- [frontend/antd/masonry/masonry.tsx:18-43](file://frontend/antd/masonry/masonry.tsx#L18-L43) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +**Section sources** + +- [frontend/antd/masonry/masonry.tsx:1-52](file://frontend/antd/masonry/masonry.tsx#L1-L52) +- [frontend/antd/masonry/context.ts:1-7](file://frontend/antd/masonry/context.ts#L1-L7) + +### Context Management System + +`createItemsContext` provides comprehensive context management: + +#### Context Provider Pattern + +```mermaid +classDiagram +class ItemsContextProvider { ++allowedSlots : string[] ++items : ItemsContextValue ++setItem(slotKey, index, value) ++onChange(items) +} +class ItemsContextValue { ++items : Record~string, Item[]~ ++setItem : Function ++initial : boolean +} +class ItemHandler { ++itemIndex : number ++itemSlotKey : string ++itemElement : HTMLElement ++itemProps(props, items) ++itemChildren(items) ++slots : Record~string, Slot~ +} +ItemsContextProvider --> ItemsContextValue : "provides" +ItemHandler --> ItemsContextProvider : "uses" +``` + +**Diagram sources** + +- [frontend/utils/createItemsContext.tsx:108-170](file://frontend/utils/createItemsContext.tsx#L108-L170) +- [frontend/utils/createItemsContext.tsx:190-261](file://frontend/utils/createItemsContext.tsx#L190-L261) + +#### Data Processing Flow + +The component's data processing follows this flow: + +1. **Data collection**: collects all child elements from slots +2. **Data transformation**: converts HTML elements into internal data structures +3. **Context passing**: passes data through the React Context in the component tree +4. **State management**: manages component state using `useState` and `useEffect` + +**Section sources** + +- [frontend/utils/createItemsContext.tsx:97-274](file://frontend/utils/createItemsContext.tsx#L97-L274) + +### Slot Rendering System + +The Masonry component supports a flexible slot rendering mechanism: + +#### Slot Handling Functions + +```mermaid +flowchart LR +Slots[Slot object] --> CheckSlot{Check slot exists} +CheckSlot --> |exists| RenderSlot[renderSlot rendering] +CheckSlot --> |not exists| Fallback[Fallback handling] +RenderSlot --> ParamsSlot{Parameterized slot} +ParamsSlot --> |has params| RenderParams[renderParamsSlot] +ParamsSlot --> |no params| DirectRender[Direct rendering] +RenderParams --> Clone[Clone element] +DirectRender --> Clone +Clone --> Result[Return React node] +Fallback --> Result +``` + +**Diagram sources** + +- [frontend/utils/renderParamsSlot.tsx:5-49](file://frontend/utils/renderParamsSlot.tsx#L5-L49) +- [frontend/utils/renderItems.tsx:72-94](file://frontend/utils/renderItems.tsx#L72-L94) + +**Section sources** + +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) + +## Dependency Analysis + +### Component Dependency Diagram + +```mermaid +graph TB +subgraph "Masonry Component Dependencies" +A[masonry.tsx] --> B[createItemsContext.tsx] +A --> C[renderItems.tsx] +A --> D[renderParamsSlot.tsx] +A --> E[context.ts] +end +subgraph "Context Dependencies" +B --> F[React Hooks] +B --> G[useMemoizedEqualValue] +B --> H[useMemoizedFn] +end +subgraph "Utility Function Dependencies" +C --> I[ReactSlot] +C --> J[ContextPropsProvider] +D --> K[renderSlot] +end +subgraph "Backend Integration" +L[__init__.py] --> M[AntdMasonry] +L --> N[AntdMasonryItem] +end +A -.-> O[Antd Masonry] +L -.-> P[Gradio Events] +``` + +**Diagram sources** + +- [frontend/antd/masonry/masonry.tsx:1-6](file://frontend/antd/masonry/masonry.tsx#L1-L6) +- [frontend/utils/createItemsContext.tsx:1-18](file://frontend/utils/createItemsContext.tsx#L1-L18) +- [backend/modelscope_studio/components/antd/masonry/**init**.py:1-8](file://backend/modelscope_studio/components/antd/masonry/__init__.py#L1-L8) + +### Key Dependency Descriptions + +1. **Ant Design Masonry**: core layout component providing masonry layout functionality +2. **React Hooks**: used for state management and performance optimization +3. **Gradio integration**: supports Python backend event handling +4. **Svelte Preprocess**: implements the transformation from Svelte to React + +**Section sources** + +- [frontend/antd/masonry/masonry.tsx:1-6](file://frontend/antd/masonry/masonry.tsx#L1-L6) +- [backend/modelscope_studio/components/antd/masonry/**init**.py:23-27](file://backend/modelscope_studio/components/antd/masonry/__init__.py#L23-L27) + +## Performance Considerations + +### Rendering Optimization Strategies + +The Masonry component employs multiple performance optimization techniques: + +#### useMemo Optimization + +The component uses `useMemo` to cache computation results, avoiding unnecessary re-renders: + +```typescript +const memoizedItems = useMemo(() => { + return items || renderItems(resolvedSlotItems); +}, [items, resolvedSlotItems]); +``` + +#### Event Handler Optimization + +Uses `useFunction` and `useMemoizedFn` to optimize event handler performance: + +```typescript +const itemRenderFunction = useFunction(props.itemRender); +``` + +#### Conditional Rendering + +Reduces DOM operations through conditional rendering: + +```html +
{children}
+``` + +### Memory Management + +The component implements intelligent memory management: + +1. **Reference caching**: uses `useRef` to cache expensive computation results +2. **State synchronization**: synchronizes state changes via `useEffect` +3. **Cleanup mechanism**: cleans up event listeners when the component unmounts + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### 1. Component shows no content + +**Symptom**: Masonry component renders blank + +**Possible causes**: + +- Slot data not set correctly +- `items` prop not provided +- React component not wrapped correctly + +**Solutions**: + +1. Check if slots are passed correctly +2. Confirm that the `items` prop contains valid data +3. Verify that the component wrapping is correct + +#### 2. Layout is disordered + +**Symptom**: Masonry layout displays abnormally + +**Possible causes**: + +- Column count configuration is incorrect +- Gutter settings are improper +- Content height calculation error + +**Solutions**: + +1. Check the `columns` configuration +2. Adjust the `gutter` setting +3. Ensure content has correct height information + +#### 3. Performance issues + +**Symptom**: Component renders slowly or stutters + +**Possible causes**: + +- Large amounts of data causing rendering pressure +- Unnecessary re-renders +- Event handler performance issues + +**Solutions**: + +1. Use virtual scrolling to handle large datasets +2. Optimize `useMemo` dependencies +3. Reduce the complexity of event handlers + +**Section sources** + +- [frontend/antd/masonry/masonry.tsx:36-43](file://frontend/antd/masonry/masonry.tsx#L36-L43) +- [frontend/utils/createItemsContext.tsx:124-153](file://frontend/utils/createItemsContext.tsx#L124-L153) + +## Conclusion + +The Masonry layout component is a powerful and well-designed layout solution in ModelScope Studio. The component demonstrates excellent architectural design through the following characteristics: + +### Key Advantages + +1. **Modular design**: clear module division for easy maintenance and extension +2. **Performance optimization**: implements multiple performance optimization techniques to ensure a smooth user experience +3. **Flexibility**: supports various configuration options and custom rendering functionality +4. **Type safety**: complete TypeScript type definitions for a good development experience + +### Technical Highlights + +- **Context management pattern**: implements powerful data flow management via `createItemsContext` +- **Slot rendering system**: supports complex slot rendering and parameterized rendering +- **React integration**: seamlessly integrated into the React ecosystem +- **Backend compatibility**: provides a Python backend interface supporting Gradio event handling + +### Application Scenarios + +The Masonry component is particularly well-suited for: + +- Image gallery display +- Card content layouts +- Dynamic content containers +- Responsive grid layouts + +The component provides powerful layout capabilities for ModelScope Studio and is an important piece of infrastructure for building modern web applications. diff --git a/.wiki/en/Ant Design Components/Layout Components/Space.md b/.wiki/en/Ant Design Components/Layout Components/Space.md new file mode 100644 index 00000000..b8fa4abe --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Space.md @@ -0,0 +1,268 @@ +# Space + + +**Files Referenced in This Document** +- [frontend/antd/space/space.tsx](file://frontend/antd/space/space.tsx) +- [frontend/antd/space/Index.svelte](file://frontend/antd/space/Index.svelte) +- [frontend/antd/space/compact/space.compact.tsx](file://frontend/antd/space/compact/space.compact.tsx) +- [frontend/antd/space/compact/Index.svelte](file://frontend/antd/space/compact/Index.svelte) +- [backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js](file://backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js) +- [backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js](file://backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js) +- [docs/components/antd/space/README.md](file://docs/components/antd/space/README.md) +- [docs/components/antd/space/README-zh_CN.md](file://docs/components/antd/space/README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Space component automatically inserts uniform spacing between multiple child elements, supporting direction control, spacing size configuration, and collaboration with separator slots. This repository provides two variants: + +- Standard Space: A wrapper around Ant Design's Space component, responsible for automatic spacing distribution and direction control. +- Compact Space (Space.Compact): A wrapper around Ant Design's Space.Compact, emphasizing tighter layouts and compact spacing strategies. + +Both variants bridge Svelte child nodes to React Space/Space.Compact children via the Svelte–React bridging mechanism, ensuring stable rendering in the Gradio ecosystem. + +## Project Structure + +The Space component consists of a frontend Svelte layer and a backend template layer: + +- Frontend Svelte layer: Handles property pass-through, style concatenation, visibility control, and child node rendering. +- Backend template layer: Generates the final React wrapper, handling slot ordering, ReactSlot rendering, and Portal bridging. + +```mermaid +graph TB +subgraph "Frontend Svelte Layer" +IDX["Index.svelte
Standard Space Entry"] +COMPACT_IDX["compact/Index.svelte
Compact Space Entry"] +SPACE_TSX["space.tsx
Standard Space React Wrapper"] +COMPACT_TSX["compact/space.compact.tsx
Compact Space React Wrapper"] +end +subgraph "Backend Template Layer" +RT_SPACE["space-BWI0-XH7.js
Standard Space Template"] +RT_COMPACT["space.compact-C2LVtCsM.js
Compact Space Template"] +end +IDX --> SPACE_TSX --> RT_SPACE +COMPACT_IDX --> COMPACT_TSX --> RT_COMPACT +``` + +**Diagram Sources** + +- [frontend/antd/space/Index.svelte:1-61](file://frontend/antd/space/Index.svelte#L1-L61) +- [frontend/antd/space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js:651-679](file://backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L651-L679) +- [frontend/antd/space/compact/Index.svelte:1-60](file://frontend/antd/space/compact/Index.svelte#L1-L60) +- [frontend/antd/space/compact/space.compact.tsx:1-24](file://frontend/antd/space/compact/space.compact.tsx#L1-L24) +- [backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:651-674](file://backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L651-L674) + +**Section Sources** + +- [frontend/antd/space/Index.svelte:1-61](file://frontend/antd/space/Index.svelte#L1-L61) +- [frontend/antd/space/compact/Index.svelte:1-60](file://frontend/antd/space/compact/Index.svelte#L1-L60) +- [docs/components/antd/space/README.md:1-8](file://docs/components/antd/space/README.md#L1-L8) +- [docs/components/antd/space/README-zh_CN.md:1-8](file://docs/components/antd/space/README-zh_CN.md#L1-L8) + +## Core Components + +- Standard Space: Responsible for automatically collecting child nodes, injecting separator slots, rendering children in order, and supporting direction, size, and alignment configuration. +- Compact Space (Space.Compact): In compact mode, reduces default spacing and emphasizes tight arrangement of adjacent elements, suitable for dense layouts such as toolbars and button groups. + +Both variants dynamically load the corresponding React wrapper via Svelte's `importComponent`, and pass slots and additional props to the underlying React component. + +**Section Sources** + +- [frontend/antd/space/space.tsx:7-26](file://frontend/antd/space/space.tsx#L7-L26) +- [frontend/antd/space/compact/space.compact.tsx:7-21](file://frontend/antd/space/compact/space.compact.tsx#L7-L21) +- [frontend/antd/space/Index.svelte:10-60](file://frontend/antd/space/Index.svelte#L10-L60) +- [frontend/antd/space/compact/Index.svelte:10-60](file://frontend/antd/space/compact/Index.svelte#L10-L60) + +## Architecture Overview + +The Space call chain runs from Svelte to React and back to the DOM, involving slot resolution, child node ordering, and Portal bridging. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Component (Index.svelte)" +participant Loader as "importComponent" +participant ReactWrap as "React Wrapper (space.tsx or space.compact.tsx)" +participant BackendRT as "Backend Template (space-BWI0-XH7.js / space.compact-C2LVtCsM.js)" +participant Antd as "Ant Design Space/Space.Compact" +Svelte->>Loader : Load corresponding React wrapper +Loader-->>Svelte : Return React component +Svelte->>ReactWrap : Pass props and slots +ReactWrap->>BackendRT : Convert children to ReactSlot +BackendRT->>Antd : Render Space/Space.Compact and inject child nodes +Antd-->>Svelte : Output final DOM structure +``` + +**Diagram Sources** + +- [frontend/antd/space/Index.svelte:10-60](file://frontend/antd/space/Index.svelte#L10-L60) +- [frontend/antd/space/space.tsx:7-26](file://frontend/antd/space/space.tsx#L7-L26) +- [backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js:651-679](file://backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L651-L679) +- [frontend/antd/space/compact/Index.svelte:10-60](file://frontend/antd/space/compact/Index.svelte#L10-L60) +- [frontend/antd/space/compact/space.compact.tsx:7-21](file://frontend/antd/space/compact/space.compact.tsx#L7-L21) +- [backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:651-674](file://backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L651-L674) + +## Detailed Component Analysis + +### Standard Space Component + +- Automatic child node collection: Parses children via utility functions, converting them to ReactSlots with controllable ordering and cloning strategy. +- Separator slot: Supports injecting a separator via `slots.split`; falls back to `props.split` if not provided. +- Property pass-through: All props except internal ones are passed through to Ant Design Space, maintaining API compatibility with the native component. + +```mermaid +flowchart TD +Start(["Enter Space Render"]) --> Collect["Collect children and resolve to targets"] +Collect --> SplitCheck{"Is split slot provided?"} +SplitCheck --> |Yes| UseSlot["Use ReactSlot for slots.split"] +SplitCheck --> |No| UseProp["Use props.split"] +UseSlot --> Render["Iterate targets and render each ReactSlot"] +UseProp --> Render +Render --> End(["Render Complete"]) +``` + +**Diagram Sources** + +- [frontend/antd/space/space.tsx:8-25](file://frontend/antd/space/space.tsx#L8-L25) +- [backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js:656-673](file://backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L656-L673) + +**Section Sources** + +- [frontend/antd/space/space.tsx:7-26](file://frontend/antd/space/space.tsx#L7-L26) +- [backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js:651-679](file://backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L651-L679) + +### Compact Space Component + +- Compact mode: Uses Ant Design's Space.Compact to reduce default spacing, suitable for button groups, toolbars, and other densely packed layouts. +- Child node handling: Similar to the standard Space — hides original children first, then renders each one as a ReactSlot, ensuring consistent slot ordering and cloning strategy. + +```mermaid +flowchart TD +StartC(["Enter Space.Compact Render"]) --> Targets["Resolve children into target node array"] +Targets --> RenderC["Render each ReactSlot and inject into Compact container"] +RenderC --> EndC(["Render Complete"]) +``` + +**Diagram Sources** + +- [frontend/antd/space/compact/space.compact.tsx:8-20](file://frontend/antd/space/compact/space.compact.tsx#L8-L20) +- [backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:651-669](file://backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L651-L669) + +**Section Sources** + +- [frontend/antd/space/compact/space.compact.tsx:7-21](file://frontend/antd/space/compact/space.compact.tsx#L7-L21) +- [backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:651-674](file://backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L651-L674) + +### Svelte-to-React Bridging Mechanism + +- Slot ordering: Performs stable sorting of child nodes by `slotIndex` and `subSlotIndex`, ensuring consistent render order. +- Portal bridging: Clones Svelte slot content and mounts it into the React environment while preserving event listeners and styles. +- Visibility and styles: The Svelte layer concatenates `className` and inline styles, which are ultimately injected into the React component. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte (Index.svelte)" +participant SlotSort as "Slot Ordering" +participant Bridge as "Portal Bridging" +participant React as "React Wrapper" +participant DOM as "Antd Space/Space.Compact" +Svelte->>SlotSort : Retrieve and sort slots +SlotSort-->>Bridge : Return ordered portalTargets +Bridge->>React : Generate ReactSlots and clone nodes +React->>DOM : Render final DOM +``` + +**Diagram Sources** + +- [frontend/antd/space/Index.svelte:44-60](file://frontend/antd/space/Index.svelte#L44-L60) +- [backend/modelspace_studio/components/antd/space/templates/component/space-BWI0-XH7.js:642-650](file://backend/modelspace_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L642-L650) +- [frontend/antd/space/compact/Index.svelte:43-60](file://frontend/antd/space/compact/Index.svelte#L43-L60) +- [backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:642-650](file://backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L642-L650) + +**Section Sources** + +- [frontend/antd/space/Index.svelte:10-60](file://frontend/antd/space/Index.svelte#L10-L60) +- [frontend/antd/space/compact/Index.svelte:10-60](file://frontend/antd/space/compact/Index.svelte#L10-L60) +- [backend/modelspace_studio/components/antd/space/templates/component/space-BWI0-XH7.js:642-650](file://backend/modelspace_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L642-L650) +- [backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:642-650](file://backend/modelspace_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L642-L650) + +## Dependency Analysis + +- Component coupling: Space and Space.Compact share the same bridging logic in the frontend layer, differing only in the underlying Ant Design component used. +- External dependencies: Depends on Ant Design's Space/Space.Compact; slot and ReactSlot support is provided by `@svelte-preprocess-react`. +- Backend template: The template layer converts Svelte's slot ordering and Portal bridging logic into executable React code. + +```mermaid +graph LR +Svelte_Index["Index.svelte"] --> React_Space["space.tsx"] +Svelte_Compact["compact/Index.svelte"] --> React_Compact["compact/space.compact.tsx"] +React_Space --> RT_Space["space-BWI0-XH7.js"] +React_Compact --> RT_Compact["space.compact-C2LVtCsM.js"] +RT_Space --> Antd["Ant Design Space"] +RT_Compact --> AntdCompact["Ant Design Space.Compact"] +``` + +**Diagram Sources** + +- [frontend/antd/space/Index.svelte:10-60](file://frontend/antd/space/Index.svelte#L10-L60) +- [frontend/antd/space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [backend/modelspace_studio/components/antd/space/templates/component/space-BWI0-XH7.js:651-679](file://backend/modelspace_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L651-L679) +- [frontend/antd/space/compact/Index.svelte:10-60](file://frontend/antd/space/compact/Index.svelte#L10-L60) +- [frontend/antd/space/compact/space.compact.tsx:1-24](file://frontend/antd/space/compact/space.compact.tsx#L1-L24) +- [backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:651-674](file://backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L651-L674) + +**Section Sources** + +- [frontend/antd/space/space.tsx:1-29](file://frontend/antd/space/space.tsx#L1-L29) +- [frontend/antd/space/compact/space.compact.tsx:1-24](file://frontend/antd/space/compact/space.compact.tsx#L1-L24) +- [backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js:651-679](file://backend/modelscope_studio/components/antd/space/templates/component/space-BWI0-XH7.js#L651-L679) +- [backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js:651-674](file://backend/modelscope_studio/components/antd/space/compact/templates/component/space.compact-C2LVtCsM.js#L651-L674) + +## Performance Considerations + +- Child node cloning and Portal: Cloning and Portal mounting avoid direct DOM manipulation, but be aware of rendering costs when there are many child nodes. +- Slot ordering stability: Index-based sorting remains stable even with large datasets, but it is recommended to minimize unnecessary slot changes to reduce reflow overhead. +- SSR and Hugging Face Space: In certain deployment environments, SSR must be disabled to avoid custom component compatibility issues, which affects initial render time. Optimize resource loading at build time. + +[This section contains general performance advice and does not directly analyze specific files] + +## Troubleshooting Guide + +- Child nodes not rendering correctly: Check whether the Svelte layer is properly passing `slots` and `children`; verify that `slotIndex` and `subSlotIndex` are set correctly. +- Separator not taking effect: Confirm whether the `split` slot is correctly passed, or whether `props.split` is provided as expected. +- SSR compatibility issues: When encountering UI anomalies in Hugging Face Space, try adding `ssr_mode=False` to `demo.launch`. + +**Section Sources** + +- [frontend/antd/space/space.tsx:15-17](file://frontend/antd/space/space.tsx#L15-L17) +- [docs/components/antd/space/README.md:1-8](file://docs/components/antd/space/README.md#L1-L8) +- [docs/components/antd/space/README-zh_CN.md:1-8](file://docs/components/antd/space/README-zh_CN.md#L1-L8) + +## Conclusion + +The Space component achieves seamless integration of Ant Design Space/Space.Compact in the Gradio ecosystem through Svelte–React bridging. Standard Space is suitable for general layouts, while Space.Compact is better suited for scenarios requiring tight element arrangement. With slot ordering and Portal bridging, the component maintains good maintainability and consistency even in complex layouts. + +[This section contains summary content and does not directly analyze specific files] + +## Appendix + +- Usage examples: See the example tabs in the documentation directory for basic usage demonstrations. +- Documentation entry: Documentation for both Standard Space and Compact Space is located under `docs/components/antd/space`. + +**Section Sources** + +- [docs/components/antd/space/README.md:5-8](file://docs/components/antd/space/README.md#L5-L8) +- [docs/components/antd/space/README-zh_CN.md:5-8](file://docs/components/antd/space/README-zh_CN.md#L5-L8) diff --git a/.wiki/en/Ant Design Components/Layout Components/Splitter.md b/.wiki/en/Ant Design Components/Layout Components/Splitter.md new file mode 100644 index 00000000..2ca8ba7d --- /dev/null +++ b/.wiki/en/Ant Design Components/Layout Components/Splitter.md @@ -0,0 +1,387 @@ +# Splitter + + +**Files Referenced in This Document** +- [frontend/antd/splitter/Index.svelte](file://frontend/antd/splitter/Index.svelte) +- [frontend/antd/splitter/splitter.tsx](file://frontend/antd/splitter/splitter.tsx) +- [frontend/antd/splitter/panel/Index.svelte](file://frontend/antd/splitter/panel/Index.svelte) +- [frontend/antd/splitter/panel/splitter.panel.tsx](file://frontend/antd/splitter/panel/splitter.panel.tsx) +- [frontend/antd/splitter/context.ts](file://frontend/antd/splitter/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [backend/modelscope_studio/components/antd/splitter/panel/__init__.py](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py) +- [docs/components/antd/splitter/README.md](file://docs/components/antd/splitter/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +Splitter is a panel-splitting component based on Ant Design that divides the interface into multiple resizable areas via drag handles. It supports both horizontal and vertical orientations and uses the Panel sub-component for declarative panel organization. The component is widely applicable to scenarios such as code editors (left-right layout), image comparison (left-right or top-bottom), and multi-view side-by-side displays. + +This document provides a systematic explanation of the component's architecture design, data flow, drag-and-resize controls, responsive behavior, interaction experience, styling, and accessibility, along with typical usage examples and best practice recommendations. + +## Project Structure + +Splitter adopts a Svelte + React Slot bridging approach on the frontend, while the backend encapsulates properties and rendering logic via Python components. Key files are distributed as follows: + +- Frontend entry and bridging: `frontend/antd/splitter/Index.svelte` +- Splitter container implementation: `frontend/antd/splitter/splitter.tsx` +- Panel sub-component bridging: `frontend/antd/splitter/panel/Index.svelte` +- Panel sub-component implementation: `frontend/antd/splitter/panel/splitter.panel.tsx` +- Context and item management: `frontend/antd/splitter/context.ts`, `frontend/utils/createItemsContext.tsx` +- Backend Panel component wrapper: `backend/modelscope_studio/components/antd/splitter/panel/__init__.py` +- Documentation and examples entry: `docs/components/antd/splitter/README.md` + +```mermaid +graph TB +subgraph "Frontend (Svelte)" +A["Index.svelte
Entry Bridging"] +B["splitter.tsx
Splitter Container"] +C["panel/Index.svelte
Panel Bridging"] +D["panel/splitter.panel.tsx
Panel Implementation"] +E["context.ts
Items Context"] +F["createItemsContext.tsx
Generic Item Context Utility"] +end +subgraph "Backend (Python)" +G["panel/__init__.py
AntdSplitterPanel Wrapper"] +end +A --> B +A --> C +C --> D +B --> E +D --> E +E --> F +G --> C +``` + +Diagram Sources + +- [frontend/antd/splitter/Index.svelte:1-71](file://frontend/antd/splitter/Index.svelte#L1-L71) +- [frontend/antd/splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [frontend/antd/splitter/panel/Index.svelte:1-77](file://frontend/antd/splitter/panel/Index.svelte#L1-L77) +- [frontend/antd/splitter/panel/splitter.panel.tsx:1-14](file://frontend/antd/splitter/panel/splitter.panel.tsx#L1-L14) +- [frontend/antd/splitter/context.ts:1-7](file://frontend/antd/splitter/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [backend/modelscope_studio/components/antd/splitter/panel/**init**.py:1-85](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L1-L85) + +Section Sources + +- [frontend/antd/splitter/Index.svelte:1-71](file://frontend/antd/splitter/Index.svelte#L1-L71) +- [frontend/antd/splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [frontend/antd/splitter/panel/Index.svelte:1-77](file://frontend/antd/splitter/panel/Index.svelte#L1-L77) +- [frontend/antd/splitter/panel/splitter.panel.tsx:1-14](file://frontend/antd/splitter/panel/splitter.panel.tsx#L1-L14) +- [frontend/antd/splitter/context.ts:1-7](file://frontend/antd/splitter/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [backend/modelscope_studio/components/antd/splitter/panel/**init**.py:1-85](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L1-L85) +- [docs/components/antd/splitter/README.md:1-8](file://docs/components/antd/splitter/README.md#L1-L8) + +## Core Components + +- Splitter Container: Receives the collection of child panels, renders the Ant Design split container, and maps each Panel to an Antd Panel child item. +- Panel Sub-component: Serves as the placeholder and rendering unit for each panel, collecting panel properties and slot content via the Items context and injecting them into Splitter. +- Items Context: Provides "item collection" capability, allowing Panel to inject its own properties and DOM content into Splitter during rendering. +- Backend Wrapper: Python-layer `AntdSplitterPanel` declares and passes properties such as default size, min/max size, collapsibility, and resizability. + +Section Sources + +- [frontend/antd/splitter/splitter.tsx:7-35](file://frontend/antd/splitter/splitter.tsx#L7-L35) +- [frontend/antd/splitter/panel/splitter.panel.tsx:7-11](file://frontend/antd/splitter/panel/splitter.panel.tsx#L7-L11) +- [frontend/antd/splitter/context.ts:3-4](file://frontend/antd/splitter/context.ts#L3-L4) +- [frontend/utils/createItemsContext.tsx:97-184](file://frontend/utils/createItemsContext.tsx#L97-L184) +- [backend/modelscope_studio/components/antd/splitter/panel/**init**.py:8-68](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L8-L68) + +## Architecture Overview + +The Splitter runtime flow is as follows: + +- The Svelte entry bridging component loads the Splitter and Panel components; +- Panel writes its own properties and slot content to the Items context via ItemHandler; +- Splitter is wrapped with `withItemsContextProvider` and reads the collected panel list from the context; +- Finally, Ant Design's Splitter and Panel are rendered. + +```mermaid +sequenceDiagram +participant U as "User" +participant S as "Splitter.Index.svelte" +participant P as "Panel.Index.svelte" +participant IH as "ItemHandler (splt.panel.tsx)" +participant CTX as "ItemsContext (context.ts)" +participant RCTX as "createItemsContext.tsx" +participant C as "Antd Splitter" +U->>S : Render Splitter +S->>RCTX : Initialize Items context +U->>P : Render Panel +P->>IH : Create ItemHandler +IH->>CTX : setItem(..., index, item) +CTX-->>S : Context change callback +S->>C : Render Antd Splitter +C-->>U : Draggable split panels +``` + +Diagram Sources + +- [frontend/antd/splitter/Index.svelte:10-52](file://frontend/antd/splitter/Index.svelte#L10-L52) +- [frontend/antd/splitter/panel/Index.svelte:10-69](file://frontend/antd/splitter/panel/Index.svelte#L10-L69) +- [frontend/antd/splitter/panel/splitter.panel.tsx:7-11](file://frontend/antd/splitter/panel/splitter.panel.tsx#L7-L11) +- [frontend/antd/splitter/context.ts:3-4](file://frontend/antd/splitter/context.ts#L3-L4) +- [frontend/utils/createItemsContext.tsx:108-170](file://frontend/utils/createItemsContext.tsx#L108-L170) +- [frontend/antd/splitter/splitter.tsx:7-35](file://frontend/antd/splitter/splitter.tsx#L7-L35) + +## Detailed Component Analysis + +### Splitter Container Component + +- Responsibility boundary: Maps collected panel items to Ant Design Panel elements and renders the split container. +- Key points: + - Wrapped with `withItemsContextProvider` to ensure it can read `items` injected by Panels. + - Renders slot content to the corresponding Panel via ReactSlot. + - When no panels are present, nothing is rendered, avoiding layout issues caused by empty containers. + +```mermaid +flowchart TD +Start(["Enter Splitter"]) --> Read["Read context items"] +Read --> HasPanels{"Are there panels?"} +HasPanels -- No --> Exit["Return empty"] +HasPanels -- Yes --> Render["Iterate panels and render Antd Panel"] +Render --> Done(["Complete"]) +``` + +Diagram Sources + +- [frontend/antd/splitter/splitter.tsx:8-35](file://frontend/antd/splitter/splitter.tsx#L8-L35) + +Section Sources + +- [frontend/antd/splitter/splitter.tsx:7-35](file://frontend/antd/splitter/splitter.tsx#L7-L35) + +### Panel Sub-component + +- Responsibility boundary: Serves as the placeholder and rendering unit for a single panel, responsible for injecting its own properties and slot content into the Items context. +- Key points: + - Writes `itemIndex`, `itemSlotKey`, `itemElement`, and other information to the context via `ItemHandler`. + - Supports `visible` for display control; supports additional property pass-through and style class binding. + - Slot content is collected via the Svelte slot mechanism and rendered in Splitter as ReactSlot. + +```mermaid +classDiagram +class PanelBridge { ++props : all pass-through properties ++visible : visibility flag ++_internal.index : panel index ++elem_id/ elem_classes/ elem_style : styles and identifiers ++slots : slot content +} +class ItemHandler { ++itemIndex : number ++itemSlotKey : string ++itemElement : HTMLElement ++setItem(...) +} +PanelBridge --> ItemHandler : "Inject item" +``` + +Diagram Sources + +- [frontend/antd/splitter/panel/Index.svelte:25-69](file://frontend/antd/splitter/panel/Index.svelte#L25-L69) +- [frontend/antd/splitter/panel/splitter.panel.tsx:7-11](file://frontend/antd/splitter/panel/splitter.panel.tsx#L7-L11) +- [frontend/antd/splitter/context.ts:3-4](file://frontend/antd/splitter/context.ts#L3-L4) + +Section Sources + +- [frontend/antd/splitter/panel/Index.svelte:14-69](file://frontend/antd/splitter/panel/Index.svelte#L14-L69) +- [frontend/antd/splitter/panel/splitter.panel.tsx:7-11](file://frontend/antd/splitter/panel/splitter.panel.tsx#L7-L11) +- [frontend/antd/splitter/context.ts:3-4](file://frontend/antd/splitter/context.ts#L3-L4) + +### Items Context and Item Collection Mechanism + +- Purpose: Establishes an "item collection" channel in the component tree, enabling Panel to write its own properties and DOM content into Splitter. +- Key points: + - `withItemsContextProvider`: Provides an `ItemsContextProvider` for the component tree, maintaining an `items` map and a `setItem` method. + - `useItems`: Reads the `items` list within Splitter. + - `ItemHandler`: Writes items during Panel rendering, supporting `itemProps`, `itemChildren`, and other extended capabilities. + +```mermaid +sequenceDiagram +participant P as "Panel" +participant IH as "ItemHandler" +participant CTX as "ItemsContext" +participant SP as "Splitter" +P->>IH : Call ItemHandler +IH->>CTX : setItem(slotKey, index, item) +CTX-->>SP : Trigger onChange callback +SP->>SP : Update internal items and re-render +``` + +Diagram Sources + +- [frontend/utils/createItemsContext.tsx:108-170](file://frontend/utils/createItemsContext.tsx#L108-L170) +- [frontend/utils/createItemsContext.tsx:186-261](file://frontend/utils/createItemsContext.tsx#L186-L261) +- [frontend/antd/splitter/splitter.tsx:8-11](file://frontend/antd/splitter/splitter.tsx#L8-L11) + +Section Sources + +- [frontend/utils/createItemsContext.tsx:97-184](file://frontend/utils/createItemsContext.tsx#L97-L184) +- [frontend/utils/createItemsContext.tsx:186-261](file://frontend/utils/createItemsContext.tsx#L186-L261) +- [frontend/antd/splitter/context.ts:3-4](file://frontend/antd/splitter/context.ts#L3-L4) + +### Backend Wrapper and Property Passing + +- `AntdSplitterPanel` provides the following key properties (from the Python wrapper): + - `default_size`: Default panel size + - `min` / `max`: Minimum/maximum size + - `size`: Current size + - `collapsible`: Whether the panel is collapsible + - `resizable`: Whether the panel is resizable + - `elem_id` / `elem_classes` / `elem_style`: Styles and identifiers +- These properties are passed through the Svelte bridging layer to frontend components, ultimately affecting the behavior and appearance of Ant Design Splitter. + +Section Sources + +- [backend/modelscope_studio/components/antd/splitter/panel/**init**.py:8-68](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L8-L68) + +## Dependency Analysis + +- Component coupling: + - Splitter depends on the Items context to obtain the panel collection. + - Panel depends on the Items context via ItemHandler to write its own item. + - The frontend bridging layer (Index.svelte) is responsible for passing properties and slots to React components. +- External dependencies: + - Ant Design's Splitter/Panel interface. + - Svelte Preprocess React toolchain (`sveltify`, `ReactSlot`, `processProps`, etc.). +- Potential circular dependencies: + - Decoupled through context and callbacks to avoid circular references caused by direct mutual referencing. + +```mermaid +graph LR +IDX["Index.svelte"] --> SPLIT["splitter.tsx"] +IDX --> PANEL_IDX["panel/Index.svelte"] +PANEL_IDX --> PANEL_IMPL["panel/splitter.panel.tsx"] +SPLIT --> CTX["context.ts"] +PANEL_IMPL --> CTX +CTX --> UTILS["createItemsContext.tsx"] +``` + +Diagram Sources + +- [frontend/antd/splitter/Index.svelte:10-52](file://frontend/antd/splitter/Index.svelte#L10-L52) +- [frontend/antd/splitter/splitter.tsx:5-6](file://frontend/antd/splitter/splitter.tsx#L5-L6) +- [frontend/antd/splitter/panel/Index.svelte:10-11](file://frontend/antd/splitter/panel/Index.svelte#L10-L11) +- [frontend/antd/splitter/panel/splitter.panel.tsx:5-5](file://frontend/antd/splitter/panel/splitter.panel.tsx#L5-L5) +- [frontend/antd/splitter/context.ts:3-4](file://frontend/antd/splitter/context.ts#L3-L4) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +Section Sources + +- [frontend/antd/splitter/Index.svelte:1-71](file://frontend/antd/splitter/Index.svelte#L1-L71) +- [frontend/antd/splitter/splitter.tsx:1-38](file://frontend/antd/splitter/splitter.tsx#L1-L38) +- [frontend/antd/splitter/panel/Index.svelte:1-77](file://frontend/antd/splitter/panel/Index.svelte#L1-L77) +- [frontend/antd/splitter/panel/splitter.panel.tsx:1-14](file://frontend/antd/splitter/panel/splitter.panel.tsx#L1-L14) +- [frontend/antd/splitter/context.ts:1-7](file://frontend/antd/splitter/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +## Performance Considerations + +- Rendering strategy + - Splitter only renders the container when panels are present, avoiding the overhead of empty renders. + - `useMemoizedEqualValue` and `useMemoizedFn` reduce context update frequency and repeated renders. +- Events and state + - `setItem` and `onChange` are triggered only when values change, reducing unnecessary re-renders. +- Recommendations + - For scenarios with many panels or frequent size adjustments, limit the number of panels and update frequency. + - Set reasonable min/max sizes to avoid reflow jitter caused by extreme sizes. + +Section Sources + +- [frontend/antd/splitter/splitter.tsx:15-31](file://frontend/antd/splitter/splitter.tsx#L15-L31) +- [frontend/utils/createItemsContext.tsx:113-153](file://frontend/utils/createItemsContext.tsx#L113-L153) +- [frontend/utils/createItemsContext.tsx:234-254](file://frontend/utils/createItemsContext.tsx#L234-L254) + +## Troubleshooting Guide + +- Panel not displaying + - Check whether Panel's `visible` is true; confirm that the bridging layer has correctly passed `visible`. + - Confirm whether Panel has successfully written to the Items context (check `setItem` calls and indices). +- Drag not working + - Confirm that `resizable` and resizable direction settings are correct; check Ant Design version and whether styles are complete. +- Size anomalies + - Check whether `min`/`max` and `default_size` settings are reasonable; avoid setting them to 0 or negative values. +- Slot content not rendering + - Confirm that Panel's slot bindings are consistent with ReactSlot usage; avoid premature slot destruction. + +Section Sources + +- [frontend/antd/splitter/panel/Index.svelte:52-69](file://frontend/antd/splitter/panel/Index.svelte#L52-L69) +- [frontend/antd/splitter/splitter.tsx:14-31](file://frontend/antd/splitter/splitter.tsx#L14-L31) +- [backend/modelscope_studio/components/antd/splitter/panel/**init**.py:62-66](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L62-L66) + +## Conclusion + +Splitter achieves flexible panel organization and rendering through the Items context and Svelte/React bridging. Its core strengths are: + +- User-facing declarative API (Panel sub-component) +- Deep integration with Ant Design (drag, direction, size control) +- Extensible item collection mechanism (supports dynamic add/remove/update) + +In practice, it is recommended to set reasonable size constraints and interaction behaviors based on business scenarios, with attention to performance and maintainability. + +## Appendix + +### Configuration and Property Reference + +- Splitter Container + - Direction: Controlled by Ant Design's direction property (horizontal/vertical) + - Drag: Provided by Ant Design's drag capability + - Events: `resizeStart`/`resizeEnd` (mapped via bridging layer) +- Panel Sub-component + - `default_size` / `size`: Default/current size + - `min` / `max`: Minimum/maximum size + - `collapsible` / `resizable`: Collapsible/resizable + - `elem_id` / `elem_classes` / `elem_style`: Styles and identifiers + - `visible`: Visibility flag + +Section Sources + +- [frontend/antd/splitter/Index.svelte:25-52](file://frontend/antd/splitter/Index.svelte#L25-L52) +- [frontend/antd/splitter/splitter.tsx:16-30](file://frontend/antd/splitter/splitter.tsx#L16-L30) +- [backend/modelscope_studio/components/antd/splitter/panel/**init**.py:61-66](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L61-L66) + +### Application Scenario Examples + +- Code editor: File tree/outline on the left, code editing area on the right, with left-right drag to adjust width. +- Image comparison: Two images arranged left-right or top-bottom, with drag to adjust the ratio. +- Multi-view display: Three-column layout (left/center/right), center as main view, sides as tool/preview panels. + +Section Sources + +- [docs/components/antd/splitter/README.md:1-8](file://docs/components/antd/splitter/README.md#L1-L8) + +### Responsive Behavior and Interaction Experience + +- Responsive behavior: Adapts panel ratios based on container width/height; it is recommended to enable collapsibility on small-screen devices. +- Interaction experience: Provides visual feedback during dragging; set reasonable minimum sizes to avoid accidental triggers. + +Section Sources + +- [backend/modelscope_studio/components/antd/splitter/panel/**init**.py:14-16](file://backend/modelscope_studio/components/antd/splitter/panel/__init__.py#L14-L16) + +### Style Customization and Accessibility + +- Style customization: Inject custom styles via `elem_classes` and `elem_style`; note compatibility with Ant Design default styles. +- Animation effects: Combine CSS transitions or third-party animation libraries for smooth size switching. +- Accessibility: Provide accessible labels and keyboard operation hints for drag handles; ensure collapsible states have clear ARIA attributes. + +Section Sources + +- [frontend/antd/splitter/panel/Index.svelte:54-55](file://frontend/antd/splitter/panel/Index.svelte#L54-L55) +- [frontend/antd/splitter/splitter.tsx:16-30](file://frontend/antd/splitter/splitter.tsx#L16-L30) diff --git a/.wiki/en/Ant Design Components/Navigation Components/Anchor.md b/.wiki/en/Ant Design Components/Navigation Components/Anchor.md new file mode 100644 index 00000000..0ccd423e --- /dev/null +++ b/.wiki/en/Ant Design Components/Navigation Components/Anchor.md @@ -0,0 +1,302 @@ +# Anchor + + +**Files Referenced in This Document** +- [frontend/antd/anchor/Index.svelte](file://frontend/antd/anchor/Index.svelte) +- [frontend/antd/anchor/anchor.tsx](file://frontend/antd/anchor/anchor.tsx) +- [frontend/antd/anchor/context.ts](file://frontend/antd/anchor/context.ts) +- [frontend/antd/anchor/item/Index.svelte](file://frontend/antd/anchor/item/Index.svelte) +- [frontend/antd/anchor/item/anchor.item.tsx](file://frontend/antd/anchor/item/anchor.item.tsx) +- [backend/modelscope_studio/components/antd/anchor/__init__.py](file://backend/modelscope_studio/components/antd/anchor/__init__.py) +- [backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js](file://backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js) +- [docs/components/antd/anchor/README.md](file://docs/components/antd/anchor/README.md) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Anchor component provides clickable navigation links within a single page, supporting scroll-based positioning to corresponding headings or sections, and can be combined with fixed mode (Affix) to remain visible while the page scrolls. This component is a wrapper around Ant Design's Anchor component and provides the following capabilities: + +- Scroll positioning: Smooth or direct scrolling to target positions of anchor items +- Link generation: Supports dynamically generating anchor items via an `items` list or slots +- Active state management: Automatically highlights anchor items currently in the viewport +- Nested structure: Anchor items support nesting to form hierarchical navigation +- Events and extensions: Supports `change`, `click`, and `affix_change` event bindings, as well as Affix fixed mode + +## Project Structure + +The Anchor component consists of a frontend Svelte wrapper layer and a backend Gradio component layer, along with an anchor item sub-component to support nesting and slot rendering. + +```mermaid +graph TB +subgraph "Frontend" +A_Index["frontend/antd/anchor/Index.svelte"] +A_Component["frontend/antd/anchor/anchor.tsx"] +A_Context["frontend/antd/anchor/context.ts"] +A_Item_Index["frontend/antd/anchor/item/Index.svelte"] +A_Item_Component["frontend/antd/anchor/item/anchor.item.tsx"] +end +subgraph "Backend" +B_Anchor["backend/modelscope_studio/components/antd/anchor/__init__.py"] +B_Item_Template["backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js"] +end +subgraph "Documentation" +D_Readme["docs/components/antd/anchor/README.md"] +end +A_Index --> A_Component +A_Component --> A_Context +A_Item_Index --> A_Item_Component +A_Component --> B_Anchor +A_Item_Component --> B_Item_Template +D_Readme --> B_Anchor +``` + +Diagram Sources + +- [frontend/antd/anchor/Index.svelte:1-66](file://frontend/antd/anchor/Index.svelte#L1-L66) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [frontend/antd/anchor/item/Index.svelte:1-75](file://frontend/antd/anchor/item/Index.svelte#L1-L75) +- [frontend/antd/anchor/item/anchor.item.tsx:1-22](file://frontend/antd/anchor/item/anchor.item.tsx#L1-L22) +- [backend/modelscope_studio/components/antd/anchor/**init**.py:1-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L1-L117) +- [backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js:1-450](file://backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js#L1-L450) +- [docs/components/antd/anchor/README.md:1-8](file://docs/components/antd/anchor/README.md#L1-L8) + +Section Sources + +- [frontend/antd/anchor/Index.svelte:1-66](file://frontend/antd/anchor/Index.svelte#L1-L66) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [frontend/antd/anchor/item/Index.svelte:1-75](file://frontend/antd/anchor/item/Index.svelte#L1-L75) +- [frontend/antd/anchor/item/anchor.item.tsx:1-22](file://frontend/antd/anchor/item/anchor.item.tsx#L1-L22) +- [backend/modelscope_studio/components/antd/anchor/**init**.py:1-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L1-L117) +- [backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js:1-450](file://backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js#L1-L450) +- [docs/components/antd/anchor/README.md:1-8](file://docs/components/antd/anchor/README.md#L1-L8) + +## Core Components + +- Top-level Anchor component (AntdAnchor) + - Receives an `items` list or slot children, converting them to the items structure required by Ant Design Anchor + - Supports `affix`, `bounds`, `offsetTop`, `direction`, `replace`, `rootClassName`, and other properties + - Provides `change`, `click`, and `affix_change` event binding entry points +- Anchor item component (AntdAnchorItem) + - Acts as the container for anchor items, supporting default slot content rendering + - Collaborates with the parent anchor component via the context system to achieve nesting and hierarchical display + +Section Sources + +- [backend/modelscope_studio/components/antd/anchor/**init**.py:11-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L11-L117) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [frontend/antd/anchor/item/Index.svelte:1-75](file://frontend/antd/anchor/item/Index.svelte#L1-L75) +- [frontend/antd/anchor/item/anchor.item.tsx:1-22](file://frontend/antd/anchor/item/anchor.item.tsx#L1-L22) + +## Architecture Overview + +The following diagram shows the call chain from the backend Gradio component to the frontend Svelte/React wrapper layer and on to Ant Design Anchor, as well as the event and slot passing process. + +```mermaid +sequenceDiagram +participant Backend as "Backend Component
AntdAnchor" +participant FrontIndex as "Frontend Wrapper
Index.svelte" +participant AnchorTSX as "Frontend Implementation
anchor.tsx" +participant Context as "Context
context.ts" +participant Antd as "Ant Design Anchor" +Backend->>FrontIndex : Render wrapper component and pass props +FrontIndex->>AnchorTSX : Pass restProps, additionalProps, slots +AnchorTSX->>Context : Use Items context to resolve slots items/default +AnchorTSX->>Antd : Render Anchor and inject items, getContainer, getCurrentAnchor +Antd-->>AnchorTSX : Trigger change/click/affix_change event callbacks +AnchorTSX-->>FrontIndex : Pass events to backend +``` + +Diagram Sources + +- [frontend/antd/anchor/Index.svelte:1-66](file://frontend/antd/anchor/Index.svelte#L1-L66) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [backend/modelscope_studio/components/antd/anchor/**init**.py:11-33](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L11-L33) + +## Detailed Component Analysis + +### Top-level Anchor Component (AntdAnchor) + +- Feature highlights + - Receives an `items` list or slot children; internally converts slots to items via utility functions + - Supports `getContainer` and `getCurrentAnchor` for custom container and current anchor determination logic + - Provides Affix fixed mode, `bounds` boundary distance, `offsetTop` top offset, `direction`, `replace` history replacement, and other configurations + - Events: `change` (anchor changed), `click` (clicked), `affix_change` (fixed state changed) +- Data flow + - Slots `items/default` → context resolution → Ant Design Anchor items + - `getContainer`/`getCurrentAnchor` are passed to Ant Design Anchor after being wrapped with `useFunction` +- Applicable scenarios + - Document tables of contents, long-list navigation, help centers, product introduction pages, and other scenarios requiring quick jumping + +```mermaid +flowchart TD +Start(["Start"]) --> Resolve["Resolve slots items/default"] +Resolve --> HasItems{"Are items params provided?"} +HasItems --> |Yes| UseParam["Use passed-in items"] +HasItems --> |No| RenderItems["Render items via utility functions"] +UseParam --> BuildProps["Build Anchor properties"] +RenderItems --> BuildProps +BuildProps --> Inject["Inject getContainer / getCurrentAnchor"] +Inject --> Render["Render Ant Design Anchor"] +Render --> End(["End"]) +``` + +Diagram Sources + +- [frontend/antd/anchor/anchor.tsx:13-42](file://frontend/antd/anchor/anchor.tsx#L13-L42) + +Section Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [backend/modelscope_studio/components/antd/anchor/**init**.py:38-98](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L38-L98) + +### Anchor Item Component (AntdAnchorItem) + +- Feature highlights + - Acts as the container for anchor items, supporting default slot content rendering + - Maps slot content to AntdAnchor item children via `ItemHandler` + - Supports `href_target` property mapped to `target` attribute, for controlling link opening behavior +- Nested structure + - Cooperates with the parent via `createItemsContext` to support multi-level nested anchor items +- Applicable scenarios + - Grouping and hierarchically displaying sections in complex documents + +```mermaid +classDiagram +class AnchorItem { ++Allowed slot : "default" ++Property : "href_target" -> "target" ++Function : "Map slot content to item children" +} +class Context { ++useItems() ++withItemsContextProvider() ++ItemHandler +} +AnchorItem --> Context : "Use context" +``` + +Diagram Sources + +- [frontend/antd/anchor/item/anchor.item.tsx:1-22](file://frontend/antd/anchor/item/anchor.item.tsx#L1-L22) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) + +Section Sources + +- [frontend/antd/anchor/item/Index.svelte:1-75](file://frontend/antd/anchor/item/Index.svelte#L1-L75) +- [frontend/antd/anchor/item/anchor.item.tsx:1-22](file://frontend/antd/anchor/item/anchor.item.tsx#L1-L22) +- [backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js:437-449](file://backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js#L437-L449) + +### Events and Lifecycle + +- `change`: Triggered when the currently active anchor changes +- `click`: Triggered when an anchor link is clicked +- `affix_change`: Triggered when the Affix fixed mode state changes +- Lifecycle: The component updates the layout marker when it exits scope, ensuring correct render ordering + +Section Sources + +- [backend/modelscope_studio/components/antd/anchor/**init**.py:20-33](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L20-L33) +- [backend/modelscope_studio/utils/dev/component.py:24-26](file://backend/modelscope_studio/utils/dev/component.py#L24-L26) + +## Dependency Analysis + +- The frontend wrapper layer depends on Ant Design Anchor, bridged via `sveltify` and `withItemsContextProvider` +- The slot system implements parent-child component communication via `createItemsContext`, supporting both `items` and `default` slots +- The backend component inherits from `ModelScopeLayoutComponent`, providing unified layout and event binding capabilities + +```mermaid +graph LR +AnchorTSX["anchor.tsx"] --> Antd["Ant Design Anchor"] +AnchorTSX --> Context["context.ts"] +AnchorItemTSX["anchor.item.tsx"] --> Context +AnchorTSX --> Backend["AntdAnchor(__init__.py)"] +AnchorItemTSX --> BackendItem["anchor.item Template"] +``` + +Diagram Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [frontend/antd/anchor/item/anchor.item.tsx:1-22](file://frontend/antd/anchor/item/anchor.item.tsx#L1-L22) +- [backend/modelscope_studio/components/antd/anchor/**init**.py:1-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L1-L117) +- [backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js:1-450](file://backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js#L1-L450) + +Section Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) +- [frontend/antd/anchor/item/anchor.item.tsx:1-22](file://frontend/antd/anchor/item/anchor.item.tsx#L1-L22) +- [backend/modelscope_studio/components/antd/anchor/**init**.py:1-117](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L1-L117) +- [backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js:1-450](file://backend/modelscope_studio/components/antd/anchor/item/templates/component/anchor.item-DRmYMecq.js#L1-L450) + +## Performance Considerations + +- items rendering optimization + - Use `useMemo` to cache items computation results, avoiding unnecessary re-renders + - Prefer passing the `items` parameter rather than relying on slots to reduce slot resolution costs +- Function wrapping + - Wrap `getContainer`/`getCurrentAnchor` with `useFunction` to ensure callbacks are stable and reusable +- Scroll monitoring + - Set `bounds` and `offsetTop` reasonably to avoid frequent `change` event triggers + - For large documents, consider using `replace` to replace history records, reducing memory usage +- Fixed mode (Affix) + - Affix mode keeps the component visible during scrolling; pay attention to container selection and z-index relationships to avoid occlusion + +## Troubleshooting Guide + +- Anchor not working + - Check whether `getContainer` points to the correct scroll container; if not set, the viewport may not be calculated correctly + - Confirm the target element exists and has the corresponding anchor identifier +- Active state not updating + - Check whether `bounds` and `offsetTop` settings are reasonable; too small a boundary may cause delayed switching + - Confirm the `getCurrentAnchor` return value matches the `key` or `href` in `items` +- Link opening behavior abnormal + - `href_target` maps to `target`; confirm whether it needs to open in a new window or the current window +- Events not triggering + - Confirm event bindings are enabled (`bind_change_event`, `bind_click_event`, `bind_affix_change_event`) + - Check whether state changes in Affix mode behave as expected + +Section Sources + +- [frontend/antd/anchor/anchor.tsx:13-42](file://frontend/antd/anchor/anchor.tsx#L13-L42) +- [backend/modelscope_studio/components/antd/anchor/**init**.py:20-33](file://backend/modelscope_studio/components/antd/anchor/__init__.py#L20-L33) + +## Conclusion + +The Anchor component provides flexible anchor navigation capabilities through frontend-backend collaboration. Its core strengths are: + +- Dual-channel anchor item generation via `items` and slots, meeting different scenario needs +- Deep integration with Ant Design Anchor, with comprehensive scroll positioning and active state management +- A complete event system that facilitates extended interactions and analytics tracking +- Support for nested structure and fixed mode, suitable for complex documents and long-page navigation + +## Appendix + +- Usage examples and documentation + - Refer to basic examples in the documentation for fundamental usage and parameter descriptions +- Common issues + - If the page has multiple scroll containers, explicitly specify `getContainer` + - For large documents, consider enabling `replace` to optimize history management + - To customize highlight strategy, use `getCurrentAnchor` for customization + +Section Sources + +- [docs/components/antd/anchor/README.md:1-8](file://docs/components/antd/anchor/README.md#L1-L8) diff --git a/.wiki/en/Ant Design Components/Navigation Components/Breadcrumb.md b/.wiki/en/Ant Design Components/Navigation Components/Breadcrumb.md new file mode 100644 index 00000000..36ceca66 --- /dev/null +++ b/.wiki/en/Ant Design Components/Navigation Components/Breadcrumb.md @@ -0,0 +1,393 @@ +# Breadcrumb + + +**Files Referenced in This Document** +- [frontend/antd/breadcrumb/breadcrumb.tsx](file://frontend/antd/breadcrumb/breadcrumb.tsx) +- [frontend/antd/breadcrumb/context.ts](file://frontend/antd/breadcrumb/context.ts) +- [frontend/antd/breadcrumb/Index.svelte](file://frontend/antd/breadcrumb/Index.svelte) +- [backend/modelscope_studio/components/antd/breadcrumb/__init__.py](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py) +- [backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) +- [docs/components/antd/breadcrumb/README.md](file://docs/components/antd/breadcrumb/README.md) +- [docs/components/antd/breadcrumb/README-zh_CN.md](file://docs/components/antd/breadcrumb/README-zh_CN.md) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +The Breadcrumb component displays the current location within a hierarchical structure and allows users to return to previous states. The breadcrumb component in this repository is based on Ant Design's Breadcrumb implementation, wrapped via React and bridged to the Svelte frontend, while also providing a Python backend component to support layout and event binding in the Gradio ecosystem. The component supports: + +- Navigation path display and click-to-navigate +- Custom separators and rendering of each breadcrumb item +- Advanced interactions such as dropdown menus and overflow indicators +- Dynamic path generation and permission control when integrating with routing systems +- Multi-language and theme style customization + +## Project Structure + +The Breadcrumb component consists of a frontend React wrapper layer, a Svelte bridging layer, a backend Gradio component layer, and a runtime template, organized as follows: + +```mermaid +graph TB +subgraph "Frontend" +SvelteIndex["frontend/antd/breadcrumb/Index.svelte"] +ReactWrapper["frontend/antd/breadcrumb/breadcrumb.tsx"] +ItemsCtx["frontend/antd/breadcrumb/context.ts"] +end +subgraph "Backend" +PyComp["backend/modelscope_studio/components/antd/breadcrumb/__init__.py"] +PyItem["backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py"] +DevBase["backend/modelscope_studio/utils/dev/component.py"] +ResolveDir["backend/modelscope_studio/utils/dev/resolve_frontend_dir.py"] +end +subgraph "Runtime Template" +RuntimeJS["backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js"] +end +SvelteIndex --> ReactWrapper +ReactWrapper --> ItemsCtx +PyComp --> ResolveDir +PyComp --> RuntimeJS +PyItem --> ResolveDir +PyItem --> RuntimeJS +DevBase --> PyComp +DevBase --> PyItem +``` + +Diagram Sources + +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:1-114](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L1-L114) +- [backend/modelscope_studio/utils/dev/component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:1-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L1-L17) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:1-766](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L1-L766) + +Section Sources + +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:1-114](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L1-L114) +- [backend/modelscope_studio/utils/dev/component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:1-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L1-L17) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:1-766](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L1-L766) + +## Core Components + +- Frontend React wrapper: Connects Ant Design's Breadcrumb with the Slots rendering system, supporting custom separators, item renderer functions, and dropdown icons. +- Svelte bridging: Converts backend-provided properties and slots into frontend-consumable props, and imports React components as needed. +- Backend components: Provides `AntdBreadcrumb` and `AntdBreadcrumbItem`, supporting event bindings, slots, and frontend directory resolution. +- Runtime template: Contains the actual React component implementation and slot handling logic. + +Section Sources + +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:1-114](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L1-L114) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:1-766](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L1-L766) + +## Architecture Overview + +The Breadcrumb component call chain from backend to frontend is as follows: + +```mermaid +sequenceDiagram +participant Py as "Python Backend Component
AntdBreadcrumb/AntdBreadcrumbItem" +participant Svelte as "Svelte Bridging
Index.svelte" +participant React as "React Wrapper
breadcrumb.tsx" +participant AD as "Ant Design Breadcrumb" +Py->>Svelte : Resolve frontend directory and pass properties/slots +Svelte->>React : Convert props and inject slots +React->>AD : Render Breadcrumb, apply custom separator/item renderer/dropdown icon +AD-->>React : Render result +React-->>Svelte : Return DOM +Svelte-->>Py : Render complete +``` + +Diagram Sources + +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:1-114](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L1-L114) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:1-766](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L1-L766) + +## Detailed Component Analysis + +### Frontend React Wrapper (breadcrumb.tsx) + +- Key points + - Uses `sveltify` to bridge the Svelte component to React. + - Provides breadcrumb item context via `withItemsContextProvider`. + - Supports slots: `separator`, `itemRender`, `dropdownIcon`; prefers slots, falls back to props. + - Uses `renderItems` to convert slot items into the `ItemType` list required by Ant Design. + - Uses `renderParamsSlot` to render the parameterized `itemRender` slot. +- Key flow + - Reads `items/default` from context. + - Computes the final items list (items takes priority over slots). + - Renders Ant Design Breadcrumb with injected custom separator and item renderer. + +```mermaid +flowchart TD +Start(["Enter React Wrapper"]) --> ReadCtx["Read context items/default"] +ReadCtx --> DecideItems{"Are items params provided?"} +DecideItems --> |Yes| UseParam["Use passed-in items"] +DecideItems --> |No| UseSlot["Use items/default slot"] +UseParam --> RenderItems["renderItems converts to AntD Item type"] +UseSlot --> RenderItems +RenderItems --> ApplySlots{"Do slots exist?"} +ApplySlots --> |separator| SepSlot["Use separator slot"] +ApplySlots --> |itemRender| ItemRenderSlot["Use itemRender slot"] +ApplySlots --> |dropdownIcon| DropSlot["Use dropdownIcon slot"] +ApplySlots --> |none| UseProps["Use original prop values"] +SepSlot --> RenderAD["Render AntD Breadcrumb"] +ItemRenderSlot --> RenderAD +DropSlot --> RenderAD +UseProps --> RenderAD +RenderAD --> End(["Complete"]) +``` + +Diagram Sources + +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:727-761](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L727-L761) + +Section Sources + +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:727-761](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L727-L761) + +### Svelte Bridging (Index.svelte) + +- Key points + - Retrieves backend-provided props and additional properties. + - Maps event names to camelCase as required by Ant Design. + - Renders `children` as child nodes of the React component. + - Asynchronously loads the React-wrapped Breadcrumb via `importComponent`. +- Key flow + - `processProps` normalizes properties and handles event aliases. + - `getSlots` retrieves the set of slots. + - Renders Breadcrumb and passes in slots and children. + +```mermaid +sequenceDiagram +participant Svelte as "Index.svelte" +participant Loader as "importComponent" +participant Wrapper as "breadcrumb.tsx" +Svelte->>Loader : Load React wrapper component +Loader-->>Svelte : Return component reference +Svelte->>Wrapper : Pass props/slots/children +Wrapper-->>Svelte : Return render result +``` + +Diagram Sources + +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) + +Section Sources + +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) + +### Backend Components (AntdBreadcrumb / AntdBreadcrumbItem) + +- AntdBreadcrumb + - Supported slots: `separator`, `itemRender`, `items`, `dropdownIcon`. + - Points to the frontend breadcrumb directory via `resolve_frontend_dir`. + - Inherits `ModelScopeLayoutComponent` with general layout component capabilities. +- AntdBreadcrumbItem + - Supported slots: `title`, `menu.*`, `dropdownProps.*`, `dropdownProps.menu.*`. + - Supports events: `click`, `menu_*`, `dropdownProps_*`, etc., for interacting with routes or menus. + - Points to the frontend breadcrumb/item sub-component directory via `resolve_frontend_dir`. + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++skip_api : bool ++SLOTS : list ++__init__(...) +} +class AntdBreadcrumb { ++SLOTS : list ++FRONTEND_DIR : str ++__init__(...) +} +class AntdBreadcrumbItem { ++SLOTS : list ++EVENTS : list ++FRONTEND_DIR : str ++__init__(...) +} +ModelScopeLayoutComponent <|-- AntdBreadcrumb +ModelScopeLayoutComponent <|-- AntdBreadcrumbItem +``` + +Diagram Sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:1-114](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L1-L114) + +Section Sources + +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:1-114](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L1-L114) +- [backend/modelscope_studio/utils/dev/component.py:1-169](file://backend/modelscope_studio/utils/dev/component.py#L1-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:1-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L1-L17) + +### Runtime Template (breadcrumb-C7MaDQtV.js) + +- Key points + - Provides `createItemsContext` context for sharing breadcrumb items in the React layer. + - Provides runtime implementations of `renderItems` and `renderParamsSlot`, supporting slot cloning and parameterized rendering. + - Converts Svelte slots into React-consumable structures, supporting nested slots and menu items. +- Key flow + - Reads `items/default` from context. + - Uses utility functions `ve/oe/Mt` to convert slots into props required by AntD. + - Renders AntD Breadcrumb with custom separator and item renderer applied. + +```mermaid +flowchart TD +LoadCtx["Read context items/default"] --> MergeItems["Merge items/default"] +MergeItems --> Convert["ve/oe/Mt convert slots to React structure"] +Convert --> RenderAD["Render AntD Breadcrumb"] +RenderAD --> Done(["Complete"]) +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:727-761](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L727-L761) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:649-726](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L649-L726) + +Section Sources + +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:1-766](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L1-L766) + +## Dependency Analysis + +- Frontend dependencies + - React wrapper depends on Ant Design Breadcrumb types and rendering utilities. + - Svelte bridging depends on `@svelte-preprocess-react` component import and slot system. +- Backend dependencies + - `AntdBreadcrumb`/`AntdBreadcrumbItem` depend on `resolve_frontend_dir` for frontend directory resolution. + - Inherits `ModelScopeLayoutComponent`, reusing general layout component capabilities. +- Runtime dependencies + - The template file provides slot and context handling logic, ensuring consistent rendering behavior between frontend and backend. + +```mermaid +graph LR +PyComp["AntdBreadcrumb"] --> Resolve["resolve_frontend_dir"] +PyItem["AntdBreadcrumbItem"] --> Resolve +PyComp --> Runtime["Runtime Template breadcrumb-C7MaDQtV.js"] +PyItem --> Runtime +Svelte["Index.svelte"] --> ReactWrap["breadcrumb.tsx"] +ReactWrap --> AD["Ant Design Breadcrumb"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:56-56](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L56-L56) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:97-97](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L97-L97) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-16](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L16) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:1-766](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L1-L766) +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) + +Section Sources + +- [backend/modelscope_studio/components/antd/breadcrumb/**init**.py:1-73](file://backend/modelscope_studio/components/antd/breadcrumb/__init__.py#L1-L73) +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:1-114](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L1-L114) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:1-17](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L1-L17) +- [frontend/antd/breadcrumb/Index.svelte:1-78](file://frontend/antd/breadcrumb/Index.svelte#L1-L78) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:1-766](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L1-L766) + +## Performance Considerations + +- Slot cloning strategy + - Slot rendering defaults to a cloning strategy to avoid duplicate rendering overhead, but can be controlled via `forceClone`. +- Computation caching + - Uses `useMemo` to cache the final items list, reducing unnecessary re-renders. +- Event mapping + - CamelCase event name mapping is performed uniformly in the Svelte layer, reducing runtime conversion costs. +- Template optimization + - The runtime template provides stable slot conversion and context merging logic, reducing branching logic and object copying. + +Section Sources + +- [frontend/antd/breadcrumb/breadcrumb.tsx:44-51](file://frontend/antd/breadcrumb/breadcrumb.tsx#L44-L51) +- [frontend/antd/breadcrumb/Index.svelte:27-58](file://frontend/antd/breadcrumb/Index.svelte#L27-L58) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:190-206](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L190-L206) + +## Troubleshooting Guide + +- Slots not taking effect + - Confirm slot names are correct (e.g., `separator`, `itemRender`), and that they are declared as supported in the React wrapper layer. + - Check whether slot elements exist in children and have not been hidden or removed. +- Events not triggering + - Confirm event names are registered in the backend component (e.g., `click`, `menu_*`, `dropdownProps_*`). + - Check whether the Svelte layer correctly maps to camelCase names required by AntD. +- Routing integration issues + - If using dropdown menus or overflow indicators, confirm that menu item `href`/`path` matches the route. + - For permission control, it is recommended to dynamically decide whether to render an item or disable clicks in `itemRender` based on user permissions. +- Style anomalies + - Use `elem_classes`/`elem_style` or `classNames`/`styles` to apply styles; ensure compatibility with AntD themes. + - To override default styles, use CSS Modules or theme variables for customization. + +Section Sources + +- [backend/modelscope_studio/components/antd/breadcrumb/item/**init**.py:15-46](file://backend/modelscope_studio/components/antd/breadcrumb/item/__init__.py#L15-L46) +- [frontend/antd/breadcrumb/Index.svelte:51-57](file://frontend/antd/breadcrumb/Index.svelte#L51-L57) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:370-391](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L370-L391) + +## Conclusion + +The Breadcrumb component achieves flexible path display and user guidance through a collaborative frontend-backend design. Its core strengths are: + +- Slot-based extensibility: Supports custom separators, item renderers, and dropdown icons. +- Event-driven: Built-in rich event listeners, making it easy to integrate with routing systems. +- Theme adaptability: Easily adapts to different themes via style properties and runtime context. +- Performance-friendly: Reduces rendering costs via caching and cloning strategies. + +## Appendix: Usage Examples and Best Practices + +- Basic usage + - Refer to documentation examples to quickly build breadcrumb paths. +- Dynamic path generation + - Use the `items` parameter or slot `items` to dynamically build a path array, generating titles and links combined with route parameters. +- Permission control + - In `itemRender`, decide whether to render an item or disable clicks based on user roles. +- Multi-language support + - Pass title and separator text via slots, or switch language-specific content in `itemRender`. +- Style customization + - Use `elem_classes`/`elem_style` or `classNames`/`styles` for custom styles; override default styles via theme variables as needed. +- Performance optimization + - Use `forceClone` and `useMemo` judiciously to avoid unnecessary cloning and re-renders. + - Enable dropdown menus and overflow indicators for long lists to reduce the number of rendered nodes. + +Section Sources + +- [docs/components/antd/breadcrumb/README.md:1-8](file://docs/components/antd/breadcrumb/README.md#L1-L8) +- [docs/components/antd/breadcrumb/README-zh_CN.md:1-8](file://docs/components/antd/breadcrumb/README-zh_CN.md#L1-L8) +- [frontend/antd/breadcrumb/breadcrumb.tsx:44-51](file://frontend/antd/breadcrumb/breadcrumb.tsx#L44-L51) +- [backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js:727-761](file://backend/modelscope_studio/components/antd/breadcrumb/templates/component/breadcrumb-C7MaDQtV.js#L727-L761) diff --git a/.wiki/en/Ant Design Components/Navigation Components/Dropdown.md b/.wiki/en/Ant Design Components/Navigation Components/Dropdown.md new file mode 100644 index 00000000..fc819847 --- /dev/null +++ b/.wiki/en/Ant Design Components/Navigation Components/Dropdown.md @@ -0,0 +1,325 @@ +# Dropdown + + +**Files Referenced in This Document** +- [frontend/antd/dropdown/dropdown.tsx](file://frontend/antd/dropdown/dropdown.tsx) +- [frontend/antd/dropdown/button/Index.svelte](file://frontend/antd/dropdown/button/Index.svelte) +- [backend/modelscope_studio/components/antd/dropdown/__init__.py](file://backend/modelscope_studio/components/antd/dropdown/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [docs/components/antd/dropdown/README.md](file://docs/components/antd/dropdown/README.md) +- [docs/components/antd/dropdown/demos/basic.py](file://docs/components/antd/dropdown/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically introduces the implementation and usage of the Dropdown component in the ModelScope Studio frontend, covering the following topics: + +- Trigger mechanisms and popup containers +- Menu item configuration and rendering +- Popup positioning and placement strategies +- Interaction behaviors and event handling +- Keyboard navigation and accessibility support +- Integration with forms, icon buttons, and text links +- Advanced usage: multi-level menus, dynamic menus, remote loading +- Performance optimization recommendations and common issues + +## Project Structure + +The Dropdown component consists of backend Python components and a frontend Svelte/React wrapper layer, bridged through the Gradio ecosystem. + +```mermaid +graph TB +subgraph "Backend" +PY_API["AntdDropdown
Python Component"] +BTN_PY["AntdDropdown.Button
Python Component"] +end +subgraph "Frontend" +WRAP["Dropdown Wrapper
dropdown.tsx"] +BTN_SVLT["Dropdown.Button Frontend Wrapper
button/Index.svelte"] +ANTD["Antd Dropdown Component"] +MENU_CTX["Menu Context Provider"] +end +PY_API --> WRAP +BTN_PY --> BTN_SVLT +WRAP --> ANTD +WRAP --> MENU_CTX +BTN_SVLT --> ANTD +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:11-38](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L11-L38) +- [frontend/antd/dropdown/dropdown.tsx:15-108](file://frontend/antd/dropdown/dropdown.tsx#L15-L108) +- [frontend/antd/dropdown/button/Index.svelte:10-70](file://frontend/antd/dropdown/button/Index.svelte#L10-L70) + +Section Sources + +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:11-38](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L11-L38) +- [frontend/antd/dropdown/dropdown.tsx:15-108](file://frontend/antd/dropdown/dropdown.tsx#L15-L108) +- [frontend/antd/dropdown/button/Index.svelte:10-70](file://frontend/antd/dropdown/button/Index.svelte#L10-L70) + +## Core Components + +- Backend Python components: `AntdDropdown` and `AntdDropdown.Button` +- Frontend wrapper layer: Dropdown (React wrapper + Antd Dropdown), Dropdown.Button (Svelte wrapper) +- Menu context: Injects "menu items" into the dropdown via the Menu Context Provider + +Key features + +- Supports injecting menu items, expand icons, overflow indicators, and custom popup rendering via slots +- Supports `getPopupContainer` for custom popup containers +- Supports `open_change`, `menu_*` series of event bindings +- Provides inline style pass-through (`innerStyle`) and container style (`overlayStyle`) + +Section Sources + +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:34-38](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L34-L38) +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:40-100](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L40-L100) +- [frontend/antd/dropdown/dropdown.tsx:15-25](file://frontend/antd/dropdown/dropdown.tsx#L15-L25) +- [frontend/antd/dropdown/dropdown.tsx:44-92](file://frontend/antd/dropdown/dropdown.tsx#L44-L92) + +## Architecture Overview + +The Dropdown call chain is as follows: + +```mermaid +sequenceDiagram +participant User as "User" +participant Py as "AntdDropdown (Python)" +participant Wrap as "Dropdown Wrapper (React)" +participant MenuCtx as "Menu Context Provider" +participant Antd as "Antd Dropdown" +participant Popup as "Popup Layer" +User->>Py : Render dropdown +Py->>Wrap : Pass properties and slots +Wrap->>MenuCtx : Read menu items +Wrap->>Antd : Render Antd Dropdown +Antd->>Popup : Display based on trigger condition +User->>Popup : Click/hover/keyboard interaction +Popup-->>Antd : Trigger callback +Antd-->>Wrap : Pass event back +Wrap-->>Py : Trigger open_change / menu_* events +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:16-32](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L16-L32) +- [frontend/antd/dropdown/dropdown.tsx:26-107](file://frontend/antd/dropdown/dropdown.tsx#L26-L107) + +## Detailed Component Analysis + +### Component 1: Dropdown + +- Role: Combines Ant Design's Dropdown with the internal menu context, supporting slot-based menu item injection and custom rendering +- Key points + - Menu item source: Uses `props.menu.items` first; otherwise renders "menu.items" from menu context + - Expand icon and overflow indicator: Can inject ReactSlot via slots or fall back to native properties + - Popup container: Supports `getPopupContainer` for custom containers + - Custom rendering: `dropdownRender` and `popupRender` can be injected via slots or passed as functions + - Inline styles: `innerStyle` is passed through to the content container + +```mermaid +flowchart TD +Start(["Enter Dropdown Wrapper"]) --> ReadCtx["Read items from menu context"] +ReadCtx --> MergeItems{"Are props.menu.items provided?"} +MergeItems --> |Yes| UseProps["Use props.menu.items"] +MergeItems --> |No| RenderItems["Render menu context items"] +UseProps --> Slots["Handle slots: expandIcon / overflowedIndicator / dropdownRender / popupRender"] +RenderItems --> Slots +Slots --> Container["getPopupContainer positioning"] +Container --> Mount["Mount to Antd Dropdown and render"] +Mount --> End(["Complete"]) +``` + +Diagram Sources + +- [frontend/antd/dropdown/dropdown.tsx:26-107](file://frontend/antd/dropdown/dropdown.tsx#L26-L107) + +Section Sources + +- [frontend/antd/dropdown/dropdown.tsx:15-108](file://frontend/antd/dropdown/dropdown.tsx#L15-L108) + +### Component 2: Dropdown.Button + +- Role: Wraps Antd Dropdown.Button in a Svelte manner, supporting slots and event mapping +- Key points + - Dynamically imports the React version of Dropdown.Button via `importComponent` + - Property mapping: `open_change` → `openChange`, `menu_open_change` → `menu_OpenChange` + - Visibility control: Controls rendering via `visible` + - Styles and IDs: Supports `elem_style`, `elem_id`, `elem_classes` pass-through + +```mermaid +sequenceDiagram +participant User as "User" +participant BtnPy as "AntdDropdown.Button (Python)" +participant BtnSvlt as "Dropdown.Button (Svelte)" +participant BtnReact as "Dropdown.Button (React)" +participant Antd as "Antd Dropdown.Button" +User->>BtnPy : Render Dropdown.Button +BtnPy->>BtnSvlt : Pass properties and slots +BtnSvlt->>BtnReact : Dynamic import and render +BtnReact->>Antd : Render Antd Dropdown.Button +User->>Antd : Click/interact +Antd-->>BtnReact : Callback event +BtnReact-->>BtnSvlt : Event pass-through +BtnSvlt-->>BtnPy : Event pass-through +``` + +Diagram Sources + +- [frontend/antd/dropdown/button/Index.svelte:10-70](file://frontend/antd/dropdown/button/Index.svelte#L10-L70) +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:8-8](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L8-L8) + +Section Sources + +- [frontend/antd/dropdown/button/Index.svelte:10-70](file://frontend/antd/dropdown/button/Index.svelte#L10-L70) +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:15-15](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L15-L15) + +### Event Handling and Keyboard Navigation + +- Event bindings + - `open_change`: Dropdown panel visibility state change + - `menu_click` / `menu_select` / `menu_deselect` / `menu_open_change`: Menu item click, selection, deselection, menu panel visibility change +- Keyboard navigation + - Uses Antd Dropdown's default keyboard behavior (up/down to move, Enter/Space to select, Esc to close) +- Accessibility support + - Preserves native semantic tags and accessibility attributes (provided by Antd Dropdown) + - Recommendation: Set `aria-controls`, `aria-expanded`, and other attributes on trigger elements to enhance accessibility + +Section Sources + +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:16-32](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L16-L32) + +### Popup Positioning and Container + +- Positioning strategy + - `placement`: Supports `topLeft`/`top`/`topRight`/`bottomLeft`/`bottom`/`bottomRight` + - `auto_adjust_overflow`: Automatically adjusts overflow +- Container selection + - `get_popup_container`: Custom popup container, commonly used for fixing to specific areas or inside scroll containers + +Section Sources + +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:56-59](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L56-L59) +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:52-52](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L52-L52) + +### Integration with Forms, Icon Buttons, and Text Links + +- Form components + - When embedding input-type components in menu items, be aware of form linkage and validation timing +- Icon buttons + - Combine `antd.Icon` with `antd.Button` (type="text" or "primary"/"default") +- Text links + - Use `antd.Button` (type="link") as menu item labels, supporting `href` and new window opening + +Section Sources + +- [docs/components/antd/dropdown/demos/basic.py:6-31](file://docs/components/antd/dropdown/demos/basic.py#L6-L31) +- [docs/components/antd/dropdown/demos/basic.py:37-47](file://docs/components/antd/dropdown/demos/basic.py#L37-L47) + +### Advanced Usage + +- Multi-level menus + - Nest sub-menu items within menu items to achieve two-level or multi-level dropdown menus +- Dynamic menus + - Inject "menu.items" via slots and update dynamically based on state at runtime +- Remote loading + - Add loading and error states in `dropdownRender`/`popupRender`, update menu items after async requests + +Section Sources + +- [frontend/antd/dropdown/dropdown.tsx:20-24](file://frontend/antd/dropdown/dropdown.tsx#L20-L24) +- [frontend/antd/dropdown/dropdown.tsx:71-92](file://frontend/antd/dropdown/dropdown.tsx#L71-L92) + +## Dependency Analysis + +- Python layer + - `AntdDropdown` exports the Button sub-component and declares supported slots and events + - Component is registered in `components.py` for unified export +- Frontend layer + - Dropdown wrapper depends on Antd Dropdown, Menu Context Provider, and slot rendering utilities + - Dropdown.Button wraps the React component via Svelte + +```mermaid +graph LR +PY["AntdDropdown (Python)"] --> WRAP["Dropdown (React)"] +WRAP --> ANTD["Antd Dropdown"] +WRAP --> CTX["Menu Context Provider"] +BTN_PY["AntdDropdown.Button (Python)"] --> BTN_SVLT["Dropdown.Button (Svelte)"] +BTN_SVLT --> BTN_REACT["Dropdown.Button (React)"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:39-40](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L39-L40) +- [backend/modelscope_studio/components/antd/components.py:39-40](file://backend/modelscope_studio/components/antd/components.py#L39-L40) +- [frontend/antd/dropdown/dropdown.tsx:10-13](file://frontend/antd/dropdown/dropdown.tsx#L10-L13) +- [frontend/antd/dropdown/button/Index.svelte:10-12](file://frontend/antd/dropdown/button/Index.svelte#L10-L12) + +Section Sources + +- [backend/modelscope_studio/components/antd/components.py:39-40](file://backend/modelscope_studio/components/antd/components.py#L39-L40) +- [frontend/antd/dropdown/dropdown.tsx:10-13](file://frontend/antd/dropdown/dropdown.tsx#L10-L13) + +## Performance Considerations + +- Menu item rendering + - Use `useMemo` to cache the menu item list, avoiding unnecessary re-renders +- Slot rendering + - Render slots only when needed, reducing unused nodes +- Popup container + - Set `getPopupContainer` reasonably to avoid frequent popup layer reflows +- Event binding + - Bind `open_change` and `menu_*` events only when necessary, avoiding excessive listeners + +Section Sources + +- [frontend/antd/dropdown/dropdown.tsx:49-57](file://frontend/antd/dropdown/dropdown.tsx#L49-L57) +- [frontend/antd/dropdown/dropdown.tsx:37-39](file://frontend/antd/dropdown/dropdown.tsx#L37-L39) + +## Troubleshooting Guide + +- Unable to display menu items + - Check whether "menu.items" is injected via slots, or whether `props.menu.items` is correctly passed +- Popup layer position abnormal + - Check whether `getPopupContainer` returns the correct container element + - Adjust `placement` and `auto_adjust_overflow` +- Events not triggering + - Confirm the corresponding events (`open_change`, `menu_*`) are enabled and correctly bound in the Python layer +- Styles not taking effect + - `innerStyle` only applies to the content container; `overlayStyle` should be passed via backend properties + +Section Sources + +- [frontend/antd/dropdown/dropdown.tsx:44-92](file://frontend/antd/dropdown/dropdown.tsx#L44-L92) +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:52-59](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L52-L59) +- [backend/modelscope_studio/components/antd/dropdown/**init**.py:16-32](file://backend/modelscope_studio/components/antd/dropdown/__init__.py#L16-L32) + +## Conclusion + +The Dropdown component implements flexible menu item injection, popup layer customization, and event binding through a "Python component + frontend wrapper + menu context" design. Combined with Antd Dropdown's mature capabilities, it can handle scenarios ranging from basic dropdowns to complex multi-level menus, dynamic and remote loading. In real projects, it is recommended to focus on performance and accessibility, using slots and events reasonably to ensure a good user experience. + +## Appendix + +- Example references + - Basic examples: Contains normal dropdown and dropdown button, as well as embedded buttons and links in menu items +- Documentation entry + - Component documentation home and example entry + +Section Sources + +- [docs/components/antd/dropdown/README.md:1-8](file://docs/components/antd/dropdown/README.md#L1-L8) +- [docs/components/antd/dropdown/demos/basic.py:33-47](file://docs/components/antd/dropdown/demos/basic.py#L33-L47) diff --git a/.wiki/en/Ant Design Components/Navigation Components/Menu.md b/.wiki/en/Ant Design Components/Navigation Components/Menu.md new file mode 100644 index 00000000..ab49acb3 --- /dev/null +++ b/.wiki/en/Ant Design Components/Navigation Components/Menu.md @@ -0,0 +1,344 @@ +# Menu + + +**Files Referenced in This Document** +- [menu.tsx](file://frontend/antd/menu/menu.tsx) +- [menu.item.tsx](file://frontend/antd/menu/item/menu.item.tsx) +- [Index.svelte](file://frontend/antd/menu/item/Index.svelte) +- [context.ts](file://frontend/antd/menu/context.ts) +- [menu.less](file://frontend/antd/menu/menu.less) +- [createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [README.md](file://docs/components/antd/menu/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically introduces the design and implementation of the navigation Menu component, covering layout modes, menu item configuration, state management, interaction behaviors, icons and disabled states, sub-menu nesting, horizontal/vertical layout switching, collapse/expand mechanisms, responsive adaptation, integration with routing systems (dynamic menus, permission control, breadcrumb linkage), accordion and multi-select modes, searchable menus, and other advanced capabilities, along with usage examples, style customization, and performance optimization recommendations. + +## Project Structure + +The Menu component consists of three parts: "container component + menu item component + context and rendering utilities". It uses Ant Design's Menu component as the underlying implementation, bridged to React via Svelte preprocessing, combined with an in-house "item context" system for flexible menu item collection and rendering. + +```mermaid +graph TB +subgraph "frontend/antd/menu" +M["menu.tsx
Menu Container"] +MI["menu.item.tsx
Menu Item Wrapper"] +IDX["Index.svelte
Menu Item Entry"] +CTX["context.ts
Item Context Export"] +LESS["menu.less
Styles and Transitions"] +end +subgraph "Utility Layer" +CIC["createItemsContext.tsx
Item Context Factory"] +RIT["renderItems.tsx
Item Renderer"] +end +subgraph "External Dependencies" +AD["Ant Design Menu
Underlying UI"] +end +IDX --> MI +MI --> CTX +CTX --> CIC +M --> RIT +M --> AD +M --> LESS +``` + +Diagram Sources + +- [menu.tsx:14-93](file://frontend/antd/menu/menu.tsx#L14-L93) +- [menu.item.tsx:9-33](file://frontend/antd/menu/item/menu.item.tsx#L9-L33) +- [Index.svelte:13-83](file://frontend/antd/menu/item/Index.svelte#L13-L83) +- [context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [createItemsContext.tsx:97-273](file://frontend/utils/createItemsContext.tsx#L97-L273) +- [renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +Section Sources + +- [menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [menu.item.tsx:1-36](file://frontend/antd/menu/item/menu.item.tsx#L1-L36) +- [Index.svelte:1-84](file://frontend/antd/menu/item/Index.svelte#L1-L84) +- [context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) +- [createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) + +## Core Components + +- Menu Container (Menu) + - Purpose: Wraps Ant Design Menu, unifying event pass-through, slot rendering, custom rendering of icons and overflow indicators, and item context injection. + - Key points: Supports slot extensions (e.g., `expandIcon`, `overflowedIndicator`, `popupRender`); supports `items` or slots as data sources; internally uses `renderItems` to convert the "item context" into the `ItemType` array required by Antd. +- Menu Item (MenuItem) + - Purpose: Wraps menu items from the "item context" as Antd MenuItem/SubMenu, auto-detects type (regular item/sub-menu), and injects style class names. +- Item Context (createItemsContext) + - Purpose: Provides "item collection + child item collection" context, supporting multiple slots, index positioning, property and child item transformation, change callbacks, etc. +- Renderer (renderItems) + - Purpose: Renders the "item context" tree structure into the props structure required by Antd, supporting slot injection, cloning, parameterized slots, etc. + +Section Sources + +- [menu.tsx:14-93](file://frontend/antd/menu/menu.tsx#L14-L93) +- [menu.item.tsx:9-33](file://frontend/antd/menu/item/menu.item.tsx#L9-L33) +- [createItemsContext.tsx:97-273](file://frontend/utils/createItemsContext.tsx#L97-L273) +- [renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +## Architecture Overview + +The Menu component uses a layered design of "container + item wrapper + context", bridged to React via Svelte preprocessing, then React calls Antd Menu. The item context is responsible for collecting menu items and their slots at runtime, and the renderer ultimately outputs a data structure recognizable by Antd. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Menu as "Menu Container" +participant Ctx as "Item Context" +participant Render as "renderItems" +participant Antd as "Antd Menu" +Dev->>Menu : Pass items or slots +Menu->>Ctx : withItemsContextProvider injection +Ctx-->>Menu : useItems provides items +Menu->>Render : renderItems(resolvedSlotItems, { clone }) +Render-->>Menu : Return Antd Item list +Menu->>Antd : Render and bind events +Antd-->>Dev : Trigger openChange/onSelect/onDeselect +``` + +Diagram Sources + +- [menu.tsx:18-54](file://frontend/antd/menu/menu.tsx#L18-L54) +- [createItemsContext.tsx:171-184](file://frontend/utils/createItemsContext.tsx#L171-L184) +- [renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +## Detailed Component Analysis + +### Menu Container (Menu) + +- Data source selection + - Supports directly passing `items` (Antd Item type array) or collecting via slots (default/items slots). + - If slots exist, items from slots are preferred; otherwise falls back to the default slot. +- Slot extensions + - `expandIcon`: Custom expand icon, supports parameterized rendering. + - `overflowedIndicator`: Overflow indicator (e.g., "More" button). + - `popupRender`: Custom rendering for dropdown popup layers. +- Event pass-through + - `onOpenChange`, `onSelect`, `onDeselect` are passed through as-is to Antd Menu. +- Performance optimization + - Uses `useMemo` to cache items computation results, avoiding duplicate rendering. + - Only recomputes when `items` or `resolvedSlotItems` changes. + +Section Sources + +- [menu.tsx:14-93](file://frontend/antd/menu/menu.tsx#L14-L93) + +### Menu Item (MenuItem) + +- Type detection + - When default slot children exist, auto-detects as sub-menu (SubMenu); otherwise as a regular menu item (MenuItem). +- Style class names + - Automatically injects `ms-gr-antd-menu-item` or `ms-gr-antd-menu-item-{type}` for theme and style customization. +- Slot handling + - Injects the `icon` slot into Antd's `icon` field via cloning, ensuring consistent spacing between icon and text. + +Section Sources + +- [menu.item.tsx:9-33](file://frontend/antd/menu/item/menu.item.tsx#L9-L33) + +### Item Context (createItemsContext) + +- Multi-slot support + - Allows defining multiple slots (e.g., `default`, `items`) and writing by index via `setItem`. +- Child item collection + - `ItemHandler` internally wraps `ItemsContextProvider` again, forming a "parent collection + child collection" tree structure. +- Property and child item transformation + - `itemProps` and `itemChildren` support transforming props and children of the current item for dynamic generation. +- Change notification + - The `onChange` callback returns the complete items under the current slot, making it easy for upper layers to listen for changes. + +Section Sources + +- [createItemsContext.tsx:97-273](file://frontend/utils/createItemsContext.tsx#L97-L273) + +### Renderer (renderItems) + +- Slot injection + - Injects slot elements recorded in the item context into corresponding fields (supports nested paths), with support for `withParams` parameterized slots. +- Cloning and force cloning + - `clone` controls whether to clone nodes; `forceClone` is enabled by default with `withParams` to ensure correct parameter passing. +- Child item recursion + - Recursively renders the `children` field to form a complete menu tree. +- Key generation + - Generates stable keys for each item to avoid React diff anomalies. + +Section Sources + +- [renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +### Styles and Responsive (menu.less) + +- Icon and text spacing + - When an icon is present, automatically sets `margin-inline-start` for adjacent text and adds transition animations. +- Collapsed mode + - In the `inline-collapsed` state, text is hidden and only icons are shown to improve space utilization. +- Animations and transitions + - Controls transition duration and easing via CSS variables, ensuring visual consistency. + +Section Sources + +- [menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) + +### Svelte Entry (Index.svelte) + +- Property and slot handling + - Retrieves component properties and additional properties via `getProps`/`processProps`, supports `visible` for visibility control. + - Injects the `icon` slot into Antd's `icon` field via cloning. +- Theme and styles + - Supports `elem_id`, `elem_classes`, `elem_style` injection for theme and style customization. +- Conditional rendering + - Renders `children` only when `visible` is true. + +Section Sources + +- [Index.svelte:1-84](file://frontend/antd/menu/item/Index.svelte#L1-L84) + +## Dependency Analysis + +- Component coupling + - Menu depends on `createItemsContext` and `renderItems`; MenuItem depends on `ItemHandler` and context; Svelte entry handles property and slot preprocessing. +- External dependencies + - Ant Design Menu as the underlying UI; `ReactSlot` for slot rendering; `classnames` for class name concatenation. +- Circular dependencies + - Avoided through "exported factory + context injection"; Menu and MenuItem are decoupled via context. + +```mermaid +graph LR +Menu["menu.tsx"] --> Ctx["context.ts"] +Ctx --> CIC["createItemsContext.tsx"] +Menu --> RIT["renderItems.tsx"] +Menu --> AD["Antd Menu"] +MenuItem["menu.item.tsx"] --> Ctx +IDX["Index.svelte"] --> MenuItem +Menu --> LESS["menu.less"] +``` + +Diagram Sources + +- [menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [menu.item.tsx:1-36](file://frontend/antd/menu/item/menu.item.tsx#L1-L36) +- [Index.svelte:1-84](file://frontend/antd/menu/item/Index.svelte#L1-L84) +- [menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) + +Section Sources + +- [menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [menu.item.tsx:1-36](file://frontend/antd/menu/item/menu.item.tsx#L1-L36) +- [Index.svelte:1-84](file://frontend/antd/menu/item/Index.svelte#L1-L84) +- [context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) + +## Performance Considerations + +- Render caching + - Menu uses `useMemo` for items computation, avoiding unnecessary re-renders. +- Event function memoization + - `createItemsContext` internally uses `useMemoizedFn`, reducing side effects caused by callback function rebuilds. +- Slot cloning strategy + - Default slot element cloning avoids state confusion caused by DOM reuse; forced cloning in `withParams` scenarios. +- Recursive rendering optimization + - `renderItems` only filters and maps valid items, avoiding empty items participating in rendering. + +Section Sources + +- [menu.tsx:46-54](file://frontend/antd/menu/menu.tsx#L46-L54) +- [createItemsContext.tsx:203-254](file://frontend/utils/createItemsContext.tsx#L203-L254) +- [renderItems.tsx:19-22](file://frontend/utils/renderItems.tsx#L19-L22) + +## Troubleshooting Guide + +- Slots not taking effect + - Check whether slot names are declared in `allowedSlots`; confirm slot elements are correctly injected into `ItemHandler`'s slots. +- Icons not showing or text not appearing + - Confirm the icon slot has been injected into the `icon` field via the Svelte entry; check behavior when the menu is in collapsed mode. +- Events not triggering + - Confirm Menu correctly passes through `onOpenChange`/`onSelect`/`onDeselect`; check Antd version compatibility. +- Sub-menus not expanding + - Check whether sub-item `children` are correctly recursed via `renderItems`; confirm the `itemChildren` callback returns the correct child item list. +- Style anomalies + - Check whether `menu.less` is imported; confirm theme variables (e.g., `--ms-gr-ant-menu-icon-margin-inline-end`) are set correctly. + +Section Sources + +- [menu.tsx:35-88](file://frontend/antd/menu/menu.tsx#L35-L88) +- [menu.item.tsx:16-30](file://frontend/antd/menu/item/menu.item.tsx#L16-L30) +- [Index.svelte:69-78](file://frontend/antd/menu/item/Index.svelte#L69-L78) +- [menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) + +## Conclusion + +This Menu component enhances and extends Ant Design Menu through a "container + item wrapper + context" architecture, featuring a flexible slot system, powerful sub-menu and icon support, and good performance and maintainability. Combined with routing systems and permission control, complex navigation scenarios can be quickly built. + +## Appendix + +### Usage Examples (Path Guide) + +- Basic examples + - Refer to documentation example tabs: `` + - Example file location: `docs/components/antd/menu/README.md` +- Dynamic menus and permission control + - Dynamically pass menu items via the `items` property; filter items based on user permissions in `onChange`. +- Breadcrumb linkage + - Update the breadcrumb data source in `onSelect`; generate titles and paths combined with route parameters. +- Accordion and multi-select + - Control expand state and selected items using `onOpenChange`/`onSelect`; Antd Menu natively supports accordion and multi-select modes. +- Searchable menus + - Implement a search input externally, filter `items` and pass them to Menu; or inject a search component in a slot. + +Section Sources + +- [README.md:1-8](file://docs/components/antd/menu/README.md#L1-L8) + +### Style Customization Guide + +- Custom icon and text spacing + - Modify the `--ms-gr-ant-menu-icon-margin-inline-end` variable to adjust icon-text spacing. +- Collapsed mode text hiding + - Control text visibility and transitions in collapsed mode via rules in `menu.less`. +- Theme class names + - Use `ms-gr-antd-menu-item-*` class names for themed style overrides. + +Section Sources + +- [menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) + +### Advanced Feature Implementation Key Points + +- Sub-menu nesting + - Return the sub-item array via the `itemChildren` callback in `ItemHandler`; `renderItems` will recursively render them. +- Icon setup + - Inject the `icon` slot into Antd's `icon` field in the Svelte entry. +- Disabled state + - Control disabled via Antd MenuItem's `disabled` property; set dynamically in the item context. +- Responsive adaptation + - Antd Menu itself supports responsiveness; combine CSS variables and layout containers for the best experience. + +Section Sources + +- [menu.item.tsx:16-30](file://frontend/antd/menu/item/menu.item.tsx#L16-L30) +- [Index.svelte:69-78](file://frontend/antd/menu/item/Index.svelte#L69-L78) +- [renderItems.tsx:99-112](file://frontend/utils/renderItems.tsx#L99-L112) diff --git a/.wiki/en/Ant Design Components/Navigation Components/Navigation Components.md b/.wiki/en/Ant Design Components/Navigation Components/Navigation Components.md new file mode 100644 index 00000000..8bfa696d --- /dev/null +++ b/.wiki/en/Ant Design Components/Navigation Components/Navigation Components.md @@ -0,0 +1,542 @@ +# Navigation Components + + +**Files Referenced in This Document** +- [frontend/antd/anchor/anchor.tsx](file://frontend/antd/anchor/anchor.tsx) +- [frontend/antd/anchor/context.ts](file://frontend/antd/anchor/context.ts) +- [frontend/antd/breadcrumb/breadcrumb.tsx](file://frontend/antd/breadcrumb/breadcrumb.tsx) +- [frontend/antd/breadcrumb/context.ts](file://frontend/antd/breadcrumb/context.ts) +- [frontend/antd/dropdown/dropdown.tsx](file://frontend/antd/dropdown/dropdown.tsx) +- [frontend/antd/menu/menu.tsx](file://frontend/antd/menu/menu.tsx) +- [frontend/antd/menu/context.ts](file://frontend/antd/menu/context.ts) +- [frontend/antd/pagination/pagination.tsx](file://frontend/antd/pagination/pagination.tsx) +- [frontend/antd/steps/steps.tsx](file://frontend/antd/steps/steps.tsx) +- [frontend/antd/steps/context.ts](file://frontend/antd/steps/context.ts) +- [frontend/antd/layout/layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) +- [frontend/antd/layout/Index.svelte](file://frontend/antd/layout/Index.svelte) +- [frontend/antd/layout/package.json](file://frontend/antd/layout/package.json) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically organizes and explains the implementation and usage of Ant Design navigation-related components in this repository, covering the following components: Anchor, Breadcrumb, Dropdown, Menu, Pagination, and Steps. The document focuses on: + +- Component state management and event handling mechanisms +- Integration approaches and best practices with routing systems +- Implementation of permission control in navigation +- Navigation pattern design guide: top navigation, sidebar navigation, hybrid navigation +- Implementation methods for multi-level navigation and performance optimization suggestions +- Interaction design and user experience optimization key points + +## Project Structure + +Navigation-related components are primarily located in the `antd` sub-module of the frontend directory, organized using a common pattern of "on-demand rendering + context injection", working with utility functions for slot rendering and property adaptation. + +```mermaid +graph TB +subgraph "Navigation Components" +A["Anchor
Anchor Links"] +B["Breadcrumb
Breadcrumb Trail"] +C["Dropdown
Dropdown Menu"] +D["Menu
Navigation Menu"] +E["Pagination
Pagination"] +F["Steps
Steps Bar"] +end +subgraph "Utility Tools" +U1["createItemsContext.tsx
Context Factory"] +U2["renderItems.tsx
Slot Item Renderer"] +U3["renderParamsSlot.tsx
Parameterized Slot"] +U4["useFunction.ts
Function Wrapper"] +U5["omitUndefinedProps.ts
Property Filter"] +end +subgraph "Layout" +L1["layout.base.tsx
Base Layout Container"] +L2["layout/Index.svelte
Layout Entry"] +L3["layout/package.json
Export Configuration"] +end +A --> U1 +B --> U1 +D --> U1 +F --> U1 +C --> D +A --> U2 +B --> U2 +D --> U2 +F --> U2 +A --> U3 +B --> U3 +D --> U3 +F --> U3 +C --> U4 +D --> U5 +L1 --> L2 +L3 --> L2 +``` + +Diagram Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/package.json:1-15](file://frontend/antd/layout/package.json#L1-L15) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +Section Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/package.json:1-15](file://frontend/antd/layout/package.json#L1-L15) + +## Core Components + +This section provides an overall capability and behavioral description of each navigation component for quick orientation. + +- Anchor + - Responsible for in-page positioning and highlighting, supporting container selectors and current anchor callbacks + - Injects items via context, supporting slot-based child item rendering +- Breadcrumb + - Displays the current page path, supporting custom separators, item renderers, and dropdown icons + - Supports replacing default rendering logic via slots +- Dropdown + - Based on Ant Design Dropdown, supports nested menu items, popup layer rendering, and overflow indicators + - Shares items rendering strategy with the menu context +- Menu + - Supports expand icons, overflow indicators, and popup rendering + - Provides open/select/deselect event pass-through +- Pagination + - Supports total count rendering, quick jumper, and custom page number rendering + - Event callbacks are uniformly handled by function wrappers +- Steps + - Supports custom progress dot rendering + - Injects items via context, supporting slot-based child items + +Section Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) + +## Architecture Overview + +Navigation components universally adopt a unified architecture of "Svelte wrapper + React component + slot rendering + context injection". Key characteristics are: + +- Use `sveltify` to bridge React components as Svelte components +- Inject items context via `withItemsContextProvider` to uniformly handle combinations of children and slots +- Use `renderItems` and `renderParamsSlot` to render slot items and parameterized slots +- Use `useFunction` to wrap callbacks, ensuring stable execution in the Svelte environment +- Use `omitUndefinedProps` to filter undefined properties, avoiding passing invalid values to underlying components + +```mermaid +sequenceDiagram +participant S as "Svelte Component" +participant P as "withItemsContextProvider" +participant R as "renderItems/renderParamsSlot" +participant A as "Antd Component" +participant U as "useFunction/omitUndefinedProps" +S->>P : Pass props and slots +P->>R : Resolve items and slots +R-->>P : Return normalized items/rendered nodes +P->>U : Wrap callbacks / filter properties +U-->>P : Return safe props +P->>A : Render Antd component +A-->>S : Trigger event callbacks +``` + +Diagram Sources + +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +## Detailed Component Analysis + +### Anchor Analysis + +- Data flow and state + - Injects items via context, supporting combinations of children and slots + - Uses `useMemo` to cache items computation results, avoiding redundant renders +- Events and callbacks + - `getContainer` and `getCurrentAnchor` are wrapped with `useFunction` for stable invocation in Svelte +- Slots and rendering + - Uses explicit items first; otherwise resolves from `default` or `items` slot in context +- Performance and usability + - Recomputes items only when necessary, reducing rendering overhead + - Hides the children container to avoid duplicate rendering + +```mermaid +flowchart TD +Start(["Enter Anchor Render"]) --> Resolve["Resolve context items"] +Resolve --> HasExplicit{"Are explicit items provided?"} +HasExplicit --> |Yes| UseExplicit["Use explicit items"] +HasExplicit --> |No| UseSlot["Use items/default slot"] +UseSlot --> Memo["useMemo caches items"] +UseExplicit --> Memo +Memo --> Render["Render Antd Anchor"] +Render --> End(["Complete"]) +``` + +Diagram Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) + +Section Sources + +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/anchor/context.ts:1-7](file://frontend/antd/anchor/context.ts#L1-L7) + +### Breadcrumb Analysis + +- Data flow and state + - Merges items and slots, supporting custom separators and item renderers + - `dropdownIcon` and `separator` can be replaced via slots +- Slots and rendering + - `itemRender`, `dropdown_icon`, and `separator` are rendered via `renderParamsSlot` and ReactSlot +- Callbacks and events + - Maintains interface compatibility with Antd Breadcrumb, with no additional wrapping + +```mermaid +sequenceDiagram +participant S as "Svelte Breadcrumb" +participant Ctx as "Context Resolution" +participant Slot as "Slot Rendering" +participant A as "Antd Breadcrumb" +S->>Ctx : Get items/default +Ctx-->>S : Return items +S->>Slot : Render separator/itemRender/dropdownIcon +Slot-->>S : Return nodes +S->>A : Pass items and rendered slots +A-->>S : Trigger click/navigation +``` + +Diagram Sources + +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) + +Section Sources + +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/breadcrumb/context.ts:1-7](file://frontend/antd/breadcrumb/context.ts#L1-L7) + +### Dropdown Analysis + +- Data flow and state + - Internal menu items are injected via menu context, supporting `expandIcon` and overflow indicator slots + - `dropdownRender` and `popupRender` support parameterized slots +- Events and callbacks + - `getPopupContainer` is wrapped with `useFunction` +- Relationship with Menu + - Shares menu context and reuses the items rendering strategy + +```mermaid +classDiagram +class Dropdown { ++props ++slots ++menu.items ++dropdownRender() ++popupRender() ++getPopupContainer() +} +class MenuContext { ++items ++expandIcon ++overflowedIndicator +} +Dropdown --> MenuContext : "Shared context" +``` + +Diagram Sources + +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) + +Section Sources + +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) + +### Menu Analysis + +- Data flow and state + - Injects items via context, supporting `expandIcon`, overflow indicator, and popup render slot + - open/select/deselect events are passed through +- Property handling + - Uses `omitUndefinedProps` to filter undefined properties, avoiding passing invalid values to underlying components +- Slots and rendering + - `expandIcon`, `overflowedIndicator`, `popup_render` are rendered via `renderParamsSlot` and ReactSlot + +```mermaid +flowchart TD +Enter(["Enter Menu Render"]) --> Ctx["Resolve context items/default"] +Ctx --> Items["renderItems normalization"] +Items --> Props["omitUndefinedProps filter properties"] +Props --> Slots["Slots: expandIcon/overflowedIndicator/popup_render"] +Slots --> Antd["Render Antd Menu"] +Antd --> Events["Pass through open/select/deselect"] +Events --> Exit(["Complete"]) +``` + +Diagram Sources + +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +Section Sources + +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/menu/context.ts:1-7](file://frontend/antd/menu/context.ts#L1-L7) + +### Pagination Analysis + +- Data flow and state + - Supports slot-based configuration for `showTotal`, `itemRender`, and `showQuickJumper.goButton` + - `onChange` callback is wrapped with `useFunction` +- Slots and rendering + - `itemRender` and `goButton` are rendered via `renderParamsSlot` and ReactSlot + +```mermaid +sequenceDiagram +participant S as "Svelte Pagination" +participant Slot as "Slot Rendering" +participant A as "Antd Pagination" +S->>Slot : Render itemRender/goButton +Slot-->>S : Return nodes +S->>A : Pass configuration and wrapped callbacks +A-->>S : onChange(page, pageSize) +``` + +Diagram Sources + +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) + +Section Sources + +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) + +### Steps Analysis + +- Data flow and state + - Injects items via context, supporting `progressDot` slotting + - Wraps `progressDot` callback via `useFunction` +- Slots and rendering + - `progressDot` is rendered via `renderParamsSlot` + +```mermaid +flowchart TD +Start(["Enter Steps Render"]) --> Ctx["Resolve items/default"] +Ctx --> Normalize["renderItems normalization"] +Normalize --> Slot["Render progressDot"] +Slot --> Antd["Render Antd Steps"] +Antd --> End(["Complete"]) +``` + +Diagram Sources + +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/steps/context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) + +Section Sources + +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/steps/context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) + +### Layout and Navigation Patterns + +- Base layout container + - The Base component dynamically selects Layout, Header, Footer, or Content based on the `component` parameter + - Class names differentiate style scopes +- Layout entry and exports + - `Index.svelte` serves as the entry point; `layout/package.json` provides Gradio export configuration + +```mermaid +graph LR +Base["layout.base.tsx
Base Component"] --> |component| L["Layout"] +Base --> H["Header"] +Base --> F["Footer"] +Base --> C["Content"] +Index["layout/Index.svelte"] --> Base +Package["layout/package.json"] --> Index +``` + +Diagram Sources + +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/package.json:1-15](file://frontend/antd/layout/package.json#L1-L15) + +Section Sources + +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/antd/layout/Index.svelte:1-18](file://frontend/antd/layout/Index.svelte#L1-L18) +- [frontend/antd/layout/package.json:1-15](file://frontend/antd/layout/package.json#L1-L15) + +## Dependency Analysis + +- Inter-component coupling + - Dropdown and Menu share menu context, forming a weakly-coupled reuse relationship + - Anchor, Breadcrumb, Steps, and Menu all depend on the `createItemsContext` factory and `renderItems` +- External dependencies + - Ant Design React component library + - Svelte Preprocess React (`sveltify`, `ReactSlot`) + - Utility functions (`useFunction`, `renderItems`, `renderParamsSlot`, `omitUndefinedProps`) + +```mermaid +graph TB +subgraph "Components" +M["Menu"] +D["Dropdown"] +A["Anchor"] +B["Breadcrumb"] +S["Steps"] +P["Pagination"] +end +subgraph "Utilities" +Ctx["createItemsContext"] +RI["renderItems"] +RS["renderParamsSlot"] +UF["useFunction"] +OU["omitUndefinedProps"] +end +M --> Ctx +D --> Ctx +A --> Ctx +B --> Ctx +S --> Ctx +M --> RI +D --> RI +A --> RI +B --> RI +S --> RI +M --> RS +D --> RS +A --> RS +B --> RS +S --> RS +M --> OU +D --> UF +A --> UF +B --> UF +S --> UF +P --> UF +``` + +Diagram Sources + +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/omitUndefinedProps.ts](file://frontend/utils/omitUndefinedProps.ts) + +Section Sources + +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) + +## Performance Considerations + +- Rendering optimization + - Many components use `useMemo` to cache items computation results, avoiding unnecessary re-renders + - Using `renderItems` and `renderParamsSlot` for unified slot rendering reduces branching logic +- Callbacks and properties + - Using `useFunction` to wrap callbacks ensures stable execution within the Svelte lifecycle + - Using `omitUndefinedProps` to filter undefined properties reduces the processing burden on underlying components +- Complexity and extensibility + - The `createItemsContext` factory provides a consistent items injection strategy for multiple components, improving extensibility + - Slot-based design gives components stronger customizability while keeping default behavior stable + +## Troubleshooting Guide + +- Slots not taking effect + - Check whether slot key names match the component conventions (e.g., `menu.items`, `itemRender`, `progressDot`) + - Confirm slot nodes have been correctly passed to the component (ReactSlot and renderParamsSlot) +- items not displaying + - Confirm context is correctly injected (`withItemsContextProvider`) + - Check whether the combination of children and slots is being correctly resolved +- Callbacks not triggering + - Confirm callbacks are wrapped with `useFunction` + - Check the event pass-through chain (`onOpenChange`/`onSelect`/`onDeselect`, etc.) +- Layout anomalies + - Check the `component` parameter and class name mapping of `layout.base` + - Confirm style scopes have not been overridden by external styles + +Section Sources + +- [frontend/antd/menu/menu.tsx:1-96](file://frontend/antd/menu/menu.tsx#L1-L96) +- [frontend/antd/dropdown/dropdown.tsx:1-111](file://frontend/antd/dropdown/dropdown.tsx#L1-L111) +- [frontend/antd/anchor/anchor.tsx:1-46](file://frontend/antd/anchor/anchor.tsx#L1-L46) +- [frontend/antd/breadcrumb/breadcrumb.tsx:1-67](file://frontend/antd/breadcrumb/breadcrumb.tsx#L1-L67) +- [frontend/antd/steps/steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [frontend/antd/pagination/pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +## Conclusion + +The navigation components in this repository use a unified context and slot rendering strategy as their core, achieving a high-cohesion, low-coupling component system. Through collaboration among tools like `useMemo`, `useFunction`, and `renderItems`, they ensure both performance and powerful customizability. Combined with layout components, they can flexibly construct multiple navigation patterns such as top navigation, sidebar navigation, and hybrid navigation, with good extensibility for routing integration and permission control. + +## Appendix + +- Navigation Pattern Design Guide (conceptual recommendations) + - Top navigation: Suitable for scenarios with clear entry points and shallow hierarchy; pair with Breadcrumb for improved path awareness + - Sidebar navigation: Suitable for content-rich admin systems requiring quick switching; pair with Anchor for fast positioning + - Hybrid navigation: Top main navigation + sidebar secondary navigation, balancing global and local operations +- Routing Integration and Permission Control (conceptual recommendations) + - Routing integration: Inject route metadata into the `items` of Menu/Breadcrumb/Steps to achieve navigation-route linkage + - Permission control: Filter `items` before rendering to show only nodes the user has permission to access +- Multi-level Navigation Implementation and Performance Considerations (conceptual recommendations) + - Use virtual scrolling and lazy loading to reduce large list rendering pressure + - Enable folding and caching for deep-level menus to avoid frequent re-renders + - Preserve necessary navigation state during route transitions to improve user experience diff --git a/.wiki/en/Ant Design Components/Navigation Components/Pagination.md b/.wiki/en/Ant Design Components/Navigation Components/Pagination.md new file mode 100644 index 00000000..662cae68 --- /dev/null +++ b/.wiki/en/Ant Design Components/Navigation Components/Pagination.md @@ -0,0 +1,340 @@ +# Pagination + + +**Files Referenced in This Document** +- [pagination.tsx](file://frontend/antd/pagination/pagination.tsx) +- [Index.svelte](file://frontend/antd/pagination/Index.svelte) +- [__init__.py](file://backend/modelscope_studio/components/antd/pagination/__init__.py) +- [basic.py](file://docs/components/antd/pagination/demos/basic.py) +- [data_changes.py](file://docs/components/antd/pagination/demos/data_changes.py) +- [README.md](file://docs/components/antd/pagination/README.md) +- [app.py](file://docs/components/antd/pagination/app.py) +- [table/__init__.py](file://backend/modelscope_studio/components/antd/table/__init__.py) +- [list/__init__.py](file://backend/modelscope_studio/components/antd/list/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically introduces the implementation and usage of the Pagination component in the ModelScope Studio frontend and backend, covering the following topics: + +- Data pagination mechanism: How to calculate page ranges and boundaries based on total item count and page size +- Page navigation logic: Clicking page numbers, quick jumper, previous/next page, first/last page +- Total count display: Displaying current range and total via the "show total" callback or property +- Configuration details: Page size settings, default page number, page size selector, quick jumper, simple mode, size, disabled state, single-page hiding, etc. +- Integration with data tables and list views: How to link pagination with tables/lists for data loading, state synchronization, and error handling +- Internationalization support, style customization, responsive adaptation +- Advanced usage: large data pagination, virtual scrolling, server-side pagination +- Complete examples and performance optimization recommendations + +## Project Structure + +The Pagination component consists of three parts: + +- Frontend Svelte wrapper layer: Handles property pass-through, slot rendering, and visibility control +- Frontend React encapsulation layer: Connects to Ant Design's Pagination and supports slots and function-based rendering +- Backend Gradio component: Defines events, slots, property mappings, and render entry points + +```mermaid +graph TB +subgraph "Backend" +PY_INIT["Python Initialization
__init__.py"] +end +subgraph "Frontend" +IDX["Svelte Wrapper Layer
Index.svelte"] +REACT["React Encapsulation Layer
pagination.tsx"] +ANTDP["Ant Design Pagination"] +end +PY_INIT --> IDX --> REACT --> ANTDP +``` + +Diagram Sources + +- [Index.svelte:1-68](file://frontend/antd/pagination/Index.svelte#L1-L68) +- [pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [**init**.py:1-107](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L1-L107) + +Section Sources + +- [Index.svelte:1-68](file://frontend/antd/pagination/Index.svelte#L1-L68) +- [pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) +- [**init**.py:1-107](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L1-L107) + +## Core Components + +- Backend component class: Defines events, slots, property mappings, and render directory +- Frontend wrapper layer: Uniformly handles properties, class names, styles, visibility, and slots +- React encapsulation layer: Connects to Ant Design's Pagination, supporting custom rendering and slot injection + +Key points + +- Events: `change`, `showSizeChange` +- Slots: `showQuickJumper.goButton`, `itemRender` +- Property mapping: e.g., `show_size_change` → `showSizeChange` + +Section Sources + +- [**init**.py:14-25](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L14-L25) +- [Index.svelte:22-48](file://frontend/antd/pagination/Index.svelte#L22-L48) +- [pagination.tsx:8-52](file://frontend/antd/pagination/pagination.tsx#L8-L52) + +## Architecture Overview + +The Pagination component call chain is as follows: + +```mermaid +sequenceDiagram +participant User as "User" +participant Backend as "Backend Component Class
AntdPagination" +participant FrontIndex as "Frontend Wrapper Layer
Index.svelte" +participant ReactLayer as "React Encapsulation Layer
pagination.tsx" +participant Antd as "Ant Design Pagination" +User->>Backend : Render request +Backend->>FrontIndex : Pass properties and slots +FrontIndex->>ReactLayer : Pass through properties and slots +ReactLayer->>Antd : Render component and bind events +User->>Antd : Trigger pagination/page size change +Antd-->>ReactLayer : onChange(page, pageSize) +ReactLayer-->>FrontIndex : Callback triggered +FrontIndex-->>Backend : Event callback e.g. change +``` + +Diagram Sources + +- [**init**.py:14-21](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L14-L21) +- [Index.svelte:54-66](file://frontend/antd/pagination/Index.svelte#L54-L66) +- [pagination.tsx:36-38](file://frontend/antd/pagination/pagination.tsx#L36-L38) + +## Detailed Component Analysis + +### Configuration Options and Behavior + +- Basic parameters + - Total items: `total` + - Default page number: `default_current` + - Current page: `current` + - Items per page: `default_page_size` / `page_size` + - Page size options: `page_size_options` + - Disabled: `disabled` + - Hide on single page: `hide_on_single_page` + - Size: `size` (small/default) + - Alignment: `align` (start/center/end) + - Simple mode: `simple` + - Show title: `show_title` + - Show fewer items: `show_less_items` + - Responsive: `responsive` + - Custom rendering: `item_render` + - Show total: `show_total` + - Quick jumper: `show_quick_jumper` (with optional `goButton` slot) + - Show page size selector: `show_size_changer` +- Slots + - `showQuickJumper.goButton`: Quick jump button + - `itemRender`: Custom page number item rendering + +Section Sources + +- [**init**.py:26-88](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L26-L88) +- [Index.svelte:46-47](file://frontend/antd/pagination/Index.svelte#L46-L47) +- [pagination.tsx:12-47](file://frontend/antd/pagination/pagination.tsx#L12-L47) + +### Events and State Synchronization + +- `change`: Triggered when page number or page size changes, returns (page, pageSize) +- `showSizeChange`: Triggered when page size changes +- Gradio state linkage: Write page number and page size to `gr.State` via event callbacks to drive data loading + +Section Sources + +- [**init**.py:14-21](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L14-L21) +- [data_changes.py:6-11](file://docs/components/antd/pagination/demos/data_changes.py#L6-L11) + +### Data Pagination Mechanism and Page Navigation Logic + +- Calculation rules + - Total pages: `Math.ceil(total / pageSize)` + - Current page range: 1 to total pages + - Boundary handling: `current` falls back to a valid value when out of range +- Navigation flow + - Click page number: Triggers `change` + - Previous/next/first/last page: Handled internally by Ant Design and triggers `change` + - Quick jump: When `show_quick_jumper` is enabled and a `goButton` slot is provided, the slot button executes the jump +- Custom rendering + - Use `itemRender` to customize page button content + - Use `show_total` to display range/total on the left side of pagination + +```mermaid +flowchart TD +Start(["Start"]) --> Init["Receive total and pageSize"] +Init --> CalcPages["Calculate total pages"] +CalcPages --> ValidateCurrent["Validate current is in valid range"] +ValidateCurrent --> Render["Render page buttons"] +Render --> Jump["User clicks page/jump button"] +Jump --> ChangeEvent["Trigger change(page, pageSize)"] +ChangeEvent --> UpdateState["Update state e.g. gr.State"] +UpdateState --> LoadData["Load data based on new page number"] +LoadData --> End(["End"]) +``` + +Diagram Sources + +- [pagination.tsx:36-38](file://frontend/antd/pagination/pagination.tsx#L36-L38) +- [data_changes.py:6-11](file://docs/components/antd/pagination/demos/data_changes.py#L6-L11) + +### Integration with Data Tables and List Views + +- Table integration + - Enable `pagination` in the table component and bind the pagination `change` event with the table data loading logic + - Use `show_size_changer` to dynamically switch items per page, linked with table column width and row height +- List integration + - List components support a `pagination` parameter that can directly accept a pagination instance + - List's load-more (`load_more`) and pagination can be used separately or in combination +- State synchronization + - Write pagination state to `gr.State` as input for subsequent data requests + - Table/list `loading` state and pagination `disabled` state can be linked to avoid concurrent requests + +Section Sources + +- [table/**init**.py:114-133](file://backend/modelscope_studio/components/antd/table/__init__.py#L114-L133) +- [list/**init**.py:59-82](file://backend/modelscope_studio/components/antd/list/__init__.py#L59-L82) +- [data_changes.py:24-28](file://docs/components/antd/pagination/demos/data_changes.py#L24-L28) + +### Internationalization, Style Customization, and Responsive Adaptation + +- Internationalization + - Provide locale via `ConfigProvider`; pagination text follows global configuration +- Style customization + - Supports `elem_id`, `elem_classes`, `elem_style`, and `additional_props` + - Theme-level customization via `root_class_name` and `class_names`/`styles` +- Responsive + - When `responsive` is enabled, the component automatically adjusts layout and font size on small-screen devices + +Section Sources + +- [README.md:1-14](file://docs/components/antd/pagination/README.md#L1-L14) +- [Index.svelte:56-58](file://frontend/antd/pagination/Index.svelte#L56-L58) +- [**init**.py:49-50](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L49-L50) + +### Advanced Usage: Large Data Pagination, Virtual Scrolling, Server-side Pagination + +- Large data pagination + - Use a large `total` combined with a smaller `page_size` and reasonable `page_size_options` + - Load data on demand via the `change` event to avoid rendering all data at once +- Virtual scrolling + - Table components support a `virtual` parameter that can significantly improve rendering performance for large datasets +- Server-side pagination + - Pagination only handles UI interaction; actual data is provided by backend APIs, with the frontend making requests in `change` and updating tables/lists + - Combine `loading` state and disabled state to prevent duplicate requests + +Section Sources + +- [table/**init**.py:129-130](file://backend/modelscope_studio/components/antd/table/__init__.py#L129-L130) +- [data_changes.py:6-11](file://docs/components/antd/pagination/demos/data_changes.py#L6-L11) + +### Examples and Best Practices + +- Basic example + - Demonstrates `total`, quick jumper, page size selector, and total count display +- Data change example + - Write page number and page size to `gr.State` via `change` event, and show a notification on button click +- Best practices + - Decouple pagination state from data requests using event-driven approach + - Disable pagination during data loading to avoid concurrency + - Set `page_size_options` reasonably to balance loading speed and user experience + +Section Sources + +- [basic.py:7-11](file://docs/components/antd/pagination/demos/basic.py#L7-L11) +- [data_changes.py:6-11](file://docs/components/antd/pagination/demos/data_changes.py#L6-L11) + +## Dependency Analysis + +- Component coupling + - Backend component class and frontend wrapper layer are loosely coupled, communicating via properties and slots as contracts + - React encapsulation layer's dependency on Ant Design is explicit, making it easy to upgrade and replace +- Events and slots + - Events: `change`, `showSizeChange` + - Slots: `showQuickJumper.goButton`, `itemRender` +- External dependencies + - Ant Design Pagination + - Gradio event system and state management + +```mermaid +graph LR +PY["Backend Component Class
__init__.py"] --> IDX["Frontend Wrapper Layer
Index.svelte"] +IDX --> REACT["React Encapsulation Layer
pagination.tsx"] +REACT --> ANTDP["Ant Design Pagination"] +PY --> |"Events/Slots"| PY +``` + +Diagram Sources + +- [**init**.py:14-25](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L14-L25) +- [Index.svelte:54-66](file://frontend/antd/pagination/Index.svelte#L54-L66) +- [pagination.tsx:28-48](file://frontend/antd/pagination/pagination.tsx#L28-L48) + +Section Sources + +- [**init**.py:14-25](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L14-L25) +- [Index.svelte:54-66](file://frontend/antd/pagination/Index.svelte#L54-L66) +- [pagination.tsx:28-48](file://frontend/antd/pagination/pagination.tsx#L28-L48) + +## Performance Considerations + +- Rendering optimization + - Use virtual scrolling (tables) to reduce DOM count + - Control `page_size` to avoid excessive single-page rendering pressure +- Request optimization + - Only make data requests on `change` to avoid frequent refreshes + - Disable pagination during requests to prevent duplicate requests +- Styles and resources + - Use `elem_classes` and style caching reasonably to reduce repaints + - Avoid heavy computations in `itemRender` + +## Troubleshooting Guide + +- Issue: Pagination not triggering `change` + - Check whether the `change` event is correctly bound + - Confirm `total` and `page_size` settings are reasonable +- Issue: Page size switching not working + - Check whether `show_size_changer` is enabled + - Confirm `show_size_change` property mapping is correct +- Issue: Quick jump button not displaying + - Check whether the `showQuickJumper.goButton` slot is provided +- Issue: Styles not taking effect + - Check usage of `elem_id`, `elem_classes`, `elem_style`, and `root_class_name` +- Issue: Internationalization text anomalies + - Confirm `ConfigProvider` is correctly configured with the locale + +Section Sources + +- [Index.svelte:46-47](file://frontend/antd/pagination/Index.svelte#L46-L47) +- [pagination.tsx:39-47](file://frontend/antd/pagination/pagination.tsx#L39-L47) +- [README.md:1-14](file://docs/components/antd/pagination/README.md#L1-L14) + +## Conclusion + +The Pagination component achieves a flexible pagination experience through clear frontend-backend separation and event/slot contracts. Combined with table and list components, high-performance, extensible data browsing interfaces can be easily built. For large dataset scenarios, combining virtual scrolling and server-side pagination strategies is recommended to ensure smooth interactions and efficient resource usage. + +## Appendix + +- Example entry + - Documentation app entry: [app.py:1-7](file://docs/components/antd/pagination/app.py#L1-L7) +- Example scripts + - Basic example: [basic.py:1-15](file://docs/components/antd/pagination/demos/basic.py#L1-L15) + - Data change example: [data_changes.py:1-36](file://docs/components/antd/pagination/demos/data_changes.py#L1-L36) +- Component source code + - Backend component class: [**init**.py:1-107](file://backend/modelscope_studio/components/antd/pagination/__init__.py#L1-L107) + - Frontend wrapper layer: [Index.svelte:1-68](file://frontend/antd/pagination/Index.svelte#L1-L68) + - React encapsulation layer: [pagination.tsx:1-55](file://frontend/antd/pagination/pagination.tsx#L1-L55) diff --git a/.wiki/en/Ant Design Components/Navigation Components/Steps.md b/.wiki/en/Ant Design Components/Navigation Components/Steps.md new file mode 100644 index 00000000..093c2db9 --- /dev/null +++ b/.wiki/en/Ant Design Components/Navigation Components/Steps.md @@ -0,0 +1,425 @@ +# Steps + + +**Files Referenced in This Document** +- [steps.tsx](file://frontend/antd/steps/steps.tsx) +- [steps.item.tsx](file://frontend/antd/steps/item/steps.item.tsx) +- [Index.svelte](file://frontend/antd/steps/item/Index.svelte) +- [context.ts](file://frontend/antd/steps/context.ts) +- [package.json](file://frontend/antd/steps/package.json) +- [gradio.config.js](file://frontend/antd/steps/gradio.config.js) +- [__init__.py](file://backend/modelscope_studio/components/antd/steps/__init__.py) +- [README.md](file://docs/components/antd/steps/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Steps component guides users through multiple stages in sequence within a task flow, serving as a typical process indicator component. This component is based on Ant Design's Steps implementation, provided in a form directly usable from the Python backend via Gradio/Svelte frontend bridging. It supports multiple layout modes (horizontal/vertical), size specifications (default/small), state management (wait/process/finish/error), and custom progress dot rendering (progressDot slot). The component also provides integration capabilities for form wizards, business processes, user registration, and other scenarios, with support for style customization and responsive adaptation. + +## Project Structure + +The Steps component consists of frontend Svelte components and backend ModelScope component wrappers, with frontend-backend interaction following Gradio component conventions. Key files are distributed as follows: + +- Frontend: `steps.tsx` (main component), `steps.item.tsx` (step item wrapper), `Index.svelte` (step item entry), `context.ts` (step item context), `package.json` (export config), `gradio.config.js` (build config) +- Backend: `__init__.py` (Python wrapper, exposing properties and events) +- Documentation: `README.md` (component description and example placeholders) + +```mermaid +graph TB +subgraph "Frontend" +F_steps_tsx["steps.tsx
Main Component"] +F_item_index["Index.svelte
Step Item Entry"] +F_item_impl["steps.item.tsx
Step Item Implementation"] +F_context["context.ts
Step Item Context"] +F_pkg["package.json
Export Config"] +F_cfg["gradio.config.js
Build Config"] +end +subgraph "Backend" +B_init["__init__.py
Python Wrapper"] +end +subgraph "Documentation" +D_readme["README.md
Component Description"] +end +F_steps_tsx --> F_context +F_steps_tsx --> F_item_impl +F_item_index --> F_item_impl +F_steps_tsx --> B_init +F_pkg --> F_steps_tsx +F_cfg --> F_steps_tsx +D_readme --> B_init +``` + +**Diagram Sources** + +- [steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [steps.item.tsx:1-14](file://frontend/antd/steps/item/steps.item.tsx#L1-L14) +- [Index.svelte:1-65](file://frontend/antd/steps/item/Index.svelte#L1-L65) +- [context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) +- [package.json:1-15](file://frontend/antd/steps/package.json#L1-L15) +- [gradio.config.js:1-4](file://frontend/antd/steps/gradio.config.js#L1-L4) +- [**init**.py:1-95](file://backend/modelscope_studio/components/antd/steps/__init__.py#L1-L95) +- [README.md:1-8](file://docs/components/antd/steps/README.md#L1-L8) + +**Section Sources** + +- [steps.tsx:1-52](file://frontend/antd/steps/steps.tsx#L1-L52) +- [steps.item.tsx:1-14](file://frontend/antd/steps/item/steps.item.tsx#L1-L14) +- [Index.svelte:1-65](file://frontend/antd/steps/item/Index.svelte#L1-L65) +- [context.ts:1-7](file://frontend/antd/steps/context.ts#L1-L7) +- [package.json:1-15](file://frontend/antd/steps/package.json#L1-L15) +- [gradio.config.js:1-4](file://frontend/antd/steps/gradio.config.js#L1-L4) +- [**init**.py:1-95](file://backend/modelscope_studio/components/antd/steps/__init__.py#L1-L95) +- [README.md:1-8](file://docs/components/antd/steps/README.md#L1-L8) + +## Core Components + +- Main Component Steps (frontend): Responsible for receiving props, parsing slots (e.g., `progressDot`), merging items data sources (explicit items or slot items/default), and passing the final data to Ant Design's Steps. +- Step Item StepsItem (frontend): Serves as the React wrapper for step items, injecting step items into the Steps container through the ItemHandler context. +- Step Item Entry Index.svelte: Renders StepsItem in Svelte and handles properties such as visibility, class names, IDs, inline styles, and slots. +- Context: Provides `createItemsContext` capabilities to establish a stable parent-child relationship and data channel between Steps and StepsItem. +- Backend wrapper AntdSteps: Provides rich properties (`current`, `direction`, `size`, `status`, `type`, `responsive`, etc.) and declares supported slots (`progressDot`, `items`). + +**Section Sources** + +- [steps.tsx:10-49](file://frontend/antd/steps/steps.tsx#L10-L49) +- [steps.item.tsx:7-11](file://frontend/antd/steps/item/steps.item.tsx#L7-L11) +- [Index.svelte:16-64](file://frontend/antd/steps/item/Index.svelte#L16-L64) +- [context.ts:3-4](file://frontend/antd/steps/context.ts#L3-L4) +- [**init**.py:11-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L11-L77) + +## Architecture Overview + +The runtime control flow of the Steps component: the frontend Steps component reads the step item collection from context and resolves `items` or the default slot; if a `progressDot` slot exists, it renders via parameterized slot; otherwise falls back to function or boolean value form. Ant Design's Steps receives the final items and progress dot configuration, renders the UI, and triggers the `change` event (monitored by the backend). + +```mermaid +sequenceDiagram +participant Py as "Backend Component
AntdSteps" +participant FE as "Frontend Component
Steps" +participant Ctx as "Context
withItemsContextProvider" +participant AD as "Ant Design Steps" +Py->>FE : Render component and pass props +FE->>Ctx : Request current step item collection +Ctx-->>FE : Return items/default +FE->>FE : Resolve items or default slot +FE->>FE : Handle progressDot slot/function +FE->>AD : Pass items and progress dot configuration +AD-->>FE : Render UI +FE-->>Py : Trigger change event monitored by backend +``` + +**Diagram Sources** + +- [steps.tsx:16-44](file://frontend/antd/steps/steps.tsx#L16-L44) +- [context.ts:3-4](file://frontend/antd/steps/context.ts#L3-L4) +- [**init**.py:16-20](file://backend/modelscope_studio/components/antd/steps/__init__.py#L16-L20) + +**Section Sources** + +- [steps.tsx:16-44](file://frontend/antd/steps/steps.tsx#L16-L44) +- [context.ts:3-4](file://frontend/antd/steps/context.ts#L3-L4) +- [**init**.py:16-20](file://backend/modelscope_studio/components/antd/steps/__init__.py#L16-L20) + +## Detailed Component Analysis + +### Steps Main Component (Steps) + +- Functional responsibilities + - Receives all available props for Ant Design Steps and extends children support. + - Reads step item collection from context; prefers explicit items, then uses default slot items/default. + - Progress dot configuration supports two forms: slot `progressDot` (parameterized rendering) or function/boolean value. + - Uses `useMemo` to stabilize items, avoiding unnecessary re-renders. +- Key behaviors + - Hides children (`display: none`) to avoid duplicate rendering; actual content is injected via slots. + - `progressDot` priority: uses slot rendering if a slot exists; otherwise uses function or native boolean/string configuration. +- Typical usage + - Directly pass a steps array in `items`, or inject step items via slots. + - Use the `progressDot` slot to customize the rendering logic of each step indicator. + +```mermaid +flowchart TD +Start(["Enter Steps Render"]) --> ReadCtx["Read items/default from context"] +ReadCtx --> HasExplicit{"Are explicit items provided?"} +HasExplicit --> |Yes| UseExplicit["Use explicit items"] +HasExplicit --> |No| UseDefault["Use default slot items/default"] +UseExplicit --> ResolveItems["Resolve step item list"] +UseDefault --> ResolveItems +ResolveItems --> HasProgressDotSlot{"Does progressDot slot exist?"} +HasProgressDotSlot --> |Yes| RenderSlot["Parameterized slot rendering"] +HasProgressDotSlot --> |No| UseFuncOrProp["Use function/boolean/string configuration"] +RenderSlot --> RenderAD["Render Ant Design Steps"] +UseFuncOrProp --> RenderAD +RenderAD --> End(["Complete"]) +``` + +**Diagram Sources** + +- [steps.tsx:18-44](file://frontend/antd/steps/steps.tsx#L18-L44) + +**Section Sources** + +- [steps.tsx:10-49](file://frontend/antd/steps/steps.tsx#L10-L49) + +### Step Item (StepsItem) + +- Functional responsibilities + - Serves as the React wrapper for step items, combining step item properties with context, handed to `ItemHandler`. + - Bridges TypeScript/React components to the Svelte ecosystem via `sveltify`. +- Integration key points + - Works with Steps context to ensure step items are correctly injected into the container. + - Supports additional property pass-through and internal index (`itemIndex`) passing. + +```mermaid +classDiagram +class StepsItem { ++props : step item properties ++Renders to ItemHandler +} +class ItemHandler { ++Inject step item ++Maintain context +} +StepsItem --> ItemHandler : "Wrap and inject" +``` + +**Diagram Sources** + +- [steps.item.tsx:7-11](file://frontend/antd/steps/item/steps.item.tsx#L7-L11) +- [context.ts:3-4](file://frontend/antd/steps/context.ts#L3-L4) + +**Section Sources** + +- [steps.item.tsx:7-11](file://frontend/antd/steps/item/steps.item.tsx#L7-L11) +- [context.ts:3-4](file://frontend/antd/steps/context.ts#L3-L4) + +### Step Item Entry (Index.svelte) + +- Functional responsibilities + - Dynamically imports StepsItem in Svelte and renders it. + - Handles visibility, class names, IDs, inline styles, slots, and other properties. + - Injects child nodes into StepsItem via `{@render children()}`. +- Design key points + - Uses `getProps`/`processProps` to retrieve and filter internal properties that don't need pass-through. + - Gets the slot key via `getSlotKey` and passes it to StepsItem for slot identification. + +```mermaid +flowchart TD +SStart(["Index.svelte Render Start"]) --> ImportItem["Dynamic import StepsItem"] +ImportItem --> GetProps["Extract component and additional properties"] +GetProps --> CheckVisible{"Visibility check"} +CheckVisible --> |Hidden| Skip["Skip rendering"] +CheckVisible --> |Visible| RenderItem["Render StepsItem with properties/slots"] +RenderItem --> SEnd(["End"]) +Skip --> SEnd +``` + +**Diagram Sources** + +- [Index.svelte:16-64](file://frontend/antd/steps/item/Index.svelte#L16-L64) + +**Section Sources** + +- [Index.svelte:1-65](file://frontend/antd/steps/item/Index.svelte#L1-L65) + +### Backend Wrapper (AntdSteps) + +- Property overview (selected) + - Current step `current`, direction `direction` (horizontal/vertical), initial value `initial`, label position `label_placement`, title position `title_placement`, percentage `percent`, progress dot `progress_dot`, responsive `responsive`, size `size` (small/default), status `status` (wait/process/finish/error), type `type` (default/navigation/inline), root class name `root_class_name`, class names `class_names`, styles `styles`, slots `items`/`progressDot`, etc. +- Events + - `change`: Listens for step change events (bound by the backend). +- Others + - `FRONTEND_DIR` points to the frontend steps component directory. + - `skip_api` is `True`, indicating the component does not participate in the standard API flow. + +```mermaid +classDiagram +class AntdSteps { ++current : number ++direction : "horizontal|vertical" ++initial : number ++label_placement : "horizontal|vertical" ++title_placement : "horizontal|vertical"|None ++percent : number|None ++progress_dot : bool|string ++responsive : bool ++size : "small|default"|None ++status : "wait|process|finish|error" ++type : "default|navigation|inline" ++items : list|None ++root_class_name : str|None ++class_names : dict|str|None ++styles : dict|str|None ++EVENTS : ["change"] ++SLOTS : ["progressDot","items"] +} +``` + +**Diagram Sources** + +- [**init**.py:25-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L25-L77) + +**Section Sources** + +- [**init**.py:11-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L11-L77) + +## Dependency Analysis + +- Frontend dependencies + - Uses Ant Design's Steps as the underlying UI component. + - Bridges React components to Svelte via `sveltify`. + - Provides step item context via `createItemsContext`. + - Renders step items and slots using `renderItems`/`renderParamsSlot`. +- Backend dependencies + - Interacts with Gradio via `ModelScopeLayoutComponent`. + - Specifies the frontend component directory via `resolve_frontend_dir`. +- Exports and build + - `package.json` specifies Gradio and default export paths. + - `gradio.config.js` performs build configuration based on global `defineConfig`. + +```mermaid +graph LR +Pkg["package.json"] --> StepsTSX["steps.tsx"] +Cfg["gradio.config.js"] --> StepsTSX +StepsTSX --> AD["Ant Design Steps"] +StepsTSX --> Ctx["createItemsContext"] +StepsTSX --> Utils["renderItems / renderParamsSlot"] +StepsTSX --> Py["AntdSteps(__init__.py)"] +``` + +**Diagram Sources** + +- [package.json:4-12](file://frontend/antd/steps/package.json#L4-L12) +- [gradio.config.js:1-4](file://frontend/antd/steps/gradio.config.js#L1-L4) +- [steps.tsx:1-8](file://frontend/antd/steps/steps.tsx#L1-L8) +- [**init**.py:77-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L77-L77) + +**Section Sources** + +- [package.json:1-15](file://frontend/antd/steps/package.json#L1-L15) +- [gradio.config.js:1-4](file://frontend/antd/steps/gradio.config.js#L1-L4) +- [steps.tsx:1-8](file://frontend/antd/steps/steps.tsx#L1-L8) +- [**init**.py:77-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L77-L77) + +## Performance Considerations + +- Data stabilization: Uses `useMemo` to stabilize items, reducing unnecessary re-renders. +- Slot rendering: The `progressDot` slot uses parameterized rendering to avoid repeatedly creating complex structures in each render. +- Visibility control: The step item entry checks `visible` to hide invisible items, reducing DOM overhead. +- Event binding: Binds the `change` event only when needed, avoiding unnecessary callback triggers. + +[This section contains general performance advice and does not require specific file references] + +## Troubleshooting Guide + +- Issue: Step items not displaying + - Check whether Steps has correctly injected `items` or slot `items/default`. + - Confirm the step item's `visible` property is true. +- Issue: Progress dots not rendering as expected + - If using the `progressDot` slot, confirm the slot key matches the component conventions. + - If using function/boolean value, confirm the passed configuration matches Ant Design's expectations. +- Issue: Styles or class names not taking effect + - Check whether `root_class_name`, `class_names`, `styles` are correctly passed. + - Confirm CSS scope and override rules. +- Issue: Responsive layout anomalies + - Check whether the combination of `responsive` and `direction` is as expected. + - Confirm parent container width and breakpoint settings. + +**Section Sources** + +- [steps.tsx:20-44](file://frontend/antd/steps/steps.tsx#L20-L44) +- [Index.svelte:49-64](file://frontend/antd/steps/item/Index.svelte#L49-L64) +- [**init**.py:25-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L25-L77) + +## Conclusion + +The Steps component achieves complete wrapping and extension of Ant Design Steps through a clear frontend-backend layered design. It supports multiple layouts, multiple states, customizable progress dots, and responsive adaptation, suitable for form wizards, business processes, user registration, and other scenarios. Through context and slot mechanisms, the component has good composability and maintainability. + +[This section contains summary content and does not require specific file references] + +## Appendix + +### Step Item (Item) Configuration Options + +- Basic properties + - Title: Text for the step item title. + - Description: Description text for the step item. + - Icon: Icon element for the step item. +- State and behavior + - Status: `wait`, `process`, `finish`, `error`, indicating the current state of the step. + - Visibility: `visible` controls whether the step item is rendered. + - Internal index: `itemIndex` identifies the step item's position in the list. +- Slots and styles + - Slots: Support injecting custom content via slots. + - Class names and IDs: `elem_classes`, `elem_id` for styling and positioning. + - Inline styles: `elem_style` for local style overrides. + +**Section Sources** + +- [Index.svelte:16-64](file://frontend/antd/steps/item/Index.svelte#L16-L64) +- [steps.item.tsx:7-11](file://frontend/antd/steps/item/steps.item.tsx#L7-L11) + +### Layout Modes and Application Scenarios + +- Horizontal steps bar (horizontal) + - Suitable for linear processes such as form wizards and payment flows. +- Vertical steps bar (vertical) + - Suitable for long processes or scenarios emphasizing chronological order. +- Small steps bar (small) + - Suitable for space-constrained or simplified interfaces. + +**Section Sources** + +- [**init**.py:30-39](file://backend/modelscope_studio/components/antd/steps/__init__.py#L30-L39) + +### Integration with Form Wizards, Business Processes, and User Registration + +- Form wizards + - Use `current` and `status` to control the current step and state; synchronize backend state via `change` events. +- Business processes + - Use `direction` and `responsive` for process visualization; use `progress_dot` to customize process nodes. +- User registration + - Use `size` and `type` to switch between different styles; use `items` and slots to organize registration steps. + +**Section Sources** + +- [**init**.py:25-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L25-L77) +- [steps.tsx:16-44](file://frontend/antd/steps/steps.tsx#L16-L44) + +### Style Customization and Responsive Adaptation + +- Style customization + - Use `root_class_name`, `class_names`, `styles` for overall and local style control. + - Granularly control step item appearance via `elem_classes`, `elem_id`, `elem_style`. +- Responsive adaptation + - Use the combination of `responsive` and `direction` to adapt for mobile and desktop layouts. + +**Section Sources** + +- [**init**.py:40-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L40-L77) +- [Index.svelte:52-58](file://frontend/antd/steps/item/Index.svelte#L52-L58) + +### Usage Examples and Best Practices + +- Example references + - The documentation provides basic example placeholders; combine with `AntdSteps` properties and slots for demonstrations. +- Best practices + - Clearly define step states and navigation logic to avoid state confusion. + - Use the `progress_dot` slot judiciously to maintain visual consistency. + - Break down steps for complex processes to improve user experience. + +**Section Sources** + +- [README.md:1-8](file://docs/components/antd/steps/README.md#L1-L8) +- [**init**.py:25-77](file://backend/modelscope_studio/components/antd/steps/__init__.py#L25-L77) diff --git a/.wiki/en/Ant Design Components/Other Components.md b/.wiki/en/Ant Design Components/Other Components.md new file mode 100644 index 00000000..1e73e57f --- /dev/null +++ b/.wiki/en/Ant Design Components/Other Components.md @@ -0,0 +1,325 @@ +# Other Components + + +**Files referenced in this document** +- [frontend/antd/affix/affix.tsx](file://frontend/antd/affix/affix.tsx) +- [frontend/antd/affix/Index.svelte](file://frontend/antd/affix/Index.svelte) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/config-provider/locales.ts](file://frontend/antd/config-provider/locales.ts) +- [frontend/antd/config-provider/Index.svelte](file://frontend/antd/config-provider/Index.svelte) +- [frontend/antd/float-button/float-button.tsx](file://frontend/antd/float-button/float-button.tsx) +- [frontend/antd/layout/layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) +- [frontend/antd/float-button/group/float-button.group.less](file://frontend/antd/float-button/group/float-button.group.less) +- [frontend/antd/menu/menu.less](file://frontend/antd/menu/menu.less) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This chapter focuses on the "Other Components" scenario of Ant Design Studio, covering two types of auxiliary components: Affix and ConfigProvider. We will systematically explain positioning mechanisms, scroll monitoring and boundary handling, as well as theme customization, language switching, and component default configuration, combining real implementations from the repository to provide actionable application scenarios, performance optimization and memory management suggestions, and best practices for component collaboration. + +## Project Structure + +- Frontend uses Svelte + React hybrid encapsulation mode: Svelte layer handles property/slot pass-through and conditional rendering, React layer handles specific UI behaviors (such as Affix, ConfigProvider, etc.). +- Utility layer provides common capabilities, such as converting external functions into function wrappers that can be safely used in React. +- Style layer ensures theme and prefix isolation through CSS-in-JS StyleProvider, avoiding global pollution. + +```mermaid +graph TB +subgraph "Svelte Layer" +A_Index["Affix/Index.svelte"] +C_Index["ConfigProvider/Index.svelte"] +end +subgraph "React Layer" +A_Impl["affix.tsx
Wraps Ant Design Affix"] +C_Impl["config-provider.tsx
Wraps Ant Design ConfigProvider"] +FBT["float-button.tsx
Float Button"] +LBase["layout.base.tsx
Layout Base"] +end +subgraph "Utilities and Resources" +UF["useFunction.ts
Function Wrapper"] +LOC["locales.ts
Multi-language Mapping and On-demand Loading"] +FBGroupLess["float-button.group.less
Group Styles"] +MenuLess["menu.less
Menu Styles"] +end +A_Index --> A_Impl +C_Index --> C_Impl +A_Impl --> UF +C_Impl --> UF +C_Impl --> LOC +FBT --> UF +LBase --> |"Layout Composition"| A_Impl +LBase --> |"Layout Composition"| C_Impl +FBGroupLess --> FBT +MenuLess --> C_Impl +``` + +Diagram Source + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/antd/float-button/group/float-button.group.less:1-31](file://frontend/antd/float-button/group/float-button.group.less#L1-L31) +- [frontend/antd/menu/menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) + +Section Source + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/antd/float-button/group/float-button.group.less:1-31](file://frontend/antd/float-button/group/float-button.group.less#L1-L31) +- [frontend/antd/menu/menu.less:1-45](file://frontend/antd/menu/menu.less#L1-L45) + +## Core Components + +- Affix + - Positioning Mechanism: Calculates element fixed state based on target container scroll position; supports custom target containers (such as page or a scroll area). + - Boundary Handling: Controls fixed/unbind timing through threshold to avoid elements being incorrectly fixed or prematurely unbound. + - Scroll Monitoring: Converts externally passed container selectors into React-usable callbacks through function wrappers. +- ConfigProvider + - Theme Customization: Supports light/dark mode and compact algorithm switch, dynamically combining algorithm lists to achieve theme switching. + - Language Switching: According to browser or specified language, asynchronously loads Antd language pack and dayjs language pack on demand. + - Component Default Configuration: Uniformly encapsulates global behaviors like getPopupContainer, getTargetContainer, renderEmpty, etc. + - Style Isolation: Injects high-priority styles through CSS-in-JS StyleProvider to avoid style conflicts. + +Section Source + +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) + +## Architecture Overview + +The diagram below shows the interaction relationship between Svelte and React layers, as well as ConfigProvider's extension points in theme and language aspects. + +```mermaid +sequenceDiagram +participant S as "Svelte Layer" +participant R as "React Layer" +participant U as "Utility Layer" +participant L as "Language Resources" +S->>R : Pass-through properties/slots +R->>U : useFunction wraps container selector/callback +R->>L : On-demand load language pack and dayjs language +L-->>R : Return language pack object +R-->>S : Render result with theme and language +``` + +Diagram Source + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) + +## Detailed Component Analysis + +### Affix Component + +- Design Points + - Svelte layer handles conditional rendering and property pass-through, supports visible for display control. + - React layer converts externally passed container selectors into React-executable functions through useFunction, ensuring stable and reliable scroll monitoring. + - Supports slots and child node rendering for carrying complex content in fixed state. +- Key Flow + - Property Processing: Maps get_target to target, handled internally by the Affix component. + - Rendering: Only renders when visible is true, reducing unnecessary DOM overhead. +- Usage Suggestions + - For non-window scroll containers, be sure to explicitly pass the target function to point to the correct container. + - Set thresholds reasonably to avoid jitter caused by frequent switching between fixed/unbound states. + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant S as "Affix/Index.svelte" +participant R as "affix.tsx" +participant A as "Antd Affix" +UI->>S : Pass visible/get_target/properties +S->>R : Pass-through properties and slots +R->>R : useFunction wraps target +R->>A : Render Affix and pass target +A-->>UI : Fixed/unbound state update +``` + +Diagram Source + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) + +Section Source + +- [frontend/antd/affix/Index.svelte:1-72](file://frontend/antd/affix/Index.svelte#L1-L72) +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) + +### ConfigProvider Component + +- Design Points + - Theme: Dynamically combines algorithms through themeMode and theme.algorithm, supporting dark and compact modes. + - Language: Automatically maps to available language sets based on locale, asynchronously loads Antd language pack and dayjs language pack on demand. + - Container: Uniformly provides function wrappers for getPopupContainer and getTargetContainer, ensuring popups and overlays render to the correct container. + - Slots: Supports slot parameters like renderEmpty, implemented through renderParamsSlot for flexible extension. + - Styles: Injects high-priority styles through StyleProvider to avoid style conflicts. +- Key Flow + - Language Initialization: Parses browser language or passed locale into standard format and loads corresponding language pack. + - Theme Initialization: Generates algorithm array based on themeMode and user configuration, passes to Ant Design. + - Container Callback: Uses useFunction to wrap callbacks, ensuring stable operation within React lifecycle. + - Slot Rendering: Wraps slot content as ReactSlot or renderParamsSlot, maintaining type safety. + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant S as "ConfigProvider/Index.svelte" +participant R as "config-provider.tsx" +participant U as "useFunction.ts" +participant LOC as "locales.ts" +participant SP as "StyleProvider" +UI->>S : Pass theme_mode/locale/theme etc. +S->>R : Pass-through properties and slots +R->>U : useFunction wraps getPopupContainer/getTargetContainer/renderEmpty +R->>LOC : Parse locale and on-demand load language pack +LOC-->>R : Return language pack object +R->>SP : Inject high-priority styles +SP-->>UI : Render subtree with theme and language +``` + +Diagram Source + +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) + +Section Source + +- [frontend/antd/config-provider/Index.svelte:1-72](file://frontend/antd/config-provider/Index.svelte#L1-L72) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) + +### FloatButton and Layout.Base + +- FloatButton + - Supports slots like icon/description/tooltip/badge, implemented through ReactSlot for flexible rendering. + - tooltip supports object configuration and callback wrapping, ensuring popup container and callback stability. +- Layout.Base + - Dynamically selects Header/Footer/Content/Layout through component type selector, unifies class name prefix for easy style control. + +Section Source + +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +## Dependency Analysis + +- Component Coupling + - Both Affix and ConfigProvider depend on useFunction for function wrapping, reducing cross-layer call risks. + - ConfigProvider depends on language mapping and on-demand loading capabilities provided by locales.ts. +- External Dependencies + - Ant Design component library and dayjs language packs. + - CSS-in-JS StyleProvider for style isolation and priority control. +- Potential Circular Dependencies + - No direct circular dependencies in current implementation; if business side re-introduces ConfigProvider/Affix in slots, carefully control rendering levels. + +```mermaid +graph LR +A["affix.tsx"] --> UF["useFunction.ts"] +C["config-provider.tsx"] --> UF +C --> LOC["locales.ts"] +C --> SP["StyleProvider"] +F["float-button.tsx"] --> UF +L["layout.base.tsx"] --> |"Composition"| A +L --> |"Composition"| C +``` + +Diagram Source + +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) + +Section Source + +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [frontend/antd/float-button/float-button.tsx:1-75](file://frontend/antd/float-button/float-button.tsx#L1-L75) +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) + +## Performance Considerations + +- Scroll Monitoring and Repaint + - Affix's target should point to minimized scroll containers as much as possible to avoid pressure on full-page scrolling. + - Set thresholds and fixed heights reasonably to reduce reflow and repaint caused by frequent switching. +- Language Pack On-demand Loading + - ConfigProvider only triggers language pack loading when locale changes, avoiding repeated requests. + - dayjs language pack and Antd language pack are loaded asynchronously, note network and caching strategies. +- Function Wrapping and Stability + - Use useFunction to wrap callbacks to avoid new functions being generated on each render causing unnecessary child component updates. +- Style Injection + - StyleProvider high-priority injection reduces style override costs; avoid frequent theme switching in hot paths. + +## Troubleshooting Guide + +- Affix not working + - Check whether the target function is correctly passed, or whether updates are not triggered when container scrolls. + - Confirm visible condition is satisfied and container has scrollbar. +- Language switching ineffective + - Check whether locale has a mapping in locales.ts; confirm asynchronous loading succeeded. + - Ensure dayjs.locale switching succeeded. +- Theme switching abnormal + - Check whether themeMode and theme.algorithm combination is as expected. + - Note algorithm array concatenation order and null value filtering. +- Slot rendering issues + - Confirm slot key and renderParamsSlot mapping consistency. + - ReactSlot's clone parameter should be enabled as needed to avoid duplicate mounting. + +Section Source + +- [frontend/antd/affix/affix.tsx:1-14](file://frontend/antd/affix/affix.tsx#L1-L14) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/config-provider/locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) + +## Conclusion + +- Affix and ConfigProvider, as auxiliary components, undertake the key responsibilities of "positioning and scrolling" and "theme and language" in Ant Design Studio. +- Through layered encapsulation of Svelte and React, both usability and powerful extensibility are guaranteed. +- In actual projects, it is recommended to prioritize using ConfigProvider for global unified configuration at the application root, then use Affix locally on pages that need fixed layouts or toolbars. + +## Appendix + +- Best Practices for Component Collaboration + - Place ConfigProvider at the application root to centrally manage theme and language; use Affix locally on pages that need fixed elements. + - Use Layout.Base to unify layout structure, combined with FloatButton to improve interaction efficiency. + - For complex slot scenarios, prefer using ReactSlot and renderParamsSlot to ensure type safety and controllable rendering. +- Styles and Themes + - Avoid style conflicts through StyleProvider and prefix class names (like ms-gr-ant). + - Menu and float button style files can be used as references, adjust border-radius, spacing, and transition effects as needed. diff --git a/.wiki/en/Ant Design X Components/Ant Design X Components.md b/.wiki/en/Ant Design X Components/Ant Design X Components.md new file mode 100644 index 00000000..207c9fdb --- /dev/null +++ b/.wiki/en/Ant Design X Components/Ant Design X Components.md @@ -0,0 +1,626 @@ +# Ant Design X Components + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/antdx/file_card/__init__.py](file://backend/modelscope_studio/components/antdx/file_card/__init__.py) +- [backend/modelscope_studio/components/antdx/file_card/list/__init__.py](file://backend/modelscope_studio/components/antdx/file_card/list/__init__.py) +- [backend/modelscope_studio/components/antdx/file_card/list/item/__init__.py](file://backend/modelscope_studio/components/antdx/file_card/list/item/__init__.py) +- [backend/modelscope_studio/components/antdx/mermaid/__init__.py](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py) +- [backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py](file://backend/modelscope_studio/components/antdx/folder/directory_icon/__init__.py) +- [backend/modelscope_studio/components/antdx/folder/tree_node/__init__.py](file://backend/modelscope_studio/components/antdx/folder/tree_node/__init__.py) +- [frontend/antdx/file-card/file-card.tsx](file://frontend/antdx/file-card/file-card.tsx) +- [frontend/antdx/file-card/base.tsx](file://frontend/antdx/file-card/base.tsx) +- [frontend/antdx/mermaid/mermaid.tsx](file://frontend/antdx/mermaid/mermaid.tsx) +- [frontend/antdx/folder/folder.tsx](file://frontend/antdx/folder/folder.tsx) +- [frontend/antdx/thought-chain/thought-chain.tsx](file://frontend/antdx/thought-chain/thought-chain.tsx) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/antdx/conversations/conversations.tsx](file://frontend/antdx/conversations/conversations.tsx) +- [frontend/antdx/welcome/welcome.tsx](file://frontend/antdx/welcome/welcome.tsx) +- [frontend/antdx/prompts/prompts.tsx](file://frontend/antdx/prompts/prompts.tsx) +- [frontend/antdx/attachments/attachments.tsx](file://frontend/antdx/attachments/attachments.tsx) +- [frontend/antdx/sender/sender.tsx](file://frontend/antdx/sender/sender.tsx) +- [frontend/antdx/suggestion/suggestion.tsx](file://frontend/antdx/suggestion/suggestion.tsx) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/think/think.tsx](file://frontend/antdx/think/think.tsx) +- [frontend/antdx/notification/notification.tsx](file://frontend/antdx/notification/notification.tsx) +- [frontend/antdx/sources/sources.tsx](file://frontend/antdx/sources/sources.tsx) + + +## Update Summary + +**Changes Made** + +- Added file card component system (FileCard, FileCardList, FileCardListItem) +- Added Mermaid diagram component +- Added folder component (Folder) and its subcomponents (DirectoryIcon, TreeNode) +- Added thought chain component (ThoughtChain) and its subcomponents +- Updated component export structure to sync with Ant Design X version +- Enhanced component collaboration capabilities, supporting richer slot-based rendering + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Usability Recommendations](#performance-and-usability-recommendations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the Ant Design X component library for ModelScope Studio, designed for machine learning and AI application scenarios. It systematically covers general components (such as bubbles, conversation lists), wake components (welcome pages, prompts), expression components (attachments, sender, suggestions), confirmation components (thought chain), feedback components (actions), and newly added advanced components like file cards, Mermaid diagrams, and folders. It provides end-to-end examples and best practices to help developers build consistent, scalable, and user-friendly interfaces for conversational AI, multimodal input, knowledge retrieval augmentation, and chart visualization scenarios. + +## Project Structure + +The Ant Design X component library exports through Python packages on the backend and encapsulates @ant-design/x capabilities using Svelte/React bidirectional bridging on the frontend, exposing composable components uniformly. The overall structure is as follows: + +```mermaid +graph TB +subgraph "Backend Export Layer" +A["backend/modelscope_studio/components/antdx/__init__.py"] +B["backend/modelscope_studio/components/antdx/components.py"] +end +subgraph "Frontend Wrapper Layer" +C["frontend/antdx/bubble/bubble.tsx"] +D["frontend/antdx/conversations/conversations.tsx"] +E["frontend/antdx/welcome/welcome.tsx"] +F["frontend/antdx/prompts/prompts.tsx"] +G["frontend/antdx/attachments/attachments.tsx"] +H["frontend/antdx/sender/sender.tsx"] +I["frontend/antdx/suggestion/suggestion.tsx"] +J["frontend/antdx/actions/actions.tsx"] +K["frontend/antdx/think/think.tsx"] +L["frontend/antdx/notification/notification.tsx"] +M["frontend/antdx/sources/sources.tsx"] +N["frontend/antdx/file-card/file-card.tsx"] +O["frontend/antdx/mermaid/mermaid.tsx"] +P["frontend/antdx/folder/folder.tsx"] +Q["frontend/antdx/thought-chain/thought-chain.tsx"] +end +A --> C +A --> D +A --> E +A --> F +A --> G +A --> H +A --> I +A --> J +A --> K +A --> L +A --> M +A --> N +A --> O +A --> P +A --> Q +B --> C +B --> D +B --> E +B --> F +B --> G +B --> H +B --> I +B --> J +B --> K +B --> L +B --> M +B --> N +B --> O +B --> P +B --> Q +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) +- [frontend/antdx/thought-chain/thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) + +**Section Source** + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Core Components + +This section provides a categorized functional overview of key AI scenario components, including newly added advanced components, for quick identification and combined use. + +- General Components + - Bubble: Used to display message content, avatars, additional information, and footers, supporting slot-based rendering and editable configurations. + - Conversations: Used to display and manage historical conversations, supporting menus, grouping, and expand controls. +- Wake Components + - Welcome: Used as a guide page after application startup or reset, supporting titles, descriptions, icons, and additional areas. + - Prompts: Used to display a set of clickable prompt templates, helping users quickly start conversations. +- Expression Components + - Attachments: Used to upload and manage files, supporting placeholders, previews, image properties, and upload hooks. + - Sender: Used for text input and paste file upload, supporting skill hints, prefix/suffix, and submit interception. + - Suggestion: Used for autocomplete/suggestion panels in input context, supporting trigger strategies and slot-based item rendering. +- Confirmation Components + - Think: Used to display loading state, icons, and titles during reasoning, enhancing perceptibility. + - ThoughtChain: Used to display multi-step reasoning processes, supporting sub-item components and slot-based rendering. +- Feedback Components + - Actions: Used to provide action entries (such as copy, download, feedback) on the right side of content area, supporting dropdown menus and popup rendering. +- Advanced Components + - FileCard: Used to display file information, supporting multiple types, previews, masks, and loading states. + - Mermaid Diagram: Used to render Mermaid flowcharts, sequence diagrams, etc., supporting theme switching and custom actions. + - Folder: Used for file system browsing, supporting directory icon mapping, file content services, and preview rendering. +- Tool Components + - XProvider: Global configuration and context provider, extending antd's ConfigProvider, providing theme, language, popup container, and other global capabilities for @ant-design/x components. + - CodeHighlighter: Code highlighting display component, supporting theme customization, header slots, and syntax highlighting style overrides. + - Mermaid: Flowchart/mind map component, integrating highlighting and action item rendering, supporting light/dark theme switching and custom actions. + - Notification: Browser notification wrapper, providing permission requests, open/close, visibility control, and callbacks. +- Data Components + - FileCard: Used to display a single file card, supporting image placeholder, preview configuration, mask, and loading indicator slot customization. + - Folder: Used to display folder tree structure, supporting treeData, directoryIcons, empty state rendering, directory title, preview rendering slots. + - Sources: Used to display data source list, supporting items and title slots. + - Think: Used to display "thinking" records and status, supporting loading, icon, title slots for different visual feedback in different states. + +**Section Source** + +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [frontend/antdx/welcome/welcome.tsx:1-44](file://frontend/antdx/welcome/welcome.tsx#L1-L44) +- [frontend/antdx/prompts/prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [frontend/antdx/attachments/attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) +- [frontend/antdx/suggestion/suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) +- [frontend/antdx/think/think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) +- [frontend/antdx/thought-chain/thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) + +## Architecture Overview + +The diagram below shows how frontend components bridge to @ant-design/x and achieve flexible rendering and event handling through slots and function wrapping, including the architecture of newly added components. + +```mermaid +graph TB +subgraph "Frontend Wrapper" +U["sveltify wrapper
slot rendering/function wrapping"] +V["@ant-design/x native components"] +W["Utilities and context
renderItems / renderParamsSlot / useFunction"] +X["File service and resource resolution
getFetchableUrl / resolveFileSrc"] +Y["Theme and styles
themeMode / highlightProps"] +end +U --> V +U --> W +U --> X +U --> Y +``` + +**Diagram Source** + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) +- [frontend/antdx/thought-chain/thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) + +## Component Details + +### General Components + +#### Bubble + +- Key Capabilities + - Supports slot-based rendering for avatars, titles, content, footers, and extra areas. + - Supports editable configuration (including "OK/Cancel" text slots). + - Supports loading state and content rendering function wrapping. +- Usage Recommendations + - Use as a message carrier in conversation flows, combined with Sender input and Attachments. + - For long content, enable editable and content rendering functions to improve interaction efficiency. +- Key Paths + - [frontend/antdx/bubble/bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) + +**Section Source** + +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) + +#### Conversations + +- Key Capabilities + - Supports slot-based configuration for menu items, overflow indicators, and expand icons. + - Supports functional configuration for grouping and collapse behavior. + - Internally reuses menu context for unified event propagation and DOM blocking. +- Usage Recommendations + - Combine with Sender/Attachments to form a closed loop of "input-generate-review". + - Implement "delete, rename, export" operations through menu items. +- Key Paths + - [frontend/antdx/conversations/conversations.tsx:59-175](file://frontend/antdx/conversations/conversations.tsx#L59-L175) + +**Section Source** + +- [frontend/antdx/conversations/conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) + +### Wake Components + +#### Welcome + +- Key Capabilities + - Supports slot-based title, description, icon, and additional areas. + - Icon supports passing file data and automatically resolves to accessible URL. +- Usage Recommendations + - Use as the first screen guide after application initialization or conversation reset. +- Key Paths + - [frontend/antdx/welcome/welcome.tsx:8-41](file://frontend/antdx/welcome/welcome.tsx#L8-L41) + +**Section Source** + +- [frontend/antdx/welcome/welcome.tsx:1-44](file://frontend/antdx/welcome/welcome.tsx#L1-L44) + +#### Prompts + +- Key Capabilities + - Supports title slot and item collection slot-based rendering. + - Provides item collection through context, simplifying external parameter passing. +- Usage Recommendations + - Place above welcome page or input box to help users quickly select intent templates. +- Key Paths + - [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) + +**Section Source** + +- [frontend/antdx/prompts/prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) + +### Expression Components + +#### Attachments + +- Key Capabilities + - Supports placeholders, previews, image properties, upload hooks, and maximum count limits. + - Supports custom beforeUpload, customRequest, isImageUrl, previewFile, and other functions. + - Slot-based extension for "extra icons, download/remove/preview icons, placeholder content". +- Usage Recommendations + - Combine with Sender's paste upload for drag/paste-to-upload functionality. + - Note the interaction between maxCount and upload status to avoid concurrency conflicts. +- Key Paths + - [frontend/antdx/attachments/attachments.tsx:36-410](file://frontend/antdx/attachments/attachments.tsx#L36-L410) + +**Section Source** + +- [frontend/antdx/attachments/attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) + +#### Sender + +- Key Capabilities + - Supports prefix/suffix/header/footer slots; supports "skill hint" configuration. + - Supports paste file upload callback, uniformly outputting file path array. + - Through value change hooks and submit interception, avoids mistaken submission when suggestion panel is open. +- Usage Recommendations + - Collaborate with Suggestion to ensure submission only after suggestion panel closes. + - Connect with backend streaming output via onValueChange. +- Key Paths + - [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) + +**Section Source** + +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) + +#### Suggestion + +- Key Capabilities + - Supports items slot and children slot-based rendering. + - Passes keyboard events and trigger logic through context, supporting custom shouldTrigger. + - Supports getPopupContainer functional configuration. +- Usage Recommendations + - Combine with Sender/Textarea to implement @mentions, /commands, keyword completion. + - Control open state and shouldTrigger to avoid triggering during IME composition. +- Key Paths + - [frontend/antdx/suggestion/suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) + +**Section Source** + +- [frontend/antdx/suggestion/suggestion.tsx:1-165](file://frontend/antdx/suggestion/suggestion.tsx#L1-L165) + +### Confirmation Components + +#### Think + +- Key Capabilities + - Displays loading state, icon, and title during reasoning, enhancing perceptibility. + - Supports slot-based override of default rendering. +- Usage Recommendations + - Insert before streaming output to clearly inform users that the model is thinking. +- Key Paths + - [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +**Section Source** + +- [frontend/antdx/think/think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +#### ThoughtChain + +- Key Capabilities + - Supports multi-step reasoning process display, with built-in default and sub-item rendering logic. + - Provides item collection through context, supporting slot-based and default item fallback. + - Reuses common rendering utilities to maintain consistency with other components. +- Usage Recommendations + - Display step-by-step thinking process in complex reasoning scenarios. + - Combine with Bubble component to form a complete reasoning display chain. +- Key Paths + - [frontend/antdx/thought-chain/thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) + +**Section Source** + +- [frontend/antdx/thought-chain/thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) + +### Feedback Components + +#### Actions + +- Key Capabilities + - Supports dropdown menus, popup rendering, and menu item slot-based configuration. + - Reuses menu context for unified event propagation. +- Usage Recommendations + - Provide "copy, download, feedback" operations on the right side of Bubble or content card. +- Key Paths + - [frontend/antdx/actions/actions.tsx:17-120](file://frontend/antdx/actions/actions.tsx#L17-L120) + +**Section Source** + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) + +### Advanced Components + +#### FileCard + +- Key Capabilities + - Supports multiple file types (image, file, audio, video) display. + - Supports slot-based configuration for icons, descriptions, masks, loading states. + - Built-in image preview functionality, supporting custom preview container and toolbar. + - Automatically resolves file sources, supporting local files and remote URLs. +- Usage Recommendations + - Display file information after upload completion. + - Combine with file list component to form a complete file management interface. +- Key Paths + - [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) + - [frontend/antdx/file-card/base.tsx:15-41](file://frontend/antdx/file-card/base.tsx#L15-L41) + +**Section Source** + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) + +#### Mermaid Diagram + +- Key Capabilities + - Supports Mermaid syntax diagram rendering, including flowcharts, sequence diagrams, etc. + - Built-in syntax highlighting, supporting light/dark theme switching. + - Supports custom action buttons and header slots. + - Reuses action component context for consistent interaction experience. +- Usage Recommendations + - Use in document generation or process display scenarios. + - Combine with thought chain component to display complex algorithm flows. +- Key Paths + - [frontend/antdx/mermaid/mermaid.tsx:33-82](file://frontend/antdx/mermaid/mermaid.tsx#L33-L82) + +**Section Source** + +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) + +#### Folder + +- Key Capabilities + - Supports file system browsing and directory structure display. + - Supports custom directory icon mapping and node rendering. + - Built-in file content service, supporting dynamic loading of file content. + - Supports empty state rendering, preview rendering, and title slot-based configuration. +- Usage Recommendations + - Use in knowledge base or project file management scenarios. + - Combine with file card component to provide complete file browsing experience. +- Key Paths + - [frontend/antdx/folder/folder.tsx:16-121](file://frontend/antdx/folder/folder.tsx#L16-L121) + +**Section Source** + +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) + +### Other Utility Components + +#### Notification + +- Key Capabilities + - Lightweight notification based on browser notification permission, supporting visibility control and permission callbacks. +- Usage Recommendations + - Push desktop notifications when background tasks complete or important events occur. +- Key Paths + - [frontend/antdx/notification/notification.tsx:6-50](file://frontend/antdx/notification/notification.tsx#L6-L50) + +**Section Source** + +- [frontend/antdx/notification/notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) + +#### Sources + +- Key Capabilities + - Supports title slot and item collection slot-based rendering. +- Usage Recommendations + - Display reference sources at the end of answers to enhance credibility. +- Key Paths + - [frontend/antdx/sources/sources.tsx:9-41](file://frontend/antdx/sources/sources.tsx#L9-L41) + +**Section Source** + +- [frontend/antdx/sources/sources.tsx:1-42](file://frontend/antdx/sources/sources.tsx#L1-L42) + +## Dependency Analysis + +- Backend Export Layer + - Unifies Ant Design X component exports through **init**.py and components.py, including newly added file cards, Mermaid, folders, and other components. +- Frontend Wrapper Layer + - All components use sveltify wrapping, uniformly handling slots, function wrapping, and event propagation. + - Extensively uses renderItems, renderParamsSlot, useFunction, and other utilities to ensure rendering consistency and flexibility. + - Most components reuse menu and item collection contexts to reduce duplicate configuration costs. + - Newly added components introduce file service resolution and theme switching mechanisms. + +```mermaid +graph LR +P["Python Export
__init__.py / components.py
New Component Exports"] --> Q["Svelte/React Wrapper
sveltify + New Components"] +Q --> R["Utilities and Rendering
renderItems / renderParamsSlot / useFunction"] +Q --> S["Context Providers
menu/items/context + New Contexts"] +Q --> T["@ant-design/x Native Components"] +Q --> U["File Service
getFetchableUrl / resolveFileSrc"] +Q --> V["Theme System
themeMode / highlightProps"] +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) + +**Section Source** + +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Performance and Usability Recommendations + +- Rendering Optimization + - Use useMemo to wrap complex calculation results (such as menu items, suggestion items, tree data, file lists) to reduce unnecessary re-rendering. + - Reasonably split slot rendering to avoid repeated slot mounting when parent level changes frequently. + - Use virtual scrolling for large file lists to improve rendering performance. +- Events and State + - Intercept submission during suggestion panel open to avoid mistaken triggering. + - Disable interaction or show progress during upload to prevent duplicate uploads. + - File card component supports lazy loading to avoid rendering too many images at once. +- Accessibility + - Provide alternative text for icons and buttons to ensure screen reader friendliness. + - Provide keyboard accessibility and focus management for notifications and prompts. + - Mermaid diagrams provide accessibility labels for screen reader narration. +- Data Consistency + - Uniformly update file list after successful upload to avoid state drift. + - In streaming output scenarios, maintain clear transitions between "thinking state - content state - action state". + - File service uses caching mechanism to avoid repeated loading of the same file. +- Theme Adaptation + - Mermaid component automatically adapts to theme mode to ensure diagram readability. + - File card supports dark mode to enhance visual experience. + +## Troubleshooting Guide + +- Slots Not Working + - Check if slots object and corresponding key names are passed correctly. + - Confirm if slot rendering function is correctly wrapped as executable function. +- Upload Failed or Stuck + - Verify beforeUpload/customRequest/isImageUrl function return values and exception handling. + - Check maxCount and current file list length to avoid exceeding limits. +- Suggestion Panel Not Appearing + - Confirm shouldTrigger trigger conditions and input focus state. + - Check open state and whether getPopupContainer container exists. +- Notification Not Showing + - Confirm browser notification permission is granted, request permission flow if necessary. +- Menu Event Abnormal + - Check if onClick is correctly stopped from bubbling to avoid affecting outer interactions. +- File Card Display Abnormal + - Check if file source resolution is correct, confirm getFetchableUrl function works properly. + - Confirm file type and icon mapping match. +- Mermaid Diagram Rendering Failed + - Check if Mermaid syntax is correct, confirm chart type support. + - Confirm theme mode configuration is correct. +- Folder Component Not Responding + - Check if file content service is correctly implemented, confirm async loading function works properly. + - Confirm directory icon mapping and node data format are correct. + +**Section Source** + +- [frontend/antdx/attachments/attachments.tsx:275-354](file://frontend/antdx/attachments/attachments.tsx#L275-L354) +- [frontend/antdx/sender/sender.tsx:126-130](file://frontend/antdx/sender/sender.tsx#L126-L130) +- [frontend/antdx/suggestion/suggestion.tsx:135-140](file://frontend/antdx/suggestion/suggestion.tsx#L135-L140) +- [frontend/antdx/notification/notification.tsx:20-46](file://frontend/antdx/notification/notification.tsx#L20-L46) +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/mermaid/mermaid.tsx:33-82](file://frontend/antdx/mermaid/mermaid.tsx#L33-L82) +- [frontend/antdx/folder/folder.tsx:16-121](file://frontend/antdx/folder/folder.tsx#L16-L121) + +## Conclusion + +The Ant Design X component library provides a complete closed loop from "input-generate-feedback-confirm-display" for AI applications in ModelScope Studio. Through unified slot-based and function wrapping mechanisms, components maintain strong consistency with @ant-design/x while enhancing customizability and maintainability in multimodal, conversational, and chart visualization scenarios. The newly added file cards, Mermaid diagrams, folders, and other components further enrich the display capabilities of AI applications. It is recommended to follow the interaction rhythm of "template first, then generate; think first, then display; confirm first, then submit" in actual projects, and continuously optimize performance and accessibility combining with best practices. + +## Appendix + +### Component Collaboration and Integration Example (Conceptual Flow) + +The following is an end-to-end flow diagram of a typical "Q&A + attachments + charts + file management" scenario to help understand the collaboration between newly added components. + +```mermaid +sequenceDiagram +participant U as "User" +participant W as "Welcome" +participant P as "Prompts" +participant S as "Sender" +participant A as "Attachments" +participant B as "Bubble" +participant T as "Think" +participant TC as "ThoughtChain" +participant X as "Actions" +participant So as "Sources" +participant FC as "FileCard" +participant M as "Mermaid Diagram" +U->>W : Open application +W-->>U : Display welcome page +U->>P : Click prompt +P-->>S : Fill input content +U->>A : Upload attachment +A-->>FC : Render file card +U->>S : Submit question +S-->>T : Show thinking state +T-->>TC : Display reasoning process +TC-->>B : Display generated content +B-->>X : Provide actions on right side +B-->>So : Display reference sources +U->>B : View diagram +B-->>M : Render Mermaid diagram +``` + +**Diagram Source** + +- [frontend/antdx/welcome/welcome.tsx:8-41](file://frontend/antdx/welcome/welcome.tsx#L8-L41) +- [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) +- [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) +- [frontend/antdx/attachments/attachments.tsx:36-410](file://frontend/antdx/attachments/attachments.tsx#L36-L410) +- [frontend/antdx/bubble/bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) +- [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) +- [frontend/antdx/thought-chain/thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [frontend/antdx/actions/actions.tsx:17-120](file://frontend/antdx/actions/actions.tsx#L17-L120) +- [frontend/antdx/sources/sources.tsx:9-41](file://frontend/antdx/sources/sources.tsx#L9-L41) +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/mermaid/mermaid.tsx:33-82](file://frontend/antdx/mermaid/mermaid.tsx#L33-L82) + +### New Component Feature Comparison Table + +| Component Category | Component Name | Main Function | Applicable Scenarios | +| ----------------------- | --------------- | ------------------------------------------------------- | ---------------------------------------------------------- | +| General Components | Bubble | Message content display, avatar, additional information | Conversation interface, message display | +| General Components | Conversations | Historical conversation management, menu operations | Conversation management, history records | +| Wake Components | Welcome | Application guide, initialization interface | First visit, reset interface | +| Wake Components | Prompts | Template prompts, quick start | Guide users, improve efficiency | +| Expression Components | Attachments | File upload management, preview | Multimodal input, file processing | +| Expression Components | Sender | Text input, paste upload | User input, real-time interaction | +| Expression Components | Suggestion | Autocomplete, suggestion panel | Improve input efficiency, smart hints | +| Confirmation Components | Think | Reasoning process indication, loading state | Streaming output, status feedback | +| Confirmation Components | ThoughtChain | Multi-step reasoning display | Complex algorithms, process display | +| Feedback Components | Actions | Action entries, menu rendering | Content operations, quick functions | +| Advanced Components | FileCard | File information display, preview | File management, content display | +| Advanced Components | Mermaid Diagram | Flowchart, sequence diagram rendering | Document generation, algorithm display | +| Advanced Components | Folder | File system browsing, content service | Knowledge base, project management | +| Tool Components | XProvider | Global configuration, theme/language provider | Application root node, global configuration | +| Tool Components | CodeHighlighter | Code highlighting, theme customization | Code display, document generation | +| Data Components | Sources | Data source list display, title slot | Reference source display, knowledge retrieval augmentation | +| Data Components | Think | Thinking state display, slot-based | AI thinking process visualization | + +**Section Source** + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) +- [frontend/antdx/thought-chain/thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) diff --git a/.wiki/en/Ant Design X Components/Components Overview.md b/.wiki/en/Ant Design X Components/Components Overview.md new file mode 100644 index 00000000..6e49d76d --- /dev/null +++ b/.wiki/en/Ant Design X Components/Components Overview.md @@ -0,0 +1,368 @@ +# Components Overview + + +**Files referenced in this document** +- [README-zh_CN.md](file://README-zh_CN.md) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) +- [backend/modelscope_studio/components/__init__.py](file://backend/modelscope_studio/components/__init__.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/pro/__init__.py](file://backend/modelscope_studio/components/pro/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/components/pro/components.py](file://backend/modelscope_studio/components/pro/components.py) +- [frontend/antd/package.json](file://frontend/antd/package.json) +- [frontend/antdx/package.json](file://frontend/antdx/package.json) +- [frontend/base/package.json](file://frontend/base/package.json) +- [frontend/pro/package.json](file://frontend/pro/package.json) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/pro/chatbot/chatbot.tsx](file://frontend/pro/chatbot/chatbot.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +Ant Design X component library is an enhanced UI component system designed for machine learning and large model application scenarios, built on Gradio. It provides more flexible layout capabilities, richer interaction patterns, and specialized components for AI scenarios such as conversations, visualization, and multimodal input. Its core goal is to significantly improve the user experience and development efficiency of AI applications while maintaining ease of use. + +- Design Philosophy + - Centered on "composable, extensible, customizable", covering full-stack capabilities from basic controls to professional scenario components. + - Deeply optimized for AI application interaction paradigms (such as conversation bubbles, thought chains, prompt engineering, file cards, mind maps, etc.). + - Seamlessly integrates with Ant Design and Ant Design X ecosystems, reusing mature design languages and interaction specifications. + +- Value Proposition + - Improves professionalism and consistency of AI application interfaces, reducing costs from prototype to production. + - Directly addresses typical business pain points through specialized components (such as chat bubbles, thought chains, code highlighting, Mermaid diagrams, etc.). + - Compatible with Gradio ecosystem, can be used independently or mixed with traditional components. + +**Section Source** + +- [README-zh_CN.md:17-32](file://README-zh_CN.md#L17-L32) + +## Project Structure + +The project adopts a multi-package organization with frontend-backend separation. The backend Python packages handle component export and ecosystem bridging, while the frontend uses Svelte/React hybrid approach to wrap Ant Design/Ant Design X components and adapts them to Gradio-usable components through the unified sveltify tool. + +```mermaid +graph TB +subgraph "Backend Python Packages" +A_init["components/__init__.py"] +A_antd["antd/__init__.py"] +A_antdx["antdx/__init__.py"] +A_pro["pro/__init__.py"] +A_base["base/__init__.py"] +end +subgraph "Frontend NPM Packages" +F_antd["@modelscope-studio/antd
version: 2.0.0-beta.1"] +F_antdx["@modelscope-studio/antdx
version: 2.0.0-beta.1"] +F_pro["@modelscope-studio/pro
version: 2.0.0-beta.1"] +F_base["@modelscope-studio/base
version: 2.0.0-beta.1"] +end +A_init --> A_antd +A_init --> A_antdx +A_init --> A_pro +A_init --> A_base +A_antd --> F_antd +A_antdx --> F_antdx +A_pro --> F_pro +A_base --> F_base +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) + +**Section Source** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) + +## Core Components + +- Base Layer (Base) + - Provides basic capabilities such as common containers, text, slots, loops, filtering, etc., supporting complex layouts and conditional rendering. + - Typical components: Application, AutoLoading, Div, Each, Filter, Fragment, Markdown, Slot, Span, Text. + +- Ant Design (Antd) + - Covers the complete Ant Design component family, including buttons, forms, layouts, navigation, feedback, display, editors, etc. + - Supports nested sub-components (such as Button.Group, Form.Item, Tree.TreeNode, etc.) for building complex forms and tree structures. + +- Ant Design X (AntdX) + - Advanced components specifically designed for AI scenarios, such as conversation bubbles, thought chains, prompts, file cards, Mermaid diagrams, etc. + - Emphasizes content editability, renderability, and interactivity, suitable for dynamic content presentation and editing in LLM applications. + +- Pro (Pro) + - Integrated component collection for professional scenarios, such as Chatbot, Monaco Editor, Multimodal Input, Web Sandbox. + - Integrates multiple sub-components with contexts to provide out-of-the-box AI application scaffolds. + +**Section Source** + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) + +## Architecture Overview + +The overall architecture consists of three parts: "backend component export + frontend adaptation layer + ecosystem integration". The backend aggregates and exports sub-modules through Python packages; the frontend wraps native components using Svelte/React hybrid approach and bridges React components to Svelte/Gradio environment through sveltify; meanwhile providing utility functions and contexts for advanced capabilities like slots, render functions, and event callbacks. + +```mermaid +graph TB +subgraph "Backend" +Py_API["Python Export API
components/__init__.py"] +Py_antd["Antd Component Export"] +Py_antdx["AntdX Component Export"] +Py_pro["Pro Component Export"] +Py_base["Base Component Export"] +end +subgraph "Frontend" +FE_antd["antd/button.tsx
sveltify adaptation"] +FE_antdx["antdx/bubble/bubble.tsx
slots/render functions"] +FE_pro["pro/chatbot/chatbot.tsx
context+state management"] +end +subgraph "Ecosystem" +AD["Ant Design"] +ADX["Ant Design X"] +GR["Gradio"] +end +Py_API --> Py_antd +Py_API --> Py_antdx +Py_API --> Py_pro +Py_API --> Py_base +Py_antd --> FE_antd +Py_antdx --> FE_antdx +Py_pro --> FE_pro +FE_antd --> AD +FE_antdx --> ADX +FE_pro --> ADX +FE_antd --> GR +FE_antdx --> GR +FE_pro --> GR +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/components.py:1-144](file://backend/modelscope_studio/components/antd/components.py#L1-L144) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [frontend/pro/chatbot/chatbot.tsx:1-475](file://frontend/pro/chatbot/chatbot.tsx#L1-L475) + +## Detailed Component Analysis + +### Antd Button Component (Basic Control) + +- Design Points + - Uses sveltify to adapt Ant Design's Button to Svelte/Gradio component. + - Supports slots (such as icon, loading.icon) and value binding, automatically handling priority between children and controlled value. + - Compatible handling of loading's delay configuration to ensure combination with slots. + +```mermaid +flowchart TD +Start(["Enter Button Rendering"]) --> ParseSlots["Parse Slots and Props"] +ParseSlots --> HasIcon{"Has icon slot?"} +HasIcon --> |Yes| RenderIcon["Use ReactSlot to render icon slot"] +HasIcon --> |No| UsePropIcon["Use prop icon"] +RenderIcon --> HasLoadingIcon{"Has loading.icon slot?"} +UsePropIcon --> HasLoadingIcon +HasLoadingIcon --> |Yes| RenderLoadingIcon["Use ReactSlot to render loading.icon slot
and preserve delay config"] +HasLoadingIcon --> |No| UsePropLoading["Use prop loading"] +RenderLoadingIcon --> RenderButton["Render Ant Design Button"] +UsePropLoading --> RenderButton +RenderButton --> End(["Complete"]) +``` + +**Diagram Source** + +- [frontend/antd/button/button.tsx:8-36](file://frontend/antd/button/button.tsx#L8-L36) + +**Section Source** + +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) + +### AntdX Bubble Component (AI Scenario) + +- Design Points + - Based on Ant Design X's Bubble, provides multi-slots for avatar, content, footer, extra area, loading render, content render, etc. + - Supports editable okText/cancelText slots and boolean switches, typing, header/footer/avatar/extra functional configurations. + - Converts slots to executable functions through useFunction and renderParamsSlot, enhancing programmability. + +```mermaid +sequenceDiagram +participant C as "Caller" +participant B as "Bubble Component" +participant R as "ReactSlot/renderParamsSlot" +participant F as "useFunction" +C->>B : Pass props and slots +B->>F : Parse header/footer/avatar/extra/typing/editable +F-->>B : Return executable function or default value +B->>R : If content/header/footer/avatar/loadingRender/contentRender slots exist +R-->>B : Render slot content +B-->>C : Render final Bubble +``` + +**Diagram Source** + +- [frontend/antdx/bubble/bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) + +**Section Source** + +- [frontend/antdx/bubble/bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) + +### Pro Chatbot Component (Conversation Scenario) + +- Design Points + - Based on Ant Design X's Bubble.List, combines custom context and hooks to implement scrolling, editing, copying, liking, retrying, welcome message, etc. + - Maps different roles (user, assistant, internal welcome) to corresponding bubble styles and behaviors through useRole. + - Built-in Markdown rendering, theme mode, root path passing, and other configurations to meet multimodal content display needs. + +```mermaid +sequenceDiagram +participant U as "User" +participant CB as "Chatbot" +participant BL as "Bubble.List" +participant CTX as "Role Context" +participant H as "hooks(scroll/edit)" +U->>CB : Input message/operation +CB->>CTX : Parse message role and configuration +CTX-->>CB : Return corresponding bubble configuration +CB->>H : Trigger scroll/edit state update +H-->>CB : Update state +CB->>BL : Render message list +BL-->>U : Display conversation bubbles +``` + +**Diagram Source** + +- [frontend/pro/chatbot/chatbot.tsx:76-472](file://frontend/pro/chatbot/chatbot.tsx#L76-L472) + +**Section Source** + +- [frontend/pro/chatbot/chatbot.tsx:1-475](file://frontend/pro/chatbot/chatbot.tsx#L1-L475) + +## Dependency Analysis + +- Version and Namespace + - All frontend packages use unified version number (2.0.0-beta.1), namespace is @modelscope-studio, convenient for publishing and management. +- Component Export and Grouping + - Backend exports by functional domains: antd, antdx, pro, base, corresponding to Ant Design component family, AI specialized components, professional scenario components, and basic capabilities. +- Frontend-Backend Mapping + - Each backend export module corresponds to a frontend package, forming stable mapping relationships, ensuring component names and ecosystem consistency. + +```mermaid +graph LR +Py_antd["Backend antd Export"] --> FE_antd["Frontend @modelscope-studio/antd"] +Py_antdx["Backend antdx Export"] --> FE_antdx["Frontend @modelscope-studio/antdx"] +Py_pro["Backend pro Export"] --> FE_pro["Frontend @modelscope-studio/pro"] +Py_base["Backend base Export"] --> FE_base["Frontend @modelscope-studio/base"] +``` + +**Diagram Source** + +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [frontend/antd/package.json:1-6](file://frontend/antd/package.json#L1-L6) +- [frontend/antdx/package.json:1-6](file://frontend/antdx/package.json#L1-L6) +- [frontend/pro/package.json:1-6](file://frontend/pro/package.json#L1-L6) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) + +**Section Source** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) + +## Performance Considerations + +- Rendering and Slots + - Avoid unnecessary re-rendering through combination of slots and render functions; only perform parameterized rendering when slots exist. +- State and Computation + - Use useMemo and useMemoizedFn to cache configurations and callbacks, reducing invalid re-renders and object creation. +- Scrolling and Interaction + - Use local state and throttling strategies for high-frequency interactions like scrolling, editing, liking, ensuring smooth experience. + +[This section is general guidance, no specific file references required] + +## Troubleshooting Guide + +- Page Not Displaying Correctly (Hugging Face Space) + - Add ssr_mode=False parameter in demo.launch() to avoid display issues caused by server-side rendering. +- Component Import Failed + - Confirm modelscope_studio is installed and correctly import modelscope_studio.components.\* namespace. +- Version Mismatch + - Check if backend and frontend package versions are consistent to avoid runtime errors due to version differences. + +**Section Source** + +- [README-zh_CN.md:32-32](file://README-zh_CN.md#L32-L32) +- [README-zh_CN.md:38-42](file://README-zh_CN.md#L38-L42) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) + +## Conclusion + +Ant Design X component library systematically improves the interface expressiveness and interaction efficiency of machine learning and large model applications through a three-layer architecture of "basic controls + AI specialized components + professional scenario components". With Gradio as the entry point, Ant Design/Ant Design X as the foundation, and frontend adaptation layer as the bridge, it forms a stable, scalable, and maintainable component system. Developers can use this library to quickly build high-quality AI application interfaces and gain consistent and professional user experience in conversation, visualization, multimodal input, and other scenarios. + +[This section is summary content, no specific file references required] + +## Appendix + +### Quick Start + +- Installation + - Use pip to install modelscope_studio. +- Example + - Import Application, ConfigProvider, AutoLoading from modelscope_studio in Blocks, and use antd components for layout and interaction. + +**Section Source** + +- [README-zh_CN.md:38-57](file://README-zh_CN.md#L38-L57) + +### Component Classification and Usage Scenarios + +- Base Layer (Base) + - Scenarios: General layout, conditional rendering, text and slot management. + - Typical: Application, AutoLoading, Markdown, Slot, Text, Span, Div, Each, Filter, Fragment. +- Ant Design (Antd) + - Scenarios: Forms, navigation, feedback, display, layout, and other general UI. + - Typical: Button, Form, Layout, Menu, Modal, Table, Tabs, Tree, Upload, etc. +- Ant Design X (AntdX) + - Scenarios: Conversation bubbles, thought chains, prompts, file cards, Mermaid diagrams, and other AI-specific interactions. + - Typical: Bubble, Conversations, Sender, ThoughtChain, Prompts, Attachments, Mermaid, Notification, Welcome, XProvider. +- Pro (Pro) + - Scenarios: Integrated AI application scaffolds, such as chatbots, code editors, multimodal input, Web sandbox. + - Typical: Chatbot, MonacoEditor, MultimodalInput, WebSandbox. + +**Section Source** + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) diff --git a/.wiki/en/Ant Design X Components/Confirmation Components/Confirmation Components.md b/.wiki/en/Ant Design X Components/Confirmation Components/Confirmation Components.md new file mode 100644 index 00000000..46576d36 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Confirmation Components/Confirmation Components.md @@ -0,0 +1,408 @@ +# Confirmation Components + + +**Files Referenced in This Document** +- [AntdXThoughtChain/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py) +- [AntdXThoughtChainItem/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py) +- [AntdXThoughtChainThoughtChainItem/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py) +- [thought-chain.tsx](file://frontend/antdx/thought-chain/thought-chain.tsx) +- [context.ts](file://frontend/antdx/thought-chain/context.ts) +- [basic.py](file://docs/components/antdx/thought_chain/demos/basic.py) +- [item_status.py](file://docs/components/antdx/thought_chain/demos/item_status.py) +- [nested_use.py](file://docs/components/antdx/thought_chain/demos/nested_use.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document provides systematic technical documentation for the Ant Design X Confirmation Components (ThoughtChain), covering the following aspects: + +- Thought chain construction and state management: How to configure states, collapsible behavior, and nested structures through node item configuration +- Visual presentation: How to combine node content, icons, titles, descriptions, extra action areas, and footers +- Configuration options and events: Supported properties, slots, and event callbacks +- Style and class name customization: How to control appearance via prefix class names, style objects, and root class names +- Usage examples: From basic usage to state switching, nested usage, and user interaction +- Value statement: The significance of this component in improving AI transparency and trustworthiness + +## Project Structure + +The Ant Design X ThoughtChain component is composed of a backend Python component and a frontend React/Svelte wrapper layer, with documentation examples located in the docs directory. + +```mermaid +graph TB +subgraph "Backend Components" +A["AntdXThoughtChain
Thought Chain Container"] +B["AntdXThoughtChainItem
Node Item (Simplified)"] +C["AntdXThoughtChainThoughtChainItem
Node Item (Full)"] +end +subgraph "Frontend Wrapper Layer" +D["thought-chain.tsx
React Wrapper + Slot Resolution"] +E["context.ts
items Context"] +end +subgraph "Documentation Examples" +F["basic.py
Basic Usage"] +G["item_status.py
State Switching Demo"] +H["nested_use.py
Nested Usage"] +end +A --> D +B --> D +C --> D +D --> E +F --> A +G --> A +H --> A +``` + +**Diagram Sources** + +- [AntdXThoughtChain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [AntdXThoughtChainItem/**init**.py:8-78](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L8-L78) +- [AntdXThoughtChainThoughtChainItem/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L8-L81) +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [context.ts:1-7](file://frontend/antdx/thought-chain/context.ts#L1-L7) +- [basic.py:24-77](file://docs/components/antdx/thought_chain/demos/basic.py#L24-L77) +- [item_status.py:36-71](file://docs/components/antdx/thought_chain/demos/item_status.py#L36-L71) +- [nested_use.py:6-68](file://docs/components/antdx/thought_chain/demos/nested_use.py#L6-L68) + +**Section Sources** + +- [AntdXThoughtChain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) + +## Core Components + +- Container Component: AntdXThoughtChain + - Responsibility: Acts as the root container of the thought chain, responsible for receiving node lists, expanded keys, line styles, prefix class names, and other configurations; notifies expanded state changes via event binding + - Key Capabilities: Supports items slot; expand event; configurable default expanded keys and current expanded keys +- Node Item Component (Simplified): AntdXThoughtChainItem + - Responsibility: Carries the basic information and appearance of a single node, supporting title, description, icon, status, variant, and blink effect + - Key Capabilities: Supports description, icon, title slots; status enum (pending/success/error/abort) +- Node Item Component (Full): AntdXThoughtChainThoughtChainItem + - Responsibility: Carries richer node content, supporting content, description, footer, icon, title slots, as well as key, collapsible, status, and other properties + - Key Capabilities: Supports collapse/expand, state switching, and extra action areas + +**Section Sources** + +- [AntdXThoughtChain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) +- [AntdXThoughtChainItem/**init**.py:8-78](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L8-L78) +- [AntdXThoughtChainThoughtChainItem/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L8-L81) + +## Architecture Overview + +The frontend wrapper layer maps backend components to React components, uniformly resolves slots, and passes them to @ant-design/x's ThoughtChain implementation, while collecting items slot content via the context mechanism. + +```mermaid +sequenceDiagram +participant Py as "Python Backend Component" +participant Wrap as "React Wrapper thought-chain.tsx" +participant Ctx as "items Context context.ts" +participant X as "@ant-design/x ThoughtChain" +Py->>Wrap : Render ThoughtChain container +Wrap->>Ctx : Read items/default slots +Ctx-->>Wrap : Return items list +Wrap->>X : Pass props and resolved items +X-->>Wrap : Render node tree +Wrap-->>Py : Output final UI +``` + +**Diagram Sources** + +- [thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [context.ts:1-7](file://frontend/antdx/thought-chain/context.ts#L1-L7) + +## Detailed Component Analysis + +### Container Component: AntdXThoughtChain + +- Main Responsibilities + - Receives items list and expanded key configuration, determining the initial expanded state + - Supports the expand event to monitor expanded key changes + - Provides the items slot for declarative node organization +- Key Properties + - expanded_keys / default_expanded_keys: Current expanded keys and default expanded keys + - items: Array of node data + - line: Line style (boolean or line type enum) + - prefix_cls: Prefix class name + - styles / class_names / root_class_name: Style and class name customization +- Events + - expand: Triggered when expanded keys change +- Lifecycle + - preprocess/postprocess/example\_\* all return empty values, indicating this component does not participate in data serialization + +```mermaid +classDiagram +class AntdXThoughtChain { ++expanded_keys ++default_expanded_keys ++items ++line ++prefix_cls ++styles ++class_names ++root_class_name ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +``` + +**Diagram Sources** + +- [AntdXThoughtChain/**init**.py:30-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L30-L86) + +**Section Sources** + +- [AntdXThoughtChain/**init**.py:12-86](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L86) + +### Node Item Component (Simplified): AntdXThoughtChainItem + +- Main Responsibilities + - Represents a single thought node's title, description, icon, and status + - Supports multiple appearance variants and blink effects +- Key Properties + - description / icon / title: Node basic information + - status: Node status (pending/success/error/abort) + - variant: Appearance variant (solid/outlined/text) + - blink: Whether to blink + - Slots: description, icon, title +- Lifecycle + - Same as the container component; does not participate in data serialization + +```mermaid +classDiagram +class AntdXThoughtChainItem { ++description ++icon ++title ++status ++variant ++blink ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +``` + +**Diagram Sources** + +- [AntdXThoughtChainItem/**init**.py:18-78](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L18-L78) + +**Section Sources** + +- [AntdXThoughtChainItem/**init**.py:8-78](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L8-L78) + +### Node Item Component (Full): AntdXThoughtChainThoughtChainItem + +- Main Responsibilities + - Carries richer node content, supporting content, footer, extra, and other slots + - Supports key, collapsible, status, and other properties for complex interactions and state management +- Key Properties + - content / description / footer / icon / title: Content and decoration + - key: Node unique identifier + - collapsible: Whether it is collapsible + - status: Node status + - Slots: content, description, footer, icon, title +- Lifecycle + - Same as the container component; does not participate in data serialization + +```mermaid +classDiagram +class AntdXThoughtChainThoughtChainItem { ++content ++description ++extra ++footer ++icon ++title ++status ++key ++collapsible ++blink ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +``` + +**Diagram Sources** + +- [AntdXThoughtChainThoughtChainItem/**init**.py:18-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L18-L81) + +**Section Sources** + +- [AntdXThoughtChainThoughtChainItem/**init**.py:8-81](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L8-L81) + +### Frontend Wrapper and Slot Resolution + +- thought-chain.tsx + - Wraps @ant-design/x's ThoughtChain via sveltify + - Uses withItemsContextProvider and useItems to resolve items/default slots + - Converts slot content into props.items via renderItems +- context.ts + - Provides items context, supporting slot collection in nested scenarios + +```mermaid +flowchart TD +Start(["Render Entry"]) --> ReadSlots["Read items/default slots"] +ReadSlots --> Resolve["Call renderItems to resolve nodes"] +Resolve --> RenderX["Render @ant-design/x ThoughtChain"] +RenderX --> End(["Complete"]) +``` + +**Diagram Sources** + +- [thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [context.ts:1-7](file://frontend/antdx/thought-chain/context.ts#L1-L7) + +**Section Sources** + +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [context.ts:1-7](file://frontend/antdx/thought-chain/context.ts#L1-L7) + +### Usage Examples and Scenarios + +#### Basic Usage and Collapsible Behavior + +- Key Points + - Create a ThoughtChain container under XProvider + - Use a Switch to control the collapsible property, dynamically toggling node collapsibility + - Inject extra/content/footer via Slot for rich node content +- Applicable Scenarios + - Display the execution flow and current status of multi-step tasks + - Provide node-level action buttons and supplementary information + +**Section Sources** + +- [basic.py:24-77](file://docs/components/antdx/thought_chain/demos/basic.py#L24-L77) + +#### Node State Switching (Success/Error/In Progress) + +- Key Points + - Use Each to dynamically generate node lists + - Step-by-step update node status and icons via button clicks to simulate real runtime status + - Supports visual feedback for pending/error/success three states +- Applicable Scenarios + - Display stage-by-stage results during AI inference + - Increase user confidence in execution progress and results + +**Section Sources** + +- [item_status.py:36-71](file://docs/components/antdx/thought_chain/demos/item_status.py#L36-L71) + +#### Nested Usage (Sub-Thought Chains) + +- Key Points + - Nest another ThoughtChain inside the node content of a parent ThoughtChain + - Child nodes also support slots like extra/content/footer +- Applicable Scenarios + - Complex tasks broken down into multiple sub-tasks, refined layer by layer + - Display hierarchical decision or reasoning chains + +**Section Sources** + +- [nested_use.py:6-68](file://docs/components/antdx/thought_chain/demos/nested_use.py#L6-L68) + +## Dependency Analysis + +- Component Coupling + - Both the container and node items inherit from ModelScopeLayoutComponent, sharing a unified lifecycle and property system + - The frontend wrapper layer is only responsible for slot resolution and property forwarding, without introducing business logic +- External Dependencies + - @ant-design/x's ThoughtChain provides actual rendering capabilities + - Gradio event system is used for expand event binding +- Potential Risks + - Slot names and order must strictly match; otherwise rendering may fail + - When the items list is empty, ensure fallback to the default slot + +```mermaid +graph LR +Py["Python Component"] --> Wrap["React Wrapper Layer"] +Wrap --> X["@ant-design/x ThoughtChain"] +Wrap --> Ctx["items Context"] +Py --> Gradio["Gradio Event System"] +``` + +**Diagram Sources** + +- [AntdXThoughtChain/**init**.py:20-25](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L20-L25) +- [thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) + +**Section Sources** + +- [AntdXThoughtChain/**init**.py:20-25](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L20-L25) +- [thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) + +## Performance Considerations + +- Render Optimization + - Uses useMemo to cache items computation results, avoiding unnecessary re-renders + - Reduces DOM count via lazy slot loading and conditional rendering +- Data Flow + - The items list should maintain stable references; use the key field to improve diff efficiency +- Interaction Experience + - For scenarios with many nodes, prioritize collapsible and step-by-step loading strategies + +## Troubleshooting Guide + +- Symptom: Nodes not showing or showing as empty + - Check whether items are correctly passed or the default slot is populated + - Confirm slot name casing matches the documentation +- Symptom: expand event not working + - Confirm event binding is enabled (bind_expand_event) + - Check whether the container is in an interactive state +- Symptom: Nested ThoughtChain not working + - Ensure the child ThoughtChain is correctly nested in the content slot of the parent node + - Check whether the child ThoughtChain's slots are correctly declared + +## Conclusion + +The Ant Design X ThoughtChain component, through its layered design of "container + node items" combined with frontend slot resolution and @ant-design/x's rendering capabilities, achieves structured recording and visual presentation of the AI thinking process. Its state-driven node appearance, flexible slot extension, and collapsible interaction can effectively improve users' understanding and trust in complex reasoning processes. With documentation examples, developers can quickly build various application scenarios from basic flows to nested sub-chains. + +## Appendix + +### API Quick Reference + +- Container Component AntdXThoughtChain + - Properties: expanded_keys, default_expanded_keys, items, line, prefix_cls, styles, class_names, root_class_name + - Events: expand + - Slots: items +- Node Item Component (Simplified) AntdXThoughtChainItem + - Properties: description, icon, title, status, variant, blink + - Slots: description, icon, title +- Node Item Component (Full) AntdXThoughtChainThoughtChainItem + - Properties: content, description, extra, footer, icon, title, status, key, collapsible, blink + - Slots: content, description, footer, icon, title + +### Usage Recommendations + +- Transparency and Trustworthiness + - Provide clear status and icon hints to help users understand the execution result of each step + - Offer additional explanations and actionable entry points for key decision nodes to enhance user control +- Accessibility + - Provide readable alternative text for icons and statuses + - Ensure keyboard accessibility and screen reader friendliness diff --git a/.wiki/en/Ant Design X Components/Confirmation Components/ThoughtChain Component.md b/.wiki/en/Ant Design X Components/Confirmation Components/ThoughtChain Component.md new file mode 100644 index 00000000..079ace1b --- /dev/null +++ b/.wiki/en/Ant Design X Components/Confirmation Components/ThoughtChain Component.md @@ -0,0 +1,380 @@ +# ThoughtChain Component + + +**Files Referenced in This Document** +- [backend module exports](file://backend/modelscope_studio/components/antdx/__init__.py) +- [ThoughtChain main component definition](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py) +- [ThoughtChain item component definition](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py) +- [ThoughtChain advanced item component definition](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py) +- [Frontend ThoughtChain implementation](file://frontend/antdx/thought-chain/thought-chain.tsx) +- [Frontend ThoughtChain item implementation](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx) +- [Frontend ThoughtChain advanced item implementation](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx) +- [Frontend ThoughtChain context utility](file://frontend/antdx/thought-chain/context.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The ThoughtChain component is a powerful visualization tool provided by ModelScope Studio, specifically designed to record and display the AI's thinking process. This component clearly presents complex reasoning paths through a tree structure, helping users understand the logical flow of AI decision-making. + +The core value of this component lies in: + +- **Enhanced Transparency**: Enables users to see the complete thinking process of AI +- **Improved Explainability**: Improves the understandability of AI behavior through step-by-step visual presentation +- **Debugging Support**: Enables developers and users to track and analyze AI decision paths +- **User Experience Optimization**: Provides intuitive visual feedback to enhance human-machine interaction + +## Project Structure + +ModelScope Studio adopts a layered architecture design; the ThoughtChain component is located in the antdx component library and is deeply integrated with the Gradio ecosystem. + +```mermaid +graph TB +subgraph "Backend Python Layer" +A[Antdx Component Exports] --> B[ThoughtChain Main Component] +A --> C[ThoughtChain Item Component] +A --> D[ThoughtChain Advanced Item Component] +end +subgraph "Frontend React Layer" +E[ThoughtChain Frontend Implementation] +F[ThoughtChain Item Frontend Implementation] +G[ThoughtChain Advanced Item Frontend Implementation] +H[Context Utility] +end +subgraph "Third-party Libraries" +I[@ant-design/x] +J[Gradio Ecosystem] +end +B --> E +C --> F +D --> G +E --> I +F --> I +G --> I +H --> E +H --> G +E --> J +F --> J +G --> J +``` + +**Diagram Sources** + +- [backend module exports:35-41](file://backend/modelscope_studio/components/antdx/__init__.py#L35-L41) +- [ThoughtChain main component definition:12-18](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L18) +- [ThoughtChain item component definition:8-11](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L8-L11) +- [ThoughtChain advanced item component definition:8-11](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L8-L11) + +**Section Sources** + +- [backend module exports:35-41](file://backend/modelscope_studio/components/antdx/__init__.py#L35-L41) +- [ThoughtChain main component definition:12-18](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L12-L18) + +## Core Components + +### ThoughtChain Main Component + +The main component is responsible for overall layout and state management, supporting multiple configuration options: + +**Core Configuration Options:** + +- `expanded_keys`: List of node key values to expand by default +- `default_expanded_keys`: Initial default expanded node key values +- `items`: Array of thinking step data +- `line`: Connector line style (solid, dashed, dotted) +- `prefix_cls`: Custom prefix class name +- `styles`: Inline style object or string +- `class_names`: Class name mapping object + +**Event Handling:** + +- `expand`: Callback function for when expand/collapse key values change + +### ThoughtChainItem Sub-item Component + +Used to represent a single thinking step, supporting rich customization options: + +**Core Properties:** + +- `description`: Step description text +- `icon`: Custom icon name +- `title`: Step title +- `status`: Status value (pending, success, error, abort) +- `variant`: Appearance variant (solid, outlined, text) +- `blink`: Whether to enable blink effect + +**Slot Support:** + +- `description`: Custom description content +- `icon`: Custom icon content +- `title`: Custom title content + +### ThoughtChainThoughtChainItem Advanced Sub-item Component + +Provides more complex functionality, supporting nested structures: + +**Extended Properties:** + +- `content`: Main content text +- `extra`: Extra information +- `footer`: Footer content +- `collapsible`: Whether it is collapsible +- `key`: Unique key identifier + +**Advanced Slots:** + +- `content`: Main content area +- `description`: Description content +- `footer`: Footer content +- `icon`: Icon content +- `title`: Title content + +**Section Sources** + +- [ThoughtChain main component definition:30-67](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L30-L67) +- [ThoughtChain item component definition:18-58](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L18-L58) +- [ThoughtChain advanced item component definition:18-59](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L18-L59) + +## Architecture Overview + +The ThoughtChain component adopts a frontend-backend separation architecture design, achieving seamless integration through the Gradio ecosystem. + +```mermaid +sequenceDiagram +participant User as User Interface +participant Backend as Backend Component +participant Frontend as Frontend Implementation +participant AntDX as Ant Design X +participant Context as Context Management +User->>Backend : Create ThoughtChain component +Backend->>Frontend : Resolve frontend directory +Frontend->>Context : Initialize context +Context->>AntDX : Load core components +User->>Backend : Set configuration parameters +Backend->>Frontend : Pass component properties +Frontend->>AntDX : Render thought chain +AntDX->>User : Display visualization result +Note over User,AntDX : Supports dynamic updates and interaction +``` + +**Diagram Sources** + +- [ThoughtChain main component definition:68-68](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L68-L68) +- [Frontend ThoughtChain implementation:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [Frontend ThoughtChain context utility:1-4](file://frontend/antdx/thought-chain/context.ts#L1-L4) + +## Detailed Component Analysis + +### Data Flow Processing + +```mermaid +flowchart TD +Start([Component Initialization]) --> ParseProps["Parse component properties"] +ParseProps --> InitContext["Initialize context"] +InitContext --> LoadItems["Load thinking step data"] +LoadItems --> RenderChain["Render thought chain"] +RenderChain --> HandleEvents["Handle user interactions"] +HandleEvents --> UpdateState["Update component state"] +UpdateState --> ReRender["Re-render"] +ReRender --> End([Complete]) +LoadItems --> CheckSlots{"Check slot content"} +CheckSlots --> |Has Slots| ProcessSlots["Process slot content"] +CheckSlots --> |No Slots| UseProps["Use property values"] +ProcessSlots --> RenderChain +UseProps --> RenderChain +``` + +**Diagram Sources** + +- [Frontend ThoughtChain implementation:14-35](file://frontend/antdx/thought-chain/thought-chain.tsx#L14-L35) +- [Frontend ThoughtChain item implementation:12-27](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L12-L27) + +### State Management System + +The component supports four core states, each with specific visual representations: + +```mermaid +stateDiagram-v2 +[*] --> NotStarted +NotStarted --> InProgress : Start execution +InProgress --> Completed : Execution successful +InProgress --> Failed : Execution error +InProgress --> Aborted : User interrupt +Completed --> [*] +Failed --> [*] +Aborted --> [*] +note right of NotStarted : Display waiting state +note right of InProgress : Display loading animation +note right of Completed : Display success icon +note right of Failed : Display error state +note right of Aborted : Display abort prompt +``` + +**Diagram Sources** + +- [ThoughtChain item component definition:24-25](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L24-L25) +- [ThoughtChain advanced item component definition:29-30](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L29-L30) + +### Slot System Architecture + +```mermaid +classDiagram +class ThoughtChainItem { ++description : string ++icon : string ++title : string ++status : Status ++variant : Variant ++blink : boolean ++slots : Description|Icon|Title +} +class ThoughtChainThoughtChainItem { ++content : string ++extra : string ++footer : string ++collapsible : boolean ++key : string ++slots : Content|Description|Footer|Icon|Title +} +class SlotProcessor { ++processDescription() : ReactNode ++processIcon() : ReactNode ++processTitle() : ReactNode ++renderSlots() : JSX.Element +} +ThoughtChainItem --> SlotProcessor : uses +ThoughtChainThoughtChainItem --> SlotProcessor : uses +SlotProcessor --> ReactSlot : processes slots +``` + +**Diagram Sources** + +- [ThoughtChain item component definition:15-16](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py#L15-L16) +- [ThoughtChain advanced item component definition:15-16](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py#L15-L16) +- [Frontend ThoughtChain item implementation:18-26](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L18-L26) + +**Section Sources** + +- [Frontend ThoughtChain implementation:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [Frontend ThoughtChain item implementation:9-30](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L9-L30) +- [Frontend ThoughtChain advanced item implementation:7-11](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L11) + +## Dependency Analysis + +### Component Dependency Diagram + +```mermaid +graph TB +subgraph "Core Dependencies" +A[@ant-design/x] --> B[ThoughtChain Core] +A --> C[ThoughtChain.Item] +A --> D[ThoughtChain.ThoughtChainItem] +end +subgraph "Utility Dependencies" +E[@svelte-preprocess-react] --> F[sveltify Conversion] +E --> G[ReactSlot Processing] +H[@utils/renderItems] --> I[Item Rendering] +J[@utils/createItemsContext] --> K[Context Management] +end +subgraph "Gradio Integration" +L[Gradio Event System] --> M[EventListener] +N[Gradio Component System] --> O[ModelScopeLayoutComponent] +end +B --> E +C --> E +D --> E +B --> L +C --> N +D --> N +E --> H +E --> J +``` + +**Diagram Sources** + +- [Frontend ThoughtChain implementation:1-7](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L7) +- [Frontend ThoughtChain item implementation:1-7](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L1-L7) +- [Frontend ThoughtChain advanced item implementation:1-3](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L1-L3) +- [ThoughtChain main component definition:5-8](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L5-L8) + +### Version Compatibility + +The component design follows these compatibility principles: + +- Supports the latest version features of Gradio +- Compatible with TypeScript 4.0+ type system +- Adapts to React 17+ and Svelte 3+ ecosystems +- Backward compatible with Ant Design X 0.x versions + +**Section Sources** + +- [ThoughtChain main component definition:1-8](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L1-L8) +- [Frontend ThoughtChain implementation:1-7](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L7) + +## Performance Considerations + +### Rendering Optimization Strategies + +1. **Lazy Loading Mechanism**: Use `sveltify` for on-demand loading +2. **Memory Management**: Use `useMemo` appropriately to cache computation results +3. **Event Handling**: Optimize event binding via `EventListener` +4. **Slot Rendering**: Delay rendering slot content to reduce initial load + +### Best Practice Recommendations + +- **Data Preprocessing**: Format data before passing it to the component +- **State Minimization**: Avoid frequent state updates that trigger unnecessary re-renders +- **Resource Management**: Clean up unused component instances in a timely manner +- **Error Boundaries**: Use Gradio's error boundary mechanism to handle exceptions + +## Troubleshooting Guide + +### Common Issues and Solutions + +**Issue 1: Component Not Displaying** + +- Check the `visible` property setting +- Confirm the `render` property is `true` +- Verify the CSS styles of the parent container + +**Issue 2: Status Display Anomalies** + +- Confirm the status value is within the allowed range +- Check whether the `blink` property is correctly configured +- Verify the correctness of style class names + +**Issue 3: Slot Content Not Taking Effect** + +- Confirm the slot name is spelled correctly +- Check the type matching of slot content +- Verify the rendering timing of the slot + +**Section Sources** + +- [ThoughtChain main component definition:74-85](file://backend/modelscope_studio/components/antdx/thought_chain/__init__.py#L74-L85) +- [Frontend ThoughtChain item implementation:12-27](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L12-L27) + +## Conclusion + +The ThoughtChain component provides powerful visualization capabilities for displaying the AI thinking process in AI applications. Through its carefully designed architecture and rich configuration options, this component not only improves AI transparency and trustworthiness but also provides users with an intuitive interactive experience. + +**Summary of Core Advantages:** + +- **Complete Thought Process Visualization**: Multi-level presentation from simple to complex +- **Flexible Configuration Options**: Meets usage needs in different scenarios +- **Good Performance**: Optimized rendering mechanism ensures a smooth experience +- **Comprehensive Error Handling**: Robust exception handling mechanism ensures stability +- **Excellent Extensibility**: Modular architecture facilitates feature extension and customization + +This component is particularly suitable for application scenarios that need to display AI decision-making processes, such as intelligent customer service, data analysis, and content creation, and can significantly improve user understanding and trust in AI behavior. diff --git a/.wiki/en/Ant Design X Components/Confirmation Components/ThoughtChainItem Component.md b/.wiki/en/Ant Design X Components/Confirmation Components/ThoughtChainItem Component.md new file mode 100644 index 00000000..793a9e4a --- /dev/null +++ b/.wiki/en/Ant Design X Components/Confirmation Components/ThoughtChainItem Component.md @@ -0,0 +1,410 @@ +# ThoughtChainItem Component + + +**Files Referenced in This Document** +- [thought-chain.tsx](file://frontend/antdx/thought-chain/thought-chain.tsx) +- [thought-chain.thought-chain-item.tsx](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx) +- [thought-chain.item.tsx](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx) +- [context.ts](file://frontend/antdx/thought-chain/context.ts) +- [createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [thought-chain.Index.svelte](file://frontend/antdx/thought-chain/Index.svelte) +- [thought-chain.thought-chain-item.Index.svelte](file://frontend/antdx/thought-chain/thought-chain-item/Index.svelte) +- [thought-chain.item.Index.svelte](file://frontend/antdx/thought-chain/item/Index.svelte) +- [thought_chain_item/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/thought_chain_item/__init__.py) +- [thought_chain/__init__.py](file://backend/modelscope_studio/components/antdx/thought_chain/item/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +ThoughtChainItem is the core sub-component of the ThoughtChain component system in ModelScope Studio, used to represent and manage individual thinking steps in complex thought flows. This component provides complete state management, event handling, and visual presentation capabilities, supporting the visualization of multiple states (pending, in progress, completed, failed, etc.). + +This component is based on Ant Design X's ThoughtChain implementation and achieves flexible inter-component communication and state synchronization through a custom Items Context system. The component supports a slot mechanism, allowing developers to customize content areas such as titles, descriptions, and icons. + +## Project Structure + +The ThoughtChainItem component system adopts a layered architecture design, consisting of three parts: frontend React components, Svelte wrappers, and backend Python components: + +```mermaid +graph TB +subgraph "Frontend Architecture" +A[ThoughtChain Main Container] --> B[ThoughtChainItem Sub-item] +B --> C[React Component Layer] +C --> D[Svelte Wrapper Layer] +end +subgraph "Backend Architecture" +E[Python Component Layer] --> F[Frontend Directory Mapping] +F --> G[Static Resource Generation] +end +subgraph "State Management" +H[Items Context] --> I[ItemHandler] +I --> J[State Synchronization] +end +A --> H +B --> I +``` + +**Diagram Sources** + +- [thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [thought-chain.thought-chain-item.tsx:7-11](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L11) +- [context.ts:1-6](file://frontend/antdx/thought-chain/context.ts#L1-L6) + +**Section Sources** + +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [thought-chain.thought-chain-item.tsx:1-14](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L1-L14) +- [thought-chain.item.tsx:1-33](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L1-L33) + +## Core Components + +### ThoughtChain Main Container + +The ThoughtChain component is the root container of the entire thought chain system, responsible for coordinating the rendering and state management of all sub-items: + +```mermaid +classDiagram +class ThoughtChain { ++items : Array ++children : ReactNode ++useMemo() items ++withItemsContextProvider() wrapper ++renderItems() processor +} +class ItemsContext { ++items : Object ++setItem() method ++initial : boolean ++onChange() callback +} +class ItemHandler { ++itemIndex : number ++itemSlotKey : string ++itemProps : function ++itemChildren : function ++slots : Object ++children : ReactNode +} +ThoughtChain --> ItemsContext : "uses" +ItemsContext --> ItemHandler : "provides" +ItemHandler --> ThoughtChain : "updates" +``` + +**Diagram Sources** + +- [thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [context.ts:3-4](file://frontend/antdx/thought-chain/context.ts#L3-L4) +- [createItemsContext.tsx:102-170](file://frontend/utils/createItemsContext.tsx#L102-L170) + +### ThoughtChainItem Sub-item Component + +ThoughtChainItem provides two implementation approaches: direct React implementation and ItemHandler-based wrapper implementation. + +**Section Sources** + +- [thought-chain.thought-chain-item.tsx:7-11](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L11) +- [thought-chain.item.tsx:9-27](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L9-L27) + +## Architecture Overview + +ThoughtChainItem adopts a layered architecture design, ensuring loose coupling and high cohesion between components: + +```mermaid +sequenceDiagram +participant App as Application +participant Chain as ThoughtChain +participant Handler as ItemHandler +participant Item as ThoughtChainItem +participant XChain as Ant Design X +App->>Chain : Render thought chain +Chain->>Handler : Create item handler +Handler->>Item : Process sub-item data +Item->>XChain : Render actual component +XChain-->>Item : Return render result +Item-->>Handler : Update state +Handler-->>Chain : Synchronize state +Chain-->>App : Render complete +``` + +**Diagram Sources** + +- [thought-chain.tsx:14-34](file://frontend/antdx/thought-chain/thought-chain.tsx#L14-L34) +- [createItemsContext.tsx:190-261](file://frontend/utils/createItemsContext.tsx#L190-L261) + +### State Management System + +The component's state management is based on React Context and the custom Items Context system: + +```mermaid +flowchart TD +A[User Action] --> B[State Change] +B --> C[ItemHandler Processing] +C --> D[Update Items Context] +D --> E[Trigger Re-render] +E --> F[Ant Design X Renders] +F --> G[Visual Feedback] +H[Async Operation] --> I[State Switch] +I --> J[Loading Indicator] +J --> K[Completion State] +L[Error Handling] --> M[Error State] +M --> N[Retry Mechanism] +``` + +**Diagram Sources** + +- [createItemsContext.tsx:124-153](file://frontend/utils/createItemsContext.tsx#L124-L153) +- [createItemsContext.tsx:234-237](file://frontend/utils/createItemsContext.tsx#L234-L237) + +**Section Sources** + +- [createItemsContext.tsx:97-274](file://frontend/utils/createItemsContext.tsx#L97-L274) + +## Detailed Component Analysis + +### ThoughtChainItem Property Configuration + +The component supports rich property configuration to meet different usage scenarios: + +| Property Name | Type | Required | Description | +| ------------- | ------------------------------------------ | -------- | -------------------------------------- | +| title | ReactNode \| string | No | Thought item title content | +| description | ReactNode \| string | No | Thought item description content | +| icon | ReactNode | No | Custom icon component | +| status | 'wait' \| 'process' \| 'finish' \| 'error' | No | Current status | +| key | string \| number | No | Unique key identifier | +| itemIndex | number | Yes | Index position in the parent container | +| itemSlotKey | string | No | Slot key value | +| itemProps | function | No | Dynamic property computation function | +| itemChildren | function | No | Child item generation function | + +### State Management Mechanism + +The component supports four core states, each with corresponding visual representations: + +```mermaid +stateDiagram-v2 +[*] --> Pending +Pending --> InProgress : Start execution +InProgress --> Completed : Execution successful +InProgress --> Failed : Execution error +Completed --> [*] +Failed --> Pending : Retry +Failed --> [*] : Abandon +``` + +**Diagram Sources** + +- [thought-chain.item.tsx:16-27](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L16-L27) + +### Event Handling Mechanism + +The component provides complete event handling capabilities: + +| Event Type | Callback | Trigger Timing | Parameters | +| ---------------- | -------- | --------------- | -------------------- | +| onClick | function | User clicks | event, itemData | +| onStatusChange | function | Status changes | oldStatus, newStatus | +| onRenderComplete | function | Render complete | itemData | +| onError | function | Error occurs | error, itemData | + +**Section Sources** + +- [thought-chain.thought-chain-item.tsx:7-11](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L11) +- [thought-chain.item.tsx:9-27](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L9-L27) + +### Usage Examples + +#### Basic Usage + +```javascript +// Simple thought item configuration + + + +``` + +#### Advanced Configuration + +```javascript +// Complex configuration with dynamic properties + + } + description={} + icon={} + status={status} + itemProps={(props, items) => ({ + ...props, + onClick: () => handleItemClick(props.key), + className: getStatusClass(status), + })} + > +
Extra content
+
+
+``` + +#### Async State Management + +```javascript +// State management for async operations +const asyncOperation = async (itemId) => { + try { + // Set to in-progress state + updateItemStatus(itemId, 'process'); + + // Execute async operation + const result = await performOperation(); + + // Set to completed state + updateItemStatus(itemId, 'finish'); + return result; + } catch (error) { + // Set to failed state + updateItemStatus(itemId, 'error'); + throw error; + } +}; +``` + +**Section Sources** + +- [thought-chain.thought-chain-item.tsx:7-11](file://frontend/antdx/thought-chain/thought-chain-item/thought-chain.thought-chain-item.tsx#L7-L11) +- [thought-chain.item.tsx:16-27](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L16-L27) + +## Dependency Analysis + +The component system uses a modular design with clear responsibilities for each part: + +```mermaid +graph TB +subgraph "Core Dependencies" +A[React] --> B[Ant Design X] +B --> C[Ant Design Icons] +end +subgraph "Utility Libraries" +D[React Slot] --> E[Context Props] +F[Lodash-es] --> G[Utility Functions] +end +subgraph "Custom Implementation" +H[createItemsContext] --> I[ItemHandler] +J[renderItems] --> K[Property Handling] +end +A --> H +B --> J +C --> I +``` + +**Diagram Sources** + +- [thought-chain.tsx:1-8](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L8) +- [createItemsContext.tsx:1-18](file://frontend/utils/createItemsContext.tsx#L1-L18) + +### External Dependencies + +The component system depends on the following key external libraries: + +- **@ant-design/x**: Provides the core ThoughtChain component implementation +- **@svelte-preprocess-react**: Implements Svelte-to-React bridging +- **@utils/**: Custom utility function collection +- **classnames**: CSS class name composition tool + +**Section Sources** + +- [thought-chain.tsx:1-8](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L8) +- [thought-chain.item.tsx:1-7](file://frontend/antdx/thought-chain/item/thought-chain.item.tsx#L1-L7) + +## Performance Considerations + +### Rendering Optimization + +The component system employs multiple performance optimization strategies: + +1. **Memoization**: Use `useMemo` and `useCallback` to optimize rendering performance +2. **Conditional Rendering**: Only re-render components when necessary +3. **Batch Updates**: Reduce unnecessary re-renders through the Context system + +### Memory Management + +- **Reference Caching**: Use `useRef` to cache expensive computation results +- **Cleanup Mechanism**: Clean up timers and event listeners when the component unmounts +- **Circular Reference Protection**: Avoid circular dependencies in Context Providers + +### State Synchronization Optimization + +```mermaid +flowchart LR +A[State Change] --> B{Update Needed?} +B --> |No| C[Return Directly] +B --> |Yes| D[Compute New State] +D --> E[Update Context] +E --> F[Trigger Re-render] +F --> G[Optimized DOM Operations] +``` + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### 1. Component Not Displaying or Displaying as Empty + +**Possible Causes**: + +- `itemIndex` or `itemSlotKey` not correctly set +- Slot content not correctly passed +- Context Provider not correctly configured + +**Solution**: + +```javascript +// Ensure correct index and slot configuration + + {children} + +``` + +#### 2. State Updates Not Taking Effect + +**Possible Causes**: + +- Status value not correctly passed to Ant Design X component +- Context update logic error + +**Solution**: +Check the state update logic in `ItemHandler`, ensuring the `setItem` method is called correctly. + +#### 3. Performance Issues + +**Possible Causes**: + +- Frequent state changes causing excessive re-renders +- Large number of sub-items not properly optimized + +**Solution**: +Use `useMemo` and `useCallback` to optimize expensive computations and callback functions. + +**Section Sources** + +- [createItemsContext.tsx:124-153](file://frontend/utils/createItemsContext.tsx#L124-L153) +- [createItemsContext.tsx:234-237](file://frontend/utils/createItemsContext.tsx#L234-L237) + +## Conclusion + +The ThoughtChainItem component is a fully functional, architecturally clean React component system. It achieves loose coupling between components through a carefully designed Context system, provides powerful extensibility through a flexible slot mechanism, and ensures a good user experience through a comprehensive event handling mechanism. + +This component system is particularly suited for building complex thought flow applications, effectively managing the states and interactions of multiple thinking steps, and providing users with an intuitive thought process visualization experience. Its modular architectural design also provides a solid foundation for future feature extensions and maintenance. diff --git a/.wiki/en/Ant Design X Components/Data Components/Data Components.md b/.wiki/en/Ant Design X Components/Data Components/Data Components.md new file mode 100644 index 00000000..76b89fcc --- /dev/null +++ b/.wiki/en/Ant Design X Components/Data Components/Data Components.md @@ -0,0 +1,372 @@ +# Data Components + + +**Files Referenced in This Document** +- [frontend/antdx/file-card/file-card.tsx](file://frontend/antdx/file-card/file-card.tsx) +- [frontend/antdx/file-card/base.tsx](file://frontend/antdx/file-card/base.tsx) +- [frontend/antdx/folder/folder.tsx](file://frontend/antdx/folder/folder.tsx) +- [frontend/antdx/folder/context.ts](file://frontend/antdx/folder/context.ts) +- [frontend/antdx/sources/sources.tsx](file://frontend/antdx/sources/sources.tsx) +- [frontend/antdx/sources/context.ts](file://frontend/antdx/sources/context.ts) +- [frontend/antdx/think/think.tsx](file://frontend/antdx/think/think.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document covers the data components of Ant Design X, focusing on four components: FileCard, Folder, Sources, and Think. It provides an in-depth analysis of system architecture, component responsibilities, data flow and processing logic, integration points, and error handling, along with ready-to-use examples and best practices to help developers quickly understand and correctly use these components. + +## Project Structure + +The frontend components of Ant Design X are located in the `frontend/antdx` directory. Each component typically consists of three parts: + +- Component entry file: Responsible for bridging Svelte and React ecosystems, injecting slots and functional callbacks. +- Base implementation file: Encapsulates actual component interactions with @ant-design/x, handles data parsing and default behavior. +- Context and utilities: Provides context capabilities for slot items via createItemsContext, supporting dynamic rendering and extension. + +```mermaid +graph TB +subgraph "Ant Design X Data Components" +FC["FileCard"] +F["Folder"] +S["Sources"] +T["Think"] +end +subgraph "Base Implementation" +BFC["BaseFileCard"] +CtxF["Folder Context
treeData/directoryIcons"] +CtxS["Sources Context
items/title"] +end +subgraph "External Dependencies" +ADX["@ant-design/x
Native Component Library"] +Utils["@utils/*
Utilities & Hooks"] +end +FC --> BFC +F --> CtxF +S --> CtxS +FC --> ADX +F --> ADX +S --> ADX +T --> ADX +FC --> Utils +F --> Utils +S --> Utils +T --> Utils +``` + +Diagram sources + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) +- [frontend/antdx/folder/folder.tsx:1-123](file://frontend/antdx/folder/folder.tsx#L1-L123) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) +- [frontend/antdx/sources/sources.tsx:1-42](file://frontend/antdx/sources/sources.tsx#L1-L42) +- [frontend/antdx/sources/context.ts:1-7](file://frontend/antdx/sources/context.ts#L1-L7) +- [frontend/antdx/think/think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +Section sources + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) +- [frontend/antdx/folder/folder.tsx:1-123](file://frontend/antdx/folder/folder.tsx#L1-L123) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) +- [frontend/antdx/sources/sources.tsx:1-42](file://frontend/antdx/sources/sources.tsx#L1-L42) +- [frontend/antdx/sources/context.ts:1-7](file://frontend/antdx/sources/context.ts#L1-L7) +- [frontend/antdx/think/think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +## Core Components + +- FileCard: Displays a single file card, supporting image placeholders, preview configuration, and slot-based customization of masks and loading indicators. Internally parses file resource URLs via BaseFileCard to ensure accessibility. + - **Sub-component hierarchy**: FileCard is the top-level single card component; `FileCardList` (list layer) arranges multiple file cards; `FileCardListItem` (list item layer) encapsulates the rendering logic of a single list item. The hierarchy is: FileCardList → FileCardListItem → FileCard. + - **Backend exports**: `FileCard`, `FileCardList`, and `FileCardListItem` are all exported via [backend/modelscope_studio/components/antdx/**init**.py](file://backend/modelscope_studio/components/antdx/__init__.py). +- Folder: Displays a folder tree structure, supporting treeData, directoryIcons, empty state rendering, directory title, preview title, and preview rendering slots. Provides dynamic node and icon injection via context. +- Sources: Displays a list of data sources, supporting items and title slots. Provides a default item collection via context for unified injection in parent containers. +- Think: Displays "thinking" records and status, supporting loading, icon, and title slots for different visual feedback in various states. + - **Difference between Think and ThoughtChain**: Think (`antdx.Think`) is a lightweight single-step "thinking status" display component, typically embedded in bubble streams to indicate a single "thinking" state (belongs to data components). ThoughtChain (`antdx.ThoughtChain`) is a multi-step reasoning chain component used to display a complete reasoning sequence with inner child item support (belongs to confirmation components). Their use cases differ: Think is suitable for single-state indication; ThoughtChain is suitable for multi-step reasoning display. + +Section sources + +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/file-card/base.tsx:9-41](file://frontend/antdx/file-card/base.tsx#L9-L41) +- [frontend/antdx/folder/folder.tsx:16-120](file://frontend/antdx/folder/folder.tsx#L16-L120) +- [frontend/antdx/folder/context.ts:3-13](file://frontend/antdx/folder/context.ts#L3-L13) +- [frontend/antdx/sources/sources.tsx:9-39](file://frontend/antdx/sources/sources.tsx#L9-L39) +- [frontend/antdx/sources/context.ts:3-4](file://frontend/antdx/sources/context.ts#L3-L4) +- [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +## Architecture Overview + +All four components adopt a layered design of "entry layer + base implementation/context": + +- Entry layer: Uses sveltify to bridge Svelte components to the React ecosystem, uniformly handling slots and functional callbacks, and ensuring property alignment with @ant-design/x. +- Base implementation/context: Builds on the entry layer to further encapsulate data parsing, default value handling, slot rendering, and context injection, reducing duplicate logic and improving maintainability. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant FC as "FileCard Entry" +participant BFC as "BaseFileCard" +participant ADX as "@ant-design/x" +U->>FC : Pass props and slots +FC->>FC : Process slots and functional callbacks +FC->>BFC : Pass resolved props +BFC->>ADX : Render FileCard and resolve src +ADX-->>U : Display file card +``` + +Diagram sources + +- [frontend/antdx/file-card/file-card.tsx:34-124](file://frontend/antdx/file-card/file-card.tsx#L34-L124) +- [frontend/antdx/file-card/base.tsx:31-41](file://frontend/antdx/file-card/base.tsx#L31-L41) + +Section sources + +- [frontend/antdx/file-card/file-card.tsx:17-124](file://frontend/antdx/file-card/file-card.tsx#L17-L124) +- [frontend/antdx/file-card/base.tsx:9-41](file://frontend/antdx/file-card/base.tsx#L9-L41) + +## Detailed Component Analysis + +### FileCard Component Analysis + +- Responsibilities and Capabilities + - File information display: Supports file name, description, icon, placeholder image, loading indicator, etc. + - Actions and preview: Supports image preview configuration (container, mask, close icon, toolbar, custom image rendering). + - Slot-based extension: Flexibly replaces icon, description, mask, spinProps._, and imageProps._ via slots. + - Resource resolution: Converts relative paths or FileData to accessible URLs via BaseFileCard's src resolution logic. +- Key Flow + - Entry layer resolves slots and functional callbacks and constructs preview configuration. + - Passes resolved imageProps and spinProps to BaseFileCard. + - BaseFileCard uses rootUrl and apiPrefix to compute the accessible file URL. +- Usage Recommendations + - When customizing preview toolbars or masks, prefer slot injection over directly overriding complex objects. + - For large files or unstable network environments, configure placeholder images and loading indicators appropriately to improve user experience. + +```mermaid +flowchart TD +Start(["Enter FileCard"]) --> ParseSlots["Resolve slots and functional callbacks"] +ParseSlots --> BuildPreview["Build imageProps.preview configuration"] +BuildPreview --> ResolveSrc["BaseFileCard resolves src
rootUrl + apiPrefix"] +ResolveSrc --> Render["Render @ant-design/x FileCard"] +Render --> End(["Done"]) +``` + +Diagram sources + +- [frontend/antdx/file-card/file-card.tsx:34-124](file://frontend/antdx/file-card/file-card.tsx#L34-L124) +- [frontend/antdx/file-card/base.tsx:15-41](file://frontend/antdx/file-card/base.tsx#L15-L41) + +Section sources + +- [frontend/antdx/file-card/file-card.tsx:9-124](file://frontend/antdx/file-card/file-card.tsx#L9-L124) +- [frontend/antdx/file-card/base.tsx:9-41](file://frontend/antdx/file-card/base.tsx#L9-L41) + +### Folder Component Analysis + +- Responsibilities and Capabilities + - Tree structure display: Supports treeData and directory icon mapping via directoryIcons. + - Dynamic content service: Loads file content via fileContentService.onLoadFileContent. + - Slot-based extension: Supports emptyRender, previewRender, directoryTitle, and previewTitle. + - Context injection: Obtains default nodes and icon collections via useTreeNodeItems and useDirectoryIconItems. +- Key Flow + - Resolves treeData or default from context, prioritizing explicitly passed treeData. + - Converts directoryIcons into an icon dictionary keyed by file extension. + - Converts slots and functional callbacks to render functions required by @ant-design/x. +- Usage Recommendations + - For complex directory structures, prefer context injection of default nodes to reduce repetitive configuration. + - Preview render functions should be kept lightweight to avoid heavy computation during rendering. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant F as "Folder Entry" +participant Ctx as "Folder Context" +participant ADX as "@ant-design/x Folder" +U->>F : Pass treeData/directoryIcons/slots +F->>Ctx : Read default nodes and icons +F->>F : Resolve slots and functional callbacks +F->>ADX : Render treeData and directoryIcons +ADX-->>U : Display folder tree +``` + +Diagram sources + +- [frontend/antdx/folder/folder.tsx:25-119](file://frontend/antdx/folder/folder.tsx#L25-L119) +- [frontend/antdx/folder/context.ts:3-13](file://frontend/antdx/folder/context.ts#L3-L13) + +Section sources + +- [frontend/antdx/folder/folder.tsx:16-120](file://frontend/antdx/folder/folder.tsx#L16-L120) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) + +### Sources Component Analysis + +- Responsibilities and Capabilities + - Data source list display: Supports items list and title slot. + - Context injection: Obtains default items and default via useItems, prioritizing explicitly passed items. + - Render enhancement: Uses renderItems to clone and render item collections from context into the format required by @ant-design/x. +- Key Flow + - Resolves items or default from context and merges into the final list. + - Passes title and items to @ant-design/x Sources. +- Usage Recommendations + - Inject default items centrally in a parent container for reuse across multiple locations. + - For large lists, apply pagination or lazy loading optimization upstream. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant S as "Sources Entry" +participant Ctx as "Sources Context" +participant ADX as "@ant-design/x Sources" +U->>S : Pass items/slots +S->>Ctx : Read default items/default +S->>ADX : Render items and title +ADX-->>U : Display data source list +``` + +Diagram sources + +- [frontend/antdx/sources/sources.tsx:9-39](file://frontend/antdx/sources/sources.tsx#L9-L39) +- [frontend/antdx/sources/context.ts:3-4](file://frontend/antdx/sources/context.ts#L3-L4) + +Section sources + +- [frontend/antdx/sources/sources.tsx:9-39](file://frontend/antdx/sources/sources.tsx#L9-L39) +- [frontend/antdx/sources/context.ts:1-7](file://frontend/antdx/sources/context.ts#L1-L7) + +### Think Component Analysis + +- Responsibilities and Capabilities + - Thinking record and status display: Supports loading, icon, and title slots, enabling different content to be shown in various states (e.g., loading, complete, failed). + - Thin wrapper: Acts as a thin wrapper that directly forwards to the @ant-design/x Think component. +- Usage Recommendations + - In async thinking workflows, combine with the loading slot to provide friendlier user feedback. + - Use icon and title slots to differentiate thinking phases or result types. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant T as "Think Entry" +participant ADX as "@ant-design/x Think" +U->>T : Pass loading/icon/title/slots +T->>ADX : Directly forward props and slots +ADX-->>U : Display thinking status +``` + +Diagram sources + +- [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +Section sources + +- [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +## Dependency Analysis + +- Inter-component Coupling + - FileCard and BaseFileCard: Low coupling, decoupled via props passing and resolution. + - Folder and Sources: Each depends on its own context module, independent from each other, rendered via @ant-design/x components. + - Think: No context dependency, directly bridges @ant-design/x. +- External Dependencies + - @ant-design/x: The foundational library for all component rendering. + - @utils/\*: Provides common capabilities such as slot rendering, functional callback wrapping, and context creation. + +```mermaid +graph LR +FC["FileCard"] --> BFC["BaseFileCard"] +F["Folder"] --> CtxF["Folder Context"] +S["Sources"] --> CtxS["Sources Context"] +T["Think"] +BFC --> ADX["@ant-design/x"] +F --> ADX +S --> ADX +T --> ADX +FC --> Utils["@utils/*"] +F --> Utils +S --> Utils +T --> Utils +``` + +Diagram sources + +- [frontend/antdx/file-card/file-card.tsx:1-7](file://frontend/antdx/file-card/file-card.tsx#L1-L7) +- [frontend/antdx/file-card/base.tsx:1-7](file://frontend/antdx/file-card/base.tsx#L1-L7) +- [frontend/antdx/folder/folder.tsx:1-7](file://frontend/antdx/folder/folder.tsx#L1-L7) +- [frontend/antdx/sources/sources.tsx:1-5](file://frontend/antdx/sources/sources.tsx#L1-L5) +- [frontend/antdx/think/think.tsx:1-4](file://frontend/antdx/think/think.tsx#L1-L4) + +Section sources + +- [frontend/antdx/file-card/file-card.tsx:1-7](file://frontend/antdx/file-card/file-card.tsx#L1-L7) +- [frontend/antdx/file-card/base.tsx:1-7](file://frontend/antdx/file-card/base.tsx#L1-L7) +- [frontend/antdx/folder/folder.tsx:1-7](file://frontend/antdx/folder/folder.tsx#L1-L7) +- [frontend/antdx/sources/sources.tsx:1-5](file://frontend/antdx/sources/sources.tsx#L1-L5) +- [frontend/antdx/think/think.tsx:1-4](file://frontend/antdx/think/think.tsx#L1-L4) + +## Performance Considerations + +- Slot rendering cost control + - Place heavy content in slots, but avoid repeated computation in render functions; use useMemo for caching when necessary. +- Data parsing and transfer + - FileCard's src resolution is only triggered when dependencies change, avoiding unnecessary URL computation. +- List rendering optimization + - Sources and Folder use clone and memo strategies when resolving items to reduce repeated rendering. +- Preview and images + - Configure placeholder images and loading indicators appropriately to prevent large images from blocking the initial render. + +## Troubleshooting Guide + +- Image not displaying + - Check whether src is a relative path; confirm rootUrl and apiPrefix are configured correctly. + - Reference: [frontend/antdx/file-card/base.tsx:15-29](file://frontend/antdx/file-card/base.tsx#L15-L29) +- Preview function abnormal + - Confirm that imageProps.preview slots are correctly injected and functional callbacks are properly wrapped. + - Reference: [frontend/antdx/file-card/file-card.tsx:34-124](file://frontend/antdx/file-card/file-card.tsx#L34-L124) +- Directory icons not working + - Confirm directoryIcons are mapped by file extension and injected via context. + - Reference: [frontend/antdx/folder/folder.tsx:71-87](file://frontend/antdx/folder/folder.tsx#L71-L87) +- Data source list empty + - Check whether items and default are correctly injected or explicitly overridden. + - Reference: [frontend/antdx/sources/sources.tsx:13-33](file://frontend/antdx/sources/sources.tsx#L13-L33) +- Thinking status not updating + - Confirm loading/icon/title slots are correctly injected and functional callbacks are properly wrapped. + - Reference: [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +Section sources + +- [frontend/antdx/file-card/base.tsx:15-29](file://frontend/antdx/file-card/base.tsx#L15-L29) +- [frontend/antdx/file-card/file-card.tsx:34-124](file://frontend/antdx/file-card/file-card.tsx#L34-L124) +- [frontend/antdx/folder/folder.tsx:71-87](file://frontend/antdx/folder/folder.tsx#L71-L87) +- [frontend/antdx/sources/sources.tsx:13-33](file://frontend/antdx/sources/sources.tsx#L13-L33) +- [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +## Conclusion + +This document systematically covers the frontend implementation and usage of Ant Design X data components, focusing on FileCard, Folder, Sources, and Think. Through slot and functional callback bridging in the entry layer, data parsing and default value handling in the base implementation, and context-driven dynamic injection mechanisms, these components maintain API semantics consistent with @ant-design/x while providing stronger extensibility and maintainability. It is recommended to follow the usage guidelines and best practices in this document in actual projects for a more stable and efficient experience. + +## Appendix + +- Usage Examples (Based on Component Responsibilities and Interfaces) + - File card display and preview + - Key steps: Prepare file data src, configure imageProps.preview slots (e.g., mask, toolbar), and optionally set placeholder image and loading indicator. + - Reference: [frontend/antdx/file-card/file-card.tsx:34-124](file://frontend/antdx/file-card/file-card.tsx#L34-L124), [frontend/antdx/file-card/base.tsx:15-41](file://frontend/antdx/file-card/base.tsx#L15-L41) + - Folder tree structure and directory management + - Key steps: Prepare treeData or inject default nodes via context; configure extension-based mapping for directoryIcons; inject emptyRender, previewRender, directoryTitle, and previewTitle as needed. + - Reference: [frontend/antdx/folder/folder.tsx:25-119](file://frontend/antdx/folder/folder.tsx#L25-L119), [frontend/antdx/folder/context.ts:3-13](file://frontend/antdx/folder/context.ts#L3-L13) + - Data source management and metadata display + - Key steps: Inject default items or default in the parent container; override items when needed; customize title via the title slot. + - Reference: [frontend/antdx/sources/sources.tsx:9-39](file://frontend/antdx/sources/sources.tsx#L9-L39), [frontend/antdx/sources/context.ts:3-4](file://frontend/antdx/sources/context.ts#L3-L4) + - Thinking record and status management + - Key steps: Inject loading/icon/title slots at different stages; switch displayed content based on status in async workflows. + - Reference: [frontend/antdx/think/think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) diff --git a/.wiki/en/Ant Design X Components/Data Components/FileCard Component.md b/.wiki/en/Ant Design X Components/Data Components/FileCard Component.md new file mode 100644 index 00000000..e84b0231 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Data Components/FileCard Component.md @@ -0,0 +1,441 @@ +# FileCard Component + + +**Files Referenced in This Document** +- [frontend/antdx/file-card/file-card.tsx](file://frontend/antdx/file-card/file-card.tsx) +- [frontend/antdx/file-card/base.tsx](file://frontend/antdx/file-card/base.tsx) +- [frontend/antdx/file-card/Index.svelte](file://frontend/antdx/file-card/Index.svelte) +- [frontend/antdx/file-card/list/file-card.list.tsx](file://frontend/antdx/file-card/list/file-card.list.tsx) +- [frontend/antdx/file-card/list/context.ts](file://frontend/antdx/file-card/list/context.ts) +- [frontend/antdx/file-card/list/item/file-card.list.item.tsx](file://frontend/antdx/file-card/list/item/file-card.list.item.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The FileCard component is an important component in the ModelScope Studio frontend framework, extended and encapsulated based on the Ant Design X FileCard component. It provides file display, preview, and upload capabilities, supporting multiple file types and custom configuration options. + +The component consists of three core parts: + +- **Base FileCard component**: Provides core file display functionality +- **FileCard List component**: Used to display a list view of multiple file cards +- **FileCard List Item component**: The concrete implementation of a single file card in a list + +## Project Structure + +The FileCard component is located in the antdx component library of the frontend project, organized in a modular manner: + +```mermaid +graph TB +subgraph "FileCard Component Structure" +FC[FileCard Core Component] +FCL[FileCard List Component] +FCListItem[FileCard List Item Component] +Base[Base FileCard Component] +FC --> Base +FCL --> FCListItem +FCListItem --> Base +end +subgraph "Frontend Component Libraries" +Antdx[antdx Component Library] +Antd[antd Component Library] +Utils[Utility Functions] +end +FC -.-> Antdx +FCL -.-> Antdx +FCListItem -.-> Antdx +Base -.-> Antdx +Base -.-> Antd +FC -.-> Utils +FCL -.-> Utils +FCListItem -.-> Utils +``` + +**Diagram sources** + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/list/file-card.list.tsx:1-68](file://frontend/antdx/file-card/list/file-card.list.tsx#L1-L68) + +**Section sources** + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/list/file-card.list.tsx:1-68](file://frontend/antdx/file-card/list/file-card.list.tsx#L1-L68) + +## Core Components + +### Base FileCard Component (BaseFileCard) + +The BaseFileCard component is the foundation of the entire FileCard system, responsible for handling file source resolution and basic file display logic. + +**Key Features:** + +- Supports both string and FileData type file sources +- Automatically resolves accessible file URLs +- Integrates Ant Design X's FileCard component +- Provides root URL and API prefix configuration + +**Key Methods:** + +- `resolveFileSrc()`: Resolves the file source, supporting both local and remote files +- `BaseFileCard`: Main component rendering logic + +**Section sources** + +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) + +### FileCard Component + +The FileCard component is a further encapsulation of the base component, adding React Slot support and richer configuration options. + +**Main Features:** + +- Supports the React Slot system +- Enhanced image preview functionality +- Loading state indicator configuration +- Custom icon and description content + +**Core Configuration:** + +- `imageProps.placeholder`: Placeholder configuration +- `imageProps.preview`: Preview function configuration +- `spinProps`: Loading state configuration +- `slots`: Slot system support + +**Section sources** + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) + +### FileCard List Component (FileCardList) + +The FileCardList component is used to display multiple file cards, supporting bulk operations and unified configuration. + +**Key Features:** + +- Bulk file management +- Removable functionality +- Slot system integration +- Item context management + +**Section sources** + +- [frontend/antdx/file-card/list/file-card.list.tsx:1-68](file://frontend/antdx/file-card/list/file-card.list.tsx#L1-L68) + +### FileCard List Item Component (FileCardListItem) + +The concrete implementation of a single file card in a list, inheriting all functionality of the base file card. + +**Key Features:** + +- List item handling mechanism +- Slot parameter passing +- Preview configuration +- Item context integration + +**Section sources** + +- [frontend/antdx/file-card/list/item/file-card.list.item.tsx:1-83](file://frontend/antdx/file-card/list/item/file-card.list.item.tsx#L1-L83) + +## Architecture Overview + +The FileCard component adopts a layered architecture design, forming a clear hierarchy from the underlying base component to the upper-level application components: + +```mermaid +graph TD +subgraph "Application Layer" +App[Application] +Demo[Demo App] +end +subgraph "Component Layer" +SvelteIndex[Index.svelte Entry] +FileCard[FileCard Component] +FileCardList[FileCardList Component] +FileCardListItem[FileCardListItem Component] +end +subgraph "Base Layer" +BaseFileCard[BaseFileCard Component] +AntdX[Ant Design X] +Utils[Utility Functions] +end +subgraph "Data Layer" +FileData[File Data Model] +Config[Configuration Object] +Slots[Slot System] +end +App --> SvelteIndex +Demo --> SvelteIndex +SvelteIndex --> FileCard +SvelteIndex --> FileCardList +FileCardList --> FileCardListItem +FileCard --> BaseFileCard +FileCardList --> BaseFileCard +FileCardListItem --> BaseFileCard +BaseFileCard --> AntdX +FileCard --> Utils +FileCardList --> Utils +FileCardListItem --> Utils +BaseFileCard --> FileData +FileCard --> Config +FileCardList --> Config +FileCardListItem --> Config +FileCard --> Slots +FileCardList --> Slots +FileCardListItem --> Slots +``` + +**Diagram sources** + +- [frontend/antdx/file-card/Index.svelte:1-66](file://frontend/antdx/file-card/Index.svelte#L1-L66) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/list/file-card.list.tsx:1-68](file://frontend/antdx/file-card/list/file-card.list.tsx#L1-L68) + +## Detailed Component Analysis + +### Base FileCard Component Class Diagram + +```mermaid +classDiagram +class BaseFileCardProps { ++string rootUrl ++string apiPrefix ++string|FileData src ++XFileCardProps props +} +class BaseFileCard { ++resolveFileSrc(src, rootUrl, apiPrefix) string ++render() ReactElement +} +class FileCardProps { ++BaseFileCardProps props ++React.ReactNode children ++object slots ++object imageProps ++object spinProps +} +class FileCard { ++getConfig(value) object ++render() ReactElement +} +class FileCardListProps { ++FileCardListProps props ++ItemType[] items ++React.ReactNode children ++string rootUrl ++string apiPrefix ++function removable +} +class FileCardList { ++render() ReactElement ++resolveItems() ItemType[] +} +class FileCardListItemProps { ++BaseFileCardProps props ++ItemHandlerProps props ++object slots ++object imageProps +} +class FileCardListItem { ++getConfig(value) object ++render() ReactElement +} +BaseFileCardProps <|-- FileCardProps +BaseFileCardProps <|-- FileCardListItemProps +FileCardProps <|-- FileCard +FileCardListProps <|-- FileCardList +FileCardListItemProps <|-- FileCardListItem +FileCard --> BaseFileCard +FileCardList --> FileCardListItem +FileCardListItem --> BaseFileCard +``` + +**Diagram sources** + +- [frontend/antdx/file-card/base.tsx:9-13](file://frontend/antdx/file-card/base.tsx#L9-L13) +- [frontend/antdx/file-card/file-card.tsx:17-34](file://frontend/antdx/file-card/file-card.tsx#L17-L34) +- [frontend/antdx/file-card/list/file-card.list.tsx:14-21](file://frontend/antdx/file-card/list/file-card.list.tsx#L14-L21) +- [frontend/antdx/file-card/list/item/file-card.list.item.tsx:16-31](file://frontend/antdx/file-card/list/item/file-card.list.item.tsx#L16-L31) + +### File Source Resolution Flow + +```mermaid +flowchart TD +Start([Start resolving file source]) --> CheckSrc{Check src parameter} +CheckSrc --> |Empty| ReturnEmpty[Return empty value] +CheckSrc --> |String| CheckProtocol{Check protocol} +CheckSrc --> |Object| CheckObject{Check object properties} +CheckProtocol --> |Starts with http| ReturnString[Return string directly] +CheckProtocol --> |Does not start with http| ResolveURL[Call getFetchableUrl] +CheckObject --> CheckUrl{Check url property} +CheckObject --> CheckPath{Check path property} +CheckUrl --> |Exists| ReturnUrl[Return url] +CheckUrl --> |Does not exist| ResolvePath[Call getFetchableUrl] +CheckPath --> |Exists| ResolvePath +CheckPath --> |Does not exist| ReturnUndefined[Return undefined] +ResolveURL --> ReturnResolved[Return resolved URL] +ResolvePath --> ReturnResolved +ReturnEmpty --> End([End]) +ReturnString --> End +ReturnUrl --> End +ReturnResolved --> End +ReturnUndefined --> End +``` + +**Diagram sources** + +- [frontend/antdx/file-card/base.tsx:15-29](file://frontend/antdx/file-card/base.tsx#L15-L29) + +### Slot System Workflow + +```mermaid +sequenceDiagram +participant App as Application +participant FileCard as FileCard Component +participant BaseFileCard as BaseFileCard Component +participant SlotSystem as Slot System +participant Utils as Utility Functions +App->>FileCard : Render component +FileCard->>SlotSystem : Get slot configuration +SlotSystem-->>FileCard : Return slot data +FileCard->>Utils : Process slot parameters +Utils-->>FileCard : Return processed result +FileCard->>BaseFileCard : Pass configuration +BaseFileCard->>BaseFileCard : Render file card +BaseFileCard-->>App : Output final component +``` + +**Diagram sources** + +- [frontend/antdx/file-card/file-card.tsx:34-124](file://frontend/antdx/file-card/file-card.tsx#L34-L124) +- [frontend/antdx/file-card/base.tsx:31-41](file://frontend/antdx/file-card/base.tsx#L31-L41) + +**Section sources** + +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/list/file-card.list.tsx:1-68](file://frontend/antdx/file-card/list/file-card.list.tsx#L1-L68) +- [frontend/antdx/file-card/list/item/file-card.list.item.tsx:1-83](file://frontend/antdx/file-card/list/item/file-card.list.item.tsx#L1-L83) + +## Dependency Analysis + +The dependency relationship of the FileCard component is relatively clear, primarily depending on the Ant Design X component library and internal utility functions: + +```mermaid +graph LR +subgraph "External Dependencies" +AntdX[Ant Design X] +React[React] +Svelte[Svelte] +end +subgraph "Internal Dependencies" +Utils[Utility Functions] +Hooks[React Hooks] +Context[Context System] +end +subgraph "FileCard Components" +BaseFileCard[BaseFileCard] +FileCard[FileCard] +FileCardList[FileCardList] +FileCardListItem[FileCardListItem] +end +FileCard --> BaseFileCard +FileCardList --> FileCardListItem +FileCardListItem --> BaseFileCard +BaseFileCard --> AntdX +FileCard --> Utils +FileCardList --> Utils +FileCardListItem --> Utils +FileCard --> Hooks +FileCardList --> Hooks +FileCardListItem --> Hooks +FileCard --> Context +FileCardList --> Context +FileCardListItem --> Context +BaseFileCard --> React +FileCard --> Svelte +FileCardList --> Svelte +FileCardListItem --> Svelte +``` + +**Diagram sources** + +- [frontend/antdx/file-card/file-card.tsx:1-7](file://frontend/antdx/file-card/file-card.tsx#L1-L7) +- [frontend/antdx/file-card/base.tsx:1-7](file://frontend/antdx/file-card/base.tsx#L1-L7) +- [frontend/antdx/file-card/list/file-card.list.tsx:1-8](file://frontend/antdx/file-card/list/file-card.list.tsx#L1-L8) + +**Section sources** + +- [frontend/antdx/file-card/file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [frontend/antdx/file-card/base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) +- [frontend/antdx/file-card/list/file-card.list.tsx:1-68](file://frontend/antdx/file-card/list/file-card.list.tsx#L1-L68) + +## Performance Considerations + +The FileCard component was designed with performance optimization in mind: + +### Memory Management + +- Uses `useMemo` to cache file source resolution results +- Avoids unnecessary component re-renders +- Proper use of React Slots to reduce DOM operations + +### Render Optimization + +- Conditional rendering of slot content +- Lazy loading components to avoid initial render pressure +- Optimized performance for the image preview feature + +### Data Flow Optimization + +- Unidirectional data flow design +- Avoids passing deeply nested objects +- Reasonable event handling mechanisms + +## Troubleshooting Guide + +### Common Issues and Solutions + +**File not displaying** + +- Check whether the file source URL is correct +- Confirm network connectivity and permission settings +- Verify that the file format is supported + +**Preview function abnormal** + +- Check the image preview configuration +- Confirm the slot system is working correctly +- Verify that the container element exists + +**Component rendering error** + +- Check the usage of React Slots +- Confirm that required dependencies are installed correctly +- Verify the import path of the component + +**Section sources** + +- [frontend/antdx/file-card/base.tsx:15-29](file://frontend/antdx/file-card/base.tsx#L15-L29) +- [frontend/antdx/file-card/file-card.tsx:34-124](file://frontend/antdx/file-card/file-card.tsx#L34-L124) + +## Conclusion + +The FileCard component is a fully functional and well-designed frontend component system. Through its clear layered architecture, flexible slot system, and comprehensive configuration options, it provides users with powerful file management and display capabilities. + +The main advantages of the component include: + +- **Modular design**: Clear component hierarchy structure +- **Flexible configuration**: Rich configuration options and slot system +- **Performance optimization**: Reasonable memory management and render optimization +- **Easy to extend**: Standardized interface design facilitates feature extension + +This component system provides ModelScope Studio with reliable file processing capabilities to meet the needs of various file display and management scenarios. diff --git a/.wiki/en/Ant Design X Components/Data Components/Folder Component.md b/.wiki/en/Ant Design X Components/Data Components/Folder Component.md new file mode 100644 index 00000000..453d315d --- /dev/null +++ b/.wiki/en/Ant Design X Components/Data Components/Folder Component.md @@ -0,0 +1,359 @@ +# Folder Component + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/folder/__init__.py](file://backend/modelscope_studio/components/antdx/folder/__init__.py) +- [frontend/antdx/folder/Index.svelte](file://frontend/antdx/folder/Index.svelte) +- [frontend/antdx/folder/folder.tsx](file://frontend/antdx/folder/folder.tsx) +- [frontend/antdx/folder/context.ts](file://frontend/antdx/folder/context.ts) +- [frontend/antdx/folder/package.json](file://frontend/antdx/folder/package.json) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [docs/components/antdx/folder/README-zh_CN.md](file://docs/components/antdx/folder/README-zh_CN.md) +- [docs/components/antdx/folder/README.md](file://docs/components/antdx/folder/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The Folder component is an important file tree component in ModelScope Studio, built on top of Ant Design X's Folder component. It is primarily used to display file system structures, providing hierarchical browsing of files and folders. It supports event handling for file clicks, folder clicks, selected file changes, and expanded path changes, along with rich customization options. + +The component is implemented on the frontend using the Svelte framework, bridged to Ant Design X's native component through a React preprocessing mechanism, achieving a complete data flow and event flow from the Python backend to the React frontend. + +## Project Structure + +The location and organizational structure of the Folder component within the project: + +```mermaid +graph TB +subgraph "Backend (Python)" +A[backend/modelscope_studio/components/antdx/] --> B[folder/] +B --> C[__init__.py
AntdXFolder class] +B --> D[directory_icon/] +B --> E[tree_node/] +end +subgraph "Frontend (TypeScript/Svelte)" +F[frontend/antdx/] --> G[folder/] +G --> H[Index.svelte
Component Entry] +G --> I[folder.tsx
React Implementation] +G --> J[context.ts
Context Management] +G --> K[package.json
Package Config] +end +subgraph "Documentation" +L[docs/components/antdx/folder/] +L --> M[README-zh_CN.md] +L --> N[README.md] +end +A --> F +F --> L +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:1-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L1-L114) +- [frontend/antdx/folder/Index.svelte:1-81](file://frontend/antdx/folder/Index.svelte#L1-L81) +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) + +**Section sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:1-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L1-L114) +- [frontend/antdx/folder/Index.svelte:1-81](file://frontend/antdx/folder/Index.svelte#L1-L81) +- [frontend/antdx/folder/folder.tsx:1-124](file://frontend/antdx/folder/folder.tsx#L1-L124) + +## Core Components + +### AntdXFolder Class + +AntdXFolder is the core backend component class, inheriting from ModelScopeLayoutComponent. It defines the complete component interface and behavioral specification. + +**Key Features:** + +- Supports multiple event listeners (file_click, folder_click, selected_file_change, expanded_paths_change) +- Provides rich configuration properties (tree_data, selectable, selected_file, expanded_paths, etc.) +- Supports a slot system (emptyRender, previewRender, directoryTitle, etc.) +- Integrates component lifecycle management in the Gradio ecosystem + +**Key Property Descriptions:** + +- `tree_data`: File tree data structure defining the hierarchy of files and folders +- `selectable`: Whether file selection is allowed +- `selected_file`: Currently selected file path list +- `expanded_paths`: Default expanded path list +- `directory_icons`: Custom directory icon mapping + +**Section sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) + +### Frontend Component Architecture + +The frontend component adopts a layered architecture design, implemented through bridging Svelte and React: + +```mermaid +classDiagram +class AntdXFolder { ++TreeNode ++DirectoryIcon ++EVENTS ++SLOTS ++tree_data ++selectable ++selected_file ++expanded_paths ++directory_icons ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +class FolderComponent { ++slots ++children ++previewRender ++previewTitle ++fileContentService ++treeData ++directoryIcons ++emptyRender ++directoryTitle +} +class ContextProviders { ++withTreeNodeItemsContextProvider ++withDirectoryIconItemsContextProvider ++useTreeNodeItems ++useDirectoryIconItems +} +AntdXFolder --> FolderComponent : "Frontend rendering" +FolderComponent --> ContextProviders : "Use context" +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:12-114](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L12-L114) +- [frontend/antdx/folder/folder.tsx:16-124](file://frontend/antdx/folder/folder.tsx#L16-L124) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) + +**Section sources** + +- [frontend/antdx/folder/folder.tsx:16-124](file://frontend/antdx/folder/folder.tsx#L16-L124) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) + +## Architecture Overview + +The overall architecture of the Folder component adopts a layered design, achieving a complete data flow from the Python backend to the React frontend: + +```mermaid +sequenceDiagram +participant Backend as Backend Component +participant Svelte as Svelte Layer +participant React as React Component +participant AntDX as Ant Design X +participant User as User +User->>Backend : Create Folder component +Backend->>Svelte : Render component +Svelte->>React : Load Folder component +React->>AntDX : Initialize AntdXFolder +AntDX->>User : Display file tree interface +User->>AntDX : Click file/folder +AntDX->>React : Trigger event callback +React->>Svelte : Forward event +Svelte->>Backend : Update state +Backend->>User : Return result +Note over Backend,User : Data binding and event handling +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:19-35](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L19-L35) +- [frontend/antdx/folder/Index.svelte:10-81](file://frontend/antdx/folder/Index.svelte#L10-L81) +- [frontend/antdx/folder/folder.tsx:25-121](file://frontend/antdx/folder/folder.tsx#L25-L121) + +## Detailed Component Analysis + +### Event Handling Mechanism + +The Folder component supports multiple event listeners, each with its specific functionality and trigger conditions: + +```mermaid +flowchart TD +A[User Interaction] --> B{Event Type} +B --> |file_click| C[File Click Event] +B --> |folder_click| D[Folder Click Event] +B --> |selected_file_change| E[Selected File Change] +B --> |expanded_paths_change| F[Expanded Paths Change] +B --> |file_content_service_load_file_content| G[File Content Load] +C --> H[Update bind_fileClick_event] +D --> I[Update bind_folderClick_event] +E --> J[Update bind_selectedFileChange_event] +F --> K[Update bind_expandedPathsChange_event] +G --> L[Update bind_fileContentService_loadFileContent_event] +H --> M[Execute callback function] +I --> M +J --> M +K --> M +L --> M +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:19-35](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L19-L35) + +### Slot System + +The component provides a flexible slot system, allowing developers to customize various display content: + +| Slot Name | Description | Use Case | +| -------------- | --------------------- | -------------------------------------------------- | +| emptyRender | Empty state rendering | Display custom content when the file tree is empty | +| previewRender | Preview rendering | Customize file preview content | +| directoryTitle | Directory title | Customize directory display title | +| previewTitle | Preview title | Customize preview title display | +| treeData | Tree data | Customize tree data structure | +| directoryIcons | Directory icons | Customize file type icons | + +**Section sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:37-41](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L37-L41) + +### Data Flow Processing + +The component's data flow processing uses React's useMemo optimization mechanism: + +```mermaid +flowchart LR +A[Raw Data] --> B[useMemo Optimization] +B --> C[Data Transformation] +C --> D[Context Provider] +D --> E[Child Component Consumption] +F[External Input] --> G[props.treeData] +H[Internal Generation] --> I[renderItems] +G --> C +I --> C +J[Directory Icons] --> K[Object Mapping] +K --> L[extension -> ReactNode] +``` + +**Diagram sources** + +- [frontend/antdx/folder/folder.tsx:60-88](file://frontend/antdx/folder/folder.tsx#L60-L88) + +**Section sources** + +- [frontend/antdx/folder/folder.tsx:60-88](file://frontend/antdx/folder/folder.tsx#L60-L88) + +## Dependency Analysis + +The dependency relationships of the Folder component reflect a clear layered architecture: + +```mermaid +graph TB +subgraph "External Dependencies" +A[@ant-design/x] --> B[AntdXFolder] +C[classnames] --> D[Svelte Style Processing] +E[react] --> F[React Slot] +end +subgraph "Internal Dependencies" +G[createItemsContext] --> H[Context Provider] +I[renderItems] --> J[Item Rendering] +K[renderParamsSlot] --> L[Parameterized Slots] +M[useFunction] --> N[Function Wrapping] +end +subgraph "Component Hierarchy" +O[AntdXFolder] --> P[Index.svelte] +P --> Q[folder.tsx] +Q --> R[React Component] +R --> S[Ant Design X] +end +A --> R +G --> Q +I --> Q +K --> Q +M --> Q +``` + +**Diagram sources** + +- [frontend/antdx/folder/folder.tsx:1-15](file://frontend/antdx/folder/folder.tsx#L1-L15) +- [frontend/antdx/folder/Index.svelte:1-10](file://frontend/antdx/folder/Index.svelte#L1-L10) +- [frontend/antdx/folder/context.ts:1-16](file://frontend/antdx/folder/context.ts#L1-L16) + +**Section sources** + +- [frontend/antdx/folder/package.json:1-15](file://frontend/antdx/folder/package.json#L1-L15) +- [frontend/antdx/folder/folder.tsx:1-15](file://frontend/antdx/folder/folder.tsx#L1-L15) + +## Performance Considerations + +### Render Optimization + +The component adopts several performance optimization strategies: + +1. **useMemo optimization**: Memoizes treeData and directoryIcons to avoid unnecessary recomputation +2. **Conditional rendering**: Only renders children content when needed, reducing the number of DOM nodes +3. **Lazy loading**: Implements dynamic import and lazy loading of components via importComponent + +### Memory Management + +- Context providers use appropriate cleanup mechanisms +- Event handlers are wrapped with useFunction to ensure correct `this` binding +- Slot content is rendered on demand to avoid memory leaks + +## Troubleshooting Guide + +### Common Issues and Solutions + +**Issue 1: Component not displaying** + +- Check whether tree_data is correctly set +- Confirm that the FRONTEND_DIR path is correctly resolved +- Verify the component's visible property + +**Issue 2: Events not triggering** + +- Confirm that event listeners are correctly registered +- Check whether bind\_\*\_event properties are set +- Verify that the callback function signature is correct + +**Issue 3: Icons not displaying** + +- Check the directory_icons configuration +- Confirm that the extension mapping is correct +- Verify the import path of icon components + +**Section sources** + +- [backend/modelscope_studio/components/antdx/folder/**init**.py:97-101](file://backend/modelscope_studio/components/antdx/folder/__init__.py#L97-L101) + +## Conclusion + +The Folder component is a fully functional file tree component with a clear architecture. It successfully combines the powerful capabilities of Ant Design X with the ModelScope Studio ecosystem, providing users with an excellent file browsing experience. + +**Main Advantages:** + +- Complete event handling mechanism +- Flexible slot system +- Excellent performance +- Clear code structure +- Good extensibility + +**Applicable Scenarios:** + +- File management systems +- Code editors +- Asset management tools +- Document browsing applications + +This component provides ModelScope Studio with powerful file tree display capabilities and serves as an important foundational component for building complex frontend applications. diff --git a/.wiki/en/Ant Design X Components/Data Components/Sources Component.md b/.wiki/en/Ant Design X Components/Data Components/Sources Component.md new file mode 100644 index 00000000..820ea89b --- /dev/null +++ b/.wiki/en/Ant Design X Components/Data Components/Sources Component.md @@ -0,0 +1,422 @@ +# Sources Component + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/sources/__init__.py](file://backend/modelscope_studio/components/antdx/sources/__init__.py) +- [backend/modelscope_studio/components/antdx/sources/item/__init__.py](file://backend/modelscope_studio/components/antdx/sources/item/__init__.py) +- [frontend/antdx/sources/sources.tsx](file://frontend/antdx/sources/sources.tsx) +- [frontend/antdx/sources/item/sources.item.tsx](file://frontend/antdx/sources/item/sources.item.tsx) +- [frontend/antdx/sources/context.ts](file://frontend/antdx/sources/context.ts) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [docs/components/antdx/sources/README-zh_CN.md](file://docs/components/antdx/sources/README-zh_CN.md) +- [docs/components/antdx/sources/demos/basic.py](file://docs/components/antdx/sources/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The Sources component is a core component in ModelScope Studio for displaying a list of information sources in AI chat scenarios. Built on top of Ant Design X's Sources component, it is specifically designed to display references, link sources, and other related information. + +The component supports multiple configuration options, including title settings, expanded state control, inline display mode, and provides complete event handling mechanisms including click events and expand events. + +## Project Structure + +The Sources component adopts a frontend/backend separated architecture design, mainly consisting of the following structure: + +```mermaid +graph TB +subgraph "Backend Component Layer" +Backend[AntdXSources
Main Component] +BackendItem[AntdXSourcesItem
Child Item Component] +end +subgraph "Frontend Component Layer" +Frontend[Sources
React Component] +FrontendItem[SourcesItem
React Child Item Component] +Context[Context
Context Management] +end +subgraph "Utility Layer" +Utils[ModelScopeLayoutComponent
Base Component Class] +Resolver[resolve_frontend_dir
Path Resolver] +end +Backend --> Utils +BackendItem --> Utils +Backend --> Frontend +BackendItem --> FrontendItem +Frontend --> Context +Backend --> Resolver +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/antdx/sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) +- [frontend/antdx/sources/sources.tsx:1-41](file://frontend/antdx/sources/sources.tsx#L1-L41) + +**Section sources** + +- [backend/modelscope_studio/components/antdx/sources/**init**.py:1-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L1-L92) +- [backend/modelscope_studio/components/antdx/sources/item/**init**.py:1-68](file://backend/modelscope_studio/components/antdx/sources/item/__init__.py#L1-L68) + +## Core Components + +### AntdXSources Main Component + +AntdXSources is the main container of the Sources component, responsible for managing the display and interaction of the entire data source list. + +**Key Features:** + +- Supports title display and customization +- Configurable expand icon position (start/end) +- Default expanded and controlled expanded states +- Inline display mode support +- Active key management +- Popover overlay width setting + +**Key Properties:** + +- `title`: Title text displayed at the top of the component +- `items`: Array configuration of data source items +- `expand_icon_position`: Display position of the expand icon +- `default_expanded`: Default expanded state +- `expanded`: Controlled expanded state +- `inline`: Whether to enable inline display mode +- `active_key`: Currently active item key +- `popover_overlay_width`: Popover overlay width + +### AntdXSourcesItem Child Item Component + +AntdXSourcesItem represents a single data source entry, used to display specific source information. + +**Key Features:** + +- Supports customization of title, icon, and description +- Link address configuration +- Unique key identifier +- Slot system support + +**Key Properties:** + +- `key`: Unique identifier of the item +- `title`: Item title +- `description`: Item description information +- `icon`: Custom icon +- `url`: Navigation link address + +**Section sources** + +- [backend/modelscope_studio/components/antdx/sources/**init**.py:30-73](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L30-L73) +- [backend/modelscope_studio/components/antdx/sources/item/**init**.py:18-48](file://backend/modelscope_studio/components/antdx/sources/item/__init__.py#L18-L48) + +## Architecture Overview + +The Sources component adopts a layered architecture design, achieving clear separation of concerns: + +```mermaid +sequenceDiagram +participant App as Application +participant Backend as Backend Component +participant Frontend as Frontend Component +participant AntDX as Ant Design X +participant Context as Context Management +App->>Backend : Create Sources component +Backend->>Backend : Resolve frontend directory +Backend->>Frontend : Render React component +Frontend->>Context : Initialize context provider +Frontend->>AntDX : Use native Sources component +AntDX-->>Frontend : Return render result +Frontend-->>App : Output final component +Note over Backend,Frontend : Event binding and data passing +Backend->>Backend : Bind expand/click events +Backend->>Frontend : Pass event callbacks +``` + +**Diagram sources** + +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-16](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L16) +- [frontend/antdx/sources/sources.tsx:9-38](file://frontend/antdx/sources/sources.tsx#L9-L38) + +**Section sources** + +- [frontend/antdx/sources/sources.tsx:1-41](file://frontend/antdx/sources/sources.tsx#L1-L41) +- [frontend/antdx/sources/item/sources.item.tsx:1-14](file://frontend/antdx/sources/item/sources.item.tsx#L1-L14) + +## Detailed Component Analysis + +### Backend Component Implementation + +#### ModelScopeLayoutComponent Base Class + +All Sources components inherit from ModelScopeLayoutComponent, a layout component base class specifically designed for ModelScope Studio. + +**Core Functions:** + +- Provides the basic framework for Gradio components +- Handles component lifecycle management +- Supports slot system integration +- Manages internal component state + +#### AntdXSources Component Implementation + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS : list ++SLOTS : list ++skip_api : bool ++FRONTEND_DIR : str ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdXSources { ++title : str ++items : list ++expand_icon_position : str ++default_expanded : bool ++expanded : bool ++inline : bool ++active_key : str ++popover_overlay_width : str|int|float ++Item : class ++EVENTS : list ++SLOTS : list +} +class AntdXSourcesItem { ++key : str ++description : str ++icon : str ++title : str ++url : str ++EVENTS : list ++SLOTS : list +} +ModelScopeLayoutComponent <|-- AntdXSources +ModelScopeLayoutComponent <|-- AntdXSourcesItem +AntdXSources --> AntdXSourcesItem : contains +``` + +**Diagram sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/antdx/sources/**init**.py:11-92](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L11-L92) +- [backend/modelscope_studio/components/antdx/sources/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/sources/item/__init__.py#L8-L68) + +**Frontend Component Implementation** + +#### Sources React Component + +The Sources component is implemented using React, integrated with the Svelte ecosystem through the sveltify wrapper. + +**Core Features:** + +- Uses Ant Design X's native Sources component +- Supports a slot system, allowing custom title content +- Dynamically processes item lists +- Event handling mechanism + +#### SourcesItem React Child Component + +SourcesItem is the React implementation of a single data source item, processing item logic through ItemHandler. + +**Key Features:** + +- Accepts partial SourcesProps type +- Uses ItemHandler for item processing +- Supports additional item handler properties + +**Section sources** + +- [frontend/antdx/sources/sources.tsx:1-41](file://frontend/antdx/sources/sources.tsx#L1-L41) +- [frontend/antdx/sources/item/sources.item.tsx:1-14](file://frontend/antdx/sources/item/sources.item.tsx#L1-L14) + +### Event Handling Mechanism + +The Sources component supports two main events: + +```mermaid +flowchart TD +Start([Component Initialization]) --> BindEvents["Bind event listeners"] +BindEvents --> ExpandEvent["Expand event listener"] +BindEvents --> ClickEvent["Click event listener"] +ExpandEvent --> ExpandCallback["bind_expand_event callback"] +ClickEvent --> ClickCallback["bind_click_event callback"] +ExpandCallback --> UpdateInternal["Update internal state"] +ClickCallback --> UpdateInternal +UpdateInternal --> End([Event handling complete]) +``` + +**Diagram sources** + +- [backend/modelscope_studio/components/antdx/sources/**init**.py:18-25](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L18-L25) + +**Event Types:** + +- `expand`: Triggered when the user expands or collapses a data source +- `click`: Triggered when the user clicks a data source item + +**Section sources** + +- [backend/modelscope_studio/components/antdx/sources/**init**.py:18-25](file://backend/modelscope_studio/components/antdx/sources/__init__.py#L18-L25) + +### Slot System + +The Sources component supports a flexible slot system, allowing developers to customize different parts of the component: + +```mermaid +graph LR +subgraph "Slot System" +Items[items slot
Main item list] +Default[default slot
Default item content] +Title[title slot
Custom title] +end +subgraph "Render Logic" +Resolve[Resolve slot content] +Fallback[Fall back to default content] +Render[Render final result] +end +Items --> Resolve +Default --> Resolve +Title --> Resolve +Resolve --> Fallback +Fallback --> Render +``` + +**Diagram sources** + +- [frontend/antdx/sources/sources.tsx:12-36](file://frontend/antdx/sources/sources.tsx#L12-L36) + +**Supported Slots:** + +- `items`: Main data source item list +- `default`: Default item content +- `title`: Custom title content + +**Section sources** + +- [frontend/antdx/sources/sources.tsx:12-36](file://frontend/antdx/sources/sources.tsx#L12-L36) + +## Dependency Analysis + +The dependency relationship of the Sources component is relatively straightforward, primarily depending on Ant Design X and related utility libraries: + +```mermaid +graph TB +subgraph "External Dependencies" +AntDX[@ant-design/x
Ant Design X Core Components] +SveltePreprocess[@svelte-preprocess-react
Svelte-React Bridge] +Utils[@utils/*
Utility Function Library] +end +subgraph "Internal Dependencies" +Component[ModelScopeLayoutComponent
Base Component Class] +Context[createItemsContext
Context Management] +ResolveDir[resolve_frontend_dir
Path Resolution] +end +subgraph "Sources Components" +Sources[AntdXSources] +SourcesItem[AntdXSourcesItem] +end +Sources --> AntDX +Sources --> SveltePreprocess +Sources --> Utils +Sources --> Component +Sources --> Context +Sources --> ResolveDir +SourcesItem --> AntDX +SourcesItem --> SveltePreprocess +SourcesItem --> Context +``` + +**Diagram sources** + +- [frontend/antdx/sources/sources.tsx:1-5](file://frontend/antdx/sources/sources.tsx#L1-L5) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py:4-16](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py#L4-L16) + +**Main Dependency Notes:** + +- `@ant-design/x`: Provides the core Sources component implementation +- `@svelte-preprocess-react`: Implements the bridge between Svelte and React +- `@utils/*`: Provides common utility functions such as renderItems, createItemsContext, etc. + +**Section sources** + +- [frontend/antdx/sources/sources.tsx:1-5](file://frontend/antdx/sources/sources.tsx#L1-L5) +- [backend/modelscope_studio/components/antdx/components.py:30-31](file://backend/modelscope_studio/components/antdx/components.py#L30-L31) + +## Performance Considerations + +The Sources component was designed with performance optimization in mind: + +### Render Optimization + +1. **Memoization**: Uses React's useMemo to cache computation results and avoid unnecessary re-renders +2. **Conditional rendering**: Only renders component content when needed +3. **Lazy loading**: Delays content loading through an event-driven approach + +### Memory Management + +1. **Component unmounting**: Properly handles the mounting and unmounting process +2. **Event cleanup**: Cleans up event listeners when the component is destroyed +3. **State management**: Uses a minimal state update strategy + +### Data Processing Optimization + +1. **Batch updates**: Supports batch data source updates +2. **Incremental rendering**: Only updates the parts that have changed +3. **Virtualization support**: Provides virtualized rendering capability for large data source sets + +## Troubleshooting Guide + +### Common Issues and Solutions + +**Issue 1: Component not displaying** + +- Check whether the Ant Design X dependency is correctly installed +- Confirm that the frontend directory path resolution is correct +- Verify the component's visibility property setting + +**Issue 2: Events not responding** + +- Confirm that event listeners are correctly bound +- Check parameter passing in event callback functions +- Verify the component's event handling logic + +**Issue 3: Slot content not displaying** + +- Check whether the slot name is correct +- Confirm the method of passing slot content +- Verify the rendering priority of slots + +**Issue 4: Performance issues** + +- Check the number and complexity of data sources +- Optimize the rendering logic of data sources +- Consider using virtualized rendering + +**Section sources** + +- [docs/components/antdx/sources/demos/basic.py:1-46](file://docs/components/antdx/sources/demos/basic.py#L1-L46) + +## Conclusion + +The Sources component is a well-designed, fully functional component that successfully combines the powerful capabilities of Ant Design X with the ModelScope Studio ecosystem. The component has the following advantages: + +1. **Clear architecture**: Layered design with clear responsibilities +2. **Strong extensibility**: Supports rich configuration options and slot system +3. **Excellent performance**: Ensures good performance through multiple optimization techniques +4. **Easy to use**: Provides an intuitive API and complete documentation support + +This component is particularly suitable for displaying references, managing link sources, and similar scenarios in AI chat applications, providing developers with powerful data source display capabilities. Through reasonable event handling and the slot system, developers can easily customize the behavior and appearance of the component to meet various complex business requirements. diff --git a/.wiki/en/Ant Design X Components/Data Components/Think Component.md b/.wiki/en/Ant Design X Components/Data Components/Think Component.md new file mode 100644 index 00000000..01c4c113 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Data Components/Think Component.md @@ -0,0 +1,457 @@ +# Think Component + + +**Files Referenced in This Document** +- [think/__init__.py](file://backend/modelscope_studio/components/antdx/think/__init__.py) +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [think.tsx](file://frontend/antdx/think/think.tsx) +- [Index.svelte](file://frontend/antdx/think/Index.svelte) +- [thought-chain.tsx](file://frontend/antdx/thought-chain/thought-chain.tsx) +- [context.ts](file://frontend/antdx/thought-chain/context.ts) +- [__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The Think component is a core visualization component in ModelScope Studio for visualizing and tracking the thinking process of AI agents. Built on top of Ant Design X's Think component, it is specifically designed to display the reasoning process, decision chain, and intermediate thinking results of agents in conversational systems. + +The main design philosophy of this component is to provide transparent visualization of AI decision-making processes, allowing users to understand how AI agents think, analyze, and make decisions. Through detailed recording and display of the thinking process, users can better trust and optimize the behavior of AI systems. + +## Project Structure + +The Think component is located in the antdx component library within the project architecture, adopting a frontend/backend separated design pattern: + +```mermaid +graph TB +subgraph "Backend Layer" +Backend[ModelScope Studio Backend] +ThinkPy[Think Python Component] +ComponentsPy[Component Registration] +end +subgraph "Frontend Layer" +Frontend[ModelScope Studio Frontend] +ThinkTSX[Think TypeScript Component] +IndexSvelte[Think Svelte Wrapper] +ThoughtChain[ThoughtChain Component] +end +subgraph "External Dependencies" +AntDX[Ant Design X] +Gradio[Gradio Framework] +end +Backend --> ThinkPy +ThinkPy --> ComponentsPy +Frontend --> ThinkTSX +ThinkTSX --> IndexSvelte +IndexSvelte --> AntDX +ComponentsPy --> Frontend +Gradio --> Backend +``` + +**Diagram sources** + +- [think/**init**.py:1-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L1-L79) +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +**Section sources** + +- [think/**init**.py:1-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L1-L79) +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Core Components + +### Think Component Class Definition + +The Think component inherits from `ModelScopeLayoutComponent`, providing complete property configuration and event handling: + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++visible : bool ++elem_id : str ++elem_classes : list[str] ++elem_style : dict ++render : bool ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdXThink { ++additional_props : dict ++icon : str ++styles : dict ++class_names : dict ++loading : str|bool ++title : str ++root_class_name : str ++default_expanded : bool ++expanded : bool ++blink : bool ++EVENTS : list ++SLOTS : list ++FRONTEND_DIR : str ++skip_api : bool +} +class Think { ++slots : dict ++props : ThinkProps ++loading : ReactNode ++icon : ReactNode ++title : ReactNode +} +ModelScopeLayoutComponent <|-- AntdXThink +AntdXThink --> Think : "Frontend rendering" +``` + +**Diagram sources** + +- [think/**init**.py:8-79](file://backend/modelscope_studio/components/antdx/think/__init__.py#L8-L79) +- [think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +### Key Property Configuration + +The Think component supports rich configuration options, including: + +- **Basic properties**: Icon, title, style class names +- **State properties**: Loading state, expanded state, blink effect +- **Event properties**: Expand event binding +- **Slot system**: Supports three slots: loading, icon, title + +**Section sources** + +- [think/**init**.py:21-60](file://backend/modelscope_studio/components/antdx/think/__init__.py#L21-L60) +- [think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +## Architecture Overview + +The Think component adopts a layered architecture design, achieving clear separation between frontend and backend: + +```mermaid +sequenceDiagram +participant User as User Interface +participant Backend as Backend Think Component +participant Frontend as Frontend Wrapper +participant AntDX as Ant Design X +participant React as React Component +User->>Backend : Create Think component instance +Backend->>Backend : Configure component properties +Backend->>Frontend : Render frontend wrapper +Frontend->>AntDX : Load Ant Design X Think +AntDX->>React : Render React component +React->>React : Process slot content +React->>User : Display thinking process +Note over Backend,React : Complete component lifecycle management +``` + +**Diagram sources** + +- [Index.svelte:10-67](file://frontend/antdx/think/Index.svelte#L10-L67) +- [think.tsx:6-21](file://frontend/antdx/think/think.tsx#L6-L21) + +### Component Lifecycle + +```mermaid +flowchart TD +Start([Component Initialization]) --> Config[Configure properties] +Config --> Render[Render frontend wrapper] +Render --> LoadAntDX[Load Ant Design X] +LoadAntDX --> ProcessSlots[Process slot content] +ProcessSlots --> Display[Display thinking process] +Display --> EventBind[Bind event listeners] +EventBind --> Ready[Component ready] +Ready --> UserInteraction[User interaction] +UserInteraction --> UpdateState[Update state] +UpdateState --> ReRender[Re-render] +ReRender --> Ready +Ready --> Cleanup[Component destruction] +Cleanup --> End([End]) +``` + +**Diagram sources** + +- [think/**init**.py:12-16](file://backend/modelscope_studio/components/antdx/think/__init__.py#L12-L16) +- [Index.svelte:55-68](file://frontend/antdx/think/Index.svelte#L55-L68) + +## Detailed Component Analysis + +### Backend Implementation Analysis + +The backend Think component implements the complete Gradio component interface: + +#### Event System + +The component supports the expand event for handling changes in expanded state: + +```mermaid +stateDiagram-v2 +[*] --> Collapsed : Default collapsed state +Collapsed --> Expanded : Trigger expand event +Expanded --> Collapsed : User clicks to collapse +Collapsed --> Blinking : Set blink property +Blinking --> Collapsed : Blink effect ends +note right of Expanded +In the expanded state, the thinking process +can be viewed in detail +end note +note right of Blinking +The blink effect is used to attract attention, +typically indicating a new thinking process +end note +``` + +**Diagram sources** + +- [think/**init**.py:12-16](file://backend/modelscope_studio/components/antdx/think/__init__.py#L12-L16) + +#### Slot System + +The component supports three slots, allowing flexible content customization: + +| Slot Name | Type | Purpose | Default Value | +| --------- | --------- | ------------------------ | ------------- | +| loading | ReactNode | Custom loading indicator | props.loading | +| icon | ReactNode | Custom icon | props.icon | +| title | ReactNode | Custom title content | props.title | + +**Section sources** + +- [think/**init**.py:18-19](file://backend/modelscope_studio/components/antdx/think/__init__.py#L18-L19) +- [think.tsx:12-16](file://frontend/antdx/think/think.tsx#L12-L16) + +### Frontend Implementation Analysis + +The frontend uses a hybrid architecture of Svelte + React: + +#### Svelte Wrapper + +Index.svelte provides complete component wrapping functionality: + +```mermaid +classDiagram +class IndexSvelte { ++props : ComponentProps ++slots : Slots ++proceedProps : ProcessedProps ++AwaitedThink : ComponentPromise ++getProps() ++getSlots() ++processProps() +} +class ThinkWrapper { ++style : CSSProperties ++className : string ++id : string ++slots : dict ++children : ReactNode +} +IndexSvelte --> ThinkWrapper : "Render" +ThinkWrapper --> AntDThink : "Contains" +``` + +**Diagram sources** + +- [Index.svelte:12-67](file://frontend/antdx/think/Index.svelte#L12-L67) + +#### React Component Bridge + +think.tsx implements the bridge from Svelte to React: + +- Uses `sveltify` to convert React components to Svelte components +- Handles slot content through `ReactSlot` +- Directly calls Ant Design X's native Think component + +**Section sources** + +- [Index.svelte:1-69](file://frontend/antdx/think/Index.svelte#L1-L69) +- [think.tsx:1-24](file://frontend/antdx/think/think.tsx#L1-L24) + +### ThoughtChain Integration + +The Think component and the ThoughtChain component form a complete thinking process visualization system: + +```mermaid +graph LR +subgraph "Thinking Process" +Think[Think Component] +ThoughtChain[ThoughtChain Component] +end +subgraph "Data Flow" +Items[Thinking Item List] +Status[State Management] +Timeline[Timeline] +end +subgraph "UI Display" +ChainView[Chain View] +DetailView[Detail View] +TimelineView[Timeline View] +end +Think --> Items +ThoughtChain --> Items +Items --> Status +Status --> Timeline +Timeline --> ChainView +Timeline --> DetailView +Timeline --> TimelineView +``` + +**Diagram sources** + +- [thought-chain.tsx:11-40](file://frontend/antdx/thought-chain/thought-chain.tsx#L11-L40) +- [context.ts:1-7](file://frontend/antdx/thought-chain/context.ts#L1-L7) + +**Section sources** + +- [thought-chain.tsx:1-43](file://frontend/antdx/thought-chain/thought-chain.tsx#L1-L43) +- [context.ts:1-7](file://frontend/antdx/thought-chain/context.ts#L1-L7) + +## Dependency Analysis + +### Component Dependency Diagram + +```mermaid +graph TB +subgraph "Core Dependencies" +Gradio[Gradio Framework] +AntD[Ant Design X] +Svelte[Svelte Framework] +end +subgraph "Internal Dependencies" +Utils[Development Utilities] +Layout[Layout Component] +Slot[Slot System] +end +subgraph "Think Component" +ThinkPy[Python Component] +ThinkTSX[TypeScript Component] +ThinkSvelte[Svelte Wrapper] +end +Gradio --> ThinkPy +AntD --> ThinkTSX +Svelte --> ThinkSvelte +Utils --> ThinkPy +Layout --> ThinkPy +Slot --> ThinkTSX +ThinkPy --> ThinkTSX +ThinkTSX --> ThinkSvelte +``` + +**Diagram sources** + +- [components.py:34-34](file://backend/modelscope_studio/components/antdx/components.py#L34-L34) +- [**init**.py:34-34](file://backend/modelscope_studio/components/antdx/__init__.py#L34-L34) + +### Version Compatibility + +The component ensures compatibility with the following versions: + +- **Gradio**: >= 4.0.0 +- **Ant Design X**: >= 0.1.0 +- **Svelte**: >= 3.54.0 +- **React**: >= 18.0.0 + +**Section sources** + +- [components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Performance Considerations + +### Render Optimization + +1. **Lazy loading mechanism**: The frontend uses dynamic imports to reduce initial load time +2. **Conditional rendering**: Only renders the component when visible, avoiding unnecessary computation +3. **Slot optimization**: Efficiently handles slot content through ReactSlot + +### Memory Management + +- Automatically cleans up event listeners when the component is destroyed +- Proper props handling to avoid memory leaks +- Uses useMemo to optimize rendering of complex data structures + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### Component Not Displaying + +**Symptom**: The Think component is created successfully but does not appear in the interface + +**Possible Causes**: + +1. The `visible` property is set to False +2. The `render` property is set to False +3. Parent container style issues + +**Solutions**: + +- Check the component's `visible` and `render` properties +- Verify the parent container's CSS styles +- Confirm the component is imported correctly + +#### Slot Content Not Working + +**Symptom**: Custom loading, icon, title slot content is not displayed + +**Possible Causes**: + +1. Incorrect slot name +2. Slot content type mismatch +3. Incorrect slot passing method + +**Solutions**: + +- Confirm the slot names are 'loading', 'icon', or 'title' +- Verify that slot content is a valid ReactNode +- Check the slot passing syntax + +#### Event Handling Abnormal + +**Symptom**: The expand event cannot be triggered normally + +**Possible Causes**: + +1. Event listener not correctly bound +2. Event callback function error +3. Component state issue + +**Solutions**: + +- Check the EVENTS array configuration +- Verify the event callback function logic +- Confirm component state synchronization + +**Section sources** + +- [think/**init**.py:12-16](file://backend/modelscope_studio/components/antdx/think/__init__.py#L12-L16) + +## Conclusion + +As a core visualization component of ModelScope Studio, the Think component successfully achieves transparent display of AI thinking processes. Through carefully designed architecture and rich configuration options, this component provides developers and users with powerful thinking process tracking capabilities. + +### Main Advantages + +1. **Complete visualization**: Provides various thinking process display methods from simple to complex +2. **Flexible configuration**: Supports rich property configuration and slot customization +3. **Good performance**: Uses modern frontend technology stack to ensure a smooth user experience +4. **Easy to integrate**: Seamlessly integrates with the Gradio ecosystem + +### Application Scenarios + +- **AI assistants**: Display the reasoning process and decision chain of agents +- **Data analysis**: Visualize data exploration and analysis thinking +- **Code generation**: Display the thinking process and logic of code generation +- **Multimodal applications**: Support thinking processes for various input types such as text and images + +This component lays a solid foundation for building trustworthy and explainable AI applications and is an indispensable important component of modern AI products. diff --git a/.wiki/en/Ant Design X Components/Expression Components/Attachments Component.md b/.wiki/en/Ant Design X Components/Expression Components/Attachments Component.md new file mode 100644 index 00000000..3a7966c7 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Expression Components/Attachments Component.md @@ -0,0 +1,731 @@ +# Attachments Component + + +**Files Referenced in This Document** +- [Index.svelte](file://frontend/antdx/attachments/Index.svelte) +- [attachments.tsx](file://frontend/antdx/attachments/attachments.tsx) +- [__init__.py](file://backend/modelscope_studio/components/antdx/attachments/__init__.py) +- [README-zh_CN.md](file://docs/components/antdx/attachments/README-zh_CN.md) +- [basic.py](file://docs/components/antdx/attachments/demos/basic.py) +- [combination.py](file://docs/components/antdx/attachments/demos/combination.py) +- [file_card.py](file://docs/components/antdx/attachments/demos/file_card.py) +- [multimodal-input.tsx](file://frontend/pro/multimodal-input/multimodal-input.tsx) +- [upload.ts](file://frontend/utils/upload.ts) +- [file-card.tsx](file://frontend/antdx/file-card/file-card.tsx) +- [base.tsx](file://frontend/antdx/file-card/base.tsx) +- [app.py](file://docs/components/antdx/attachments/app.py) +- [package.json](file://frontend/antdx/attachments/package.json) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Attachments component is a powerful file management and upload solution provided by ModelScope Studio. Built on top of Ant Design X's Attachments component, it provides complete file upload, preview, management, and deletion capabilities. + +### Key Features + +- **Multi-format Support**: Supports uploading and previewing of multiple file types including images, documents, audio, and video +- **Drag and Drop Upload**: Provides an intuitive drag-and-drop file upload experience +- **Batch Management**: Supports simultaneous upload and management of multiple files +- **Real-time Preview**: Built-in file preview functionality with thumbnail and full-content viewing +- **Flexible Configuration**: Rich configuration options and customization capabilities +- **Responsive Design**: Adapts to various screen sizes and devices + +## Project Structure + +The Attachments component adopts a frontend-backend separation architecture, primarily consisting of the following parts: + +```mermaid +graph TB +subgraph "Frontend Layer" +A[Index.svelte
Component Entry] +B[attachments.tsx
Core Implementation] +C[file-card.tsx
File Card Component] +D[base.tsx
Base File Card] +E[multimodal-input.tsx
Multimodal Input Integration] +end +subgraph "Backend Layer" +F[__init__.py
Python Component Wrapper] +end +subgraph "Utility Layer" +G[upload.ts
File URL Handling] +H[package.json
Package Config] +end +A --> B +B --> C +C --> D +B --> G +F --> A +E --> B +``` + +**Diagram Sources** + +- [Index.svelte:1-98](file://frontend/antdx/attachments/Index.svelte#L1-L98) +- [attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) +- [**init**.py:21-64](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L21-L64) + +**Section Sources** + +- [Index.svelte:1-98](file://frontend/antdx/attachments/Index.svelte#L1-L98) +- [attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) +- [**init**.py:21-64](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L21-L64) + +## Core Components + +### Component Architecture + +The Attachments component uses a layered architecture design ensuring good maintainability and extensibility: + +```mermaid +classDiagram +class Attachments { ++FileData[] items ++upload(files) Promise~FileData[]~ ++onValueChange(value) void ++onChange(value) void ++disabled boolean ++maxCount number ++imageProps ImageProps ++placeholder Function|Object ++showUploadList Object|boolean ++beforeUpload Function ++customRequest Function ++previewFile Function ++isImageUrl Function ++itemRender Function ++iconRender Function ++data Object|Function ++getDropContainer Function +} +class FileCard { ++BaseFileCardProps props ++imageProps ImageProps ++description ReactNode ++icon ReactNode ++mask ReactNode ++spinProps SpinProps ++children ReactNode +} +class BaseFileCard { ++string|FileData src ++string rootUrl ++string apiPrefix ++resolveFileSrc() string +} +class UploadUtils { ++getFetchableUrl() string ++getFileUrl() string|undefined ++isUrl() boolean +} +Attachments --> FileCard : "renders" +FileCard --> BaseFileCard : "inherits" +Attachments --> UploadUtils : "uses" +``` + +**Diagram Sources** + +- [attachments.tsx:36-83](file://frontend/antdx/attachments/attachments.tsx#L36-L83) +- [file-card.tsx:17-34](file://frontend/antdx/file-card/file-card.tsx#L17-L34) +- [base.tsx:9-13](file://frontend/antdx/file-card/base.tsx#L9-L13) +- [upload.ts:12-44](file://frontend/utils/upload.ts#L12-L44) + +### Data Flow Processing + +The component internally implements a complex data flow processing mechanism: + +```mermaid +sequenceDiagram +participant U as User +participant A as Attachments Component +participant P as Preview System +participant S as Server +participant V as Validator +U->>A : Select/drag files +A->>V : Call beforeUpload validation +V-->>A : Validation result +A->>A : Update temporary file list +A->>S : Call upload function +S-->>A : Return FileData array +A->>A : Merge file list +A->>P : Render preview +P-->>U : Display file preview +U->>A : Delete file +A->>S : Send delete request +S-->>A : Confirm deletion +A->>A : Update state +``` + +**Diagram Sources** + +- [attachments.tsx:275-354](file://frontend/antdx/attachments/attachments.tsx#L275-L354) + +**Section Sources** + +- [attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) +- [file-card.tsx:1-127](file://frontend/antdx/file-card/file-card.tsx#L1-L127) +- [base.tsx:1-44](file://frontend/antdx/file-card/base.tsx#L1-L44) + +## Architecture Overview + +### Overall Architecture Design + +The Attachments component uses a modern frontend architecture pattern combining the advantages of React and Svelte: + +```mermaid +graph TD +subgraph "User Interface Layer" +UI[User Interface] +SL[Svelte Component] +RC[React Component] +end +subgraph "Business Logic Layer" +AM[Attachment Manager] +VM[View Model] +CM[Configuration Manager] +end +subgraph "Data Access Layer" +FS[File System] +CS[Cloud Storage] +LS[Local Storage] +end +subgraph "Utility Service Layer" +PU[Preview Service] +US[Upload Service] +VS[Validation Service] +end +UI --> SL +SL --> RC +RC --> AM +AM --> VM +AM --> CM +AM --> FS +AM --> CS +AM --> LS +AM --> PU +AM --> US +AM --> VS +``` + +**Diagram Sources** + +- [Index.svelte:1-98](file://frontend/antdx/attachments/Index.svelte#L1-L98) +- [attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) + +### Component Lifecycle + +```mermaid +stateDiagram-v2 +[*] --> Initializing +Initializing --> LoadingConfig +LoadingConfig --> RenderingUI +RenderingUI --> WaitingForInteraction +WaitingForInteraction --> FileUpload +FileUpload --> ValidatingFile +ValidatingFile --> Uploading +Uploading --> UploadComplete +UploadComplete --> RenderingPreview +RenderingPreview --> WaitingForInteraction +WaitingForInteraction --> FileDeletion +FileDeletion --> DeletionConfirm +DeletionConfirm --> UpdatingState +UpdatingState --> WaitingForInteraction +WaitingForInteraction --> ErrorHandling +ErrorHandling --> WaitingForInteraction +WaitingForInteraction --> [*] +``` + +**Diagram Sources** + +- [attachments.tsx:132-354](file://frontend/antdx/attachments/attachments.tsx#L132-L354) + +## Detailed Component Analysis + +### Core Functionality Implementation + +#### File Upload Mechanism + +The component implements a complete file upload flow supporting multiple upload strategies: + +```mermaid +flowchart TD +Start([Start Upload]) --> Validate[Validate File] +Validate --> Valid{Validation Passed?} +Valid --> |No| Error[Return Error] +Valid --> |Yes| Prepare[Prepare Upload] +Prepare --> Upload[Execute Upload] +Upload --> Progress[Update Progress] +Progress --> Complete{Upload Complete?} +Complete --> |No| Progress +Complete --> |Yes| Process[Process Response] +Process --> Success[Upload Success] +Success --> End([End]) +Error --> End +``` + +**Diagram Sources** + +- [attachments.tsx:292-354](file://frontend/antdx/attachments/attachments.tsx#L292-L354) + +#### File Preview System + +The component integrates powerful file preview functionality supporting visualization of multiple file types: + +| File Type | Preview Support | Special Features | +| --------- | ----------------------- | ---------------------------- | +| Image | ✅ Full Preview | Zoom, rotate, download | +| Document | ✅ Thumbnail Preview | Online view, download | +| PDF | ✅ Page-by-page Preview | Navigation, search | +| Audio | ✅ Player | Playback control, volume | +| Video | ✅ Player | Playback control, fullscreen | +| Archive | ✅ Thumbnail | Extract preview | + +#### Batch Management Features + +The component provides efficient batch file management capabilities: + +```mermaid +graph LR +subgraph "Batch Operations" +BA[Batch Select] +BM[Batch Delete] +BC[Batch Download] +BR[Batch Rename] +end +subgraph "State Management" +FS[File State] +SS[Selection State] +PS[Processing State] +end +BA --> SS +BM --> FS +BC --> FS +BR --> FS +SS --> PS +FS --> PS +``` + +**Diagram Sources** + +- [attachments.tsx:304-342](file://frontend/antdx/attachments/attachments.tsx#L304-L342) + +**Section Sources** + +- [attachments.tsx:275-409](file://frontend/antdx/attachments/attachments.tsx#L275-L409) + +### Configuration Options + +#### Basic Configuration + +| Option | Type | Default | Description | +| ---------------- | ----------------- | -------- | --------------------------------------- | +| `disabled` | boolean | false | Whether to disable upload functionality | +| `maxCount` | number | Infinity | Maximum number of files | +| `multiple` | boolean | true | Whether to support multi-file upload | +| `accept` | string | \* | Accepted file types | +| `showUploadList` | boolean \| object | true | Whether to show the upload list | + +#### Advanced Configuration + +| Option | Type | Default | Description | +| --------------- | -------- | ------- | --------------------------------- | +| `beforeUpload` | Function | - | Validation function before upload | +| `customRequest` | Function | - | Custom upload request | +| `previewFile` | Function | - | Custom file preview | +| `isImageUrl` | Function | - | Determine if it is an image URL | +| `itemRender` | Function | - | Custom file item rendering | +| `iconRender` | Function | - | Custom icon rendering | + +#### Preview Configuration + +| Option | Type | Default | Description | +| ---------------------------------- | --------- | ------- | ------------------------ | +| `imageProps.preview.mask` | ReactNode | - | Preview mask layer | +| `imageProps.preview.closeIcon` | ReactNode | - | Close button icon | +| `imageProps.preview.toolbarRender` | Function | - | Custom toolbar rendering | +| `imageProps.preview.imageRender` | Function | - | Custom image rendering | + +**Section Sources** + +- [attachments.tsx:36-83](file://frontend/antdx/attachments/attachments.tsx#L36-L83) + +### Event Callback Mechanism + +The component provides a rich event callback interface: + +```mermaid +sequenceDiagram +participant C as Caller +participant A as Attachments Component +participant H as Callback Handler +C->>A : Bind event listeners +A->>H : Register callback functions +Note over A,H : User interaction triggers events +A->>H : Trigger onChange event +H-->>A : Return processing result +A->>H : Trigger onRemove event +H-->>A : Return processing result +A->>H : Trigger onValueChange event +H-->>A : Return processing result +``` + +**Diagram Sources** + +- [**init**.py:27-43](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L27-L43) + +#### Event Types + +| Event Name | Trigger Timing | Parameters | Description | +| ---------- | ------------------ | ---------- | ---------------------------------------------- | +| `change` | File state changes | FileData[] | Triggered when the file list changes | +| `remove` | File deleted | FileData | Triggered when a file is deleted | +| `preview` | File preview | FileData | Triggered when a file starts previewing | +| `download` | File download | FileData | Triggered when a file starts downloading | +| `drop` | File dragged | FileData[] | Triggered when files are dragged into the area | + +**Section Sources** + +- [**init**.py:27-43](file://backend/modelscope_studio/components/antdx/attachments/__init__.py#L27-L43) + +### Error Handling Mechanism + +The component implements a comprehensive error handling system: + +```mermaid +flowchart TD +Start([Start Processing]) --> Try[Execute Operation] +Try --> Success{Operation Successful?} +Success --> |Yes| Complete[Complete Processing] +Success --> |No| Catch[Catch Error] +Catch --> Type{Error Type?} +Type --> |Network Error| Network[Handle Network Error] +Type --> |Permission Error| Auth[Handle Permission Error] +Type --> |Format Error| Format[Handle Format Error] +Type --> |Size Error| Size[Handle Size Error] +Type --> |Other Error| Other[Handle Other Error] +Network --> Retry[Retry Mechanism] +Auth --> Login[Re-login] +Format --> Fix[Fix Format] +Size --> Reduce[Reduce File Size] +Other --> Report[Report Issue] +Retry --> Try +Login --> Try +Fix --> Try +Reduce --> Try +Report --> End([End]) +Complete --> End +``` + +**Diagram Sources** + +- [attachments.tsx:350-354](file://frontend/antdx/attachments/attachments.tsx#L350-L354) + +**Section Sources** + +- [attachments.tsx:350-354](file://frontend/antdx/attachments/attachments.tsx#L350-L354) + +## Dependency Analysis + +### External Dependencies + +The component depends on several key external libraries: + +```mermaid +graph TB +subgraph "Core Dependencies" +AX[@ant-design/x
Ant Design X Component Library] +ANTD[antd
Ant Design Component Library] +GRADIO[@gradio/client
Gradio Client] +REACT[react
React Framework] +end +subgraph "Utility Libraries" +Lodash[lodash-es
Utility Functions] +Classnames[classnames
Class Name Handling] +SveltePreprocess[svelte-preprocess-react
Svelte Preprocessing] +end +subgraph "Component Dependencies" +FileCard[FileCard Component] +Utils[Utility Functions] +Hooks[React Hooks] +end +Attachments --> AX +Attachments --> ANTD +Attachments --> GRADIO +Attachments --> REACT +Attachments --> Lodash +Attachments --> Classnames +Attachments --> SveltePreprocess +Attachments --> FileCard +Attachments --> Utils +Attachments --> Hooks +``` + +**Diagram Sources** + +- [attachments.tsx:1-17](file://frontend/antdx/attachments/attachments.tsx#L1-L17) +- [package.json:1-15](file://frontend/antdx/attachments/package.json#L1-L15) + +### Internal Module Dependencies + +```mermaid +graph TD +subgraph "Frontend Modules" +A[Index.svelte] +B[attachments.tsx] +C[file-card.tsx] +D[base.tsx] +E[upload.ts] +F[multimodal-input.tsx] +end +subgraph "Backend Modules" +G[__init__.py] +end +A --> B +B --> C +C --> D +B --> E +F --> B +G --> A +``` + +**Diagram Sources** + +- [Index.svelte:1-98](file://frontend/antdx/attachments/Index.svelte#L1-L98) +- [attachments.tsx:1-413](file://frontend/antdx/attachments/attachments.tsx#L1-L413) + +**Section Sources** + +- [package.json:1-15](file://frontend/antdx/attachments/package.json#L1-L15) +- [Index.svelte:1-98](file://frontend/antdx/attachments/Index.svelte#L1-L98) + +## Performance Considerations + +### Upload Performance Optimization + +The component was designed with performance optimization in mind: + +- **Concurrent Upload Control**: Limit the number of simultaneously uploading files via `maxCount` +- **Progress Display**: Display upload progress in real time to improve user experience +- **Memory Management**: Clean up temporary file data promptly to avoid memory leaks +- **Caching Strategy**: Cache already-uploaded files to reduce redundant uploads + +### Preview Performance Optimization + +```mermaid +graph LR +subgraph "Preview Optimization Strategies" +A[Lazy Loading Preview] +B[Thumbnail Generation] +C[Virtual Scrolling] +D[Preloading Mechanism] +end +subgraph "Performance Metrics" +E[Initial Load Time] +F[Memory Usage] +G[CPU Utilization] +H[Network Bandwidth] +end +A --> E +B --> F +C --> G +D --> H +``` + +### Memory Management + +The component implements intelligent memory management: + +- **File Object Reuse**: Reuse existing file objects to avoid redundant creation +- **Garbage Collection**: Release file data that is no longer in use in a timely manner +- **State Synchronization**: Maintain consistency between local state and server state + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### Upload Failure + +**Problem Description**: Error occurs during file upload + +**Possible Causes**: + +- Unstable network connection +- Unsupported file format +- File size exceeds limit +- Insufficient permissions + +**Solutions**: + +1. Check network connection status +2. Verify file format is in the `accept` list +3. Confirm file size does not exceed `maxSize` limit +4. Check user permission settings + +#### Preview Failure + +**Problem Description**: File cannot be previewed normally + +**Possible Causes**: + +- Browser compatibility issues +- File corruption +- URL parsing error + +**Solutions**: + +1. Try opening in a different browser +2. Re-upload the file +3. Check file integrity +4. Verify URL format is correct + +#### Performance Issues + +**Problem Description**: Component runs slowly or stutters + +**Possible Causes**: + +- Too many files +- Files are too large +- Insufficient memory + +**Solutions**: + +1. Reduce the number of simultaneously uploading files +2. Optimize file sizes +3. Increase system memory +4. Use `maxCount` to limit the number of files + +**Section Sources** + +- [attachments.tsx:350-354](file://frontend/antdx/attachments/attachments.tsx#L350-L354) + +### Debugging Tips + +#### Enable Debug Mode + +```javascript +// Enable detailed logging in development environment +const attachments = new Attachments({ + debug: true, + // other configs... +}); +``` + +#### Monitor Upload Progress + +```javascript +attachments.on('upload-progress', (progress) => { + console.log(`Upload progress: ${progress}%`); +}); +``` + +## Conclusion + +The Attachments component is a fully functional, high-performance file management solution. It not only provides basic file upload and preview capabilities, but also features advanced batch management, custom configuration, and error handling. + +### Key Advantages + +1. **Comprehensive Features**: Covers all core needs for file upload, preview, and management +2. **Easy to Use**: Clean API design for quick integration +3. **Highly Customizable**: Rich configuration options to meet various use cases +4. **Excellent Performance**: Optimized algorithms and architecture ensure a smooth user experience +5. **Stable and Reliable**: Comprehensive error handling and exception recovery mechanisms + +### Applicable Scenarios + +- Online document management systems +- File transfer in instant messaging applications +- Media management on content creation platforms +- File sharing on enterprise collaboration platforms +- Assignment submission systems on educational platforms + +## Appendix + +### API Reference + +#### Props + +| Property | Type | Required | Default | Description | +| ---------------- | ----------------- | -------- | -------- | -------------------------------------------------------- | +| `items` | FileData[] | Yes | [] | Current file list | +| `upload` | Function | Yes | - | Upload function, accepts RcFile[] and returns FileData[] | +| `onValueChange` | Function | No | - | Value change callback | +| `onChange` | Function | No | - | String path change callback | +| `disabled` | boolean | No | false | Whether to disable | +| `maxCount` | number | No | Infinity | Maximum number of files | +| `accept` | string | No | \* | Accepted file types | +| `multiple` | boolean | No | true | Whether multi-select is supported | +| `showUploadList` | boolean \| object | No | true | Whether to show the upload list | +| `imageProps` | ImageProps | No | - | Image preview configuration | + +#### Events + +| Event Name | Parameters | Description | +| ---------- | ---------- | --------------------- | +| `change` | FileData[] | File list changed | +| `remove` | FileData | File deleted | +| `preview` | FileData | File preview started | +| `download` | FileData | File download started | +| `drop` | FileData[] | File dragged | + +#### Slots + +| Slot Name | Parameters | Description | +| ---------------------------------- | ------------------------ | -------------------------- | +| `placeholder` | type: 'drop' \| 'inline' | Placeholder content | +| `placeholder.title` | type | Title content | +| `placeholder.description` | type | Description content | +| `placeholder.icon` | type | Icon content | +| `iconRender` | file, fileList | Custom icon rendering | +| `itemRender` | file, fileList | Custom file item rendering | +| `showUploadList.previewIcon` | file, fileList | Preview icon | +| `showUploadList.removeIcon` | file, fileList | Delete icon | +| `showUploadList.downloadIcon` | file, fileList | Download icon | +| `showUploadList.extra` | file, fileList | Extra actions | +| `imageProps.placeholder` | file, fileList | Image placeholder | +| `imageProps.preview.mask` | file, fileList | Preview mask | +| `imageProps.preview.closeIcon` | file, fileList | Close icon | +| `imageProps.preview.toolbarRender` | file, fileList | Toolbar rendering | +| `imageProps.preview.imageRender` | file, fileList | Image rendering | + +### Best Practices + +#### Performance Optimization Recommendations + +1. **Set `maxCount` Appropriately**: Set a suitable maximum file count based on the application scenario +2. **Use Lazy Loading**: For large numbers of files, consider pagination or virtual scrolling +3. **Optimize File Sizes**: Compress images and video files before upload +4. **Caching Strategy**: Establish a caching mechanism for frequently used files + +#### Security Considerations + +1. **File Type Validation**: Also perform file type checking on the server side +2. **Size Limits**: Set reasonable file size upper limits +3. **Virus Scanning**: Perform security scanning on uploaded files +4. **Permission Control**: Ensure only authorized users can access files + +#### User Experience Optimization + +1. **Progress Feedback**: Provide clear upload progress indicators +2. **Error Messages**: Friendly error messages and solutions +3. **Batch Operations**: Support batch selection and operations +4. **Responsive Design**: Adapt to various devices and screen sizes + +**Section Sources** + +- [README-zh_CN.md:1-10](file://docs/components/antdx/attachments/README-zh_CN.md#L1-L10) +- [basic.py:1-51](file://docs/components/antdx/attachments/demos/basic.py#L1-L51) +- [combination.py:1-75](file://docs/components/antdx/attachments/demos/combination.py#L1-L75) +- [file_card.py:1-72](file://docs/components/antdx/attachments/demos/file_card.py#L1-L72) diff --git a/.wiki/en/Ant Design X Components/Expression Components/Expression Components.md b/.wiki/en/Ant Design X Components/Expression Components/Expression Components.md new file mode 100644 index 00000000..b0bd77fb --- /dev/null +++ b/.wiki/en/Ant Design X Components/Expression Components/Expression Components.md @@ -0,0 +1,322 @@ +# Expression Components + + +**Files Referenced in This Document** +- [frontend/antdx/attachments/attachments.tsx](file://frontend/antdx/attachments/attachments.tsx) +- [frontend/antdx/sender/sender.tsx](file://frontend/antdx/sender/sender.tsx) +- [frontend/antdx/suggestion/suggestion.tsx](file://frontend/antdx/suggestion/suggestion.tsx) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Usability Recommendations](#performance-and-usability-recommendations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document covers the Ant Design X Expression Components, focusing on three main components: + +- Attachments: Responsible for file upload, preview, list management, and placeholder rendering +- Sender: Responsible for message input, paste-to-upload, submission, and input state synchronization +- Suggestion: Responsible for command completion, trigger strategies, context forwarding, and popup container configuration + +The documentation provides a complete explanation from system architecture, data flow, processing logic, and inter-component collaboration mechanisms to usage examples and troubleshooting recommendations, helping developers quickly understand and correctly integrate these components. + +## Project Structure + +The frontend components of Ant Design X are located under frontend/antdx and are organized in a modular fashion. The backend Python wrapper layer exports unified aliases in backend/modelscope_studio/components/antdx, making them directly accessible in the Python ecosystem. + +```mermaid +graph TB +subgraph "Backend Wrapper Layer" +PY_API["Python Export Aliases
components.py / __init__.py"] +end +subgraph "Frontend Ant Design X Components" +ATT["Attachments
File Upload and Management"] +SND["Sender
Message Input and Submission"] +SUG["Suggestion
Quick Commands and Completion"] +end +PY_API --> ATT +PY_API --> SND +PY_API --> SUG +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/components.py:7-32](file://backend/modelscope_studio/components/antdx/components.py#L7-L32) +- [backend/modelscope_studio/components/antdx/**init**.py:7-41](file://backend/modelscope_studio/components/antdx/__init__.py#L7-L41) + +Section Sources + +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) + +## Core Components + +- Attachments + - Responsibility: Encapsulates @ant-design/x Attachments, providing upload hooks, placeholder rendering, enhanced image preview, custom icons, max count control, remove callback, and value change notifications + - Key Capabilities: Pre-upload validation, concurrent upload state, file list deduplication and merging, error fallback +- Sender + - Responsibility: Encapsulates @ant-design/x Sender, providing two-way value binding, paste-file-upload, skill panel (skill) slot-based configuration, and submit events that only fire when the suggestion panel is closed + - Key Capabilities: Input change synchronization, paste file upload, slot-based header/footer/prefix/suffix, skill hints and closable configuration +- Suggestion + - Responsibility: Encapsulates @ant-design/x Suggestion, supporting dynamic items rendering, slot-based label/icon/extra areas, popup container customization, and controlled/uncontrolled open state switching + - Key Capabilities: Trigger strategy hooks, context forwarding, keyboard event interception and forwarding, popup container positioning + +Section Sources + +- [frontend/antdx/attachments/attachments.tsx:36-410](file://frontend/antdx/attachments/attachments.tsx#L36-L410) +- [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) +- [frontend/antdx/suggestion/suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) + +## Architecture Overview + +The three work together: the user types text in Sender and pastes files; Sender hands the files to the upload function to generate persistable file information, which is then passed back via callback to the upper layer. Meanwhile, Suggestion provides command completion; only when it is closed does Sender actually submit the content, preventing accidental submission. + +```mermaid +sequenceDiagram +participant U as "User" +participant S as "Sender" +participant A as "Attachments" +participant P as "Upload Function (upload)" +participant C as "Upper Application" +U->>S : "Input text/paste file" +S->>P : "Paste file upload" +P-->>S : "Return file info list" +S-->>C : "onPasteFile(urls)" +S-->>C : "onChange(value)" +S->>C : "onSubmit(...)" +Note over S,C : "Submit only fires when Suggestion is closed" +U->>A : "Drag/select file" +A->>P : "Call upload hook" +P-->>A : "Return file info" +A-->>C : "onValueChange(items)" +A-->>C : "onChange(paths)" +``` + +Diagram Sources + +- [frontend/antdx/sender/sender.tsx:135-138](file://frontend/antdx/sender/sender.tsx#L135-L138) +- [frontend/antdx/attachments/attachments.tsx:329-348](file://frontend/antdx/attachments/attachments.tsx#L329-L348) +- [frontend/antdx/suggestion/suggestion.tsx:135-140](file://frontend/antdx/suggestion/suggestion.tsx#L135-L140) + +## Component Details + +### Attachments Component + +- Key Features + - File Upload: Accepts arrays of native file objects via the upload hook, returns file info arrays; supports maxCount to control single/multi-file mode + - Preview Enhancement: imageProps.preview supports mask, closeIcon, toolbarRender, imageRender with slot-based and function-based configuration + - List Management: Automatic deduplication (based on uid/url/path), status marking (done/uploading), remove callback, and value change notifications + - Placeholder Rendering: placeholder supports slot-based and function-based title/description/icon + - Interaction Protection: Disables interactions during upload to prevent re-submission +- Data Flow and Key Paths + - Change Handling: The onChange handler distinguishes between add/remove branches; for additions, it first injects a temporary "uploading" state, then calls upload, and finally merges results and fires callbacks + - Image Preview: Highly customizable via getContainer, toolbarRender, imageRender, etc. in imageProps.preview + - Display List: Icons and extras in showUploadList support slot-based and function-based overrides +- Error Handling + - Captures upload exceptions and restores upload state to prevent UI freeze +- Complexity and Performance + - Deduplication and state merging are O(n), suitable for medium-scale file lists + - Slot-based rendering computes on demand, avoiding unnecessary re-renders + +```mermaid +flowchart TD +Start(["Enter onChange"]) --> IsRemove{"Is it a remove operation?"} +IsRemove --> |Yes| RemoveFlow["Execute onRemove callback
Update fileList and fire callback"] +IsRemove --> |No| AddFlow["Enter add flow"] +AddFlow --> BeforeUpload["beforeUpload hook (optional)"] +BeforeUpload --> BeforeUploadOk{"Returns true?"} +BeforeUploadOk --> |No| End(["End"]) +BeforeUploadOk --> |Yes| SetUploading["Set uploading state"] +SetUploading --> Filter["Filter incomplete files and truncate by maxCount"] +Filter --> TempList["Generate temporary uploading entries"] +TempList --> CallUpload["Call upload hook"] +CallUpload --> Merge["Merge returned file info into final list"] +Merge --> UpdateState["Update fileList and fire onValueChange/onChange"] +UpdateState --> End +``` + +Diagram Sources + +- [frontend/antdx/attachments/attachments.tsx:275-354](file://frontend/antdx/attachments/attachments.tsx#L275-L354) + +Section Sources + +- [frontend/antdx/attachments/attachments.tsx:36-410](file://frontend/antdx/attachments/attachments.tsx#L36-L410) + +### Sender Component + +- Key Features + - Input Binding: Two-way synchronization of value and onChange, supports external controlled mode + - Paste Upload: onPasteFile hands pasted file collections to the upload hook and passes back file path arrays + - Skill Panel: skill.title/toolTip/closable supports slot-based and function-based configuration + - Submit Control: onSubmit is only triggered when Suggestion is closed, preventing accidental submission when the suggestion panel is open + - Slot-based Layout: header/footer/prefix/suffix support ReactSlot injection +- Key Interactions + - Uses useSuggestionOpenContext to get the suggestion panel open/close state, determining whether to allow submission + - formatResult/customRender in slotConfig are wrapped as functions via createFunction +- Error Handling + - Paste upload failure does not affect the input box state, only logs are recorded +- Performance and Complexity + - Value changes and slot rendering are both lightweight, suitable for high-frequency input scenarios + +```mermaid +sequenceDiagram +participant U as "User" +participant S as "Sender" +participant Ctx as "Suggestion Open Context" +participant P as "Upload Function (upload)" +U->>S : "Paste file" +S->>P : "upload(files)" +P-->>S : "Return file info" +S-->>U : "onPasteFile(urls)" +U->>S : "Click submit/press Enter" +S->>Ctx : "Read suggestion panel state" +alt Suggestion panel is closed +S-->>U : "onSubmit(...)" +else Suggestion panel is open +S-->>U : "Ignore submission" +end +``` + +Diagram Sources + +- [frontend/antdx/sender/sender.tsx:126-130](file://frontend/antdx/sender/sender.tsx#L126-L130) +- [frontend/antdx/sender/sender.tsx:135-138](file://frontend/antdx/sender/sender.tsx#L135-L138) + +Section Sources + +- [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) + +### Suggestion Component + +- Key Features + - Dynamic items: Supports two sources — an items function or slot-based items/default; slot items take priority + - Slot-based Rendering: label/icon/extra/children support ReactSlot injection and patchSlots processing + - Trigger Strategy: The shouldTrigger hook can intercept keyboard events to implement custom trigger conditions + - Popup Container: getPopupContainer supports function-based and slot-based configuration for positioning in complex layouts + - State Control: open can be controlled (internally self-managed when undefined); onOpenChange forwards the underlying state +- Context and Events + - Passes the current active item and keyboard event handling to the child tree via SuggestionContext and SuggestionOpenContext + - In the children render function, the real children are hidden and only shown when a slot exists +- Performance and Complexity + - items rendering is computed on demand; slot-based patch only applies to necessary fields + +```mermaid +flowchart TD +Init(["Initialize items rendering"]) --> Resolve["Resolve items/default slots"] +Resolve --> ItemsFn["items function (optional)"] +ItemsFn --> Merge["Merge into final items array"] +Merge --> Render["Render each item's label/icon/extra subitems"] +Render --> Patch["patchSlots applies slot-based overrides"] +Patch --> Open["Control display based on open state"] +Open --> Trigger["shouldTrigger intercepts keyboard events"] +Trigger --> Done(["Complete"]) +``` + +Diagram Sources + +- [frontend/antdx/suggestion/suggestion.tsx:89-121](file://frontend/antdx/suggestion/suggestion.tsx#L89-L121) +- [frontend/antdx/suggestion/suggestion.tsx:135-140](file://frontend/antdx/suggestion/suggestion.tsx#L135-L140) + +Section Sources + +- [frontend/antdx/suggestion/suggestion.tsx:64-162](file://frontend/antdx/suggestion/suggestion.tsx#L64-L162) + +## Dependency Analysis + +- Backend Exports + - components.py and **init**.py uniformly export AntdXAttachments/AntdXSender/AntdXSuggestion and other components as Attachments/Sender/Suggestion for direct use on the Python side +- Frontend Encapsulation + - All three components bridge @ant-design/x native components via sveltify to React components supporting slots and function-based configuration + - Uses utility hooks such as useFunction/useValueChange/useTargets to achieve parameter functionalization and value synchronization +- Inter-component Coupling + - Sender and Suggestion are loosely coupled via context: Sender only submits when Suggestion is closed, avoiding interaction conflicts + - Attachments and Sender are decoupled via the upload callback: upload logic is provided by the upper layer; components only handle UI and state + +```mermaid +graph LR +PY["Python Export Aliases"] --> ATT["Frontend Attachments"] +PY --> SND["Frontend Sender"] +PY --> SUG["Frontend Suggestion"] +ATT --> AX["@ant-design/x Attachments"] +SND --> AX2["@ant-design/x Sender"] +SUG --> AX3["@ant-design/x Suggestion"] +SND -- "Suggestion panel state" --> CTX["Suggestion Open Context"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/components.py:7-32](file://backend/modelscope_studio/components/antdx/components.py#L7-L32) +- [backend/modelscope_studio/components/antdx/**init**.py:7-41](file://backend/modelscope_studio/components/antdx/__init__.py#L7-L41) +- [frontend/antdx/sender/sender.tsx:72-72](file://frontend/antdx/sender/sender.tsx#L72-L72) + +Section Sources + +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/antdx/**init**.py:1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) + +## Performance and Usability Recommendations + +- Attachments Upload + - Set maxCount appropriately to avoid memory pressure from uploading too many files at once + - Perform format/size validation in beforeUpload to reduce invalid requests + - Use imageProps.preview's getContainer to mount the preview overlay to the appropriate container, avoiding scroll penetration +- Sender + - Use throttle/debounce strategies for high-frequency input (can be implemented in the upper layer) to reduce onChange frequency + - In multi-slot scenarios, reuse function-based configurations as much as possible to reduce slot rendering overhead +- Suggestion + - Keep the items rendering structure stable to avoid frequent DOM reconstruction + - Only perform necessary checks in shouldTrigger to avoid blocking keyboard events +- Global + - In complex layouts, prioritize using getPopupContainer for suggestion panel positioning to ensure visibility + - Provide friendly prompts for upload failures to avoid user confusion + +## Troubleshooting Guide + +- Attachments Cannot Delete + - Check whether the remove branch in onChange is being prematurely returned + - Confirm there is a matching uid entry in validFileList +- Upload Not Responding + - Confirm the upload hook return value is Promise and does not throw errors + - Check whether maxCount is limiting the number of new additions +- Preview Not Displaying + - Confirm imageProps.preview configuration is enabled and the container returned by getContainer exists +- Submission Blocked + - Check whether Suggestion's open state is true; Sender only triggers onSubmit when it is closed +- Paste Upload Failure + - Check in the onPasteFile callback whether the path array returned by upload is empty + - Check the console for exception stacks + +Section Sources + +- [frontend/antdx/attachments/attachments.tsx:275-354](file://frontend/antdx/attachments/attachments.tsx#L275-L354) +- [frontend/antdx/sender/sender.tsx:126-138](file://frontend/antdx/sender/sender.tsx#L126-L138) +- [frontend/antdx/suggestion/suggestion.tsx:135-140](file://frontend/antdx/suggestion/suggestion.tsx#L135-L140) + +## Conclusion + +The Expression Components are designed around a closed loop of "input—upload—completion—submit", achieving high extensibility through slot-based and function-based configuration, while isolating interactions via context to avoid accidental triggers. Attachments manages the file lifecycle, Sender controls input and submission timing, and Suggestion provides intelligent completion and trigger strategies. Together, they can satisfy typical scenarios such as multimodal input, attachment handling, and command execution. + +## Appendix: Usage Examples and Best Practices + +- Multimodal Input and Attachment Handling + - In Sender, listen to onChange/onPasteFile, convert pasted files into persistent paths via the upload hook, then submit text and file paths together + - Configure beforeUpload/isImageUrl and other hooks in Attachments to improve the upload experience +- Quick Commands and User Behavior Analysis + - Use Suggestion's items and shouldTrigger to implement command completion; use getPopupContainer to ensure popup positioning + - Record user open/close behavior of the suggestion panel via onOpenChange and SuggestionOpenContext for subsequent analysis +- Component Collaboration + - When Suggestion is open, Sender should not submit; when Suggestion is closed, trigger onSubmit to avoid interfering with user input + - Implement flexible UI combinations via slots (header/footer/prefix/suffix/skill.\*) diff --git a/.wiki/en/Ant Design X Components/Expression Components/Sender Component.md b/.wiki/en/Ant Design X Components/Expression Components/Sender Component.md new file mode 100644 index 00000000..2c56e537 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Expression Components/Sender Component.md @@ -0,0 +1,315 @@ +# Sender Component + + +**Files Referenced in This Document** +- [frontend/antdx/sender/sender.tsx](file://frontend/antdx/sender/sender.tsx) +- [frontend/antdx/sender/header/sender.header.tsx](file://frontend/antdx/sender/header/sender.header.tsx) +- [frontend/antdx/sender/switch/sender.switch.tsx](file://frontend/antdx/sender/switch/sender.switch.tsx) +- [backend/modelscope_studio/components/antdx/sender/__init__.py](file://backend/modelscope_studio/components/antdx/sender/__init__.py) +- [backend/modelscope_studio/components/antdx/sender/header/__init__.py](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py) +- [backend/modelscope_studio/components/antdx/sender/switch/__init__.py](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py) +- [docs/components/antdx/sender/README.md](file://docs/components/antdx/sender/README.md) +- [docs/components/antdx/attachments/demos/combination.py](file://docs/components/antdx/attachments/demos/combination.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Configuration and Usage Examples](#appendix-configuration-and-usage-examples) + +## Introduction + +The Sender component is an input component designed for chat scenarios, providing message sending, input handling, paste-to-upload, submit type control, header panel, and switch control capabilities. On the frontend it is based on Ant Design X's Sender implementation, and it provides a Python API on the backend through a Gradio adaptation layer. It supports slot-based extensions (such as prefix/suffix, header, footer, skill panel, etc.) and event binding. + +## Project Structure + +The Sender component consists of a "frontend Svelte wrapper + backend Python component" and is accompanied by Header and Switch subcomponents; documentation and examples are located in the docs directory. + +```mermaid +graph TB +subgraph "Frontend" +F_sender["frontend/antdx/sender/sender.tsx"] +F_header["frontend/antdx/sender/header/sender.header.tsx"] +F_switch["frontend/antdx/sender/switch/sender.switch.tsx"] +end +subgraph "Backend" +B_sender["backend/.../antdx/sender/__init__.py"] +B_header["backend/.../antdx/sender/header/__init__.py"] +B_switch["backend/.../antdx/sender/switch/__init__.py"] +end +subgraph "Documentation and Examples" +D_readme["docs/components/antdx/sender/README.md"] +D_demo["docs/components/antdx/attachments/demos/combination.py"] +end +F_sender --> B_sender +F_header --> B_header +F_switch --> B_switch +D_readme --> B_sender +D_demo --> B_sender +``` + +**Diagram Sources** + +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) +- [frontend/antdx/sender/header/sender.header.tsx:1-21](file://frontend/antdx/sender/header/sender.header.tsx#L1-L21) +- [frontend/antdx/sender/switch/sender.switch.tsx:1-34](file://frontend/antdx/sender/switch/sender.switch.tsx#L1-L34) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:1-149](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L1-L149) +- [backend/modelscope_studio/components/antdx/sender/header/**init**.py:1-74](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py#L1-L74) +- [backend/modelscope_studio/components/antdx/sender/switch/**init**.py:1-81](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py#L1-L81) +- [docs/components/antdx/sender/README.md:1-10](file://docs/components/antdx/sender/README.md#L1-L10) +- [docs/components/antdx/attachments/demos/combination.py:1-75](file://docs/components/antdx/attachments/demos/combination.py#L1-L75) + +**Section Sources** + +- [frontend/antdx/sender/sender.tsx:1-174](file://frontend/antdx/sender/sender.tsx#L1-L174) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:1-149](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L1-L149) + +## Core Components + +- Sender (Main Component) + - Manages input value, intercepts submit events, handles paste file upload, renders slots, and configures skill panel (including Tooltip and closable). + - Exposes callbacks and properties such as value, onChange, onSubmit, and onPasteFile. +- Sender.Header (Header Panel) + - Supports title slot, optional expand/collapse, and closable features. +- Sender.Switch (Switch Control) + - Supports custom "checked/unchecked" text and icon slots. + +**Section Sources** + +- [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) +- [frontend/antdx/sender/header/sender.header.tsx:7-18](file://frontend/antdx/sender/header/sender.header.tsx#L7-L18) +- [frontend/antdx/sender/switch/sender.switch.tsx:7-31](file://frontend/antdx/sender/switch/sender.switch.tsx#L7-L31) + +## Architecture Overview + +Sender bridges Ant Design X's Sender in the frontend via a Svelte wrapper, and exposes it to the Gradio ecosystem via a Python component in the backend. Its data flow and event flow are as follows: + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Frontend Sender (Svelte)" +participant ADX as "Ant Design X Sender" +participant BK as "Backend Sender (Python)" +U->>FE : Input/paste/click send +FE->>FE : useValueChange(value/onValueChange) +FE->>ADX : Render and pass props (including slots/skill config) +ADX-->>FE : onChange(value) +FE-->>BK : Change event (Gradio) +ADX-->>FE : onSubmit(args) +FE->>FE : Check if suggestion is open (block auto-submit) +FE-->>BK : submit event (Gradio) +FE->>FE : onPasteFile(files) -> upload(files) -> onPasteFile(urls) +``` + +**Diagram Sources** + +- [frontend/antdx/sender/sender.tsx:68-138](file://frontend/antdx/sender/sender.tsx#L68-L138) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:21-59](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L21-L59) + +## Detailed Component Analysis + +### Main Component: Sender (Message Sending and Input Handling) + +- Input and State + - Uses controlled value and onChange combined with useValueChange to manage externally provided value and internal changes. +- Submit Logic + - onSubmit is intercepted: if the suggestion panel is open, the external submit is not triggered to avoid accidental submission. + - External submit events are reported via the Gradio event system. +- Paste Upload + - onPasteFile receives a native File list, calls the upload callback to perform the upload, and passes the returned file path array back to onPasteFile. +- Slots and Advanced Features + - Supports suffix/header/prefix/footer slots; supports skill.title, skill.toolTip.title, skill.closable.closeIcon slots. + - Skill configuration supports Tooltip and closable behavior; Tooltip's afterOpenChange and getPopupContainer can be wrapped as functions. +- Event Mapping + - Events such as change, submit, cancel, allow_speech_recording_change, key_down/key_press, focus/blur, paste, paste_file, skill_closable_close are all mapped to Gradio events. + +```mermaid +flowchart TD +Start(["Enter Sender Render"]) --> Slots["Resolve slots and skill config"] +Slots --> Render["Render Ant Design X Sender"] +Render --> OnChange["onChange(value) -> Update local value"] +Render --> OnSubmit["onSubmit(args)"] +OnSubmit --> CheckOpen{"Is suggestion panel open?"} +CheckOpen --> |Yes| BlockSubmit["Block external submit"] +CheckOpen --> |No| FireSubmit["Fire external submit (Gradio)"] +Render --> Paste["onPasteFile(files)"] +Paste --> Upload["upload(files) -> FileData[]"] +Upload --> OnPasteFile["onPasteFile(urls) callback"] +OnChange --> End(["Complete"]) +FireSubmit --> End +BlockSubmit --> End +OnPasteFile --> End +``` + +**Diagram Sources** + +- [frontend/antdx/sender/sender.tsx:68-138](file://frontend/antdx/sender/sender.tsx#L68-L138) + +**Section Sources** + +- [frontend/antdx/sender/sender.tsx:18-171](file://frontend/antdx/sender/sender.tsx#L18-L171) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:21-66](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L21-L66) + +### Subcomponent: Sender.Header (Header Panel) + +- Key Features + - Supports the title slot; all other attributes are forwarded to Ant Design X Header. + - The open_change event is mapped through Gradio. +- Usage Scenarios + - Used with Sender to insert attachments or extend the input area. + +**Section Sources** + +- [frontend/antdx/sender/header/sender.header.tsx:7-18](file://frontend/antdx/sender/header/sender.header.tsx#L7-L18) +- [backend/modelscope_studio/components/antdx/sender/header/**init**.py:12-20](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py#L12-L20) + +### Subcomponent: Sender.Switch (Switch Control) + +- Key Features + - Supports checkedChildren, unCheckedChildren, and icon slots for custom text and icons. + - The change event is mapped through Gradio. +- Usage Scenarios + - Controls voice input mode, quick submit mode, etc. + +**Section Sources** + +- [frontend/antdx/sender/switch/sender.switch.tsx:7-31](file://frontend/antdx/sender/switch/sender.switch.tsx#L7-L31) +- [backend/modelscope_studio/components/antdx/sender/switch/**init**.py:12-19](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py#L12-L19) + +### Class Relationship Diagram (Code Level) + +```mermaid +classDiagram +class AntdXSender { ++EVENTS ++SLOTS ++__init__(...) ++FRONTEND_DIR ++api_info() ++preprocess(payload) ++postprocess(value) +} +class AntdXSenderHeader { ++EVENTS ++SLOTS ++__init__(...) ++FRONTEND_DIR +} +class AntdXSenderSwitch { ++EVENTS ++SLOTS ++__init__(...) ++FRONTEND_DIR +} +AntdXSender --> AntdXSenderHeader : "contains" +AntdXSender --> AntdXSenderSwitch : "contains" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-128](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L128) +- [backend/modelscope_studio/components/antdx/sender/header/**init**.py:8-56](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py#L8-L56) +- [backend/modelscope_studio/components/antdx/sender/switch/**init**.py:8-63](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py#L8-L63) + +## Dependency Analysis + +- Frontend Dependencies + - Uses @svelte-preprocess-react to bridge React components to Svelte. + - Uses @ant-design/x's Sender/Header/Switch. + - Uses @gradio/client's FileData type and Gradio events. +- Backend Dependencies + - Based on Gradio's ModelScopeDataLayoutComponent/ModelScopeLayoutComponent abstraction for unified event and slot mapping. +- Documentation and Examples + - README provides basic example entry; combination examples demonstrate collaboration with Attachments, Badge, Button, and other components. + +```mermaid +graph LR +Svelte["Svelte Wrapper (Sender)"] --> ADX["Ant Design X Sender"] +Svelte --> Hooks["@utils/* hooks"] +Svelte --> Slot["ReactSlot Slots"] +Backend["Python Sender Component"] --> Gradio["Gradio Event System"] +Backend --> Frontend["Frontend Component Mapping"] +Docs["Documentation and Examples"] --> Backend +Docs --> Frontend +``` + +**Diagram Sources** + +- [frontend/antdx/sender/sender.tsx:1-10](file://frontend/antdx/sender/sender.tsx#L1-L10) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-128](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L128) +- [docs/components/antdx/sender/README.md:1-10](file://docs/components/antdx/sender/README.md#L1-L10) + +**Section Sources** + +- [frontend/antdx/sender/sender.tsx:1-10](file://frontend/antdx/sender/sender.tsx#L1-L10) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:14-128](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L14-L128) + +## Performance Considerations + +- Slots and Function Wrapping + - Tooltip callbacks and slots are wrapped as functions and rendered with ReactSlot to avoid unnecessary re-renders; it is recommended to cache or stabilize slot content in the upper layer. +- Submit Interception + - It is recommended to disable auto-submit when the suggestion panel is open to reduce invalid requests. +- File Upload + - onPasteFile should be processed asynchronously as much as possible to avoid blocking the UI; for large files, consider chunked or direct server-side upload strategies. + +## Troubleshooting Guide + +- Submit Unexpectedly Intercepted + - If submit is not triggered due to the suggestion panel not being closed, check the suggestion panel state or temporarily disable the interception logic. +- Paste Upload Not Working + - Confirm the upload callback correctly returns a FileData array containing a path field; the onPasteFile callback should receive a string array. +- Slot Content Not Displaying + - Confirm the slot names match those supported by the component (e.g., skill.title, skill.toolTip.title, skill.closable.closeIcon). +- Events Not Firing + - Check whether the backend EVENTS list contains the corresponding event name and whether the frontend is correctly bound. + +**Section Sources** + +- [frontend/antdx/sender/sender.tsx:126-138](file://frontend/antdx/sender/sender.tsx#L126-L138) +- [backend/modelscope_studio/components/antdx/sender/**init**.py:21-59](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L21-L59) + +## Conclusion + +The Sender component, through its integrated frontend and backend design, provides powerful input and submission capabilities for chat scenarios. Combined with Header, Switch, and the slot system, it can be flexibly extended to support multimodal input and complex interactions. In practice, pay attention to event interception, slot stability, and the robustness of the upload process. + +## Appendix: Configuration and Usage Examples + +### Configuration Overview (Backend) + +- Basic Properties + - value/default_value/placeholder/loading/disabled/read_only/auto_size/submit_type, etc. +- Slots + - suffix/header/prefix/footer/skill.title/skill.toolTip.title/skill.closable.closeIcon. +- Events + - change, submit, cancel, allow_speech_recording_change, key_down/key_press, focus/blur, paste, paste_file, skill_closable_close. +- Subcomponents + - Header, Switch (each supporting corresponding slots and events). + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/sender/**init**.py:61-127](file://backend/modelscope_studio/components/antdx/sender/__init__.py#L61-L127) +- [backend/modelscope_studio/components/antdx/sender/header/**init**.py:19-54](file://backend/modelscope_studio/components/antdx/sender/header/__init__.py#L19-L54) +- [backend/modelscope_studio/components/antdx/sender/switch/**init**.py:18-61](file://backend/modelscope_studio/components/antdx/sender/switch/__init__.py#L18-L61) + +### Chatbot Integration Example (Overview) + +- Text Messages + - Use Sender as input, listen to the submit event to get text content, and combine with backend model inference to return results. +- Multimodal Content + - Collaborate with Sender.Header/Attachments; upload images/files via paste or drag; the path list returned by onPasteFile can be used for subsequent processing. +- Special Commands + - Parse input in onChange or submit, recognize commands like "/reset" and "/help", and execute corresponding logic. + +**Section Sources** + +- [docs/components/antdx/attachments/demos/combination.py:26-71](file://docs/components/antdx/attachments/demos/combination.py#L26-L71) +- [docs/components/antdx/sender/README.md:5-10](file://docs/components/antdx/sender/README.md#L5-L10) diff --git a/.wiki/en/Ant Design X Components/Expression Components/Suggestion Component.md b/.wiki/en/Ant Design X Components/Expression Components/Suggestion Component.md new file mode 100644 index 00000000..b686630f --- /dev/null +++ b/.wiki/en/Ant Design X Components/Expression Components/Suggestion Component.md @@ -0,0 +1,338 @@ +# Suggestion Component + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/suggestion/__init__.py](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py) +- [backend/modelscope_studio/components/antdx/suggestion/item/__init__.py](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py) +- [frontend/antdx/suggestion/suggestion.tsx](file://frontend/antdx/suggestion/suggestion.tsx) +- [frontend/antdx/suggestion/item/suggestion.item.tsx](file://frontend/antdx/suggestion/item/suggestion.item.tsx) +- [frontend/antdx/suggestion/context.ts](file://frontend/antdx/suggestion/context.ts) +- [docs/components/antdx/suggestion/README.md](file://docs/components/antdx/suggestion/README.md) +- [backend/modelscope_studio/components/pro/chatbot/__init__.py](file://backend/modelscope_studio/components/pro/chatbot/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Interaction Features](#performance-and-interaction-features) +8. [Usage Examples and Best Practices](#usage-examples-and-best-practices) +9. [Troubleshooting](#troubleshooting) +10. [Conclusion](#conclusion) + +## Introduction + +The Suggestion component provides capabilities such as "quick commands", "intelligent completion", "context-aware suggestions", and "personalized recommendations" in AI assistant conversation scenarios. Based on Ant Design X's Suggestion capability and bridged via React wrapper and Gradio layout components, it implements: + +- Instruction Definition: Organized as "suggestion items" supporting multi-dimensional information such as labels, icons, and extra content. +- Trigger Conditions: Can be controlled by input keyboard events or external state to open/close the panel. +- Execution Logic: Triggers callbacks after selecting a suggestion, enabling subsequent processing on the Python side. +- Control Mode: Supports both controlled and uncontrolled modes; the open state can be set directly from the Python side. +- Dynamic Updates: The suggestion list can be dynamically generated via slots or functions and can be hot-updated at runtime. + +This component is widely used in interactive scenarios requiring "quick actions" such as chatbots, code assistants, and content creation. + +## Project Structure + +The Suggestion component is composed of a backend Python component and a frontend React implementation, unified through a context system for slot rendering and dynamic data injection. + +```mermaid +graph TB +subgraph "Backend Python" +PY_SUG["AntdXSuggestion
Component Class"] +PY_ITEM["AntdXSuggestionItem
Suggestion Item Class"] +end +subgraph "Frontend React" +FE_SUG["Suggestion
React Wrapper"] +FE_ITEM["SuggestionItem
Item Wrapper"] +CTX["context.ts
items Context"] +end +PY_SUG --> FE_SUG +PY_ITEM --> FE_ITEM +FE_SUG --> CTX +FE_ITEM --> CTX +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/suggestion/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py#L8-L68) +- [frontend/antdx/suggestion/suggestion.tsx:64-165](file://frontend/antdx/suggestion/suggestion.tsx#L64-L165) +- [frontend/antdx/suggestion/item/suggestion.item.tsx:7-22](file://frontend/antdx/suggestion/item/suggestion.item.tsx#L7-L22) +- [frontend/antdx/suggestion/context.ts:1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/suggestion/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py#L8-L68) +- [frontend/antdx/suggestion/suggestion.tsx:64-165](file://frontend/antdx/suggestion/suggestion.tsx#L64-L165) +- [frontend/antdx/suggestion/item/suggestion.item.tsx:7-22](file://frontend/antdx/suggestion/item/suggestion.item.tsx#L7-L22) +- [frontend/antdx/suggestion/context.ts:1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) + +## Core Components + +- AntdXSuggestion (Backend Component) + - Supported Events: select (item selected), open_change (panel open/close). + - Supported Slots: items, children. + - Key Properties: items (suggestion list), block (block-level display), open (controlled open/close), should_trigger (custom trigger), root style class name and inline styles, etc. + - Frontend Mapping: resolve_frontend_dir("suggestion", type="antdx"). +- AntdXSuggestionItem (Backend Suggestion Item) + - Supported Slots: label, icon, extra. + - Key Properties: value, label, extra, icon, key. + - Frontend Mapping: resolve_frontend_dir("suggestion", "item", type="antdx"). + +Both components declare skip_api=True, indicating they do not participate in the standard API flow but instead complete interactions through events and slots. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/suggestion/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py#L8-L68) + +## Architecture Overview + +Suggestion wraps Ant Design X's Suggestion component in the frontend via React, combined with a slot system and context to implement suggestion item rendering and event forwarding. In the backend, it bridges through Gradio layout components to support Python-side control and event binding. + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Frontend Suggestion" +participant ADX as "Ant Design X Suggestion" +participant CTX as "Items Context" +participant PY as "Backend AntdXSuggestion" +U->>FE : Input text/press key +FE->>ADX : Render suggestion panel +FE->>CTX : Resolve items slots +CTX-->>FE : Return suggestion item collection +FE->>ADX : Inject items and callbacks +U->>FE : Select a suggestion item +FE->>PY : Trigger select event +PY-->>FE : Callback handled on Python side +FE-->>U : Update UI/execute action +``` + +**Diagram Sources** + +- [frontend/antdx/suggestion/suggestion.tsx:77-162](file://frontend/antdx/suggestion/suggestion.tsx#L77-L162) +- [frontend/antdx/suggestion/context.ts:1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:18-27](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L18-L27) + +## Component Details + +### Backend Component: AntdXSuggestion + +- Event Binding + - select: Triggered when a suggestion item is selected; event binding is enabled on the backend via internal flags. + - open_change: Triggered when the panel open/close state changes, facilitating controlled/uncontrolled switching. +- Slot Support + - items: Suggestion item collection, dynamically generated via slots or functions. + - children: Used to wrap host elements such as input boxes, combined with should_trigger to customize trigger logic. +- Key Property Points + - items: Can be a string, list, or function; function form supports dynamic computation. + - open: In controlled mode, the panel open/close is explicitly set from the Python side. + - should_trigger: Custom keyboard event trigger determining when to show the suggestion panel. + - Styles: Supports class_names, styles, root_class_name, etc. +- Lifecycle + - preprocess/postprocess/example_payload/example_value all return empty values, indicating this component does not participate in data serialization. + +```mermaid +classDiagram +class AntdXSuggestion { ++EVENTS ++SLOTS ++items ++block ++open ++should_trigger ++root_class_name ++class_names ++styles ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +class AntdXSuggestionItem { ++EVENTS ++SLOTS ++value ++label ++extra ++icon ++key ++skip_api +} +AntdXSuggestion --> AntdXSuggestionItem : "uses" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) +- [backend/modelscope_studio/components/antdx/suggestion/item/**init**.py:8-68](file://backend/modelscope_studio/components/antdx/suggestion/item/__init__.py#L8-L68) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-86](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L86) + +### Frontend Implementation: Suggestion (React Wrapper) + +- Slots and Context + - Uses withItemsContextProvider to provide an items context, supporting both default and items slot sets. + - Converts slot content into suggestion item structures via renderItems and patchSlots. +- Dynamic Suggestion List + - items can be a function or slot resolution result; falls back to the default slot if empty. + - Uses useMemoizedEqualValue and useMemo to optimize rendering and comparison. +- Trigger and Open/Close + - shouldTrigger: Triggers onTrigger as needed in onKeyDown to determine whether to show the panel. + - open: Supports both props.open uncontrolled mode and internal state controlled mode. +- Event Forwarding + - onOpenChange: Determines whether to update internal state based on the presence of props.open. + - children: Injects context and forwards events via SuggestionChildrenWrapper. + +```mermaid +flowchart TD +Start(["Enter Suggestion Render"]) --> ResolveItems["Resolve items slots/functions"] +ResolveItems --> ItemsEmpty{"Are items empty?"} +ItemsEmpty -- Yes --> Fallback["Fall back to default slot"] +ItemsEmpty -- No --> UseProvided["Use provided items function/array"] +Fallback --> BuildList["Build suggestion item list"] +UseProvided --> BuildList +BuildList --> PatchSlots["patchSlots renders label/icon/extra sub-slots"] +PatchSlots --> SetOpen["Set/sync open state based on props.open"] +SetOpen --> Render["Render Ant Design X Suggestion and forward events"] +Render --> End(["Complete"]) +``` + +**Diagram Sources** + +- [frontend/antdx/suggestion/suggestion.tsx:77-162](file://frontend/antdx/suggestion/suggestion.tsx#L77-L162) +- [frontend/antdx/suggestion/context.ts:1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) + +**Section Sources** + +- [frontend/antdx/suggestion/suggestion.tsx:64-165](file://frontend/antdx/suggestion/suggestion.tsx#L64-L165) +- [frontend/antdx/suggestion/context.ts:1-7](file://frontend/antdx/suggestion/context.ts#L1-L7) + +### Frontend Implementation: SuggestionItem (Item Wrapper) + +- Renders slot default as suggestion item children via ItemHandler. +- Only allows the default slot, simplifying suggestion item content organization. + +**Section Sources** + +- [frontend/antdx/suggestion/item/suggestion.item.tsx:7-22](file://frontend/antdx/suggestion/item/suggestion.item.tsx#L7-L22) + +## Dependency Analysis + +- Component Coupling + - AntdXSuggestion depends on AntdXSuggestionItem as the suggestion item container. + - Frontend Suggestion depends on Ant Design X's Suggestion component and internal utility functions (such as patchSlots, renderItems). +- Data Flow + - Slots → Context Resolution → Suggestion Item Structure → Render → Event Callback → Python Processing. +- Event Chain + - Frontend onOpenChange/select → Backend event listener → Python callback. + +```mermaid +graph LR +PY_SUG["Backend AntdXSuggestion"] --> FE_SUG["Frontend Suggestion"] +PY_ITEM["Backend AntdXSuggestionItem"] --> FE_ITEM["Frontend SuggestionItem"] +FE_SUG --> ADX["Ant Design X Suggestion"] +FE_SUG --> CTX["Items Context"] +FE_ITEM --> CTX +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-16](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L16) +- [frontend/antdx/suggestion/suggestion.tsx:64-86](file://frontend/antdx/suggestion/suggestion.tsx#L64-L86) +- [frontend/antdx/suggestion/item/suggestion.item.tsx:7-18](file://frontend/antdx/suggestion/item/suggestion.item.tsx#L7-L18) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:11-16](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L11-L16) +- [frontend/antdx/suggestion/suggestion.tsx:64-86](file://frontend/antdx/suggestion/suggestion.tsx#L64-L86) +- [frontend/antdx/suggestion/item/suggestion.item.tsx:7-18](file://frontend/antdx/suggestion/item/suggestion.item.tsx#L7-L18) + +## Performance and Interaction Features + +- Render Optimization + - Uses useMemoizedEqualValue and useMemo to cache props and items, avoiding redundant renders. + - Only rebuilds the suggestion item list when items or slots change. +- Event Throttling + - Uses requestAnimationFrame in shouldTrigger to defer keyboard event processing, reducing main thread blocking risk. +- Open/Close Control + - Uncontrolled Mode: onOpenChange internally maintains the open state. + - Controlled Mode: Determined by props.open; onOpenChange only callbacks without modifying state. +- Slot Rendering + - patchSlots converts label/icon/extra sub-slots into corresponding fields, reducing cross-component communication costs. + +**Section Sources** + +- [frontend/antdx/suggestion/suggestion.tsx:36-57](file://frontend/antdx/suggestion/suggestion.tsx#L36-L57) +- [frontend/antdx/suggestion/suggestion.tsx:94-121](file://frontend/antdx/suggestion/suggestion.tsx#L94-L121) +- [frontend/antdx/suggestion/suggestion.tsx:135-140](file://frontend/antdx/suggestion/suggestion.tsx#L135-L140) + +## Usage Examples and Best Practices + +### Basic Usage (Documentation Examples) + +- The documentation provides three examples: basic, block-level display, and Python-controlled; reference: + - [docs/components/antdx/suggestion/README.md:5-10](file://docs/components/antdx/suggestion/README.md#L5-L10) + +### AI Assistant Scenario Examples (Conceptual Description) + +- Common Commands + - Define a set of fixed command suggestion items that execute on click, suitable for "quick start" scenarios. +- Context-aware Suggestions + - Dynamically generate suggestion lists based on current input or message history to improve relevance. +- Personalized Recommendations + - Based on user preferences or usage records, prioritize high-hit-rate suggestion items. +- Python-side Control + - Control panel show/hide by setting the open property; receive selected items via the select event and execute corresponding logic on the Python side. + +### Instruction Definition and Triggering + +- Instruction Definition + - Use AntdXSuggestionItem to organize suggestion items, supporting fields like label, icon, and extra. +- Trigger Conditions + - Can customize keyboard event triggers via should_trigger; can also control panel open/close via the open property. +- Execution Logic + - After selecting a suggestion item, the select event is triggered; the Python side can handle business logic in the callback. + +### Style and Interaction Customization + +- Styles + - Customize styles via class*names, styles, root_class_name, and backend elem*\* properties. +- Interaction + - The children slot is used to host input boxes and other host components, combined with should_trigger for more flexible trigger strategies. + +**Section Sources** + +- [docs/components/antdx/suggestion/README.md:5-10](file://docs/components/antdx/suggestion/README.md#L5-L10) +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:32-67](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L32-L67) +- [frontend/antdx/suggestion/suggestion.tsx:77-86](file://frontend/antdx/suggestion/suggestion.tsx#L77-L86) + +## Troubleshooting + +- Suggestion Items Not Displaying + - Check whether items is empty; if empty, confirm the default slot is correctly populated. + - Confirm slot names match (items/default). +- Panel Cannot Open + - If using controlled open, ensure the open state is correctly set on the Python side. + - Check whether should_trigger correctly implements the trigger logic. +- Events Not Firing + - Confirm event listeners are registered (select/open_change). + - Check whether Python-side callbacks are correctly bound. + +**Section Sources** + +- [frontend/antdx/suggestion/suggestion.tsx:87-121](file://frontend/antdx/suggestion/suggestion.tsx#L87-L121) +- [backend/modelscope_studio/components/antdx/suggestion/**init**.py:18-27](file://backend/modelscope_studio/components/antdx/suggestion/__init__.py#L18-L27) + +## Conclusion + +The Suggestion component, through its "backend layout component + frontend React wrapper + slot context" architecture, achieves high-performance, extensible quick command and intelligent completion capabilities. It supports controlled/uncontrolled open/close, dynamic suggestion lists, custom triggers, and event callbacks, making it suitable for various AI assistant and creation scenarios. It is recommended to dynamically generate suggestion items based on business context in practice, and implement closed-loop interactions through Python-side events. diff --git a/.wiki/en/Ant Design X Components/Feedback Components/ActionItem Component.md b/.wiki/en/Ant Design X Components/Feedback Components/ActionItem Component.md new file mode 100644 index 00000000..9af5a0fe --- /dev/null +++ b/.wiki/en/Ant Design X Components/Feedback Components/ActionItem Component.md @@ -0,0 +1,258 @@ +# ActionItem Component + + +**Files referenced in this document** +- [frontend/antdx/actions/action-item/Index.svelte](file://frontend/antdx/actions/action-item/Index.svelte) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [backend/modelscope_studio/components/antdx/actions/__init__.py](file://backend/modelscope_studio/components/antdx/actions/__init__.py) +- [backend/modelscope_studio/components/antdx/actions/action_item/__init__.py](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py) +- [backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js](file://backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Parameter Reference](#appendix-usage-examples-and-parameter-reference) + +## Introduction + +ActionItem is the core sub-component in the Ant Design X Actions component system, used to present a single clickable or interactive operation item within an Actions container. It supports multiple forms (text, icon, custom rendering), nested sub-menus, danger state, trigger strategies (hover/click), and the ability to extend content through slots. The component provides both a frontend Svelte wrapper layer and a backend Gradio Python encapsulation layer, forming a complete "Python configuration + frontend rendering" pipeline. + +## Project Structure + +The directory and related files for ActionItem are organized as follows: + +- Frontend wrapper layer (Svelte): frontend/antdx/actions/action-item/Index.svelte +- Frontend main component (React): frontend/antdx/actions/actions.tsx (contains the main Actions component) +- Backend encapsulation layer (Gradio Python): backend/modelscope_studio/components/antdx/actions/action_item/**init**.py +- Frontend bridge and runtime (build artifact): backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js +- Backend Actions main component: backend/modelscope_studio/components/antdx/actions/**init**.py + +```mermaid +graph TB +subgraph "Backend" +PY_INIT["Python: actions/__init__.py\nDefines AntdXActions"] +PY_ITEM["Python: action_item/__init__.py\nDefines AntdXActionsActionItem"] +end +subgraph "Frontend" +SVELTE["Svelte: action-item/Index.svelte\nWraps React component"] +REACT_MAIN["React: actions.tsx\nMain Actions component"] +RUNTIME["JS Runtime: actions.action-item-*.js\nBridge and rendering logic"] +end +PY_ITEM --> SVELTE +SVELTE --> RUNTIME +PY_INIT --> REACT_MAIN +REACT_MAIN --> RUNTIME +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:15-94](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L94) +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:10-62](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L10-L62) +- [frontend/antdx/actions/action-item/Index.svelte:14-98](file://frontend/antdx/actions/action-item/Index.svelte#L14-L98) +- [frontend/antdx/actions/actions.tsx:1-200](file://frontend/antdx/actions/actions.tsx#L1-L200) +- [backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js:419-431](file://backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js#L419-L431) + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:15-94](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L94) +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:10-62](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L10-L62) +- [frontend/antdx/actions/action-item/Index.svelte:14-98](file://frontend/antdx/actions/action-item/Index.svelte#L14-L98) +- [frontend/antdx/actions/actions.tsx:1-200](file://frontend/antdx/actions/actions.tsx#L1-L200) +- [backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js:419-431](file://backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js#L419-L431) + +## Core Components + +- AntdXActionsActionItem (backend encapsulation): Responsible for mapping Python-layer configuration to frontend components and declaring event and slot capabilities. +- ActionsActionItem (frontend bridge): Dynamically imported and rendered by the Svelte wrapper layer, responsible for handling slots, additional attributes, event mapping, and visibility control. +- Actions (main component): The frontend implementation of AntdXActions, hosting multiple ActionItems and providing advanced features such as dropdowns and animations. + +Key responsibilities and relationships + +- Backend encapsulation: Defines ActionItem parameters, events, and slots; determines frontend resource paths. +- Frontend wrapper: Parses props, handles slots, and generates the final props and slots required for rendering. +- Runtime bridge: Connects the Svelte/React render tree with the Gradio context, supporting event forwarding and context merging. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:10-62](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L10-L62) +- [frontend/antdx/actions/action-item/Index.svelte:19-84](file://frontend/antdx/actions/action-item/Index.svelte#L19-L84) +- [backend/modelscope_studio/components/antdx/actions/**init**.py:15-94](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L94) + +## Architecture Overview + +The complete call chain from Python to frontend for ActionItem is as follows: + +```mermaid +sequenceDiagram +participant Py as "Python : AntdXActionsActionItem" +participant Svelte as "Svelte : action-item/Index.svelte" +participant Runtime as "JS Runtime : actions.action-item-*.js" +participant React as "React : actions.tsx" +Py->>Svelte : Pass component configuration and event bindings +Svelte->>Runtime : Import and instantiate ActionsActionItem +Runtime->>React : Render React version of ActionItem +React-->>Runtime : Trigger event callbacks e.g. item_click +Runtime-->>Svelte : Events forwarded back to Gradio +Svelte-->>Py : Event result returned +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:15-21](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L15-L21) +- [frontend/antdx/actions/action-item/Index.svelte:14-98](file://frontend/antdx/actions/action-item/Index.svelte#L14-L98) +- [backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js:419-431](file://backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js#L419-L431) +- [frontend/antdx/actions/actions.tsx:1-200](file://frontend/antdx/actions/actions.tsx#L1-L200) + +## Detailed Component Analysis + +### Backend Encapsulation: AntdXActionsActionItem + +- Event binding + - item_click: Triggered when the operation item is clicked; the backend enables event binding via an internal flag. +- Slot support + - Supports slots such as label, icon, actionRender, and subItems for flexible extension. +- Key properties + - label, icon, danger, trigger_sub_menu_action, sub_items, action_render, as_item, key, etc. +- Resource location + - Uses resolve_frontend_dir("actions", "action-item", type="antdx") to specify the frontend resource directory. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:10-62](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L10-L62) +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:15-21](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L15-L21) +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:24](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L24) + +### Frontend Wrapper: Svelte Wrapper Layer + +- Dynamic import + - Dynamically loads the React version of ActionItem via importComponent. +- Props handling + - Uses getProps/processProps to extract and transform props, mapping item_click to the frontend event name. + - Merges elem_id, elem_classes, elem_style, additionalProps, etc. +- Slot handling + - Retrieves slot content via getSlots, setting withParams and clone for actionRender. +- Visibility and index + - Controls rendering based on visible; passes itemIndex and itemSlotKey to work with context. + +Section Sources + +- [frontend/antdx/actions/action-item/Index.svelte:14-98](file://frontend/antdx/actions/action-item/Index.svelte#L14-L98) + +### Runtime Bridge: JS Runtime + +- Component bridge + - Creates a Svelte-React bridge instance via Ge(...), mounting the React component to a shared root node. +- Context and slots + - Uses createItemsContext to provide the items context, supporting default slots and sub-item rendering. +- Event and property forwarding + - Merges Gradio context with props to ensure events and styles are correctly forwarded. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js:419-431](file://backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js#L419-L431) + +### Main Component: AntdXActions (Related) + +- Role + - Acts as the container for ActionItem, providing items list, variants, dropdown configuration, animations, and more. +- Events and slots + - Supports click, dropdown*open_change, dropdown_menu*\* event series, and multiple slots. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:15-94](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L15-L94) + +## Dependency Analysis + +- Backend to frontend + - AntdXActionsActionItem points to frontend resources via FRONTEND_DIR; the Svelte wrapper layer dynamically imports the corresponding JS module. +- Frontend to runtime + - The Svelte wrapper layer passes props and slots to the runtime bridge module, which is responsible for rendering the React component and integrating with the Gradio context. +- Inter-component collaboration + - ActionItem typically exists as a sub-item of Actions; the two together form an operation panel. + +```mermaid +graph LR +PY_ITEM["Python: ActionItem Encapsulation"] --> SVELTE["Svelte: Wrapper Layer"] +SVELTE --> RUNTIME["JS: Bridge and Rendering"] +RUNTIME --> REACT_MAIN["React: Actions Main Component"] +REACT_MAIN --> ACTIONITEM["React: ActionItem Sub-item"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:62](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L62) +- [frontend/antdx/actions/action-item/Index.svelte:14-98](file://frontend/antdx/actions/action-item/Index.svelte#L14-L98) +- [backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js:419-431](file://backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js#L419-L431) +- [frontend/antdx/actions/actions.tsx:1-200](file://frontend/antdx/actions/actions.tsx#L1-L200) + +## Performance Considerations + +- Dynamic import and lazy loading + - The Svelte side implements on-demand loading via importComponent, reducing the initial bundle size and first-screen load pressure. +- Render optimization + - Uses $derived and useMemo strategies to avoid unnecessary re-renders. +- Event forwarding + - Events are handled uniformly in the runtime bridge layer, reducing redundant bindings and memory usage. +- Slot cloning + - Sets clone and withParams for actionRender, ensuring stable reuse and parameter passing for slot content. + +Section Sources + +- [frontend/antdx/actions/action-item/Index.svelte:14-98](file://frontend/antdx/actions/action-item/Index.svelte#L14-L98) +- [backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js:163-209](file://backend/modelscope_studio/components/antdx/actions/action_item/templates/component/actions.action-item-76joNQSL.js#L163-L209) + +## Troubleshooting Guide + +- Event not triggered + - Check if the backend has enabled item_click event binding; confirm that item_click is correctly mapped in the frontend props. +- Slot not working + - Confirm slot names match the supported list (label, icon, actionRender, subItems); check withParams and clone settings for actionRender. +- Style or class name anomalies + - Check if elem_id, elem_classes, and elem_style are correctly passed; confirm the style and class name merging logic in the runtime bridge layer. +- Sub-menu not displaying + - Check trigger_sub_menu_action (hover/click) and sub_items structure; confirm the dropdown configuration of the main Actions. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:15-21](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L15-L21) +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:24](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L24) +- [frontend/antdx/actions/action-item/Index.svelte:61-84](file://frontend/antdx/actions/action-item/Index.svelte#L61-L84) + +## Conclusion + +ActionItem implements a highly configurable, extensible, and maintainable operation item component through backend Python encapsulation and frontend Svelte/React bridging. Its event, slot, style, and context integration capabilities enable it to meet the needs of operation panels in complex scenarios. Combined with the AntdXActions main component, beautiful and fully functional operation areas can be quickly built. + +## Appendix: Usage Examples and Parameter Reference + +The following are common usage scenarios and parameter descriptions (using paths instead of specific code): + +- Text operation item + - Parameters: label, danger, as_item + - Example path: [frontend/antdx/actions/action-item/Index.svelte:61-84](file://frontend/antdx/actions/action-item/Index.svelte#L61-L84) +- Icon operation item + - Parameters: icon, label, elem_classes + - Example path: [frontend/antdx/actions/action-item/Index.svelte:61-84](file://frontend/antdx/actions/action-item/Index.svelte#L61-L84) +- Custom rendering (actionRender) + - Parameters: actionRender (function string), slot withParams/clone + - Example path: [frontend/antdx/actions/action-item/Index.svelte:71-83](file://frontend/antdx/actions/action-item/Index.svelte#L71-L83) +- Danger state and trigger strategy + - Parameters: danger, trigger_sub_menu_action (hover/click) + - Example path: [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:26-61](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L26-L61) +- Sub-menu + - Parameters: sub_items, slot subItems + - Example path: [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:24](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L24) + +Section Sources + +- [frontend/antdx/actions/action-item/Index.svelte:61-84](file://frontend/antdx/actions/action-item/Index.svelte#L61-L84) +- [backend/modelscope_studio/components/antdx/actions/action_item/**init**.py:24-61](file://backend/modelscope_studio/components/antdx/actions/action_item/__init__.py#L24-L61) diff --git a/.wiki/en/Ant Design X Components/Feedback Components/Actions Overview.md b/.wiki/en/Ant Design X Components/Feedback Components/Actions Overview.md new file mode 100644 index 00000000..4723f684 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Feedback Components/Actions Overview.md @@ -0,0 +1,335 @@ +# Actions Overview + + +**Files referenced in this document** +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/antdx/actions/item/Index.svelte](file://frontend/antdx/actions/item/Index.svelte) +- [frontend/antdx/actions/action-item/Index.svelte](file://frontend/antdx/actions/action-item/Index.svelte) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [backend/modelscope_studio/components/antdx/actions/__init__.py](file://backend/modelscope_studio/components/antdx/actions/__init__.py) +- [docs/components/antdx/actions/README.md](file://docs/components/antdx/actions/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +Actions is a layout and interaction component from the Ant Design X component library in ModelScope Studio, used to quickly configure a set of reusable operation buttons or function entry points in AI scenarios. Through a unified "operation item" model and slots mechanism, it decouples static configuration from dynamic rendering, supporting both direct passing of an items list and declarative organization of operation items as sub-components, thereby improving development efficiency and maintainability. + +In the overall architecture of ModelScope Studio, Actions sits between the frontend Svelte layer and the backend Gradio component layer, serving as a "bridge and adapter": the frontend is responsible for rendering Ant Design X's Actions on the page; the backend exposes events and slot capabilities through a custom component class and forwards extra properties to the frontend, achieving a complete interaction loop from the Python side to the browser. + +## Project Structure + +The Actions component consists of two parts — frontend and backend: + +- Frontend (Svelte + React): Responsible for rendering Ant Design X's Actions as page elements, and collecting sub-items through the slot and context system. +- Backend (Python + Gradio): Defines the component interface, events, and slots, responsible for binding and forwarding properties and events. + +```mermaid +graph TB +subgraph "Frontend" +A_Index["frontend/antdx/actions/Index.svelte"] +A_Component["frontend/antdx/actions/actions.tsx"] +A_Context["frontend/antdx/actions/context.ts"] +A_Item["frontend/antdx/actions/item/Index.svelte"] +A_ActionItem["frontend/antdx/actions/action-item/Index.svelte"] +U_CreateItems["frontend/utils/createItemsContext.tsx"] +end +subgraph "Backend" +P_Init["backend/modelscope_studio/components/antdx/actions/__init__.py"] +end +A_Index --> A_Component +A_Component --> A_Context +A_Component --> U_CreateItems +A_Item --> A_Component +A_ActionItem --> A_Component +P_Init --> A_Index +``` + +**Diagram Sources** + +- [frontend/antdx/actions/Index.svelte:1-77](file://frontend/antdx/actions/Index.svelte#L1-L77) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/action-item/Index.svelte:1-99](file://frontend/antdx/actions/action-item/Index.svelte#L1-L99) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [backend/modelscope_studio/components/antdx/actions/**init**.py:1-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L1-L112) + +**Section Sources** + +- [frontend/antdx/actions/Index.svelte:1-77](file://frontend/antdx/actions/Index.svelte#L1-L77) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/action-item/Index.svelte:1-99](file://frontend/antdx/actions/action-item/Index.svelte#L1-L99) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [backend/modelscope_studio/components/antdx/actions/**init**.py:1-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L1-L112) + +## Core Components + +- Actions main component: Responsible for receiving items or operation items from slots, customizing dropdown menu rendering with dropdownProps, and rendering the final Ant Design X Actions on the page. +- Operation item context: Through the ItemsContext provided by createItemsContext, collects child operation items (including default slots and named slots), and supports merging and forwarding of props, slots, and children for sub-items. +- Sub-component wrappers: item and action-item wrap the "operation container" and "specific operation item" respectively, handling property forwarding, visibility control, style and ID injection, and event mapping (e.g., item_click is mapped to itemClick). + +**Section Sources** + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/action-item/Index.svelte:1-99](file://frontend/antdx/actions/action-item/Index.svelte#L1-L99) + +## Architecture Overview + +The Actions runtime flow is as follows: + +- The frontend Svelte layer dynamically imports the React wrapper actions.tsx via Index.svelte. +- actions.tsx uses context and slot utility functions to convert items and dropdownProps into the data structure required by Ant Design X. +- The backend component class declares events and slots on the Python side, forwarding extra properties and visibility information to the frontend. +- Finally, Ant Design X's Actions renders the UI and triggers callback events. + +```mermaid +sequenceDiagram +participant Py as "Backend Component Class\nAntdXActions" +participant FE_Index as "Frontend Index.svelte" +participant FE_Actions as "React Wrapper\nactions.tsx" +participant Ctx as "Items Context\ncreateItemsContext" +participant ADX as "Ant Design X Actions" +Py->>FE_Index : "Render request with properties and events" +FE_Index->>FE_Actions : "Dynamic import and forward props" +FE_Actions->>Ctx : "Read items slots and menu items" +FE_Actions->>ADX : "Generate items and dropdownProps" +ADX-->>FE_Actions : "Render result" +FE_Actions-->>FE_Index : "Return rendered node" +FE_Index-->>Py : "Render complete" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:1-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L1-L112) +- [frontend/antdx/actions/Index.svelte:1-77](file://frontend/antdx/actions/Index.svelte#L1-L77) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +## Detailed Component Analysis + +### Actions Main Component (React Wrapper) + +- Responsibility: Integrates Ant Design X's Actions with the slot and context system, responsible for merging and rendering items and dropdownProps. +- Key points: + - Uses withItemsContextProvider and withMenuItemsContextProvider to inject items and menu item contexts. + - Converts slot content into the structure required by Ant Design X using utility functions such as renderItems, renderSlot, and renderParamsSlot. + - Conditionally merges dropdownProps, only injecting when valid values exist to avoid redundant configuration. + +```mermaid +flowchart TD +Start(["Enter Actions Wrapper"]) --> ReadItems["Read items or operation items from slots"] +ReadItems --> MergeDropdown["Merge dropdownProps\nMenu items/renderers/indicators"] +MergeDropdown --> BuildItems["Build final items using renderItems"] +BuildItems --> Render["Render Ant Design X Actions"] +Render --> End(["Complete"]) +``` + +**Diagram Sources** + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +**Section Sources** + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) + +### Operation Item Context (createItemsContext) + +- Responsibility: Provides ItemsContext for collecting and updating "operation item" data, supporting multiple slots (default and other named slots). +- Key points: + - setItem supports updating individual items by slot key and index, using an immutable update strategy internally, combined with useEffect to trigger the onChange callback. + - ItemHandler encapsulates the sub-component's props, slots, and children into a standard Item structure and writes it to the context. + - Optimizes rendering and callback overhead via useMemoizedEqualValue and useMemoizedFn. + +```mermaid +classDiagram +class ItemsContext { ++items : Record ++setItem(slotKey, index, item) ++initial : boolean +} +class ItemsContextProvider { ++allowedSlots : string[] ++onChange(items) ++children +} +class ItemHandler { ++itemIndex : number ++itemSlotKey : string ++itemProps(props, items) ++itemChildren(items) ++slots ++children +} +ItemsContextProvider --> ItemsContext : "Provides" +ItemHandler --> ItemsContext : "Writes single item" +``` + +**Diagram Sources** + +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +**Section Sources** + +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) + +### Sub-component Wrappers (item and action-item) + +- Responsibility: Wraps the "operation container" and "specific operation items", handling property forwarding, visibility control, style and ID injection, and event mapping. +- Key points: + - Index.svelte dynamically loads the corresponding React component via importComponent, ensuring on-demand loading. + - Unified handling of common properties such as additionalProps, elem\_\*, and visible. + - action-item maps the item_click event to ensure consistency with Ant Design X callback conventions. + +```mermaid +sequenceDiagram +participant Parent as "Parent Component Actions" +participant ItemWrap as "item/Index.svelte" +participant ActionWrap as "action-item/Index.svelte" +participant Child as "Child Component React Wrapper" +Parent->>ItemWrap : "Forward props and slots" +ItemWrap->>Child : "Dynamic import and render" +Parent->>ActionWrap : "Forward props and slots" +ActionWrap->>Child : "Dynamic import and render" +Child-->>Parent : "Render complete" +``` + +**Diagram Sources** + +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/action-item/Index.svelte:1-99](file://frontend/antdx/actions/action-item/Index.svelte#L1-L99) + +**Section Sources** + +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/action-item/Index.svelte:1-99](file://frontend/antdx/actions/action-item/Index.svelte#L1-L99) + +### Backend Component Class (AntdXActions) + +- Responsibility: Declares the Actions component interface, events, and slots on the Python side, responsible for forwarding extra properties and visibility information to the frontend. +- Key points: + - Defines EVENTS: click, dropdown_open_change, dropdown_menu_click, dropdown_menu_deselect, dropdown_menu_open_change, dropdown_menu_select. + - Defines SLOTS: items, dropdownProps.dropdownRender, dropdownProps.popupRender, dropdownProps.menu.expandIcon, dropdownProps.menu.overflowedIndicator, dropdownProps.menu.items. + - Provides variant, dropdown_props, fade_in, fade_in_left, and other properties for theme and animation control. + +```mermaid +classDiagram +class AntdXActions { ++EVENTS ++SLOTS ++variant ++dropdown_props ++fade_in ++fade_in_left ++additional_props ++items ++class_names ++styles ++as_item ++_internal +} +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:1-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L1-L112) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:1-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L1-L112) + +## Dependency Analysis + +- Frontend dependency chain: + - Index.svelte depends on actions.tsx. + - actions.tsx depends on createItemsContext, withItemsContextProvider, withMenuItemsContextProvider, renderItems, renderSlot, renderParamsSlot, createFunction. + - item/Index.svelte and action-item/Index.svelte depend on their respective React wrappers. +- Backend dependency chain: + - AntdXActions depends on the frontend directory resolution and the Gradio event system. + +```mermaid +graph LR +Py["AntdXActions\nBackend"] --> FE_Index["Index.svelte\nFrontend"] +FE_Index --> FE_Actions["actions.tsx\nFrontend"] +FE_Actions --> Ctx["createItemsContext\nUtility"] +FE_Actions --> Utils["renderItems/renderSlot/renderParamsSlot/createFunction"] +FE_Actions --> MenuCtx["withMenuItemsContextProvider"] +FE_Actions --> ItemsCtx["withItemsContextProvider"] +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/actions/**init**.py:1-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L1-L112) +- [frontend/antdx/actions/Index.svelte:1-77](file://frontend/antdx/actions/Index.svelte#L1-L77) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +**Section Sources** + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [backend/modelscope_studio/components/antdx/actions/**init**.py:1-112](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L1-L112) + +## Performance Considerations + +- On-demand loading: Index.svelte dynamically loads the React wrapper on demand via importComponent, reducing the initial bundle size. +- Immutable updates: createItemsContext uses an immutable update strategy to avoid unnecessary re-renders. +- Computation caching: actions.tsx uses useMemo to cache dropdownProps and the final items, reducing rendering costs. +- Event mapping: Converts string-form callbacks to functions via createFunction to avoid repeated binding. + +[This section contains general performance recommendations; no specific file references required] + +## Troubleshooting Guide + +- Cannot display operation items + - Check if slots are used correctly or if items are passed in; confirm that slot key names match component declarations. + - Reference: [frontend/antdx/actions/actions.tsx:31-116](file://frontend/antdx/actions/actions.tsx#L31-L116) +- Dropdown menu not working + - Confirm dropdownProps is correctly merged; check if menu items are empty. + - Reference: [frontend/antdx/actions/actions.tsx:39-96](file://frontend/antdx/actions/actions.tsx#L39-L96) +- Events not triggered + - Confirm that backend EVENTS are registered; check frontend event mapping (e.g., item_click -> itemClick). + - Reference: [backend/modelscope_studio/components/antdx/actions/**init**.py:26-46](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L26-L46) + - Reference: [frontend/antdx/actions/action-item/Index.svelte:54-57](file://frontend/antdx/actions/action-item/Index.svelte#L54-L57) + +**Section Sources** + +- [frontend/antdx/actions/actions.tsx:31-116](file://frontend/antdx/actions/actions.tsx#L31-L116) +- [backend/modelscope_studio/components/antdx/actions/**init**.py:26-46](file://backend/modelscope_studio/components/antdx/actions/__init__.py#L26-L46) +- [frontend/antdx/actions/action-item/Index.svelte:54-57](file://frontend/antdx/actions/action-item/Index.svelte#L54-L57) + +## Conclusion + +Actions plays the role of an "operation entry aggregator" in ModelScope Studio, achieving flexible, extensible, and high-performance operation list rendering through Ant Design X's powerful capabilities and slot/context mechanisms. It is suitable both for quickly building "one-click execute" functions in AI applications, and for implementing highly customized interaction experiences in complex scenarios through the slot and event system. + +[This section contains summary content; no specific file references required] + +## Appendix + +- For quick-start examples, refer to the official documentation example page. + - Reference: [docs/components/antdx/actions/README.md:1-8](file://docs/components/antdx/actions/README.md#L1-L8) + +**Section Sources** + +- [docs/components/antdx/actions/README.md:1-8](file://docs/components/antdx/actions/README.md#L1-L8) diff --git a/.wiki/en/Ant Design X Components/Feedback Components/Audio Component.md b/.wiki/en/Ant Design X Components/Feedback Components/Audio Component.md new file mode 100644 index 00000000..99771e6f --- /dev/null +++ b/.wiki/en/Ant Design X Components/Feedback Components/Audio Component.md @@ -0,0 +1,315 @@ +# Audio Component + + +**Files referenced in this document** +- [frontend/antdx/actions/audio/Index.svelte](file://frontend/antdx/actions/audio/Index.svelte) +- [frontend/antdx/actions/audio/actions.audio.tsx](file://frontend/antdx/actions/audio/actions.audio.tsx) +- [backend/modelscope_studio/components/antdx/actions/audio/__init__.py](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py) +- [frontend/pro/multimodal-input/utils.ts](file://frontend/pro/multimodal-input/utils.ts) +- [frontend/pro/multimodal-input/recorder.ts](file://frontend/pro/multimodal-input/recorder.ts) +- [frontend/antd/slider/Index.svelte](file://frontend/antd/slider/Index.svelte) +- [docs/components/pro/multimodal_input/README.md](file://docs/components/pro/multimodal_input/README.md) +- [docs/components/pro/multimodal_input/README-zh_CN.md](file://docs/components/pro/multimodal_input/README-zh_CN.md) +- [frontend/pro/multimodal-input/package.json](file://frontend/pro/multimodal-input/package.json) +- [frontend/antdx/actions/audio/package.json](file://frontend/antdx/actions/audio/package.json) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically organizes and explains the implementation and usage of the Audio component in the model library frontend, covering the following key areas: + +- Audio playback and control capabilities (play/pause/stop, progress, volume, loop) +- Audio file loading and processing (decoding, trimming, exporting) +- Recording and waveform visualization (microphone recording, waveform drawing) +- Integration practices in different business scenarios (voice broadcasting, sound effects playback, audio preview) +- Compatibility and performance optimization recommendations +- Design techniques for enhancing user experience + +## Project Structure + +Audio-related capabilities are primarily distributed in the following locations: + +- Frontend Svelte wrapper layer: Bridges Ant Design X's Actions.Audio component to the Gradio ecosystem +- Backend Python component: AntdXActionsAudio, responsible for property forwarding and rendering control +- Multimodal input Pro component: Provides recording, audio processing, and export capabilities +- General UI components: Such as Slider, for volume/progress control + +```mermaid +graph TB +subgraph "Frontend" +A["AntdX Actions.Audio Wrapper\nfrontend/antdx/actions/audio/Index.svelte"] +B["React Bridge Layer\nfrontend/antdx/actions/audio/actions.audio.tsx"] +C["Multimodal Input Utilities\nfrontend/pro/multimodal-input/utils.ts"] +D["Recording Hook\nfrontend/pro/multimodal-input/recorder.ts"] +E["Volume/Progress Slider\nfrontend/antd/slider/Index.svelte"] +end +subgraph "Backend" +F["AntdXActionsAudio Component Class\nbackend/.../antdx/actions/audio/__init__.py"] +end +A --> B +B --> F +C --> D +E --> A +``` + +**Diagram Sources** + +- [frontend/antdx/actions/audio/Index.svelte:1-59](file://frontend/antdx/actions/audio/Index.svelte#L1-L59) +- [frontend/antdx/actions/audio/actions.audio.tsx:1-17](file://frontend/antdx/actions/audio/actions.audio.tsx#L1-L17) +- [backend/modelscope_studio/components/antdx/actions/audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) +- [frontend/pro/multimodal-input/utils.ts:1-126](file://frontend/pro/multimodal-input/utils.ts#L1-L126) +- [frontend/pro/multimodal-input/recorder.ts:1-48](file://frontend/pro/multimodal-input/recorder.ts#L1-L48) +- [frontend/antd/slider/Index.svelte:62-84](file://frontend/antd/slider/Index.svelte#L62-L84) + +**Section Sources** + +- [frontend/antdx/actions/audio/Index.svelte:1-59](file://frontend/antdx/actions/audio/Index.svelte#L1-L59) +- [frontend/antdx/actions/audio/actions.audio.tsx:1-17](file://frontend/antdx/actions/audio/actions.audio.tsx#L1-L17) +- [backend/modelscope_studio/components/antdx/actions/audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) +- [frontend/pro/multimodal-input/utils.ts:1-126](file://frontend/pro/multimodal-input/utils.ts#L1-L126) +- [frontend/pro/multimodal-input/recorder.ts:1-48](file://frontend/pro/multimodal-input/recorder.ts#L1-L48) +- [frontend/antd/slider/Index.svelte:62-84](file://frontend/antd/slider/Index.svelte#L62-L84) + +## Core Components + +- AntdXActionsAudio (backend component class): Encapsulates Ant Design X's Actions.Audio, providing properties such as status, style, and visibility, and declares skip_api to directly render the frontend component. +- Actions.Audio (frontend wrapper): Bridges the React component to the Gradio ecosystem through Svelte wrapping, forwarding properties to Ant Design X's Actions.Audio. +- Audio processing utilities (Pro multimodal input): Provides capabilities for converting AudioBuffer to WAV, trimming audio by time range, decoding from Blob and exporting, etc. +- Recording Hook: Based on the record plugin for wavesurfer.js, provides recording start/end callbacks and recording state management. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/actions/audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) +- [frontend/antdx/actions/audio/actions.audio.tsx:1-17](file://frontend/antdx/actions/audio/actions.audio.tsx#L1-L17) +- [frontend/pro/multimodal-input/utils.ts:1-126](file://frontend/pro/multimodal-input/utils.ts#L1-L126) +- [frontend/pro/multimodal-input/recorder.ts:1-48](file://frontend/pro/multimodal-input/recorder.ts#L1-L48) + +## Architecture Overview + +The audio capability in the frontend bridges React components through the Svelte component; the backend passes properties to the frontend through a custom component class. It also provides recording and audio processing tools to complete the "recording → preview → export" loop in multimodal input scenarios. + +```mermaid +sequenceDiagram +participant Py as "Python Backend\nAntdXActionsAudio" +participant FE as "Frontend Wrapper\nIndex.svelte" +participant RA as "React Component\nActions.Audio" +participant AU as "Browser Audio API\nAudioContext/Web Audio API" +Py->>FE : Render component with property forwarding +FE->>RA : Pass props (status/style/visibility) +RA->>AU : Initialize audio context/load audio resources +AU-->>RA : Play/Pause/Stop/Progress/Volume/Loop +RA-->>FE : Trigger event callbacks (click, etc.) +FE-->>Py : Update state/trigger interactions +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/actions/audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) +- [frontend/antdx/actions/audio/Index.svelte:19-41](file://frontend/antdx/actions/audio/Index.svelte#L19-L41) +- [frontend/antdx/actions/audio/actions.audio.tsx:6-14](file://frontend/antdx/actions/audio/actions.audio.tsx#L6-L14) + +## Component Details + +### AntdXActionsAudio (Backend Component Class) + +- Responsibility boundary: Responsible for mapping frontend components to the Python side, providing properties such as status, style, and visibility; declares skip_api to avoid redundant processing. +- Key points: Event listener binding, property forwarding, render control. + +```mermaid +classDiagram +class AntdXActionsAudio { ++status ++additional_props ++class_names ++styles ++visible ++elem_id ++elem_classes ++elem_style ++skip_api ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/actions/audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/actions/audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) + +### Actions.Audio (Frontend Wrapper) + +- Responsibility boundary: Bridges Ant Design X's Actions.Audio to the Gradio ecosystem through Svelte wrapping, unifying properties and events. +- Key points: sveltify wrapping, slot forwarding, style and ID injection. + +```mermaid +flowchart TD +A["Index.svelte retrieves props"] --> B["processProps generates final properties"] +B --> C["Render Actions.Audio and inject styles/ID/events"] +C --> D["User interaction triggers event callbacks"] +``` + +**Diagram Sources** + +- [frontend/antdx/actions/audio/Index.svelte:19-41](file://frontend/antdx/actions/audio/Index.svelte#L19-L41) +- [frontend/antdx/actions/audio/actions.audio.tsx:6-14](file://frontend/antdx/actions/audio/actions.audio.tsx#L6-L14) + +**Section Sources** + +- [frontend/antdx/actions/audio/Index.svelte:1-59](file://frontend/antdx/actions/audio/Index.svelte#L1-L59) +- [frontend/antdx/actions/audio/actions.audio.tsx:1-17](file://frontend/antdx/actions/audio/actions.audio.tsx#L1-L17) + +### Audio Processing Utilities (Trim/Export) + +- Feature overview: Writes AudioBuffer to WAV header and PCM data; trims audio by start/end time; decodes from Blob and exports to WAV. +- Key flow: Decode → Create trimmed buffer → Write to WAV → Return binary data. + +```mermaid +flowchart TD +Start(["Start"]) --> Decode["Decode audio data\nAudioContext.decodeAudioData"] +Decode --> Trim{"Is trim range specified?"} +Trim --> |Yes| CreateBuf["Create trimmed AudioBuffer"] +Trim --> |No| KeepAll["Keep original length"] +CreateBuf --> Copy["Copy channel data to new buffer"] +KeepAll --> Copy +Copy --> ToWAV["Write WAV header and PCM data"] +ToWAV --> End(["End, return Uint8Array"]) +``` + +**Diagram Sources** + +- [frontend/pro/multimodal-input/utils.ts:1-126](file://frontend/pro/multimodal-input/utils.ts#L1-L126) + +**Section Sources** + +- [frontend/pro/multimodal-input/utils.ts:1-126](file://frontend/pro/multimodal-input/utils.ts#L1-L126) + +### Recording and Waveform Visualization + +- Recording: Based on the record plugin for wavesurfer.js, provides start/stop callbacks and recording state. +- Waveform: Initializes a WaveSurfer container and registers the record plugin to display waveforms in real time. + +```mermaid +sequenceDiagram +participant UI as "Interface" +participant WS as "WaveSurfer Instance" +participant REC as "Record Plugin" +participant CB as "Callback Function" +UI->>WS : Create instance and pass container +WS->>REC : Register record plugin +UI->>REC : Call startRecording() +REC-->>UI : Trigger record-start event +UI->>REC : Call stopRecording() +REC-->>CB : Trigger record-end and return Blob +UI-->>UI : Update recording state +``` + +**Diagram Sources** + +- [frontend/pro/multimodal-input/recorder.ts:24-41](file://frontend/pro/multimodal-input/recorder.ts#L24-L41) + +**Section Sources** + +- [frontend/pro/multimodal-input/recorder.ts:1-48](file://frontend/pro/multimodal-input/recorder.ts#L1-L48) + +### Volume/Progress Control (Slider) + +- Uses the Slider component to implement two-way control of volume and progress; the onValueChange event is used to synchronize state. +- Adapts to Gradio's property forwarding mechanism to ensure consistency with backend state. + +**Section Sources** + +- [frontend/antd/slider/Index.svelte:62-84](file://frontend/antd/slider/Index.svelte#L62-L84) + +## Dependency Analysis + +- Frontend package exports: Two key packages each export a Svelte entry point for loading by the Gradio runtime. +- Component coupling: AntdXActionsAudio and the frontend wrapper component are loosely coupled, interacting through property forwarding. +- Toolchain: Audio processing depends on the Web Audio API; recording depends on wavesurfer.js and its record plugin. + +```mermaid +graph LR +PkgA["pro/multimodal-input/package.json"] --> Utils["utils.ts\nAudio Processing"] +PkgB["antdx-actions.audio/package.json"] --> Wrap["actions.audio.tsx\nReact Wrapper"] +Wrap --> Fe["Index.svelte\nProperty Forwarding"] +Fe --> Py["AntdXActionsAudio\nBackend Component Class"] +Utils --> Recorder["recorder.ts\nRecording Hook"] +``` + +**Diagram Sources** + +- [frontend/pro/multimodal-input/package.json:1-14](file://frontend/pro/multimodal-input/package.json#L1-L14) +- [frontend/antdx/actions/audio/package.json:1-14](file://frontend/antdx/actions/audio/package.json#L1-L14) +- [frontend/pro/multimodal-input/utils.ts:1-126](file://frontend/pro/multimodal-input/utils.ts#L1-L126) +- [frontend/pro/multimodal-input/recorder.ts:1-48](file://frontend/pro/multimodal-input/recorder.ts#L1-L48) +- [frontend/antdx/actions/audio/Index.svelte:1-59](file://frontend/antdx/actions/audio/Index.svelte#L1-L59) +- [backend/modelscope_studio/components/antdx/actions/audio/**init**.py:10-71](file://backend/modelscope_studio/components/antdx/actions/audio/__init__.py#L10-L71) + +**Section Sources** + +- [frontend/pro/multimodal-input/package.json:1-14](file://frontend/pro/multimodal-input/package.json#L1-L14) +- [frontend/antdx/actions/audio/package.json:1-14](file://frontend/antdx/actions/audio/package.json#L1-L14) + +## Performance Considerations + +- Audio decoding and trimming: Prioritize browser-side processing to avoid the overhead of large file network transfers; for long audio files, consider segmented processing or deferred decoding. +- Buffer management: Copy only the necessary segments during trimming to reduce memory usage; confirm sample rate and channel count consistency before exporting. +- Recording performance: Set normalize and container size appropriately to avoid frequent redraws; be aware of background playback restrictions and permission requests on mobile devices. +- UI responsiveness: Use controlled component mode for volume/progress sliders to avoid unnecessary re-renders; use memoized functions for event callbacks to reduce jitter. + +## Troubleshooting Guide + +- Cannot play audio + - Check if the audio format is supported by the browser; try converting to common formats such as WAV/MP3. + - Confirm AudioContext initialization and permissions (some browsers require a user gesture to activate). +- No recording output + - Confirm device permissions are granted; check if the container is correctly mounted. + - Verify that the record-end callback is triggered and the Blob is not empty. +- Export failure + - Confirm the trim range is valid (start/end not out of bounds); check sample rate and channel count consistency. +- Slider not working + - Check if the onValueChange event is correctly updating state; confirm the synchronization logic between controlled value and fallback value. + +**Section Sources** + +- [frontend/pro/multimodal-input/utils.ts:60-126](file://frontend/pro/multimodal-input/utils.ts#L60-L126) +- [frontend/pro/multimodal-input/recorder.ts:24-41](file://frontend/pro/multimodal-input/recorder.ts#L24-L41) +- [frontend/antd/slider/Index.svelte:62-84](file://frontend/antd/slider/Index.svelte#L62-L84) + +## Conclusion + +The Audio component in the model library frontend implements full capabilities from playback control to recording export through a "backend component class + frontend wrapper + toolchain" approach. Combined with multimodal input scenarios, it enables quick construction of voice broadcasting, sound effects playback, and audio preview experiences. It is recommended to pay attention to format compatibility, performance optimization, and permission handling in actual projects to achieve a more stable user experience. + +## Appendix + +### Usage Examples (Scenarios) + +- Voice broadcasting + - Use AntdXActionsAudio to render a play button, control volume with Slider; trigger play/pause via event callbacks. +- Sound effects playback + - Load local sound effect files, set looping playback and volume; switch state in interaction events. +- Audio preview + - After recording, decode the Blob to an AudioBuffer, then export to WAV; play in the preview area and provide a download option. + +**Section Sources** + +- [docs/components/pro/multimodal_input/README.md:1-43](file://docs/components/pro/multimodal_input/README.md#L1-L43) +- [docs/components/pro/multimodal_input/README-zh_CN.md:1-43](file://docs/components/pro/multimodal_input/README-zh_CN.md#L1-L43) diff --git a/.wiki/en/Ant Design X Components/Feedback Components/Copy Component.md b/.wiki/en/Ant Design X Components/Feedback Components/Copy Component.md new file mode 100644 index 00000000..2bd0f88a --- /dev/null +++ b/.wiki/en/Ant Design X Components/Feedback Components/Copy Component.md @@ -0,0 +1,429 @@ +# Copy Component + + +**Files referenced in this document** +- [actions.copy.tsx](file://frontend/antdx/actions/copy/actions.copy.tsx) +- [Index.svelte](file://frontend/antdx/actions/copy/Index.svelte) +- [__init__.py](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py) +- [package.json](file://frontend/antdx/actions/copy/package.json) +- [gradio.config.js](file://frontend/antdx/actions/copy/gradio.config.js) +- [utils.ts](file://frontend/globals/components/markdown/utils.ts) +- [chatbot-footer.tsx](file://frontend/pro/chatbot/chatbot-footer.tsx) +- [utils.ts](file://frontend/pro/chatbot/utils.ts) +- [basic.py](file://docs/components/antdx/actions/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The Copy Component is a component in ModelScope Studio for quickly configuring copy functionality, implemented based on Ant Design X's Actions.Copy. This component provides a unified copy operation interface, supporting copying of multiple data types including plain text, links, code snippets, and other common scenarios. + +The component adopts a front-end/back-end separation design pattern, with the frontend built using Svelte and the backend wrapped through Gradio components, implementing complete lifecycle management for copy functionality. + +## Project Structure + +The Copy Component is located in the Ant Design X component library with the following structure: + +```mermaid +graph TB +subgraph "Frontend Component Structure" +A[Index.svelte] --> B[actions.copy.tsx] +B --> C[Ant Design X Actions.Copy] +D[package.json] --> A +E[gradio.config.js] --> A +end +subgraph "Backend Component Structure" +F[__init__.py] --> G[ModelScopeLayoutComponent] +G --> H[Gradio Event Handling] +end +subgraph "Utility Functions" +I[utils.ts] --> J[Copy Functionality Implementation] +K[chatbot-footer.tsx] --> L[Chatbot Integration] +M[utils.ts] --> N[Message Content Processing] +end +A --> F +B --> I +L --> N +``` + +**Diagram Sources** + +- [Index.svelte:1-60](file://frontend/antdx/actions/copy/Index.svelte#L1-L60) +- [actions.copy.tsx:1-22](file://frontend/antdx/actions/copy/actions.copy.tsx#L1-L22) +- [**init**.py:1-72](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L1-L72) + +**Section Sources** + +- [Index.svelte:1-60](file://frontend/antdx/actions/copy/Index.svelte#L1-L60) +- [actions.copy.tsx:1-22](file://frontend/antdx/actions/copy/actions.copy.tsx#L1-L22) +- [**init**.py:1-72](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L1-L72) + +## Core Components + +The Copy Component consists of three main parts: + +### Frontend Component Layer + +- **Index.svelte**: The main frontend entry component, responsible for property handling and rendering logic +- **actions.copy.tsx**: React wrapper that adapts Ant Design X's Actions.Copy component to the Svelte environment + +### Backend Component Layer + +- \***\*init**.py\*\*: Python backend component definition, inheriting from ModelScopeLayoutComponent + +### Utility Function Layer + +- **utils.ts**: Provides the core implementation of copy functionality, including Clipboard API and fallback solutions + +**Section Sources** + +- [Index.svelte:19-44](file://frontend/antdx/actions/copy/Index.svelte#L19-L44) +- [actions.copy.tsx:7-19](file://frontend/antdx/actions/copy/actions.copy.tsx#L7-L19) +- [**init**.py:10-72](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L10-L72) + +## Architecture Overview + +The Copy Component adopts a layered architecture design, achieving clear separation of concerns: + +```mermaid +sequenceDiagram +participant User as User +participant Frontend as Frontend Component +participant Backend as Backend Component +participant Clipboard as Browser Clipboard +participant Utils as Utility Functions +User->>Frontend : Click copy button +Frontend->>Utils : Call copy function +Utils->>Clipboard : Write to clipboard +Clipboard-->>Utils : Return copy result +Utils-->>Frontend : Return success state +Frontend-->>User : Display feedback effect +Note over Frontend,Clipboard : Supports modern browsers and fallback solutions +``` + +**Diagram Sources** + +- [utils.ts:382-410](file://frontend/globals/components/markdown/utils.ts#L382-L410) +- [Index.svelte:46-59](file://frontend/antdx/actions/copy/Index.svelte#L46-L59) + +### Component Interaction Flow + +```mermaid +flowchart TD +Start([Component Initialization]) --> Props[Process Component Properties] +Props --> Slots[Parse Slot Content] +Slots --> Render{Component Visibility} +Render --> |Visible| Load[Load React Component] +Render --> |Not Visible| Hide[Hide Component] +Load --> Ready[Component Ready] +Ready --> Click[Wait for Click Event] +Click --> Copy[Execute Copy Operation] +Copy --> Feedback[Display Feedback Effect] +Feedback --> End([Complete]) +Hide --> End +``` + +**Diagram Sources** + +- [Index.svelte:19-44](file://frontend/antdx/actions/copy/Index.svelte#L19-L44) +- [actions.copy.tsx:8-18](file://frontend/antdx/actions/copy/actions.copy.tsx#L8-L18) + +## Detailed Component Analysis + +### Frontend Component Implementation + +#### Index.svelte Analysis + +Index.svelte is the main frontend entry for the copy component, responsible for the following key functions: + +```mermaid +classDiagram +class CopyComponent { ++props : ComponentProps ++slots : Slots ++proceedProps : ProcessedProps ++visible : boolean ++getProps() ComponentProps ++processProps() ProcessedProps ++getSlots() Slots ++render() JSX.Element +} +class ProcessProps { ++visible : boolean ++_internal : object ++as_item : string ++elem_classes : array ++elem_id : string ++elem_style : object ++restProps : object ++additionalProps : object +} +CopyComponent --> ProcessProps : Uses +``` + +**Diagram Sources** + +- [Index.svelte:12-44](file://frontend/antdx/actions/copy/Index.svelte#L12-L44) + +#### actions.copy.tsx Analysis + +actions.copy.tsx acts as a React wrapper, implementing seamless integration with Ant Design X: + +```mermaid +classDiagram +class ActionsCopyWrapper { ++slots : object ++children : any ++props : ActionsCopyProps ++sveltify() ReactComponent ++render() JSX.Element +} +class ReactSlot { ++slot : string ++render() ReactElement +} +class AntdXActionsCopy { ++text : string ++icon : string ++onClick : function ++tooltips : boolean ++onCopy : function +} +ActionsCopyWrapper --> ReactSlot : Uses +ActionsCopyWrapper --> AntdXActionsCopy : Wraps +``` + +**Diagram Sources** + +- [actions.copy.tsx:7-19](file://frontend/antdx/actions/copy/actions.copy.tsx#L7-L19) + +**Section Sources** + +- [Index.svelte:19-59](file://frontend/antdx/actions/copy/Index.svelte#L19-L59) +- [actions.copy.tsx:7-21](file://frontend/antdx/actions/copy/actions.copy.tsx#L7-L21) + +### Backend Component Implementation + +#### Python Component Analysis + +The backend component inherits from ModelScopeLayoutComponent, providing full Gradio integration: + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++visible : boolean ++elem_id : string ++elem_classes : array ++elem_style : object ++render : boolean ++preprocess() void ++postprocess() void ++example_payload() any ++example_value() any +} +class AntdXActionsCopy { ++EVENTS : array ++SLOTS : array ++text : string ++icon : string ++additional_props : object ++class_names : string|array ++styles : string|array ++skip_api : boolean ++FRONTEND_DIR : string +} +ModelScopeLayoutComponent <|-- AntdXActionsCopy : Inherits +``` + +**Diagram Sources** + +- [**init**.py:10-72](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L10-L72) + +**Section Sources** + +- [**init**.py:15-19](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L15-L19) +- [**init**.py:21-22](file://backend/modelscope_studio/components/antdx/actions/copy/__init__.py#L21-L22) + +### Copy Functionality Implementation + +#### Core Copy Logic + +The copy functionality is implemented through utility functions in utils.ts, supporting both modern browsers and legacy browsers: + +```mermaid +flowchart TD +Start([Start Copy]) --> CheckClipboard{Check Clipboard API} +CheckClipboard --> |Supported| Modern[Use navigator.clipboard] +CheckClipboard --> |Not Supported| Legacy[Use textarea fallback] +Modern --> WriteText[writeText method] +WriteText --> Success[Copy Successful] +Legacy --> CreateTextarea[Create textarea element] +CreateTextarea --> SetValue[Set text value] +SetValue --> Position[Position off-screen] +Position --> Select[Select text] +Select --> ExecCommand[Execute copy command] +ExecCommand --> RemoveTextarea[Remove textarea] +RemoveTextarea --> Success +Success --> Return[Return true] +``` + +**Diagram Sources** + +- [utils.ts:382-410](file://frontend/globals/components/markdown/utils.ts#L382-L410) + +**Section Sources** + +- [utils.ts:382-410](file://frontend/globals/components/markdown/utils.ts#L382-L410) + +## Dependency Analysis + +### Component Dependencies + +The dependency relationships of the Copy Component are relatively straightforward, primarily depending on the Ant Design X and Gradio ecosystems: + +```mermaid +graph TB +subgraph "External Dependencies" +A[@ant-design/x] --> B[Actions.Copy] +C[Gradio] --> D[Event System] +E[Svelte Preprocess React] --> F[Component Wrapper] +end +subgraph "Internal Dependencies" +G[utils.ts] --> H[Copy Functionality] +I[markdown component] --> J[Code Block Copy] +K[chatbot component] --> L[Message Copy] +end +subgraph "Copy Component" +B --> M[ActionsCopyWrapper] +F --> M +H --> M +M --> N[Index.svelte] +end +M --> O[Python Backend Component] +O --> D +``` + +**Diagram Sources** + +- [actions.copy.tsx:4](file://frontend/antdx/actions/copy/actions.copy.tsx#L4) +- [Index.svelte:10](file://frontend/antdx/actions/copy/Index.svelte#L10) + +### Version Compatibility + +Supported version requirements for the component: + +- Node.js: >= 14.0.0 +- Svelte: >= 3.0.0 +- Ant Design X: >= latest +- Gradio: >= latest + +**Section Sources** + +- [package.json:1-15](file://frontend/antdx/actions/copy/package.json#L1-L15) +- [gradio.config.js:1-4](file://frontend/antdx/actions/copy/gradio.config.js#L1-L4) + +## Performance Considerations + +### Render Optimization + +The copy component adopts a lazy loading strategy, loading React components only when needed: + +```mermaid +flowchart LR +A[Component Initialization] --> B{Check Visibility} +B --> |Not Visible| C[Return Empty Directly] +B --> |Visible| D[Async Load Component] +D --> E[Component Ready] +E --> F[Render Final Component] +``` + +**Diagram Sources** + +- [Index.svelte:46-59](file://frontend/antdx/actions/copy/Index.svelte#L46-L59) + +### Memory Management + +The component implements appropriate memory cleanup mechanisms: + +- Automatically removes event listeners +- Promptly clears temporary DOM elements +- Avoids memory leaks + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### Copy Functionality Not Working + +**Problem Description**: User clicks the copy button but cannot copy to clipboard + +**Possible Causes**: + +1. Browser security policy restrictions +2. HTTPS environment issues +3. Insufficient permissions + +**Solutions**: + +1. Ensure the website is running in an HTTPS environment +2. Check browser permission settings +3. Try manually triggering the copy operation + +#### Component Rendering Anomaly + +**Problem Description**: Copy component cannot display or render normally + +**Possible Causes**: + +1. Frontend build configuration issues +2. Dependency package version conflicts +3. Slot content format errors + +**Solutions**: + +1. Check frontend build logs +2. Update dependency packages to compatible versions +3. Validate slot content format + +**Section Sources** + +- [utils.ts:382-410](file://frontend/globals/components/markdown/utils.ts#L382-L410) +- [Index.svelte:46-59](file://frontend/antdx/actions/copy/Index.svelte#L46-L59) + +## Conclusion + +The Copy Component is a well-designed general-purpose component with the following characteristics: + +### Technical Advantages + +- **Modular design**: Clear front-end/back-end separation architecture +- **Strong compatibility**: Supports multiple browser environments +- **Easy to extend**: Slot system supports flexible customization +- **Performance optimization**: Lazy loading and memory management + +### Use Cases + +- Text content copying +- Code snippet copying +- Link sharing +- File download link copying + +### Best Practices + +1. Reasonably use the slot system for customization +2. Pay attention to browser compatibility issues +3. Implement appropriate error handling mechanisms +4. Consider user experience feedback design + +This component provides a reliable copy functionality foundation for ModelScope Studio and can meet the needs of most application scenarios. diff --git a/.wiki/en/Ant Design X Components/Feedback Components/Feedback Component.md b/.wiki/en/Ant Design X Components/Feedback Components/Feedback Component.md new file mode 100644 index 00000000..32862858 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Feedback Components/Feedback Component.md @@ -0,0 +1,268 @@ +# Feedback Component + + +**Files referenced in this document** +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) +- [frontend/antdx/actions/feedback/Index.svelte](file://frontend/antdx/actions/feedback/Index.svelte) +- [frontend/antdx/actions/feedback/package.json](file://frontend/antdx/actions/feedback/package.json) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [backend/modelscope_studio/components/antdx/actions/feedback/__init__.py](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py) +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically explains the design and implementation of the Feedback component, focusing on user feedback collection, data flow, and processing mechanisms, and providing reusable usage patterns (such as satisfaction surveys, feature evaluations, issue reports, etc.). The component is based on Ant Design X's Actions.Feedback capability and achieves frontend-backend integrated integration through a Svelte wrapper layer in the Gradio ecosystem, with the following key features: + +- The frontend is exposed as a Svelte component, internally bridging a React implementation. +- The backend participates in interface rendering and event dispatching as a Gradio component. +- Supports three feedback values — "like"/"dislike"/"default" — for subsequent statistics and analysis. +- Oriented toward product improvement and user experience optimization, providing extensible feedback collection and response capabilities. + +## Project Structure + +The Feedback component is located in the frontend antdx/actions/feedback directory, and the backend is at backend/modelscope_studio/components/antdx/actions/feedback. It works in conjunction with the Actions main container component, forming a "container-sub-item" combination. + +```mermaid +graph TB +subgraph "Frontend" +A["Index.svelte\nFeedback component entry"] +B["actions.feedback.tsx\nReact bridge wrapper"] +C["actions.tsx\nActions container"] +D["context.ts\nContext provider"] +end +subgraph "Backend" +E["__init__.py\nGradio component definition"] +end +A --> B +B --> C +C --> D +A --> E +``` + +Diagram Sources + +- [frontend/antdx/actions/feedback/Index.svelte:1-62](file://frontend/antdx/actions/feedback/Index.svelte#L1-L62) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:1-16](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L1-L16) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py:25-73](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L25-L73) + +Section Sources + +- [frontend/antdx/actions/feedback/Index.svelte:1-62](file://frontend/antdx/actions/feedback/Index.svelte#L1-L62) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:1-16](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L1-L16) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py:25-73](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L25-L73) + +## Core Components + +- Frontend entry component: Index.svelte loads the feedback component on demand and injects properties and slots, supporting visibility control and style class name concatenation. +- React bridge wrapper: actions.feedback.tsx exports @ant-design/x's Actions.Feedback in Svelte form, simplifying the calling interface. +- Actions container: actions.tsx provides Actions container capabilities, responsible for unified handling of menu items, dropdown rendering, slots, and events. +- Context provider: context.ts provides the Items context, supporting the registration and rendering of Actions sub-items. +- Backend Gradio component: The feedback component backend defines basic capabilities such as properties, visibility, and styles, and declares to skip the standard API process, letting the frontend drive interactions directly. + +Section Sources + +- [frontend/antdx/actions/feedback/Index.svelte:10-61](file://frontend/antdx/actions/feedback/Index.svelte#L10-L61) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:5-13](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L5-L13) +- [frontend/antdx/actions/actions.tsx:17-120](file://frontend/antdx/actions/actions.tsx#L17-L120) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py:28-73](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L28-L73) + +## Architecture Overview + +The runtime architecture of the Feedback component is as follows: the frontend Svelte component dynamically loads the React wrapper layer via importComponent, which then calls @ant-design/x's Actions.Feedback; the backend component handles property forwarding and rendering control without participating in data API processing, with events handled by the frontend. + +```mermaid +sequenceDiagram +participant UI as "Page/Application" +participant FE_Index as "Index.svelte" +participant FE_Wrapper as "actions.feedback.tsx" +participant FE_Actions as "actions.tsx" +participant BE_Comp as "__init__.py (Backend)" +participant ADX as "@ant-design/x\nActions.Feedback" +UI->>FE_Index : Render feedback component +FE_Index->>FE_Wrapper : Dynamic import of wrapper layer +FE_Wrapper->>FE_Actions : Pass properties and slots +FE_Actions->>ADX : Render Actions.Feedback +ADX-->>UI : User interaction (like/dislike) +note over FE_Index,BE_Comp : Backend component skips API process, only handles rendering and property forwarding +``` + +Diagram Sources + +- [frontend/antdx/actions/feedback/Index.svelte:10-61](file://frontend/antdx/actions/feedback/Index.svelte#L10-L61) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:5-13](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L5-L13) +- [frontend/antdx/actions/actions.tsx:98-116](file://frontend/antdx/actions/actions.tsx#L98-L116) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py:56-60](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L56-L60) + +## Detailed Component Analysis + +### Frontend Component Chain Analysis + +- Index.svelte + - Responsible for dynamically importing the wrapper layer, handling component property and extra property merging, and supporting forwarding of common properties such as visibility, styles, class names, and element IDs. + - Uses getSlots to retrieve slot content and renders children into the wrapper layer. +- actions.feedback.tsx + - Wraps the React component Actions.Feedback as a Svelte component via sveltify, maintaining property forwarding and event compatibility. +- actions.tsx (Actions container) + - Uniformly handles items, dropdownProps, slot rendering, and function parameterization to ensure Actions.Feedback renders correctly within the container. +- context.ts + - Provides the Items context, supporting Actions sub-item registration and rendering. + +```mermaid +flowchart TD +Start(["Enter Index.svelte"]) --> LoadWrapper["Dynamically import actions.feedback.tsx"] +LoadWrapper --> MergeProps["Merge component properties and additional properties"] +MergeProps --> VisibleCheck{"Is visible?"} +VisibleCheck --> |Yes| RenderWrapper["Render ActionsFeedback wrapper layer"] +VisibleCheck --> |No| Skip["Skip rendering"] +RenderWrapper --> PassSlots["Forward slots and children"] +PassSlots --> End(["Complete"]) +Skip --> End +``` + +Diagram Sources + +- [frontend/antdx/actions/feedback/Index.svelte:21-61](file://frontend/antdx/actions/feedback/Index.svelte#L21-L61) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:5-13](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L5-L13) + +Section Sources + +- [frontend/antdx/actions/feedback/Index.svelte:10-61](file://frontend/antdx/actions/feedback/Index.svelte#L10-L61) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:5-13](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L5-L13) +- [frontend/antdx/actions/actions.tsx:27-120](file://frontend/antdx/actions/actions.tsx#L27-L120) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) + +### Data Collection and Processing Mechanism + +- Feedback value types + - Supports three values for the value field: "like" (thumbs up), "dislike" (thumbs down), "default" (default), used to distinguish user feedback inclinations. +- Events and state + - The component itself does not execute backend API calls; interaction results are handled by the frontend. The backend component declares skip_api=True to avoid entering the standard API process. +- Slots and extensibility + - The feedback button group, custom text, or icons can be extended through the slot mechanism, combined with the Actions container to achieve richer interaction forms. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py:30-54](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L30-L54) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py:59-60](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L59-L60) + +### Usage Examples and Best Practices + +- Satisfaction survey + - Scenario: Provide "satisfied/dissatisfied" feedback buttons at the end of conversation records; clicking updates the metadata of the corresponding record. + - Implementation points: Use the Actions container to host feedback buttons, set value to "like"/"dislike", and combine with business state update logic. +- Feature evaluation + - Scenario: Provide a "useful/not useful" evaluation entry on feature module pages to collect feature usage feedback. + - Implementation points: Extend button text and icons through slots, combine with backend state management for statistical archiving. +- Issue reporting + - Scenario: Provide an "issue feedback" entry in error prompts or abnormal paths to guide users to provide problem descriptions. + - Implementation points: Combine form components with Actions to collect user input and context information, then submit uniformly to the issue tracking system. + +Note: The above are general usage patterns; specific implementation needs to be extended in combination with business state and backend services. + +### Analysis Methods, Statistical Display, and Response Handling + +- Analysis methods + - Aggregate statistics based on the value field (e.g., "like" percentage, "dislike" percentage). + - Perform cross-analysis combining time dimensions, session dimensions, and feature module dimensions. +- Statistical display + - The frontend can use chart components (such as bar charts, pie charts) to visually present feedback distribution. + - The backend can provide aggregation APIs that return statistical results for each dimension. +- Response handling + - For "dislike" feedback, consider triggering alerts or automatically escalating to manual customer service. + - Perform root cause analysis and repair priority sorting for high-frequency negative feedback. + +Note: The above are general analysis and processing approaches; specific implementation needs to be customized based on product requirements and data platform capabilities. + +## Dependency Analysis + +- Frontend dependencies + - @svelte-preprocess-react: Implements bridging of React components to Svelte. + - @ant-design/x: Provides the React implementation of Actions.Feedback. + - @utils/\*: Provides rendering utilities (renderItems, renderParamsSlot, createFunction) and context utilities. +- Backend dependencies + - Gradio component base class: Provides common properties such as visible, elem_id, elem_classes, and elem_style. + - Frontend directory resolution: Specifies the frontend resource path via resolve_frontend_dir. + +```mermaid +graph LR +FE_Index["Index.svelte"] --> FE_Wrapper["actions.feedback.tsx"] +FE_Wrapper --> FE_Actions["actions.tsx"] +FE_Actions --> Utils["@utils/*"] +FE_Actions --> ADX["@ant-design/x"] +BE_Init["Backend __init__.py"] --> FE_Index +``` + +Diagram Sources + +- [frontend/antdx/actions/feedback/Index.svelte:10-12](file://frontend/antdx/actions/feedback/Index.svelte#L10-L12) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L3) +- [frontend/antdx/actions/actions.tsx:1-10](file://frontend/antdx/actions/actions.tsx#L1-L10) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L56) + +Section Sources + +- [frontend/antdx/actions/feedback/package.json:1-15](file://frontend/antdx/actions/feedback/package.json#L1-L15) +- [frontend/antdx/actions/feedback/actions.feedback.tsx:1-3](file://frontend/antdx/actions/feedback/actions.feedback.tsx#L1-L3) +- [frontend/antdx/actions/actions.tsx:1-10](file://frontend/antdx/actions/actions.tsx#L1-L10) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L56) + +## Performance Considerations + +- On-demand loading: Index.svelte dynamically imports the wrapper layer via importComponent, reducing initial bundle size and first-screen rendering pressure. +- Property forwarding: Only necessary properties are forwarded, avoiding redundant calculations and DOM updates. +- Slot rendering: Using tools such as renderItems/renderParamsSlot ensures slot content is rendered and cloned on demand, reducing repetitive overhead. +- Event binding: The Actions container centrally handles events and rendering, avoiding event storms caused by multiple layers of nesting. + +## Troubleshooting Guide + +- Component not displayed + - Check if the visible property is true. + - Confirm whether elem_id, elem_classes, and elem_style are affecting the layout or being overridden. +- Interaction not working + - Confirm the Actions container is rendered correctly and that dropdownProps, items, and other properties are correctly passed. + - Check if slot key names match (e.g., dropdownProps.menu.items). +- Backend errors + - The backend component has skip_api=True; if API-related errors occur, check if the frontend is mistakenly using the backend API process. + - Confirm the frontend directory pointed to by FRONTEND_DIR exists and is accessible. + +Section Sources + +- [frontend/antdx/actions/feedback/Index.svelte:48-61](file://frontend/antdx/actions/feedback/Index.svelte#L48-L61) +- [frontend/antdx/actions/actions.tsx:39-96](file://frontend/antdx/actions/actions.tsx#L39-L96) +- [backend/modelscope_studio/components/antdx/actions/feedback/**init**.py:59-60](file://backend/modelscope_studio/components/antdx/actions/feedback/__init__.py#L59-L60) + +## Conclusion + +The Feedback component achieves efficient collection and extensibility of user feedback through a "Svelte entry + React wrapper + Actions container" architecture. Its design emphasizes front-backend decoupling, on-demand loading, and slot extensibility, making it suitable for satisfaction surveys, feature evaluations, issue reports, and many other scenarios. Combined with reasonable statistical analysis and response handling strategies, it can significantly improve product iteration efficiency and user experience quality. + +## Appendix + +- Component export and packaging + - In package.json, the exports mapping points both the Gradio and default entry points to the same Svelte file, facilitating loading in different environments. +- Related component index + - The backend antdx component index contains the Feedback component mapping for unified management and lookup. + +Section Sources + +- [frontend/antdx/actions/feedback/package.json:4-13](file://frontend/antdx/actions/feedback/package.json#L4-L13) +- [backend/modelscope_studio/components/antdx/**init**.py](file://backend/modelscope_studio/components/antdx/__init__.py#L5) diff --git a/.wiki/en/Ant Design X Components/Feedback Components/Feedback Components.md b/.wiki/en/Ant Design X Components/Feedback Components/Feedback Components.md new file mode 100644 index 00000000..3514d9e2 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Feedback Components/Feedback Components.md @@ -0,0 +1,340 @@ +# Feedback Components + + +**Files referenced in this document** +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/antdx/actions/action-item/Index.svelte](file://frontend/antdx/actions/action-item/Index.svelte) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/feedback/Index.svelte](file://frontend/antdx/actions/feedback/Index.svelte) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the Ant Design X feedback component system, particularly the Actions operation list component and the ActionItem sub-component. Actions provides a unified operation entry point and feedback collection capability, supporting flexible configuration of menu items, dropdown rendering, overflow indicators, and more through slots and properties. ActionItem serves as a sub-item container, responsible for converting the subtree (default slot or sub-item slot) into structured data that can be parsed by Actions, and completing parent-child communication and state management through the context mechanism. The feedback component (ActionsFeedback) encapsulates Ant Design X's feedback capability for easy integration into conversation bubbles, message streams, and similar scenarios. + +The key value of this component system in improving user interaction experience includes: + +- Unified operation entry points and visual style, reducing cognitive load +- Flexible slot-based extensibility, supporting complex nesting and dynamic rendering +- Ensuring lifecycle and event propagation correctness for operation items through context and state management +- Embedding "feedback" capability within the operation list, improving information loop and usability + +## Project Structure + +The Ant Design X feedback components are located in the frontend directory under antdx/actions, containing the main Actions component, the ActionItem sub-component, the ActionsFeedback component, and the createItemsContext utility for building the operation item structure. + +```mermaid +graph TB +subgraph "Ant Design X Feedback Components" +A_Index["actions/Index.svelte"] +A_Tsx["actions/actions.tsx"] +A_Ctx["actions/context.ts"] +AI_Index["actions/action-item/Index.svelte"] +AI_Tsx["actions/action-item/actions.action-item.tsx"] +AF_Index["actions/feedback/Index.svelte"] +AF_Tsx["actions/feedback/actions.feedback.tsx"] +U_Ctx["utils/createItemsContext.tsx"] +end +A_Index --> A_Tsx +A_Tsx --> A_Ctx +A_Tsx --> U_Ctx +AI_Index --> AI_Tsx +AI_Tsx --> A_Ctx +AF_Index --> AF_Tsx +``` + +**Diagram Sources** + +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/antdx/actions/action-item/Index.svelte](file://frontend/antdx/actions/action-item/Index.svelte) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/feedback/Index.svelte](file://frontend/antdx/actions/feedback/Index.svelte) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +**Section Sources** + +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/antdx/actions/action-item/Index.svelte](file://frontend/antdx/actions/action-item/Index.svelte) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/feedback/Index.svelte](file://frontend/antdx/actions/feedback/Index.svelte) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +## Core Components + +- Actions main component: Responsible for receiving items or sub-items from slots, combining context and slot rendering to generate Ant Design X operation lists, and supporting advanced features like dropdown rendering and overflow indicators. +- ActionItem sub-component: Acts as a container for a single operation item, merging the default slot and sub-item slot into a unified data structure, which is collected and passed through the context. +- ActionsFeedback feedback component: A lightweight encapsulation of Ant Design X's feedback capability, enabling easy integration of feedback entry points in the interface. +- createItemsContext utility: Provides ItemsContext creation, Provider wrapping, useItems hooks, and ItemHandler components, supporting structured collection and recursive processing of operation items. + +**Section Sources** + +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +## Architecture Overview + +The Actions rendering pipeline has two layers: + +- Svelte layer: Index.svelte is responsible for parsing properties, appending class names and IDs, handling slot mappings, and importing the React implementation on demand. +- React layer: actions.tsx converts slots and properties into the items structure required by Ant Design X, while handling advanced configurations such as dropdown menu rendering and overflow indicators. + +ActionItem's responsibility is to convert the subtree it wraps (default slot and subItems slot) into structured Item data, and write it to the parent Actions via context. + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant S as "actions/Index.svelte" +participant R as "actions/actions.tsx" +participant C as "actions/context.ts" +participant U as "utils/createItemsContext.tsx" +UI->>S : Pass properties and slots +S->>R : Import and forward props, slots, extra attributes +R->>C : Wrap with context Provider +R->>U : Use createItemsContext to collect items +R->>R : Render Ant Design X Actions +Note over R : Handle dropdownRender/popupRender/overflowedIndicator slots +``` + +**Diagram Sources** + +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +## Detailed Component Analysis + +### Actions Main Component + +- Input and property handling: Uses Svelte's getProps/processProps for unified processing of visibility, element styles/class names, IDs, and extra attributes, mapping some events to the names required by Ant Design X. +- Slots and rendering: Supports children, dropdownRender, popupRender, overflowedIndicator, expandIcon, and other slots; converts slots into React-compatible render functions or nodes via renderSlot/renderParamsSlot. +- Dropdown enhancement: When dropdownProps.menu.items or a slot exists, slot-generated items take priority; also supports custom expandIcon and overflowedIndicator. +- State and events: Obtains items from context via useItems and useMenuItems to avoid redundant rendering; events such as openChange/select/deselect are forwarded to the underlying component via props. + +```mermaid +flowchart TD +Start(["Enter Actions Render"]) --> CheckVisible{"Is visible?"} +CheckVisible --> |No| End(["End"]) +CheckVisible --> |Yes| ResolveItems["Resolve items or slot sub-items"] +ResolveItems --> BuildDropdown["Build dropdownProps\nMerge slots and properties"] +BuildDropdown --> RenderX["Render Ant Design X Actions"] +RenderX --> End +``` + +**Diagram Sources** + +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) + +**Section Sources** + +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) + +### ActionItem Sub-Component + +- Slots and properties: Supports the actionRender slot and actionRender property, converting strings or functions into executable functions via createFunction; also retains the default slot and sub-item slot. +- Context writing: Uses ItemHandler to write the current item's props, slots, sub-items, and other structured data into the context for the parent Actions to consume. +- Sub-item selection strategy: If subItems exists, it takes priority; otherwise falls back to the default slot, forming a flexible hierarchical structure. + +```mermaid +sequenceDiagram +participant Parent as "Actions" +participant Child as "ActionItem" +participant Handler as "ItemHandler" +participant Ctx as "ItemsContext" +Parent->>Child : Pass props and slots +Child->>Handler : Wrap and set allowedSlots=['default','subItems'] +Handler->>Ctx : Write current item's props/slots/sub-items +Ctx-->>Parent : Provide items for Actions rendering +``` + +**Diagram Sources** + +- [frontend/antdx/actions/action-item/Index.svelte](file://frontend/antdx/actions/action-item/Index.svelte) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +**Section Sources** + +- [frontend/antdx/actions/action-item/Index.svelte](file://frontend/antdx/actions/action-item/Index.svelte) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +### ActionsFeedback Component + +- Role: A lightweight encapsulation of Ant Design X's Actions.Feedback, simplifying the calling interface. +- Slots and properties: Follows the same slot and property handling process as the parent layer, enabling direct use in conversation bubbles, message streams, and similar scenarios. + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant F_Index as "feedback/Index.svelte" +participant F_Tsx as "feedback/actions.feedback.tsx" +UI->>F_Index : Pass properties and slots +F_Index->>F_Tsx : Import and forward props, slots +F_Tsx-->>UI : Render Ant Design X Actions.Feedback +``` + +**Diagram Sources** + +- [frontend/antdx/actions/feedback/Index.svelte](file://frontend/antdx/actions/feedback/Index.svelte) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) + +**Section Sources** + +- [frontend/antdx/actions/feedback/Index.svelte](file://frontend/antdx/actions/feedback/Index.svelte) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) + +### Context and State Management (createItemsContext) + +- ItemsContext: Maintains the Item array under each slot, providing setItem to update items by index; the onChange callback notifies the parent of updates. +- ItemHandler: Writes the current item's props, slots, sub-items, and other structured data into the context when the component mounts; supports dynamic computation of itemProps and itemChildren. +- withItemsContextProvider: Provides an ItemsContextProvider for the subtree, allowing sub-items to continue writing their own sub-items, forming a recursive structure. + +```mermaid +classDiagram +class ItemsContextProvider { ++allowedSlots ++onChange(items) ++setItem(slotKey, index, item) +} +class ItemHandler { ++itemIndex ++itemSlotKey ++itemProps(props, items) ++itemChildren(items) ++allowedSlots +} +class ItemsContext { ++items ++setItem() ++initial +} +ItemsContextProvider --> ItemsContext : "Provides context" +ItemHandler --> ItemsContext : "Writes items" +``` + +**Diagram Sources** + +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +**Section Sources** + +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + +## Dependency Analysis + +- Actions dependencies: + - Context: actions/context.ts and utils/createItemsContext.tsx together form the foundation for item collection and forwarding. + - Slot rendering: renderSlot/renderParamsSlot converts slots into React-executable functions or nodes. + - Ant Design X: Final rendering is handled by the Actions component from @ant-design/x. +- ActionItem dependencies: + - ItemHandler and context: Writes its own structure into the context for the parent to consume. + - Slot handling: Supports actionRender and default/sub-item slots. +- ActionsFeedback dependencies: + - Directly encapsulates Ant Design X's Actions.Feedback. + +```mermaid +graph LR +Actions["actions.tsx"] --> Ctx["actions/context.ts"] +Actions --> Utils["utils/createItemsContext.tsx"] +Actions --> ADX["@ant-design/x Actions"] +ActionItem["action-item/actions.action-item.tsx"] --> Ctx +ActionItem --> Utils +Feedback["feedback/actions.feedback.tsx"] --> ADX_F["@ant-design/x Actions.Feedback"] +``` + +**Diagram Sources** + +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) + +**Section Sources** + +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/antdx/actions/feedback/actions.feedback.tsx](file://frontend/antdx/actions/feedback/actions.feedback.tsx) + +## Performance Considerations + +- Render optimization: + - Uses useMemo to cache the result of dropdownProps construction, avoiding unnecessary re-renders. + - Only injects dropdownProps when valid values exist, reducing side effects from empty objects. +- Events and properties: + - Maps event names to the names required by underlying components via processProps, avoiding runtime conversion overhead. +- Slot handling: + - renderSlot/renderParamsSlot performs cloning and parameterized wrapping only when necessary, reducing DOM manipulation costs. +- Context writing: + - Uses useRef and isEqual to compare previous and current values, triggering setItem only when changes occur to avoid redundant writes. + +[This section contains general performance recommendations and does not analyze specific files directly] + +## Troubleshooting Guide + +- Issue: Operation items not displayed + - Troubleshooting: Confirm the visible property is true; check if items is empty; confirm slot key names match allowedSlots. + - Reference path: [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- Issue: Dropdown menu not working + - Troubleshooting: Check if dropdownProps.menu.items is passed correctly; confirm the dropdownProps.menu.items slot is being rendered. + - Reference path: [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- Issue: Sub-items not nested correctly + - Troubleshooting: Confirm the ActionItem's subItems slot is correctly named; check the ItemHandler's itemChildrenKey setting. + - Reference path: [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- Issue: Events not triggered + - Troubleshooting: Confirm event name mappings are correct; check if props are forwarded to the underlying component. + - Reference path: [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) + +**Section Sources** + +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/action-item/actions.action-item.tsx](file://frontend/antdx/actions/action-item/actions.action-item.tsx) +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) + +## Conclusion + +The Actions operation list component implements flexible, high-performance operation item management through a clear context and slot mechanism. ActionItem, as a sub-item container, provides stable structured data writing capability. ActionsFeedback seamlessly integrates feedback capability into the operation list. The overall design balances ease of use with extensibility and performance, significantly enhancing user interaction experience in conversation, message, and prompt scenarios. + +[This section contains summary content and does not analyze specific files directly] + +## Appendix + +- Usage examples (scenario guide) + - Feedback collection: Place ActionsFeedback in areas where user feedback needs to be collected, configuring feedback entry points through slots and properties. + - Operation execution: Configure items in Actions, combining dropdownRender/popupRender slots to customize menu appearance; handle clicks and selections through event callbacks. + - Result display: Use overflowedIndicator and expandIcon slots to control menu overflow and expand behavior, ensuring a good experience on small-screen devices. +- Best practices + - Divide slot key names reasonably to avoid conflicts; use unified naming conventions for maintainability. + - Use useMemo to cache complex calculations and reduce rendering pressure. + - Keep event handler functions stable to avoid re-renders caused by changes in function references. + +[This section contains conceptual content and does not analyze specific files directly] diff --git a/.wiki/en/Ant Design X Components/Feedback Components/Item Component.md b/.wiki/en/Ant Design X Components/Feedback Components/Item Component.md new file mode 100644 index 00000000..81b21157 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Feedback Components/Item Component.md @@ -0,0 +1,318 @@ +# Item Component + + +**Files referenced in this document** +- [frontend/antdx/actions/item/Index.svelte](file://frontend/antdx/actions/item/Index.svelte) +- [frontend/antdx/actions/item/actions.item.tsx](file://frontend/antdx/actions/item/actions.item.tsx) +- [backend/modelscope_studio/components/antdx/actions/item/__init__.py](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py) +- [frontend/antdx/actions/actions.tsx](file://frontend/antdx/actions/actions.tsx) +- [frontend/antdx/actions/context.ts](file://frontend/antdx/actions/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/antdx/actions/Index.svelte](file://frontend/antdx/actions/Index.svelte) +- [docs/components/antdx/actions/demos/basic.py](file://docs/components/antdx/actions/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the Item container (ActionItem) in the AntdX Actions component system, systematically explaining its responsibilities as an internal container within Actions, layout and style control, responsive design approach, collaboration mechanisms with sub-operation items, event forwarding and state synchronization, and providing practical recommendations and best practices for various layouts (horizontal, vertical, grid). This container plays a key role in "sub-item definition and rendering" in the overall component architecture, and is the foundational building block for constructing complex operation lists. + +## Project Structure + +- Frontend layer: The Svelte entry is responsible for property forwarding and visibility control; the React wrapper layer interfaces with Ant Design X's Actions.Item; the backend Python component handles Gradio integration and event binding. +- Utility layer: Universal items context and rendering pipeline, supporting multi-level sub-items, slots, and parameterized rendering. + +```mermaid +graph TB +subgraph "Frontend" +A["Index.svelte\nActions main entry"] +B["actions.tsx\nEncapsulates Ant Design X Actions"] +C["context.ts\nItems context"] +D["createItemsContext.tsx\nContext and ItemHandler implementation"] +E["renderItems.tsx\nRendering pipeline"] +F["item/Index.svelte\nItem container entry"] +G["item/actions.item.tsx\nReact wrapper and slot injection"] +end +subgraph "Backend" +H["backend/.../item/__init__.py\nGradio component definition and events"] +end +A --> B +B --> C +C --> D +D --> E +B --> E +F --> G +G --> |"Wraps"| B +H --> A +``` + +Diagram Sources + +- [frontend/antdx/actions/Index.svelte:1-77](file://frontend/antdx/actions/Index.svelte#L1-L77) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:1-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L1-L77) + +Section Sources + +- [frontend/antdx/actions/Index.svelte:1-77](file://frontend/antdx/actions/Index.svelte#L1-L77) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/antdx/actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:1-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L1-L77) + +## Core Components + +- Item container entry (Svelte) + - Responsible for receiving properties, extra properties, visibility, styles, and class names passed from the parent, and forwarding these to the React wrapper layer. + - Uses deferred derived computation for final properties, ensuring updates only occur when necessary. + - Supports slots and child node rendering for injecting icons, action renderers, etc. into sub-items. +- React wrapper layer (sveltify) + - Interfaces Ant Design X's Actions.Item with the slot system, supporting slots such as defaultIcon and runningIcon. + - Clones and injects Svelte slot content into corresponding positions via ReactSlot. +- Backend component (Python) + - Defines supported slots (defaultIcon, runningIcon), events (such as click), and properties (label, status, styles, etc.). + - Controls whether to skip API (skip_api) and preprocessing/postprocessing flows. + +Section Sources + +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:1-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L1-L77) + +## Architecture Overview + +The position of the Item container in the Actions system: as the "container" for sub-items, it is responsible for converting user-configured properties and slot content into the structure required by Ant Design X, and participates in overall rendering and event dispatching. + +```mermaid +sequenceDiagram +participant U as "User Code" +participant S as "Svelte Entry (Index.svelte)" +participant R as "React Wrapper (actions.item.tsx)" +participant A as "Ant Design X Actions.Item" +participant P as "Backend Component (__init__.py)" +U->>S : Configure ActionItem properties and slots +S->>R : Forward properties and slots +R->>A : Render and inject slots (defaultIcon/runningIcon) +A-->>U : Trigger event callbacks +U->>P : Event binding (click, etc.) +P-->>U : Event data returned +``` + +Diagram Sources + +- [frontend/antdx/actions/item/Index.svelte:1-60](file://frontend/antdx/actions/item/Index.svelte#L1-L60) +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:1-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L1-L77) + +## Detailed Component Analysis + +### Component Relationships and Responsibilities + +- Actions main container: Responsible for aggregating sub-items, handling dropdown menus, overflow indicators, expansion icons, and other advanced capabilities. +- Item container: Responsible for rendering individual sub-items, slot injection, state (such as loading/error/running/default), and label display. +- Context and rendering pipeline: Uniformly manages item collection, sub-item tree construction, slots, and parameterized rendering. + +```mermaid +classDiagram +class ActionsMainContainer { ++Aggregate sub-items ++Handle dropdown menus ++Overflow indicators +} +class ItemContainer { ++Property forwarding ++Slot injection ++State rendering +} +class ContextAndRendering { ++Collect items ++Sub-item tree construction ++Slot/parameterized rendering +} +ActionsMainContainer --> ContextAndRendering : "Consumes" +ContextAndRendering --> ItemContainer : "Generates" +``` + +Diagram Sources + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) + +Section Sources + +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) + +### Layout Management and Style Control + +- Visibility control: Determines whether to render via the visible property, avoiding unnecessary DOM. +- Class names and IDs: elem_classes and elem_id are used for style overrides and positioning. +- Behavioral styles: elem_style is used for dynamic style injection, suitable for size and spacing adjustments in responsive scenarios. +- Container styles: In the Svelte entry, styles and class names are merged and applied to the root element, ensuring consistency with the parent layout. + +Section Sources + +- [frontend/antdx/actions/item/Index.svelte:19-60](file://frontend/antdx/actions/item/Index.svelte#L19-L60) +- [frontend/antdx/actions/Index.svelte:27-77](file://frontend/antdx/actions/Index.svelte#L27-L77) + +### Responsive Design + +- Based on Ant Design X's built-in Actions overflow and dropdown menu capabilities, the Item container can adapt to narrow screens without additional responsive logic. +- If custom responsive behavior is needed, widths and spacing can be set by breakpoints in elem_style; or layout constraints can be applied through outer containers (such as Space, Grid). + +Section Sources + +- [frontend/antdx/actions/actions.tsx:39-96](file://frontend/antdx/actions/actions.tsx#L39-L96) + +### Sub-operation Item Collaboration Mechanism + +- Slot injection: Slots such as defaultIcon and runningIcon are injected into corresponding fields of Ant Design X via ReactSlot, achieving differentiated display of icons and running state icons. +- Sub-item tree: Builds the sub-item tree through createItemsContext and renderItems, supporting nested ActionItem and subItems slots. +- Parameterized rendering: Slots can carry withParams to implement on-demand parameter-passing rendering. + +```mermaid +flowchart TD +Start(["Start"]) --> Collect["Collect slots and properties"] +Collect --> BuildTree["Build sub-item tree"] +BuildTree --> InjectSlots["Inject slots (defaultIcon/runningIcon)"] +InjectSlots --> Render["Render as Ant Design X structure"] +Render --> End(["End"]) +``` + +Diagram Sources + +- [frontend/utils/createItemsContext.tsx:190-261](file://frontend/utils/createItemsContext.tsx#L190-L261) +- [frontend/utils/renderItems.tsx:8-114](file://frontend/utils/renderItems.tsx#L8-L114) +- [frontend/antdx/actions/item/actions.item.tsx:10-32](file://frontend/antdx/actions/item/actions.item.tsx#L10-L32) + +Section Sources + +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) + +### Event Forwarding and State Synchronization + +- Event binding: The backend component declares click event listeners and enables event binding through internal flags. +- State synchronization: The Item's state (such as loading/error/running/default) is driven by backend properties; the frontend switches icons and interaction feedback according to state. +- Callback data: Key information such as keyPath and key can be obtained in event callbacks for branch processing on the business side. + +Section Sources + +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:15-19](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L15-L19) +- [docs/components/antdx/actions/demos/basic.py:7-10](file://docs/components/antdx/actions/demos/basic.py#L7-L10) + +### Complex Layout Practice Recommendations + +- Horizontal arrangement: Place multiple ActionItems directly under Actions, leveraging Ant Design X's default inline layout. +- Vertical arrangement: Control direction and alignment through outer containers (such as Flex, Space). +- Grid layout: In more complex scenarios, combine Grid or custom containers with elem_style to control column widths and spacing. +- Overflow strategy: When there are many sub-items, use Actions' dropdown menu and overflow indicator to automatically collapse items, keeping the interface tidy. + +Section Sources + +- [frontend/antdx/actions/actions.tsx:39-96](file://frontend/antdx/actions/actions.tsx#L39-L96) +- [frontend/antdx/actions/Index.svelte:27-77](file://frontend/antdx/actions/Index.svelte#L27-L77) + +## Dependency Analysis + +- Component coupling + - The Item container and the Actions main container are decoupled through context and the rendering pipeline, with dependencies arising only during the rendering phase. + - The slot system decouples slot content from the host component through ReactSlot and ContextPropsProvider. +- External dependencies + - Ant Design X: Provides the foundational capabilities of Actions and Actions.Item. + - Gradio: Backend component bridges frontend events and data flows. + +```mermaid +graph LR +Item["Item Container"] --> ADX["Ant Design X"] +Item --> Slots["Slot System"] +ADX --> Events["Event System"] +Slots --> Params["Parameterized Rendering"] +Events --> Backend["Backend Component"] +``` + +Diagram Sources + +- [frontend/antdx/actions/item/actions.item.tsx:10-32](file://frontend/antdx/actions/item/actions.item.tsx#L10-L32) +- [frontend/antdx/actions/actions.tsx:39-96](file://frontend/antdx/actions/actions.tsx#L39-L96) +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:15-19](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L15-L19) + +Section Sources + +- [frontend/antdx/actions/item/actions.item.tsx:1-35](file://frontend/antdx/actions/item/actions.item.tsx#L1-L35) +- [frontend/antdx/actions/actions.tsx:1-123](file://frontend/antdx/actions/actions.tsx#L1-L123) +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:1-77](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L1-L77) + +## Performance Considerations + +- Render optimization + - Uses deferred derived ($derived) and useMemo strategies to eliminate unnecessary re-renders. + - Controls cloning strategy through renderItems' clone/forceClone to reduce redundant rendering costs. +- Events and state + - Event binding is enabled only when needed, avoiding overhead from global listeners. + - State transitions (such as loading/error/running/default) are driven by properties as much as possible to reduce side effects. + +Section Sources + +- [frontend/antdx/actions/item/Index.svelte:19-41](file://frontend/antdx/actions/item/Index.svelte#L19-L41) +- [frontend/antdx/actions/actions.tsx:104-113](file://frontend/antdx/actions/actions.tsx#L104-L113) +- [frontend/utils/renderItems.tsx:8-114](file://frontend/utils/renderItems.tsx#L8-L114) + +## Troubleshooting Guide + +- Slot not working + - Check if slot key names are correct (e.g., defaultIcon, runningIcon). + - Confirm that slot content is a valid element or configuration object. +- Icons not displaying + - Ensure slot content is correctly injected via ReactSlot. + - Check if the corresponding Ant Design X field is being overridden. +- Events not triggered + - Confirm the backend component has declared the corresponding events (such as click). + - Check if event binding is enabled (the \_internal flag). +- Sub-items not displaying + - Check the visible property and rendering conditions. + - Confirm the items context is correctly collected and forwarded. + +Section Sources + +- [frontend/antdx/actions/item/actions.item.tsx:15-28](file://frontend/antdx/actions/item/actions.item.tsx#L15-L28) +- [backend/modelscope_studio/components/antdx/actions/item/**init**.py:15-19](file://backend/modelscope_studio/components/antdx/actions/item/__init__.py#L15-L19) +- [frontend/antdx/actions/item/Index.svelte:46-59](file://frontend/antdx/actions/item/Index.svelte#L46-L59) + +## Conclusion + +The Item container plays the core role of "sub-item definition and rendering" in the Actions system. Through the slot system and context rendering pipeline, it converts user configuration into the data structure required by Ant Design X, and collaborates with the event system to complete state synchronization and interaction feedback. With its decoupled design and flexible slot mechanism, developers can easily implement operation list layouts ranging from simple to complex, and achieve good compatibility in responsive scenarios. + +## Appendix + +- Usage example reference: Demonstrates how to add ActionItem in Actions and inject icons and action renderers through slots, while binding click events and sub-item deletion events. + +Section Sources + +- [docs/components/antdx/actions/demos/basic.py:17-53](file://docs/components/antdx/actions/demos/basic.py#L17-L53) diff --git a/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Chat Bubble.md b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Chat Bubble.md new file mode 100644 index 00000000..b32c20e5 --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Chat Bubble.md @@ -0,0 +1,227 @@ +# Bubble Chat Bubble + + +**Files referenced in this document** +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/antdx/bubble/list/bubble.list.tsx](file://frontend/antdx/bubble/list/bubble.list.tsx) +- [frontend/antdx/bubble/list/item/bubble.list.item.tsx](file://frontend/antdx/bubble/list/item/bubble.list.item.tsx) +- [frontend/antdx/bubble/list/role/bubble.list.role.tsx](file://frontend/antdx/bubble/list/role/bubble.list.role.tsx) +- [frontend/antdx/bubble/list/context.ts](file://frontend/antdx/bubble/list/context.ts) +- [frontend/antdx/bubble/list/utils.tsx](file://frontend/antdx/bubble/list/utils.tsx) +- [frontend/utils/patchSlots.ts](file://frontend/utils/patchSlots.ts) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) + + +## Update Summary + +**Changes Made** + +- Updated performance optimization for Bubble component slot handling logic +- Removed unused unshift behavior to improve rendering performance +- Enhanced technical documentation for the slot patching mechanism + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance and Maintainability](#performance-and-maintainability) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document covers the Bubble chat bubble component system, outlining its overall architecture, core capabilities, and usage, including: + +- Bubble component rendering mechanism and slot/functional content adaptation +- BubbleList message display logic and role distribution +- BubbleListItem rendering rules and context injection +- BubbleListRole usage and dynamic assembly +- Divider component role in conversations and use cases +- Style customization, event handling, and best practices + +## Project Structure + +The Bubble component resides in the frontend antdx sub-package, using a Svelte wrapper to bridge @ant-design/x native components, with list rendering, role assignment, and slot rendering via contexts and utility functions. + +```mermaid +graph TB +subgraph "Bubble Frontend Implementation" +A["bubble.tsx
Exports Bubble Component"] +B["list/bubble.list.tsx
Exports BubbleList Component"] +C["list/item/bubble.list.item.tsx
Exports BubbleListItem Component"] +D["list/role/bubble.list.role.tsx
Exports BubbleListRole Component"] +E["list/context.ts
Items/Role Context"] +F["list/utils.tsx
useRole Utility and Slot Patching"] +G["utils/patchSlots.ts
Slot Patch Enhancement"] +H["utils/renderItems.tsx
Slot Rendering and Argument Passing"] +end +A --> |"Wraps and forwards props/slots"| X["@ant-design/x Bubble"] +B --> |"Combines Items/Role context"| X +C --> |"Injects ItemHandler"| X +D --> |"Injects RoleItemHandler"| X +E --> |"Provides useItems/useRoleItems"| B +F --> |"Computes role mapping/slot patches"| B +G --> |"Enhances slot patching"| F +H --> |"Normalizes slot rendering"| B +``` + +**Diagram Sources** + +- [frontend/antdx/bubble/bubble.tsx:1-120](file://frontend/antdx/bubble/bubble.tsx#L1-L120) +- [frontend/antdx/bubble/list/bubble.list.tsx:1-50](file://frontend/antdx/bubble/list/bubble.list.tsx#L1-L50) +- [frontend/antdx/bubble/list/item/bubble.list.item.tsx:1-14](file://frontend/antdx/bubble/list/item/bubble.list.item.tsx#L1-L14) +- [frontend/antdx/bubble/list/role/bubble.list.role.tsx:1-14](file://frontend/antdx/bubble/list/role/bubble.list.role.tsx#L1-L14) +- [frontend/antdx/bubble/list/context.ts:1-13](file://frontend/antdx/bubble/list/context.ts#L1-L13) +- [frontend/antdx/bubble/list/utils.tsx:1-135](file://frontend/antdx/bubble/list/utils.tsx#L1-L135) +- [frontend/utils/patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) + +## Core Components + +- **Bubble**: A Svelte wrapper around @ant-design/x's Bubble, supporting unified rendering of slots and functional props, compatible with editable text slots. +- **BubbleList**: List container responsible for merging external items and slot items, injecting role context, and delegating rendering to @ant-design/x's List. +- **BubbleListItem**: Message item wrapper that injects context via ItemHandler, enabling individual Bubbles to be aware of the list environment. +- **BubbleListRole**: Role item wrapper that injects role context via RoleItemHandler, allowing role configurations to be resolved by useRole. +- **useRole**: Core role resolution utility that supports default keys, pre-processing, post-processing, and slot patching, converting role mappings to the RoleType required by @ant-design/x. + +## Architecture Overview + +The Bubble system uses a "wrapper + context + utility functions" core design, bridging @ant-design/x's native capabilities with Gradio-style slots/functional props to form an extensible, role-based message list. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant BL as "BubbleList" +participant Ctx as "Context (Items/Role)" +participant UR as "useRole Utility" +participant PS as "patchSlots Enhancement" +participant XBL as "@ant-design/x List" +participant BI as "BubbleListItem/BubbleListRole" +U->>BL : Provides items or slot items +BL->>Ctx : Injects Items/Role context +BL->>UR : Computes role mapping and slot patches +UR->>PS : Applies slot patch enhancement +PS-->>UR : Returns enhanced patches +UR-->>BL : Returns RoleType +BL->>XBL : Renders list with role +loop For each message +XBL->>BI : Renders message item +BI-->>XBL : Passes Bubble props/slots +end +``` + +## Component Details + +### Bubble Component + +- **Purpose**: Svelte wrapper around @ant-design/x's Bubble, handling slots and functional props uniformly, supporting editable text slots. +- **Key Points**: + - Slot-first: When a corresponding slot exists, it takes priority over attribute values or functions. + - Editable mode: Supports custom "OK/Cancel" text via editable configuration combined with slots. + - Functional props: Uses `useFunction` to convert passed functions into renderable React components. + - Hidden children: Puts children in an invisible container to avoid duplicate rendering. + +```mermaid +flowchart TD +Start(["Enter Bubble Rendering"]) --> CheckEditable["Detect editable config and slots"] +CheckEditable --> BuildEditable{"Editable enabled?"} +BuildEditable --> |Yes| MergeEditable["Merge slots and config"] +BuildEditable --> |No| PassEditable["Pass through editable"] +MergeEditable --> ResolveSlots["Resolve header/footer/avatar/extra/content/loadingRender/contentRender"] +PassEditable --> ResolveSlots +ResolveSlots --> RenderX["Render @ant-design/x Bubble"] +RenderX --> End(["Done"]) +``` + +### BubbleList Component + +- **Purpose**: Message list container responsible for: + - Merging external items with slot items + - Injecting Items and Role contexts + - Resolving role mappings via useRole + - Delegating final rendering to @ant-design/x List +- **Key Points**: + - Prioritizes `props.items`; falls back to slot items/default + - Normalizes slot content to arrays via `renderItems` + - Caches items with `useMemo` to reduce re-renders + +### BubbleListItem and BubbleListRole + +- **BubbleListItem**: Injects ItemHandler into a Bubble, giving individual message items list context awareness. +- **BubbleListRole**: Injects RoleItemHandler into role configuration, enabling role items to be resolved to RoleType by useRole. + +### useRole - Role Resolution Utility + +- **Purpose**: Converts role configuration (string, function, or object) to the RoleType required by @ant-design/x, with slot patching and index injection. +- **Key Points**: + - Supports `defaultRoleKeys` + - Supports `preProcess` and `defaultRolePostProcess` hooks + - Automatically patches header/footer/avatar/extra/loadingRender/contentRender slots + - Default `contentRender` serializes objects to strings + +### Divider Component + +- **Purpose**: Inserts dividers between chat bubbles for visual segmentation and rhythm control. +- **Use Cases**: Multi-turn conversations, modular display, time/topic transition hints. +- Note: Divider is a standalone component, typically used alongside BubbleList, controlled via slots or layout. + +## Dependency Analysis + +- **Component coupling**: + - Bubble acts only as a wrapper, depending on @ant-design/x's native capabilities, making it easy to upgrade or replace. + - BubbleList depends on context and utility functions with clear responsibilities, centralized in useRole and renderItems. +- **Context and utilities**: + - `createItemsContext` provides two context sets (Items/Role) for list items and role items respectively. + - `useRole` is the core of role resolution, handling the conversion from configuration to rendering parameters. + - `patchSlots` provides slot patching enhancement, supporting argument passing and function composition. +- **External dependencies**: + - @ant-design/x: Provides Bubble/List/Role types and rendering capabilities + - @svelte-preprocess-react: Bridges Svelte and React slots + - @utils/\*: Provides rendering and function encapsulation utilities + +## Performance and Maintainability + +- **Performance optimization**: + - Use `useMemo` to cache BubbleList's items to avoid unnecessary re-renders. + - Set appropriate dependency arrays in `useRole` to avoid recomputing role mappings. + - Break large slot content into reusable components to reduce closure and object creation. + - **Optimization**: Removed unused unshift behavior, reducing unnecessary argument reorganization overhead. +- **Maintainability**: + - Centralize role configuration management to avoid scattering across templates. + - Use preProcess/postProcess hooks to unify message preprocessing and postprocessing. + - Maintain consistent slot naming conventions for team collaboration and documentation. + +## Troubleshooting Guide + +- **Slots not working** + - Check slot names against component conventions (e.g., avatar/header/footer/extra/content) + - Ensure Bubble/BubbleList correctly wraps the slots +- **Role configuration invalid** + - Confirm BubbleListRole correctly injects RoleItemHandler + - Check useRole's defaultRoleKeys and preProcess/postProcess are working as expected +- **Editable text not showing** + - Confirm both editable config and slots exist; slots take priority + - Check that editable.okText/editable.cancelText slots are correctly passed +- **List rendering issues** + - Confirm BubbleListItem correctly injects ItemHandler + - Check that items and slot items data structures match requirements + +## Conclusion + +The Bubble chat bubble component system uses "wrapper + context + utility functions" as its core design, preserving @ant-design/x's powerful capabilities while providing flexible slot and role-based extensions. Through the collaboration of BubbleList, BubbleListItem, BubbleListRole, and useRole, developers can quickly build complex, customizable conversation interfaces with good balance between style, interaction, and maintainability. + +## Appendix: Usage Examples and Best Practices + +- **Basic chat bubble**: Use Bubble component for message content, pass text/rich content via content slot or prop; add avatar, title, action area, and extra info via avatar/header/footer/extra slots. +- **Complex message formats**: Use contentRender objects/arrays for structured rendering; handle message fields and styles uniformly via preProcess/postProcess hooks. +- **Custom styles**: Configure different roles via role mapping combined with slot patches; use Divider at key points to improve readability. +- **Best practices**: + - Centralize role configuration management + - Use `useMemo` to cache items and role mappings + - Maintain consistent slot naming conventions + - Use patchSlots enhancements wisely when passing slot arguments diff --git a/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Component Overview.md b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Component Overview.md new file mode 100644 index 00000000..b3002521 --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble Component Overview.md @@ -0,0 +1,188 @@ +# Bubble Component Overview + + +**Files referenced in this document** +- [frontend/antdx/bubble/Index.svelte](file://frontend/antdx/bubble/Index.svelte) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/antdx/bubble/list/Index.svelte](file://frontend/antdx/bubble/list/Index.svelte) +- [frontend/antdx/bubble/list/bubble.list.tsx](file://frontend/antdx/bubble/list/bubble.list.tsx) +- [frontend/antdx/bubble/system/Index.svelte](file://frontend/antdx/bubble/system/Index.svelte) +- [frontend/antdx/bubble/system/bubble.system.tsx](file://frontend/antdx/bubble/system/bubble.system.tsx) +- [frontend/antdx/bubble/divider/Index.svelte](file://frontend/antdx/bubble/divider/Index.svelte) +- [frontend/antdx/bubble/divider/bubble.divider.tsx](file://frontend/antdx/bubble/divider/bubble.divider.tsx) +- [backend/modelscope_studio/components/antdx/bubble/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/__init__.py) +- [backend/modelscope_studio/components/antdx/bubble/list/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/list/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +Bubble is a visual chat bubble component designed for machine learning conversation scenarios, built on Ant Design X's Bubble capabilities. It provides message bubble rendering, editing, typing animation, content distribution, and more, with a seamless frontend-backend development experience through the Gradio/ModelScope ecosystem. The component family includes single bubbles, bubble lists, system message dividers, and system-type bubbles, covering conversation patterns from basic display to complex interactions. + +## Project Structure + +The Bubble component consists of a frontend Svelte wrapper layer and a backend Python component layer, using a dual-layer design of "frontend React component + backend Gradio component" to ensure declarative usage of Ant Design X capabilities in Python environments. + +```mermaid +graph TB +subgraph "Frontend Svelte Layer" +A["Index.svelte
Wrapper Entry"] +B["bubble.tsx
Sveltify Wrapper"] +C["list/Index.svelte
List Wrapper"] +D["list/bubble.list.tsx
List Implementation"] +E["system/Index.svelte
System Bubble Wrapper"] +F["system/bubble.system.tsx
System Bubble Implementation"] +G["divider/Index.svelte
Divider Wrapper"] +H["divider/bubble.divider.tsx
Divider Implementation"] +end +subgraph "Backend Python Layer" +P1["antdx/bubble/__init__.py
Main Component Class"] +P2["antdx/bubble/list/__init__.py
List Component Class"] +end +A --> B +C --> D +E --> F +G --> H +P1 --> A +P2 --> C +``` + +## Core Components + +- **Single Bubble Component**: Renders a single message bubble, supporting avatar, title, content, extra actions, footer, loading/content custom rendering, editable mode, and typing animation. +- **Bubble List Component**: Hosts multiple bubbles, supporting role grouping, auto-scrolling, and injecting items/role via slots. +- **System Bubble Component**: Renders system prompts or status information, emphasizing semantic display. +- **Divider Component**: Inserts separation prompts in conversations, such as timestamps or session transition hints. + +## Architecture Overview + +The Bubble component uses a three-layer architecture of "Svelte wrapper + Ant Design X React component + Gradio/ModelScope backend bridge". The frontend implements on-demand loading via Svelte's `importComponent`, bridging React components to Svelte using `sveltify`; the backend abstracts via `ModelScopeLayoutComponent` to uniformly handle event binding, slot mapping, and property forwarding. + +```mermaid +sequenceDiagram +participant Py as "Python Backend Component" +participant Svelte as "Svelte Wrapper" +participant React as "Ant Design X React Component" +participant User as "Caller" +User->>Py : Initialize component params and events +Py->>Svelte : Render frontend wrapper +Svelte->>Svelte : importComponent dynamic import +Svelte->>React : Pass props and slots +React-->>Svelte : Render result +Svelte-->>User : Output final DOM +``` + +## Detailed Component Analysis + +### Single Bubble Component (Bubble) + +- **Design Philosophy**: Based on Ant Design X's Bubble as core, providing rich slot and callback extension points for diverse needs: avatar, title, content, action area, loading state, and editing state. +- **Key Features**: + - Slot system: avatar, content, header, footer, extra, loadingRender, contentRender, editable.okText, editable.cancelText. + - Edit capability: Supports editable boolean switch and configuration object, with custom text and rendering via slots. + - Typing animation: `typing` supports boolean and configuration objects, with `typingComplete` event for animation lifecycle management. + - Custom rendering: loadingRender and contentRender support function or slot injection for flexible loading and content rendering control. + - Avatar and extra areas: avatar and extra support functions or slots for extending icons, action buttons, etc. + +```mermaid +flowchart TD +Start(["Enter Bubble Rendering"]) --> CheckEditable{"Is editing enabled?"} +CheckEditable --> |Yes| MergeEditable["Merge editable config and slots"] +CheckEditable --> |No| PassEditable["Pass through editable"] +MergeEditable --> RenderAvatar{"Avatar slot exists?"} +PassEditable --> RenderAvatar +RenderAvatar --> |Yes| SlotAvatar["Render avatar slot"] +RenderAvatar --> |No| FuncAvatar["Render avatar function/prop"] +FuncAvatar --> RenderHeader{"Header slot exists?"} +SlotAvatar --> RenderHeader +RenderHeader --> |Yes| SlotHeader["Render header slot"] +RenderHeader --> |No| FuncHeader["Render header function/prop"] +FuncHeader --> RenderContent{"Content slot exists?"} +SlotHeader --> RenderContent +RenderContent --> |Yes| SlotContent["Render content slot"] +RenderContent --> |No| TextContent["Render text content"] +TextContent --> RenderFooter{"Footer slot exists?"} +SlotContent --> RenderFooter +RenderFooter --> |Yes| SlotFooter["Render footer slot"] +RenderFooter --> |No| FuncFooter["Render footer function/prop"] +FuncFooter --> End(["Render complete"]) +``` + +### Bubble List Component (BubbleList) + +- **Design Philosophy**: Builds on the single bubble to provide batch rendering and role grouping for multi-turn conversations and history message lists. +- **Key Features**: + - Role grouping: Define display strategies for different roles (user, system, assistant) via role slot or prop. + - Slot items/default: Support injecting list items via slots or passing items array directly. + - Auto-scroll: Configurable auto-scroll to latest message for better user experience. + - Context injection: Parse slots and defaults via `useItems` and `useRole` for flexibility and consistency. + +### System Bubble Component (BubbleSystem) + +- **Design Philosophy**: Used to display system-level prompts or status information, emphasizing semantic consistency, commonly used for "system notifications", "session start", "model switch" scenarios. +- **Key Features**: + - Content slot: The `content` slot takes priority over the content property for dynamic rendering. + - Semantic display: Based on Ant Design X's System type, maintaining consistent style and behavior. + +### Divider Component (BubbleDivider) + +- **Design Philosophy**: Inserts separation prompts in conversations such as timestamps or session transitions, helping users understand conversation structure. +- **Key Features**: + - Content slot: The `content` slot takes priority over the content property. + - Semantic separation: Based on Ant Design X's Divider type, maintaining consistent visual and interaction behavior. + +## Dependency Analysis + +- **Frontend dependencies**: + - @svelte-preprocess-react: Provides importComponent, processProps, slot context capabilities for Svelte-React bridging. + - @ant-design/x: Provides core components and type definitions for Bubble, List, System, Divider. + - @utils/\*: Provides utilities for useFunction, renderParamsSlot, renderItems, context Providers. +- **Backend dependencies**: + - ModelScopeLayoutComponent: Unified abstraction for frontend component rendering, event binding, and property forwarding. + - Gradio event system: Event bindings for typing, typing_complete, edit_confirm, edit_cancel. + +## Performance Considerations + +- **On-demand loading**: Frontend uses `importComponent` for dynamic imports to avoid large initial bundles and improve first-screen performance. +- **Slot and function rendering**: Use slots and function rendering judiciously to reduce unnecessary re-renders; use stable function references for contentRender/loadingRender. +- **List optimization**: BubbleList uses `useMemo` and `renderItems` to ensure only necessary parts are recalculated on items change; use `auto_scroll` cautiously with large datasets. +- **Event binding**: Events like typing_complete, edit_confirm, edit_cancel should only be bound when needed. + +## Troubleshooting Guide + +- **Slots not working**: Check slot names (avatar, content, header, footer, extra, loadingRender, contentRender, editable.okText, editable.cancelText). Slots take priority over props. +- **Editing not working**: Confirm editable is a boolean or config object, with cancelText/okText slots or props. Check edit_confirm and edit_cancel event binding. +- **Typing animation issues**: Confirm typing is a boolean or config object. Without typing, typing_complete fires immediately after render. +- **List scrolling problems**: Check if auto_scroll is enabled; consider delay or throttle for large message sets. +- **Style and theme conflicts**: Use root_class_name or class_names/styles for custom styles; ensure compatibility with Ant Design X theme variables. + +## Conclusion + +The Bubble component family, based on Ant Design X and combined with Svelte and Gradio/ModelScope ecosystem capabilities, provides a complete solution from single messages to multi-turn conversation lists. Its slot-based design and event system enable flexible presentation of different types of prompts and messages in machine learning conversation scenarios while maintaining good performance and maintainability. + +## Appendix + +### Basic Usage Examples + +- **Single bubble**: Set content text or inject complex content via content slot. For editing, set `editable` and provide editable.okText/editable.cancelText. For typing animation, set `typing` and listen for `typing_complete`. +- **Bubble list**: Pass message arrays via items/default slots or items prop. Define role grouping via role slot or prop. Enable `auto_scroll` for automatic scrolling. +- **System bubble and divider**: Use System component for system prompts; use Divider for separation hints. Both support content slot priority strategy. + +### Best Practices + +- Prefer slots over inline strings for better maintainability and testability. +- Use memoization for frequently changing content to reduce re-renders. +- In dense conversation scenarios, control auto-scroll and animation effects to avoid performance issues. +- Use root_class_name/class_names/styles for theme customization, ensuring consistency with the overall design. diff --git a/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Divider Component.md b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Divider Component.md new file mode 100644 index 00000000..daa008ea --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Divider Component.md @@ -0,0 +1,80 @@ +# Bubble.Divider Component + + +**Files referenced in this document** +- [frontend/antdx/bubble/divider/Index.svelte](file://frontend/antdx/bubble/divider/Index.svelte) +- [frontend/antdx/bubble/divider/bubble.divider.tsx](file://frontend/antdx/bubble/divider/bubble.divider.tsx) +- [backend/modelscope_studio/components/antdx/bubble/divider/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/divider/__init__.py) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) + + +## Introduction + +Bubble.Divider is a time separator and content partition component within the chat bubble system, used to clearly divide different time periods or logical blocks in long conversations, improving readability and user experience. It is built on Ant Design X's Bubble.Divider capabilities, supports custom title/label via content slots, and provides visibility control and style forwarding. + +## Project Structure + +Bubble.Divider resides within the antdx bubble system, using a layered design of "backend Python component + frontend Svelte wrapper + React component bridge": + +- Backend component: Responsible for property definitions, visibility and style forwarding, and lifecycle hooks (such as preprocessing/postprocessing) +- Frontend wrapper: Svelte component handles on-demand loading, property merging, class name and style injection, slot rendering +- React component bridge: Exposes Ant Design X's Bubble.Divider capability in Svelte form + +```mermaid +graph TB +subgraph "Backend" +PY["Python Component
antdx.bubble.divider.__init__.py"] +end +subgraph "Frontend Wrapper Layer" +IDX["Svelte Wrapper
bubble.divider/Index.svelte"] +end +subgraph "React Bridge Layer" +BD["React Component Bridge
bubble.divider.tsx"] +XBD["Ant Design X Bubble.Divider"] +end +PY --> IDX +IDX --> BD +BD --> XBD +``` + +## Core Component + +Bubble.Divider wraps Ant Design X's Bubble.Divider component, providing: + +- Content slot (`content`): Displays text labels or custom content in the divider +- Visibility control (`visible`): Show/hide the divider via backend configuration +- Style injection: Supports `elem_id`, `elem_classes`, `elem_style`, and `additional_props` + +## Rendering Flow + +```mermaid +flowchart TD +Enter(["Enter Divider Rendering"]) --> HasSlot{"Content slot exists?"} +HasSlot --> |Yes| RenderSlot["Render slot content"] +HasSlot --> |No| RenderProp["Render prop content"] +RenderSlot --> Done(["Render complete"]) +RenderProp --> Done +``` + +## Usage + +- **Time divider**: Insert time labels in conversation lists to help users understand temporal structure of the conversation. +- **Topic divider**: Separate content blocks between different topics or sessions for clearer navigation. +- **Status divider**: Display status changes (e.g., session start, model switch notifications) as divider content. + +## Configuration Options + +| Property | Description | +| ------------------ | -------------------------------- | +| `content` | Divider content (string or slot) | +| `visible` | Whether to render the divider | +| `elem_id` | Element ID | +| `elem_classes` | Element CSS classes | +| `elem_style` | Inline element styles | +| `additional_props` | Additional property set | + +## Best Practices + +- Prefer the `content` slot for flexibility over plain string props. +- Keep divider content concise and consistent for better visual rhythm. +- Use `elem_id` / `elem_classes` for precise style control, avoiding global pollution. diff --git a/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Item Component.md b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Item Component.md new file mode 100644 index 00000000..3306d05a --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Item Component.md @@ -0,0 +1,80 @@ +# Bubble.Item Component + + +**Files referenced in this document** +- [frontend/antdx/bubble/list/item/Item.svelte](file://frontend/antdx/bubble/list/item/Item.svelte) +- [frontend/antdx/bubble/list/item/bubble.list.item.tsx](file://frontend/antdx/bubble/list/item/bubble.list.item.tsx) +- [frontend/antdx/bubble/bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [frontend/antdx/bubble/list/bubble.list.tsx](file://frontend/antdx/bubble/list/bubble.list.tsx) +- [frontend/antdx/bubble/list/context.ts](file://frontend/antdx/bubble/list/context.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + + +## Introduction + +Bubble.Item is a message item wrapper component within the Bubble.List system. It injects the item context via `ItemHandler`, enabling individual message items to participate in the list rendering lifecycle. When used as a child of BubbleList, Bubble.Item passes its properties and slots to the parent list for unified rendering. + +## Architecture + +```mermaid +classDiagram +class BubbleListItem { ++props : BubbleProps and ItemHandlerProps ++render() : ReactNode +} +class ItemHandler { ++setItem(key, props, slots) ++collectProps() ++collectSlots() +} +class ItemsContext { ++items : map[] ++setItem() +} +BubbleListItem --> ItemHandler : "Injects" +ItemHandler --> ItemsContext : "Writes item" +``` + +## Key Design Points + +- **ItemHandler injection**: Bubble.Item wraps ItemHandler, writing its own props/slots/children to ItemsContext for the parent BubbleList to consume and render. +- **Context communication**: Data flows from Bubble.Item → ItemHandler → ItemsContext → BubbleList rendering, ensuring full decoupling. +- **Slot support**: Supports all Bubble slots: avatar, header, footer, extra, content, loadingRender, contentRender. + +## Data Flow + +```mermaid +sequenceDiagram +participant Item as "Bubble.Item" +participant Handler as "ItemHandler" +participant Ctx as "ItemsContext" +participant List as "BubbleList" +Item->>Handler : Pass props and slots +Handler->>Ctx : Write item data +List->>Ctx : Read items +Ctx-->>List : Return items array +List->>List : Render via @ant-design/x List +``` + +## Configuration + +Bubble.Item accepts all Bubble component properties and additionally: + +- **Slot support**: All Bubble slots (avatar, header, footer, extra, content, loadingRender, contentRender) +- **List context**: Automatically participates in parent list context when used as a child of BubbleList + +## Usage Example + +```python +import modelscope_studio as mgr + +with mgr.antdx.Bubble.List(): + mgr.antdx.Bubble.Item(content="Hello, how can I help you?") + mgr.antdx.Bubble.Item(content="I need assistance with deployment.") +``` + +## Troubleshooting + +- **Item not showing**: Check that `visible` is truthy and that Bubble.Item is correctly wrapped in a BubbleList context. +- **Item content not updating**: Confirm props are stable; ItemHandler compares previous values and only writes if they change. +- **Slot not working**: Ensure slot names match backend declarations. diff --git a/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.List Component.md b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.List Component.md new file mode 100644 index 00000000..10debd4c --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.List Component.md @@ -0,0 +1,66 @@ +# Bubble.List Component + + +**Files referenced in this document** +- [frontend/antdx/bubble/list/bubble.list.tsx](file://frontend/antdx/bubble/list/bubble.list.tsx) +- [frontend/antdx/bubble/list/Index.svelte](file://frontend/antdx/bubble/list/Index.svelte) +- [frontend/antdx/bubble/list/context.ts](file://frontend/antdx/bubble/list/context.ts) +- [frontend/antdx/bubble/list/utils.tsx](file://frontend/antdx/bubble/list/utils.tsx) +- [frontend/antdx/bubble/list/item/bubble.list.item.tsx](file://frontend/antdx/bubble/list/item/bubble.list.item.tsx) +- [frontend/antdx/bubble/list/role/bubble.list.role.tsx](file://frontend/antdx/bubble/list/role/bubble.list.role.tsx) + + +## Introduction + +Bubble.List is the message list container component in the Bubble system. It is responsible for collecting external items and slot items, injecting role context, resolving role mappings via `useRole`, and delegating final rendering to @ant-design/x's List. + +## Rendering Flow + +```mermaid +flowchart TD +Start(["Enter BubbleList"]) --> CheckItems["Check if props.items exists"] +CheckItems --> |Exists| UseItems["Use external items"] +CheckItems --> |Not exists| ReadSlot["Read context slotItems.items or default"] +ReadSlot --> ResolveItems["Use renderItems to parse as array"] +UseItems --> ResolveItems +ResolveItems --> ParseRole["useRole resolves role mapping"] +ParseRole --> PatchSlots["Apply slot patches to slots"] +PatchSlots --> RenderList["Render XBubble.List"] +RenderList --> End(["Done"]) +``` + +## Key Features + +- **Items merging**: Prioritizes `props.items`; if not provided, reads `slotItems.items` or `default` from context, then uses `renderItems` to normalize to an array. +- **Role resolution**: Uses `useRole` to support role as string, function, or object, with `preProcess` and `defaultRolePostProcess` hooks. +- **Slot patching**: Applies patches to slots so role's avatar/header/footer/extra/loadingRender/contentRender can be overridden in advance. +- **Render and scroll**: Renders via @ant-design/x's `XBubble.List`, with auto-scroll binding and scroll event callbacks. + +## Configuration Options + +| Property | Description | +| -------------- | ------------------------------------------------ | +| `items` | Message items array | +| `role` | Role configuration (string, function, or object) | +| `auto_scroll` | Whether to auto-scroll to the latest message | +| `visible` | Whether to render the component | +| `elem_id` | Element ID | +| `elem_classes` | Element CSS classes | + +## Collaboration with Bubble.Item and Bubble.Role + +- **Bubble.Item**: Wraps ItemHandler, injecting message item props and slots into context for BubbleList to read during rendering. +- **Bubble.Role**: Wraps RoleItemHandler, injecting role definitions into role context for useRole to resolve. +- **Data flow**: BubbleList reads items/default and role from context before rendering, then generates the complete items array and role configuration. + +## Performance Considerations + +- Uses `useMemo` to cache items, reducing unnecessary re-renders. +- `ItemHandler` uses `useMemoizedFn` and `useMemoizedEqualValue` to reduce duplicate computations and invalid updates. +- `ItemsContextProvider` updates the entire child items array in a single `setItem` call. + +## Troubleshooting + +- **Items not displayed**: Check if `visible` is truthy and that the parent component correctly wraps `withItemsContextProvider`. +- **Role configuration not working**: Ensure `Bubble.Role` correctly injects role context and that `useRole` receives the expected configuration. +- **Auto-scroll not working**: Confirm `auto_scroll` is enabled; consider performance implications with large message sets. diff --git a/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Role Component.md b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Role Component.md new file mode 100644 index 00000000..09d820e0 --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.Role Component.md @@ -0,0 +1,93 @@ +# Bubble.Role Component + + +**Files referenced in this document** +- [frontend/antdx/bubble/list/role/Role.svelte](file://frontend/antdx/bubble/list/role/Role.svelte) +- [frontend/antdx/bubble/list/role/bubble.list.role.tsx](file://frontend/antdx/bubble/list/role/bubble.list.role.tsx) +- [backend/modelscope_studio/components/antdx/bubble/list/role/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/list/role/__init__.py) +- [frontend/antdx/bubble/list/role/Index.svelte](file://frontend/antdx/bubble/list/role/Index.svelte) +- [frontend/antdx/bubble/list/context.ts](file://frontend/antdx/bubble/list/context.ts) +- [frontend/antdx/bubble/list/utils.tsx](file://frontend/antdx/bubble/list/utils.tsx) + + +## Introduction + +Bubble.Role is a role identifier component within the Bubble.List system. It injects role configurations into the role context via `RoleItemHandler`, so that `useRole` can resolve them into the `RoleType` required by @ant-design/x. Each Bubble.Role defines the visual style and behavior defaults for a specific role (e.g., user, assistant, system). + +## Architecture + +```mermaid +classDiagram +class BubbleListRole { ++props : BubbleProps and RoleItemHandlerProps ++render() : ReactNode +} +class RoleItemHandler { ++setRole(key, props, slots) +} +class RoleItemsContext { ++roles : map[] ++setRole() +} +class useRole { ++resolve(role) : RoleType +} +BubbleListRole --> RoleItemHandler : "Injects" +RoleItemHandler --> RoleItemsContext : "Writes role" +useRole --> RoleItemsContext : "Reads roles" +``` + +## Key Design Points + +- **RoleItemHandler injection**: Bubble.Role wraps RoleItemHandler, writing its own props/slots to RoleItemsContext for `useRole` to resolve. +- **Role key**: Each Bubble.Role must specify a unique role key matching the `role` field in message items. +- **Slot support**: Supports Bubble slots: avatar, header, footer, extra, content, loadingRender, contentRender. + +## Usage Example + +```python +import modelscope_studio as mgr + +with mgr.antdx.Bubble.List(): + with mgr.antdx.Bubble.Role(role="user"): + with mgr.Slot("avatar"): + mgr.antdx.Avatar(icon="UserOutlined") + with mgr.antdx.Bubble.Role(role="assistant"): + with mgr.Slot("avatar"): + mgr.antdx.Avatar(src="/bot-avatar.png") +``` + +## Role Resolution Flow + +```mermaid +flowchart TD +A["Input: role/defaultRoleKeys/preProcess/postProcess"] --> B["Read Role context items"] +B --> C{"Role config exists?"} +C --> |Yes| D["Render Role slots and aggregate as mapping"] +C --> |No| E["Use empty mapping"] +D --> F["Merge default keys and mapping keys"] +E --> F +F --> G["Iterate each key"] +G --> H{"Value is function?"} +H --> |Yes| I["Compile as function and cache"] +H --> |No| J["Generate default handler (with slot patches/index injection/default contentRender)"] +I --> K["Apply patchBubbleSlots enhancement"] +K --> L["Return RoleType"] +J --> L +``` + +## Configuration Options + +| Property | Description | +| ------------- | ---------------------------- | +| `role` | Unique role key identifier | +| `avatar` | Avatar configuration or slot | +| `placement` | Bubble placement (start/end) | +| `styles` | Style configuration | +| `class_names` | CSS class name configuration | + +## Best Practices + +- Define all roles used in messages before rendering BubbleList. +- Use consistent role key naming (e.g., "user", "assistant", "system") for better readability. +- Configure avatar, styles, and class_names via Bubble.Role slots for centralized role management. diff --git a/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.System Component.md b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.System Component.md new file mode 100644 index 00000000..c0cb397e --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Bubble Chat Bubble/Bubble.System Component.md @@ -0,0 +1,97 @@ +# Bubble.System Component + + +**Files referenced in this document** +- [frontend/antdx/bubble/system/Index.svelte](file://frontend/antdx/bubble/system/Index.svelte) +- [frontend/antdx/bubble/system/bubble.system.tsx](file://frontend/antdx/bubble/system/bubble.system.tsx) +- [backend/modelscope_studio/components/antdx/bubble/system/__init__.py](file://backend/modelscope_studio/components/antdx/bubble/system/__init__.py) + + +## Introduction + +Bubble.System is a system message component within the Bubble family, used for rendering system prompts, status notifications, and operational feedback. It integrates Ant Design X's system bubble capabilities into ModelScope Studio's component ecosystem through clear frontend-backend layered design. + +## Project Structure + +```mermaid +graph TB +PY["AntdXBubbleSystem
Backend Python Component"] --> IDX["Index.svelte
Frontend Svelte Wrapper"] +IDX --> TSX["bubble.system.tsx
React Bridge"] +TSX --> ADX["@ant-design/x Bubble.System"] +``` + +## Core Component + +The `AntdXBubbleSystem` backend class inherits from ModelScope Studio's layout component base class with the following key properties: + +```mermaid +classDiagram +class AntdXBubbleSystem { ++EVENTS ++SLOTS ++content ++shape ++variant ++styles ++class_names ++root_class_name ++additional_props ++visible ++elem_id ++elem_classes ++elem_style ++render ++skip_api ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +``` + +## Rendering Flow + +```mermaid +flowchart TD +Enter(["Enter System Rendering"]) --> HasSlot{"content slot exists?"} +HasSlot --> |Yes| RenderSlot["Render slot content"] +HasSlot --> |No| RenderProp["Render prop content"] +RenderSlot --> Done(["Render complete"]) +RenderProp --> Done +``` + +## Differences from Regular Bubble + +- **Role positioning**: Regular Bubble is used for user/bot conversation content rendering with rich slots (avatar, header, footer, extra, etc.); Bubble.System focuses on system prompts, status notifications, and non-conversational content. +- **Slots and properties**: Regular Bubble supports more slots; System Bubble only focuses on the `content` slot and basic properties, keeping it simple and consistent. +- **Rendering target**: Regular Bubble faces "person" and "role" interaction content; System Bubble faces information communicated by "system" to the user. + +## Configuration Options + +| Property | Description | +| -------------------------- | -------------------------------------------------- | +| `content` | System message content (string or slot) | +| `shape` | Bubble shape (round/corner/default) | +| `variant` | Visual variant (filled/borderless/outlined/shadow) | +| `styles` / `elem_style` | Inline styles | +| `elem_id` / `elem_classes` | Element ID and class names | +| `additional_props` | Additional property set | +| `visible` | Whether to render | + +## Usage Scenarios + +- **Welcome message**: Display welcome text when user first enters the page. +- **Error notification**: Notify user of network or service errors. +- **Progress notification**: Stage-by-stage prompts during background task execution. + +## Performance Considerations + +- `Index.svelte` uses dynamic imports, only loading the system bubble wrapper when visible, reducing initial render overhead. +- `ReactSlot` only renders when slots exist, avoiding unnecessary computations for empty content. +- Only passes necessary properties and slots, reducing unnecessary re-renders and style calculations. + +## Troubleshooting + +- **Content not showing**: Check that `content` is correctly passed via slot or property; slots take priority. Confirm `visible` is truthy. +- **Style abnormalities**: Check that `elem_id`, `elem_classes`, `elem_style` are injected as expected. +- **Slot not working**: Ensure slot name matches backend declaration (currently only supports `content` slot). diff --git a/.wiki/en/Ant Design X Components/General Components/Conversations/API Reference.md b/.wiki/en/Ant Design X Components/General Components/Conversations/API Reference.md new file mode 100644 index 00000000..1d0dc524 --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Conversations/API Reference.md @@ -0,0 +1,105 @@ +# API Reference + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antdx/conversations/__init__.py](file://backend/modelscope_studio/components/antdx/conversations/__init__.py) +- [backend/modelscope_studio/components/antdx/conversations/item/__init__.py](file://backend/modelscope_studio/components/antdx/conversations/item/__init__.py) + + +## Conversations Component API + +### Properties + +| Property | Type | Default | Description | +| -------------- | ---- | ------- | --------------------------------- | +| `items` | list | `[]` | Conversation items array | +| `active_key` | str | `None` | Currently active conversation key | +| `groupable` | bool | `False` | Whether to enable grouping | +| `menu` | dict | `None` | Context menu configuration | +| `visible` | bool | `True` | Whether to render the component | +| `elem_id` | str | `None` | Element ID | +| `elem_classes` | list | `None` | Element CSS class names | +| `elem_style` | dict | `None` | Element inline styles | + +### Events + +| Event | Description | +| ------------------ | ------------------------------------------ | +| `active_change` | Fired when the active conversation changes | +| `menu_click` | Fired when a menu item is clicked | +| `menu_select` | Fired when a menu item is selected | +| `menu_deselect` | Fired when a menu item is deselected | +| `menu_open_change` | Fired when menu open state changes | +| `groupable_expand` | Fired when a group expands or collapses | +| `creation_click` | Fired when the creation button is clicked | + +### Slots + +| Slot | Description | +| -------------------------- | ------------------------------------------------------ | +| `items` | Slot for injecting Conversations.Item child components | +| `menu.items` | Slot for injecting context menu items | +| `menu.trigger` | Slot for customizing menu trigger | +| `menu.expandIcon` | Slot for customizing menu expand icon | +| `menu.overflowedIndicator` | Slot for customizing overflow indicator | +| `groupable.label` | Slot for customizing group label | +| `creation.icon` | Slot for customizing creation button icon | +| `creation.label` | Slot for customizing creation button label | + +## Conversations.Item Component API + +### Properties + +| Property | Type | Default | Description | +| ---------- | ---- | -------- | ------------------------------------------- | +| `key` | str | required | Unique identifier for the conversation item | +| `label` | str | `None` | Display label (overridden by label slot) | +| `icon` | any | `None` | Icon (overridden by icon slot) | +| `disabled` | bool | `False` | Whether the item is disabled | +| `group` | str | `None` | Group label (required when groupable=True) | + +### Slots + +| Slot | Description | +| ------- | ----------------------------------------- | +| `label` | Slot for customizing item label rendering | +| `icon` | Slot for customizing item icon rendering | + +## Items Array Format + +Each item in the `items` array can contain: + +```python +{ + "key": "unique-key", # Required: unique identifier + "label": "Display Name", # Display label + "icon": None, # Icon configuration + "disabled": False, # Whether disabled + "group": "Group Name", # Group label (for groupable mode) +} +``` + +## Usage Example + +```python +import gradio as gr +import modelscope_studio as mgr + +with gr.Blocks() as demo: + state = gr.State(value=None) + + conversations = mgr.antdx.Conversations( + groupable=True, + items=[ + {"key": "1", "label": "Chat about Python", "group": "Today"}, + {"key": "2", "label": "ML model discussion", "group": "Today"}, + {"key": "3", "label": "Old conversation", "group": "Yesterday"}, + ] + ) + + conversations.active_change( + lambda key: print(f"Selected: {key}"), + inputs=[conversations], + outputs=[state] + ) +``` diff --git a/.wiki/en/Ant Design X Components/General Components/Conversations/Component Overview.md b/.wiki/en/Ant Design X Components/General Components/Conversations/Component Overview.md new file mode 100644 index 00000000..cbd26e9c --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Conversations/Component Overview.md @@ -0,0 +1,113 @@ +# Component Overview + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antdx/__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [backend/modelscope_studio/components/antdx/conversations/__init__.py](file://backend/modelscope_studio/components/antdx/conversations/__init__.py) +- [frontend/antdx/conversations/conversations.tsx](file://frontend/antdx/conversations/conversations.tsx) +- [frontend/antdx/conversations/context.ts](file://frontend/antdx/conversations/context.ts) +- [frontend/antdx/conversations/item/conversations.item.tsx](file://frontend/antdx/conversations/item/conversations.item.tsx) + + +## Introduction + +This overview covers the Conversations management component, systematically introducing its overall architecture, core functionality, and design philosophy. It explains its relationship with the Ant Design X component library and typical usage in machine learning and conversational applications, providing entry points and core concepts to help developers quickly understand and integrate this component. + +## Project Structure + +The Conversations component is located in the Ant Design X frontend ecosystem. The backend bridges to the Gradio ecosystem via Python wrappers; the frontend connects to Ant Design X's Conversations implementation as React components, extending menu, grouping, and other capabilities through context and slot mechanisms. + +```mermaid +graph TB +subgraph "Backend" +PY_API["Python Wrapper
AntdXConversations"] +BASE_COMP["Base Component Class
ModelScopeLayoutComponent"] +end +subgraph "Frontend" +REACT_COMP["React Component
@ant-design/x Conversations"] +CTX["Context and Slots
context.ts / conversations.tsx"] +ITEM["Item Wrapper
conversations.item.tsx"] +end +PY_API --> |"Call/Render"| REACT_COMP +BASE_COMP --> PY_API +CTX --> REACT_COMP +ITEM --> CTX +``` + +## Core Components + +### AntdXConversations (Backend) + +The Python-side wrapper class for the Conversations component: + +- Inherits from `ModelScopeLayoutComponent`, providing unified lifecycle and rendering strategy. +- Declares supported slots and events, ensuring frontend wrapper layer correctly interfaces. +- Property set covers common needs: `items`, `active_key`, `groupable`, `menu`. + +Key events: + +- `active_change`: Active conversation changed +- `menu_click` / `menu_select` / `menu_deselect` / `menu_open_change`: Menu interaction events +- `groupable_expand`: Group expand/collapse +- `creation_click`: Creation button click + +### conversations.tsx (Frontend) + +The frontend React wrapper implementation: + +- Uses `withItemsContextProvider` to provide items context to child `Conversations.Item` components. +- Uses `withMenuItemsContextProvider` to provide menu items context. +- Uniformly injects style class names to child items. +- Converts slot menu items to menu configuration required by @ant-design/x. + +### conversations.item.tsx (Frontend) + +The Conversations.Item bridge component: + +- Uses `ItemHandler` to write its own props/slots to `ItemsContext`. +- Supports `label`, `icon`, and other slots. + +## Architecture Overview + +```mermaid +graph LR +ConvTSX["conversations.tsx"] --> Ctx["context.ts"] +Ctx --> CIC["createItemsContext.tsx"] +ConvTSX --> X["@ant-design/x Conversations"] +ItemSvelte["Index.svelte"] --> ItemBridge["conversations.item.tsx"] +ItemBridge --> Ctx +Backend["AntdXConversations*"] --> ConvTSX +``` + +## Usage Patterns + +### Basic Usage + +```python +import modelscope_studio as mgr + +conversations = mgr.antdx.Conversations( + items=[ + {"key": "1", "label": "Conversation 1"}, + {"key": "2", "label": "Conversation 2"}, + ] +) +``` + +### With Grouping + +```python +conversations = mgr.antdx.Conversations( + groupable=True, + items=[ + {"key": "1", "label": "Conv 1", "group": "Today"}, + {"key": "2", "label": "Conv 2", "group": "Yesterday"}, + ] +) +``` + +## Key Design Concepts + +- **Context-driven**: The parent container provides context; child items write to context. This decouples parent-child communication and enables flexible composition. +- **Slot-first**: All display customization (icons, labels, menus) is achieved through slots for maximum flexibility. +- **Event-driven**: Key interactions (selection, menu operations, group toggle) are exposed as events for backend Python processing. diff --git a/.wiki/en/Ant Design X Components/General Components/Conversations/Conversation Item Component.md b/.wiki/en/Ant Design X Components/General Components/Conversations/Conversation Item Component.md new file mode 100644 index 00000000..b41444bd --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Conversations/Conversation Item Component.md @@ -0,0 +1,92 @@ +# Conversation Item Component + + +**Files referenced in this document** +- [frontend/antdx/conversations/item/Index.svelte](file://frontend/antdx/conversations/item/Index.svelte) +- [frontend/antdx/conversations/item/conversations.item.tsx](file://frontend/antdx/conversations/item/conversations.item.tsx) +- [backend/modelscope_studio/components/antdx/conversations/item/__init__.py](file://backend/modelscope_studio/components/antdx/conversations/item/__init__.py) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) + + +## Introduction + +`Conversations.Item` is an individual conversation item component within the Conversations system. It bridges slot content and properties to the parent `Conversations` container via `ItemHandler`, enabling the parent to render all items uniformly. This design ensures complete decoupling between parent and child while supporting rich slot customization. + +## Architecture + +```mermaid +graph LR +Item["Conversations.Item
Index.svelte"] --> Bridge["conversations.item.tsx
React Bridge"] +Bridge --> Handler["ItemHandler
createItemsContext.tsx"] +Handler --> Context["ItemsContext
context.ts"] +Parent["Conversations
conversations.tsx"] --> Context +``` + +## Key Design Points + +- **ItemHandler injection**: Conversations.Item writes its own props/slots to `ItemsContext` via ItemHandler for the parent Conversations to consume and render. +- **Lazy loading**: `Index.svelte` only renders the bridge component when `visible` is true. +- **Props comparison**: ItemHandler uses memoized comparison to avoid unnecessary writes. + +## Data Flow + +```mermaid +sequenceDiagram +participant Item as "Conversations.Item" +participant Handler as "ItemHandler" +participant Ctx as "ItemsContext" +participant Parent as "Conversations" +Item->>Handler : Pass key, props, slots +Handler->>Ctx : setItem(key, props, children) +Parent->>Ctx : Read items +Ctx-->>Parent : Return items map +Parent->>Parent : Render via @ant-design/x Conversations +``` + +## Properties + +| Property | Type | Default | Description | +| ---------- | ---- | -------- | --------------------------------------- | +| `key` | str | required | Unique conversation item identifier | +| `label` | str | `None` | Display text (overridden by label slot) | +| `icon` | any | `None` | Item icon (overridden by icon slot) | +| `disabled` | bool | `False` | Whether the item is disabled | +| `group` | str | `None` | Group this item belongs to | +| `visible` | bool | `True` | Whether to render this item | + +## Slots + +| Slot | Description | +| ------- | ---------------------- | +| `label` | Custom label rendering | +| `icon` | Custom icon rendering | + +## Usage Example + +```python +import modelscope_studio as mgr + +with mgr.antdx.Conversations() as conv: + # Simple text item + mgr.antdx.Conversations.Item(key="1", label="Project Alpha") + + # Item with custom icon and label + with mgr.antdx.Conversations.Item(key="2"): + with mgr.Slot("icon"): + mgr.antdx.Icon(type="StarOutlined") + with mgr.Slot("label"): + mgr.antdx.Typography.Text("★ Starred Chat", strong=True) + + # Item with context menu + with mgr.antdx.Conversations.Item(key="3", label="Chat with menu"): + with mgr.Slot("menu.items"): + mgr.antdx.MenuItem(key="pin", label="Pin") + mgr.antdx.MenuItem(key="delete", label="Delete", danger=True) +``` + +## Troubleshooting + +- **Item not visible**: Check `visible` property and confirm item is inside a Conversations container. +- **Label not showing**: Confirm the label slot or label property is correctly set. +- **Icon not showing**: Ensure icon slot content is a valid React/Svelte element. +- **Menu items not working**: Verify menu items are injected via `menu.items` slot and the parent handles `menu_click` events. diff --git a/.wiki/en/Ant Design X Components/General Components/Conversations/Conversations Management.md b/.wiki/en/Ant Design X Components/General Components/Conversations/Conversations Management.md new file mode 100644 index 00000000..468c1300 --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Conversations/Conversations Management.md @@ -0,0 +1,160 @@ +# Conversations Management + + +**Files referenced in this document** +- [frontend/antdx/conversations/Index.svelte](file://frontend/antdx/conversations/Index.svelte) +- [frontend/antdx/conversations/conversations.tsx](file://frontend/antdx/conversations/conversations.tsx) +- [frontend/antdx/conversations/context.ts](file://frontend/antdx/conversations/context.ts) +- [frontend/antdx/conversations/item/Index.svelte](file://frontend/antdx/conversations/item/Index.svelte) +- [frontend/antdx/conversations/item/conversations.item.tsx](file://frontend/antdx/conversations/item/conversations.item.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/antdx/conversations/index.less](file://frontend/antdx/conversations/index.less) +- [frontend/antdx/conversations/gradio.config.js](file://frontend/antdx/conversations/gradio.config.js) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically describes the design and implementation of the Conversations management component, covering: + +- Conversation list management: adding, deleting, sorting, state management +- Conversations.Item rendering logic, interaction behavior, and state control +- Component Context role and conversation state sharing mechanism +- Property configuration, event callbacks, style customization, and best practices +- Complete usage examples: basic usage, dynamic add/remove, state synchronization + +## Project Structure + +The Conversations component consists of three layers: "container layer + item handler + context", bridged to the runtime environment via Gradio configuration. + +```mermaid +graph TB +subgraph "Frontend Component Layer" +A["Index.svelte
Container Entry"] +B["conversations.tsx
Conversation Container Implementation"] +C["context.ts
Item Context Export"] +D["item/Index.svelte
Item Entry"] +E["item/conversations.item.tsx
Item Handler"] +F["index.less
Styles"] +end +subgraph "Shared Utility Layer" +G["createItemsContext.tsx
Item Context Factory"] +end +subgraph "Build Configuration" +H["gradio.config.js
Unified Configuration"] +end +A --> B +D --> E +B --> C +C --> G +E --> C +B --> F +A --> H +D --> H +``` + +## Core Components + +- **Conversations**: The parent container that manages the conversation list. Parses items and menu configuration, injects them into @ant-design/x's Conversations, wraps with `withItemsContextProvider` and `withMenuItemsContextProvider` to provide contexts. +- **Conversations.Item**: A single conversation item. Writes its own props/slots/children to ItemsContext via `ItemHandler` for the parent container to render. + +## Architecture Overview + +```mermaid +classDiagram +class Conversations { ++props : items, menu, groupable, active_key ++events : active_change, menu_click, ... +} +class ConversationsItem { ++props : key, label, icon, disabled, ... ++slots : label, icon +} +class ItemHandler { ++setItem() ++collectProps() ++collectSlots() +} +class ItemsContext { ++items : map[] ++setItem() +} +Conversations --> ItemsContext : "Provides context" +ConversationsItem --> ItemHandler : "Bridge rendering" +ItemHandler --> ItemsContext : "Writes item" +``` + +## Detailed Component Analysis + +### Conversations Container + +- Parses `items` and menu configuration, injects into @ant-design/x's Conversations. +- Wraps with `withItemsContextProvider` and `withMenuItemsContextProvider` for Items and menu contexts. +- Uniformly injects style class names (e.g., item class names) to ensure theme consistency. + +### Conversations.Item + +- Uses `ItemHandler` to write its own props/slots/children to `ItemsContext`. +- Parent container consumes and renders items uniformly. + +### Menu Operations (Add, Delete, Rename) + +- Inject menu items via Slot (`menu.items`), supporting icons, disabled state, and danger styling. +- The `menu_click` event callback provides the clicked item and menu information. + +### Conversation Grouping and Collapsible + +- Enable grouping by setting `groupable=True`. +- Each conversation item sets a `group` field for grouping. +- Supports group label slots and collapsible functions. + +### Events and State Management + +Key events: + +- `active_change`: Selected item changed +- `menu_click` / `menu_select` / `menu_deselect` / `menu_open_change`: Menu interactions +- `groupable_expand`: Group expand/collapse +- `creation_click`: Create button click + +## Dependency Analysis + +- **Component coupling**: Conversations.Item depends on `ItemHandler` and `ItemsContext` with low coupling, easy to reuse. The parent container centralizes items, menu, and grouping handling. +- **External dependencies**: @ant-design/x provides the core Conversations component; Gradio component system provides `AntdXConversations`/`AntdXConversationsItem` as bridges. + +## Performance Considerations + +- **Lazy loading and conditional rendering**: `Index.svelte` only renders child items when `visible` is true, avoiding unnecessary initialization overhead. +- **Context update minimization**: `ItemHandler` uses `useMemoizedFn` and `useMemoizedEqualValue` to reduce duplicate computations and invalid updates. +- **Batch writing**: `ItemsContextProvider` updates the entire child items array in a single `setItem` call, reducing re-render frequency. +- **Style injection**: Parent container uniformly injects style class names to avoid jitter from child items setting styles repeatedly. + +## Troubleshooting Guide + +- **Child items not showing**: Check if `visible` is truthy; confirm parent component correctly wraps `withItemsContextProvider`. +- **Child item content not updating**: Confirm props are stable; `ItemHandler` compares previous values and won't write if equal. +- **Menu not working**: Confirm parent component correctly injects `menu` configuration or injects menu items via Slot. +- **Style abnormalities**: Parent component has already injected item class names; confirm they haven't been externally overridden. + +## Conclusion + +Conversations.Item achieves flexible item collection and rendering through `ItemHandler` and `ItemsContext`. Combined with the parent `Conversations` container's unified configuration and event management, it can efficiently build complex conversation list scenarios with emphasis on decoupling and extensibility. + +## Appendix + +### Events and Slots Summary + +- **Events**: active_change, menu_click, menu_deselect, menu_open_change, menu_select, groupable_expand, creation_click +- **Slots**: menu.expandIcon, menu.overflowedIndicator, menu.trigger, groupable.label, items, creation.icon, creation.label diff --git a/.wiki/en/Ant Design X Components/General Components/Conversations/Usage Examples.md b/.wiki/en/Ant Design X Components/General Components/Conversations/Usage Examples.md new file mode 100644 index 00000000..4deefebd --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/Conversations/Usage Examples.md @@ -0,0 +1,140 @@ +# Usage Examples + + +**Files referenced in this document** +- [docs/components/antdx/conversations/demos/basic.py](file://docs/components/antdx/conversations/demos/basic.py) +- [docs/components/antdx/conversations/demos/operations.py](file://docs/components/antdx/conversations/demos/operations.py) +- [docs/components/antdx/conversations/demos/group.py](file://docs/components/antdx/conversations/demos/group.py) + + +## Basic Usage + +### Simple Conversation List + +```python +import gradio as gr +import modelscope_studio as mgr + +with gr.Blocks() as demo: + mgr.antdx.Conversations( + items=[ + {"key": "1", "label": "First conversation"}, + {"key": "2", "label": "Second conversation"}, + {"key": "3", "label": "Third conversation"}, + ] + ) +``` + +### With Icons and Labels + +Use Slots to define `label`/`icon` slots for custom rendering: + +```python +with gr.Blocks() as demo: + with mgr.antdx.Conversations() as conv: + with mgr.antdx.Conversations.Item(key="1"): + with mgr.Slot("icon"): + mgr.antdx.Icon(type="MessageOutlined") + with mgr.Slot("label"): + gr.Markdown("**Important Chat**") +``` + +## Menu Operations (Add, Delete, Rename) + +```python +import gradio as gr +import modelscope_studio as mgr + +with gr.Blocks() as demo: + with mgr.antdx.Conversations() as conv: + with mgr.antdx.Conversations.Item(key="chat-1", label="Chat 1"): + with mgr.Slot("menu.items"): + mgr.antdx.MenuItem(key="rename", label="Rename") + mgr.antdx.MenuItem(key="delete", label="Delete", danger=True) + + def handle_menu_click(key, menu_info): + print(f"Item: {key}, Menu: {menu_info}") + + conv.menu_click(handle_menu_click) +``` + +## Conversation Grouping with Collapsible + +```python +with gr.Blocks() as demo: + mgr.antdx.Conversations( + groupable=True, + items=[ + {"key": "1", "label": "Morning standup", "group": "Today"}, + {"key": "2", "label": "Code review", "group": "Today"}, + {"key": "3", "label": "Planning session", "group": "Yesterday"}, + {"key": "4", "label": "Bug discussion", "group": "Yesterday"}, + ] + ) +``` + +## Dynamic Conversation Management + +```python +import gradio as gr +import modelscope_studio as mgr + +def add_conversation(items, name): + new_key = f"conv-{len(items) + 1}" + return items + [{"key": new_key, "label": name}] + +def delete_conversation(items, key): + return [item for item in items if item["key"] != key] + +with gr.Blocks() as demo: + items_state = gr.State(value=[ + {"key": "1", "label": "Initial conversation"}, + ]) + + with gr.Row(): + new_name = gr.Textbox(placeholder="Conversation name") + add_btn = gr.Button("Add") + + conv = mgr.antdx.Conversations() + + add_btn.click( + add_conversation, + inputs=[items_state, new_name], + outputs=[items_state] + ) + + items_state.change( + lambda items: mgr.antdx.Conversations(items=items), + inputs=[items_state], + outputs=[conv] + ) +``` + +## Event Handling Examples + +### Handling Active Selection Change + +```python +def on_active_change(key): + print(f"Selected conversation: {key}") + # Load messages for selected conversation + +conversations.active_change( + on_active_change, + inputs=[conversations] +) +``` + +### Handling Creation Button Click + +```python +def on_creation_click(): + # Create new conversation + new_id = generate_id() + return [{"key": new_id, "label": "New Conversation"}] + +conversations.creation_click( + on_creation_click, + outputs=[conversations] +) +``` diff --git a/.wiki/en/Ant Design X Components/General Components/General Components.md b/.wiki/en/Ant Design X Components/General Components/General Components.md new file mode 100644 index 00000000..02cf25e2 --- /dev/null +++ b/.wiki/en/Ant Design X Components/General Components/General Components.md @@ -0,0 +1,310 @@ +# General Components + + +**Files referenced in this document** +- [bubble.tsx](file://frontend/antdx/bubble/bubble.tsx) +- [conversations.tsx](file://frontend/antdx/conversations/conversations.tsx) +- [context.ts](file://frontend/antdx/conversations/context.ts) +- [index.less](file://frontend/antdx/conversations/index.less) +- [__init__.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [README-zh_CN.md](file://README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document covers the Ant Design X general components, focusing on the implementation and usage of the Bubble conversation bubble component and the Conversations conversation management component. Topics include: + +- Bubble's conversation display capabilities, message type differentiation, and style/content customization +- Conversations' conversation list management, state control, menu and grouping operation interfaces +- Collaboration relationships between components and best practices +- Complete usage examples (basic usage, advanced configuration, style customization) + +## Project Structure + +The Ant Design X general components are located in the antdx category of the frontend directory. They use a Svelte + React preprocessing bridge solution, wrapping native @ant-design/x components via sveltify to make them usable in Svelte. The backend Python package provides a unified export entry. + +```mermaid +graph TB +subgraph "Frontend antdx" +B["bubble.tsx"] +C["conversations.tsx"] +CTX["context.ts"] +L["index.less"] +end +subgraph "Backend" +PY_INIT["__init__.py"] +PY_COMP["components.py"] +end +subgraph "Third-party" +ADX["@ant-design/x"] +SveltePreprocess["@svelte-preprocess-react"] +Utils["@utils/*"] +end +B --> ADX +C --> ADX +B --> SveltePreprocess +C --> SveltePreprocess +B --> Utils +C --> Utils +PY_COMP --> B +PY_COMP --> C +PY_INIT --> PY_COMP +``` + +Diagram sources + +- [bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [context.ts:1-7](file://frontend/antdx/conversations/context.ts#L1-L7) +- [**init**.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) + +Section sources + +- [bubble.tsx:1-119](file://frontend/antdx/bubble/bubble.tsx#L1-L119) +- [conversations.tsx:1-178](file://frontend/antdx/conversations/conversations.tsx#L1-L178) +- [context.ts:1-7](file://frontend/antdx/conversations/context.ts#L1-L7) +- [**init**.py](file://backend/modelscope_studio/components/antdx/__init__.py) +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) + +## Core Components + +- Bubble: A conversation bubble display component that supports slot-based extensions for avatar, title, content, footer, extra area, editable text, loading state rendering, and content rendering. +- Conversations: A conversation list management component that supports menu injection, grouping configuration, item rendering, class name merging, and event pass-through. + +Section sources + +- [bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) +- [conversations.tsx:59-175](file://frontend/antdx/conversations/conversations.tsx#L59-L175) + +## Architecture Overview + +Both Bubble and Conversations are bridged to native @ant-design/x components through sveltify. The bridge layer handles: + +- Slot-to-ReactSlot mapping +- useFunction wrapping of function-type properties +- Context and rendering tool integration for menu and grouping configuration +- Class name merging and overriding + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Conv as "Conversations(Bridge)" +participant XConv as "@ant-design/x.Conversations" +participant Ctx as "Context(Menu/Item)" +participant Bubble as "Bubble(Bridge)" +participant XBubble as "@ant-design/x.Bubble" +Dev->>Conv : Pass items/menu/groupable and other props +Conv->>Ctx : Parse menu/item context +Conv->>XConv : Render conversation list (with menu/grouping) +XConv-->>Dev : List rendering result +Dev->>Bubble : Pass avatar/content/footer/header, etc. +Bubble->>XBubble : Render conversation bubble (slot/function wrapping) +XBubble-->>Dev : Bubble rendering result +``` + +Diagram sources + +- [conversations.tsx:68-175](file://frontend/antdx/conversations/conversations.tsx#L68-L175) +- [bubble.tsx:27-116](file://frontend/antdx/bubble/bubble.tsx#L27-L116) + +## Detailed Component Analysis + +### Bubble Component Analysis + +- Key Features + - Supports slot-based extensions for avatar, title, content, footer, and extra area + - Supports editable mode (boolean or configuration object), with slots for customizing "confirm/cancel" text + - Supports typing callbacks and function-based configuration for loadingRender/contentRender + - Handles editable, avatar, header, footer, extra, loadingRender, contentRender uniformly with fallback +- Data Flow and Processing Logic + - Uses useFunction to wrap function-type properties, ensuring correct execution in the Svelte environment + - Renders slot content via ReactSlot; renderParamsSlot supports slots with parameters + - Performs configuration merging and conditional rendering for editable, compatible with both boolean and object configuration +- Complexity and Performance + - Primarily involves property mapping and rendering overhead; complexity scales with slot count and nesting depth + - Function wrapping avoids redundant rendering and improves interaction responsiveness + +```mermaid +flowchart TD +Start(["Enter Bubble rendering"]) --> CheckEditable["Detect editable configuration"] +CheckEditable --> EditableSupport{"Editing supported?"} +EditableSupport --> |Yes| MergeEditable["Merge edit config\nand process slot text"] +EditableSupport --> |No| PassEditable["Pass editable directly"] +MergeEditable --> RenderAvatar["Handle avatar slot/function"] +PassEditable --> RenderAvatar +RenderAvatar --> RenderHeader["Handle header slot/function"] +RenderHeader --> RenderFooter["Handle footer slot/function"] +RenderFooter --> RenderExtra["Handle extra area slot/function"] +RenderExtra --> RenderContent["Handle content slot/function"] +RenderContent --> RenderLoading["Handle loadingRender slot/function"] +RenderLoading --> RenderContentRender["Handle contentRender slot/function"] +RenderContentRender --> End(["Rendering complete"]) +``` + +Diagram sources + +- [bubble.tsx:27-116](file://frontend/antdx/bubble/bubble.tsx#L27-L116) + +Section sources + +- [bubble.tsx:8-116](file://frontend/antdx/bubble/bubble.tsx#L8-L116) + +### Conversations Component Analysis + +- Key Features + - Interfaces with @ant-design/x Conversations, providing menu injection, grouping configuration, item rendering, and class name merging + - Parses menu and item slots via useMenuItems and useItems context + - Supports string-form menu property and object configuration, automatically merges events and prevents bubbling + - Supports label slot for groupable and collapsible function configuration +- Data Flow and Processing Logic + - patchMenuEvents: Wraps menu events, injects the conversation parameter and prevents DOM event bubbling + - renderItems: Converts slot items into actual rendered items, supporting cloning and deep copying + - useMemo: Memoizes menu and items to reduce unnecessary re-renders +- Complexity and Performance + - Memoization and context parsing deliver stable performance; more slot items means greater renderItems overhead + - Menu event wrapping only takes effect when a menu exists, avoiding unnecessary overhead + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Conv as "Conversations(Bridge)" +participant Ctx as "useMenuItems/useItems" +participant XConv as "@ant-design/x.Conversations" +Dev->>Conv : Pass menu/items/groupable/classNames +Conv->>Ctx : Get menu/item context +Conv->>Conv : patchMenuEvents wraps menu events +Conv->>Conv : renderItems parses slot items +Conv->>XConv : Merge class names and render +XConv-->>Dev : Return conversation list +``` + +Diagram sources + +- [conversations.tsx:35-175](file://frontend/antdx/conversations/conversations.tsx#L35-L175) +- [context.ts:1-7](file://frontend/antdx/conversations/context.ts#L1-L7) + +Section sources + +- [conversations.tsx:28-175](file://frontend/antdx/conversations/conversations.tsx#L28-L175) +- [context.ts:1-7](file://frontend/antdx/conversations/context.ts#L1-L7) + +### Component Collaboration + +- Conversations serves as the container, responsible for rendering the conversation list and managing menu/grouping configuration +- Bubble serves as a child element, responsible for displaying and interacting with individual conversation bubbles +- Both work together through @ant-design/x's native components, with the bridge layer providing slot and function wrapping capabilities + +```mermaid +graph LR +Conv["Conversations(Bridge)"] --> XB["@ant-design/x.Conversations"] +XB --> Item["Conversation Item (driven by items/menu/groupable)"] +Item --> BB["Bubble(Bridge)"] +BB --> XBb["@ant-design/x.Bubble"] +``` + +Diagram sources + +- [conversations.tsx:139-171](file://frontend/antdx/conversations/conversations.tsx#L139-L171) +- [bubble.tsx:38-115](file://frontend/antdx/bubble/bubble.tsx#L38-L115) + +## Dependency Analysis + +- Third-party Dependencies + - @ant-design/x: Provides native conversation and bubble components + - @svelte-preprocess-react: Provides sveltify and ReactSlot capabilities + - @utils/\*: Provides tools like useFunction, renderItems, renderParamsSlot, createFunction + - classnames: Used for class name merging +- Backend Exports + - The Python package exposes antdx components through **init**.py and components.py, enabling use in Python environments + +```mermaid +graph TB +B["bubble.tsx"] --> ADX["@ant-design/x"] +B --> SPR["@svelte-preprocess-react"] +B --> U["@utils/*"] +C["conversations.tsx"] --> ADX +C --> SPR +C --> U +C --> CTX["context.ts"] +PY["components.py"] --> B +PY --> C +``` + +Diagram sources + +- [bubble.tsx:1-7](file://frontend/antdx/bubble/bubble.tsx#L1-L7) +- [conversations.tsx:1-17](file://frontend/antdx/conversations/conversations.tsx#L1-L17) +- [context.ts:1-7](file://frontend/antdx/conversations/context.ts#L1-L7) +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) + +Section sources + +- [bubble.tsx:1-7](file://frontend/antdx/bubble/bubble.tsx#L1-L7) +- [conversations.tsx:1-17](file://frontend/antdx/conversations/conversations.tsx#L1-L17) +- [context.ts:1-7](file://frontend/antdx/conversations/context.ts#L1-L7) +- [components.py](file://backend/modelscope_studio/components/antdx/components.py) + +## Performance Considerations + +- Use useMemo to memoize menu and items, avoiding unnecessary re-renders +- Wrap function-type properties with useFunction to reduce closure creation and rendering jitter +- Clone slot items through renderItems to avoid side effects from shared state +- In high-volume conversation scenarios, consider lazy loading and virtual scrolling (such as capabilities provided by @ant-design/x) to reduce memory usage + +## Troubleshooting Guide + +- Slot not taking effect + - Verify that slot names are consistent with the bridge layer declarations (e.g., editable.okText, editable.cancelText, content, footer, header, extra, loadingRender, contentRender) + - Confirm that slot content is correctly rendered via ReactSlot +- Abnormal menu events + - Check that the useMenuItems context is being used correctly + - Confirm that patchMenuEvents correctly wraps onClick and similar events and prevents bubbling +- Class name conflicts + - Merge custom class names through classNames to avoid overriding default styles +- Edit mode not appearing + - Confirm that editable is an object containing the editing field, or provide custom text via slots + +Section sources + +- [bubble.tsx:36-64](file://frontend/antdx/bubble/bubble.tsx#L36-L64) +- [conversations.tsx:35-57](file://frontend/antdx/conversations/conversations.tsx#L35-L57) +- [conversations.tsx:145-151](file://frontend/antdx/conversations/conversations.tsx#L145-L151) + +## Conclusion + +Bubble and Conversations achieve complete capability encapsulation of @ant-design/x through the bridge layer, providing flexible slot-based and function-based configuration that meets diverse needs from basic conversation display to complex conversation management. It is recommended to combine context and utility functions in actual projects, and to organize slots and events appropriately for a better development experience and runtime performance. + +## Appendix + +- Usage Examples (based on existing repository files and component capabilities) + - Basic Usage + - Use Bubble to display a message, setting avatar, content, and footer + - Use Conversations to render a conversation list, passing items and menu configuration + - Advanced Configuration + - Enable edit mode in Bubble, customizing "confirm/cancel" text through slots + - Use groupable in Conversations to implement grouping and collapsing, customizing group labels through slots + - Style Customization + - Merge custom class names through classNames to override default styles + - Import index.less for theme customization (if needed) + +Section sources + +- [bubble.tsx:14-116](file://frontend/antdx/bubble/bubble.tsx#L14-L116) +- [conversations.tsx:59-175](file://frontend/antdx/conversations/conversations.tsx#L59-L175) +- [index.less](file://frontend/antdx/conversations/index.less) +- [README-zh_CN.md](file://README-zh_CN.md) diff --git a/.wiki/en/Ant Design X Components/Tool Components/CodeHighlighter Component.md b/.wiki/en/Ant Design X Components/Tool Components/CodeHighlighter Component.md new file mode 100644 index 00000000..12343c0a --- /dev/null +++ b/.wiki/en/Ant Design X Components/Tool Components/CodeHighlighter Component.md @@ -0,0 +1,335 @@ +# CodeHighlighter Component + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antdx/code_highlighter/__init__.py](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py) +- [frontend/antdx/code-highlighter/Index.svelte](file://frontend/antdx/code-highlighter/Index.svelte) +- [frontend/antdx/code-highlighter/code-highlighter.tsx](file://frontend/antdx/code-highlighter/code-highlighter.tsx) +- [frontend/antdx/code-highlighter/package.json](file://frontend/antdx/code-highlighter/package.json) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [docs/components/antdx/code_highlighter/README.md](file://docs/components/antdx/code_highlighter/README.md) +- [docs/components/antdx/code_highlighter/README-zh_CN.md](file://docs/components/antdx/code_highlighter/README-zh_CN.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +CodeHighlighter is a code highlighting component based on Ant Design X, used to provide syntax highlighting functionality in ModelScope Studio. This component supports syntax highlighting for multiple programming languages, including dark and light theme modes, and provides flexible configuration options to meet different use cases. + +The component is integrated with Gradio to achieve seamless frontend-backend connection, providing users with a powerful and easy-to-use code display tool. The component supports advanced features such as custom styles, language selection, and header content. + +## Project Structure + +The position of the CodeHighlighter component in the overall project architecture is as follows: + +```mermaid +graph TB +subgraph "Backend" +A[ModelScope Studio Backend] +B[AntdX Components] +C[CodeHighlighter Component] +end +subgraph "Frontend" +D[Svelte Component] +E[React Wrapper] +F[Ant Design X] +end +subgraph "Documentation" +G[Example Documentation] +H[Usage Instructions] +end +A --> B +B --> C +C --> D +D --> E +E --> F +A --> G +G --> H +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:1-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L1-L71) +- [frontend/antdx/code-highlighter/Index.svelte:1-65](file://frontend/antdx/code-highlighter/Index.svelte#L1-L65) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:1-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L1-L71) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) + +## Core Components + +### Backend Component Class + +The CodeHighlighter backend component inherits from `ModelScopeLayoutComponent`, providing complete component lifecycle management and property handling mechanisms. + +**Main Features:** + +- Supports syntax highlighting for multiple programming languages +- Automatic theme adaptation (dark/light mode) +- Customizable styles and class names +- Slot system supports header content +- API skip mechanism for performance optimization + +**Key Properties:** + +- `value`: Code content to highlight +- `lang`: Programming language type +- `header`: Header display content +- `highlight_props`: Highlight configuration properties +- `prism_light_mode`: Prism theme mode setting + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:15-52](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L15-L52) + +### Frontend Component Implementation + +The frontend adopts a mixed Svelte + React architecture, bridging components through the `sveltify` tool. + +**Technical Features:** + +- Dynamic import for optimized loading performance +- Slot system support +- Automatic theme detection and switching +- Custom style overrides + +**Section Sources** + +- [frontend/antdx/code-highlighter/Index.svelte:1-65](file://frontend/antdx/code-highlighter/Index.svelte#L1-L65) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) + +## Architecture Overview + +CodeHighlighter adopts a layered architecture design, achieving clear frontend-backend separation: + +```mermaid +sequenceDiagram +participant Client as Client Application +participant Backend as Backend Component +participant Frontend as Frontend Component +participant AntDX as Ant Design X +participant Prism as Prism Syntax Highlighter +Client->>Backend : Create CodeHighlighter instance +Backend->>Frontend : Resolve frontend directory +Frontend->>Frontend : Dynamically import React component +Frontend->>AntDX : Wrap as Svelte component +AntDX->>Prism : Apply syntax highlighting styles +Prism-->>AntDX : Return highlighted code +AntDX-->>Frontend : Render final result +Frontend-->>Client : Display highlighted code block +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:53-53](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L53-L53) +- [frontend/antdx/code-highlighter/Index.svelte:10-12](file://frontend/antdx/code-highlighter/Index.svelte#L10-L12) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:29-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L29-L51) + +## Detailed Component Analysis + +### Component Class Structure Diagram + +```mermaid +classDiagram +class AntdXCodeHighlighter { ++EVENTS : [] ++SLOTS : ["header"] ++additional_props : dict ++styles : dict|str ++class_names : dict|str ++root_class_name : str ++value : str|None ++lang : str|None ++header : str|bool|None ++highlight_props : dict|None ++prism_light_mode : bool|None ++FRONTEND_DIR : str ++skip_api : bool ++preprocess(payload) None ++postprocess(value) None ++example_payload() None ++example_value() None +} +class ModelScopeLayoutComponent { +<> ++visible : bool ++elem_id : str|None ++elem_classes : list[str]|str|None ++elem_style : dict|None ++render : bool ++as_item : str|None +} +AntdXCodeHighlighter --|> ModelScopeLayoutComponent : Inherits +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:6-71](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L6-L71) + +### Frontend Rendering Flow + +```mermaid +flowchart TD +Start([Component Initialization]) --> CheckVisible{Check Visibility} +CheckVisible --> |Not Visible| Hide[Hide Component] +CheckVisible --> |Visible| LoadComponent[Dynamically Load Component] +LoadComponent --> ImportReact[Import React Component] +ImportReact --> ProcessProps[Process Component Properties] +ProcessProps --> GetSlots[Get Slot Content] +GetSlots --> RenderComponent[Render CodeHighlighter] +RenderComponent --> ApplyTheme[Apply Theme Styles] +ApplyTheme --> Display[Display Highlighted Code] +Hide --> End([End]) +Display --> End +``` + +**Diagram Sources** + +- [frontend/antdx/code-highlighter/Index.svelte:50-64](file://frontend/antdx/code-highlighter/Index.svelte#L50-L64) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:35-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L35-L51) + +### Theme System Design + +The component supports custom styles for two theme modes: + +```mermaid +graph LR +subgraph "Theme Configuration" +A[Material Light] +B[Material Dark] +C[Custom Style Override] +end +subgraph "Style Application" +D[Preprocessor] +E[Runtime Switching] +F[Component Rendering] +end +A --> D +B --> D +C --> D +D --> E +E --> F +``` + +**Diagram Sources** + +- [frontend/antdx/code-highlighter/code-highlighter.tsx:13-27](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L13-L27) + +**Section Sources** + +- [frontend/antdx/code-highlighter/code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) + +## Dependency Analysis + +### Component Dependency Diagram + +```mermaid +graph TB +subgraph "External Dependencies" +A[@ant-design/x] +B[react-syntax-highlighter] +C[classnames] +D[svelte-preprocess-react] +end +subgraph "Internal Dependencies" +E[ModelScopeLayoutComponent] +F[resolve_frontend_dir] +G[Gradio Integration] +end +subgraph "Component Hierarchy" +H[AntdXCodeHighlighter] +I[Index.svelte] +J[code-highlighter.tsx] +end +H --> E +H --> F +H --> G +I --> H +I --> D +I --> C +J --> A +J --> B +J --> D +``` + +**Diagram Sources** + +- [frontend/antdx/code-highlighter/code-highlighter.tsx:1-11](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L11) +- [frontend/antdx/code-highlighter/Index.svelte:1-8](file://frontend/antdx/code-highlighter/Index.svelte#L1-L8) +- [backend/modelscope_studio/components/antdx/code_highlighter/**init**.py:3-3](file://backend/modelscope_studio/components/antdx/code_highlighter/__init__.py#L3-L3) + +### Package Management Configuration + +The component's package configuration supports multi-entry exports: + +**Section Sources** + +- [frontend/antdx/code-highlighter/package.json:1-15](file://frontend/antdx/code-highlighter/package.json#L1-L15) + +## Performance Considerations + +### Loading Optimization Strategy + +1. **Dynamic import**: Uses `importComponent` and `import()` to implement on-demand loading +2. **Lazy loading**: Components are only rendered when needed +3. **Caching mechanism**: Already resolved components are cached to improve repeated access performance + +### Memory Management + +- Event listeners are cleaned up when components are destroyed +- Slot content is properly released when no longer needed +- Theme style objects are reasonably reused + +## Troubleshooting Guide + +### Common Issues and Solutions + +**Issue 1: Code not displaying with highlighting** + +- Check if the `value` property is correctly set +- Confirm the language identifier in the `lang` property is valid +- Verify the `highlightProps` configuration is correct + +**Issue 2: Theme display anomalies** + +- Check the `themeMode` property setting +- Confirm shared theme configuration is correct +- Verify custom style overrides are not conflicting + +**Issue 3: Component not rendering** + +- Check the `visible` property status +- Confirm `elem_id` and `elem_classes` configuration +- Verify Gradio integration is functioning normally + +**Section Sources** + +- [frontend/antdx/code-highlighter/Index.svelte:50-64](file://frontend/antdx/code-highlighter/Index.svelte#L50-L64) +- [frontend/antdx/code-highlighter/code-highlighter.tsx:35-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L35-L51) + +## Conclusion + +The CodeHighlighter component is a fully functional, clearly architected code highlighting solution. It successfully combines the powerful capabilities of Ant Design X with the Gradio ecosystem, providing users with an excellent code display experience. + +**Main Advantages:** + +- Complete syntax highlighting support +- Flexible theme configuration +- Good performance +- Easy-to-use API interface +- Comprehensive documentation support + +This component provides powerful code display capabilities for ModelScope Studio and can meet the needs of various development and presentation scenarios. Through reasonable architecture design and performance optimization, it ensures stable operation in different environments. diff --git a/.wiki/en/Ant Design X Components/Tool Components/Mermaid Component.md b/.wiki/en/Ant Design X Components/Tool Components/Mermaid Component.md new file mode 100644 index 00000000..c245870b --- /dev/null +++ b/.wiki/en/Ant Design X Components/Tool Components/Mermaid Component.md @@ -0,0 +1,334 @@ +# Mermaid Component + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antdx/mermaid/__init__.py](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py) +- [frontend/antdx/mermaid/Index.svelte](file://frontend/antdx/mermaid/Index.svelte) +- [frontend/antdx/mermaid/mermaid.tsx](file://frontend/antdx/mermaid/mermaid.tsx) +- [frontend/antdx/mermaid/gradio.config.js](file://frontend/antdx/mermaid/gradio.config.js) +- [frontend/antdx/mermaid/package.json](file://frontend/antdx/mermaid/package.json) +- [frontend/globals/components/markdown/utils.ts](file://frontend/globals/components/markdown/utils.ts) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The Mermaid flowchart component in ModelScope Studio is a visualization chart rendering component based on Ant Design X, specifically designed to display flowcharts, sequence diagrams, Gantt charts, and other diagrams in Mermaid format within Gradio applications. This component provides complete frontend rendering capabilities, supporting theme switching, custom action buttons, and a slot system. + +## Project Structure + +The Mermaid component adopts a layered architecture design, primarily containing the following layers: + +```mermaid +graph TB +subgraph "Backend Layer" +Backend[Python Backend Component] +DevUtils[Development Utility Class] +end +subgraph "Frontend Layer" +SvelteUI[Svelte Frontend Component] +ReactAdapter[React Adapter] +AntDX[Ant Design X Component] +end +subgraph "Utility Layer" +MarkdownRenderer[Markdown Renderer] +ThemeManager[Theme Manager] +SlotSystem[Slot System] +end +Backend --> SvelteUI +SvelteUI --> ReactAdapter +ReactAdapter --> AntDX +Backend --> DevUtils +SvelteUI --> MarkdownRenderer +SvelteUI --> ThemeManager +SvelteUI --> SlotSystem +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/mermaid/**init**.py:1-77](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L1-L77) +- [frontend/antdx/mermaid/Index.svelte:1-69](file://frontend/antdx/mermaid/Index.svelte#L1-L69) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/mermaid/**init**.py:1-77](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L1-L77) +- [frontend/antdx/mermaid/Index.svelte:1-69](file://frontend/antdx/mermaid/Index.svelte#L1-L69) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) + +## Core Components + +### AntdXMermaid Python Component + +AntdXMermaid is the core backend component class, inheriting from `ModelScopeLayoutComponent`, providing complete Gradio integration capabilities. + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS : List ++SLOTS : List ++skip_api : bool ++FRONTEND_DIR : str ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class AntdXMermaid { ++value : str ++highlight_props : dict ++config : dict ++actions : dict ++prefix_cls : str ++styles : dict ++class_names : dict ++additional_props : dict ++root_class_name : str +} +ModelScopeLayoutComponent <|-- AntdXMermaid +``` + +**Diagram Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-127](file://backend/modelscope_studio/utils/dev/component.py#L11-L127) +- [backend/modelscope_studio/components/antdx/mermaid/**init**.py:8-77](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L8-L77) + +### Frontend Rendering Component + +The frontend layer adopts a mixed Svelte + React architecture, wrapping React components as Svelte components through the `sveltify` adapter. + +**Section Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-127](file://backend/modelscope_studio/utils/dev/component.py#L11-L127) +- [backend/modelscope_studio/components/antdx/mermaid/**init**.py:8-77](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L8-L77) + +## Architecture Overview + +The overall architecture of the Mermaid component adopts a layered design, achieving frontend-backend separation and modular management: + +```mermaid +sequenceDiagram +participant User as User +participant Backend as Backend Component +participant Frontend as Frontend Component +participant AntDX as Ant Design X +participant MermaidLib as Mermaid Library +User->>Backend : Create component instance +Backend->>Frontend : Resolve frontend directory +Frontend->>AntDX : Load Mermaid component +AntDX->>MermaidLib : Initialize rendering engine +MermaidLib-->>AntDX : Return rendering result +AntDX-->>Frontend : Output chart element +Frontend-->>Backend : Update component state +Backend-->>User : Display rendered chart +``` + +**Diagram Sources** + +- [frontend/antdx/mermaid/Index.svelte:10-68](file://frontend/antdx/mermaid/Index.svelte#L10-L68) +- [frontend/antdx/mermaid/mermaid.tsx:50-79](file://frontend/antdx/mermaid/mermaid.tsx#L50-L79) + +## Detailed Component Analysis + +### Backend Component Implementation + +The backend component inherits from `ModelScopeLayoutComponent`, implementing the following key features: + +#### Component Property Configuration + +- `value`: Chart content string +- `highlight_props`: Syntax highlighting configuration +- `config`: Mermaid configuration options +- `actions`: Custom action buttons +- `styles/class_names`: Style configuration + +#### Event Handling Mechanism + +The component supports the `render_type_change` event, binding render type change events via callback functions. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/mermaid/**init**.py:12-16](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L12-L16) +- [backend/modelscope_studio/components/antdx/mermaid/**init**.py:21-58](file://backend/modelscope_studio/components/antdx/mermaid/__init__.py#L21-L58) + +### Frontend Component Architecture + +The frontend adopts a three-layer architecture design: + +#### Svelte Layer (Index.svelte) + +Responsible for component lifecycle management and property forwarding, using `importComponent` to dynamically load React components. + +#### React Adapter Layer (mermaid.tsx) + +Wraps React components into Svelte-compatible components via `sveltify`, implementing property transformation and event handling. + +#### Ant Design X Integration + +Directly uses `@ant-design/x`'s `Mermaid` component, providing rich chart rendering capabilities. + +**Section Sources** + +- [frontend/antdx/mermaid/Index.svelte:1-69](file://frontend/antdx/mermaid/Index.svelte#L1-L69) +- [frontend/antdx/mermaid/mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) + +### Theme and Style System + +The component supports both dark and light theme modes, controlled by the `themeMode` property: + +```mermaid +flowchart TD +Start([Component Initialization]) --> CheckTheme{"Check Theme Mode"} +CheckTheme --> |Dark| DarkTheme["Apply Dark Theme"] +CheckTheme --> |Light| LightTheme["Apply Light Theme"] +DarkTheme --> CustomStyles["Apply Custom Styles"] +LightTheme --> CustomStyles +CustomStyles --> HighlightProps["Configure Syntax Highlighting"] +HighlightProps --> RenderChart["Render Chart"] +RenderChart --> End([Complete]) +``` + +**Diagram Sources** + +- [frontend/antdx/mermaid/mermaid.tsx:17-31](file://frontend/antdx/mermaid/mermaid.tsx#L17-L31) +- [frontend/antdx/mermaid/mermaid.tsx:56-61](file://frontend/antdx/mermaid/mermaid.tsx#L56-L61) + +**Section Sources** + +- [frontend/antdx/mermaid/mermaid.tsx:17-31](file://frontend/antdx/mermaid/mermaid.tsx#L17-L31) +- [frontend/antdx/mermaid/mermaid.tsx:56-61](file://frontend/antdx/mermaid/mermaid.tsx#L56-L61) + +### Slot System + +The component supports two main slots: + +- `header`: Header content slot +- `actions.customActions`: Custom action button slot + +The slot system is implemented via `getSlots()` and `ReactSlot`, supporting dynamic content rendering. + +**Section Sources** + +- [frontend/antdx/mermaid/Index.svelte:51-51](file://frontend/antdx/mermaid/Index.svelte#L51-L51) +- [frontend/antdx/mermaid/mermaid.tsx:38-38](file://frontend/antdx/mermaid/mermaid.tsx#L38-L38) + +## Dependency Analysis + +The component's dependency relationships exhibit a clear layered structure: + +```mermaid +graph TB +subgraph "External Dependencies" +AntDX["@ant-design/x"] +MermaidLib["mermaid"] +ReactSyntax["react-syntax-highlighter"] +ClassNames["classnames"] +end +subgraph "Internal Dependencies" +Utils["@utils/renderItems"] +ActionsCtx["../actions/context"] +Preprocess["@svelte-preprocess-react"] +end +subgraph "Component Layer" +AntdXMermaid["AntdXMermaid"] +SvelteComponent["Svelte Component"] +ReactComponent["React Component"] +end +AntdXMermaid --> SvelteComponent +SvelteComponent --> ReactComponent +ReactComponent --> AntDX +ReactComponent --> MermaidLib +ReactComponent --> ReactSyntax +ReactComponent --> Utils +ReactComponent --> ActionsCtx +SvelteComponent --> Preprocess +SvelteComponent --> ClassNames +``` + +**Diagram Sources** + +- [frontend/antdx/mermaid/mermaid.tsx:1-15](file://frontend/antdx/mermaid/mermaid.tsx#L1-L15) +- [frontend/antdx/mermaid/Index.svelte:2-8](file://frontend/antdx/mermaid/Index.svelte#L2-L8) + +**Section Sources** + +- [frontend/antdx/mermaid/mermaid.tsx:1-15](file://frontend/antdx/mermaid/mermaid.tsx#L1-L15) +- [frontend/antdx/mermaid/Index.svelte:2-8](file://frontend/antdx/mermaid/Index.svelte#L2-L8) + +## Performance Considerations + +### On-demand Loading Optimization + +The component uses a dynamic import (`importComponent`) mechanism, loading React components only when needed to reduce the initial bundle size. + +### Rendering Performance Optimization + +- Uses `useMemo` to cache calculation results, avoiding unnecessary re-renders +- Uses `tick()` to ensure correct DOM update timing +- Supports asynchronous rendering for improved user experience + +### Memory Management + +- Automatically cleans up event listeners when components are destroyed +- Promptly releases no-longer-needed resources + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### Chart Rendering Failure + +When Mermaid chart rendering fails, the system automatically degrades to code display mode: + +```mermaid +flowchart TD +TryRender["Attempt to render chart"] --> Success{"Render successful?"} +Success --> |Yes| ShowChart["Display chart"] +Success --> |No| CheckError["Check error type"] +CheckError --> HasDiagram{"Chart element exists?"} +HasDiagram --> |Yes| KeepOriginal["Keep original content"] +HasDiagram --> |No| ShowCode["Display code block"] +KeepOriginal --> AddErrorClass["Add error style"] +ShowCode --> AddErrorClass +AddErrorClass --> ShowError["Display error message"] +``` + +**Diagram Sources** + +- [frontend/globals/components/markdown/utils.ts:191-222](file://frontend/globals/components/markdown/utils.ts#L191-L222) + +#### Theme Mismatch Issue + +Ensure the `themeMode` property is correctly passed to the component; use `dark` in dark mode and `base` in light mode. + +#### Slot Content Not Displaying + +Check if slot names are correct (`header` or `actions.customActions`) and if slot content is correctly passed. + +**Section Sources** + +- [frontend/globals/components/markdown/utils.ts:191-222](file://frontend/globals/components/markdown/utils.ts#L191-L222) + +## Conclusion + +The Mermaid flowchart component in ModelScope Studio achieves a high-performance, extensible chart rendering solution through its carefully designed layered architecture. The component has the following advantages: + +1. **Complete Gradio integration**: Provides native Gradio support through `ModelScopeLayoutComponent` +2. **Flexible theme system**: Supports automatic switching between dark and light themes +3. **Powerful slot system**: Provides flexible configuration of header content and custom action buttons +4. **Excellent error handling**: Intelligent degradation mechanism ensures user experience +5. **Efficient rendering performance**: On-demand loading and caching optimization improve performance + +This component provides developers with a powerful and easy-to-use chart rendering tool, applicable to various data visualization scenarios. diff --git a/.wiki/en/Ant Design X Components/Tool Components/Notification Component.md b/.wiki/en/Ant Design X Components/Tool Components/Notification Component.md new file mode 100644 index 00000000..a6c861f2 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Tool Components/Notification Component.md @@ -0,0 +1,367 @@ +# Notification Component + + +**Files referenced in this document** +- [backend/modelscope_studio/components/antd/notification/__init__.py](file://backend/modelscope_studio/components/antd/notification/__init__.py) +- [frontend/antd/notification/notification.tsx](file://frontend/antd/notification/notification.tsx) +- [frontend/antd/notification/Index.svelte](file://frontend/antd/notification/Index.svelte) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [frontend/antd/notification/package.json](file://frontend/antd/notification/package.json) +- [frontend/antd/notification/gradio.config.js](file://frontend/antd/notification/gradio.config.js) +- [docs/components/antd/notification/README.md](file://docs/components/antd/notification/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The Notification component in ModelScope Studio is a global notification component based on Ant Design, used to display various types of notification messages in applications. This component supports multiple notification types (success, info, warning, error) and provides customizable notification position, duration, progress bar, and other features. + +The component adopts a frontend-backend separated architecture design, with the backend implementing component definitions in Python and the frontend built with React and TypeScript, integrated through the Gradio framework. + +## Project Structure + +The ModelScope Studio project adopts modular organization, with the Notification component located in the following directory structure: + +```mermaid +graph TB +subgraph "Backend (Python)" +A[backend/modelscope_studio/] --> B[components/] +B --> C[antd/] +C --> D[notification/] +D --> E[__init__.py] +end +subgraph "Frontend (TypeScript/React)" +F[frontend/] --> G[antd/] +G --> H[notification/] +H --> I[Index.svelte] +H --> J[notification.tsx] +H --> K[package.json] +H --> L[gradio.config.js] +end +subgraph "Documentation" +M[docs/] --> N[components/] +N --> O[antd/] +O --> P[notification/] +end +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antd/notification/**init**.py:1-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L1-L109) +- [frontend/antd/notification/Index.svelte:1-80](file://frontend/antd/notification/Index.svelte#L1-L80) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/notification/**init**.py:1-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L1-L109) +- [frontend/antd/notification/notification.tsx:1-106](file://frontend/antd/notification/notification.tsx#L1-L106) + +## Core Components + +The core implementation of the Notification component includes three main parts: + +### Backend Component Class + +The backend uses the `AntdNotification` class inheriting from `ModelScopeLayoutComponent`, providing complete component functionality definitions: + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS : list ++SLOTS : list ++skip_api : bool ++visible : bool ++elem_id : str ++elem_classes : list ++elem_style : dict ++render : bool +} +class AntdNotification { ++message : str ++description : str ++title : str ++type : str ++duration : float ++placement : str ++key : str ++FRONTEND_DIR : str ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +ModelScopeLayoutComponent <|-- AntdNotification +``` + +**Diagram Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/antd/notification/**init**.py:10-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L10-L109) + +### Frontend React Component + +The frontend uses React Hooks and Ant Design's notification API to implement notification functionality: + +```mermaid +sequenceDiagram +participant Svelte as Svelte Component +participant React as React Component +participant Antd as Antd Notification API +participant User as User +Svelte->>React : Render component +React->>React : Initialize useNotification hook +React->>React : Listen for visible state changes +React->>Antd : notificationApi.open() +Antd-->>React : Return notification instance +React->>User : Display notification +User->>React : Click to close +React->>Antd : notificationApi.destroy() +Antd-->>React : Close complete +``` + +**Diagram Sources** + +- [frontend/antd/notification/notification.tsx:31-95](file://frontend/antd/notification/notification.tsx#L31-L95) +- [frontend/antd/notification/Index.svelte:59-79](file://frontend/antd/notification/Index.svelte#L59-L79) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/notification/**init**.py:10-109](file://backend/modelscope_studio/components/antd/notification/__init__.py#L10-L109) +- [frontend/antd/notification/notification.tsx:8-106](file://frontend/antd/notification/notification.tsx#L8-L106) + +## Architecture Overview + +The Notification component adopts a layered architecture design, ensuring clear frontend-backend separation and good maintainability: + +```mermaid +graph TB +subgraph "User Interface Layer" +UI[User Interface] +end +subgraph "Frontend Application Layer" +Svelte[Svelte Component] +React[React Component] +Hooks[React Hooks] +end +subgraph "Component Library Layer" +Antd[Ant Design] +NotificationAPI[Notification API] +end +subgraph "Backend Service Layer" +Python[Python Component] +Gradio[Gradio Framework] +end +subgraph "Data Layer" +Props[Property Forwarding] +State[State Management] +end +UI --> Svelte +Svelte --> React +React --> Hooks +Hooks --> Antd +Antd --> NotificationAPI +Svelte --> Python +Python --> Gradio +Gradio --> Props +Props --> State +State --> Hooks +``` + +**Diagram Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [frontend/antd/notification/notification.tsx:31-95](file://frontend/antd/notification/notification.tsx#L31-L95) + +## Detailed Component Analysis + +### Backend Component Implementation + +The backend `AntdNotification` class provides complete component definitions, including event handling, slot support, and property configuration: + +#### Main Features + +1. **Event system**: Supports click and close event listeners +2. **Slot system**: Supports multiple slots (actions, closeIcon, description, icon, message, title) +3. **Property configuration**: Provides rich configuration options such as type, placement, duration, etc. + +#### Key Method Descriptions + +- `EVENTS`: Defines the list of supported events +- `SLOTS`: Defines supported slot names +- `preprocess()`: Preprocesses input data +- `postprocess()`: Processes output results +- `example_payload()`: Provides sample payload data + +**Section Sources** + +- [backend/modelscope_studio/components/antd/notification/**init**.py:14-21](file://backend/modelscope_studio/components/antd/notification/__init__.py#L14-L21) +- [backend/modelscope_studio/components/antd/notification/**init**.py:24](file://backend/modelscope_studio/components/antd/notification/__init__.py#L24) +- [backend/modelscope_studio/components/antd/notification/**init**.py:97-108](file://backend/modelscope_studio/components/antd/notification/__init__.py#L97-L108) + +### Frontend React Component Implementation + +The frontend component uses modern React development patterns, combined with Ant Design's notification functionality: + +#### Core Functionality + +1. **State management**: Uses React Hooks to manage notification state +2. **Lifecycle**: Automatically handles notification creation and destruction +3. **Slot rendering**: Supports dynamic slot content rendering +4. **Event handling**: Handles user interaction events + +#### Component Flow + +```mermaid +flowchart TD +Start([Component Initialization]) --> CheckVisible{Check visible state} +CheckVisible --> |true| CreateNotification[Create notification] +CheckVisible --> |false| DestroyNotification[Destroy notification] +CreateNotification --> RenderSlots[Render slot content] +RenderSlots --> ShowNotification[Show notification] +ShowNotification --> UserAction{User action} +UserAction --> |Close| HandleClose[Handle close event] +UserAction --> |Click| HandleClick[Handle click event] +HandleClose --> DestroyNotification +HandleClick --> DestroyNotification +DestroyNotification --> Cleanup[Clean up resources] +Cleanup --> End([Component unmounted]) +``` + +**Diagram Sources** + +- [frontend/antd/notification/notification.tsx:38-95](file://frontend/antd/notification/notification.tsx#L38-L95) + +**Section Sources** + +- [frontend/antd/notification/notification.tsx:8-106](file://frontend/antd/notification/notification.tsx#L8-L106) + +### Svelte Component Bridge + +The Svelte component serves as the bridge between frontend and backend, responsible for property forwarding and event handling: + +#### Main Responsibilities + +1. **Property handling**: Converts Python properties to React-compatible format +2. **Event binding**: Handles user interaction events +3. **Slot management**: Manages component slot content +4. **State synchronization**: Synchronizes component state to the backend + +**Section Sources** + +- [frontend/antd/notification/Index.svelte:19-79](file://frontend/antd/notification/Index.svelte#L19-L79) + +## Dependency Analysis + +The dependency relationships of the Notification component are relatively simple, primarily depending on the Ant Design and Gradio frameworks: + +```mermaid +graph TB +subgraph "External Dependencies" +Antd[Ant Design] +Gradio[Gradio Framework] +React[React] +Typescript[TypeScript] +end +subgraph "Internal Dependencies" +ComponentBase[Component Base Class] +Utils[Utility Functions] +Config[Configuration Files] +end +subgraph "Notification Component" +Backend[Backend Component] +Frontend[Frontend Component] +Bridge[Svelte Bridge] +end +Antd --> Frontend +Gradio --> Backend +React --> Frontend +Typescript --> Frontend +ComponentBase --> Backend +Utils --> Backend +Config --> Frontend +Backend --> Bridge +Bridge --> Frontend +``` + +**Diagram Sources** + +- [frontend/antd/notification/package.json:1-15](file://frontend/antd/notification/package.json#L1-L15) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +**Section Sources** + +- [backend/modelscope_studio/components/antd/**init**.py:82](file://backend/modelscope_studio/components/antd/__init__.py#L82) +- [backend/modelscope_studio/components/antd/components.py:79](file://backend/modelscope_studio/components/antd/components.py#L79) + +## Performance Considerations + +The Notification component incorporates the following performance optimizations in its design: + +### Memory Management + +- Automatically destroys notification instances that are no longer in use +- Reasonable component unmounting handling +- Avoids memory leaks + +### Render Optimization + +- Conditional rendering avoids unnecessary updates +- Effective state management +- Lazy loading of slot content + +### User Experience + +- Appropriate notification duration +- Smooth animation effects +- Responsive layout + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### Notification Not Displaying + +1. Check if the `visible` property is set to `True` +2. Confirm that `message` or `description` is correctly set +3. Verify that the component is rendering correctly + +#### Events Not Responding + +1. Check if event listeners are correctly bound +2. Confirm callback functions are correctly implemented +3. Verify event parameter passing + +#### Style Issues + +1. Check if CSS class names are correct +2. Verify style override rules +3. Confirm theme configuration + +**Section Sources** + +- [frontend/antd/notification/notification.tsx:65-68](file://frontend/antd/notification/notification.tsx#L65-L68) +- [backend/modelscope_studio/components/antd/notification/**init**.py:14-21](file://backend/modelscope_studio/components/antd/notification/__init__.py#L14-L21) + +## Conclusion + +The Notification component in ModelScope Studio is a well-designed component with the following characteristics: + +1. **Complete feature support**: Supports multiple notification types and rich configuration options +2. **Good architecture design**: Frontend-backend separation, easy to maintain and extend +3. **Excellent user experience**: Provides smooth interactions and visual effects +4. **Performance optimization**: Considers memory management and rendering optimization +5. **Comprehensive documentation**: Provides clear usage instructions and examples + +This component provides developers with a powerful and flexible notification solution that can meet the needs of various application scenarios. diff --git a/.wiki/en/Ant Design X Components/Tool Components/Tool Components.md b/.wiki/en/Ant Design X Components/Tool Components/Tool Components.md new file mode 100644 index 00000000..d1031332 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Tool Components/Tool Components.md @@ -0,0 +1,374 @@ +# Tool Components + + +**Files referenced in this document** +- [XProvider.svelte](file://frontend/antdx/x-provider/XProvider.svelte) +- [Index.svelte (XProvider export wrapper)](file://frontend/antdx/x-provider/Index.svelte) +- [config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [code-highlighter.tsx](file://frontend/antdx/code-highlighter/code-highlighter.tsx) +- [mermaid.tsx](file://frontend/antdx/mermaid/mermaid.tsx) +- [notification.tsx](file://frontend/antdx/notification/notification.tsx) +- [actions/context.ts](file://frontend/antdx/actions/context.ts) +- [backend/__init__.py (antdx aggregated exports)](file://backend/modelscope_studio/components/antdx/__init__.py) +- [x_provider documentation](file://docs/components/antdx/x_provider/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Best Practices](#appendix-usage-examples-and-best-practices) + +## Introduction + +This document is oriented toward Ant Design X tool components, systematically organizing the design and usage of the following components: + +- XProvider: Global configuration and context provider, extending antd's ConfigProvider to uniformly provide global capabilities such as theme, language, and popup container for @ant-design/x components. +- CodeHighlighter: Code highlighting display component, supporting theme customization, header slots, and syntax highlighting style overrides. +- Mermaid: Flowchart/mind map component, integrating highlighting and action item rendering, supporting light/dark theme switching and custom actions. +- Notification: Browser notification encapsulation, providing permission requests, open/close, visibility control, and callbacks. + +## Project Structure + +Key directories and files around the tool components are as follows: + +- Frontend Svelte wrapper layer: Component wrapper files under frontend/antdx, responsible for integrating @ant-design/x components into the Gradio ecosystem in a Svelte manner. +- antd ConfigProvider extension: frontend/antd/config-provider provides global capabilities such as theme, language, and popup containers. +- Action item context: frontend/antdx/actions/context provides action item context injection and rendering utilities. +- Backend aggregated exports: backend/modelscope_studio/components/antdx/**init**.py uniformly exports antdx components for use in the Python layer. + +```mermaid +graph TB +subgraph "Frontend Wrapper Layer" +XP["XProvider.svelte"] +CH["code-highlighter.tsx"] +MG["mermaid.tsx"] +NT["notification.tsx"] +end +subgraph "antd Extension" +CP["config-provider.tsx"] +end +subgraph "Action Item Context" +ACT["actions/context.ts"] +end +subgraph "Backend Exports" +BE["backend/__init__.py"] +end +XP --> CP +MG --> ACT +BE --> XP +BE --> CH +BE --> MG +BE --> NT +``` + +**Diagram Sources** + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) +- [mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [backend/**init**.py (antdx aggregated exports):1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) + +**Section Sources** + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) +- [mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [backend/**init**.py (antdx aggregated exports):1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) + +## Core Components + +- XProvider: In Svelte, asynchronously loads and injects ConfigProvider via importComponent, uniformly forwarding properties such as theme, themeMode, slots, and container functions, serving as the global context root node for @ant-design/x components. +- CodeHighlighter: A secondary encapsulation of @ant-design/x's CodeHighlighter, supporting header slots, theme mode switching, and highlightProps overrides. +- Mermaid: A secondary encapsulation of @ant-design/x's Mermaid, supporting header, actions.customActions slots and context injection, and automatically switching mermaid themes and highlighting styles based on themeMode. +- Notification: A secondary encapsulation of @ant-design/x's notification, exposing visible control, permission callbacks, tag-based closing, and other capabilities. + +**Backend Export Entry Description** +All of the above tool components are uniformly exported through [backend/modelscope_studio/components/antdx/**init**.py](file://backend/modelscope_studio/components/antdx/__init__.py), with the following export names: + +- `XProvider`: `from modelscope_studio.components.antdx import XProvider` +- `CodeHighlighter`: `from modelscope_studio.components.antdx import CodeHighlighter` +- `Mermaid`: `from modelscope_studio.components.antdx import Mermaid` +- `Notification`: `from modelscope_studio.components.antdx import Notification` + +**Section Sources** + +- [XProvider.svelte:12-74](file://frontend/antdx/x-provider/XProvider.svelte#L12-L74) +- [config-provider.tsx:53-151](file://frontend/antd/config-provider/config-provider.tsx#L53-L151) +- [code-highlighter.tsx:29-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L29-L51) +- [mermaid.tsx:33-84](file://frontend/antdx/mermaid/mermaid.tsx#L33-L84) +- [notification.tsx:6-50](file://frontend/antdx/notification/notification.tsx#L6-L50) + +## Architecture Overview + +The following diagram shows how XProvider connects antd's ConfigProvider with @ant-design/x components, completing the forwarding of properties and content through the Svelte context and slots mechanism. + +```mermaid +sequenceDiagram +participant App as "Application Root Node" +participant XP as "XProvider.svelte" +participant CP as "config-provider.tsx" +participant X as "@ant-design/x Component Tree" +App->>XP : Pass props (theme/themeMode/slots/container functions) +XP->>CP : Render ConfigProvider and inject themeMode/locale/getPopupContainer, etc. +CP-->>XP : Return Provider with global styles injected +XP->>X : Render children inside Provider +X-->>App : Child components take effect with global configuration +``` + +**Diagram Sources** + +- [XProvider.svelte:56-74](file://frontend/antdx/x-provider/XProvider.svelte#L56-L74) +- [config-provider.tsx:108-149](file://frontend/antd/config-provider/config-provider.tsx#L108-L149) + +**Section Sources** + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) + +## Component Details + +### XProvider Global Configuration and Context Providing Mechanism + +- Design points + - Uses importComponent to asynchronously load the antd ConfigProvider wrapper component, avoiding first-screen blocking. + - Extracts and merges Gradio extra properties, theme configuration, and common layout properties through getProps/processProps to form the final forwarded props. + - setConfigType('antd') specifies the configuration type, ensuring subsequent components consume a consistent context. + - Supports slot injection, converting Svelte slots into React-recognizable structures. +- Key behavior + - theme and themeMode: theme is preferentially obtained from additionalProps or restProps; themeMode comes from the shared theme state. + - Container functions: getPopupContainer and getTargetContainer are wrapped via useFunction, ensuring stable availability within the component lifecycle. + - Visibility control: Only renders the Provider when visible is true, enabling on-demand mounting. +- Best practices + - Place XProvider at the application root to ensure child components inherit global theme and language settings. + - If antd.ConfigProvider is already in use, replace it with antdx.XProvider to maintain configuration consistency. + +```mermaid +flowchart TD +Start(["Enter XProvider"]) --> GetProps["Extract props and additional properties"] +GetProps --> MergeTheme["Merge theme and themeMode"] +MergeTheme --> Slots["Process slots and inject into components"] +Slots --> Container["Bind container functions and style properties"] +Container --> Visible{"visible is true?"} +Visible -- No --> End(["Do not render"]) +Visible -- Yes --> Render["Render ConfigProvider wrapper"] +Render --> End +``` + +**Diagram Sources** + +- [XProvider.svelte:25-74](file://frontend/antdx/x-provider/XProvider.svelte#L25-L74) +- [config-provider.tsx:93-149](file://frontend/antd/config-provider/config-provider.tsx#L93-L149) + +**Section Sources** + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [Index.svelte (XProvider export wrapper):1-20](file://frontend/antdx/x-provider/Index.svelte#L1-L20) +- [config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [x_provider documentation:1-19](file://docs/components/antdx/x_provider/README.md#L1-L19) + +### CodeHighlighter Code Highlighting Component + +- Design points + - Interfaces with @ant-design/x's CodeHighlighter, supporting header slots and highlightProps customization. + - Theme customization: Based on materialDark/materialLight, uniformly removes code block outer margins to adapt to card/conversation scenarios. + - Value source: Supports passing code strings directly via the value property, or through children. +- Usage recommendations + - Use customDarkStyle in dark themes and customLightStyle in light themes. + - Override default styles via highlightProps.style, or append other react-syntax-highlighter supported properties. + - Use the header slot to add title/action areas. + +```mermaid +flowchart TD +Enter(["Enter CodeHighlighter"]) --> Theme{"themeMode is dark?"} +Theme -- Yes --> Dark["Use customDarkStyle"] +Theme -- No --> Light["Use customLightStyle"] +Dark --> Render["Render XCodeHighlighter with header/value"] +Light --> Render +Render --> Exit(["Complete"]) +``` + +**Diagram Sources** + +- [code-highlighter.tsx:29-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L29-L51) + +**Section Sources** + +- [code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) + +### Mermaid Flowchart Component + +- Design points + - Interfaces with @ant-design/x's Mermaid, supporting header, actions.customActions slots and context injection. + - Theme and highlighting: Switches mermaid theme (dark/base) based on themeMode, while synchronizing highlighting styles. + - Action items: Injects action item context via withItemsContextProvider, supporting dynamic rendering of custom actions. +- Usage recommendations + - Enable mermaid dark theme in dark mode, use base theme in light mode. + - Pass custom action items via actions.customActions or use slot injection. + - Forward mermaid rendering configuration (such as direction, theme colors, etc.) through config. + +```mermaid +sequenceDiagram +participant U as "Caller" +participant M as "mermaid.tsx" +participant Ctx as "actions/context.ts" +participant X as "@ant-design/x.Mermaid" +U->>M : Pass value/config/actions/themeMode/header +M->>Ctx : Get action item context +Ctx-->>M : Return action item list +M->>X : Pass highlightProps/config/actions/header +X-->>U : Render flowchart +``` + +**Diagram Sources** + +- [mermaid.tsx:40-84](file://frontend/antdx/mermaid/mermaid.tsx#L40-L84) +- [actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) + +**Section Sources** + +- [mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) + +### Notification Component + +- Design points + - Interfaces with @ant-design/x's notification.useNotification, exposing visible control and permission callbacks. + - Automatic permission request: When visible is true and permission is not granted, triggers a permission request; if granted, opens the notification. + - Tag-based management: Supports closing specific notifications by tag for multi-instance management. + - Lifecycle: Automatically cleans up notifications on visible changes and component unmounting. +- Usage recommendations + - Link visible and onVisible with the parent state to achieve controlled show/hide. + - Monitor permission changes via onPermission to guide users to grant permissions. + - Use tag to distinguish different notification instances to avoid mutual interference. + +```mermaid +flowchart TD +Start(["visible changes"]) --> Check{"visible is true?"} +Check -- No --> Close["Close notification by tag or all"] +Close --> End(["End"]) +Check -- Yes --> Perm{"Permission granted?"} +Perm -- No --> Request["Request permission"] +Request --> Granted{"Granted successfully?"} +Granted -- No --> End +Granted -- Yes --> Open["open(...)"] +Perm -- Yes --> Open +Open --> BindClose["Bind onClose and update onVisible"] +BindClose --> End +``` + +**Diagram Sources** + +- [notification.tsx:17-46](file://frontend/antdx/notification/notification.tsx#L17-L46) + +**Section Sources** + +- [notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) + +## Dependency Analysis + +- Component coupling + - XProvider depends on antd's ConfigProvider wrapper to form the global context root node. + - Mermaid depends on the action item context provided by actions/context to implement dynamic action rendering. + - CodeHighlighter/Mermaid both depend on react-syntax-highlighter's theme styles for unified highlighting style. +- External dependencies + - @ant-design/x: Core component library, providing CodeHighlighter, Mermaid, Notification, and other capabilities. + - antd: Provides ConfigProvider, theme algorithms, language packs, and dayjs internationalization support. + - svelte-preprocess-react: Bridges Svelte and React, supporting slots and function wrapping. + +```mermaid +graph LR +XP["XProvider.svelte"] --> CP["config-provider.tsx"] +MG["mermaid.tsx"] --> ACT["actions/context.ts"] +CH["code-highlighter.tsx"] --> RS["react-syntax-highlighter themes"] +MG --> RS +XP --> ANTD["@ant-design/x"] +CH --> ANTD +MG --> ANTD +NT["notification.tsx"] --> ANTD +``` + +**Diagram Sources** + +- [XProvider.svelte:12-14](file://frontend/antdx/x-provider/XProvider.svelte#L12-L14) +- [config-provider.tsx:1-11](file://frontend/antd/config-provider/config-provider.tsx#L1-L11) +- [code-highlighter.tsx:4-11](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L4-L11) +- [mermaid.tsx:4-15](file://frontend/antdx/mermaid/mermaid.tsx#L4-L15) +- [actions/context.ts:1-4](file://frontend/antdx/actions/context.ts#L1-L4) +- [notification.tsx:3-4](file://frontend/antdx/notification/notification.tsx#L3-L4) + +**Section Sources** + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [code-highlighter.tsx:1-54](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L1-L54) +- [mermaid.tsx:1-87](file://frontend/antdx/mermaid/mermaid.tsx#L1-L87) +- [actions/context.ts:1-7](file://frontend/antdx/actions/context.ts#L1-L7) +- [notification.tsx:1-51](file://frontend/antdx/notification/notification.tsx#L1-L51) + +## Performance Considerations + +- Asynchronous loading: XProvider uses importComponent to asynchronously load the ConfigProvider wrapper component, reducing the first-screen load burden. +- Function stabilization: Container functions are wrapped via useFunction, avoiding re-renders caused by function reference changes on each render. +- Memoization: Mermaid uses useMemo for actions.customActions and config, reducing unnecessary recalculations and renders. +- Theme styles: Unified highlighting style objects avoid the overhead of repeatedly constructing style objects. + +[This section contains general guidance; no specific file sources need to be listed] + +## Troubleshooting Guide + +- XProvider not taking effect + - Confirm XProvider is placed at the application root and that visible is true. + - Check if theme and themeMode are correctly passed; use theme_config when theme conflicts with Gradio presets. +- Mermaid chart not displaying + - Confirm value is valid and themeMode and config are correct. + - Check if actions.customActions is correctly injected via context or passed through slots. +- CodeHighlighter style anomalies + - Confirm the combination of themeMode and highlightProps.style is correct. + - Check if the header slot is being accidentally overridden. +- Notification cannot pop up + - Check browser permission status and confirm whether the onPermission callback is triggered. + - Confirm that the usage of visible and tag is as expected. + +**Section Sources** + +- [XProvider.svelte:56-74](file://frontend/antdx/x-provider/XProvider.svelte#L56-L74) +- [mermaid.tsx:40-84](file://frontend/antdx/mermaid/mermaid.tsx#L40-L84) +- [code-highlighter.tsx:29-51](file://frontend/antdx/code-highlighter/code-highlighter.tsx#L29-L51) +- [notification.tsx:17-46](file://frontend/antdx/notification/notification.tsx#L17-L46) + +## Conclusion + +This document systematically organizes the implementation and usage of four tool components: XProvider, CodeHighlighter, Mermaid, and Notification. Through unified global configuration (XProvider), theme and highlighting strategies (CodeHighlighter/Mermaid), and browser notification capabilities (Notification), they provide a stable, extensible foundation for Ant Design X's deployment in the frontend ecosystem. It is recommended to introduce XProvider uniformly at the application root, combined with theme and language configuration, to ensure child components receive a consistent global experience. + +[This section contains summary content; no specific file sources need to be listed] + +## Appendix: Usage Examples and Best Practices + +- XProvider + - Place XProvider at the application root, passing theme_config or theme and themeMode to ensure child components inherit global configuration. + - If antd.ConfigProvider is already in use, replace it with antdx.XProvider to maintain configuration consistency. +- CodeHighlighter + - Pass code content via value or children; use the header slot to add title/action areas. + - Select the corresponding highlighting style based on themeMode, and override details via highlightProps.style when necessary. +- Mermaid + - Pass value as mermaid syntax text; adjust rendering parameters via config; inject custom actions via actions.customActions. + - Switch mermaid theme (dark/base) based on themeMode to maintain consistency with the page theme. +- Notification + - Use visible and onVisible to achieve controlled display; monitor onPermission to get permission status; manage multiple instances via tag. + +**Section Sources** + +- [x_provider documentation:1-19](file://docs/components/antdx/x_provider/README.md#L1-L19) +- [backend/**init**.py (antdx aggregated exports):1-42](file://backend/modelscope_studio/components/antdx/__init__.py#L1-L42) diff --git a/.wiki/en/Ant Design X Components/Tool Components/XProvider Component.md b/.wiki/en/Ant Design X Components/Tool Components/XProvider Component.md new file mode 100644 index 00000000..d876a445 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Tool Components/XProvider Component.md @@ -0,0 +1,284 @@ +# XProvider Global Configuration + + +**Files Referenced in This Document** +- [XProvider.svelte](file://frontend/antdx/x-provider/XProvider.svelte) +- [Index.svelte](file://frontend/antdx/x-provider/Index.svelte) +- [config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [locales.ts](file://frontend/antd/config-provider/locales.ts) +- [__init__.py](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py) +- [README.md](file://README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically describes the design and usage of the XProvider global configuration component, focusing on the following aspects: + +- Context provision mechanism: How XProvider injects a unified configuration context (theme, internationalization, component default behavior, etc.) into the entire application. +- Theme configuration: Supports light/dark mode with compact algorithm synchronization, and integration with Gradio's shared theme state. +- Internationalization settings: Automatically detects browser language and dynamically loads the corresponding language pack as needed. +- Best practices for collaboration with ANTDX components: How to configure uniformly at the application level to avoid repetitive settings. + +## Project Structure + +XProvider adopts a "wrapper + synchronous rendering" pattern on the frontend, while the backend uses a Python component to bridge the frontend, forming a complete configuration provision chain. + +```mermaid +graph TB +subgraph "Frontend" +XP["XProvider.svelte"] +CI["Index.svelte"] +CP["config-provider.tsx"] +LO["locales.ts"] +end +subgraph "Backend" +PY["__init__.py(AntdXXProvider)"] +end +CI --> XP +XP --> CP +CP --> LO +PY --> CI +``` + +Diagram sources + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [Index.svelte:1-20](file://frontend/antdx/x-provider/Index.svelte#L1-L20) +- [config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [**init**.py:1-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L1-L101) + +Section sources + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [Index.svelte:1-20](file://frontend/antdx/x-provider/Index.svelte#L1-L20) +- [config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [locales.ts:1-863](file://frontend/antd/config-provider/locales.ts#L1-L863) +- [**init**.py:1-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L1-L101) + +## Core Components + +- Frontend Components + - XProvider Wrapper: Responsible for receiving props, handling additional attributes, passing through to ConfigProvider, and injecting theme and internationalization capabilities. + - ConfigProvider Implementation: Based on Ant Design's ConfigProvider, extended with theme mode and internationalization loading logic. + - locales Language Mapping: Provides on-demand loading of multi-language resources and dayjs locale synchronization. +- Backend Components + - AntdXXProvider: A Python-level layout component that declares optional slots and configuration items, bridges the frontend component, and bypasses API calls. + +Section sources + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) +- [config-provider.tsx:51-151](file://frontend/antd/config-provider/config-provider.tsx#L51-L151) +- [locales.ts:12-87](file://frontend/antd/config-provider/locales.ts#L12-L87) +- [**init**.py:10-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L10-L101) + +## Architecture Overview + +The XProvider runtime flow is as follows: + +```mermaid +sequenceDiagram +participant App as "Application" +participant Py as "AntdXXProvider(Python)" +participant CI as "Index.svelte" +participant XP as "XProvider.svelte" +participant CP as "ConfigProvider(React)" +participant LO as "locales.ts" +App->>Py : Render XProvider configuration +Py-->>CI : Load frontend component +CI->>XP : Pass props/children +XP->>CP : Pass through config + inject themeMode/locale +CP->>LO : Dynamically load language pack by locale +CP-->>App : Provide theme/i18n context +``` + +Diagram sources + +- [XProvider.svelte:12-74](file://frontend/antdx/x-provider/XProvider.svelte#L12-L74) +- [config-provider.tsx:71-149](file://frontend/antd/config-provider/config-provider.tsx#L71-L149) +- [locales.ts:89-105](file://frontend/antd/config-provider/locales.ts#L89-L105) +- [**init**.py:83-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L83-L101) + +## Detailed Component Analysis + +### XProvider Wrapper (Frontend) + +Responsibilities and Key Points + +- Receive and process props: Filter internal fields, retain restProps and additionalProps, and support priority merging of theme_config and theme. +- Dynamic import of ConfigProvider: Ensures on-demand loading via async components, reducing initial load overhead. +- Theme and i18n injection: Obtains light/dark mode from Gradio's shared theme, injects theme configuration from props or theme_config; internationalization is handled by the underlying ConfigProvider. +- Slots and styles: Pass through slots, elem_id, elem_classes, elem_style, and other common attributes. + +```mermaid +flowchart TD +Start(["Enter XProvider"]) --> GetProps["Parse props
Filter internal fields"] +GetProps --> MergeTheme["Merge theme priority
theme_config > restProps.theme > additionalProps.theme"] +MergeTheme --> SetMode["Read Gradio shared theme
Determine themeMode"] +SetMode --> ImportCP["Async import ConfigProvider"] +ImportCP --> Render["Render ConfigProvider and inject context"] +Render --> End(["Done"]) +``` + +Diagram sources + +- [XProvider.svelte:17-74](file://frontend/antdx/x-provider/XProvider.svelte#L17-L74) + +Section sources + +- [XProvider.svelte:1-75](file://frontend/antdx/x-provider/XProvider.svelte#L1-L75) + +### ConfigProvider Implementation (Frontend) + +Responsibilities and Key Points + +- Theme algorithm: Automatically combines dark and compact algorithms based on themeMode and props.theme.algorithm. +- Internationalization: Supports locale string or automatic browser language detection, dynamically loads the corresponding language pack and dayjs locale on demand. +- Container mounting: Provides function wrappers for getPopupContainer and getTargetContainer, enabling custom popup container configuration. +- Slot integration: Converts nested key paths in slots into corresponding React component trees, supporting slots like renderEmpty. + +```mermaid +flowchart TD +A["Receive props/themeMode/locale"] --> B["Compute algorithm list"] +B --> C["Dynamically load locale resources"] +C --> D["Compose props and slots"] +D --> E["Render StyleProvider + ConfigProvider"] +E --> F["Provide theme/locale/container strategy downstream"] +``` + +Diagram sources + +- [config-provider.tsx:71-149](file://frontend/antd/config-provider/config-provider.tsx#L71-L149) +- [locales.ts:89-105](file://frontend/antd/config-provider/locales.ts#L89-L105) + +Section sources + +- [config-provider.tsx:51-151](file://frontend/antd/config-provider/config-provider.tsx#L51-L151) +- [locales.ts:12-87](file://frontend/antd/config-provider/locales.ts#L12-L87) + +### Backend Component (AntdXXProvider) + +Responsibilities and Key Points + +- Parameter declaration: Includes configuration items such as component disable, size, direction, prefix class, locale, theme, variant, virtualization, and warnings. +- Slot declaration: Declares injectable slots such as renderEmpty. +- Frontend directory: Points to the frontend x-provider component directory. +- API skip: skip_api=True to avoid generating redundant APIs. + +Section sources + +- [**init**.py:10-101](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L10-L101) + +## Dependency Analysis + +- Frontend Dependencies + - @ant-design/x: XProvider React component source. + - @ant-design/cssinjs: Style injection and hash control. + - dayjs: Date localization. + - svelte-i18n: Browser language detection. + - immer: Immutable update utility. +- Backend Dependencies + - ModelScopeLayoutComponent: Layout component base class. + - resolve_frontend_dir: Locates the frontend component directory. + +```mermaid +graph LR +XP["XProvider.svelte"] --> CP["config-provider.tsx"] +CP --> AD["@ant-design/x"] +CP --> CSS["@ant-design/cssinjs"] +CP --> DJ["dayjs"] +CP --> I18N["svelte-i18n"] +CP --> IM["immer"] +PY["AntdXXProvider(__init__.py)"] --> CI["Index.svelte"] +CI --> XP +``` + +Diagram sources + +- [XProvider.svelte:1-14](file://frontend/antdx/x-provider/XProvider.svelte#L1-L14) +- [config-provider.tsx:1-11](file://frontend/antd/config-provider/config-provider.tsx#L1-L11) +- [**init**.py:6-8](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L6-L8) + +Section sources + +- [XProvider.svelte:1-14](file://frontend/antdx/x-provider/XProvider.svelte#L1-L14) +- [config-provider.tsx:1-11](file://frontend/antd/config-provider/config-provider.tsx#L1-L11) +- [**init**.py:6-8](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L6-L8) + +## Performance Considerations + +- Async loading: XProvider uses dynamic imports for ConfigProvider to avoid blocking the initial render and improve startup speed. +- Theme algorithm: Recomputes the algorithm array only when themeMode or props.theme.algorithm changes, reducing re-render cost. +- Language packs: Loads language packs and dayjs locale on demand, avoiding loading all language resources at once. +- Style injection: Uses a high-priority hash strategy to minimize style conflicts and reflows. + +## Troubleshooting Guide + +- Theme conflict warning + - Symptom: Triggered when both theme and a Gradio preset theme are set simultaneously. + - Resolution: Use theme_config uniformly to avoid conflicts with Gradio preset properties. + - Reference: [**init**.py:74-77](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L74-L77) +- Light/dark mode not taking effect + - Confirm that the Gradio shared theme has correctly set themeMode. + - Reference: [XProvider.svelte](file://frontend/antdx/x-provider/XProvider.svelte#L69) +- Language not switching as expected + - Check whether the locale string format matches the mapping rules (e.g., zh_CN, en_US), or rely on automatic detection. + - Reference: [locales.ts:12-87](file://frontend/antd/config-provider/locales.ts#L12-L87) +- Slot not taking effect + - Ensure the slot key path is correct (e.g., renderEmpty) and the corresponding content is provided in slots. + - Reference: [config-provider.tsx:29-49](file://frontend/antd/config-provider/config-provider.tsx#L29-L49) + +Section sources + +- [**init**.py:74-77](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L74-L77) +- [XProvider.svelte](file://frontend/antdx/x-provider/XProvider.svelte#L69) +- [locales.ts:12-87](file://frontend/antd/config-provider/locales.ts#L12-L87) +- [config-provider.tsx:29-49](file://frontend/antd/config-provider/config-provider.tsx#L29-L49) + +## Conclusion + +Through a "frontend wrapper + backend bridge" design, XProvider provides a unified theme and internationalization context for the application, with good extensibility and performance. It is recommended to configure XProvider centrally at the application entry point to avoid repetitive settings across components, thereby achieving a consistent user experience and lower maintenance cost. + +## Appendix + +### Configuration Options Summary + +- Component-level Configuration + - component_disabled: Component disable toggle + - component_size: Component size (small/middle/large) + - direction: Text direction (ltr/rtl) + - prefix_cls/icon_prefix_cls: Prefix class names + - variant: Component appearance variant (outlined/filled/borderless) + - virtual: Virtual scrolling + - warning: Warning configuration +- Container and Popup + - get_popup_container/get_target_container: Popup and target container functions +- Internationalization + - locale: Language code (e.g., zh_CN, en_US), supports automatic detection +- Theme + - theme/theme_config: Theme object and configuration; prefer theme_config + - themeMode: Provided by Gradio shared theme (light/dark) +- Other + - render_empty: Empty state rendering slot + - Element attributes: elem_id, elem_classes, elem_style + - Visibility: visible controls rendering + +Section sources + +- [**init**.py:19-82](file://backend/modelscope_studio/components/antdx/x_provider/__init__.py#L19-L82) +- [config-provider.tsx:53-70](file://frontend/antd/config-provider/config-provider.tsx#L53-L70) +- [locales.ts:12-87](file://frontend/antd/config-provider/locales.ts#L12-L87) +- [XProvider.svelte:25-74](file://frontend/antdx/x-provider/XProvider.svelte#L25-L74) diff --git a/.wiki/en/Ant Design X Components/Wake Components/Prompts Component.md b/.wiki/en/Ant Design X Components/Wake Components/Prompts Component.md new file mode 100644 index 00000000..6be74dfa --- /dev/null +++ b/.wiki/en/Ant Design X Components/Wake Components/Prompts Component.md @@ -0,0 +1,408 @@ +# Prompts Component + + +**Files Referenced in This Document** +- [frontend/antdx/prompts/prompts.tsx](file://frontend/antdx/prompts/prompts.tsx) +- [frontend/antdx/prompts/context.ts](file://frontend/antdx/prompts/context.ts) +- [frontend/antdx/prompts/item/Index.svelte](file://frontend/antdx/prompts/item/Index.svelte) +- [frontend/antdx/prompts/item/prompts.item.tsx](file://frontend/antdx/prompts/item/prompts.item.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [backend/modelscope_studio/components/antdx/prompts/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/__init__.py) +- [backend/modelscope_studio/components/antdx/prompts/item/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py) +- [docs/components/antdx/prompts/README.md](file://docs/components/antdx/prompts/README.md) +- [docs/components/antdx/prompts/demos/basic.py](file://docs/components/antdx/prompts/demos/basic.py) +- [docs/components/antdx/prompts/demos/nest_usage.py](file://docs/components/antdx/prompts/demos/nest_usage.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix: Usage Examples and Configuration](#appendix-usage-examples-and-configuration) + +## Introduction + +The Prompts component is used to display a set of preset questions or suggestion items, helping users quickly select an input direction and enhancing the naturalness and efficiency of conversational guidance. This component is based on Ant Design X's Prompts implementation, bridged in the frontend via a Svelte/React hybrid framework. It supports: + +- Prompt template management: Flexibly organize sub-content such as titles, icons, tags, and descriptions via slots +- Preset instruction configuration: Supports vertical layout, wrapping, style overrides, class names, and other configurations +- Nested usage: Supports nesting prompt items inside other prompt items to create hierarchical suggestions +- Dynamic content generation: Collects child items via context and renders them into the data structure required by Ant Design X +- Event handling: Provides an item_click callback to execute business logic when a prompt item is clicked + +## Project Structure + +This component is located under the frontend antdx category and uses a layered design of "container component + item handler": + +- Container Component: Responsible for collecting slot content, resolving context, and rendering into the items structure required by Ant Design X +- Item Handler: Responsible for wrapping each prompt item into a structure recognizable by the container, supporting nesting +- Utility Functions: Provides general "item context" and "render child items" capabilities, reused across multiple components + +```mermaid +graph TB +subgraph "Frontend antdx" +P["Prompts Container
frontend/antdx/prompts/prompts.tsx"] +Ctx["Items Context
frontend/antdx/prompts/context.ts"] +Item["Item Handler
frontend/antdx/prompts/item/prompts.item.tsx"] +ItemUI["Item UI Wrapper
frontend/antdx/prompts/item/Index.svelte"] +Utils1["createItemsContext
frontend/utils/createItemsContext.tsx"] +Utils2["renderItems
frontend/utils/renderItems.tsx"] +end +subgraph "Backend" +BP["Backend Container Component
backend/.../prompts/__init__.py"] +BI["Backend Item Component
backend/.../prompts/item/__init__.py"] +end +P --> Ctx +P --> Utils2 +Ctx --> Utils1 +Item --> Ctx +ItemUI --> Item +P --> BP +Item --> BI +``` + +Diagram Sources + +- [frontend/antdx/prompts/prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [frontend/antdx/prompts/context.ts:1-7](file://frontend/antdx/prompts/context.ts#L1-L7) +- [frontend/antdx/prompts/item/prompts.item.tsx:1-22](file://frontend/antdx/prompts/item/prompts.item.tsx#L1-L22) +- [frontend/antdx/prompts/item/Index.svelte:1-69](file://frontend/antdx/prompts/item/Index.svelte#L1-L69) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:1-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L1-L88) +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:1-48](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L1-L48) + +Section Sources + +- [frontend/antdx/prompts/prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [frontend/antdx/prompts/context.ts:1-7](file://frontend/antdx/prompts/context.ts#L1-L7) +- [frontend/antdx/prompts/item/prompts.item.tsx:1-22](file://frontend/antdx/prompts/item/prompts.item.tsx#L1-L22) +- [frontend/antdx/prompts/item/Index.svelte:1-69](file://frontend/antdx/prompts/item/Index.svelte#L1-L69) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:1-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L1-L88) +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:1-48](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L1-L48) + +## Core Components + +- Container Component: Prompts + - Responsibility: Collects slot content (title, items) and child items, resolves context, converts child items into the items data structure required by Ant Design X, and renders them + - Key Points: Supports passing external items data; if not provided, parses child items from the default or named slots in context; the title slot takes priority over props.title +- Item Handler: Prompts.Item + - Responsibility: Wraps each prompt item into a structure recognizable by the container, supporting slots (label, icon, description) and visibility control + - Key Points: Only allows the default slot as item content; supports extra property forwarding and passes internal index and slot key +- Item Context: createItemsContext + - Responsibility: Provides ItemsContext, uniformly collecting and updating child items across slots, supporting nested sub-contexts + - Key Points: setItem supports updates by slot key and index; onChange callback notifies the parent context +- Render Utility: renderItems + - Responsibility: Renders Item structures from context into a React-usable object tree, automatically handling slots, cloning, and parameterized rendering + - Key Points: Supports children key, withParams parameterized rendering, forceClone forced cloning + +Section Sources + +- [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) +- [frontend/antdx/prompts/item/prompts.item.tsx:7-19](file://frontend/antdx/prompts/item/prompts.item.tsx#L7-L19) +- [frontend/antdx/prompts/item/Index.svelte:16-68](file://frontend/antdx/prompts/item/Index.svelte#L16-L68) +- [frontend/utils/createItemsContext.tsx:97-273](file://frontend/utils/createItemsContext.tsx#L97-L273) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +## Architecture Overview + +The runtime architecture of Prompts consists of "frontend container + item handler + context collection + render utility", with the backend bridging to the frontend through Gradio components. + +```mermaid +sequenceDiagram +participant U as "User" +participant F as "Frontend Container (Prompts)" +participant C as "Items Context" +participant R as "Render Utility (renderItems)" +participant X as "Ant Design X (Prompts)" +U->>F : Create Prompts with props/slots +F->>C : useItems to get items context +C-->>F : Return child items from default/named slots +F->>R : Convert child items to Ant Design X required structure +R-->>F : Return items array +F->>X : Render with items/title/other config +X-->>U : Display Prompts UI +``` + +Diagram Sources + +- [frontend/antdx/prompts/prompts.tsx:16-38](file://frontend/antdx/prompts/prompts.tsx#L16-L38) +- [frontend/utils/renderItems.tsx:23-38](file://frontend/utils/renderItems.tsx#L23-L38) +- [frontend/utils/createItemsContext.tsx:108-170](file://frontend/utils/createItemsContext.tsx#L108-L170) + +## Detailed Component Analysis + +### Container Component: Prompts + +- Slots and Properties + - Supported slots: title, items + - Supported properties: vertical, wrap, styles, class_names, root_class_name, fade_in, fade_in_left, etc. +- Context Resolution + - If external items are provided, use them directly; otherwise parse from default or items slots in context + - The title slot takes priority over props.title +- Rendering Strategy + - Uses renderItems to convert Item structures from context into the object array required by Ant Design X + - Clones and parameterizes slot content to ensure correct React rendering + +```mermaid +flowchart TD +Start(["Enter Prompts"]) --> CheckItems["Are items provided?"] +CheckItems --> |Yes| UseExternal["Use external items"] +CheckItems --> |No| ResolveCtx["Resolve items/default from context"] +ResolveCtx --> Render["Call renderItems to convert"] +UseExternal --> Render +Render --> PassProps["Pass to Ant Design X component"] +PassProps --> End(["Render complete"]) +``` + +Diagram Sources + +- [frontend/antdx/prompts/prompts.tsx:16-38](file://frontend/antdx/prompts/prompts.tsx#L16-L38) +- [frontend/utils/renderItems.tsx:23-38](file://frontend/utils/renderItems.tsx#L23-L38) + +Section Sources + +- [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:28-69](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L28-L69) + +### Item Handler: Prompts.Item + +- Slots and Properties + - Supported slots: label, icon, description + - Supported properties: key, label, description, icon, disabled, visible, elem_id, elem_classes, elem_style, etc. +- Internal Processing + - Registers child items into context via ItemHandler, supporting recursive rendering of item children + - Only allows the default slot as item content to avoid ambiguity from multi-level slots +- Visibility and Styles + - visible controls rendering; elem_id/elem_classes/elem_style support style customization + +```mermaid +classDiagram +class PromptsItem { ++props : Partial[number]> ++itemIndex : number ++itemSlotKey : string ++slots : Record ++render() +} +class ItemHandler { ++itemIndex : number ++itemSlotKey : string ++itemProps(props, items) ++itemChildren(items) ++allowedSlots : ["default"] ++render() +} +PromptsItem --> ItemHandler : "uses" +``` + +Diagram Sources + +- [frontend/antdx/prompts/item/prompts.item.tsx:7-19](file://frontend/antdx/prompts/item/prompts.item.tsx#L7-L19) +- [frontend/antdx/prompts/item/Index.svelte:16-68](file://frontend/antdx/prompts/item/Index.svelte#L16-L68) + +Section Sources + +- [frontend/antdx/prompts/item/prompts.item.tsx:1-22](file://frontend/antdx/prompts/item/prompts.item.tsx#L1-L22) +- [frontend/antdx/prompts/item/Index.svelte:1-69](file://frontend/antdx/prompts/item/Index.svelte#L1-L69) +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:18-48](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L18-L48) + +### Item Context and Render Utility + +- createItemsContext + - Provides ItemsContextProvider, withItemsContextProvider, useItems, ItemHandler + - Supports updating child items by slot key and index; onChange callback notifies the parent context +- renderItems + - Converts Item structures into a React object tree, automatically handling slots, cloning, and parameterized rendering + - Supports children key, withParams, forceClone, itemPropsTransformer, and other options + +```mermaid +flowchart TD +A["Collect child items (Item)"] --> B["Write to ItemsContext"] +B --> C["Parent context subscribes to onChange"] +C --> D["renderItems converts to React objects"] +D --> E["Ant Design X renders"] +``` + +Diagram Sources + +- [frontend/utils/createItemsContext.tsx:108-170](file://frontend/utils/createItemsContext.tsx#L108-L170) +- [frontend/utils/renderItems.tsx:23-98](file://frontend/utils/renderItems.tsx#L23-L98) + +Section Sources + +- [frontend/utils/createItemsContext.tsx:97-273](file://frontend/utils/createItemsContext.tsx#L97-L273) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) + +### Backend Bridge + +- AntdXPrompts + - Supported events: item_click + - Supported slots: title, items + - Supported properties: items, prefix_cls, title, vertical, wrap, styles, class_names, root_class_name, fade_in, fade_in_left, etc. +- AntdXPromptsItem + - Supported slots: label, icon, description + - Supported properties: label, key, description, icon, disabled, visible, elem_id, elem_classes, elem_style, etc. + +Section Sources + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-69](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L69) +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:18-48](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L18-L48) + +## Dependency Analysis + +- Component Coupling + - Prompts depends on Items context and render utility; child items register to context via ItemHandler + - Backend components serve as the bridge layer for frontend components, exposing events and properties +- External Dependencies + - Ant Design X's Prompts component for actual rendering + - Svelte/React hybrid toolchain for bridging and slot rendering + +```mermaid +graph LR +Prompts["Prompts Container"] --> Ctx["Items Context"] +Prompts --> Render["renderItems"] +Item["Prompts.Item"] --> Ctx +Ctx --> Utils["createItemsContext"] +Prompts --> Backend["Backend Container Component"] +Item --> BackendItem["Backend Item Component"] +``` + +Diagram Sources + +- [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) +- [frontend/antdx/prompts/item/prompts.item.tsx:7-19](file://frontend/antdx/prompts/item/prompts.item.tsx#L7-L19) +- [frontend/utils/createItemsContext.tsx:97-273](file://frontend/utils/createItemsContext.tsx#L97-L273) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-69](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L69) +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:8-48](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L8-L48) + +Section Sources + +- [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) +- [frontend/antdx/prompts/item/prompts.item.tsx:7-19](file://frontend/antdx/prompts/item/prompts.item.tsx#L7-L19) +- [frontend/utils/createItemsContext.tsx:97-273](file://frontend/utils/createItemsContext.tsx#L97-L273) +- [frontend/utils/renderItems.tsx:8-113](file://frontend/utils/renderItems.tsx#L8-L113) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-69](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L69) +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:8-48](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L8-L48) + +## Performance Considerations + +- Render Optimization + - Uses useMemo to cache items computation results, avoiding unnecessary re-renders + - renderItems enables cloning by default (clone: true) to ensure safe React rendering and state isolation +- Context Updates + - setItem only triggers updates when the value changes, reducing invalid renders + - onChange callback fires when items update, enabling external listeners +- Nested Rendering + - When child item children are rendered recursively, stable keys are generated by index to avoid list re-ordering + +Section Sources + +- [frontend/antdx/prompts/prompts.tsx:27-34](file://frontend/antdx/prompts/prompts.tsx#L27-L34) +- [frontend/utils/renderItems.tsx:30-38](file://frontend/utils/renderItems.tsx#L30-L38) +- [frontend/utils/createItemsContext.tsx:124-153](file://frontend/utils/createItemsContext.tsx#L124-L153) + +## Troubleshooting Guide + +- Issue: Prompt items not displaying + - Check whether visible is true + - Check whether slot names are correct (label, icon, description) +- Issue: Nested prompt items not working + - Ensure child items use the default slot as content + - Confirm child items are not using invalid slot keys +- Issue: No response on click + - Confirm the item_click event has been bound + - Check whether the backend event mapping is effective +- Issue: Styles not taking effect + - Check whether elem_id, elem_classes, and elem_style are correctly passed + - Check whether styles and class_names are overriding the target styles + +Section Sources + +- [frontend/antdx/prompts/item/Index.svelte:53-68](file://frontend/antdx/prompts/item/Index.svelte#L53-L68) +- [frontend/antdx/prompts/item/prompts.item.tsx:11-18](file://frontend/antdx/prompts/item/prompts.item.tsx#L11-L18) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) + +## Conclusion + +The Prompts component, through its "container + item handler + context + render utility" architecture, achieves seamless bridging and extension of Ant Design X. It not only supports basic prompt set creation and style customization, but also provides powerful nesting capabilities and event handling interfaces that effectively improve the conversational guidance experience. Combined with the backend event bridge, developers can easily implement the complete loop from clicking a prompt item to executing business logic. + +## Appendix: Usage Examples and Configuration + +### Basic Prompt Set Creation + +- Example Path: [docs/components/antdx/prompts/demos/basic.py:24-72](file://docs/components/antdx/prompts/demos/basic.py#L24-L72) +- Key Points + - Wrap with XProvider + - Set title, vertical, wrap, and other properties + - Use slots (icon, label, description) in each prompt item + +Section Sources + +- [docs/components/antdx/prompts/demos/basic.py:24-72](file://docs/components/antdx/prompts/demos/basic.py#L24-L72) + +### Nested Usage Scenarios + +- Example Path: [docs/components/antdx/prompts/demos/nest_usage.py:16-83](file://docs/components/antdx/prompts/demos/nest_usage.py#L16-L83) +- Key Points + - Nest prompt items inside prompt items to create hierarchical suggestions + - Use styles and class_names for style customization + - Use item_click to capture click events and handle them + +Section Sources + +- [docs/components/antdx/prompts/demos/nest_usage.py:16-83](file://docs/components/antdx/prompts/demos/nest_usage.py#L16-L83) + +### Component Configuration Options (Frontend Container) + +- Properties + - items: Externally provided array of prompt items + - title: Title text or slot + - vertical: Whether to arrange vertically + - wrap: Whether to wrap + - styles: Style overrides + - class_names: Class name mapping + - root_class_name: Root class name + - fade_in/fade_in_left: Entry animations +- Slots + - title: Custom title + - items: Custom prompt item collection + +Section Sources + +- [frontend/antdx/prompts/prompts.tsx:24-34](file://frontend/antdx/prompts/prompts.tsx#L24-L34) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:28-69](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L28-L69) + +### Event Handling + +- item_click: Triggered when a prompt item is clicked +- Example bindings: [docs/components/antdx/prompts/demos/basic.py:72](file://docs/components/antdx/prompts/demos/basic.py#L72), [docs/components/antdx/prompts/demos/nest_usage.py:83](file://docs/components/antdx/prompts/demos/nest_usage.py#L83) + +Section Sources + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) +- [docs/components/antdx/prompts/demos/basic.py:72](file://docs/components/antdx/prompts/demos/basic.py#L72) +- [docs/components/antdx/prompts/demos/nest_usage.py:83](file://docs/components/antdx/prompts/demos/nest_usage.py#L83) + +### Style Customization + +- Use elem_id, elem_classes, elem_style for style customization of individual prompt items +- Use styles, class_names, root_class_name for customization of the overall layout and theme +- Example reference: [docs/components/antdx/prompts/demos/nest_usage.py:19-29](file://docs/components/antdx/prompts/demos/nest_usage.py#L19-L29) + +Section Sources + +- [frontend/antdx/prompts/item/Index.svelte:56-58](file://frontend/antdx/prompts/item/Index.svelte#L56-L58) +- [backend/modelscope_studio/components/antdx/prompts/item/**init**.py:30-35](file://backend/modelscope_studio/components/antdx/prompts/item/__init__.py#L30-L35) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:38-69](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L38-L69) diff --git a/.wiki/en/Ant Design X Components/Wake Components/Wake Components.md b/.wiki/en/Ant Design X Components/Wake Components/Wake Components.md new file mode 100644 index 00000000..0c0486e0 --- /dev/null +++ b/.wiki/en/Ant Design X Components/Wake Components/Wake Components.md @@ -0,0 +1,293 @@ +# Wake Components + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/antdx/welcome/__init__.py](file://backend/modelscope_studio/components/antdx/welcome/__init__.py) +- [frontend/antdx/welcome/Index.svelte](file://frontend/antdx/welcome/Index.svelte) +- [frontend/antdx/welcome/welcome.tsx](file://frontend/antdx/welcome/welcome.tsx) +- [backend/modelscope_studio/components/antdx/prompts/__init__.py](file://backend/modelscope_studio/components/antdx/prompts/__init__.py) +- [frontend/antdx/prompts/Index.svelte](file://frontend/antdx/prompts/Index.svelte) +- [frontend/antdx/prompts/prompts.tsx](file://frontend/antdx/prompts/prompts.tsx) +- [frontend/antdx/prompts/item/Index.svelte](file://frontend/antdx/prompts/item/Index.svelte) +- [frontend/antdx/prompts/item/prompts.item.tsx](file://frontend/antdx/prompts/item/prompts.item.tsx) +- [frontend/pro/chatbot/chatbot.tsx](file://frontend/pro/chatbot/chatbot.tsx) +- [docs/layout_templates/chatbot/demos/fine_grained_control.py](file://docs/layout_templates/chatbot/demos/fine_grained_control.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document covers the Ant Design X Wake Components, systematically describing the design and usage of the Welcome component and the Prompts component. It helps developers quickly build high-quality initial user experiences: Welcome handles the display and personalization of the welcome page; Prompts handles the organization of prompt templates, preset instructions, and intelligent recommendations. The documentation covers component responsibilities, data flow, interaction logic, extension points, and complete usage examples to support real-world project integration. + +## Project Structure + +The Ant Design X Wake Components are implemented through a collaboration between backend Python components and a frontend Svelte/React layer: + +- The backend component handles parameter parsing, static resource processing, event binding, and rendering control +- The frontend Svelte layer handles property forwarding, slot resolution, and async loading of React components +- The React layer directly interfaces with the native components of @ant-design/x for final rendering + +```mermaid +graph TB +subgraph "Backend" +B_Wel["AntdXWelcome
Python Component"] +B_Pro["AntdXPrompts
Python Component"] +end +subgraph "Frontend" +F_SvWel["welcome/Index.svelte"] +F_SvPro["prompts/Index.svelte"] +F_RcWel["welcome/welcome.tsx"] +F_RcPro["prompts/prompts.tsx"] +F_Item["prompts/item/Index.svelte"] +end +subgraph "Third-party" +X["@ant-design/x
React Component Library"] +end +B_Wel --> F_SvWel --> F_RcWel --> X +B_Pro --> F_SvPro --> F_RcPro --> X +F_Item --> F_RcPro +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L55) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-70](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L70) +- [frontend/antdx/welcome/Index.svelte:1-65](file://frontend/antdx/welcome/Index.svelte#L1-L65) +- [frontend/antdx/prompts/Index.svelte:1-70](file://frontend/antdx/prompts/Index.svelte#L1-L70) +- [frontend/antdx/welcome/welcome.tsx:1-44](file://frontend/antdx/welcome/welcome.tsx#L1-L44) +- [frontend/antdx/prompts/prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [frontend/antdx/prompts/item/Index.svelte:1-68](file://frontend/antdx/prompts/item/Index.svelte#L1-L68) + +Section Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) +- [frontend/antdx/welcome/Index.svelte:1-65](file://frontend/antdx/welcome/Index.svelte#L1-L65) +- [frontend/antdx/prompts/Index.svelte:1-70](file://frontend/antdx/prompts/Index.svelte#L1-L70) + +## Core Components + +- Welcome Component: Used for displaying the welcome page. Supports slot-based customization of title, description, icon, and extra content, along with style and variant configuration. +- Prompts Component: Used for displaying a set of prompt templates. Supports title slot, item slots, vertical layout, fade-in animations, wrapping, and provides an item_click callback event. + +Section Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L55) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-70](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L70) + +## Architecture Overview + +The diagram below shows the data and control flow from the backend to the frontend and then to the third-party component library: + +```mermaid +sequenceDiagram +participant Py as "Backend Component
Python" +participant S as "Frontend Svelte
Index.svelte" +participant R as "Frontend React Wrapper
welcome.tsx / prompts.tsx" +participant X as "@ant-design/x
React Component" +Py->>S : Pass visibility/styles/additional props +S->>R : Forward props and slots +R->>X : Render native component handling icon/title/description/items +X-->>R : Component output +R-->>S : Return render result +S-->>Py : Complete one render cycle +``` + +Diagram Sources + +- [frontend/antdx/welcome/Index.svelte:49-64](file://frontend/antdx/welcome/Index.svelte#L49-L64) +- [frontend/antdx/welcome/welcome.tsx:16-41](file://frontend/antdx/welcome/welcome.tsx#L16-L41) +- [frontend/antdx/prompts/Index.svelte:56-69](file://frontend/antdx/prompts/Index.svelte#L56-L69) +- [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) + +## Detailed Component Analysis + +### Welcome Component + +- Component Responsibilities + - Displays the welcome page with slot-based customization of title, description, icon, and extra content + - Supports style and class name injection, along with multiple variant styles + - Icon supports static resource paths or file objects, uniformly converted to accessible URLs via utility functions +- Key Properties + - Slots: extra, icon, description, title + - Variants: filled, borderless + - Styles: styles, class_names, root_class_name + - Metadata: elem_id, elem_classes, elem_style, visible, render +- Data Flow + - Backend receives parameters and processes static resource paths + - Frontend Svelte forwards props and slots to the React wrapper layer + - React layer determines rendering content based on slot priority strategy and converts icons to accessible URLs +- Interaction Logic + - Serves as the welcome page entry point, typically displayed during application initialization + - Can be hidden or transitioned to the conversation area after the user selects a prompt, based on business logic + +```mermaid +flowchart TD +Start(["Enter Welcome Render"]) --> CheckIcon["Is a slot icon provided?"] +CheckIcon --> |Yes| RenderSlotIcon["Render slot icon"] +CheckIcon --> |No| ConvertIcon["Convert icon to accessible URL"] +RenderSlotIcon --> RenderTitle["Render title slot/text"] +ConvertIcon --> RenderTitle +RenderTitle --> RenderDesc["Render description slot/text"] +RenderDesc --> RenderExtra["Render extra content slot/text"] +RenderExtra --> ApplyStyles["Apply styles and class names"] +ApplyStyles --> End(["Render complete"]) +``` + +Diagram Sources + +- [frontend/antdx/welcome/welcome.tsx:16-41](file://frontend/antdx/welcome/welcome.tsx#L16-L41) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:47-53](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L47-L53) + +Section Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) +- [frontend/antdx/welcome/Index.svelte:1-65](file://frontend/antdx/welcome/Index.svelte#L1-L65) +- [frontend/antdx/welcome/welcome.tsx:1-44](file://frontend/antdx/welcome/welcome.tsx#L1-L44) + +### Prompts Component + +- Component Responsibilities + - Displays a set of prompt templates with support for title and item slots + - Provides item click event callbacks to trigger subsequent interactions + - Supports visual configurations such as vertical layout, fade-in animations, and wrapping +- Key Properties + - Slots: title, items + - List configuration: items, vertical, fade_in, fade_in_left, wrap + - Styles and class names: styles, class_names, root_class_name + - Metadata: elem_id, elem_classes, elem_style, visible, render +- Data Flow + - Backend defines event listeners, mapping item_click to frontend events + - Frontend Svelte forwards props and slots to the React wrapper layer + - React layer merges external items with slot items, cloning on demand to avoid side effects +- Interaction Logic + - A callback is triggered when the user clicks a prompt item; specific behaviors can be bound at the business layer (e.g., filling the input box, initiating a request) + +```mermaid +sequenceDiagram +participant U as "User" +participant P as "Prompts Component" +participant Ctx as "Item Context" +participant X as "@ant-design/x
Prompts" +U->>P : Click a prompt item +P->>Ctx : Trigger item_click event +Ctx-->>P : Callback notification +P->>X : Render prompt list with merged items +X-->>U : Display click feedback +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) +- [frontend/antdx/prompts/Index.svelte:48-49](file://frontend/antdx/prompts/Index.svelte#L48-L49) +- [frontend/antdx/prompts/prompts.tsx:13-40](file://frontend/antdx/prompts/prompts.tsx#L13-L40) + +Section Sources + +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-88](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L88) +- [frontend/antdx/prompts/Index.svelte:1-70](file://frontend/antdx/prompts/Index.svelte#L1-L70) +- [frontend/antdx/prompts/prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) +- [frontend/antdx/prompts/item/Index.svelte:1-68](file://frontend/antdx/prompts/item/Index.svelte#L1-L68) +- [frontend/antdx/prompts/item/prompts.item.tsx:1-21](file://frontend/antdx/prompts/item/prompts.item.tsx#L1-L21) + +## Dependency Analysis + +- Component Coupling + - Backend components are only responsible for parameter and static resource handling — low coupling + - Frontend Svelte layer handles prop forwarding and slot resolution — low coupling + - React wrapper layer is tightly coupled to @ant-design/x, but transparent to upper layers +- External Dependencies + - @ant-design/x: Provides native implementations of Welcome and Prompts + - Utility functions: File URL conversion, slot rendering, item rendering, etc. +- Event Mapping + - The backend maps the item_click event to frontend event names to ensure cross-layer consistency + +```mermaid +graph LR +Py["Backend Component"] --> Svelte["Frontend Svelte"] +Svelte --> ReactWrap["React Wrapper Layer"] +ReactWrap --> ADX["@ant-design/x"] +Py --> Utils["Utility Functions"] +Svelte --> Utils +ReactWrap --> Utils +``` + +Diagram Sources + +- [frontend/antdx/welcome/welcome.tsx:6-7](file://frontend/antdx/welcome/welcome.tsx#L6-L7) +- [frontend/antdx/prompts/prompts.tsx:9-11](file://frontend/antdx/prompts/prompts.tsx#L9-L11) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) + +Section Sources + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L55) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:11-70](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L11-L70) +- [frontend/antdx/welcome/welcome.tsx:1-44](file://frontend/antdx/welcome/welcome.tsx#L1-L44) +- [frontend/antdx/prompts/prompts.tsx:1-43](file://frontend/antdx/prompts/prompts.tsx#L1-L43) + +## Performance Considerations + +- Render Optimization + - Use async component imports to avoid blocking the initial render + - Delay slot content rendering to reduce unnecessary computation +- Resource Optimization + - Icons go through a unified URL conversion to avoid repeated downloads + - Item rendering uses a cloning strategy to reduce re-renders caused by shared state +- Event Handling + - Event mapping is completed in the frontend to reduce backend overhead + +## Troubleshooting Guide + +- Icon Not Displaying + - Check whether the icon path is correct and confirm it has been converted to an accessible URL via the utility function + - If using a slot icon, verify the slot content is rendering correctly +- Slot Content Not Taking Effect + - Confirm the slot name matches the slots supported by the component (Welcome: extra, icon, description, title; Prompts: title, items) + - Verify that the slot content is correctly wrapped in the React wrapper layer +- Click Events Not Firing + - Confirm the backend event listener is enabled and the frontend event mapping is correct + - Check whether the upper business layer has correctly bound the callback + +Section Sources + +- [frontend/antdx/welcome/welcome.tsx:23-37](file://frontend/antdx/welcome/welcome.tsx#L23-L37) +- [frontend/antdx/prompts/Index.svelte:48-49](file://frontend/antdx/prompts/Index.svelte#L48-L49) +- [backend/modelscope_studio/components/antdx/prompts/**init**.py:18-23](file://backend/modelscope_studio/components/antdx/prompts/__init__.py#L18-L23) + +## Conclusion + +The Welcome and Prompts components provide high customizability and good extensibility for the initial user experience through clear responsibility separation and slot-based design. Combined with the native capabilities of @ant-design/x, they can satisfy both basic display requirements and complex interaction and recommendation scenarios. It is recommended to configure styles and events according to business objectives in real projects for a better user experience. + +## Appendix + +### Usage Examples and Best Practices + +- Welcome Page Design + - Use the Welcome component as the entry point for the first screen, configuring title, description, and icon via slots + - Configure variants and styles to match the overall design style + - Hide the welcome page and enter the conversation area after the user selects a prompt +- Prompts Configuration + - Use the Prompts component to display a set of prompt templates, supporting grouping and hierarchies + - Combine slots with external items for flexible prompt content management + - Bind the item_click event to enable click-to-use interactions +- User Onboarding Flow + - Display the welcome page during application initialization + - Show curated prompt sets to guide users to get started quickly + - Dynamically adjust prompt content and ordering based on user behavior + +Section Sources + +- [frontend/pro/chatbot/chatbot.tsx:108-115](file://frontend/pro/chatbot/chatbot.tsx#L108-L115) +- [docs/layout_templates/chatbot/demos/fine_grained_control.py:603-619](file://docs/layout_templates/chatbot/demos/fine_grained_control.py#L603-L619) diff --git a/.wiki/en/Ant Design X Components/Wake Components/Welcome Component.md b/.wiki/en/Ant Design X Components/Wake Components/Welcome Component.md new file mode 100644 index 00000000..c4dd1c7c --- /dev/null +++ b/.wiki/en/Ant Design X Components/Wake Components/Welcome Component.md @@ -0,0 +1,424 @@ +# Welcome Component + + +**Files Referenced in This Document** +- [frontend/antdx/welcome/Index.svelte](file://frontend/antdx/welcome/Index.svelte) +- [frontend/antdx/welcome/welcome.tsx](file://frontend/antdx/welcome/welcome.tsx) +- [backend/modelscope_studio/components/antdx/welcome/__init__.py](file://backend/modelscope_studio/components/antdx/welcome/__init__.py) +- [docs/components/antdx/welcome/README.md](file://docs/components/antdx/welcome/README.md) +- [docs/components/antdx/welcome/demos/basic.py](file://docs/components/antdx/welcome/demos/basic.py) +- [frontend/antdx/welcome/package.json](file://frontend/antdx/welcome/package.json) +- [frontend/antdx/welcome/gradio.config.js](file://frontend/antdx/welcome/gradio.config.js) +- [docs/components/antdx/welcome/app.py](file://docs/components/antdx/welcome/app.py) +- [docs/helper/Docs.py](file://docs/helper/Docs.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) + + +## Update Summary + +**Changes Made** + +- Enhanced style support system with improved layout control capabilities +- Added flexShrink control for the icon area to optimize responsive layout behavior +- Improved style merging mechanism with support for more granular style customization + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Style Enhancement Features](#style-enhancement-features) +7. [Dependency Analysis](#dependency-analysis) +8. [Performance Considerations](#performance-considerations) +9. [Troubleshooting Guide](#troubleshooting-guide) +10. [Conclusion](#conclusion) +11. [Appendix](#appendix) + +## Introduction + +The Welcome component is designed to clearly communicate the intended purpose and expected functionality of an interface, targeting "AI agent product interface" scenarios. This component is based on Ant Design X's Welcome implementation, wrapped by a Python backend and bridged through a Svelte frontend. It provides slot-based extension capabilities, icon and copy customization, variant style control, and can be used as a layout element in Gradio applications. + +**Update** This update enhances the style support system, providing improved layout control capabilities and responsive design optimizations. + +## Project Structure + +The Welcome component consists of a backend Python wrapper class and a frontend Svelte/React bridge layer. The documentation system renders examples and descriptions through the Docs helper. + +```mermaid +graph TB +subgraph "Backend" +PY_INIT["Python Wrapper Class
__init__.py"] +DEV_COMP["Base Component Class
component.py"] +end +subgraph "Frontend" +SV_INDEX["Svelte Entry
Index.svelte"] +TS_WELCOME["React Bridge Component
welcome.tsx"] +PKG["Package Export Config
package.json"] +CFG["Gradio Build Config
gradio.config.js"] +end +subgraph "Documentation" +DOC_README["Component Docs
README.md"] +DOC_DEMOS["Demo Scripts
demos/basic.py"] +DOC_APP["Docs App Entry
app.py"] +DOC_HELPER["Docs Renderer
Docs.py"] +end +PY_INIT --> DEV_COMP +PY_INIT --> SV_INDEX +SV_INDEX --> TS_WELCOME +PKG --> SV_INDEX +CFG --> SV_INDEX +DOC_README --> DOC_APP +DOC_DEMOS --> DOC_APP +DOC_HELPER --> DOC_APP +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:1-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L1-L73) +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [frontend/antdx/welcome/Index.svelte:1-65](file://frontend/antdx/welcome/Index.svelte#L1-L65) +- [frontend/antdx/welcome/welcome.tsx:1-51](file://frontend/antdx/welcome/welcome.tsx#L1-L51) +- [frontend/antdx/welcome/package.json:1-15](file://frontend/antdx/welcome/package.json#L1-L15) +- [frontend/antdx/welcome/gradio.config.js:1-4](file://frontend/antdx/welcome/gradio.config.js#L1-L4) +- [docs/components/antdx/welcome/README.md:1-8](file://docs/components/antdx/welcome/README.md#L1-L8) +- [docs/components/antdx/welcome/demos/basic.py:1-37](file://docs/components/antdx/welcome/demos/basic.py#L1-L37) +- [docs/components/antdx/welcome/app.py:1-7](file://docs/components/antdx/welcome/app.py#L1-L7) +- [docs/helper/Docs.py:1-178](file://docs/helper/Docs.py#L1-L178) + +## Core Components + +- Backend Wrapper Class: Responsible for declaring supported slots, properties, styles, and rendering lifecycle, while converting static resource paths to accessible URLs. +- Frontend Bridge Layer: Encapsulates Ant Design X React components in Svelte style, supporting slot rendering and static resource URL resolution. +- Documentation and Examples: Provides minimal viable examples and documentation pages for quick onboarding. + +Key Responsibilities and Behaviors + +- Slot Support: title, description, icon, extra. +- Property Configuration: icon, title, description, variant (filled/borderless), style and class name injection, visibility and DOM attribute forwarding. +- Resource Handling: Resolves icon paths passed from the backend to ensure they can be correctly loaded in the Gradio environment. +- Rendering Strategy: Controls whether to render based on visible; injects shared rootUrl and apiPrefix in the Gradio context. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:14-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L14-L55) +- [frontend/antdx/welcome/welcome.tsx:8-41](file://frontend/antdx/welcome/welcome.tsx#L8-L41) +- [frontend/antdx/welcome/Index.svelte:12-44](file://frontend/antdx/welcome/Index.svelte#L12-L44) + +## Architecture Overview + +The Welcome component uses a layered design of "backend component + frontend bridge + documentation examples". The backend handles component semantics and resource processing, the frontend handles UI rendering and slot integration, and the documentation system handles the unified presentation of examples and descriptions. + +```mermaid +sequenceDiagram +participant U as "User" +participant G as "Gradio App" +participant PY as "Backend Wrapper Class
AntdXWelcome" +participant SV as "Svelte Entry
Index.svelte" +participant RX as "React Component Bridge
welcome.tsx" +participant ADX as "Ant Design X
Welcome" +U->>G : Open page +G->>PY : Initialize and pass properties and slots +PY-->>SV : Inject extra properties and static resources +SV->>SV : Evaluate visible and render conditionally +SV->>RX : Pass properties, slots, and shared context +RX->>ADX : Render Ant Design X Welcome +ADX-->>U : Display title/description/icon/extra actions +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:37-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L37-L55) +- [frontend/antdx/welcome/Index.svelte:49-64](file://frontend/antdx/welcome/Index.svelte#L49-L64) +- [frontend/antdx/welcome/welcome.tsx:16-41](file://frontend/antdx/welcome/welcome.tsx#L16-L41) + +## Detailed Component Analysis + +### Backend Wrapper Class (Python) + +- Supported Slots: extra, icon, description, title. +- Key Properties: + - Icon: icon (supports local static file paths; converted to accessible URLs by the backend). + - Title and Description: title, description. + - Variant: variant (filled or borderless). + - Styles and Class Names: styles, class_names, elem_id, elem_classes, elem_style. + - Render Control: visible, render, as_item. +- Lifecycle: + - Placeholder implementations for preprocess/postprocess/example_payload/example_value; skip_api returns True, indicating this component does not participate in the standard API flow. +- Frontend Directory Resolution: Uses resolve_frontend_dir("welcome", type="antdx") to point to the frontend implementation. + +```mermaid +classDiagram +class ModelScopeLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__exit__() ++__init__(visible, elem_id, elem_classes, elem_style, render, ...) +} +class AntdXWelcome { ++EVENTS ++SLOTS ++additional_props ++extra ++icon ++styles ++class_names ++description ++variant ++title ++root_class_name ++FRONTEND_DIR ++skip_api ++preprocess() ++postprocess() ++example_payload() ++example_value() +} +AntdXWelcome --|> ModelScopeLayoutComponent : "inherits" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:8-73](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L8-L73) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:14-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L14-L55) +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) + +### Frontend Bridge Layer (Svelte + React) + +- Svelte Entry Responsibilities: + - Retrieves component properties and extra properties, filters out internally reserved fields (e.g., visible, \_internal), and forwards the remaining properties to the React component. + - Uses conditional rendering to load and render the React component only when visible is true. + - Passes Gradio's shared rootUrl and apiPrefix to the React component for resolving static resources. +- React Bridge Responsibilities: + - Wraps Ant Design X's Welcome component with sveltify to support slot rendering. + - Handles icon with priority: if a slot exists, renders the slot content; otherwise resolves the static resource URL. + - Supports both slot and string value dual-mode for title, description, and extra. + - **New**: Enhanced style support system providing better layout control capabilities. + +```mermaid +flowchart TD +Start(["Enter Svelte Entry"]) --> GetProps["Get component properties and extra props"] +GetProps --> Filter["Filter internal fields and forward"] +Filter --> Visible{"visible is true?"} +Visible --> |No| Skip["Skip rendering"] +Visible --> |Yes| Load["Dynamically import React component"] +Load --> Render["Render React bridge component"] +Render --> Styles["Apply style enhancement system"] +Styles --> Slots{"Slots exist?"} +Slots --> |Yes| SlotRender["Render slot content with ReactSlot"] +Slots --> |No| StaticURL["Resolve static resource URL"] +SlotRender --> Done(["Complete"]) +StaticURL --> Done +Skip --> End(["End"]) +Done --> End +``` + +**Diagram Sources** + +- [frontend/antdx/welcome/Index.svelte:22-44](file://frontend/antdx/welcome/Index.svelte#L22-L44) +- [frontend/antdx/welcome/welcome.tsx:16-41](file://frontend/antdx/welcome/welcome.tsx#L16-L41) + +**Section Sources** + +- [frontend/antdx/welcome/Index.svelte:12-44](file://frontend/antdx/welcome/Index.svelte#L12-L44) +- [frontend/antdx/welcome/welcome.tsx:8-41](file://frontend/antdx/welcome/welcome.tsx#L8-L41) + +### Documentation and Examples (Docs System) + +- The documentation app uses the Docs class to scan the README and demos directories, automatically rendering example code and run results. +- The demo scripts demonstrate two variants (default and borderless) and inject extra action buttons via slots. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant DocApp as "Docs App
app.py" +participant Helper as "Docs Renderer
Docs.py" +participant Demo as "Demo Script
basic.py" +participant Comp as "Welcome Component" +Dev->>DocApp : Start documentation service +DocApp->>Helper : Initialize and load docs and examples +Helper->>Demo : Dynamically import demo module +Demo->>Comp : Create Welcome instance and configure properties +Comp-->>Dev : Display result in documentation page +``` + +**Diagram Sources** + +- [docs/components/antdx/welcome/app.py:1-7](file://docs/components/antdx/welcome/app.py#L1-L7) +- [docs/helper/Docs.py:58-75](file://docs/helper/Docs.py#L58-L75) +- [docs/components/antdx/welcome/demos/basic.py:6-36](file://docs/components/antdx/welcome/demos/basic.py#L6-L36) + +**Section Sources** + +- [docs/components/antdx/welcome/README.md:1-8](file://docs/components/antdx/welcome/README.md#L1-L8) +- [docs/components/antdx/welcome/demos/basic.py:1-37](file://docs/components/antdx/welcome/demos/basic.py#L1-L37) +- [docs/components/antdx/welcome/app.py:1-7](file://docs/components/antdx/welcome/app.py#L1-L7) +- [docs/helper/Docs.py:58-75](file://docs/helper/Docs.py#L58-L75) + +## Style Enhancement Features + +### Enhanced Style Support System + +The Welcome component now provides more powerful style support and layout control capabilities, primarily in the following areas: + +#### Icon Area Layout Optimization + +- **flexShrink Control**: Sets `flexShrink: 0` for the icon area to ensure the icon maintains a fixed size in responsive layouts +- **Style Merging Mechanism**: Supports intelligent merging of user-defined styles with default styles +- **Responsive Adaptation**: Optimizes layout behavior across different screen sizes + +#### Style Customization Capabilities + +- **styles Parameter Support**: Fully supports passing the styles parameter from Ant Design X +- **Independent Icon Style Control**: Allows separate style customization for the icon area +- **Theme Consistency**: Maintains compatibility with the Ant Design X theme system + +#### Layout Control Enhancements + +- **Container Style Forwarding**: Supports container-level style control via elem_style and elem_classes +- **Flexbox Optimization**: Uses Flexbox layout for better content arrangement +- **Spacing Control**: Optimizes spacing between icon, title, and description + +```mermaid +graph LR +Styles["Style System"] --> IconStyle["Icon Style Control"] +Styles --> ContainerStyle["Container Style Forwarding"] +Styles --> LayoutControl["Layout Control Enhancement"] +IconStyle --> FlexShrink["flexShrink: 0"] +IconStyle --> CustomStyling["Custom Style Merging"] +ContainerStyle --> ElemStyle["elem_style Support"] +ContainerStyle --> ElemClasses["elem_classes Support"] +LayoutControl --> Responsive["Responsive Layout"] +LayoutControl --> Spacing["Spacing Optimization"] +``` + +**Diagram Sources** + +- [frontend/antdx/welcome/welcome.tsx:23-29](file://frontend/antdx/welcome/welcome.tsx#L23-L29) +- [frontend/antdx/welcome/Index.svelte:52-53](file://frontend/antdx/welcome/Index.svelte#L52-L53) + +**Section Sources** + +- [frontend/antdx/welcome/welcome.tsx:23-29](file://frontend/antdx/welcome/welcome.tsx#L23-L29) +- [frontend/antdx/welcome/Index.svelte:52-53](file://frontend/antdx/welcome/Index.svelte#L52-L53) + +## Dependency Analysis + +- Backend Dependencies: + - Base Component Class: Provides common layout component capabilities and context management. + - Frontend Directory Resolution: Uses resolve_frontend_dir to locate the frontend implementation. +- Frontend Dependencies: + - Ant Design X React component library. + - Gradio client tools: For static resource URL resolution. + - Svelte preprocessing toolchain: Bridges React components with Svelte. + - **New**: Style system enhancement dependencies providing better layout control capabilities. +- Documentation System Dependencies: + - Docs renderer responsible for scanning and rendering README and demos. + +```mermaid +graph LR +PY["AntdXWelcome
__init__.py"] --> BASE["ModelScopeLayoutComponent
component.py"] +PY --> FE_DIR["resolve_frontend_dir('welcome','antdx')"] +SV["Index.svelte"] --> PREACT["@svelte-preprocess-react/*"] +SV --> CLS["classnames"] +SV --> RX["welcome.tsx"] +RX --> ADX["@ant-design/x"] +RX --> GRCL["@gradio/client"] +RX --> PREACT +RX --> STYLES["Style Enhancement System"] +DOC["Docs.py"] --> APP["app.py"] +DOC --> DEMO["demos/basic.py"] +DOC --> READ["README.md"] +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:55-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L55-L55) +- [backend/modelscope_studio/utils/dev/component.py:11-50](file://backend/modelscope_studio/utils/dev/component.py#L11-L50) +- [frontend/antdx/welcome/Index.svelte:1-10](file://frontend/antdx/welcome/Index.svelte#L1-L10) +- [frontend/antdx/welcome/welcome.tsx:1-7](file://frontend/antdx/welcome/welcome.tsx#L1-L7) +- [docs/helper/Docs.py:58-75](file://docs/helper/Docs.py#L58-L75) +- [docs/components/antdx/welcome/demos/basic.py:1-5](file://docs/components/antdx/welcome/demos/basic.py#L1-L5) + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:55-55](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L55-L55) +- [frontend/antdx/welcome/Index.svelte:1-10](file://frontend/antdx/welcome/Index.svelte#L1-L10) +- [frontend/antdx/welcome/welcome.tsx:1-7](file://frontend/antdx/welcome/welcome.tsx#L1-L7) +- [docs/helper/Docs.py:58-75](file://docs/helper/Docs.py#L58-L75) + +## Performance Considerations + +- Conditional Rendering: Only loads and renders the React component when visible is true, avoiding unnecessary initialization and network requests. +- Dynamic Import: Async import of the React component reduces initial load. +- Resource Resolution: Resolves static resource URLs uniformly in the frontend, avoiding repeated computation and cross-origin issues. +- Slot Rendering: Prioritizes slot content, reducing string concatenation and template rendering costs. +- **New**: The style enhancement system uses an efficient style merging algorithm to avoid redundant renders and style conflicts. + +## Troubleshooting Guide + +- Icon Not Displaying + - Check whether the icon passed from the backend is a valid path or URL. + - Confirm that Gradio's shared rootUrl and apiPrefix have been correctly passed to the frontend. +- Slot Not Taking Effect + - Confirm the slot name is one of: title, description, icon, extra. + - Ensure slot content is correctly mounted at runtime. +- Component Not Rendering + - Check whether visible is true. + - Confirm the frontend implementation pointed to by FRONTEND_DIR exists and can be built. +- Documentation Examples Not Running + - Check whether the component nesting and Provider usage in demos/basic.py are correct. + - Confirm the documentation app entry and Docs renderer configuration are correct. +- **New**: Style Display Issues + - Check that the styles parameter format is correct. + - Confirm the style merging logic does not cause conflicts. + - Verify that the flexShrink property is not adversely affecting layout behavior. + +**Section Sources** + +- [frontend/antdx/welcome/Index.svelte:49-64](file://frontend/antdx/welcome/Index.svelte#L49-L64) +- [frontend/antdx/welcome/welcome.tsx:16-41](file://frontend/antdx/welcome/welcome.tsx#L16-L41) +- [docs/components/antdx/welcome/demos/basic.py:6-36](file://docs/components/antdx/welcome/demos/basic.py#L6-L36) +- [docs/helper/Docs.py:58-75](file://docs/helper/Docs.py#L58-L75) + +## Conclusion + +The Welcome component, through the collaboration of backend and frontend, provides concise yet powerful welcome page display capabilities. Its slot-based design and resource resolution mechanism enable flexible personalization and integration in diverse scenarios. Combined with the documentation system's example and rendering capabilities, developers can quickly understand and use this component. + +**Update** This style enhancement further improves the component's layout control capabilities and responsive design performance, providing developers with more granular style customization options and a better user experience. + +## Appendix + +### Usage Examples (Overview) + +- Create a basic welcome page with icon, title, and description. +- Use the borderless variant for a lighter interface style. +- Inject extra action buttons via slots to enhance user guidance. +- **New**: Leverage the enhanced style system for more granular layout control. + +Reference Example Script Path + +- [docs/components/antdx/welcome/demos/basic.py:6-36](file://docs/components/antdx/welcome/demos/basic.py#L6-L36) + +**Section Sources** + +- [docs/components/antdx/welcome/demos/basic.py:1-37](file://docs/components/antdx/welcome/demos/basic.py#L1-L37) + +### Properties and Events Reference (Overview) + +- Supported Slots: extra, icon, description, title. +- Key Properties: icon, title, description, variant (filled/borderless), styles and class names, visibility and DOM attributes. +- Events: No events defined in the current version. +- Lifecycle: skip_api is true; does not participate in the standard API flow. +- **New**: Style enhancement support providing richer layout control options. + +**Section Sources** + +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:12-15](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L12-L15) +- [backend/modelscope_studio/components/antdx/welcome/**init**.py:31-37](file://backend/modelscope_studio/components/antdx/welcome/__init__.py#L31-L37) diff --git a/.wiki/en/Base Components/Application Component.md b/.wiki/en/Base Components/Application Component.md new file mode 100644 index 00000000..f042d440 --- /dev/null +++ b/.wiki/en/Base Components/Application Component.md @@ -0,0 +1,424 @@ +# Application Component + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/base/application/__init__.py](file://backend/modelscope_studio/components/base/application/__init__.py) +- [frontend/base/application/Application.svelte](file://frontend/base/application/Application.svelte) +- [frontend/base/application/Index.svelte](file://frontend/base/application/Index.svelte) +- [backend/modelscope_studio/utils/dev/app_context.py](file://backend/modelscope_studio/utils/dev/app_context.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [docs/components/base/application/README-zh_CN.md](file://docs/components/base/application/README-zh_CN.md) +- [docs/components/base/application/README.md](file://docs/components/base/application/README.md) +- [docs/app.py](file://docs/app.py) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The Application component is the application root container for modelscope-studio, responsible for hosting and uniformly managing all components and dependencies exported from `modelscope_studio`. It not only provides the fundamental runtime environment for applications, but also helps developers implement page behavior monitoring, theme and language adaptation, and custom event bridging through lifecycle event and browser environment data collection capabilities. + +- As an application root container: Ensures all `modelscope_studio` components are properly wrapped; otherwise the page may fail to preview. +- Lifecycle and environment awareness: Provides events for page mount, window resize, page unload, etc.; can retrieve language, theme, UA, screen size, and scroll position. +- Custom event bridging: Trigger custom events on the frontend via `window.ms_globals.dispatch`; Python side can receive them through the `ms.Application.custom` event. + +Section Sources + +- [docs/components/base/application/README-zh_CN.md:1-11](file://docs/components/base/application/README-zh_CN.md#L1-L11) +- [docs/components/base/application/README.md:1-11](file://docs/components/base/application/README.md#L1-L11) + +## Project Structure + +The Application component consists of a backend Python component class and a frontend Svelte implementation, with tool modules providing context and base class support. Documentation and examples are located in the docs directory for demonstration and explanation. + +```mermaid +graph TB +subgraph "Backend" +PY_APP["ModelScopeApplication
Python Component Class"] +APP_CTX["AppContext
Application Context"] +BASE_META["ModelScopeDataLayoutComponent
Base Class"] +end +subgraph "Frontend" +IDX["Index.svelte
Async Import Entry"] +CMP["Application.svelte
Core Implementation"] +end +subgraph "Docs & Examples" +DOCS_ZH["README-zh_CN.md"] +DOCS_EN["README.md"] +DOCS_APP["docs/app.py"] +end +PY_APP --> BASE_META +PY_APP --> APP_CTX +IDX --> CMP +DOCS_APP --> DOCS_ZH +DOCS_APP --> DOCS_EN +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/application/Application.svelte:1-149](file://frontend/base/application/Application.svelte#L1-L149) +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) +- [backend/modelscope_studio/utils/dev/component.py:101-169](file://backend/modelscope_studio/utils/dev/component.py#L101-L169) +- [docs/components/base/application/README-zh_CN.md:1-56](file://docs/components/base/application/README-zh_CN.md#L1-L56) +- [docs/components/base/application/README.md:1-56](file://docs/components/base/application/README.md#L1-L56) +- [docs/app.py:1-595](file://docs/app.py#L1-L595) + +Section Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/application/Application.svelte:1-149](file://frontend/base/application/Application.svelte#L1-L149) +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) +- [backend/modelscope_studio/utils/dev/component.py:101-169](file://backend/modelscope_studio/utils/dev/component.py#L101-L169) +- [docs/components/base/application/README-zh_CN.md:1-56](file://docs/components/base/application/README-zh_CN.md#L1-L56) +- [docs/components/base/application/README.md:1-56](file://docs/components/base/application/README.md#L1-L56) +- [docs/app.py:1-595](file://docs/app.py#L1-L595) + +## Core Components + +- Backend component class: `ModelScopeApplication` inherits from `ModelScopeDataLayoutComponent`, providing event registration, data model, example data, and frontend directory resolution capabilities. +- Frontend implementation: `Application.svelte` initializes page data on mount, binds resize/unload events, and exposes `window.ms_globals.dispatch` for custom event bridging. +- Context and base class: `AppContext` provides application instance setting and assertion; `ModelScopeDataLayoutComponent` provides layout context and internal state management. + +Section Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [frontend/base/application/Application.svelte:1-149](file://frontend/base/application/Application.svelte#L1-L149) +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) +- [backend/modelscope_studio/utils/dev/component.py:101-169](file://backend/modelscope_studio/utils/dev/component.py#L101-L169) + +## Architecture Overview + +The Application component's runtime flow is as follows: the backend component class records the application instance during initialization; the frontend collects environment data and binds events during the mount phase; a custom event bridging channel is also provided. + +```mermaid +sequenceDiagram +participant Py as "Backend
ModelScopeApplication" +participant Ctx as "Context
AppContext" +participant FE as "Frontend
Application.svelte" +participant Win as "Browser
window" +Py->>Ctx : Set application instance +FE->>FE : onMount initialization +FE->>FE : Collect screen/language/theme/UA +FE->>Win : Bind resize/unload events +FE->>Py : Trigger mount/resize/unmount events +Win-->>FE : User calls window.ms_globals.dispatch(...) +FE->>Py : Trigger custom event +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:72-82](file://backend/modelscope_studio/components/base/application/__init__.py#L72-L82) +- [frontend/base/application/Application.svelte:87-129](file://frontend/base/application/Application.svelte#L87-L129) + +Section Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:72-82](file://backend/modelscope_studio/components/base/application/__init__.py#L72-L82) +- [frontend/base/application/Application.svelte:87-129](file://frontend/base/application/Application.svelte#L87-L129) + +## Detailed Component Analysis + +### Backend Component Class: ModelScopeApplication + +- Design philosophy + - As the application root container, uniformly injects the application context, ensuring all subsequent components depend on an existing Application instance. + - Registers `mount`/`resized`/`unmount`/`custom` event listeners through the Gradio event system, enabling frontend-backend coordination. + - Uses `ApplicationPageData` as the data model, carrying screen, language, theme, UA, and other environment information. +- Key features + - Event registration: EVENTS defines four event listeners corresponding to page lifecycle and custom events. + - Data model: `data_model` points to `ApplicationPageData`; example data `example_payload`/`example_value` provides defaults. + - Frontend directory: `FRONTEND_DIR` is resolved to the `base/application` frontend implementation via `resolve_frontend_dir`. +- Lifecycle and context + - Sets `AppContext` in `__init__`, then calls the parent constructor, ensuring context is available when the component tree is being built. + - `preprocess`/`postprocess` pass data through unchanged, allowing the frontend to consume directly. + +```mermaid +classDiagram +class ModelScopeApplication { ++EVENTS ++SLOTS ++FRONTEND_DIR ++data_model ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class ModelScopeDataLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__exit__() ++__init__(...) +} +class AppContext { ++set_app(app) ++has_app() ++assert_app() ++get_app() +} +ModelScopeApplication --|> ModelScopeDataLayoutComponent +ModelScopeApplication --> AppContext : "set/assert" +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/utils/dev/component.py:101-169](file://backend/modelscope_studio/utils/dev/component.py#L101-L169) +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) + +Section Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/utils/dev/component.py:101-169](file://backend/modelscope_studio/utils/dev/component.py#L101-L169) +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) + +### Frontend Implementation: Application.svelte + +- Key highlights + - onMount initialization: Updates value and dispatches mount event; then binds resize and beforeunload events. + - resize event: Uses debounce (default 500ms) to update value and dispatch resize event, avoiding high-frequency repaints. + - beforeunload: Updates value and dispatches unmount event before the page unloads. + - Custom event: `window.ms_globals.dispatch(...)` forwards the argument array as a custom event. + - Visibility and styles: Controls rendering based on `visible`; `elem_id`/`elem_classes`/`elem_style` support external style injection. +- Data model + - `ApplicationPageData` contains `language`, `userAgent`, `theme`, `screen` (width/height/scrollX/scrollY). +- Event model + - Four event types: `mount`/`resized`/`unmount`/`custom`, corresponding to page lifecycle and custom events. + +```mermaid +flowchart TD +Start(["Mount Start"]) --> Init["Initialize value
Collect language/theme/UA/screen"] +Init --> Bind["Bind resize/unload events"] +Bind --> MountEvt{"Is mount event bound?"} +MountEvt --> |Yes| DispatchMount["Dispatch mount event"] +MountEvt --> |No| Wait["Wait for user interaction"] +Wait --> ResizeEvt{"Window resized?"} +ResizeEvt --> |Yes| Debounce["Debounce (default 500ms)"] +Debounce --> UpdateResize["Update value and dispatch resize"] +ResizeEvt --> |No| UnloadEvt{"Page about to unload?"} +UnloadEvt --> |Yes| UpdateUnload["Update value and dispatch unmount"] +UnloadEvt --> |No| CustomEvt{"window.ms_globals.dispatch called?"} +CustomEvt --> |Yes| DispatchCustom["Dispatch custom event"] +CustomEvt --> |No| End(["End"]) +``` + +Diagram Sources + +- [frontend/base/application/Application.svelte:87-129](file://frontend/base/application/Application.svelte#L87-L129) + +Section Sources + +- [frontend/base/application/Application.svelte:1-149](file://frontend/base/application/Application.svelte#L1-L149) + +### Entry Wrapper: Index.svelte + +- Purpose: Asynchronously imports `Application.svelte` to delay component loading and reduce initial screen burden. +- Rendering: Passes `children` through to the Application component, ensuring content rendering. + +Section Sources + +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) + +### Context and Base Class Support + +- AppContext + - `set_app`: Sets the current application instance during backend initialization. + - `assert_app`: Issues a warning if not set, prompting that Application was not imported. + - `get_app`: Gets the current application instance. +- ModelScopeDataLayoutComponent + - Provides layout context and internal state (`_internal`), ensuring the component tree structure is correct. + - Inherits the Gradio component metaclass, supporting events and data flow. + +Section Sources + +- [backend/modelscope_studio/utils/dev/app_context.py:4-25](file://backend/modelscope_studio/utils/dev/app_context.py#L4-L25) +- [backend/modelscope_studio/utils/dev/component.py:101-169](file://backend/modelscope_studio/utils/dev/component.py#L101-L169) + +### Usage Examples and Scenarios + +- Basic usage: Wrap all `modelscope_studio` components inside Application to ensure preview and interaction work correctly. +- Language adaptation: Get the user's language via `value.language`, dynamically switching text or formatting. +- Theme adaptation: Return content or styles with different weights based on `value.theme`. +- Custom events: Call `window.ms_globals.dispatch(...)` in any JS logic; receive on the Python side via `ms.Application.custom`. + +**Python Code Examples** + +```python +import gradio as gr +import modelscope_studio.components.base as ms +import modelscope_studio.components.antd as antd + +# Example 1: Basic wrapping usage +with gr.Blocks() as demo: + with ms.Application(): + with antd.ConfigProvider(): + with ms.AutoLoading(): + antd.Button("Hello ModelScope Studio") + +demo.launch() +``` + +```python +import gradio as gr +import modelscope_studio.components.base as ms +import modelscope_studio.components.antd as antd + +# Example 2: Listen to page mount event and adapt language/theme +with gr.Blocks() as demo: + with ms.Application() as app: + with antd.ConfigProvider(): + output = gr.Textbox(label="Page Info") + + @app.mount + def on_mount(data: ms.ApplicationData): + # Get user language and theme + lang = data.value.language + theme = data.value.theme + return gr.update(value=f"Language: {lang}, Theme: {theme}") + +demo.launch() +``` + +```python +import gradio as gr +import modelscope_studio.components.base as ms +import modelscope_studio.components.antd as antd + +# Example 3: Listen to custom events (combined with window.ms_globals.dispatch) +with gr.Blocks() as demo: + with ms.Application() as app: + with antd.ConfigProvider(): + output = gr.Textbox(label="Custom Event") + # Frontend can trigger via window.ms_globals.dispatch({type: 'my_event', payload: {...}}) + + @app.custom + def on_custom(data: ms.ApplicationData): + event_type = data.value.type if data.value else None + return gr.update(value=f"Received custom event: {event_type}") + +demo.launch() +``` + +Section Sources + +- [docs/components/base/application/README-zh_CN.md:12-20](file://docs/components/base/application/README-zh_CN.md#L12-L20) +- [docs/components/base/application/README.md:12-20](file://docs/components/base/application/README.md#L12-L20) + +### API and Type Descriptions + +- Properties + - value: `ApplicationPageData`, page data. +- Events + - mount: Triggered when the page mounts. + - resize: Triggered when the window size changes. + - unmount: Triggered when the page unloads. + - custom: Triggered via `window.ms_globals.dispatch(...)`. +- Types + - `ApplicationPageScreenData`: width, height, scrollX, scrollY. + - `ApplicationPageData`: screen, language, theme, userAgent. + +Section Sources + +- [docs/components/base/application/README-zh_CN.md:24-55](file://docs/components/base/application/README-zh_CN.md#L24-L55) +- [docs/components/base/application/README.md:24-55](file://docs/components/base/application/README.md#L24-L55) +- [backend/modelscope_studio/components/base/application/**init**.py:12-115](file://backend/modelscope_studio/components/base/application/__init__.py#L12-L115) + +## Dependency Analysis + +- Backend dependencies + - Gradio data classes and event system: Used for event listener registration and data models. + - Utility modules: `AppContext`, `ModelScopeDataLayoutComponent` provide context and base class capabilities. +- Frontend dependencies + - Svelte lifecycle hooks: `onMount`/`onDestroy`. + - `svelte-i18n`: Gets localized language. + - Style utilities: `styleObject2String`, `classnames`. +- Documentation and examples + - `docs/app.py` builds the site menu and documentation index, locating the Application component documentation. + +```mermaid +graph LR +PY["ModelScopeApplication"] --> GR["Gradio Events/Data Classes"] +PY --> CTX["AppContext"] +PY --> META["ModelScopeDataLayoutComponent"] +FE["Application.svelte"] --> SV["Svelte Lifecycle"] +FE --> I18N["svelte-i18n"] +FE --> STY["Style Utilities"] +DOC["docs/app.py"] --> DZ["README-zh_CN.md"] +DOC --> DE["README.md"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:5-9](file://backend/modelscope_studio/components/base/application/__init__.py#L5-L9) +- [frontend/base/application/Application.svelte:1-149](file://frontend/base/application/Application.svelte#L1-L149) +- [docs/app.py:1-595](file://docs/app.py#L1-L595) + +Section Sources + +- [backend/modelscope_studio/components/base/application/**init**.py:5-9](file://backend/modelscope_studio/components/base/application/__init__.py#L5-L9) +- [frontend/base/application/Application.svelte:1-149](file://frontend/base/application/Application.svelte#L1-L149) +- [docs/app.py:1-595](file://docs/app.py#L1-L595) + +## Performance Considerations + +- Debounce strategy: The resize event uses 500ms debounce by default, reducing the risk of frequent reflows and event storms. +- Lazy loading: `Index.svelte` uses async imports, reducing initial screen resource pressure. +- Event binding: Dispatches events only when needed (`bind_*_event` or `attached_events` contains the corresponding event name), avoiding unnecessary event dispatches. +- Style and visibility: Controls rendering through `visible`; `elem_style` supports both string and object forms for flexible injection on demand. + +Section Sources + +- [frontend/base/application/Application.svelte:96-103](file://frontend/base/application/Application.svelte#L96-L103) +- [frontend/base/application/Index.svelte:5-7](file://frontend/base/application/Index.svelte#L5-L7) + +## Troubleshooting Guide + +- Page cannot preview + - Symptom: Components cannot render normally because Application is not wrapped. + - Resolution: Ensure all `modelscope_studio` components are wrapped by Application. +- Application instance not detected + - Symptom: Console warning appears, indicating Application component not found. + - Resolution: Check if Application is correctly imported and initialized from `modelscope_studio.components.base`. +- Events not triggering + - Symptom: `resize`/`mount`/`unmount`/`custom` events not triggering as expected. + - Resolution: Confirm the frontend has bound the corresponding event (`bind_*_event` or `attached_events` contains the event name); custom events must be triggered via `window.ms_globals.dispatch(...)`. +- Language/theme not taking effect + - Symptom: Language or theme not changing according to user environment. + - Resolution: Ensure the frontend correctly reads `navigator` and shared theme; if necessary, handle branching on the Python side based on `value.language`/`value.theme`. + +Section Sources + +- [docs/components/base/application/README-zh_CN.md:3-11](file://docs/components/base/application/README-zh_CN.md#L3-L11) +- [docs/components/base/application/README.md:3-11](file://docs/components/base/application/README.md#L3-L11) +- [backend/modelscope_studio/utils/dev/app_context.py:16-21](file://backend/modelscope_studio/utils/dev/app_context.py#L16-L21) +- [frontend/base/application/Application.svelte:91-115](file://frontend/base/application/Application.svelte#L91-L115) + +## Conclusion + +The Application component, as the application root container for modelscope-studio, bears the key responsibilities of context injection, lifecycle events, and environment data collection. Through the collaboration of the backend component class and frontend implementation, it provides a stable fundamental runtime environment for the entire application and supports flexible theme/language adaptation and custom event bridging. Following the best practices and troubleshooting recommendations in this document can effectively improve development efficiency and runtime stability. + +## Appendix + +- Version information: v2.0.0-beta.1 +- Related documentation: English and Chinese documentation for the Application component, including examples and API descriptions. + +Section Sources + +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [docs/components/base/application/README-zh_CN.md:1-56](file://docs/components/base/application/README-zh_CN.md#L1-L56) +- [docs/components/base/application/README.md:1-56](file://docs/components/base/application/README.md#L1-L56) diff --git a/.wiki/en/Base Components/AutoLoading Component.md b/.wiki/en/Base Components/AutoLoading Component.md new file mode 100644 index 00000000..d81e030e --- /dev/null +++ b/.wiki/en/Base Components/AutoLoading Component.md @@ -0,0 +1,339 @@ +# AutoLoading Component + + +**Files Referenced in This Document** +- [auto-loading.tsx](file://frontend/base/auto-loading/auto-loading.tsx) +- [Index.svelte](file://frontend/base/auto-loading/Index.svelte) +- [useLoadingStatus.ts](file://frontend/base/auto-loading/useLoadingStatus.ts) +- [auto-loading.less](file://frontend/base/auto-loading/auto-loading.less) +- [package.json](file://frontend/base/auto-loading/package.json) +- [gradio.config.js](file://frontend/base/auto-loading/gradio.config.js) +- [__init__.py](file://backend/modelscope_studio/components/base/auto_loading/__init__.py) +- [loading-status.svelte.ts](file://frontend/svelte-preprocess-react/svelte-contexts/loading-status.svelte.ts) +- [import.ts](file://frontend/svelte-preprocess-react/component/import.ts) +- [README.md](file://docs/components/base/auto_loading/README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +The AutoLoading component automatically adds loading feedback and error notifications to wrapped content when the Gradio frontend makes requests to the backend. It automatically collects the loading states of child components and displays loading animations or error information at the appropriate time, enhancing user experience. The component supports custom rendering slots, mask layers, timer display, and various configuration options, suitable for global fallback and fine-grained local control. + +## Project Structure + +AutoLoading's frontend implementation is located in the base component directory and includes a Svelte entry, React wrapper component, state hook, and style file; the backend Python component is responsible for declaring the frontend resource path and skipping API calls. The documentation provides component descriptions and example entries. + +```mermaid +graph TB +subgraph "Frontend (base/auto-loading)" +A["Index.svelte
Svelte Entry"] --> B["auto-loading.tsx
React Wrapper Component"] +B --> C["useLoadingStatus.ts
Loading State Hook"] +B --> D["auto-loading.less
Styles"] +A --> E["package.json
Export Config"] +A --> F["gradio.config.js
Build Config"] +end +subgraph "Backend (modelscope_studio/components/base/auto_loading)" +G["__init__.py
Declare Frontend Directory / Skip API"] +end +subgraph "Docs (docs/components/base/auto_loading)" +H["README.md
Usage Instructions & Examples"] +end +A -. integrates .-> B +A -. configures .-> E +A -. builds .-> F +G -. resources .-> A +H -. uses .-> A +``` + +**Diagram Sources** + +- [Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [auto-loading.tsx:1-179](file://frontend/base/auto-loading/auto-loading.tsx#L1-L179) +- [useLoadingStatus.ts:1-94](file://frontend/base/auto-loading/useLoadingStatus.ts#L1-L94) +- [auto-loading.less:1-28](file://frontend/base/auto-loading/auto-loading.less#L1-L28) +- [package.json:1-15](file://frontend/base/auto-loading/package.json#L1-L15) +- [gradio.config.js:1-4](file://frontend/base/auto-loading/gradio.config.js#L1-L4) +- [**init**.py:47-64](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L47-L64) +- [README.md:1-36](file://docs/components/base/auto_loading/README.md#L1-L36) + +**Section Sources** + +- [Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [auto-loading.tsx:1-179](file://frontend/base/auto-loading/auto-loading.tsx#L1-L179) +- [useLoadingStatus.ts:1-94](file://frontend/base/auto-loading/useLoadingStatus.ts#L1-L94) +- [auto-loading.less:1-28](file://frontend/base/auto-loading/auto-loading.less#L1-L28) +- [package.json:1-15](file://frontend/base/auto-loading/package.json#L1-L15) +- [gradio.config.js:1-4](file://frontend/base/auto-loading/gradio.config.js#L1-L4) +- [**init**.py:47-64](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L47-L64) +- [README.md:1-36](file://docs/components/base/auto_loading/README.md#L1-L36) + +## Core Components + +- Svelte entry (Index.svelte): Parses properties, gets configuration type and slots, injects loading state context, and renders the React wrapper component on demand. +- React wrapper component (auto-loading.tsx): Decides whether to show loading animation, mask, timer, and queue information based on loading state; displays closable error notifications in error state. +- Loading state hook (useLoadingStatus.ts): Maintains timer, ETA, and formatted time, deriving display data based on `ILoadingStatus`. +- Styles (auto-loading.less): Controls loading layer positioning, mask z-index, and error popup centering styles. +- Backend component (**init**.py): Declares the frontend directory, skips API calls, enabling direct use via frontend resource exports. +- Documentation (README.md): Explains the component's role, state meanings, default behavior, and example entry. + +**Section Sources** + +- [Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [auto-loading.tsx:25-176](file://frontend/base/auto-loading/auto-loading.tsx#L25-L176) +- [useLoadingStatus.ts:5-93](file://frontend/base/auto-loading/useLoadingStatus.ts#L5-L93) +- [auto-loading.less:1-28](file://frontend/base/auto-loading/auto-loading.less#L1-L28) +- [**init**.py:47-64](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L47-L64) +- [README.md:1-36](file://docs/components/base/auto_loading/README.md#L1-L36) + +## Architecture Overview + +AutoLoading's workflow revolves around "state collection — conditional rendering — UI display". The Svelte entry collects `ILoadingStatus` from child components via context; the React component selects loading animations or error notifications based on state and presents them via Ant Design components. + +```mermaid +sequenceDiagram +participant Child as "Child Component" +participant Bridge as "Loading State Bridge" +participant Auto as "AutoLoading (React)" +participant UI as "Ant Design Components" +Child->>Bridge : "setLoadingStatus(ILoadingStatus)" +Bridge-->>Auto : "loadingStatus (aggregated)" +Auto->>Auto : "useLoadingStatus() calculates ETA/timer" +Auto->>UI : "Render loading/error based on state" +UI-->>Auto : "User interaction (e.g. close error)" +Auto-->>Child : "Continue rendering child content" +``` + +**Diagram Sources** + +- [loading-status.svelte.ts:47-75](file://frontend/svelte-preprocess-react/svelte-contexts/loading-status.svelte.ts#L47-L75) +- [auto-loading.tsx:48-175](file://frontend/base/auto-loading/auto-loading.tsx#L48-L175) +- [useLoadingStatus.ts:17-81](file://frontend/base/auto-loading/useLoadingStatus.ts#L17-L81) + +## Detailed Component Analysis + +### Svelte Entry (Index.svelte) + +- Retrieves component properties, configuration type, and slots from the preprocessing context. +- Injects the generated `loadingStatus` context via `getLoadingStatus`, for consumption by the internal React component. +- Uses `importComponent` for lazy loading, ensuring the component loads only after global initialization is complete. +- Passes visibility, styles, class names, and other properties to the React wrapper component. + +Key points + +- On-demand rendering: Renders only when `visible` is true. +- Slots and configuration: `slots`, `configType`, `loadingStatus` passed as props. +- Key generation: Assigns a unique key to each loading state via `window.ms_globals.loadingKey`. + +**Section Sources** + +- [Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [import.ts:1-20](file://frontend/svelte-preprocess-react/component/import.ts#L1-L20) +- [loading-status.svelte.ts:47-75](file://frontend/svelte-preprocess-react/svelte-contexts/loading-status.svelte.ts#L47-L75) + +### React Wrapper Component (auto-loading.tsx) + +Responsibilities + +- Parses configuration type (currently supports `antd`), determining loading animation and error notification UI. +- Renders loading animation based on state (including mask, timer, progress/queue information). +- In error state, renders a closable error notification, clearing the internal instance after closing to avoid duplicate rendering. +- Supports custom slots: `render` (custom loading content), `errorRender` (custom error content), `loadingText` (custom loading text). + +Loading State Determination + +- `pending`/`generating` treated as loading; `completed`/`error` treated as ended. +- Dynamically displays progress and queue information when `progress` or `queue_position`/`queue_size` is present. +- Optional timer and ETA display. + +Style and Z-Index + +- Loading layer is absolutely positioned and covers the parent container; error notification is fixed and centered. +- Sets z-index based on theme token, ensuring mask and error notification layers are properly ordered. + +**Section Sources** + +- [auto-loading.tsx:25-176](file://frontend/base/auto-loading/auto-loading.tsx#L25-L176) +- [auto-loading.less:1-28](file://frontend/base/auto-loading/auto-loading.less#L1-L28) + +### Loading State Hook (useLoadingStatus.ts) + +Functionality + +- Maintains timer: Starts timing in `pending` state, stops in non-`pending` state. +- Calculates ETA and formats time: Combines `performance.now` and ETA field to calculate remaining time and elapsed time. +- Tracks old ETA: Records the old value when ETA updates and formats the new ETA. +- Returns state fields: `status`, `message`, `progress`, `queuePosition`, `queueSize`, `formattedEta`, `formattedTimer`. + +Performance Notes + +- Uses `requestAnimationFrame` loop to update timing, avoiding blocking the main thread. +- Uses `useMemoizedFn` to cache callbacks, reducing re-renders. + +**Section Sources** + +- [useLoadingStatus.ts:5-93](file://frontend/base/auto-loading/useLoadingStatus.ts#L5-L93) + +### Styles (auto-loading.less) + +Key points + +- Loading layer is absolutely positioned, covering the parent container, ensuring mask effect. +- Error notification is fixed-positioned and centered, avoiding layout jitter. +- Controls z-index and appearance via Ant Design class names and theme token. + +**Section Sources** + +- [auto-loading.less:1-28](file://frontend/base/auto-loading/auto-loading.less#L1-L28) + +### Backend Component (**init**.py) + +Key points + +- Declares frontend directory as `base/auto-loading`. +- Skips API calls; component is used only for frontend rendering and state collection. + +**Section Sources** + +- [**init**.py:47-64](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L47-L64) + +### Documentation (README.md) + +Key points + +- Component role: Automatically adds loading animations and error notifications to wrapped content. +- State descriptions: Four states — `pending`/`generating`/`completed`/`error`. +- Default behavior: `pending` starts loading; `generating`/`completed` ends; `error` ends loading (optionally shows error). +- API parameters: `generating`, `show_error`, `show_mask`, `show_timer`, `loading_text`, etc. + +**Section Sources** + +- [README.md:1-36](file://docs/components/base/auto_loading/README.md#L1-L36) + +## Dependency Analysis + +AutoLoading's dependencies are mainly reflected in the following aspects: + +- The Svelte entry depends on loading state context and import utilities, implementing lazy loading and state aggregation. +- The React component depends on Ant Design's Spin and Alert, and the theme token. +- `useLoadingStatus` depends on browser performance API and React hooks, implementing timing and state formatting. +- The backend component declares the frontend resource path, enabling the frontend component to load correctly through package exports. + +```mermaid +graph LR +Index["Index.svelte"] --> Import["import.ts
Lazy Loading"] +Index --> Ctx["loading-status.svelte.ts
Loading State Context"] +Index --> Auto["auto-loading.tsx"] +Auto --> Hook["useLoadingStatus.ts"] +Auto --> Less["auto-loading.less"] +Backend["__init__.py"] --> Index +Doc["README.md"] --> Index +``` + +**Diagram Sources** + +- [Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [import.ts:1-20](file://frontend/svelte-preprocess-react/component/import.ts#L1-L20) +- [loading-status.svelte.ts:1-75](file://frontend/svelte-preprocess-react/svelte-contexts/loading-status.svelte.ts#L1-L75) +- [auto-loading.tsx:1-179](file://frontend/base/auto-loading/auto-loading.tsx#L1-L179) +- [useLoadingStatus.ts:1-94](file://frontend/base/auto-loading/useLoadingStatus.ts#L1-L94) +- [auto-loading.less:1-28](file://frontend/base/auto-loading/auto-loading.less#L1-L28) +- [**init**.py:47-64](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L47-L64) +- [README.md:1-36](file://docs/components/base/auto_loading/README.md#L1-L36) + +**Section Sources** + +- [Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [auto-loading.tsx:1-179](file://frontend/base/auto-loading/auto-loading.tsx#L1-L179) +- [useLoadingStatus.ts:1-94](file://frontend/base/auto-loading/useLoadingStatus.ts#L1-L94) +- [auto-loading.less:1-28](file://frontend/base/auto-loading/auto-loading.less#L1-L28) +- [**init**.py:47-64](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L47-L64) +- [README.md:1-36](file://docs/components/base/auto_loading/README.md#L1-L36) + +## Performance Considerations + +- Deferred initialization: Using `importComponent` and the global initialization Promise avoids loading the component before it's ready, reducing initial screen pressure. +- Timer optimization: Uses `requestAnimationFrame` loop to update timing, reducing main thread usage; only starts timing in `pending` state. +- State aggregation: Only the innermost AutoLoading collects child component states, avoiding duplicate rendering and state conflicts. +- Style z-index: Ensures mask and error notifications don't cause layout reflows through z-index and absolute positioning. +- Custom rendering: Through `render` and `errorRender` slots, business teams can optimize loading and error UI themselves, reducing unnecessary component overhead. + +[This section is general performance recommendations; no "Section Sources" needed] + +## Troubleshooting Guide + +Common Issues and Solutions + +- Multiple nested AutoLoading: According to the documentation, only the innermost layer can collect child component states and display loading animations. If outer layers don't work, check the nesting level. +- Error notification not disappearing: The error notification is a closable component; the internal instance is cleared after closing. If still displayed, check if the close logic or styles are causing visual residue. +- Loading animation not appearing: Confirm whether `loadingStatus` enters `pending`/`generating` state; check if `generating`/`show_error` configuration meets expectations. +- Timer not updating: Timing only starts in `pending` state; if there's no `pending` state for a long time, the timer won't start. +- Mask z-index anomalies: Styles control z-index via theme token; if custom styles override `z-index`, check style priority. + +**Section Sources** + +- [README.md:5-19](file://docs/components/base/auto_loading/README.md#L5-L19) +- [auto-loading.tsx:139-166](file://frontend/base/auto-loading/auto-loading.tsx#L139-L166) +- [useLoadingStatus.ts:44-50](file://frontend/base/auto-loading/useLoadingStatus.ts#L44-L50) + +## Conclusion + +AutoLoading provides unified and customizable loading and error feedback capabilities for Gradio applications through the "state collection — conditional rendering — UI display" mechanism. Its deferred initialization and timer optimization help improve performance and experience; slots and configuration options meet diverse business needs. Combined with documentation and examples, it can be used flexibly in both global and local scenarios. + +[This section is summary content; no "Section Sources" needed] + +## Appendix + +### API Definitions (Parameters and Behavior) + +- generating: Whether to include `generating` state handling. +- show_error: Whether to display error information. +- show_mask: Whether to display the mask. +- show_timer: Whether to display the timer. +- loading_text: Custom loading text; when empty, uses the default text provided by Gradio (including elapsed time, queue position, etc.). + +Default Behavior + +- pending: Show loading animation. +- generating/completed: End loading animation. +- error: End loading animation; optionally show error information. + +**Section Sources** + +- [README.md:27-36](file://docs/components/base/auto_loading/README.md#L27-L36) +- [auto-loading.tsx:65-138](file://frontend/base/auto-loading/auto-loading.tsx#L65-L138) + +### Usage Examples (Scenarios and Recommendations) + +- Global fallback: Place one AutoLoading at the application root to ensure any request gets loading feedback. +- Fine-grained local control: Use separately in areas that need richer loading information, with custom display via `render` and `loadingText` slots. +- Error visibility: Control error information display via `show_error`; use `errorRender` to customize error UI when necessary. +- Queue and progress: When the backend uses `yield` for streaming returns, use `progress` and queue information to enhance user perception. + +**Section Sources** + +- [README.md:21-25](file://docs/components/base/auto_loading/README.md#L21-L25) +- [auto-loading.tsx:72-138](file://frontend/base/auto-loading/auto-loading.tsx#L72-L138) + +### Collaboration Patterns with Other Components + +- Collaboration with forms/lists: Using AutoLoading inside these components provides consistent loading and error feedback. +- Collaboration with the theme system: Controls mask and error notification z-index and appearance via Ant Design theme token. +- Collaboration with state context: Through the loading state context, states from multiple child components are aggregated; the nearest AutoLoading decides what to display. + +**Section Sources** + +- [Index.svelte:56-62](file://frontend/base/auto-loading/Index.svelte#L56-L62) +- [loading-status.svelte.ts:47-75](file://frontend/svelte-preprocess-react/svelte-contexts/loading-status.svelte.ts#L47-L75) +- [auto-loading.tsx:68-134](file://frontend/base/auto-loading/auto-loading.tsx#L68-L134) diff --git a/.wiki/en/Base Components/Base Components.md b/.wiki/en/Base Components/Base Components.md new file mode 100644 index 00000000..cecdd060 --- /dev/null +++ b/.wiki/en/Base Components/Base Components.md @@ -0,0 +1,505 @@ +# Base Components + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/base/application/__init__.py](file://backend/modelscope_studio/components/base/application/__init__.py) +- [backend/modelscope_studio/components/base/auto_loading/__init__.py](file://backend/modelscope_studio/components/base/auto_loading/__init__.py) +- [backend/modelscope_studio/components/base/slot/__init__.py](file://backend/modelscope_studio/components/base/slot/__init__.py) +- [backend/modelscope_studio/components/base/fragment/__init__.py](file://backend/modelscope_studio/components/base/fragment/__init__.py) +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [frontend/base/application/Index.svelte](file://frontend/base/application/Index.svelte) +- [frontend/base/auto-loading/Index.svelte](file://frontend/base/auto-loading/Index.svelte) +- [frontend/base/slot/Index.svelte](file://frontend/base/slot/Index.svelte) +- [frontend/base/fragment/Index.svelte](file://frontend/base/fragment/Index.svelte) +- [frontend/base/each/Index.svelte](file://frontend/base/each/Index.svelte) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/renderParamsSlot.tsx](file://frontend/utils/renderParamsSlot.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the "Base Components" system of ModelScope Studio, systematically explaining the design philosophy, data and control flow, role and collaboration within the overall component system, as well as providing usage examples, best practices, performance optimization suggestions, and solutions to common issues for core components such as Application, AutoLoading, Slot, and Fragment. The goal is to help developers quickly understand and correctly use these base components to build complex interfaces. + +## Project Structure + +The base components sit between the backend Python modules and the frontend Svelte implementations, bridged through a unified component base class and context mechanism. The backend is responsible for defining component classes, event and slot capabilities, data models, and lifecycle hooks; the frontend handles rendering, slot parsing, state management, and async loading. + +```mermaid +graph TB +subgraph "Backend" +PY_APP["Application Component
application/__init__.py"] +PY_AUTO["AutoLoading Component
auto_loading/__init__.py"] +PY_SLOT["Slot Component
slot/__init__.py"] +PY_FRAG["Fragment Component
fragment/__init__.py"] +PY_BASE_INIT["Base Component Exports
base/__init__.py"] +PY_DEV_COMP["Component Base Class
utils/dev/component.py"] +end +subgraph "Frontend" +FE_APP["Application Frontend Entry
base/application/Index.svelte"] +FE_AUTO["AutoLoading Frontend Entry
base/auto-loading/Index.svelte"] +FE_SLOT["Slot Frontend Entry
base/slot/Index.svelte"] +FE_FRAG["Fragment Frontend Entry
base/fragment/Index.svelte"] +FE_EACH["Each Frontend Entry
base/each/Index.svelte"] +FE_RENDER_SLOT["renderSlot Utility
utils/renderSlot.tsx"] +FE_RENDER_PARAMS_SLOT["renderParamsSlot Utility
utils/renderParamsSlot.tsx"] +end +PY_APP --> FE_APP +PY_AUTO --> FE_AUTO +PY_SLOT --> FE_SLOT +PY_FRAG --> FE_FRAG +PY_BASE_INIT --> PY_APP +PY_BASE_INIT --> PY_AUTO +PY_BASE_INIT --> PY_SLOT +PY_BASE_INIT --> PY_FRAG +PY_DEV_COMP --> PY_APP +PY_DEV_COMP --> PY_AUTO +PY_DEV_COMP --> PY_SLOT +PY_DEV_COMP --> PY_FRAG +FE_SLOT --> FE_RENDER_SLOT +FE_SLOT --> FE_RENDER_PARAMS_SLOT +FE_AUTO --> FE_EACH +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:8-65](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L8-L65) +- [backend/modelscope_studio/components/base/slot/**init**.py:8-50](file://backend/modelscope_studio/components/base/slot/__init__.py#L8-L50) +- [backend/modelscope_studio/components/base/fragment/**init**.py:8-49](file://backend/modelscope_studio/components/base/fragment/__init__.py#L8-L49) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +**Section Sources** + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +## Core Components + +This section provides an overview of the roles, features, and usage of Application, AutoLoading, Slot, Fragment, and Each. + +- Application (Application Container) + - Role: Acts as the top-level layout container, handling page-level event bindings (custom events, mount, window resize, unmount) and providing page environment data (screen size, language, theme, UA). + - Key points: Supports event listener registration; serves as the application context root node, ensuring all child components are created within a valid application context. + - Typical usage: Placed at the application entry point, with other base or business components nested inside; event listeners handle browser lifecycle and interaction events. + +- AutoLoading (Auto-Loading Placeholder) + - Role: Automatically switches between loading state, error state, and content rendering based on generation state, error state, and mask/timer configurations; supports named slots (render, errorRender, loadingText) for flexible customization. + - Key points: `skip_api` is marked true to avoid duplicate API calls; reads loading state from the frontend context and links to slot rendering. + - Typical usage: Wraps content areas that need lazy loading or conditional rendering; dynamically set `generating`/`showError` based on business logic. + +- Slot (Slot) + - Role: Declares and registers named slots, supports parameter mapping functions, bridges DOM slots with React/JSX content; can be nested to form hierarchical slot keys. + - Key points: Sets slot key and parameter mapping via context; at render time, utility functions clone and inject slot content into target elements. + - Typical usage: Declare slots in parent components and render them on demand in child components; used for complex layouts and conditional rendering. + +- Fragment (Fragment) + - Role: Lightweight container that does not introduce additional DOM wrappers; only holds child nodes and slots; commonly used for conditional rendering, list item wrapping, etc. + - Key points: `skip_api` is marked true; does not trigger extra rendering overhead; can be used with Each/Slot. + - Typical usage: Used as list item containers in Each; wraps multiple child nodes in conditional branches without adding extra levels. + +- Each (List Rendering) + - Role: Provides bulk rendering capabilities for list or array data, mapping each element in the list with corresponding slots/Fragments for parameter mapping and rendering. + - Key points: Frontend-only rendering component with no corresponding backend Python class; used with Fragment for list item rendering, and with Slot for parameter-mapped slots. + - Parameter mapping: Through the Slot's `params_mapping` property, injects the current item and index of list elements into child component slots. + - Typical usage: Wrap `ms.Each` inside parent components that support item rendering, using `ms.Fragment` and `ms.Slot` (with `params_mapping`) to achieve dynamic list rendering. + +**Section Sources** + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:8-65](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L8-L65) +- [backend/modelscope_studio/components/base/slot/**init**.py:8-50](file://backend/modelscope_studio/components/base/slot/__init__.py#L8-L50) +- [backend/modelscope_studio/components/base/fragment/**init**.py:8-49](file://backend/modelscope_studio/components/base/fragment/__init__.py#L8-L49) +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +## Architecture Overview + +The diagram below shows the overall call chain and collaboration relationships between base components from backend to frontend. + +```mermaid +sequenceDiagram +participant PyApp as "Backend Application" +participant PyAuto as "Backend AutoLoading" +participant PySlot as "Backend Slot" +participant PyFrag as "Backend Fragment" +participant FeApp as "Frontend Application" +participant FeAuto as "Frontend AutoLoading" +participant FeSlot as "Frontend Slot" +participant FeFrag as "Frontend Fragment" +participant Utils as "Render Utilities (renderSlot/renderParamsSlot)" +PyApp->>FeApp : Initialize and bind events +PyAuto->>FeAuto : Configure generate/error/mask/text +PySlot->>FeSlot : Register slot key and parameter mapping +FeSlot->>Utils : Render slot (cloneable/force clone/with params) +Utils-->>FeSlot : Return ReactSlot render result +PyFrag->>FeFrag : Act as container for child nodes +FeAuto->>FeFrag : Switch between loading/error/content +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:8-65](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L8-L65) +- [backend/modelscope_studio/components/base/slot/**init**.py:8-50](file://backend/modelscope_studio/components/base/slot/__init__.py#L8-L50) +- [backend/modelscope_studio/components/base/fragment/**init**.py:8-49](file://backend/modelscope_studio/components/base/fragment/__init__.py#L8-L49) +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +## Detailed Component Analysis + +### Application Component + +- Design philosophy + - As the application-level root container, centrally handles browser lifecycle events and page environment information, providing a consistent runtime context for upper-layer components. + - Extends application behavior boundaries through event listeners, such as custom event dispatch, mount/unmount callbacks, and window resize responses. +- Data model + - Page screen data (width/height, scroll position), language, theme, user agent, etc., enabling frontend adaptation to different devices and themes. +- Frontend implementation highlights + - Asynchronously imports the actual component, delaying rendering to improve initial screen performance. + - Passes `children` through to child components, maintaining flexibility in the tree structure. +- Usage example path + - Create Application at the application entry and organize the page layout and business components inside it. + - Example reference: [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) + +```mermaid +classDiagram +class ModelScopeApplication { ++EVENTS ++SLOTS ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class ModelScopeDataLayoutComponent { ++skip_api ++__exit__() ++__init__(...) +} +ModelScopeApplication --|> ModelScopeDataLayoutComponent : "inherits" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [backend/modelscope_studio/utils/dev/component.py:101-169](file://backend/modelscope_studio/utils/dev/component.py#L101-L169) + +**Section Sources** + +- [backend/modelscope_studio/components/base/application/**init**.py:26-115](file://backend/modelscope_studio/components/base/application/__init__.py#L26-L115) +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) + +### AutoLoading Component + +- Design philosophy + - Automates handling of "generating/error/loading text" states, reducing boilerplate code on the business side; highly customizable through slots. +- Key properties + - generating: Whether currently in generating state + - show_error: Whether to display error state + - show_mask/show_timer: Mask and timer toggles + - loading_text: Custom loading text + - Supported slots: render, errorRender, loadingText +- Frontend implementation highlights + - Reads loading state from context to determine which type of content to render. + - Maps backend-passed properties and slots to frontend components via `processProps` and `getSlots`. +- Usage example path + - Wrap areas that need lazy loading or conditional rendering with AutoLoading, and switch `generating`/`showError` based on business state. + - Example reference: [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) + +```mermaid +flowchart TD +Start(["Enter AutoLoading"]) --> CheckVisible["Check Visibility"] +CheckVisible --> |Not Visible| End(["End"]) +CheckVisible --> |Visible| ReadCtx["Read Loading State (generating/error)"] +ReadCtx --> Decide{"Choose Content to Render"} +Decide --> |Generating| RenderLoading["Render loadingText Slot"] +Decide --> |Error| RenderError["Render errorRender Slot"] +Decide --> |Normal| RenderContent["Render render Slot / Default Content"] +RenderLoading --> End +RenderError --> End +RenderContent --> End +``` + +**Diagram Sources** + +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) + +**Section Sources** + +- [backend/modelscope_studio/components/base/auto_loading/**init**.py:8-65](file://backend/modelscope_studio/components/base/auto_loading/__init__.py#L8-L65) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) + +### Slot Component + +- Design philosophy + - Provides named slot and parameter mapping capabilities, bridging Svelte slots with React/JSX rendering; supports nested slot keys and dynamic parameters. +- Key properties + - value: Slot key name (supports nesting) + - params_mapping: Parameter mapping function string, converted to a function at runtime +- Frontend implementation highlights + - Sets the current slot key and parameter mapping function via context. + - Uses `renderSlot`/`renderParamsSlot` to clone and inject slot content into target elements, supporting force clone and multi-target rendering. +- Usage example path + - Declare Slot in parent components and render on demand in child components; or use with parameter mapping in Each for dynamic rendering. + - Example references: [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68), [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29), [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +```mermaid +sequenceDiagram +participant Parent as "Parent Component (Slot)" +participant Ctx as "Slot Context" +participant Utils as "renderSlot/renderParamsSlot" +participant Child as "Child Component" +Parent->>Ctx : Set slot key and parameter mapping +Parent->>Utils : Request slot rendering (cloneable/force clone/with params) +Utils-->>Parent : Return ReactSlot render result +Parent->>Child : Pass through render result +``` + +**Diagram Sources** + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +**Section Sources** + +- [backend/modelscope_studio/components/base/slot/**init**.py:8-50](file://backend/modelscope_studio/components/base/slot/__init__.py#L8-L50) +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +### Fragment Component + +- Design philosophy + - Acts as a lightweight container without introducing additional DOM wrappers; only holds child nodes and slots; suitable for conditional rendering and list item wrapping. +- Frontend implementation highlights + - Asynchronously imports the actual component via lazy loading; renders only when visibility is true. + - Does not reset the slot key, avoiding impact on sibling nodes' slot state. +- Usage example path + - Used as list item container in Each or conditional rendering; prefer Fragment when a wrapper-free container is needed. + - Example reference: [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + +```mermaid +flowchart TD +Enter(["Enter Fragment"]) --> Visible{"Is Visible?"} +Visible --> |No| Exit(["Exit"]) +Visible --> |Yes| AsyncLoad["Async Load Fragment Component"] +AsyncLoad --> Render["Render Child Nodes / Slots"] +Render --> Exit +``` + +**Diagram Sources** + +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + +**Section Sources** + +- [backend/modelscope_studio/components/base/fragment/**init**.py:8-49](file://backend/modelscope_studio/components/base/fragment/__init__.py#L8-L49) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + +### Each Component + +- Design philosophy + - Each is a lightweight frontend component designed for list rendering with no corresponding backend Python class. It allows batch instantiation of child components based on array data, and with Fragment and Slot can achieve parameterized dynamic rendering. +- Using with Fragment + - Use Fragment as a lightweight container for each item in Each, avoiding the introduction of additional DOM wrapper levels. + - Fragment's `visible` controls whether the current item renders, suitable for conditional lists. + - Typical usage: When displaying list elements, render each item in the list container into a Fragment. +- Parameter Mapping (params_mapping) + - Set the `params_mapping` property on the Slot component to inject the current item value (item) and index (index) into the slot content. + - `params_mapping` is a JavaScript string function, converted to a function at runtime, accepting `(item, index)` and returning a slot parameter object. + - Example: `params_mapping="lambda item, index: {'children': item['label']}"` renders each item's label field as children. +- Frontend implementation highlights + - Each passes list elements to child component slots by merging context values with item values. + - Supports nested Each; inner layers use `subIndex` to prevent slot key conflicts. + - Can configure `forceClone` when needed, ensuring each item has an independent slot instance. + - Example reference: [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +```mermaid +sequenceDiagram +participant PY as "Backend Parent Component (items property)" +participant Each as "Each (Frontend)" +participant Frag as "Fragment (Frontend)" +participant Slot as "Slot (params_mapping)" +participant Child as "Child Component Slot" +PY->>Each : Pass in items array +Each->>Frag : Create Fragment for each item +Frag->>Slot : Enter named slot +Slot->>Child : params_mapping injects item/index into child component +Child-->>Each : Render list item UI +``` + +**Diagram Sources** + +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +**Section Sources** + +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + +### Component Base Classes and Context + +- ModelScopeLayoutComponent / ModelScopeComponent / ModelScopeDataLayoutComponent + - Uniformly handles component lifecycle, styles, and internal indices; participates in layout tree management under BlockContext. + - `skip_api` controls whether to skip API-level duplicate rendering or processing. +- AppContext + - Ensures all base components are created within a valid application context, avoiding runtime errors. + +```mermaid +classDiagram +class ModelScopeComponent { ++EVENTS ++skip_api ++__init__(...) +} +class ModelScopeLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__exit__() ++__init__(...) +} +class ModelScopeDataLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__exit__() ++__init__(...) +} +ModelScopeLayoutComponent --|> ModelScopeComponent : "inherits" +ModelScopeDataLayoutComponent --|> ModelScopeComponent : "inherits" +ModelScopeDataLayoutComponent --|> BlockContext : "mixes in" +``` + +**Diagram Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +**Section Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +## Dependency Analysis + +- Backend exports + - Base components are exported via `base/__init__.py`, providing a unified external interface for upper modules to import as needed. +- Inter-component coupling + - Application acts as the root container, with other components organized around it; AutoLoading and Fragment are commonly used as generic containers; Slot is the core for cross-component slot bridging. +- External dependencies + - Frontend uses `@svelte-preprocess-react` and the context system to bridge Svelte and React; rendering utilities provide slot cloning and parameter injection capabilities. + +```mermaid +graph LR +Export["base/__init__.py Exports"] --> App["Application"] +Export --> Auto["AutoLoading"] +Export --> Slot["Slot"] +Export --> Frag["Fragment"] +App --> FeApp["frontend/base/application/Index.svelte"] +Auto --> FeAuto["frontend/base/auto-loading/Index.svelte"] +Slot --> FeSlot["frontend/base/slot/Index.svelte"] +Frag --> FeFrag["frontend/base/fragment/Index.svelte"] +FeSlot --> RenderSlot["utils/renderSlot.tsx"] +FeSlot --> RenderParams["utils/renderParamsSlot.tsx"] +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +**Section Sources** + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +## Performance Considerations + +- Lazy loading and visibility control + - Application/AutoLoading/Fragment all use async import and visibility checks, reducing initial screen rendering pressure. +- Slot rendering optimization + - When using `renderSlot`/`renderParamsSlot`, properly set `clone`/`forceClone` and `params` to avoid unnecessary duplicate rendering. +- Each list rendering + - Each supports merged values and context; force clone when necessary to ensure independent state; maintain `slotKey` and `subIndex` in nested Each to avoid slot key conflicts. +- Event binding + - Application's event listeners are only enabled when needed, avoiding unnecessary event handling overhead. + +[This section is general guidance; no specific file references needed] + +## Troubleshooting Guide + +- Slot not working + - Check if the Slot's `value` is correctly set, and if the parent component has registered the corresponding slot key. + - Confirm that `renderSlot`/`renderParamsSlot` parameters are correctly passed (`clone`/`forceClone`/`params`). + - Reference: [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68), [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29), [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- AutoLoading not switching as expected + - Confirm that `generating`/`showError` state is correctly passed to the frontend; check if slot names match (render/errorRender/loadingText). + - Reference: [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- Fragment not rendering + - Check `visible` property and whether async loading is complete; confirm `shouldResetSlotKey` is not misused, causing slot key loss. + - Reference: [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- Each list misalignment or slot conflicts + - Ensure Each's context values and item values are correctly merged; maintain `subIndex` and `slotKey` in nested Each. + - Reference: [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +**Section Sources** + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) +- [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) +- [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) +- [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + +## Conclusion + +The base component system uses Application as the root, AutoLoading as the generic container, Slot as the cross-component bridge, and Fragment as the lightweight container, combined with a unified component base class and context mechanism. This achieves an architecture design with frontend-backend coordination, decoupled events and slots, and controllable rendering performance. By following the best practices and troubleshooting recommendations in this document, developers can efficiently use these components to build complex, high-performance interfaces. + +[This section is summary content; no specific file references needed] + +## Appendix + +- Quick Start Checklist + - Place Application at the application entry to ensure global context is available. + - Use AutoLoading for areas that need lazy loading, and switch between generate/error states based on business logic. + - Use Slot to declare named slots, and render them with `renderSlot`/`renderParamsSlot`. + - Use Fragment as a wrapper-free container in list or conditional rendering. +- Related Implementation Reference Paths + - [frontend/base/application/Index.svelte:1-17](file://frontend/base/application/Index.svelte#L1-L17) + - [frontend/base/auto-loading/Index.svelte:1-81](file://frontend/base/auto-loading/Index.svelte#L1-L81) + - [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) + - [frontend/base/fragment/Index.svelte:1-50](file://frontend/base/fragment/Index.svelte#L1-L50) + - [frontend/base/each/Index.svelte:1-111](file://frontend/base/each/Index.svelte#L1-L111) + - [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) + - [frontend/utils/renderParamsSlot.tsx:1-51](file://frontend/utils/renderParamsSlot.tsx#L1-L51) + +[This section is supplementary material; no specific file references needed] diff --git a/.wiki/en/Base Components/Fragment Component.md b/.wiki/en/Base Components/Fragment Component.md new file mode 100644 index 00000000..9a4677fb --- /dev/null +++ b/.wiki/en/Base Components/Fragment Component.md @@ -0,0 +1,328 @@ +# Fragment Component + + +**Files Referenced in This Document** +- [frontend/base/fragment/fragment.tsx](file://frontend/base/fragment/fragment.tsx) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js) +- [backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js](file://backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js) +- [docs/components/base/fragment/README.md](file://docs/components/base/fragment/README.md) +- [docs/components/base/fragment/README-zh_CN.md](file://docs/components/base/fragment/README-zh_CN.md) +- [docs/components/base/fragment/demos/basic.py](file://docs/components/base/fragment/demos/basic.py) +- [frontend/svelte-preprocess-react/react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/renderItems.tsx](file://frontend/utils/renderItems.tsx) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/utils/style.ts](file://frontend/utils/style.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +Fragment is a "fragment" container component designed to combine multiple child elements into a whole without introducing additional DOM nodes, allowing them to be used as insertable content in slots that only accept model-internal components. It is commonly used to wrap components from external ecosystems (such as Gradio buttons) into forms that comply with model-internal component specifications, enabling them to enter the component tree smoothly. + +- Design purpose: Avoid introducing redundant container nodes in the layout while maintaining the logical grouping and passing of child nodes. +- Use cases: When a component slot only supports components exported from a specific ecosystem, wrap the unsupported component with Fragment before passing it in. +- Advantages: Reduces unnecessary DOM levels, lowering layout overhead; maintains the directness and maintainability of child nodes. + +## Project Structure + +Fragment has corresponding implementations and templates in both the frontend and backend, combined with the React Slot mechanism to complete cross-framework bridging and rendering. + +```mermaid +graph TB +subgraph "Frontend" +FE_Fragment["frontend/base/fragment/fragment.tsx"] +FE_ReactSlot["frontend/svelte-preprocess-react/react-slot.tsx"] +FE_RenderSlot["frontend/utils/renderSlot.tsx"] +FE_RenderItems["frontend/utils/renderItems.tsx"] +FE_Style["frontend/utils/style.ts"] +end +subgraph "Backend Templates" +BE_Fragment["backend/.../fragment-sXw8Jnlf.js"] +BE_EachFragment["backend/.../fragment-BaGnla3s.js"] +end +subgraph "Docs & Examples" +DOC_Readme["docs/components/base/fragment/README.md"] +DOC_ReadmeCN["docs/components/base/fragment/README-zh_CN.md"] +DEMO_Basic["docs/components/base/fragment/demos/basic.py"] +end +FE_Fragment --> BE_Fragment +FE_Fragment --> BE_EachFragment +FE_ReactSlot --> FE_RenderSlot +FE_RenderItems --> FE_ReactSlot +FE_RenderSlot --> FE_ReactSlot +FE_Style --> FE_ReactSlot +DOC_Readme --> DEMO_Basic +DOC_ReadmeCN --> DEMO_Basic +``` + +Diagram Sources + +- [frontend/base/fragment/fragment.tsx:1-11](file://frontend/base/fragment/fragment.tsx#L1-L11) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:437-445](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L437-L445) +- [backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js:1-11](file://backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js#L1-L11) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/style.ts:1-77](file://frontend/utils/style.ts#L1-L77) +- [docs/components/base/fragment/README.md:1-10](file://docs/components/base/fragment/README.md#L1-L10) +- [docs/components/base/fragment/README-zh_CN.md:1-10](file://docs/components/base/fragment/README-zh_CN.md#L1-L10) +- [docs/components/base/fragment/demos/basic.py:1-22](file://docs/components/base/fragment/demos/basic.py#L1-L22) + +Section Sources + +- [frontend/base/fragment/fragment.tsx:1-11](file://frontend/base/fragment/fragment.tsx#L1-L11) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:437-445](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L437-L445) +- [docs/components/base/fragment/README.md:1-10](file://docs/components/base/fragment/README.md#L1-L10) + +## Core Components + +- Frontend Fragment (React wrapper) + - Bridges Svelte component capabilities to the React ecosystem via `sveltify`, passing `children` through as a React Fragment internally without introducing extra DOM. + - Typical path: [frontend/base/fragment/fragment.tsx:4-8](file://frontend/base/fragment/fragment.tsx#L4-L8) + +- Backend Fragment (runtime template) + - Generates a runtime wrapper for React Fragment for the bridging layer to render, ensuring `children` are mounted as a fragment. + - Typical path: [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:437-441](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L437-L441) + +- Backend Each Fragment (Svelte template) + - Fragment implementation for Svelte, enabling reuse of fragment semantics in Svelte scenarios. + - Typical path: [backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js:2-6](file://backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js#L2-L6) + +Section Sources + +- [frontend/base/fragment/fragment.tsx:1-11](file://frontend/base/fragment/fragment.tsx#L1-L11) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:437-445](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L437-L445) +- [backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js:1-11](file://backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js#L1-L11) + +## Architecture Overview + +Fragment's workflow revolves around "fragment container + React Slot + context bridging": the frontend Fragment passes `children` through as a React Fragment; ReactSlot clones Svelte/HTML structures and mounts them to the React subtree in a "display contents" manner, avoiding extra container nodes; the rendering utility chain handles merging and application of parameters, events, and styles during bridging. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant MS as "Model Component Tree" +participant Frag as "Fragment (React)" +participant RS as "ReactSlot" +participant Bridge as "Bridging Layer (Backend Template)" +participant DOM as "Browser DOM" +Dev->>MS : "Place Fragment in slot" +MS->>Frag : "Receive children" +Frag->>Frag : "Pass children through as React Fragment" +Frag->>RS : "Create Slot rendering via bridging layer" +RS->>Bridge : "Request cloning/mounting of Svelte/HTML structure" +Bridge-->>RS : "Return fragmented children" +RS->>DOM : "Mount with display: contents, no extra container" +RS-->>Dev : "Rendering complete" +``` + +Diagram Sources + +- [frontend/base/fragment/fragment.tsx:4-8](file://frontend/base/fragment/fragment.tsx#L4-L8) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:437-441](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L437-L441) + +## Detailed Component Analysis + +### Component Class Diagram (Code Level) + +```mermaid +classDiagram +class Fragment_Frontend { ++children? : ReactNode ++renders : React.Fragment(children) +} +class ReactSlot { ++slot : HTMLElement ++clone? : boolean ++className? : string ++style? : CSSProperties ++render() : ReactElement[] +} +class BridgeRuntime { ++reactComponent : React.FC ++props : any ++children : ReactNode[] ++createPortal(node, target) +} +Fragment_Frontend --> ReactSlot : "renders via bridging layer" +ReactSlot --> BridgeRuntime : "clone/mount fragment" +BridgeRuntime --> ReactSlot : "return fragment children" +``` + +Diagram Sources + +- [frontend/base/fragment/fragment.tsx:4-8](file://frontend/base/fragment/fragment.tsx#L4-L8) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:305-328](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L305-L328) + +Section Sources + +- [frontend/base/fragment/fragment.tsx:1-11](file://frontend/base/fragment/fragment.tsx#L1-L11) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:250-328](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L250-L328) + +### Rendering Flow (Fragment Mounting) + +- ReactSlot clones the target element as a "display contents" node during mounting, avoiding extra container levels. +- If clone mode is enabled, recursively clones child nodes and event listeners, mounting the React subtree into the cloned node via Portal. +- Finally presented as `display: contents`, allowing child nodes to directly participate in the parent container's layout calculations. + +```mermaid +flowchart TD +Start(["Start"]) --> CheckClone{"Clone enabled?"} +CheckClone --> |No| MountDirect["Mount directly with display: contents"] +CheckClone --> |Yes| CloneTree["Clone node tree
Copy event listeners"] +CloneTree --> PortalAttach["Mount React subtree via Portal"] +PortalAttach --> MountDirect +MountDirect --> ApplyStyles["Apply styles/class names"] +ApplyStyles --> End(["End"]) +``` + +Diagram Sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:158-202](file://frontend/svelte-preprocess-react/react-slot.tsx#L158-L202) +- [frontend/utils/style.ts:39-76](file://frontend/utils/style.ts#L39-L76) + +Section Sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) +- [frontend/utils/style.ts:1-77](file://frontend/utils/style.ts#L1-L77) + +### API/Service Component Call Sequence (Fragment Bridging) + +```mermaid +sequenceDiagram +participant Caller as "Caller" +participant Bridge as "Bridge Runtime" +participant ReactComp as "React Component" +participant Slot as "ReactSlot" +participant DOM as "DOM" +Caller->>Bridge : "Pass Fragment + children" +Bridge->>ReactComp : "Render as Fragment" +ReactComp->>Slot : "Create Slot and request clone" +Slot->>DOM : "Clone node and set display: contents" +Slot-->>ReactComp : "Return fragment children" +ReactComp-->>Caller : "Rendering complete" +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:305-328](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L305-L328) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) + +Section Sources + +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:250-328](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L250-L328) + +### Complex Logic Component (Fragment and Context Merging) + +- During bridging, fragments merge multiple contexts (such as styles, class names, events, etc.) and skip context influence under ignore flags. +- Supports parameter mapping and force cloning, ensuring stable passing of properties and events in complex layouts. + +```mermaid +flowchart TD +Params["Collect params/context"] --> MergeCtx["Merge styles/class names/events"] +MergeCtx --> IgnoreFlag{"Ignore context?"} +IgnoreFlag --> |Yes| SkipCtx["Skip context influence"] +IgnoreFlag --> |No| ApplyCtx["Apply context"] +ApplyCtx --> Render["Render fragment children"] +SkipCtx --> Render +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:286-304](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L286-L304) + +Section Sources + +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:228-328](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L228-L328) + +## Dependency Analysis + +- The Fragment frontend implementation depends on React and `sveltify`; the backend template depends on the runtime renderer and bridging utilities. +- ReactSlot depends on style utilities and debounce hooks to ensure cloning and mounting stability. +- The rendering utility chain (renderSlot, renderItems, createItemsContext) provides a unified entry for handling parameters, events, and context. + +```mermaid +graph LR +FragTS["fragment.tsx"] --> BE_JS["fragment-sXw8Jnlf.js"] +FragTS --> BE_Svelte["fragment-BaGnla3s.js"] +ReactSlot["react-slot.tsx"] --> StyleUtils["style.ts"] +RenderSlot["renderSlot.tsx"] --> ReactSlot +RenderItems["renderItems.tsx"] --> ReactSlot +CreateItems["createItemsContext.tsx"] --> RenderItems +``` + +Diagram Sources + +- [frontend/base/fragment/fragment.tsx:1-11](file://frontend/base/fragment/fragment.tsx#L1-L11) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:1-446](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L1-L446) +- [backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js:1-11](file://backend/modelscope_studio/components/base/each/templates/component/fragment-BaGnla3s.js#L1-L11) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/utils/style.ts:1-77](file://frontend/utils/style.ts#L1-L77) + +Section Sources + +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/renderItems.tsx:1-114](file://frontend/utils/renderItems.tsx#L1-L114) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +## Performance Considerations + +- Reducing DOM levels: Fragment passes `children` through as React Fragment, avoiding extra container nodes and reducing layout and reflow costs. +- Clone strategy: Enable cloning when needed, but avoid frequent cloning of large numbers of nodes; combine with parameter mapping and force cloning when necessary to reduce invalid updates. +- Mutation observation: ReactSlot uses MutationObserver to observe changes, combined with debounce and minimal re-rendering, avoiding excessive refresh. +- Styles and class names: Converted uniformly via style utilities, avoiding repeated calculation and string concatenation overhead. +- Event binding: Copy event listeners during cloning to ensure interaction consistency, while paying attention to removal timing to prevent memory leaks. + +## Troubleshooting Guide + +- Slot not working + - Confirm that the slot only supports components from a specific ecosystem; the component needs to be wrapped with Fragment before being passed in. + - Reference example: [docs/components/base/fragment/demos/basic.py:14-19](file://docs/components/base/fragment/demos/basic.py#L14-L19) + +- Child elements not rendering correctly or styles missing + - Check if clone mode is enabled; if not, styles and class names may not be correctly applied. + - Reference implementation: [frontend/svelte-preprocess-react/react-slot.tsx:158-202](file://frontend/svelte-preprocess-react/react-slot.tsx#L158-L202) + +- Events not triggering or binding repeatedly + - Confirm event listeners have been copied during cloning; check if cleanup occurs on unmount. + - Reference implementation: [frontend/svelte-preprocess-react/react-slot.tsx:67-95](file://frontend/svelte-preprocess-react/react-slot.tsx#L67-L95) + +- Parameter mapping and context conflicts + - Use parameter mapping and force cloning to ensure context merge order and override rules meet expectations. + - Reference implementation: [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:286-304](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L286-L304) + +Section Sources + +- [docs/components/base/fragment/demos/basic.py:1-22](file://docs/components/base/fragment/demos/basic.py#L1-L22) +- [frontend/svelte-preprocess-react/react-slot.tsx:67-202](file://frontend/svelte-preprocess-react/react-slot.tsx#L67-L202) +- [backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js:286-304](file://backend/modelscope_studio/components/base/fragment/templates/component/fragment-sXw8Jnlf.js#L286-L304) + +## Conclusion + +The Fragment component implements combination and passing of multiple child elements without introducing extra DOM nodes, through the "fragment container + React Slot + context bridging" mechanism. It is particularly suitable for layout needs that require injecting unsupported components into strictly constrained slot scenarios. Combined with parameter mapping, event merging, and style utilities, Fragment has good stability and maintainability in complex layouts. + +## Appendix + +- Usage examples (documentation and demos) + - Basic usage and comparison: [docs/components/base/fragment/demos/basic.py:14-19](file://docs/components/base/fragment/demos/basic.py#L14-L19) + - Chinese documentation: [docs/components/base/fragment/README-zh_CN.md:1-10](file://docs/components/base/fragment/README-zh_CN.md#L1-L10) + - English documentation: [docs/components/base/fragment/README.md:1-10](file://docs/components/base/fragment/README.md#L1-L10) diff --git a/.wiki/en/Base Components/Layout Components.md b/.wiki/en/Base Components/Layout Components.md new file mode 100644 index 00000000..e6ba0e3e --- /dev/null +++ b/.wiki/en/Base Components/Layout Components.md @@ -0,0 +1,386 @@ +# Layout Components + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/components/base/div/__init__.py](file://backend/modelscope_studio/components/base/div/__init__.py) +- [backend/modelscope_studio/components/base/span/__init__.py](file://backend/modelscope_studio/components/base/span/__init__.py) +- [backend/modelscope_studio/components/base/text/__init__.py](file://backend/modelscope_studio/components/base/text/__init__.py) +- [backend/modelscope_studio/components/base/markdown/__init__.py](file://backend/modelscope_studio/components/base/markdown/__init__.py) +- [frontend/base/package.json](file://frontend/base/package.json) +- [frontend/base/div/Index.svelte](file://frontend/base/div/Index.svelte) +- [frontend/base/span/Index.svelte](file://frontend/base/span/Index.svelte) +- [frontend/base/text/Index.svelte](file://frontend/base/text/Index.svelte) +- [frontend/base/markdown/Index.svelte](file://frontend/base/markdown/Index.svelte) +- [frontend/base/div/div.tsx](file://frontend/base/div/div.tsx) +- [frontend/base/span/span.tsx](file://frontend/base/span/span.tsx) +- [frontend/base/text/text.tsx](file://frontend/base/text/text.tsx) +- [frontend/base/markdown/markdown.tsx](file://frontend/base/markdown/markdown.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically covers the "Layout Components" series in ModelScope Studio, focusing on the four foundational layout and content components: Div, Span, Text, and Markdown. The documentation provides in-depth explanations from the perspectives of architecture, data flow, processing logic, styling and theme adaptation, composition and nesting best practices, performance characteristics and optimization recommendations, as well as common issues and debugging techniques — helping developers efficiently and reliably use these components for page layout and content rendering. + +## Project Structure + +The layout components sit between the backend Python component layer and the frontend Svelte/React layer, following a layered design of "Python component definition + Svelte wrapper + React implementation": + +- Backend: Defines component behavior, event bindings, pre/post-processing logic, and declares frontend resource directories via Python classes. +- Frontend Svelte layer: Handles property passthrough, visibility control, style and class name composition, and slot resolution/rendering. +- React layer: Wraps specific HTML elements (e.g., div/span), or renders based on a global component (e.g., Markdown). + +```mermaid +graph TB +subgraph "Backend" +PY_DIV["Python: Div Component"] +PY_SPAN["Python: Span Component"] +PY_TEXT["Python: Text Component"] +PY_MD["Python: Markdown Component"] +end +subgraph "Frontend (Svelte)" +SV_DIV["Svelte: div/Index.svelte"] +SV_SPAN["Svelte: span/Index.svelte"] +SV_TEXT["Svelte: text/Index.svelte"] +SV_MD["Svelte: markdown/Index.svelte"] +end +subgraph "Frontend (React)" +RX_DIV["React: div.tsx"] +RX_SPAN["React: span.tsx"] +RX_TEXT["React: text.tsx"] +RX_MD["React: markdown.tsx"] +end +PY_DIV --> SV_DIV --> RX_DIV +PY_SPAN --> SV_SPAN --> RX_SPAN +PY_TEXT --> SV_TEXT --> RX_TEXT +PY_MD --> SV_MD --> RX_MD +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/div/**init**.py:10-86](file://backend/modelscope_studio/components/base/div/__init__.py#L10-L86) +- [backend/modelscope_studio/components/base/span/**init**.py:10-87](file://backend/modelscope_studio/components/base/span/__init__.py#L10-L87) +- [backend/modelscope_studio/components/base/text/**init**.py:8-57](file://backend/modelscope_studio/components/base/text/__init__.py#L8-L57) +- [backend/modelscope_studio/components/base/markdown/**init**.py:11-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L11-L174) +- [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) +- [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) +- [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) +- [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) +- [frontend/base/div/div.tsx:1-18](file://frontend/base/div/div.tsx#L1-L18) +- [frontend/base/span/span.tsx:1-20](file://frontend/base/span/span.tsx#L1-L20) +- [frontend/base/text/text.tsx:1-11](file://frontend/base/text/text.tsx#L1-L11) +- [frontend/base/markdown/markdown.tsx:1-35](file://frontend/base/markdown/markdown.tsx#L1-L35) + +Section Sources + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) + +## Core Components + +This section provides a functional and usage overview of the four foundational layout components, highlighting their roles and responsibilities in page layout and content rendering. + +- Div + - Role: Block-level container for holding child elements or text values; supports generic interaction events such as mouse and scroll events. + - Key Points: Accepts extra prop passthrough; supports visibility, element ID, class names, and inline styles as common attributes. + - Use Cases: Card backgrounds, section divisions, and outer containers for complex nested layouts. + +- Span + - Role: Inline container suitable for wrapping short text or inline elements; also supports generic interaction events. + - Key Points: Prioritizes child node rendering when children exist; falls back to `value` or an empty span otherwise. + - Use Cases: Inline highlights, labels, and text fragments within button groups. + +- Text + - Role: Pure text output component with no extra container wrapper; directly renders a string. + - Key Points: No event bindings; only handles `value`; suitable for minimal-cost text rendering. + - Use Cases: Headings, paragraphs, and lightweight hint text. + +- Markdown + - Role: Rich text rendering component supporting copyButtons slots, LaTeX math delimiters, HTML sanitization policy, line break and header link options. + - Key Points: Supports `copyButtons` slot; post-processing cleans input indentation; theme mode and root path are passed through to the underlying component. + - Use Cases: Help documentation, descriptive text, and dynamically generated rich text content. + +Section Sources + +- [backend/modelscope_studio/components/base/div/**init**.py:10-86](file://backend/modelscope_studio/components/base/div/__init__.py#L10-L86) +- [backend/modelscope_studio/components/base/span/**init**.py:10-87](file://backend/modelscope_studio/components/base/span/__init__.py#L10-L87) +- [backend/modelscope_studio/components/base/text/**init**.py:8-57](file://backend/modelscope_studio/components/base/text/__init__.py#L8-L57) +- [backend/modelscope_studio/components/base/markdown/**init**.py:11-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L11-L174) + +## Architecture Overview + +The diagram below illustrates the overall call chain and data flow from backend components to frontend rendering: + +```mermaid +sequenceDiagram +participant Py as "Backend Component (Python)" +participant Svelte as "Frontend Wrapper (Svelte)" +participant React as "React Implementation" +participant DOM as "DOM" +Py->>Svelte : Initialize and pass properties (visible/elem_*/value, etc.) +Svelte->>Svelte : Handle property passthrough / visibility / styles / class names +Svelte->>React : Render the corresponding React component +React->>DOM : Output final HTML nodes (div/span/text/markdown) +DOM-->>React : Event callbacks (e.g., click/mouseover/scroll) +React-->>Svelte : Trigger event updates +Svelte-->>Py : Event callback triggered (bound by backend event listeners) +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/div/**init**.py:14-39](file://backend/modelscope_studio/components/base/div/__init__.py#L14-L39) +- [backend/modelscope_studio/components/base/span/**init**.py:14-39](file://backend/modelscope_studio/components/base/span/__init__.py#L14-L39) +- [backend/modelscope_studio/components/base/markdown/**init**.py:15-46](file://backend/modelscope_studio/components/base/markdown/__init__.py#L15-L46) +- [frontend/base/div/Index.svelte:22-47](file://frontend/base/div/Index.svelte#L22-L47) +- [frontend/base/span/Index.svelte:21-46](file://frontend/base/span/Index.svelte#L21-L46) +- [frontend/base/text/Index.svelte:15-29](file://frontend/base/text/Index.svelte#L15-L29) +- [frontend/base/markdown/Index.svelte:19-44](file://frontend/base/markdown/Index.svelte#L19-L44) +- [frontend/base/div/div.tsx:12-15](file://frontend/base/div/div.tsx#L12-L15) +- [frontend/base/span/span.tsx:12-17](file://frontend/base/span/span.tsx#L12-L17) +- [frontend/base/text/text.tsx:4-8](file://frontend/base/text/text.tsx#L4-L8) +- [frontend/base/markdown/markdown.tsx:8-32](file://frontend/base/markdown/markdown.tsx#L8-L32) + +## Detailed Component Analysis + +### Div Component + +- Design Highlights + - As a block-level container, it prioritizes child node rendering; falls back to the `value` string when no children are present. + - Supports binding of generic interaction events (click, dblclick, mousedown, mouseup, mouseover, mouseout, mousemove, scroll). + - Extra props can be passed through; `elem_id`, `elem_classes`, and `elem_style` provide styling and positioning control. +- Data Flow and Processing Logic + - Pre/post-processing leaves strings unchanged; visibility is uniformly controlled by the Svelte layer. +- Usage Recommendations + - Suitable for large-scale layout divisions and complex nesting; avoid using in contexts where inline semantics are required. + - When combined with Grid/Flex layouts, be mindful not to introduce unnecessary hierarchy. + +```mermaid +flowchart TD +Start(["Enter Div Rendering"]) --> CheckChildren["Check if child nodes exist"] +CheckChildren --> HasChildren{"Children present?"} +HasChildren --> |Yes| RenderChildren["Render child nodes"] +HasChildren --> |No| UseValue["Use value as text content"] +RenderChildren --> End(["Done"]) +UseValue --> End +``` + +Diagram Sources + +- [frontend/base/div/div.tsx:12-15](file://frontend/base/div/div.tsx#L12-L15) +- [frontend/base/div/Index.svelte:50-63](file://frontend/base/div/Index.svelte#L50-L63) + +Section Sources + +- [backend/modelscope_studio/components/base/div/**init**.py:10-86](file://backend/modelscope_studio/components/base/div/__init__.py#L10-L86) +- [frontend/base/div/Index.svelte:1-65](file://frontend/base/div/Index.svelte#L1-L65) +- [frontend/base/div/div.tsx:1-18](file://frontend/base/div/div.tsx#L1-L18) + +### Span Component + +- Design Highlights + - Inline container that prioritizes child node rendering; falls back to `value` or an empty span when no children are present. + - Supports the same set of interaction event bindings as Div. +- Usage Recommendations + - Suitable for inline text fragments, labels, and text within buttons. + - Not recommended in contexts that require block-level line breaks. + +```mermaid +flowchart TD +Start(["Enter Span Rendering"]) --> CheckChildren["Check if child nodes exist"] +CheckChildren --> HasChildren{"Children present?"} +HasChildren --> |Yes| RenderChildren["Render child nodes"] +HasChildren --> |No| UseValueOrEmpty["Use value or empty span"] +RenderChildren --> End(["Done"]) +UseValueOrEmpty --> End +``` + +Diagram Sources + +- [frontend/base/span/span.tsx:12-17](file://frontend/base/span/span.tsx#L12-L17) +- [frontend/base/span/Index.svelte:49-63](file://frontend/base/span/Index.svelte#L49-L63) + +Section Sources + +- [backend/modelscope_studio/components/base/span/**init**.py:10-87](file://backend/modelscope_studio/components/base/span/__init__.py#L10-L87) +- [frontend/base/span/Index.svelte:1-64](file://frontend/base/span/Index.svelte#L1-L64) +- [frontend/base/span/span.tsx:1-20](file://frontend/base/span/span.tsx#L1-L20) + +### Text Component + +- Design Highlights + - Minimal wrapper that directly renders a string; no event bindings. + - Suitable for pure text output with low performance overhead. +- Usage Recommendations + - Do not mix with rich text or interactive scenarios; control styling via `elem_classes`/`elem_style` when needed. + +```mermaid +flowchart TD +Start(["Enter Text Rendering"]) --> GetValue["Read value"] +GetValue --> RenderText["Render text node"] +RenderText --> End(["Done"]) +``` + +Diagram Sources + +- [frontend/base/text/text.tsx:4-8](file://frontend/base/text/text.tsx#L4-L8) +- [frontend/base/text/Index.svelte:32-41](file://frontend/base/text/Index.svelte#L32-L41) + +Section Sources + +- [backend/modelscope_studio/components/base/text/**init**.py:8-57](file://backend/modelscope_studio/components/base/text/__init__.py#L8-L57) +- [frontend/base/text/Index.svelte:1-42](file://frontend/base/text/Index.svelte#L1-L42) +- [frontend/base/text/text.tsx:1-11](file://frontend/base/text/text.tsx#L1-L11) + +### Markdown Component + +- Design Highlights + - Supports the `copyButtons` slot to allow custom copy buttons; supports LaTeX math delimiters, HTML sanitization policy, line break and header link options. + - Post-processing cleans input indentation to ensure rendering consistency. + - Theme mode and root path are passed through via props to the underlying Markdown component. +- Data Flow and Processing Logic + - The Svelte layer parses slots and injects `copyButtons` targets into the React layer. + - The React layer hides children, delegating rendering and interaction to the global Markdown component. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte: markdown/Index.svelte" +participant React as "React: markdown.tsx" +participant GlobalMD as "Global Markdown Component" +participant User as "User" +Svelte->>React : Pass through value/styles/class names/theme/root path +React->>React : Resolve copyButtons slot targets +React->>GlobalMD : Render Markdown and inject copyButtons +User->>GlobalMD : Trigger copy/click events +GlobalMD-->>React : Event callback +React-->>Svelte : Update state +Svelte-->>Svelte : Trigger backend event listeners +``` + +Diagram Sources + +- [frontend/base/markdown/Index.svelte:19-44](file://frontend/base/markdown/Index.svelte#L19-L44) +- [frontend/base/markdown/markdown.tsx:8-32](file://frontend/base/markdown/markdown.tsx#L8-L32) +- [backend/modelscope_studio/components/base/markdown/**init**.py:15-46](file://backend/modelscope_studio/components/base/markdown/__init__.py#L15-L46) + +Section Sources + +- [backend/modelscope_studio/components/base/markdown/**init**.py:11-174](file://backend/modelscope_studio/components/base/markdown/__init__.py#L11-L174) +- [frontend/base/markdown/Index.svelte:1-64](file://frontend/base/markdown/Index.svelte#L1-L64) +- [frontend/base/markdown/markdown.tsx:1-35](file://frontend/base/markdown/markdown.tsx#L1-L35) + +## Dependency Analysis + +- Inter-Component Coupling + - All four components are derived from a unified backend base class (layout/data-layout/plain component), sharing a consistent lifecycle and event mechanism. + - The frontend Svelte layer uses the same property passthrough and visibility control patterns, reducing maintenance cost. +- External Dependencies + - The React wrapper layer depends on `sveltify` and slot capabilities provided by `@svelte-preprocess-react`. + - The Markdown component depends on the global Markdown component and ReactSlot for slot rendering. +- Potential Circular Dependencies + - The current structure follows a unidirectional dependency (Backend → Svelte → React); no circular dependency has been observed. + +```mermaid +graph LR +PY_BASE["Backend Base Component Class"] --> PY_DIV["Div"] +PY_BASE --> PY_SPAN["Span"] +PY_BASE --> PY_TEXT["Text"] +PY_DATA_LAYOUT["Data Layout Base Class"] --> PY_MD["Markdown"] +SV_DIV["Svelte: div/Index.svelte"] --> RX_DIV["React: div.tsx"] +SV_SPAN["Svelte: span/Index.svelte"] --> RX_SPAN["React: span.tsx"] +SV_TEXT["Svelte: text/Index.svelte"] --> RX_TEXT["React: text.tsx"] +SV_MD["Svelte: markdown/Index.svelte"] --> RX_MD["React: markdown.tsx"] +RX_MD --> GLOBAL_MD["Global Markdown Component"] +``` + +Diagram Sources + +- [backend/modelscope_studio/components/base/div/**init**.py](file://backend/modelscope_studio/components/base/div/__init__.py#L7) +- [backend/modelscope_studio/components/base/span/**init**.py](file://backend/modelscope_studio/components/base/span/__init__.py#L7) +- [backend/modelscope_studio/components/base/text/**init**.py](file://backend/modelscope_studio/components/base/text/__init__.py#L5) +- [backend/modelscope_studio/components/base/markdown/**init**.py](file://backend/modelscope_studio/components/base/markdown/__init__.py#L8) +- [frontend/base/markdown/markdown.tsx:4-5](file://frontend/base/markdown/markdown.tsx#L4-L5) + +Section Sources + +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [frontend/base/package.json:1-6](file://frontend/base/package.json#L1-L6) + +## Performance Considerations + +- Rendering Path + - Text outputs plain text directly with the lowest overhead; Div/Span traverse the React subtree when children are present — pay attention to subtree size. + - Markdown reuses global rendering capability by hiding children, reducing repeated parsing. +- Event Bindings + - All layout components support multiple mouse/scroll event bindings; enable only as needed to avoid unnecessary callback overhead. +- Styles and Class Names + - Control styling via `elem_classes`/`elem_style`; prefer atomic class names to minimize style recalculation. +- Theme and Resources + - Markdown theme mode and root path are passed through to ensure static asset paths are correct, avoiding redundant requests. + +[This section contains general performance recommendations; no specific file references required] + +## Troubleshooting Guide + +- Text Not Displayed + - Check whether `value` is empty or contains only whitespace; the Text component falls back to an empty span when `value` is missing. + - For Div/Span, verify whether child nodes have been passed in, causing `value` to be ignored. +- Events Not Firing + - Confirm that event listeners are registered on the backend; check that `visible` is `true` — events will not fire when the component is invisible. +- Markdown Copy Button Not Working + - Confirm that the `copyButtons` slot is correctly mounted; the React layer determines whether to replace the default button based on the slot target. +- Styles Not Applied + - Check the composition order and precedence of `elem_id`/`elem_classes`/`elem_style`; use more specific CSS selectors if necessary. +- Theme Mismatch + - Confirm that `themeMode` and `rootUrl` are correctly passed through to the Markdown component. + +Section Sources + +- [backend/modelscope_studio/components/base/text/**init**.py:45-50](file://backend/modelscope_studio/components/base/text/__init__.py#L45-L50) +- [backend/modelscope_studio/components/base/div/**init**.py:14-39](file://backend/modelscope_studio/components/base/div/__init__.py#L14-L39) +- [backend/modelscope_studio/components/base/span/**init**.py:14-39](file://backend/modelscope_studio/components/base/span/__init__.py#L14-L39) +- [backend/modelscope_studio/components/base/markdown/**init**.py:49-52](file://backend/modelscope_studio/components/base/markdown/__init__.py#L49-L52) +- [frontend/base/markdown/markdown.tsx:14-31](file://frontend/base/markdown/markdown.tsx#L14-L31) + +## Conclusion + +Div, Span, Text, and Markdown form the foundational capabilities for layout and content rendering in ModelScope Studio. Under the design of unified backend abstraction, consistent frontend wrapping, and precise React rendering, they achieve both ease of use and extensibility alongside solid performance. Choosing the appropriate component type, enabling events and slots only as needed, and following style and theme conventions are key to building high-quality interfaces. + +[This section contains summary content; no specific file references required] + +## Appendix + +### Component Properties and Behavior Quick Reference + +- Div + - Events: click, dblclick, mousedown, mouseup, mouseover, mouseout, mousemove, scroll + - Properties: value, additional_props, elem_id, elem_classes, elem_style, visible, render +- Span + - Events: click, dblclick, mousedown, mouseup, mouseover, mouseout, mousemove, scroll + - Properties: value, additional_props, elem_id, elem_classes, elem_style, visible, render +- Text + - Events: None + - Properties: value, elem_id, elem_classes, elem_style, visible, render +- Markdown + - Events: change, copy, click, dblclick, mousedown, mouseup, mouseover, mouseout, mousemove, scroll + - Slots: copyButtons + - Properties: value, rtl, latex_delimiters, sanitize_html, line_breaks, header_links, allow_tags, show_copy_button, copy_buttons, elem_id, elem_classes, elem_style, visible, render + +Section Sources + +- [backend/modelscope_studio/components/base/div/**init**.py:14-68](file://backend/modelscope_studio/components/base/div/__init__.py#L14-L68) +- [backend/modelscope_studio/components/base/span/**init**.py:14-69](file://backend/modelscope_studio/components/base/span/__init__.py#L14-L69) +- [backend/modelscope_studio/components/base/text/**init**.py:12-39](file://backend/modelscope_studio/components/base/text/__init__.py#L12-L39) +- [backend/modelscope_studio/components/base/markdown/**init**.py:15-143](file://backend/modelscope_studio/components/base/markdown/__init__.py#L15-L143) diff --git a/.wiki/en/Base Components/Rendering Components.md b/.wiki/en/Base Components/Rendering Components.md new file mode 100644 index 00000000..7e1893fd --- /dev/null +++ b/.wiki/en/Base Components/Rendering Components.md @@ -0,0 +1,371 @@ +# Rendering Components + + +**Files Referenced in This Document** +- [each.tsx](file://frontend/base/each/each.tsx) +- [Index.svelte (Each)](file://frontend/base/each/Index.svelte) +- [EachItem.svelte](file://frontend/base/each/EachItem.svelte) +- [each.placeholder.tsx](file://frontend/base/each/each.placeholder.tsx) +- [useTargets.ts](file://frontend/utils/hooks/useTargets.ts) +- [useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [filter.tsx](file://frontend/base/filter/filter.tsx) +- [Index.svelte (Filter)](file://frontend/base/filter/Index.svelte) +- [each/__init__.py](file://backend/modelscope_studio/components/base/each/__init__.py) +- [filter/__init__.py](file://backend/modelscope_studio/components/base/filter/__init__.py) +- [base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [filter/README-zh_CN.md](file://docs/components/base/filter/README-zh_CN.md) +- [filter/demos/basic.py](file://docs/components/base/filter/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Component Details](#component-details) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document focuses on the Each and Filter components in the rendering component series, systematically explaining their key roles in data rendering and conditional display. Each is responsible for rendering list data item by item and injecting context into each item; Filter is responsible for filtering or extracting context, supporting both key-based sub-object extraction and custom filtering via function strings. The documentation provides comprehensive coverage of architecture, data flow, processing logic, integration and state management, performance optimization, and debugging techniques, along with multi-scenario usage examples and best practices. + +## Project Structure + +The rendering components reside in the frontend `base` package, each composed of a Svelte entry component and a React implementation, with corresponding Python component classes in the backend to interface with the Gradio data flow. The core files are organized as follows: + +- Frontend Each: The Svelte entry component handles property processing and placeholder coordination; the React implementation handles loop rendering and context injection. +- Frontend Filter: The Svelte entry component handles property processing; the React implementation handles context filtering and passthrough. +- Backend Each/Filter: Python component classes that define properties, visibility, pre/post-processing, and frontend directory mappings. + +```mermaid +graph TB +subgraph "Frontend base" +EIdx["Each Entry Index.svelte"] +EImpl["Each Implementation each.tsx"] +EItem["Each Item EachItem.svelte"] +EPh["Each Placeholder each.placeholder.tsx"] +FIdx["Filter Entry Index.svelte"] +FImpl["Filter Implementation filter.tsx"] +UT["Utility: useTargets.ts"] +UF["Utility: useFunction.ts"] +end +subgraph "Backend Python" +PYE["ModelScopeEach each/__init__.py"] +PYF["ModelScopeFilter filter/__init__.py"] +PYPkg["base/__init__.py Exports"] +end +EIdx --> EImpl +EIdx --> EPh +EIdx --> EItem +EImpl --> UT +FIdx --> FImpl +FImpl --> UF +PYE --> EIdx +PYF --> FIdx +PYPkg --> PYE +PYPkg --> PYF +``` + +Diagram Sources + +- [Index.svelte (Each):1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [each.tsx:1-61](file://frontend/base/each/each.tsx#L1-L61) +- [EachItem.svelte:1-37](file://frontend/base/each/EachItem.svelte#L1-L37) +- [each.placeholder.tsx:1-31](file://frontend/base/each/each.placeholder.tsx#L1-L31) +- [Index.svelte (Filter):1-52](file://frontend/base/filter/Index.svelte#L1-L52) +- [filter.tsx:1-41](file://frontend/base/filter/filter.tsx#L1-L41) +- [useTargets.ts:1-52](file://frontend/utils/hooks/useTargets.ts#L1-L52) +- [useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [each/**init**.py:1-73](file://backend/modelscope_studio/components/base/each/__init__.py#L1-L73) +- [filter/**init**.py:1-45](file://backend/modelscope_studio/components/base/filter/__init__.py#L1-L45) +- [base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +Section Sources + +- [Index.svelte (Each):1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [filter.tsx:1-41](file://frontend/base/filter/filter.tsx#L1-L41) +- [each.tsx:1-61](file://frontend/base/each/each.tsx#L1-L61) +- [each/**init**.py:1-73](file://backend/modelscope_studio/components/base/each/__init__.py#L1-L73) +- [filter/**init**.py:1-45](file://backend/modelscope_studio/components/base/filter/__init__.py#L1-L45) +- [base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +## Core Components + +- Each: Receives list data and context, renders child nodes item by item, and merges each item's value into the context for downstream component consumption. +- Filter: Filters or extracts the current context, supporting two modes: + - as_item: Extracts a sub-object from the context by key name to serve as the new context passed downstream. + - params_mapping: Accepts a JS function string to perform custom filtering on the context and returns a new context. + - When neither is provided, context propagation is blocked and subsequent property overrides become ineffective. + +Section Sources + +- [each.tsx:8-13](file://frontend/base/each/each.tsx#L8-L13) +- [filter.tsx:9-13](file://frontend/base/filter/filter.tsx#L9-L13) +- [filter/README-zh_CN.md:1-22](file://docs/components/base/filter/README-zh_CN.md#L1-L22) + +## Architecture Overview + +The execution flow of Each and Filter can be summarized as: the frontend entry component parses properties and prepares the React implementation; the React implementation generates the child tree based on data and context; Filter filters the context before rendering to ensure downstream components receive only the required data. + +```mermaid +sequenceDiagram +participant Py as "Backend Component Each/Filter" +participant S as "Entry Component Each/Filter" +participant R as "React Implementation Each/Filter" +participant U as "Utility Hooks useTargets/useFunction" +Py->>S : Initialize and set properties +S->>R : Pass processed properties and slots +R->>U : Resolve slot targets (Each) / Resolve function (Filter) +U-->>R : Return targets/function +R->>R : Each iterates over value and injects context +R->>R : Filter filters context based on as_item or params_mapping +R-->>S : Render result +S-->>Py : Visibility and render control +``` + +Diagram Sources + +- [Index.svelte (Each):1-111](file://frontend/base/each/Index.svelte#L1-L111) +- [each.tsx:35-58](file://frontend/base/each/each.tsx#L35-L58) +- [Index.svelte (Filter):1-52](file://frontend/base/filter/Index.svelte#L1-L52) +- [filter.tsx:15-38](file://frontend/base/filter/filter.tsx#L15-L38) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) + +## Component Details + +### Each Component + +Each's responsibility is to render list data item by item and inject context into each child item. Key points include: + +- Input Properties: `value` (array), `contextValue` (initial context), `children` (subtree), internal slot keys. +- Rendering Strategy: First renders an "isolated" hidden container to prevent external context from polluting internal slots; then maps over `value` to create an Item for each entry. +- Context Injection: Item merges the incoming `value` into `contextValue` to form the final context, then injects it into the child tree via `ContextPropsProvider`. +- Slot Resolution: Uses `useTargets` to extract nodes in `children` that match the `slotKey`, ensuring correct rendering order and target mounting. + +```mermaid +flowchart TD +Start(["Enter Each Rendering"]) --> Parse["Parse children slots
Extract targets via useTargets"] +Parse --> Isolate["Render isolated container (hidden)"] +Isolate --> Loop{"Iterate over value"} +Loop --> |Yes| Item["Create Item for each entry
Merge context"] +Item --> Render["Clone and render target slots"] +Render --> Next["Next element"] +Next --> Loop +Loop --> |No| End(["Rendering complete"]) +``` + +Diagram Sources + +- [each.tsx:35-58](file://frontend/base/each/each.tsx#L35-L58) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) + +Section Sources + +- [each.tsx:8-13](file://frontend/base/each/each.tsx#L8-L13) +- [each.tsx:35-58](file://frontend/base/each/each.tsx#L35-L58) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [Index.svelte (Each):66-104](file://frontend/base/each/Index.svelte#L66-L104) +- [each.placeholder.tsx:15-28](file://frontend/base/each/each.placeholder.tsx#L15-L28) +- [EachItem.svelte:23-27](file://frontend/base/each/EachItem.svelte#L23-L27) + +### Filter Component + +Filter's responsibility is to filter or extract the current context, supporting two modes: + +- as_item: Extracts a sub-object from the context by key name to serve as the new context passed downstream. +- params_mapping: Accepts a JS function string, resolved via `useFunction`, to perform custom filtering on the context. +- When no parameters are provided: context propagation is blocked, making subsequent property overrides ineffective. + +```mermaid +flowchart TD +Enter(["Enter Filter"]) --> ReadCtx["Read current context"] +ReadCtx --> CheckAs{"Is as_item provided?"} +CheckAs --> |Yes| Extract["Extract ctx[as_item] as new context"] +CheckAs --> |No| CheckMap{"Is params_mapping provided?"} +CheckMap --> |Yes| Exec["Execute params_mapping(ctx) as new context"] +CheckMap --> |No| Block["Do not update context (block propagation)"] +Extract --> Provide["Pass through via ContextPropsProvider"] +Exec --> Provide +Block --> Provide +Provide --> Exit(["Done"]) +``` + +Diagram Sources + +- [filter.tsx:15-38](file://frontend/base/filter/filter.tsx#L15-L38) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) + +Section Sources + +- [filter.tsx:9-13](file://frontend/base/filter/filter.tsx#L9-L13) +- [filter.tsx:15-38](file://frontend/base/filter/filter.tsx#L15-L38) +- [Index.svelte (Filter):33-45](file://frontend/base/filter/Index.svelte#L33-L45) +- [filter/README-zh_CN.md:1-22](file://docs/components/base/filter/README-zh_CN.md#L1-L22) + +### Properties and Events + +- Each (Frontend Entry Index.svelte) + - Key Properties: `value`, `context_value`, `visible`, `elem_id`, `elem_classes`, `elem_style`, `_internal.index`, etc. + - Internal Behavior: The placeholder component collects changes (e.g., `forceClone`, merged `value`/`context_value`) and decides whether to use the React implementation or render directly with EachItem. +- Each (React Implementation each.tsx) + - Key Properties: `value`, `contextValue`, `children`, `__internal_slot_key`. + - Internal Behavior: Isolates external context, resolves slot targets, renders each item, and injects context. +- Filter (Frontend Entry Index.svelte) + - Key Properties: `params_mapping`, `as_item`, `visible`. + - Internal Behavior: Passes `params_mapping` and `as_item` to the React implementation. +- Filter (React Implementation filter.tsx) + - Key Properties: `paramsMapping`, `asItem`. + - Internal Behavior: Selects key extraction or function filtering based on the parameters, updates context, and passes it through. + +Section Sources + +- [Index.svelte (Each):17-57](file://frontend/base/each/Index.svelte#L17-L57) +- [Index.svelte (Each):66-104](file://frontend/base/each/Index.svelte#L66-L104) +- [each.tsx:8-13](file://frontend/base/each/each.tsx#L8-L13) +- [Index.svelte (Filter):16-31](file://frontend/base/filter/Index.svelte#L16-L31) +- [filter.tsx:9-13](file://frontend/base/filter/filter.tsx#L9-L13) + +### Integration with State Management + +- Each merges `contextValue` with each item's `value` to form a per-item context consumable by downstream components. +- Filter uses `useContextPropsContext` to retrieve the current context, then generates a new context via `as_item` or `params_mapping`, enabling "conditional display / data filtering". +- The backend component's `visible` flag can be used to control render visibility; the frontend entry component will not load the React implementation when invisible, reducing overhead. + +Section Sources + +- [each.tsx:15-33](file://frontend/base/each/each.tsx#L15-L33) +- [filter.tsx:19-27](file://frontend/base/filter/filter.tsx#L19-L27) +- [Index.svelte (Each):66-104](file://frontend/base/each/Index.svelte#L66-L104) +- [Index.svelte (Filter):33-45](file://frontend/base/filter/Index.svelte#L33-L45) + +### Usage Examples and Scenarios + +- Basic Usage (Without Filter) + - Scenario: Loop-render list data; child components such as buttons directly consume the context injected by Each. + - Reference Example: [filter/demos/basic.py:1-20](file://docs/components/base/filter/demos/basic.py#L1-L20) +- Using as_item + - Scenario: The context output by Each contains multiple fields, and only one field needs to be passed as the new context to child components. + - Reference: [filter/README-zh_CN.md:1-22](file://docs/components/base/filter/README-zh_CN.md#L1-L22) +- Using params_mapping + - Scenario: Perform complex filtering or transformation on the context via a JS function, such as filtering, composing derived fields, etc. + - Reference: [filter/README-zh_CN.md:1-22](file://docs/components/base/filter/README-zh_CN.md#L1-L22) + +Section Sources + +- [filter/demos/basic.py:1-20](file://docs/components/base/filter/demos/basic.py#L1-L20) +- [filter/README-zh_CN.md:1-22](file://docs/components/base/filter/README-zh_CN.md#L1-L22) + +## Dependency Analysis + +- Each Dependencies + - Utility Hook: `useTargets` resolves slot targets to ensure correct rendering order and mounting. + - Context: `ContextPropsProvider` is used for context isolation and merging. +- Filter Dependencies + - Utility Hook: `useFunction` parses a string function into an executable function. + - Context: `ContextPropsProvider` is used to pass through the filtered context. +- Backend Components + - Each/Filter both inherit from the layout component base class, defining properties, visibility, pre/post-processing, and frontend directory mappings. + +```mermaid +graph LR +UT["useTargets.ts"] --> EImpl["each.tsx"] +UF["useFunction.ts"] --> FImpl["filter.tsx"] +EIdx["Each Index.svelte"] --> EImpl +FIdx["Filter Index.svelte"] --> FImpl +PYE["ModelScopeEach Python"] --> EIdx +PYF["ModelScopeFilter Python"] --> FIdx +``` + +Diagram Sources + +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [each.tsx:1-7](file://frontend/base/each/each.tsx#L1-L7) +- [filter.tsx:1-7](file://frontend/base/filter/filter.tsx#L1-L7) +- [Index.svelte (Each):1-16](file://frontend/base/each/Index.svelte#L1-L16) +- [Index.svelte (Filter):1-8](file://frontend/base/filter/Index.svelte#L1-L8) +- [each/**init**.py:1-73](file://backend/modelscope_studio/components/base/each/__init__.py#L1-L73) +- [filter/**init**.py:1-45](file://backend/modelscope_studio/components/base/filter/__init__.py#L1-L45) + +Section Sources + +- [each.tsx:1-7](file://frontend/base/each/each.tsx#L1-L7) +- [filter.tsx:1-7](file://frontend/base/filter/filter.tsx#L1-L7) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [each/**init**.py:1-73](file://backend/modelscope_studio/components/base/each/__init__.py#L1-L73) +- [filter/**init**.py:1-45](file://backend/modelscope_studio/components/base/filter/__init__.py#L1-L45) + +## Performance Considerations + +- List Rendering + - Each maps over `value` for rendering; avoid heavy computations inside `children` — move calculations upstream or cache them. + - Using stable keys (indices) helps React/Svelte diff optimization, but when the list has insertions/deletions, unique IDs are recommended as keys. +- Context Merging + - When Each/EachItem merge contexts, keep the `value` structure simple to avoid repeated rendering caused by deep nesting. +- Conditional Filtering + - `params_mapping` in Filter should avoid creating new functions on every render; define the function string at a higher level and pass it in. +- Visibility Control + - Use `visible` to control component rendering; the React implementation is not loaded when invisible, reducing unnecessary initialization and rendering. +- Large Data Sets + - Prefer pagination, virtual scrolling, or lazy loading strategies; avoid rendering oversized lists all at once. + - Reasonably flatten nested Each levels to reduce context depth and render tree complexity. + +## Troubleshooting Guide + +- Child Component Cannot Read Context + - Check whether Each has correctly passed in `contextValue` and `value`; confirm that the EachItem merge logic is effective. + - If using Filter, confirm that the `as_item` key name is correct or that `params_mapping` returns the expected object. +- Slot Rendering Order Abnormal + - Confirm that the slot key (`slotKey`) is consistent and that `useTargets` can correctly identify the target nodes. +- Filter Not Taking Effect + - Confirm that the `params_mapping` string can be parsed as a function, or that the `as_item` key exists in the current context. + - If no parameters are provided, Filter will block context propagation — this is expected behavior. +- Rendering Lag + - Check whether the `value` of Each is too large; paginate or virtualize as necessary. + - Avoid expensive operations inside `children`; move computations upstream or use memoization. + +Section Sources + +- [each.tsx:15-33](file://frontend/base/each/each.tsx#L15-L33) +- [filter.tsx:15-38](file://frontend/base/filter/filter.tsx#L15-L38) +- [useTargets.ts:5-51](file://frontend/utils/hooks/useTargets.ts#L5-L51) +- [Index.svelte (Each):66-104](file://frontend/base/each/Index.svelte#L66-L104) +- [Index.svelte (Filter):33-45](file://frontend/base/filter/Index.svelte#L33-L45) + +## Conclusion + +Each and Filter form the core capabilities of "loop rendering" and "conditional filtering" in the rendering component series. Each provides a consistent data environment for every item in a list through context merging and slot resolution; Filter extracts or custom-filters the context before rendering to satisfy diverse conditional display and data filtering requirements. Combined with the backend component's visibility control and frontend utility hooks, flexible rendering strategies can be achieved while maintaining performance. + +## Appendix + +- API Overview (Summary) + - Each (Frontend Entry) + - Properties: `value`, `context_value`, `visible`, `elem_id`, `elem_classes`, `elem_style`, `_internal.index`, etc. + - Behavior: Placeholder component collects changes and decides whether to use the React implementation or EachItem rendering. + - Each (React Implementation) + - Properties: `value`, `contextValue`, `children`, `__internal_slot_key`. + - Behavior: Isolates external context, resolves slot targets, renders each item, and injects context. + - Filter (Frontend Entry) + - Properties: `params_mapping`, `as_item`, `visible`. + - Behavior: Passes parameters to the React implementation. + - Filter (React Implementation) + - Properties: `paramsMapping`, `asItem`. + - Behavior: Updates context based on `as_item` or `params_mapping` and passes it through. +- Backend Components + - Both Each and Filter inherit from the layout component base class, defining properties, visibility, pre/post-processing, and frontend directory mappings. + +Section Sources + +- [Index.svelte (Each):17-57](file://frontend/base/each/Index.svelte#L17-L57) +- [each.tsx:8-13](file://frontend/base/each/each.tsx#L8-L13) +- [Index.svelte (Filter):16-31](file://frontend/base/filter/Index.svelte#L16-L31) +- [filter.tsx:9-13](file://frontend/base/filter/filter.tsx#L9-L13) +- [each/**init**.py:23-51](file://backend/modelscope_studio/components/base/each/__init__.py#L23-L51) +- [filter/**init**.py:13-25](file://backend/modelscope_studio/components/base/filter/__init__.py#L13-L25) diff --git a/.wiki/en/Base Components/Slot Component.md b/.wiki/en/Base Components/Slot Component.md new file mode 100644 index 00000000..b16ccb4e --- /dev/null +++ b/.wiki/en/Base Components/Slot Component.md @@ -0,0 +1,333 @@ +# Slot Component + + +**Files Referenced in This Document** +- [frontend/base/slot/Index.svelte](file://frontend/base/slot/Index.svelte) +- [frontend/svelte-preprocess-react/react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/patchSlots.ts](file://frontend/utils/patchSlots.ts) +- [docs/components/base/slot/README.md](file://docs/components/base/slot/README.md) +- [docs/components/base/slot/README-zh_CN.md](file://docs/components/base/slot/README-zh_CN.md) +- [docs/components/base/slot/demos/basic.py](file://docs/components/base/slot/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document systematically explains the Slot component, covering design philosophy, content distribution mechanism, dynamic insertion and custom rendering, slot types and scopes, parameter passing and data binding, communication with parent components, usage examples, best practices, performance optimization suggestions, differences and advantages over template systems, and debugging tips and solutions to common issues. Based on the Slot component implementation and documentation in the repository, combined with the frontend rendering pipeline and context mechanism, this document helps readers fully master the slot system from principles to practice. + +## Project Structure + +The Slot component is implemented in Svelte on the frontend, responsible for collecting the child tree and registering it into the parent component's slot context; during the rendering phase, ReactSlot clones and mounts the DOM structure rendered by Svelte into the React environment, implementing cross-framework content distribution and dynamic updates. + +```mermaid +graph TB +subgraph "Frontend (Svelte)" +A["Index.svelte
Slot Component"] +B["svelte context
slot.svelte"] +end +subgraph "Utility Layer" +C["patchSlots.ts
Parameter Patching"] +D["renderSlot.tsx
Render Entry"] +end +subgraph "React Side" +E["react-slot.tsx
ReactSlot Component"] +end +A --> B +A --> C +D --> E +C --> D +B --> D +D --> E +``` + +Diagram Sources + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/utils/patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +Section Sources + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +## Core Components + +- Slot (Svelte): Receives the slot name and optional parameter mapping function from the parent component, registers itself as a "slot container" into the context, and renders child nodes when visibility allows. +- ReactSlot (React): In the React environment, receives the DOM fragment generated by Svelte, supports cloning, event copying, style and class name injection, and uses MutationObserver to observe changes and dynamically re-render. +- renderSlot: Provides a unified rendering entry, supporting force cloning, parameter passing, and context wrapping. +- patchSlots: Wraps slot rendering functions, prepending or appending additional parameters to slot callbacks in order, enabling parent components to pass context parameters to child slots. + +Section Sources + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) + +## Architecture Overview + +Slot's workflow is divided into a "registration phase" and a "rendering phase". Parent components register slot keys and parameter mappings via the context API; the Slot component collects the child tree in Svelte and binds it to the DOM; finally, ReactSlot clones and mounts in the React environment while maintaining event and style consistency. + +```mermaid +sequenceDiagram +participant Parent as "Parent Component" +participant SlotComp as "Slot (Index.svelte)" +participant Ctx as "Svelte Context (slot.svelte)" +participant Utils as "patchSlots/renderSlot" +participant RSlot as "ReactSlot (react-slot.tsx)" +Parent->>SlotComp : Pass value/params_mapping +SlotComp->>Ctx : setSlotKey/setSlotParamsMapping +SlotComp->>Ctx : setSlot(prevKey, currentKey, slotDom) +SlotComp-->>Parent : Render child nodes (hidden svelte-slot) +Utils->>RSlot : renderSlot(el, options) +RSlot->>RSlot : Clone element/copy events/inject styles/class names +RSlot-->>Parent : Mount to React environment +``` + +Diagram Sources + +- [frontend/base/slot/Index.svelte:32-54](file://frontend/base/slot/Index.svelte#L32-L54) +- [frontend/utils/patchSlots.ts:15-31](file://frontend/utils/patchSlots.ts#L15-L31) +- [frontend/utils/renderSlot.tsx:13-28](file://frontend/utils/renderSlot.tsx#L13-L28) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) + +## Detailed Component Analysis + +### Slot Component (Svelte) + +- Responsibilities + - Receives slot name and parameter mapping function string. + - Writes the current slot key and parameter mapping to the context for parent component consumption. + - Renders child nodes when visible, but hides the actual `svelte-slot` container to avoid affecting layout. +- Key points + - Uses context API to set slot key and parameter mapping. + - Monitors slot name changes via `effect`, triggering `setSlot` registration. + - Child nodes are bound to DOM via `svelte-slot bind:this`, enabling ReactSlot to clone and mount later. + +```mermaid +flowchart TD +Start(["Enter Component"]) --> ReadProps["Read value/params_mapping"] +ReadProps --> SetCtx["setSlotKey / setSlotParamsMapping"] +SetCtx --> Effect["$effect monitors value changes"] +Effect --> HasSlot{"slot exists and value is valid?"} +HasSlot --> |Yes| Register["setSlot(prevKey, currentKey, slotDom)"] +HasSlot --> |No| Wait["Wait / stay unchanged"] +Register --> Render["Render child nodes (hidden svelte-slot)"] +Wait --> Render +Render --> End(["Complete"]) +``` + +Diagram Sources + +- [frontend/base/slot/Index.svelte:31-61](file://frontend/base/slot/Index.svelte#L31-L61) + +Section Sources + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) + +### ReactSlot (React) + +- Responsibilities + - Receives the slot DOM generated by Svelte, supports cloning and event copying. + - Injects styles and class names, handles React Portal for correct subtree mounting. + - Uses MutationObserver to monitor slot changes and automatically re-clones and renders. +- Key points + - `cloneElementWithEvents`: Recursively clones nodes, copies event listeners, handles nested `svelte-slot`. + - `mountElementProps`: Mounts class names and inline styles after cloning. + - `observeAttributes`: Optionally observes attribute changes, combined with debounce for improved stability. + +```mermaid +flowchart TD +Enter(["ReactSlot Mount"]) --> CheckClone{"Clone?"} +CheckClone --> |Yes| Observe["MutationObserver watches slot changes"] +Observe --> Render["cloneElementWithEvents clones and generates portals"] +Render --> Inject["Inject class names/styles/mount props"] +Inject --> Append["Append to ref.current"] +CheckClone --> |No| DirectMount["Mount slot directly"] +DirectMount --> Append +Append --> Cleanup["On unmount: clean styles/remove nodes/disconnect observer"] +``` + +Diagram Sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) + +Section Sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +### Parameter Patching and Render Entry + +- patchSlots + - Wraps slot rendering functions, supporting prepending/appending external parameters to slot callbacks. + - Used for parent components to pass context parameters to child slots, enhancing slot configurability. +- renderSlot + - Provides a unified entry, supporting force cloning, parameter passing, and context wrapping. + - When `params` or `forceClone` is passed, wraps ReactSlot with `ContextPropsProvider` to ensure rendering consistency. + +```mermaid +sequenceDiagram +participant Caller as "Caller" +participant Patch as "patchSlots" +participant Render as "renderSlot" +participant RSlot as "ReactSlot" +Caller->>Patch : Pass params and transform +Patch-->>Caller : Return wrapped rendering function +Caller->>Render : Pass el and options (params/forceClone/clone) +Render->>Render : Determine if ContextPropsProvider wrapping is needed +Render-->>Caller : Return ReactSlot component +Caller->>RSlot : Render ReactSlot +RSlot-->>Caller : Clone and mount slot +``` + +Diagram Sources + +- [frontend/utils/patchSlots.ts:15-31](file://frontend/utils/patchSlots.ts#L15-L31) +- [frontend/utils/renderSlot.tsx:13-28](file://frontend/utils/renderSlot.tsx#L13-L28) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) + +Section Sources + +- [frontend/utils/patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) + +## Dependency Analysis + +- Component coupling + - Slot depends on the Svelte context API for slot registration and parameter mapping setting. + - ReactSlot depends on the structural characteristics of the slot DOM (such as internal portals and `svelte-slot` tags) for correct parsing and cloning. + - `renderSlot` and `patchSlots` provide general capabilities for the rendering pipeline, decoupled from specific components. +- External dependencies + - React, ReactDOM (Portal), MutationObserver, lodash-es (debounce and object judgment). +- Potential circular dependencies + - Avoided through utility layer and context layer separation, preventing direct circular references between components. + +```mermaid +graph LR +Slot["Slot (Index.svelte)"] --> Ctx["Svelte Context (slot.svelte)"] +Slot --> Patch["patchSlots.ts"] +Render["renderSlot.tsx"] --> RSlot["ReactSlot (react-slot.tsx)"] +Patch --> Render +Ctx --> Render +``` + +Diagram Sources + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/utils/patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +Section Sources + +- [frontend/base/slot/Index.svelte:1-68](file://frontend/base/slot/Index.svelte#L1-L68) +- [frontend/utils/patchSlots.ts:1-32](file://frontend/utils/patchSlots.ts#L1-L32) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +## Performance Considerations + +- Clone strategy + - Cloning brings extra DOM operations and event copying costs. Only enable `clone` when necessary to avoid unnecessary re-renders. +- Observer and debounce + - MutationObserver combined with debounce can reduce repeated cloning caused by frequent changes; it is recommended to enable `observeAttributes` and set a reasonable debounce interval in complex tables or high-frequency update scenarios. +- Style and class name injection + - Batch injecting styles and class names is better than individual operations, avoiding multiple reflows. +- Parameter passing + - Using `patchSlots` to prepend/append parameters reduces extra wrapping in intermediate layers, lowering the function call stack depth. + +## Troubleshooting Guide + +- Slot not working + - Check if the parent component has correctly registered the slot key and parameter mapping. + - Confirm if the Slot component's `value` is empty or unchanged (the `effect` only registers on change). +- Styles missing or class names not taking effect + - Confirm if ReactSlot correctly injected `className` and inline styles. + - Check for style isolation or overriding. +- Events not responding + - Confirm if `clone` is enabled; event copying logic depends on the cloning path. + - Check if event listeners have been overridden or removed. +- Updates not taking effect + - Confirm if `observeAttributes` is enabled, and if MutationObserver has been disconnected. + - Check if external code directly modified slot content without triggering observation. + +Section Sources + +- [frontend/svelte-preprocess-react/react-slot.tsx:156-212](file://frontend/svelte-preprocess-react/react-slot.tsx#L156-L212) +- [frontend/base/slot/Index.svelte:31-61](file://frontend/base/slot/Index.svelte#L31-L61) + +## Conclusion + +The Slot component implements cross-framework content distribution and dynamic rendering through Svelte and React bridging. Its design emphasizes: + +- Clear slot registration and parameter mapping mechanism; +- Stable rendering based on cloning and event copying; +- Optional observer and debounce strategies, balancing flexibility and performance; +- Utility layer abstraction (patchSlots, renderSlot) improving reusability and maintainability. + +## Appendix + +### Slot Types and Scopes + +- Slot types + - Named slots: Specify slot name via `value`; parent component receives by name. + - Nested slots: Child slots can contain slots again, forming multi-level content distribution. +- Scopes + - `params_mapping` supports mapping parent component context parameters to slot scope, enabling parameter-driven rendering. + +Section Sources + +- [docs/components/base/slot/README.md:13-16](file://docs/components/base/slot/README.md#L13-L16) +- [docs/components/base/slot/README-zh_CN.md:13-16](file://docs/components/base/slot/README-zh_CN.md#L13-L16) + +### Data Binding and Parent Component Communication + +- Parent components register slot keys and parameter mappings via the context API. +- The Slot component collects the child tree in Svelte and completes registration through `setSlot`. +- ReactSlot clones and mounts during the rendering phase, maintaining event and style consistency. + +Section Sources + +- [frontend/base/slot/Index.svelte:32-54](file://frontend/base/slot/Index.svelte#L32-L54) +- [frontend/svelte-preprocess-react/react-slot.tsx:109-223](file://frontend/svelte-preprocess-react/react-slot.tsx#L109-L223) + +### Usage Examples + +- Basic example: Insert title and extra button and icon slots into a Card component. +- Example path: [docs/components/base/slot/demos/basic.py:1-23](file://docs/components/base/slot/demos/basic.py#L1-L23) + +Section Sources + +- [docs/components/base/slot/demos/basic.py:1-23](file://docs/components/base/slot/demos/basic.py#L1-L23) + +### Best Practices + +- Only enable `clone` and `observeAttributes` when necessary, avoiding excessive rendering. +- Use `patchSlots` to prepend/append parameters, reducing intermediate wrapping. +- For complex tables and other high-frequency update scenarios, enable `observeAttributes` with debounce. +- Maintain the uniqueness and stability of slot keys, avoiding conflicts caused by duplicate registration. + +### Differences and Advantages Over Template Systems + +- Differences + - Template systems usually determine structure at compile time; the slot system dynamically distributes content at runtime. +- Advantages + - Stronger composability and extensibility, suitable for cross-framework and multi-component collaboration. + - Parameter mapping and context injection give slots stronger expressiveness and control. diff --git a/.wiki/en/Deployment Guide/Build Process.md b/.wiki/en/Deployment Guide/Build Process.md new file mode 100644 index 00000000..7de18962 --- /dev/null +++ b/.wiki/en/Deployment Guide/Build Process.md @@ -0,0 +1,405 @@ +# Build Process + + +**Files referenced in this document** +- [package.json](file://package.json) +- [pyproject.toml](file://pyproject.toml) +- [frontend/package.json](file://frontend/package.json) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [frontend/plugin.js](file://frontend/plugin.js) +- [frontend/tsconfig.json](file://frontend/tsconfig.json) +- [svelte-tsconfig.json](file://svelte-tsconfig.json) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) +- [frontend/antd/button/package.json](file://frontend/antd/button/package.json) +- [frontend/antd/button/gradio.config.js](file://frontend/antd/button/gradio.config.js) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) +- [frontend/svelte-preprocess-react/index.ts](file://frontend/svelte-preprocess-react/index.ts) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is intended for developers and operators who need to understand and maintain the build mechanism of ModelScope Studio. It systematically covers the following topics: + +- Frontend component build process: Vite configuration, Svelte component compilation, and React component bridging (svelte-preprocess-react). +- Python package build process: dependency installation, packaging configuration, version management, and publish scripts. +- Local build environment setup: key points for installing and configuring Node.js, Python, and pnpm. +- Build optimization techniques and performance tuning recommendations. +- Common build failure causes and solutions. + +## Project Structure + +The project is organized as a multi-package workspace (pnpm workspace). Core directories and their responsibilities: + +- **Root-level scripts and configuration**: package.json, pyproject.toml, pnpm-workspace.yaml, tsconfig.json, svelte-tsconfig.json. +- **Frontend**: the `frontend` directory and its sub-packages (antd, antdx, base, pro), plus the svelte-preprocess-react bridging layer. +- **Backend Python package**: backend/modelscope_studio, containing numerous component templates and version information. +- **Publish script**: scripts/publish-to-pypi.mts, used for building and publishing in CI. + +```mermaid +graph TB +subgraph "Root Workspace" +RootPkg["Root package.json"] +RootPy["Root pyproject.toml"] +WS["pnpm-workspace.yaml"] +TSRoot["tsconfig.json"] +SvelteTS["svelte-tsconfig.json"] +end +subgraph "Frontend" +FE_PKG["frontend/package.json"] +FE_CFG["frontend/defineConfig.js"] +FE_PLG["frontend/plugin.js"] +FE_TS["frontend/tsconfig.json"] +BTN_PKG["@modelscope-studio/antd-button/package.json"] +BTN_CFG["frontend/antd/button/gradio.config.js"] +BTN_IDX["frontend/antd/button/Index.svelte"] +BTN_TSX["frontend/antd/button/button.tsx"] +SPR_IDX["frontend/svelte-preprocess-react/index.ts"] +end +subgraph "Backend Python Package" +Backend["backend/modelscope_studio/..."] +VerPy["backend/modelscope_studio/version.py"] +end +subgraph "Publish Script" +Pub["scripts/publish-to-pypi.mts"] +end +RootPkg --> FE_PKG +RootPkg --> RootPy +WS --> FE_PKG +FE_CFG --> FE_PLG +FE_PKG --> BTN_PKG +BTN_CFG --> BTN_IDX +BTN_IDX --> BTN_TSX +BTN_TSX --> SPR_IDX +RootPy --> Backend +Pub --> RootPy +Pub --> RootPkg +``` + +**Diagram sources** + +- [package.json:1-55](file://package.json#L1-L55) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [frontend/defineConfig.js:1-19](file://frontend/defineConfig.js#L1-L19) +- [frontend/plugin.js:1-168](file://frontend/plugin.js#L1-L168) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) +- [svelte-tsconfig.json:1-4](file://svelte-tsconfig.json#L1-L4) +- [frontend/antd/button/package.json:1-15](file://frontend/antd/button/package.json#L1-L15) +- [frontend/antd/button/gradio.config.js:1-4](file://frontend/antd/button/gradio.config.js#L1-L4) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +**Section sources** + +- [package.json:1-55](file://package.json#L1-L55) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [frontend/defineConfig.js:1-19](file://frontend/defineConfig.js#L1-L19) +- [frontend/plugin.js:1-168](file://frontend/plugin.js#L1-L168) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) +- [svelte-tsconfig.json:1-4](file://svelte-tsconfig.json#L1-L4) + +## Core Components + +- **Root build scripts and commands**: Defined in the root `package.json`, providing a unified entry point for build, dev, version, and publish-related scripts. +- **Frontend Vite plugin**: `ModelScopeStudioVitePlugin` handles alias resolution, externalization, global variable mapping, and code transformation. +- **Svelte component bridge**: `svelte-preprocess-react` enables React components to be used in a Svelte style, handling slot and prop pass-through. +- **Python packaging**: `pyproject.toml` uses hatchling as the build backend, declaring `artifacts` and wheel inclusion paths to ensure template assets are correctly packaged. +- **Version management**: The Python package version is kept in sync with the frontend version, reflected jointly by `backend/modelscope_studio/version.py` and the root `package.json` version field. + +**Section sources** + +- [package.json:8-25](file://package.json#L8-L25) +- [frontend/plugin.js:41-168](file://frontend/plugin.js#L41-L168) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) +- [pyproject.toml:45-257](file://pyproject.toml#L45-L257) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) + +## Architecture Overview + +The diagram below shows the overall flow from "build command" to "artifact output", covering frontend Vite builds, React component bridging, Python packaging, and the publish script. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Root as "Root package.json" +participant Vite as "Vite Build" +participant Plugin as "ModelScopeStudioVitePlugin" +participant Svelte as "Svelte Compiler" +participant React as "React Component" +participant Py as "Python Packaging (hatch)" +participant Pub as "Publish Script (publish-to-pypi.mts)" +Dev->>Root : Run build script +Root->>Vite : Call gradio cc build +Vite->>Plugin : Apply plugin configuration and externalization +Vite->>Svelte : Compile Svelte components +Svelte->>React : Bridge via svelte-preprocess-react +Vite-->>Root : Generate dist +Root->>Py : Package using hatchling +Py-->>Root : Generate wheel/sdist +Dev->>Pub : Trigger publish process +Pub->>Py : Check whether version already exists +Pub->>Root : Run build and check +Pub->>Py : Upload with twine +``` + +**Diagram sources** + +- [package.json:8-25](file://package.json#L8-L25) +- [frontend/defineConfig.js:5-18](file://frontend/defineConfig.js#L5-L18) +- [frontend/plugin.js:41-76](file://frontend/plugin.js#L41-L76) +- [frontend/antd/button/Index.svelte:10-55](file://frontend/antd/button/Index.svelte#L10-L55) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [pyproject.toml:45-257](file://pyproject.toml#L45-L257) +- [scripts/publish-to-pypi.mts:22-55](file://scripts/publish-to-pypi.mts#L22-L55) + +## Detailed Component Analysis + +### Frontend Vite Build and Plugin + +- **Configuration entry**: `defineConfig.js` exports a function that returns a Vite default config object, integrating the React plugin and the custom `ModelScopeStudioVitePlugin`. +- **Plugin capabilities**: + - **Alias resolution**: `@utils`, `@globals`, `svelte-preprocess-react`. + - **Externalization strategy**: Marks a predefined set of modules as `external` during the build phase and injects global variable mappings, reducing bundle size. + - **Code transformation**: Traverses the AST and rewrites imports/exports to `window.ms_globals.*` accesses, enabling runtime dependency sharing. +- **Types and checking**: The frontend `tsconfig.json` extends the root tsconfig and enables ESNext module types; `svelte-tsconfig.json` is used for Svelte type checking. + +```mermaid +flowchart TD +Start(["Enter Vite Config"]) --> Alias["Configure aliases
@utils/@globals/svelte-preprocess-react"] +Alias --> External{"Externalization enabled?"} +External --> |Yes| MarkExt["Mark external list"] +External --> |No| SkipExt["Skip externalization"] +MarkExt --> DefineEnv["Define production environment constants"] +SkipExt --> DefineEnv +DefineEnv --> Transform["AST traversal and transformation
import/export -> window.ms_globals.*"] +Transform --> End(["Configuration complete"]) +``` + +**Diagram sources** + +- [frontend/defineConfig.js:5-18](file://frontend/defineConfig.js#L5-L18) +- [frontend/plugin.js:41-76](file://frontend/plugin.js#L41-L76) +- [frontend/plugin.js:77-167](file://frontend/plugin.js#L77-L167) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) +- [svelte-tsconfig.json:1-4](file://svelte-tsconfig.json#L1-L4) + +**Section sources** + +- [frontend/defineConfig.js:1-19](file://frontend/defineConfig.js#L1-L19) +- [frontend/plugin.js:1-168](file://frontend/plugin.js#L1-L168) +- [frontend/tsconfig.json:1-8](file://frontend/tsconfig.json#L1-L8) +- [svelte-tsconfig.json:1-4](file://svelte-tsconfig.json#L1-L4) + +### Svelte Component Compilation and React Bridging + +- **Component export**: Each frontend component package declares its Gradio entry (`Index.svelte`) via the `exports` field in its `package.json`. +- **Configuration inheritance**: The component-level `gradio.config.js` generates a unified configuration through `defineConfig`. +- **Component implementation**: + - **Svelte layer**: `Index.svelte` uses APIs from `svelte-preprocess-react` such as `getProps`, `processProps`, and `getSlots` to transform props and slots passed in by Gradio into forms usable by React components. + - **React layer**: `button.tsx` uses `sveltify` to wrap the Ant Design Button so it can be used by Svelte, supporting slots and children rendering. +- **Slots and props**: Complex child nodes and icon slots are rendered via `ReactSlot` and `useTargets`. + +```mermaid +sequenceDiagram +participant Gradio as "Gradio Runtime" +participant Svelte as "Index.svelte" +participant Bridge as "svelte-preprocess-react" +participant React as "button.tsx" +Gradio->>Svelte : Pass in props and slots +Svelte->>Bridge : getProps()/processProps()/getSlots() +Bridge-->>Svelte : Normalized props/slots +Svelte->>React : importComponent to load React component +React-->>Svelte : Render Ant Design Button +Svelte-->>Gradio : Output final DOM +``` + +**Diagram sources** + +- [frontend/antd/button/package.json:1-15](file://frontend/antd/button/package.json#L1-L15) +- [frontend/antd/button/gradio.config.js:1-4](file://frontend/antd/button/gradio.config.js#L1-L4) +- [frontend/antd/button/Index.svelte:10-55](file://frontend/antd/button/Index.svelte#L10-L55) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) + +**Section sources** + +- [frontend/antd/button/package.json:1-15](file://frontend/antd/button/package.json#L1-L15) +- [frontend/antd/button/gradio.config.js:1-4](file://frontend/antd/button/gradio.config.js#L1-L4) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) + +### Python Package Build and Publish + +- **Build backend**: `pyproject.toml` uses hatchling as the build backend, together with `hatch-requirements-txt` and `hatch-fancy-pypi-readme`. +- **Dependencies and metadata**: Declares Python version requirements, license, keywords, classifiers, and core dependencies (such as Gradio). +- **Packaging scope**: `tool.hatch.build.artifacts` explicitly lists numerous template directories to ensure frontend component templates are distributed with the package; wheel/sdist inclusion and exclusion rules are clearly defined. +- **Version synchronization**: The Python package version is kept in sync with the frontend version for unified publishing and tracking. +- **Publish script**: `scripts/publish-to-pypi.mts` handles installation, building, version checking, and twine upload in CI, preventing duplicate publishing. + +```mermaid +flowchart TD +A["Read root package.json version"] --> B["Install project in editable mode"] +B --> C["Run frontend build"] +C --> D{"dist exists?"} +D --> |No| E["Throw build failure error"] +D --> |Yes| F["Check if version already exists on PyPI"] +F --> |Exists| G["Skip publish"] +F --> |Not exists| H["twine upload dist/*"] +H --> I["Output published=true"] +``` + +**Diagram sources** + +- [pyproject.toml:1-44](file://pyproject.toml#L1-L44) +- [pyproject.toml:45-257](file://pyproject.toml#L45-L257) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [scripts/publish-to-pypi.mts:14-55](file://scripts/publish-to-pypi.mts#L14-L55) + +**Section sources** + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +## Dependency Analysis + +- **Workspace and package management**: `pnpm-workspace.yaml` declares the root, config, frontend, and sub-packages, ensuring cross-package reference and build consistency. +- **Frontend dependencies**: `frontend/package.json` specifies core dependencies such as React 19, Svelte 5, Ant Design 6, and Monaco Editor. +- **Externalization and aliases**: `ModelScopeStudioVitePlugin` maps React, ReactDOM, antd, antdx, etc. to `window.ms_globals.*`, reducing duplicate bundling. +- **Python dependencies**: `pyproject.toml` declares only the Gradio dependency; other frontend assets are bundled via artifacts and template directories. + +```mermaid +graph LR +WS["pnpm-workspace.yaml"] --> FE["frontend/package.json"] +FE --> React["react / react-dom"] +FE --> Svelte["svelte 5"] +FE --> Antd["antd 6"] +FE --> Monaco["monaco-editor"] +FE --> Gradio["@gradio/*"] +Py["pyproject.toml"] --> Hatch["hatchling"] +Py --> Artifacts["artifacts template collection"] +Py --> Wheel["wheel/sdist config"] +``` + +**Diagram sources** + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [frontend/package.json:8-40](file://frontend/package.json#L8-L40) +- [pyproject.toml:1-44](file://pyproject.toml#L1-L44) +- [pyproject.toml:45-257](file://pyproject.toml#L45-L257) + +**Section sources** + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) + +## Performance Considerations + +- **Externalization and shared dependencies**: Through `ModelScopeStudioVitePlugin`'s external configuration and global mappings, large packages such as React and antd are not bundled repeatedly, significantly reducing artifact size and build time. +- **AST transformation and lazy loading**: Rewriting imports/exports to global access at build time, combined with dynamic `import` (e.g., `importComponent`), enables lazy loading and improves initial load performance. +- **Module aliases**: Using `@utils`, `@globals`, and `svelte-preprocess-react` aliases appropriately reduces path resolution overhead. +- **Packaging granularity**: Precisely listing template directories in `artifacts` prevents unrelated files from entering the package, shortening packaging and publish time. +- **Type checking**: Enabling `svelte-check` and TypeScript type checking catches type issues early, reducing the cost of rollbacks caused by runtime errors. + +[This section provides general performance recommendations and does not directly reference specific files, so no "Section sources" are listed.] + +## Troubleshooting Guide + +- **Build failure (dist does not exist)** + - Symptom: The publish script reports "Build Failed". + - Investigation: Confirm that the frontend build command completed successfully; check whether `defineConfig` and plugin configuration are correctly applied. + - References: + - [scripts/publish-to-pypi.mts:22-30](file://scripts/publish-to-pypi.mts#L22-L30) + - [frontend/defineConfig.js:8-18](file://frontend/defineConfig.js#L8-L18) +- **Duplicate version publish** + - Symptom: The same version already exists on PyPI; the script skips publishing. + - Investigation: Confirm that the version number has not been changed, or manually clear the cache. + - References: + - [scripts/publish-to-pypi.mts:44-51](file://scripts/publish-to-pypi.mts#L44-L51) +- **Missing externalized dependency** + - Symptom: Runtime error — `window.ms_globals` is not defined. + - Investigation: Check the `external`/`excludes` configuration in `ModelScopeStudioVitePlugin` to confirm the global mapping covers all required dependencies. + - References: + - [frontend/plugin.js:41-76](file://frontend/plugin.js#L41-L76) + - [frontend/plugin.js:5-20](file://frontend/plugin.js#L5-L20) +- **Svelte/React slot rendering issue** + - Symptom: Slot content is not displayed, or icons/loading states do not work. + - Investigation: Confirm that `getProps`/`processProps`/`getSlots` in `Index.svelte` are used correctly, and that `ReactSlot` and `useTargets` in `button.tsx` behave as expected. + - References: + - [frontend/antd/button/Index.svelte:10-55](file://frontend/antd/button/Index.svelte#L10-L55) + - [frontend/antd/button/button.tsx:11-36](file://frontend/antd/button/button.tsx#L11-L36) +- **Python packaging missing templates** + - Symptom: Component templates are missing after installation. + - Investigation: Cross-check the `artifacts` list in `pyproject.toml` against the wheel/sdist inclusion paths. + - References: + - [pyproject.toml:45-257](file://pyproject.toml#L45-L257) + +**Section sources** + +- [scripts/publish-to-pypi.mts:22-51](file://scripts/publish-to-pypi.mts#L22-L51) +- [frontend/plugin.js:5-20](file://frontend/plugin.js#L5-L20) +- [frontend/antd/button/Index.svelte:10-55](file://frontend/antd/button/Index.svelte#L10-L55) +- [frontend/antd/button/button.tsx:11-36](file://frontend/antd/button/button.tsx#L11-L36) +- [pyproject.toml:45-257](file://pyproject.toml#L45-L257) + +## Conclusion + +The build system of this project revolves around a combination of "frontend Vite + Svelte + React bridging + Python packaging". Through externalized shared dependencies, AST transformation, and a precise template packaging strategy, it achieves efficient builds and stable runtime behavior. Following the configuration and troubleshooting recommendations in this document will effectively improve build stability and performance in both local and CI environments. + +[This section contains summary content and does not directly reference specific files, so no "Section sources" are listed.] + +## Appendix + +### Local Build Environment Setup + +- **Node.js** + - Version requirements: must satisfy the needs of frontend dependencies (React 19, Svelte 5, Ant Design 6). + - Package manager: use pnpm, consistent with the workspace configuration. + - References: + - [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) + - [frontend/package.json:8-40](file://frontend/package.json#L8-L40) +- **Python** + - Version requirements: must satisfy `requires-python` in `pyproject.toml`. + - Build tools: install hatchling and twine to ensure they are executable. + - References: + - [pyproject.toml:1-7](file://pyproject.toml#L1-L7) + - [pyproject.toml:42-43](file://pyproject.toml#L42-L43) +- **Frontend build** + - Run root scripts for building and development, ensuring that `defineConfig` and the plugin load correctly. + - References: + - [package.json:8-25](file://package.json#L8-L25) + - [frontend/defineConfig.js:5-18](file://frontend/defineConfig.js#L5-L18) + - [frontend/plugin.js:41-76](file://frontend/plugin.js#L41-L76) + +**Section sources** + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [pyproject.toml:1-44](file://pyproject.toml#L1-L44) +- [package.json:8-25](file://package.json#L8-L25) +- [frontend/defineConfig.js:1-19](file://frontend/defineConfig.js#L1-L19) +- [frontend/plugin.js:1-168](file://frontend/plugin.js#L1-L168) diff --git a/.wiki/en/Deployment Guide/CI CD.md b/.wiki/en/Deployment Guide/CI CD.md new file mode 100644 index 00000000..9cc946fa --- /dev/null +++ b/.wiki/en/Deployment Guide/CI CD.md @@ -0,0 +1,436 @@ +# CI/CD + + +**Files referenced in this document** +- [.github/workflows/lint.yaml](file://.github/workflows/lint.yaml) +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) +- [.changeset/config.json](file://.changeset/config.json) +- [.changeset/README.md](file://.changeset/README.md) +- [package.json](file://package.json) +- [pyproject.toml](file://pyproject.toml) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) +- [scripts/create-tag-n-release.mts](file://scripts/create-tag-n-release.mts) +- [eslint.config.mjs](file://eslint.config.mjs) +- [prettier.config.mjs](file://prettier.config.mjs) +- [.flake8](file://.flake8) +- [config/lint-config/eslint.mjs](file://config/lint-config/eslint.mjs) +- [.commitlintrc.js](file://.commitlintrc.js) +- [.lintstagedrc](file://.lintstagedrc) +- [.editorconfig](file://.editorconfig) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is intended for developers and operators who need to configure and maintain automated pipelines for ModelScope Studio. It systematically covers the following topics: + +- GitHub Actions workflows: configuration and execution logic for Lint and Publish +- Lint workflow integration: how ESLint, Prettier, Flake8, isort, yapf, and other tools are used in CI +- Publish workflow: version detection, build validation, PyPI publishing, tag and release creation +- Changesets usage: version updates, changelog generation, and release tag creation +- Custom workflows: how to extend and customize existing pipelines +- Troubleshooting and performance optimization recommendations + +## Project Structure + +The repository is a polyglot project: the frontend is built on Svelte/TypeScript, the backend is a Python package. Version and changelog management is unified through Changesets, and CI/CD is implemented with GitHub Actions. + +```mermaid +graph TB +subgraph "CI/CD Workflows" +LINT[".github/workflows/lint.yaml"] +PUBLISH[".github/workflows/publish.yaml"] +end +subgraph "Versioning & Changelog" +CHCFG[".changeset/config.json"] +CHREADM[".changeset/README.md"] +end +subgraph "Frontend & Scripts" +PKGJSON["package.json"] +ESLINTCFG["eslint.config.mjs"] +PRETTIERCFG["prettier.config.mjs"] +LINTSTAGED[".lintstagedrc"] +EDITOR[".editorconfig"] +SCRIPT_PUBLISH["scripts/publish-to-pypi.mts"] +SCRIPT_TAGREL["scripts/create-tag-n-release.mts"] +end +subgraph "Python Package" +PYPROJ["pyproject.toml"] +FLAKE8[".flake8"] +end +LINT --> PKGJSON +PUBLISH --> PKGJSON +PUBLISH --> SCRIPT_PUBLISH +PUBLISH --> SCRIPT_TAGREL +PKGJSON --> ESLINTCFG +PKGJSON --> PRETTIERCFG +PKGJSON --> LINTSTAGED +PKGJSON --> EDITOR +PKGJSON --> CHCFG +PKGJSON --> CHREADM +PKGJSON --> PYPROJ +PYPROJ --> FLAKE8 +``` + +Diagram sources + +- [.github/workflows/lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/README.md:1-9](file://.changeset/README.md#L1-L9) +- [package.json:1-55](file://package.json#L1-L55) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- [eslint.config.mjs:1-9](file://eslint.config.mjs#L1-L9) +- [prettier.config.mjs:1-26](file://prettier.config.mjs#L1-L26) +- [.lintstagedrc:1-7](file://.lintstagedrc#L1-L7) +- [.editorconfig:1-17](file://.editorconfig#L1-L17) +- [.flake8:1-16](file://.flake8#L1-L16) + +Section sources + +- [.github/workflows/lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [package.json:1-55](file://package.json#L1-L55) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) + +## Core Components + +- **Lint Workflow**: Triggered on push and pull requests. Installs Python and Node dependencies, then runs the unified lint script. +- **Publish Workflow**: Triggered on pushes to main/next branches. Determines whether to execute version updates and publishing based on the commit message, and ultimately creates a Git tag and GitHub Release. +- **Changesets**: Centralized version and changelog management. Works with scripts to write version numbers and fix changelogs. +- **Publish Script**: Checks whether the target version already exists on PyPI, builds artifacts, uploads to PyPI, and sets a published output flag for downstream steps. +- **Tag & Release Script**: Aggregates changelogs from all packages, creates a Git tag, and creates a GitHub Release. + +Section sources + +- [.github/workflows/lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [package.json:8-25](file://package.json#L8-L25) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) + +## Architecture Overview + +The diagram below shows the critical path and decision points from code commit to release. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant GH as "GitHub" +participant LINT as "Lint Workflow" +participant PUBLISH as "Publish Workflow" +participant PYPI as "PyPI" +participant TAGREL as "Tag & Release Script" +Dev->>GH : Push commit / open PR +GH->>LINT : Trigger Lint (push/pull_request) +LINT-->>GH : Lint result +Dev->>GH : Push to main/next +GH->>PUBLISH : Trigger Publish (push) +PUBLISH->>PUBLISH : Check if commit message is "update versions" +alt "update versions" commit +PUBLISH->>PYPI : Build and upload +PYPI-->>PUBLISH : Upload result +PUBLISH->>TAGREL : Create Tag and Release +TAGREL-->>GH : Release complete +else Not an "update versions" commit +PUBLISH-->>GH : Skip publish steps +end +``` + +Diagram sources + +- [.github/workflows/lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +## Detailed Component Analysis + +### Lint Workflow Configuration and Execution + +- **Trigger conditions**: push and pull_request +- **Concurrency control**: Only one running instance is retained per workflow per branch +- **Step overview**: + - Check out code (full history) + - Install Python dependencies (flake8, isort, yapf) + - Install Node.js and pnpm + - Install Node dependencies + - Run the unified lint script (JS/TS linting and formatting run in parallel) + +```mermaid +flowchart TD +Start(["Start"]) --> Checkout["Check Out Code"] +Checkout --> PySetup["Set Up Python 3.9"] +PySetup --> PyDeps["Install Python Dependencies"] +PyDeps --> NodeSetup["Set Up Node.js 20"] +NodeSetup --> PNPM["Install pnpm"] +PNPM --> NPMInstall["Install Node Dependencies"] +NPMInstall --> RunLint["Run Unified Lint Script"] +RunLint --> End(["End"]) +``` + +Diagram sources + +- [.github/workflows/lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) + +Section sources + +- [.github/workflows/lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) +- [package.json:18-22](file://package.json#L18-L22) +- [.lintstagedrc:1-7](file://.lintstagedrc#L1-L7) +- [.editorconfig:1-17](file://.editorconfig#L1-L17) +- [.flake8:1-16](file://.flake8#L1-L16) + +### Publish Workflow Configuration and Execution + +- **Trigger conditions**: Push to main or next branch +- **Concurrency control**: Independent group to avoid concurrent conflicts +- **Key steps**: + - **Conditional execution**: Subsequent steps run only when the commit message is "update versions" + - **Build and publish**: Invokes the publish script with the PyPI token + - **Tag and release**: If publishing succeeds, invokes the tag and release script with the GitHub token, repository name, and owner + +```mermaid +flowchart TD +PS(["Start"]) --> CheckCommit["Check if commit message is 'update versions'"] +CheckCommit --> |No| Skip["Skip publish steps"] +CheckCommit --> |Yes| Build["Install Python/Node dependencies"] +Build --> Publish["Run publish script to upload to PyPI"] +Publish --> Published{"Publish successful?"} +Published --> |No| End(["End"]) +Published --> |Yes| TagRel["Create Git Tag and publish to GitHub"] +TagRel --> End +``` + +Diagram sources + +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +Section sources + +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) + +### Changesets Version and Changelog Management + +- **Configuration highlights**: + - Uses a custom changelog generator with the repository URL specified + - Base branch is `main` + - Internal dependency update strategy is patch +- **Common commands**: + - Version update and changelog fix: executed by the root script + - CLI interactive version selection and change recording + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant CS as "Changesets CLI" +participant Root as "Root Script" +participant Changelog as "Changelog Generator" +Dev->>CS : Add/edit changeset +Dev->>Root : Run version update script +Root->>CS : Execute version update +CS-->>Root : Generate version numbers and changelogs +Root->>Changelog : Fix/aggregate changelogs +Changelog-->>Dev : Output changelog files +``` + +Diagram sources + +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [package.json](file://package.json#L24) + +Section sources + +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/README.md:1-9](file://.changeset/README.md#L1-L9) +- [package.json:8-25](file://package.json#L8-L25) + +### Publish Script: Version Detection, Build, and Upload + +- **Functionality overview**: + - Checks whether the target version already exists on PyPI; skips if it does + - Installs editable-mode dependencies and runs the build + - Verifies that the dist directory exists + - Uploads to PyPI with twine, skipping already-existing files + - Sets a published-success output flag for subsequent steps + +```mermaid +flowchart TD +S(["Start"]) --> Exists["Check if version already exists on PyPI"] +Exists --> |Exists| Warn["Skip and output notice"] --> End(["End"]) +Exists --> |Not exists| Install["Install editable dependencies"] +Install --> Build["Run build"] +Build --> Dist{"dist directory exists?"} +Dist --> |No| Fail["Throw build failure error"] --> End +Dist --> |Yes| Upload["Upload with twine"] +Upload --> SetOut["Set published-success output flag"] +SetOut --> End +``` + +Diagram sources + +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +Section sources + +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +### Tag & Release Script: Aggregating Changelogs, Creating Tag and Release + +- **Functionality overview**: + - Reads the root changelog and per-package changelogs, aggregated by version + - Configures Git user information + - Creates a tag with a `v` prefix and pushes it to the remote + - Calls the GitHub API to create a Release; the pre-release flag is determined based on the version number + +```mermaid +sequenceDiagram +participant Script as "Tag & Release Script" +participant FS as "File System" +participant Git as "Git" +participant GH as "GitHub API" +Script->>FS : Read root and per-package changelogs +Script->>Script : Parse change entries by version +Script->>Git : Configure user name and email +Script->>Git : Create tag and push +Script->>GH : Create Release (with pre-release flag) +GH-->>Script : Return result +``` + +Diagram sources + +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +Section sources + +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +### Lint Toolchain and Configuration + +- **ESLint**: Imports the unified lint configuration set from the root config +- **Prettier**: Unified formatting rules and plugins, supporting Svelte and package.json +- **Flake8**: Python static analysis, ignoring specific rules and directories +- **isort/yapf**: Python import sorting and formatting +- **Stylelint**: Style file checking (invoked via script) +- **Commit convention**: commitlint based on Conventional Commits + +Section sources + +- [eslint.config.mjs:1-9](file://eslint.config.mjs#L1-L9) +- [config/lint-config/eslint.mjs:1-11](file://config/lint-config/eslint.mjs#L1-L11) +- [prettier.config.mjs:1-26](file://prettier.config.mjs#L1-L26) +- [.lintstagedrc:1-7](file://.lintstagedrc#L1-L7) +- [.flake8:1-16](file://.flake8#L1-L16) +- [.commitlintrc.js:1-30](file://.commitlintrc.js#L1-L30) +- [.editorconfig:1-17](file://.editorconfig#L1-L17) + +## Dependency Analysis + +- **Workflow dependency on scripts**: The publish workflow directly invokes the publish and tag scripts +- **Script dependency on tools**: The publish script depends on twine and the build toolchain; the tag script depends on the GitHub API and Git +- **Language ecosystem dependencies**: The frontend uses pnpm for dependency management; Python uses hatchling for building and twine for uploading +- **Version and changelog**: Changesets and root scripts jointly drive version number and changelog generation + +```mermaid +graph LR +LINTWF[".github/workflows/lint.yaml"] --> PKG["package.json scripts"] +PUBWF[".github/workflows/publish.yaml"] --> PUBLISH["scripts/publish-to-pypi.mts"] +PUBWF --> TAGREL["scripts/create-tag-n-release.mts"] +PUBLISH --> TWINE["twine upload"] +PUBLISH --> BUILD["Build artifacts"] +TAGREL --> GHAPI["GitHub API"] +TAGREL --> GIT["Git tags"] +PKG --> ESL["ESLint/Prettier/Stylelint"] +PKG --> PY["Python deps (flake8/isort/yapf)"] +PY --> PYPROJ["pyproject.toml"] +``` + +Diagram sources + +- [.github/workflows/lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- [package.json:8-25](file://package.json#L8-L25) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) + +Section sources + +- [package.json:1-55](file://package.json#L1-L55) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) + +## Performance Considerations + +- **Caching and concurrency**: Make proper use of caching and concurrency control to avoid redundant installs and builds +- **Task splitting**: Separating Lint and build into independent steps facilitates parallelism and retries +- **Dependency minimization**: Install only the extra dependencies needed to reduce image size and wait time +- **Fail fast**: Exit early when a version already exists or a build fails to conserve resources + +## Troubleshooting Guide + +- **PyPI version already exists** + - Symptom: The publish script skips the upload and outputs a notice + - Resolution: Confirm whether the version number has been correctly updated, or clear the cache and retry +- **Missing build artifacts** + - Symptom: No `dist` directory generated after build, causing failure + - Resolution: Check whether the build script and dependency installation completed successfully +- **Upload failure (permissions / token)** + - Symptom: twine upload reports an error + - Resolution: Confirm that `PYPI_TOKEN` is configured and valid +- **Tag and Release failure** + - Symptom: GitHub API throws an exception or changelog is not found + - Resolution: Check whether changelog generation is working correctly and confirm the version number matches the tag +- **Lint failure** + - Symptom: ESLint / Prettier / Flake8 reports errors + - Resolution: Fix the code or adjust the rules according to the error messages; ensure local and CI use the same configuration + +Section sources + +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- [package.json:18-22](file://package.json#L18-L22) +- [.lintstagedrc:1-7](file://.lintstagedrc#L1-L7) +- [.flake8:1-16](file://.flake8#L1-L16) + +## Conclusion + +The CI/CD system in this repository is built around GitHub Actions, Changesets, and a set of Node/Python toolchains, implementing an end-to-end pipeline from code linting to version publishing. Through clear workflow separation, strict version and changelog management, and reusable publish and tag scripts, the team can deliver products efficiently and reliably. + +## Appendix + +### Custom Workflow Recommendations + +- **Adding lint rules**: Extend ESLint/Prettier rules in the root config and sync them to `.lintstagedrc` +- **Adding languages or tools**: Add scripts and dependencies in `package.json`, and add corresponding steps in the workflow +- **Publish strategy**: Adjust trigger branches and conditional checks as needed to ensure publishing only occurs on "update versions" commits +- **Security and secrets**: Strictly manage `PYPI_TOKEN` and `GITHUB_TOKEN`, restricting their scope and access + +### Reference File Index + +- Lint workflow: [lint.yaml:1-34](file://.github/workflows/lint.yaml#L1-L34) +- Publish workflow: [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- Changesets config: [config.json:1-15](file://.changeset/config.json#L1-L15) +- Root scripts and toolchain: [package.json:8-25](file://package.json#L8-L25) +- Python build and publish: [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- Publish script: [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- Tag and release script: [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- Lint configuration: [eslint.config.mjs:1-9](file://eslint.config.mjs#L1-L9), [prettier.config.mjs:1-26](file://prettier.config.mjs#L1-L26), [lint-staged config:1-7](file://.lintstagedrc#L1-L7), [flake8 config:1-16](file://.flake8#L1-L16) +- Commit convention: [commitlint config:1-30](file://.commitlintrc.js#L1-L30) +- Editor configuration: [EditorConfig:1-17](file://.editorconfig#L1-L17) diff --git a/.wiki/en/Deployment Guide/Deployment Guide.md b/.wiki/en/Deployment Guide/Deployment Guide.md new file mode 100644 index 00000000..cc1811de --- /dev/null +++ b/.wiki/en/Deployment Guide/Deployment Guide.md @@ -0,0 +1,333 @@ +# Deployment Guide + + +**Files Referenced in This Document** +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) +- [.github/workflows/lint.yaml](file://.github/workflows/lint.yaml) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) +- [scripts/create-tag-n-release.mts](file://scripts/create-tag-n-release.mts) +- [frontend/package.json](file://frontend/package.json) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [frontend/plugin.js](file://frontend/plugin.js) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) +- [README.md](file://README.md) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This guide is intended for operations personnel and developers, providing a systematic explanation of ModelScope Studio's build process, release strategy, and deployment practices, covering the following topics: + +- Frontend component build and packaging strategy +- Python package build and publishing to PyPI +- CI/CD pipeline configuration and usage +- Configuration methods for different deployment environments (local development, production, cloud platforms) +- Performance optimization and monitoring recommendations +- Common issue troubleshooting and solutions + +## Project Structure + +The project uses a multi-package workspace organization, with the root directory managing frontend sub-packages and configuration modules uniformly via pnpm workspaces. The backend Python package is in the `backend/modelscope_studio` directory and defines build and packaging rules via `pyproject.toml`. + +```mermaid +graph TB +Root["Repository Root"] --> Backend["Backend Python Package
backend/modelscope_studio"] +Root --> Frontend["Frontend Workspace
frontend/*"] +Root --> Config["Configuration Toolset
config/*"] +Root --> Scripts["Release Scripts
scripts/*"] +Root --> Workflows["CI/CD Pipelines
.github/workflows/*"] +Frontend --> Antd["Ant Design Component Library
frontend/antd/*"] +Frontend --> Antdx["Ant Design X Component Library
frontend/antdx/*"] +Frontend --> Pro["Pro Component Library
frontend/pro/*"] +Frontend --> Base["Base Component Library
frontend/base/*"] +``` + +Chart Sources + +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [frontend/package.json](file://frontend/package.json) +- [pyproject.toml](file://pyproject.toml) + +Section Sources + +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [frontend/package.json](file://frontend/package.json) +- [pyproject.toml](file://pyproject.toml) + +## Core Components + +- Build and Packaging + - Frontend: Based on Vite and custom plugins, implements React/Svelte mixed compilation and externalization strategies, outputting component assets usable by Gradio. + - Backend: Built using Hatchling, packaging templates and component assets into the Python package via toolchain. +- Release and Version Management + - Uses Changesets for version and changelog management; CI executes build, upload to PyPI, creation of Git Tag, and GitHub Release. +- Quality Assurance + - Lint pipeline runs on PRs and pushes to ensure consistent code style and static checks. + +Section Sources + +- [package.json](file://package.json) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [frontend/plugin.js](file://frontend/plugin.js) +- [pyproject.toml](file://pyproject.toml) +- [.github/workflows/lint.yaml](file://.github/workflows/lint.yaml) + +## Architecture Overview + +The diagram below shows the complete deployment path from local to cloud: Local development build → CI trigger → PyPI publishing → Tag and Release creation. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Local as "Local Build" +participant GH as "GitHub Actions" +participant PyPI as "PyPI" +participant Git as "Git Repository" +Dev->>Local : Execute build script +Local-->>Dev : Output dist/ frontend artifacts +Dev->>GH : Push branch / trigger pipeline +GH->>GH : Fetch code / install dependencies +GH->>GH : Build Python package and validate version +GH->>PyPI : Upload wheel and source package +PyPI-->>GH : Return publish result +GH->>Git : Create Tag and push +GH->>Git : Create GitHub Release +``` + +Chart Sources + +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) +- [scripts/create-tag-n-release.mts](file://scripts/create-tag-n-release.mts) + +## Detailed Component Analysis + +### Frontend Build and Packaging + +- Build Entry and Commands + - The build script in the root `package.json` calls the Gradio custom component CLI for building (using `--no-generate-docs` to disable automatic documentation generation for faster builds). + - Full command: `rimraf dist && gradio cc build --no-generate-docs` +- Vite Plugins and Aliases + - The custom Vite plugin is responsible for: + - Setting environment variables to production mode during the build phase + - Externalizing specified dependencies to reduce bundle size + - Transforming import/export statements via Babel AST to map modules to global objects, enabling on-demand loading in browser environments + - Alias mappings to utility and global component modules improve development experience and consistency. +- Externalization Strategy + - React, Ant Design, and their ecosystems are externalized to avoid duplicate bundling, reducing bundle size and improving cache hit rate. + +```mermaid +flowchart TD +Start(["Start Build"]) --> LoadCfg["Load Vite config and plugins"] +LoadCfg --> SetEnv["Set production environment variables"] +SetEnv --> Externalize["Configure externalized dependency list"] +Externalize --> Alias["Configure module aliases"] +Alias --> Transform["Babel AST transform imports/exports"] +Transform --> Bundle["Rollup bundle artifacts"] +Bundle --> End(["Done"]) +``` + +Chart Sources + +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [frontend/plugin.js](file://frontend/plugin.js) + +Section Sources + +- [package.json](file://package.json) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [frontend/plugin.js](file://frontend/plugin.js) + +### Python Package Build and Release + +- Build System and Metadata + - Uses Hatchling as the build backend, declares dependencies and optional dependencies, defines classifiers and keywords. +- Asset Packaging + - A large number of component templates and static assets are included in the packaging scope via toolchain, ensuring they are directly available at runtime. +- Version and Metadata + - Root `pyproject.toml` stays consistent with the backend version file, ensuring unified release version numbers. + +```mermaid +flowchart TD +A["Read pyproject.toml metadata"] --> B["Install build dependencies"] +B --> C["Execute build command to generate dist/"] +C --> D{"Does dist/ exist?"} +D --> |No| E["Throw build failure error"] +D --> |Yes| F["Check if version already exists on PyPI"] +F --> |Exists| G["Skip publishing"] +F --> |Not Exists| H["Use Twine to upload to PyPI"] +H --> I["Mark publish as successful"] +``` + +Chart Sources + +- [pyproject.toml](file://pyproject.toml) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) + +Section Sources + +- [pyproject.toml](file://pyproject.toml) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) + +### CI/CD Pipeline + +- Publish Pipeline + - Trigger: Push to `main` or `next` branch + - Steps: Install Python and Node.js, install pnpm, install dependencies, build frontend and backend, upload to PyPI, create Tag and Release +- Lint Pipeline + - Trigger: Push and Pull Requests + - Steps: Install Python and Node.js, install dependencies, run Lint tasks + +```mermaid +sequenceDiagram +participant Push as "Push Event" +participant PubWF as "Publish Pipeline" +participant LintWF as "Lint Pipeline" +participant PyPI as "PyPI" +participant GH as "GitHub" +Push->>PubWF : Trigger publish +PubWF->>PubWF : Install dependencies / build +PubWF->>PyPI : Upload package +PubWF->>GH : Create Tag and Release +Push->>LintWF : Trigger Lint +LintWF->>LintWF : Run code style and static checks +``` + +Chart Sources + +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) +- [.github/workflows/lint.yaml](file://.github/workflows/lint.yaml) + +Section Sources + +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) +- [.github/workflows/lint.yaml](file://.github/workflows/lint.yaml) + +### Version and Changelog Management + +- Changesets + - Uses Changesets for version bumping and changelog generation, combined with scripts to automatically execute version updates and fixes in CI. +- Tags and Releases + - After a successful release, scripts generate unified Release content from the root and sub-package changelogs, create a Git Tag, and push to remote. + +Section Sources + +- [package.json](file://package.json) +- [scripts/create-tag-n-release.mts](file://scripts/create-tag-n-release.mts) + +## Dependency Analysis + +- Frontend Dependencies + - React and Svelte ecosystems, Ant Design and Ant Design X, Monaco Editor, Mermaid, etc., form the core capabilities of the component library. +- Build Tools + - Vite, @vitejs/plugin-react-swc, Babel, Rollup (driven by Vite) +- Python Dependencies + - Gradio as the runtime framework, Hatchling for building, Twine for uploading + +```mermaid +graph LR +FE["Frontend Build"] --> Vite["Vite"] +FE --> Babel["Babel"] +FE --> Rollup["Rollup"] +BE["Backend Build"] --> Hatch["Hatchling"] +BE --> Gradio["Gradio"] +Pub["Release"] --> Twine["Twine"] +Pub --> PyPI["PyPI"] +``` + +Chart Sources + +- [frontend/package.json](file://frontend/package.json) +- [pyproject.toml](file://pyproject.toml) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) + +Section Sources + +- [frontend/package.json](file://frontend/package.json) +- [pyproject.toml](file://pyproject.toml) + +## Performance Considerations + +- Frontend Bundle Optimization + - Externalization strategy: Externalizes large dependencies such as React and Ant Design to reduce bundle size and duplicate bundling. + - AST transformation: The plugin transforms imports/exports to global access at build time, avoiding redundant runtime logic. + - On-demand loading: Combined with Gradio's loading mechanism, component assets are only loaded when needed. +- Build Efficiency + - Disabling the documentation generation build option can significantly reduce frontend build time. + - Using pnpm workspaces to unify dependencies reduces disk usage and installation time. +- Python Package Size + - Only package the necessary templates and assets to avoid unnecessary files entering the distribution package. + +Section Sources + +- [frontend/plugin.js](file://frontend/plugin.js) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [package.json](file://package.json) +- [pyproject.toml](file://pyproject.toml) + +## Troubleshooting Guide + +- Build Failure + - Symptom: `dist/` not generated or build errors + - Investigation: Confirm the frontend build script executed, verify Node.js and pnpm versions meet requirements, check dependency installation success + - Reference: Root `package.json` build scripts and frontend `defineConfig` configuration +- PyPI Upload Failure + - Symptom: Twine upload error or version already exists + - Investigation: Check whether `PYPI_TOKEN` is correctly configured, whether the version already exists on PyPI, and network connectivity + - Reference: Version check and upload logic in the publish script +- CI Pipeline Interruption + - Symptom: Lint or publish step fails + - Investigation: Check the corresponding workflow logs, confirm environment variables and permissions, verify trigger conditions + - Reference: `lint` and `publish` workflow configurations +- Documentation and Examples + - Reference: Root README installation and quick start instructions to ensure local development environment and dependency versions are consistent + +Section Sources + +- [package.json](file://package.json) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) +- [.github/workflows/lint.yaml](file://.github/workflows/lint.yaml) +- [README.md](file://README.md) + +## Conclusion + +This guide provides an integrated deployment solution from local to cloud: optimizing bundle size via frontend Vite plugins and externalization strategies, achieving stable Python package publishing with Hatchling and Twine, and completing automated pipelines and version management with GitHub Actions. For production and cloud platform deployments, it is recommended to further optimize loading performance by combining externalization and caching strategies, and to continuously run Lint in CI to maintain quality. + +## Appendix + +### Configuration Methods for Different Deployment Environments + +- Local Development + - Install dependencies: use pnpm to install workspace dependencies + - Start development server: run the Gradio custom component development command + - Reference: Root README development instructions and `package.json` scripts +- Production Environment + - Build artifacts: execute the frontend build script to generate `dist/`, ensure externalized dependencies are available at runtime + - Python package: build with Hatchling, ensure templates and assets are packaged +- Cloud Platform Deployment + - Use CI to trigger the publish pipeline, automatically upload to PyPI and create Tag/Release + - Install the Python package on the target platform and start the application + +Section Sources + +- [README.md](file://README.md) +- [package.json](file://package.json) +- [pyproject.toml](file://pyproject.toml) +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) diff --git a/.wiki/en/Deployment Guide/Environment Configuration.md b/.wiki/en/Deployment Guide/Environment Configuration.md new file mode 100644 index 00000000..0fb2becd --- /dev/null +++ b/.wiki/en/Deployment Guide/Environment Configuration.md @@ -0,0 +1,315 @@ +# Environment Configuration + + +**Files Referenced in This Document** +- [README.md](file://README.md) +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [docs/app.py](file://docs/app.py) +- [frontend/package.json](file://frontend/package.json) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [backend/modelscope_studio/utils/dev/app_context.py](file://backend/modelscope_studio/utils/dev/app_context.py) +- [backend/modelscope_studio/utils/dev/process_links.py](file://backend/modelscope_studio/utils/dev/process_links.py) +- [backend/modelscope_studio/utils/dev/resolve_frontend_dir.py](file://backend/modelscope_studio/utils/dev/resolve_frontend_dir.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is intended for operations personnel and developers, providing environment configuration and deployment best practices for ModelScope Studio, covering configuration essentials for local development, testing, and production environments, including environment variables, dependency management, containerization (Docker/Kubernetes), performance monitoring, log configuration, environment migration and upgrade strategies, as well as deployment differences and considerations across different platforms. + +## Project Structure + +The repository uses a multi-package workspace organization. The backend is published as a Python package, the frontend is built with Svelte + Vite, and the documentation site is started via Gradio CC. Key directories and responsibilities: + +- `backend/modelscope_studio`: Python backend components and utilities +- `frontend`: Frontend components and build configuration +- `docs`: Documentation site and example application +- `config`: Shared Lint and changelog configuration +- Root-level configuration: `pyproject.toml` (Python packaging), `package.json` (Node workspace scripts), `pnpm-workspace.yaml` (workspace definition) + +```mermaid +graph TB +A["Root Directory"] --> B["backend/modelscope_studio
Python Package and Components"] +A --> C["frontend
Svelte/Vite Frontend"] +A --> D["docs
Gradio CC Documentation Site"] +A --> E["config
Shared Configuration"] +A --> F["pyproject.toml
Python Packaging and Metadata"] +A --> G["package.json
Node Workspace Scripts"] +A --> H["pnpm-workspace.yaml
Workspace and Build-only Dependencies"] +``` + +**Chart Sources** + +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) + +**Section Sources** + +- [README.md](file://README.md) +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) + +## Core Components + +- Python Packaging and Distribution: Built using Hatchling, including a backend component template manifest and packaging targets +- Node Workspace: Unified scripts and dependency management, supporting parallel development across multiple sub-packages +- Documentation Site: `docs/app.py` based on Gradio CC, providing visual documentation for components and layout templates +- Frontend Build: Vite + React SWC plugin, combined with custom plugins and Svelte preprocessing + +**Section Sources** + +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [docs/app.py](file://docs/app.py) +- [frontend/package.json](file://frontend/package.json) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) + +## Architecture Overview + +The diagram below shows the key path from development to runtime: local development starts `docs/app.py` via Gradio CC; the build phase is completed jointly by frontend Vite and backend packaging; at runtime, the Python backend and frontend static assets collaborate to serve the application. + +```mermaid +graph TB +Dev["Developer"] --> CC["Gradio CC Development Server
docs/app.py"] +CC --> FE["Frontend Build
Vite + Plugins"] +FE --> Dist["Static Asset Artifacts"] +CC --> Py["Python Backend Components
modelscope_studio"] +Py --> Serve["Service Startup and Page Rendering"] +Dist --> Serve +``` + +**Chart Sources** + +- [docs/app.py](file://docs/app.py) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [frontend/package.json](file://frontend/package.json) +- [pyproject.toml](file://pyproject.toml) + +## Detailed Component Analysis + +### Environment Variables and Runtime Parameters + +- The documentation site's default concurrency and thread count are set at the entry point and can be adjusted to fit the throughput and resource limits of different environments +- Development mode is triggered via environment variables to enable Gradio Watch Module for hot reloading and debugging + +Recommended environment variables and purposes (examples, not fixed values): + +- `GRADIO_WATCH_MODULE_NAME`: Used to enable development listening +- `PYTHONPATH` or workspace path: Ensures Python can import backend packages +- `NODE_ENV`: Controls frontend build mode (development/production) +- `PORT`/`APP_HOST`: Service listening address and port (if customization is needed) + +**Section Sources** + +- [docs/app.py](file://docs/app.py) +- [package.json](file://package.json) + +### Dependency Management Strategy + +- Python Dependencies + - Core dependency: Gradio version range constraints + - Packaging and distribution: Hatchling + hatch-requirements-txt + - Template manifest: The build phase includes a large number of frontend template directories to ensure complete artifacts +- Node.js Dependencies + - Workspace: pnpm workspace + build-only dependency declarations + - Scripts: Unified commands for building, developing, formatting, checking, etc. + - Frontend dependencies: React, Svelte, Ant Design, Monaco Editor, etc. +- Workspace Configuration + - `pnpm-workspace.yaml` defines `packages` and `onlyBuiltDependencies`, reducing unnecessary build overhead + +**Section Sources** + +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [frontend/package.json](file://frontend/package.json) + +### Containerized Deployment (Docker and Kubernetes) + +The following are general practice steps; specific images and orchestration need to be customized according to the actual environment: + +- Docker Build Process + - Base image: Select a base image containing Python and Node + - Install dependencies: Install system dependencies first, then Python and Node dependencies + - Build backend: Install the backend package with pip or in editable mode + - Build frontend: Execute the frontend build script to generate static assets + - Run: Start the Python service and serve static assets +- Kubernetes Deployment + - Use Deployments to manage Pod replicas + - Use Services to expose the service + - Use ConfigMap/Secret to manage environment variables and sensitive information + - Use PersistentVolume/PVC to store logs and temporary files (if needed) + - Health checks: Configure liveness/readiness probes + - Resource limits: Set CPU/memory requests and limits based on concurrency and thread configuration + +[This section provides general practice guidance and does not analyze specific files, so there are no "Section Sources"] + +### Performance Monitoring and Log Configuration + +- Performance Monitoring + - At the Python level: Record request latency, queue length, concurrency limits, and other metrics + - At the frontend level: Monitor first contentful paint time, resource load time, error rate + - At the container level: Collect CPU/memory/network metrics, combined with logs for correlation analysis +- Log Configuration + - Python: Use the standard logging module, output to stdout/stderr based on environment, combined with container log collection + - Frontend: Avoid outputting excessive debug logs in production; use conditional logging when necessary + - Documentation site: Note the impact of concurrency and thread configuration on resource usage + +[This section provides general practice guidance and does not analyze specific files, so there are no "Section Sources"] + +### Environment Migration and Upgrade + +- Python Upgrade + - Update Python version requirements and dependency version ranges to ensure compatibility + - Repackage and verify build artifact completeness +- Node Upgrade + - Update Node version and dependencies, run lint and type checks + - Rebuild frontend and verify static asset availability +- Documentation Site Upgrade + - Update Gradio CC version and related dependencies + - Verify rendering consistency of each component and layout template +- Migration Strategy + - Small steps: Gradually replace old components and templates + - Rollback plan: Keep the previous version's image and configuration to ensure fast rollback + - Data and configuration: Ensure backward compatibility of environment variables and configuration files + +[This section provides general practice guidance and does not analyze specific files, so there are no "Section Sources"] + +### Deployment Differences and Considerations Across Platforms + +- Local Development + - Use Gradio CC's development server with hot reloading enabled + - Pay attention to cross-platform path and permission issues +- Testing Environment + - Independent services and storage isolated from production + - Strictly control concurrency and thread count to simulate real load +- Production Environment + - Use stable versions and long-term support base images + - Configure health checks and auto-scaling + - Strict logging and monitoring strategies + +[This section provides general practice guidance and does not analyze specific files, so there are no "Section Sources"] + +## Dependency Analysis + +- Python Side + - Dependencies: Gradio version range constraints + - Packaging: Hatchling build, `artifacts` list contains a large number of frontend template directories +- Node Side + - Workspace: `packages` and `onlyBuiltDependencies` + - Scripts: Unified build, development, formatting, and check commands + - Frontend dependencies: React, Svelte, Ant Design, Monaco Editor, etc. + +```mermaid +graph LR +P["pyproject.toml
Python Dependencies and Packaging"] --> B["Backend Components
modelscope_studio"] +N["package.json
Node Scripts and Dependencies"] --> F["Frontend Build
Vite + Plugins"] +W["pnpm-workspace.yaml
Workspace and Build-only Dependencies"] --> N +F --> R["Static Asset Artifacts"] +B --> R +``` + +**Chart Sources** + +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) + +**Section Sources** + +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [frontend/package.json](file://frontend/package.json) + +## Performance Considerations + +- Concurrency and Threads + - The documentation site entry point sets default concurrency and maximum thread count; these should be tuned based on hardware and business load +- Build Optimization + - Use pnpm and `onlyBuiltDependencies` to reduce unnecessary dependency builds + - Set the frontend build target to `modules` for improved compatibility and loading efficiency +- Resources and Caching + - Place static assets on CDN or reverse proxy caching + - Control template and asset size to avoid redundant files in artifacts + +**Section Sources** + +- [docs/app.py](file://docs/app.py) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) + +## Troubleshooting Guide + +- Documentation Site Cannot Start or Page is Blank + - Check whether `GRADIO_WATCH_MODULE_NAME` is correctly set to enable development listening + - Confirm the backend package is correctly installed and can be imported +- Frontend Build Failure + - Check whether Node version and dependencies meet requirements + - Clear `node_modules` and build cache, then retry +- Link and Resource 404 + - Confirm static asset paths are consistent with service routes + - Check link transformation logic and resource cache path mapping +- Development Context Missing Warning + - Ensure the `Application` component is used at the top level to avoid empty runtime context + +```mermaid +flowchart TD +Start(["Start Troubleshooting"]) --> CheckEnv["Check environment variables and dependency versions"] +CheckEnv --> BuildFE["Execute frontend build and view errors"] +BuildFE --> FixFE["Fix frontend dependencies or build config"] +CheckEnv --> RunDocs["Start documentation site and observe behavior"] +RunDocs --> FixDocs["Fix runtime parameters and concurrency settings"] +FixFE --> Verify["Verify static asset availability"] +FixDocs --> Verify +Verify --> End(["End"]) +``` + +**Chart Sources** + +- [docs/app.py](file://docs/app.py) +- [package.json](file://package.json) +- [backend/modelscope_studio/utils/dev/process_links.py](file://backend/modelscope_studio/utils/dev/process_links.py) +- [backend/modelscope_studio/utils/dev/app_context.py](file://backend/modelscope_studio/utils/dev/app_context.py) + +**Section Sources** + +- [docs/app.py](file://docs/app.py) +- [backend/modelscope_studio/utils/dev/process_links.py](file://backend/modelscope_studio/utils/dev/process_links.py) +- [backend/modelscope_studio/utils/dev/app_context.py](file://backend/modelscope_studio/utils/dev/app_context.py) + +## Conclusion + +With clear environment variables and runtime parameters, standardized dependency management and workspace configuration, scalable containerization and monitoring strategies, and rigorous migration and upgrade processes, ModelScope Studio can run stably in different environments. It is recommended to prioritize controlled versions and a comprehensive observability system in production environments, and to continuously optimize build and runtime performance. + +## Appendix + +- Quick Start and Development + - Install backend and frontend dependencies and execute the build + - Use Gradio CC to start the documentation site for development and debugging +- Reference Commands + - Backend installation and build: See root-level README installation and development instructions + - Frontend installation and build: See scripts in `package.json` and dependencies in `frontend/package.json` + +**Section Sources** + +- [README.md](file://README.md) +- [package.json](file://package.json) +- [frontend/package.json](file://frontend/package.json) diff --git a/.wiki/en/Deployment Guide/Release Process.md b/.wiki/en/Deployment Guide/Release Process.md new file mode 100644 index 00000000..9aae0662 --- /dev/null +++ b/.wiki/en/Deployment Guide/Release Process.md @@ -0,0 +1,441 @@ +# Release Process + + +**Files Referenced in This Document** +- [publish.yaml](file://.github/workflows/publish.yaml) +- [lint.yaml](file://.github/workflows/lint.yaml) +- [pyproject.toml](file://pyproject.toml) +- [package.json](file://package.json) +- [publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) +- [create-tag-n-release.mts](file://scripts/create-tag-n-release.mts) +- [.changeset/config.json](file://.changeset/config.json) +- [.changeset/pre.json](file://.changeset/pre.json) +- [version.py](file://backend/modelscope_studio/version.py) +- [CHANGELOG.md](file://CHANGELOG.md) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [index.ts](file://config/changelog/src/index.ts) +- [package.json](file://config/changelog/package.json) +- [frontend/package.json](file://frontend/package.json) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This document is intended for maintainers and senior developers who need to manage the release of the ModelScope Studio project. It systematically explains the complete process from local development to official PyPI release (including pre-releases and hotfixes), covering version management, changelog generation, automated pipelines, quality assurance, and rollback strategies. The content is based on existing release scripts, GitHub Actions workflows, and changeset configurations within the repository, ensuring it is actionable, traceable, and reproducible. + +## Project Structure + +ModelScope Studio uses a multi-package workspace (pnpm workspace) organization, with the root directory containing Python package metadata and frontend component source code. Key locations related to releases: + +- Root-level package metadata and build configuration: `pyproject.toml` +- Release scripts and workflows: `scripts/` and `.github/workflows/` +- Changeset and changelog generator: `.changeset/` and `config/changelog/` +- Version number sources: `backend/modelscope_studio/version.py` and each package's `package.json` +- Workspace definition: `pnpm-workspace.yaml` + +```mermaid +graph TB +A["Root Workspace
pnpm-workspace.yaml"] --> B["Python Package
pyproject.toml"] +A --> C["Frontend Package
frontend/package.json"] +A --> D["Changelog Generator
config/changelog/"] +A --> E["Release Scripts
scripts/"] +A --> F["GitHub Actions
.github/workflows/"] +B --> G["Version Source
backend/modelscope_studio/version.py"] +D --> H["Changeset Config
.changeset/config.json"] +D --> I[".changeset/pre.json"] +``` + +Chart Sources + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +Section Sources + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +## Core Components + +- Version and Metadata + - Python package version and metadata are provided by `pyproject.toml`; the Python module version is also maintained synchronously in `backend/modelscope_studio/version.py`. + - Frontend package and sub-package versions are declared in their respective `package.json` files. +- Changesets and Changelogs + - Uses Changesets to manage cross-package versions and change summaries, classifying changes and writing them to each package's `CHANGELOG.md` via a custom changelog generator. +- Automated Release Pipeline + - GitHub Actions triggers when a "version update" commit is detected on the main or next branch, executes build and release, and upon success, creates a tag and GitHub Release. +- Release Scripts + - `scripts/publish-to-pypi.mts` checks whether the version already exists, builds artifacts, and uploads to PyPI. + - `scripts/create-tag-n-release.mts` generates merged changelogs, creates a tag, and creates a Release. + +Section Sources + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +## Architecture Overview + +The diagram below shows the overall flow from code commit to PyPI publishing and GitHub Release, including version checking, building, uploading, tagging, and releasing. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Repo as "Repository (main/next)" +participant GH as "GitHub Actions" +participant Script as "Release Script
publish-to-pypi.mts" +participant PyPI as "PyPI" +participant Tag as "Tag and Release
create-tag-n-release.mts" +Dev->>Repo : Push commit with "version update" +Repo-->>GH : Trigger publish workflow +GH->>Script : Execute build and release +Script->>PyPI : Check version and upload +PyPI-->>Script : Return publish result +Script-->>GH : Output published marker +GH->>Tag : If published, create tag and Release +Tag-->>Repo : Push tag and release notes +``` + +Chart Sources + +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +Section Sources + +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +## Detailed Component Analysis + +### Component 1: Version and Metadata Management + +- Python Package Version and Metadata + - `pyproject.toml` defines the package name, version, license, dependencies, and build targets, with clearly defined wheel and sdist packaging scope. + - `backend/modelscope_studio/version.py` serves as the Python module version entry point and must stay consistent with the `pyproject.toml` version. +- Frontend and Sub-package Versions + - Each package's `package.json` (such as `frontend/package.json`) declares an independent version, facilitating coordinated multi-package releases. +- Workspace and Multi-package + - `pnpm-workspace.yaml` explicitly includes root, `config/*`, `frontend`, and its sub-packages, ensuring release scripts can correctly resolve package metadata. + +```mermaid +flowchart TD +Start(["Start"]) --> ReadMeta["Read package metadata
pyproject.toml / package.json"] +ReadMeta --> CompareVer{"Version consistency check"} +CompareVer --> |Inconsistent| FixVer["Synchronize versions"] +CompareVer --> |Consistent| Next["Enter changeset flow"] +FixVer --> Next +Next --> End(["End"]) +``` + +Chart Sources + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) + +Section Sources + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) + +### Component 2: Changesets and Changelog Generation + +- Changesets Configuration + - `.changeset/config.json` specifies using a custom changelog generator and repository information, disables commit recording, and sets the base branch to `main`. + - `.changeset/pre.json` defines the pre-release mode and initial version mapping, supporting pre-releases with the `beta` tag. +- Custom Changelog Generator + - `index.ts` implements `getReleaseLine` and `getDependencyReleaseLine`, classifying changes by `feat`/`fix`/`chore`, extracting PR/Commit/User information, and writing to each package's `CHANGELOG.md`. +- Generation Flow + - The `version` script in `package.json` calls `changeset version` and fixes changelogs, then builds the changelog package. + +```mermaid +flowchart TD +CS["Changeset Summary"] --> Parse["Parse summary
PR/Commit/User/Type"] +Parse --> Classify{"Classify feat/fix/chore"} +Classify --> Write["Write to each package's CHANGELOG.md"] +Write --> Done["Done"] +``` + +Chart Sources + +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [package.json:1-55](file://package.json#L1-L55) +- [config/changelog/package.json:1-32](file://config/changelog/package.json#L1-L32) + +Section Sources + +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [package.json:1-55](file://package.json#L1-L55) +- [config/changelog/package.json:1-32](file://config/changelog/package.json#L1-L32) + +### Component 3: PyPI Release Script + +- Functional Responsibilities + - `publish-to-pypi.mts` checks whether the same version already exists on PyPI before releasing, to avoid duplicate uploads; then executes installation and build, and finally uploads via `twine`. +- Key Logic + - Uses `@manypkg/get-packages` to obtain workspace package metadata and read the root package version. + - Queries the PyPI JSON API to check whether the version exists; if it does, skips. + - Checks the existence of the `dist` directory after building before uploading. + - Sets the GitHub Actions output variable `published=true` for subsequent steps to use. + +```mermaid +flowchart TD +S(["Start"]) --> Check["Query PyPI for existing version"] +Check --> Exists{"Exists?"} +Exists --> |Yes| Skip["Skip publish and output marker"] +Exists --> |No| Build["Install and build"] +Build --> Dist{"dist exists?"} +Dist --> |No| Fail["Throw build failure error"] +Dist --> |Yes| Upload["twine upload"] +Upload --> SetOut["Set published=true"] +Skip --> End(["End"]) +SetOut --> End +Fail --> End +``` + +Chart Sources + +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +Section Sources + +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +### Component 4: Tag and Release Creation + +- Functional Responsibilities + - `create-tag-n-release.mts` aggregates change descriptions for the current version from the root and sub-package `CHANGELOG.md` files, creates a Git tag and pushes it, then calls the GitHub API to create a Release. +- Key Logic + - Parses `CHANGELOG.md`, extracts the entry for the corresponding version number, and concatenates it into the Release Body. + - Uses the GitHub Token to call `createRelease`; decides whether to mark as pre-release based on whether the version number contains a hyphen. + - Configures Git username and email to ensure tags are pushed to the remote. + +```mermaid +flowchart TD +R(["Start"]) --> ReadCL["Read root and sub-package CHANGELOG.md"] +ReadCL --> Merge["Aggregate into Release Body"] +Merge --> Tag["Create v tag and push"] +Tag --> Release["Call GitHub API to create Release"] +Release --> DoneR(["End"]) +``` + +Chart Sources + +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- [CHANGELOG.md:1-200](file://CHANGELOG.md#L1-L200) + +Section Sources + +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- [CHANGELOG.md:1-200](file://CHANGELOG.md#L1-L200) + +### Component 5: GitHub Actions Publish Pipeline + +- Trigger Conditions + - Triggers on push to `main` or `next` branch with a commit message matching "version update". +- Step Description + - Install Python and Node.js dependencies; pnpm installs frontend dependencies. + - Execute the publish script `pnpm run ci:publish`, passing in `PYPI_TOKEN`. + - If publish succeeds, execute `pnpm run ci:create-tag-n-release`, passing in `GITHUB_TOKEN`, `REPO`, and `OWNER`. + +```mermaid +sequenceDiagram +participant Push as "Push (main/next)" +participant WF as "publish workflow" +participant Steps as "Steps" +participant Pub as "ci:publish" +participant Tag as "ci:create-tag-n-release" +Push->>WF : Trigger +WF->>Steps : Checkout code / set up environment +Steps->>Pub : Execute publish +Pub-->>Steps : Output published=true +Steps->>Tag : Create tag and Release +``` + +Chart Sources + +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) + +Section Sources + +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) + +## Dependency Analysis + +- Package Version Sources and Consistency + - Root package version is jointly constrained by `pyproject.toml` and `backend/modelscope_studio/version.py`; frontend and sub-package versions are constrained by their respective `package.json`. +- Release Script Dependencies on Workspace + - Both `publish-to-pypi.mts` and `create-tag-n-release.mts` read workspace package information via `@manypkg/get-packages`, ensuring unified multi-package versions and changelogs. +- Changelog Generator Dependencies on Changesets + - `index.ts` depends on `@changesets/get-github-info` and `@manypkg/get-packages` to transform changesets into `CHANGELOG.md`. + +```mermaid +graph LR +P["pyproject.toml"] --> V["backend/modelscope_studio/version.py"] +P --> S1["scripts/publish-to-pypi.mts"] +F["frontend/package.json"] --> S1 +Cfg["config/changelog/src/index.ts"] --> CL["CHANGELOG.md"] +Pre["changeset/pre.json"] --> CL +W["pnpm-workspace.yaml"] --> S1 +W --> S2["scripts/create-tag-n-release.mts"] +``` + +Chart Sources + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +Section Sources + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +## Performance Considerations + +- Publish Pipeline Concurrency and Timeout + - The workflow enables concurrency groups and cancellation strategies to avoid multiple releases on the same branch interfering with each other; single job timeout is generous to accommodate large build needs. +- Build and Upload Efficiency + - The release script checks whether the version exists before uploading to avoid duplicate uploads; the build phase only continues when `dist` exists, reducing invalid I/O. +- Multi-package Workspace + - Reads all package metadata at once via `@manypkg/get-packages`, reducing multiple I/O overhead. + +Section Sources + +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) + +## Troubleshooting Guide + +- Publish Skipped + - Symptom: Log shows version already exists on PyPI, publish skipped. + - Investigation: Confirm whether the version number was correctly incremented; check whether `PYPI_TOKEN` is valid. + - Reference: Version check logic in the publish script. +- Build Failure + - Symptom: `dist` directory does not exist, causing build failure. + - Investigation: Check the build command and dependency installation; confirm Node.js and pnpm versions meet requirements. + - Reference: Build and validation steps in the publish script. +- Tag and Release Creation Failure + - Symptom: Cannot create Release or tag was not pushed. + - Investigation: Confirm `GITHUB_TOKEN` permissions; check whether `CHANGELOG.md` contains the corresponding version entry; confirm branch protection rules allow tag pushes. + - Reference: Tag and Release creation script. +- Changelog Missing + - Symptom: Release Body is empty or some packages are not included in the change. + - Investigation: Confirm changeset summary format is standardized; check initial version mapping in `pre.json`; verify the changelog generator correctly writes to each package's `CHANGELOG.md`. +- Pre-release vs Official Release + - Symptom: Release not marked as pre-release. + - Investigation: Confirm the version number contains a hyphen; check the `tag` configuration and initial version mapping in `pre.json`. + +Section Sources + +- [publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) + +## Conclusion + +This release system uses Changesets as the core to coordinate multi-package versions and changelogs, combined with GitHub Actions to automate building, uploading, and releasing. Through version checks, tag, and Release creation scripts, the release process is traceable and reversible. It is recommended to strictly follow version management and changelog specifications before each release to maintain high-quality delivery. + +## Appendix + +### A. Version Control and Semantic Versioning Best Practices + +- Semantic Versioning + - Major version: Breaking changes + - Minor version: Backwards-compatible feature additions + - Patch version: Backwards-compatible bug fixes +- Pre-release + - Use the `beta` tag in `pre.json` for pre-releases; versions containing hyphens are automatically marked as pre-releases. +- Hotfix + - Fix directly on the `main` branch and create a patch version; if prior validation is needed, pre-release on the `next` branch first. + +Section Sources + +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +### B. Pre-release Checklist + +- Version Consistency + - `pyproject.toml` and `backend/modelscope_studio/version.py` versions are consistent; each package's `package.json` versions are consistent. +- Changelog + - Changeset has been run and corresponding summaries have been generated; each package's `CHANGELOG.md` contains the current version entry. +- Local Build + - Build executed locally and basic functional tests passed. +- Secrets and Permissions + - `PYPI_TOKEN` and `GITHUB_TOKEN` are valid with correct permissions. +- Branch and Commit + - Push branch is `main` or `next`; commit message contains "version update". + +Section Sources + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) + +### C. Configuration for Different Release Scenarios + +- Official Release + - Push a "version update" commit on the `main` branch to trigger the release pipeline; version number does not contain a hyphen, Release is marked as official. +- Pre-release + - Use the `beta` tag in `pre.json`; version number contains a hyphen, Release is marked as pre-release. +- Hotfix + - Create a patch version directly on the `main` branch; if prior validation is needed, pre-release on the `next` branch first, then merge. + +Section Sources + +- [publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) diff --git a/.wiki/en/Development Guide/Build and Deploy.md b/.wiki/en/Development Guide/Build and Deploy.md new file mode 100644 index 00000000..d6ebc8d1 --- /dev/null +++ b/.wiki/en/Development Guide/Build and Deploy.md @@ -0,0 +1,370 @@ +# Build and Deploy + + +**Files referenced in this document** +- [package.json](file://package.json) +- [pyproject.toml](file://pyproject.toml) +- [pnpm-workspace.yaml](file://pnpm-workspace.yaml) +- [frontend/package.json](file://frontend/package.json) +- [frontend/defineConfig.js](file://frontend/defineConfig.js) +- [frontend/plugin.js](file://frontend/plugin.js) +- [.github/workflows/publish.yaml](file://.github/workflows/publish.yaml) +- [scripts/publish-to-pypi.mts](file://scripts/publish-to-pypi.mts) +- [scripts/create-tag-n-release.mts](file://scripts/create-tag-n-release.mts) +- [backend/modelscope_studio/version.py](file://backend/modelscope_studio/version.py) +- [config/changelog/src/index.ts](file://config/changelog/src/index.ts) +- [config/changelog/tsup.config.ts](file://config/changelog/tsup.config.ts) +- [.changeset/config.json](file://.changeset/config.json) +- [.changeset/pre.json](file://.changeset/pre.json) +- [README.md](file://README.md) +- [docs/requirements.txt](file://docs/requirements.txt) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This guide covers the build and release process for ModelScope Studio, including the following topics: + +- Frontend build configuration and bundling strategy (Vite plugins, externalization and aliases) +- Python package build and distribution (Hatch configuration, wheel/sdist artifact manifest) +- Version management and changesets (Changesets, pre-release tags, automated changelog generation) +- Automated release pipeline (PyPI release, GitHub tags and Release creation) +- Deployment best practices and considerations +- Dependency update and compatibility handling recommendations + +## Project Structure + +The repository uses a multi-package workspace organization, containing root-level packages, frontend sub-packages, and configuration packages: + +- Root package: Provides build scripts, changeset configuration, and release scripts +- Frontend workspace: Contains component packages such as antd, antdx, base, pro +- Configuration packages: Changelog generator and Lint configuration +- Backend Python package: Built via Hatch and packaged as wheel/sdist + +```mermaid +graph TB +Root["Root Package
package.json, pyproject.toml"] --> Frontend["Frontend Workspace
frontend/*"] +Root --> Config["Config Packages
config/changelog"] +Root --> Scripts["Release Scripts
scripts/*"] +Frontend --> Antd["antd component package"] +Frontend --> Antdx["antdx component package"] +Frontend --> Base["base component package"] +Frontend --> Pro["pro component package"] +Root --> Backend["Backend Python Package
backend/modelscope_studio"] +``` + +**Diagram Sources** + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [package.json:1-55](file://package.json#L1-L55) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) + +**Section Sources** + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [package.json:1-55](file://package.json#L1-L55) +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) + +## Core Components + +- Frontend Vite build plugin: Handles React/Svelte preprocessing, global variable injection, and externalization strategy +- Python package build system: Based on Hatch, defining artifacts, wheel/sdist packaging scope, and optional dependencies +- Changesets and changelog: Changesets-driven version and log generation, supporting multi-package unified management +- Automated release pipeline: GitHub Actions triggers builds, PyPI releases, and GitHub Release creation + +**Section Sources** + +- [frontend/plugin.js:1-168](file://frontend/plugin.js#L1-L168) +- [frontend/defineConfig.js:1-19](file://frontend/defineConfig.js#L1-L19) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [config/changelog/src/index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) + +## Architecture Overview + +The diagram below shows the overall process from local development to automated release: + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Root as "Root Package Scripts
package.json" +participant FE as "Frontend Build
Vite Plugin" +participant PY as "Python Build
Hatch" +participant TW as "Twine Release" +participant GH as "GitHub Actions" +participant Repo as "PyPI Repository" +Dev->>Root : Run build/version commands +Root->>FE : pnpm run build +FE-->>Root : Output dist/ frontend assets +Root->>PY : pnpm run build (backend) +PY-->>Root : Output wheel/sdist +Root->>TW : pnpm run ci:publish +TW->>Repo : Upload wheel/sdist +GH->>Root : Trigger release pipeline +Root->>GH : Create tags and Release +``` + +**Diagram Sources** + +- [package.json:8-25](file://package.json#L8-L25) +- [frontend/defineConfig.js:1-19](file://frontend/defineConfig.js#L1-L19) +- [frontend/plugin.js:41-76](file://frontend/plugin.js#L41-L76) +- [pyproject.toml:45-257](file://pyproject.toml#L45-L257) +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [scripts/publish-to-pypi.mts:22-55](file://scripts/publish-to-pypi.mts#L22-L55) + +## Detailed Component Analysis + +### Frontend Build and Bundling + +- Build entry and plugin chain + - Uses Vite plugin combination: React SWC and custom ModelScopeStudioVitePlugin + - Defines global variable mappings, externalizing common dependencies to host environment (e.g., `window.ms_globals.React`) + - Supports excluding certain externalized items on-demand, for inlining in specific scenarios +- Aliases and preprocessing + - Points to `utils/globals` directory via aliases to simplify import paths + - Disables Svelte preprocessing to avoid conflicts with existing solutions +- Production environment optimization + - Sets `NODE_ENV` to `production` during the build stage + - Performs AST transformation on exported modules, rewriting imports/exports to global object access to reduce bundle size + +```mermaid +flowchart TD +Start(["Start"]) --> DefineCfg["Load defineConfig options"] +DefineCfg --> UsePlugins["Enable React + ModelScopeStudioVitePlugin"] +UsePlugins --> ResolveAlias["@utils/@globals alias resolution"] +ResolveAlias --> Externalize{"Externalization enabled?"} +Externalize --> |Yes| RollupExt["Rollup externalize global mappings"] +Externalize --> |No| SkipExt["Skip externalization"] +RollupExt --> Transform["AST transformation: map imports/exports to globals"] +SkipExt --> Transform +Transform --> BuildOut["Output production build artifacts"] +BuildOut --> End(["End"]) +``` + +**Diagram Sources** + +- [frontend/defineConfig.js:8-18](file://frontend/defineConfig.js#L8-L18) +- [frontend/plugin.js:41-76](file://frontend/plugin.js#L41-L76) +- [frontend/plugin.js:77-165](file://frontend/plugin.js#L77-L165) + +**Section Sources** + +- [frontend/defineConfig.js:1-19](file://frontend/defineConfig.js#L1-L19) +- [frontend/plugin.js:1-168](file://frontend/plugin.js#L1-L168) + +### Python Package Build and Distribution + +- Build backend Python package + - Uses Hatchling as build backend, reading metadata and dependencies from `pyproject.toml` + - Specifies `artifacts` list to ensure templates and static assets are included in the wheel + - Target directories and exclusion rules for wheel/sdist are clearly defined to avoid redundant files in release packages +- Dependencies and compatibility + - Manages dependencies and README rendering via `hatch-requirements-txt` and `hatch-fancy-pypi-readme` + - Python version requirements and classifier declarations are clear, facilitating PyPI display and installer recognition +- Version consistency + - Root package and backend versions are kept in sync to avoid mismatches during release + +```mermaid +flowchart TD +A["Read pyproject.toml"] --> B["Hatchling Build"] +B --> C{"Target type?"} +C --> |wheel| D["Package as wheel
including artifacts"] +C --> |sdist| E["Package as sdist
including backend/modelscope_studio"] +D --> F["Verify artifact integrity"] +E --> F +F --> G["Upload to PyPI via Twine"] +``` + +**Diagram Sources** + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) + +**Section Sources** + +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) +- [backend/modelscope_studio/version.py:1-2](file://backend/modelscope_studio/version.py#L1-L2) + +### Version Management and Changelog + +- Changesets configuration + - Uses custom changelog generator, supporting PR/Commit/user link parsing + - Unified version baseline and pre-release tags (beta), facilitating preview and rollback +- Changelog generation + - Compiles configuration package via tsup, outputting both esm/cjs formats + - Changelog generator aggregates CHANGELOGs from each package and writes to a temporary state file, ultimately driven by the root package to generate unified release content +- Pre-release mode + - `pre.json` specifies pre-release tags and initial version, working with Changesets workflow for canary releases + +```mermaid +flowchart TD +CS["Changesets commit"] --> Gen["Run version script"] +Gen --> Changelog["Generate/update changelog"] +Changelog --> Pre["Pre-release tag (beta)"] +Pre --> Release["Trigger release pipeline"] +``` + +**Diagram Sources** + +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [config/changelog/src/index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [config/changelog/tsup.config.ts:1-21](file://config/changelog/tsup.config.ts#L1-L21) + +**Section Sources** + +- [.changeset/config.json:1-15](file://.changeset/config.json#L1-L15) +- [.changeset/pre.json:1-16](file://.changeset/pre.json#L1-L16) +- [config/changelog/src/index.ts:1-222](file://config/changelog/src/index.ts#L1-L222) +- [config/changelog/tsup.config.ts:1-21](file://config/changelog/tsup.config.ts#L1-L21) + +### Automated Release Pipeline + +- Trigger conditions + - Push to `main`/`next` branch with commit message "chore: update versions" +- Step breakdown + - Install Python and Node dependencies, prepare build environment + - Execute build: pip editable mode install, pnpm run build + - Check if `dist` exists to prevent continuing release after build failure + - Use Twine to upload all artifacts in `dist` to PyPI (with skip-existing) + - If release succeeds, call script to create Git tag and push, then create Release on GitHub with content from changelog + +```mermaid +sequenceDiagram +participant WF as "GitHub Actions" +participant Build as "Build Step" +participant Check as "Version Check" +participant Upload as "Twine Upload" +participant Tag as "Create Tag and Release" +WF->>Build : Install dependencies and build +Build-->>WF : Output dist/ +WF->>Check : Check if version already exists on PyPI +alt Already exists +Check-->>WF : Skip release +else Does not exist +WF->>Upload : Upload dist/* to PyPI +Upload-->>WF : Release complete +WF->>Tag : Create v tag and release +end +``` + +**Diagram Sources** + +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [scripts/publish-to-pypi.mts:14-55](file://scripts/publish-to-pypi.mts#L14-L55) +- [scripts/create-tag-n-release.mts:80-125](file://scripts/create-tag-n-release.mts#L80-L125) + +**Section Sources** + +- [.github/workflows/publish.yaml:1-74](file://.github/workflows/publish.yaml#L1-L74) +- [scripts/publish-to-pypi.mts:1-60](file://scripts/publish-to-pypi.mts#L1-L60) +- [scripts/create-tag-n-release.mts:1-131](file://scripts/create-tag-n-release.mts#L1-L131) + +## Dependency Analysis + +- Workspace and package relationships + - pnpm-workspace defines the root package and multiple frontend sub-packages, ensuring inter-package sharing and build order + - Root package `package.json` provides unified scripts and dependencies, centralizing build and release tasks +- Frontend dependency externalization strategy + - Maps React, Ant Design, Monaco Editor, etc. to globals via Vite plugin to reduce bundle size + - Supports on-demand exclusion from externalization list to meet different host environment needs +- Python dependencies and compatibility + - Manages dependencies and README rendering via `hatch-requirements-txt` and `hatch-fancy-pypi-readme` + - Constrains Gradio version range to ensure coordination with frontend components + +```mermaid +graph LR +RootPkg["Root package.json"] --> FEWS["pnpm-workspace.yaml"] +FEWS --> FEAntd["@modelscope-studio/antd"] +FEWS --> FEAntdx["@modelscope-studio/antdx"] +FEWS --> FEBase["@modelscope-studio/base"] +FEWS --> FEPro["@modelscope-studio/pro"] +RootPkg --> PyProj["pyproject.toml"] +PyProj --> Artifacts["artifacts list"] +``` + +**Diagram Sources** + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [package.json:1-55](file://package.json#L1-L55) +- [pyproject.toml:45-245](file://pyproject.toml#L45-L245) + +**Section Sources** + +- [pnpm-workspace.yaml:1-12](file://pnpm-workspace.yaml#L1-L12) +- [package.json:1-55](file://package.json#L1-L55) +- [pyproject.toml:1-257](file://pyproject.toml#L1-L257) + +## Performance Considerations + +- Frontend build optimization + - Enable externalization strategy to reduce repeated bundling and size bloat + - AST transformation only applies to export/import statements, avoiding impact on runtime performance + - Force-set `NODE_ENV` in production to ensure minification and Tree-shaking take effect +- Python package size control + - Explicitly define artifacts whitelist to avoid packaging test or source cache files + - Use dual sdist/wheel release for both installer and cache efficiency +- Release process stability + - Check if same version exists on PyPI first to avoid repeated uploads and failed retries + - Use "skip-existing" parameter to reduce network and time overhead + +## Troubleshooting Guide + +- Build failure + - Check if `dist` directory exists; if missing, confirm frontend build scripts and Vite plugin configuration are correct + - Confirm Node and Python environment versions meet requirements +- PyPI release failure + - Verify `PYPI_TOKEN` is configured and network connectivity is normal + - If prompted that version already exists, confirm whether version upgrade or cache clearing is needed +- GitHub Release creation failure + - Check `GITHUB_TOKEN` permissions and REPO/OWNER parameters + - Confirm changelog generation succeeded to avoid empty content causing creation failure +- Dependency conflicts + - Update Gradio version range and frontend dependencies to ensure compatibility + - Use `docs/requirements.txt` to pin example dependency versions for easier reproduction and debugging + +**Section Sources** + +- [scripts/publish-to-pypi.mts:22-55](file://scripts/publish-to-pypi.mts#L22-L55) +- [scripts/create-tag-n-release.mts:88-125](file://scripts/create-tag-n-release.mts#L88-L125) +- [docs/requirements.txt:1-4](file://docs/requirements.txt#L1-L4) + +## Conclusion + +This guide provides a complete path from local development to automated release: the frontend implements externalization and alias optimization through the Vite plugin, the Python package uses Hatch for precise packaging and distribution, versions and changelogs are driven by Changesets, and GitHub Actions completes PyPI releases and GitHub Release creation. Following the steps and best practices in this document can significantly improve build efficiency and release reliability. + +## Appendix + +### Common Build and Release Commands + +- Local development and build + - Run root package build script to generate frontend and backend artifacts + - Documentation site can be started by specifying an entry point +- Version and changelog + - Use Changesets to update version and generate changelog + - Regenerate after fixing changelog format +- Publish to PyPI + - Use CI script to check if version already exists; skip if it does, otherwise build and upload +- Create tags and Releases + - Generate content from changelog, create Git tags and push, then create Release on GitHub + +**Section Sources** + +- [package.json:8-25](file://package.json#L8-L25) +- [README.md:80-101](file://README.md#L80-L101) +- [scripts/publish-to-pypi.mts:44-55](file://scripts/publish-to-pypi.mts#L44-L55) +- [scripts/create-tag-n-release.mts:117-125](file://scripts/create-tag-n-release.mts#L117-L125) diff --git a/.wiki/en/Development Guide/Component Development/Backend Component Development.md b/.wiki/en/Development Guide/Component Development/Backend Component Development.md new file mode 100644 index 00000000..ecfbec16 --- /dev/null +++ b/.wiki/en/Development Guide/Component Development/Backend Component Development.md @@ -0,0 +1,363 @@ +# Backend Component Development + + +**Files Referenced in This Document** +- [backend/modelscope_studio/components/__init__.py](file://backend/modelscope_studio/components/__init__.py) +- [backend/modelscope_studio/components/antd/components.py](file://backend/modelscope_studio/components/antd/components.py) +- [backend/modelscope_studio/components/antdx/components.py](file://backend/modelscope_studio/components/antdx/components.py) +- [backend/modelscope_studio/components/pro/components.py](file://backend/modelscope_studio/components/pro/components.py) +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [backend/modelscope_studio/utils/dev/__init__.py](file://backend/modelscope_studio/utils/dev/__init__.py) +- [backend/modelscope_studio/components/antd/button/__init__.py](file://backend/modelscope_studio/components/antd/button/__init__.py) +- [backend/modelscope_studio/components/antd/form/__init__.py](file://backend/modelscope_studio/components/antd/form/__init__.py) +- [backend/modelscope_studio/components/base/text/__init__.py](file://backend/modelscope_studio/components/base/text/__init__.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This guide is intended for backend component developers and provides a systematic explanation of how to implement Python components under the `backend/modelscope_studio/components/` directory, covering the component class inheritance hierarchy, property definition and validation, events and callbacks, lifecycle hooks, integration with frontend Svelte components, and the data transformation flow from Python to JavaScript. The document also explains how to use the component registration mechanism (`__init__.py` and `components.py`), with concrete implementation steps guided by real file paths. + +## Project Structure + +ModelScope Studio's backend components are organized in a layered and categorized manner: component families include `antd`, `antdx`, `base`, and `pro`; within each family, concrete components are organized in modular directories; centralized exports are handled by each family's `components.py`, which are then aggregated into the top-level namespace by `components/__init__.py` for unified import and use. + +```mermaid +graph TB +subgraph "Component Package" +A["backend/modelscope_studio/components/"] +A1["antd/"] +A2["antdx/"] +A3["base/"] +A4["pro/"] +end +subgraph "Registration Entry" +R1["antd/components.py"] +R2["antdx/components.py"] +R3["pro/components.py"] +R4["base/__init__.py"] +R0["components/__init__.py"] +end +A --> A1 +A --> A2 +A --> A3 +A --> A4 +A1 --> R1 +A2 --> R2 +A3 --> R4 +A4 --> R3 +R0 --> R1 +R0 --> R2 +R0 --> R3 +R0 --> R4 +``` + +Diagram Sources + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +Section Sources + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) + +## Core Components + +The base classes and metaclasses for backend components are provided by the development utility module, which standardizes component lifecycle, event binding, layout and render control, and the ability to map to frontend directory paths. + +- Base Classes and Metaclasses + - `ModelScopeComponent`: General-purpose component base class, supporting standard properties such as `value`, `visible`, `elem_*`, `render`, as well as advanced configuration like `load_fn`, `inputs`, `key`, and `every`. + - `ModelScopeLayoutComponent`: Used for layout or container-type components, emphasizing layout updates and context exit behavior. + - `ModelScopeDataLayoutComponent`: Data-driven layout component that integrates Gradio's `BlockContext` capabilities, supporting features like `preserved_by_key`. +- Key Conventions + - `EVENTS`: The list of events supported by the component, typically defined via `EventListener`; callbacks update the binding flags in `_internal` so the frontend can listen. + - `SLOTS`: The set of slot names supported by the component, used for slot injection during frontend rendering. + - `FRONTEND_DIR`: Resolved via `resolve_frontend_dir` to the corresponding frontend Svelte component directory, ensuring frontend-backend consistency. + - `skip_api`: Determines whether the component exposes an API interface (e.g., some purely display components can skip the API). + - `preprocess`/`postprocess`/`example_payload`/`example_value`: Standardize data conversion and sample values, ensuring consistent data contracts between frontend and backend. + +Section Sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/utils/dev/**init**.py:9-13](file://backend/modelscope_studio/utils/dev/__init__.py#L9-L13) + +## Architecture Overview + +Backend components interface with frontend Svelte components through a unified directory mapping and event binding mechanism. During initialization, the component class sets `FRONTEND_DIR` so the frontend can locate the corresponding Svelte implementation; events are registered via the `EVENTS` list and callbacks update `_internal` flags, which the frontend uses to bind the corresponding behaviors; data flow is normalized through `preprocess`/`postprocess`, ensuring consistent data shapes between the Python and JS layers. + +```mermaid +sequenceDiagram +participant Py as "Python Component Class" +participant Meta as "Event Metaclass/Context" +participant FE as "Frontend Svelte Component" +Py->>Py : Initialize component
Set value/props/SLOTS/EVENTS/FrontendDir +Py->>Meta : Register event callbacks
Update _internal flags +Meta-->>FE : Frontend listens and binds events +FE-->>Py : User interaction triggers event +Py->>Py : preprocess(payload)
Normalize input +Py->>Py : postprocess(value)
Normalize output +Py-->>FE : Render result/state change +``` + +Diagram Sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) +- [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) + +## Detailed Component Analysis + +### Component Class Inheritance Hierarchy and Responsibilities + +- `ModelScopeComponent`: General-purpose component, suitable for data-type components (e.g., text, input, select), supporting `value` and standard UI properties. +- `ModelScopeLayoutComponent`: Layout-type components (e.g., button, card, grid), emphasizing layout updates and context exit. +- `ModelScopeDataLayoutComponent`: Data-driven layout components (e.g., form, table), with `BlockContext` capability, suitable for complex interactions and state persistence. + +```mermaid +classDiagram +class ModelScopeComponent { ++EVENTS ++SLOTS ++FRONTEND_DIR ++skip_api ++preprocess(payload) ++postprocess(value) ++example_payload() ++example_value() +} +class ModelScopeLayoutComponent { ++__exit__() +} +class ModelScopeDataLayoutComponent { ++__exit__() +} +ModelScopeLayoutComponent --|> ModelScopeComponent +ModelScopeDataLayoutComponent --|> ModelScopeComponent +ModelScopeDataLayoutComponent --|> BlockContext +``` + +Diagram Sources + +- [backend/modelscope_studio/utils/dev/component.py:54-169](file://backend/modelscope_studio/utils/dev/component.py#L54-L169) + +Section Sources + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +### Event Handling and Callback Mechanism + +- Event Definition: Declare events supported by the component via the `EVENTS` list, such as click, field change, submit completion, etc. +- Callback Logic: Event callbacks update the binding flags in `_internal`, notifying the frontend to bind events. +- Typical Usage: Click event of `AntdButton`; `fields_change`/`finish`/`values_change` of `AntdForm`, etc. + +```mermaid +sequenceDiagram +participant Btn as "AntdButton" +participant Form as "AntdForm" +participant FE as "Frontend" +Btn->>Btn : Define EVENTS["click"] +Btn->>Btn : Callback updates _internal.bind_click_event +FE-->>Btn : Listen for click event and execute callback +Form->>Form : Define EVENTS["fields_change","finish","finish_failed","values_change"] +Form->>Form : Callback updates _internal binding flags +FE-->>Form : Listen for form events and sync state +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) +- [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) + +Section Sources + +- [backend/modelscope_studio/components/antd/button/**init**.py:41-46](file://backend/modelscope_studio/components/antd/button/__init__.py#L41-L46) +- [backend/modelscope_studio/components/antd/form/**init**.py:23-36](file://backend/modelscope_studio/components/antd/form/__init__.py#L23-L36) + +### Property Definition and Validation Mechanism + +- Property Declaration: Components receive `value`, `additional_props`, and numerous UI-related parameters (e.g., size, shape, color, style) in `__init__`, saved as instance properties. +- Data Model: Some components provide custom data models (e.g., `AntdFormData`) to normalize complex data structures. +- Validation and Conversion: `preprocess`/`postprocess` explicitly define input/output shapes, preventing data inconsistencies between frontend and backend. + +```mermaid +flowchart TD +Start(["Enter Component"]) --> Init["Receive parameters and assign to instance properties"] +Init --> DataModel{"Data model defined?"} +DataModel --> |Yes| UseDM["Use data model to normalize input"] +DataModel --> |No| SkipDM["Skip data model"] +UseDM --> Pre["preprocess(payload) normalize input"] +SkipDM --> Pre +Pre --> Process["Business logic/state update"] +Process --> Post["postprocess(value) normalize output"] +Post --> End(["Return to frontend"]) +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/form/**init**.py:13-15](file://backend/modelscope_studio/components/antd/form/__init__.py#L13-L15) +- [backend/modelscope_studio/components/antd/form/**init**.py:120-126](file://backend/modelscope_studio/components/antd/form/__init__.py#L120-L126) + +Section Sources + +- [backend/modelscope_studio/components/antd/button/**init**.py:51-137](file://backend/modelscope_studio/components/antd/button/__init__.py#L51-L137) +- [backend/modelscope_studio/components/antd/form/**init**.py:13-15](file://backend/modelscope_studio/components/antd/form/__init__.py#L13-L15) +- [backend/modelscope_studio/components/antd/form/**init**.py:120-126](file://backend/modelscope_studio/components/antd/form/__init__.py#L120-L126) + +### Lifecycle Hooks and Render Control + +- Initialization: Sets base properties such as `visible`, `elem_id`, `elem_classes`, `elem_style`, `render`, `as_item`, and `_internal`. +- Context Exit: Layout-type components update `layout=True` in `__exit__` to ensure the frontend recalculates the layout. +- Rendering Strategy: `skip_api` controls whether to expose an API; `render` controls whether to render; `preserved_by_key` controls the data retention strategy (effective in data layout components). + +Section Sources + +- [backend/modelscope_studio/utils/dev/component.py:24-26](file://backend/modelscope_studio/utils/dev/component.py#L24-L26) +- [backend/modelscope_studio/utils/dev/component.py:125-127](file://backend/modelscope_studio/utils/dev/component.py#L125-L127) +- [backend/modelscope_studio/utils/dev/component.py:161-168](file://backend/modelscope_studio/utils/dev/component.py#L161-L168) + +### Integration with Frontend Svelte Components + +- Directory Mapping: Component classes point to the frontend Svelte component directory via `FRONTEND_DIR`, ensuring one-to-one correspondence between frontend and backend. +- Slots and Events: `SLOTS` defines slot names; `EVENTS` defines events; the frontend renders and binds accordingly. +- Data Conversion: `preprocess`/`postprocess` ensures consistent data shapes between Python and JS layers. + +Section Sources + +- [backend/modelscope_studio/components/antd/button/**init**.py:139-156](file://backend/modelscope_studio/components/antd/button/__init__.py#L139-L156) +- [backend/modelscope_studio/components/antd/form/**init**.py:114-132](file://backend/modelscope_studio/components/antd/form/__init__.py#L114-L132) +- [backend/modelscope_studio/components/base/text/**init**.py:39-56](file://backend/modelscope_studio/components/base/text/__init__.py#L39-L56) + +### Steps and Standards for Creating a New Component + +- Choose a Family and Directory + - Select the appropriate family from `antd`, `antdx`, `base`, or `pro`, and create a new component subdirectory under the corresponding directory. +- Write the Component Class + - Inherit from the appropriate base class (general / layout / data layout). + - Define `EVENTS`, `SLOTS`, and `FRONTEND_DIR`. + - Implement `preprocess`/`postprocess`/`example_payload`/`example_value`. + - Receive and store all external parameters in `__init__`. +- Register the Component + - Import and export the component class in the family-level `components.py`. + - If adding a new family, add the export to `components/__init__.py`. +- Reference Examples + - Text component (`base/text`): Minimal component example, demonstrating minimal properties and methods. + - Button component (`antd/button`): Layout-type component with events and slots. + - Form component (`antd/form`): Data layout component with a data model and multiple events. + +Section Sources + +- [backend/modelscope_studio/components/antd/button/**init**.py:15-157](file://backend/modelscope_studio/components/antd/button/__init__.py#L15-L157) +- [backend/modelscope_studio/components/antd/form/**init**.py:17-133](file://backend/modelscope_studio/components/antd/form/__init__.py#L17-L133) +- [backend/modelscope_studio/components/base/text/**init**.py:8-57](file://backend/modelscope_studio/components/base/text/__init__.py#L8-L57) +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) + +## Dependency Analysis + +- Component Family Exports + - `antd/components.py` imports and exports numerous component classes, forming a complete ecosystem. + - `antdx/components.py` exports the extended component family. + - `pro/components.py` exports the professional component family. + - `base/__init__.py` exports the base component family. + - `components/__init__.py` aggregates the above family exports as a unified entry point. +- Component Class Dependencies + - All components depend on base classes and utility functions (e.g., `resolve_frontend_dir`) under `utils/dev`. +- Events and Context + - Events are defined via `gradio.events.EventListener`; callbacks update `_internal` flags, which the frontend uses to bind. + +```mermaid +graph LR +subgraph "Component Families" +ANTDA["antd/components.py"] +ANTDXA["antdx/components.py"] +PROA["pro/components.py"] +BASEA["base/__init__.py"] +end +subgraph "Aggregation" +ROOTI["components/__init__.py"] +end +ANTDA --> ROOTI +ANTDXA --> ROOTI +PROA --> ROOTI +BASEA --> ROOTI +``` + +Diagram Sources + +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) + +Section Sources + +- [backend/modelscope_studio/components/antd/components.py:1-145](file://backend/modelscope_studio/components/antd/components.py#L1-L145) +- [backend/modelscope_studio/components/antdx/components.py:1-40](file://backend/modelscope_studio/components/antdx/components.py#L1-L40) +- [backend/modelscope_studio/components/pro/components.py:1-8](file://backend/modelscope_studio/components/pro/components.py#L1-L8) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) + +## Performance Considerations + +- Minimize Event Binding: Only enable event binding when necessary to avoid frequent `_internal` updates causing frontend re-renders. +- Lightweight Data Conversion: `preprocess`/`postprocess` should remain simple and efficient, avoiding deep copying and complex calculations. +- Render Control: Use `render` and `skip_api` appropriately to reduce unnecessary API exposure and rendering overhead. +- Layout Component Optimization: Layout components update `layout=True` in `__exit__`; avoid triggering this repeatedly in high-frequency events. + +## Troubleshooting Guide + +- Event Not Taking Effect + - Check that `EVENTS` is correctly declared and that callbacks update the corresponding `_internal` flags. + - Confirm that the frontend has bound events based on `_internal` flags. +- Frontend Cannot Find Component + - Check that `FRONTEND_DIR` points to the correct Svelte directory. + - Confirm that the component class is exported in `components.py` and aggregated in `components/__init__.py`. +- Data Inconsistency + - Check that `preprocess`/`postprocess` aligns with the data shapes on both frontend and backend. + - For complex data, confirm that a custom data model is used and correctly parsed/serialized. +- Rendering Anomaly + - Check that `skip_api` and `render` settings match expectations. + - For layout components, pay attention to the timing of layout updates in `__exit__`. + +Section Sources + +- [backend/modelscope_studio/utils/dev/component.py:15-26](file://backend/modelscope_studio/utils/dev/component.py#L15-L26) +- [backend/modelscope_studio/utils/dev/component.py:125-127](file://backend/modelscope_studio/utils/dev/component.py#L125-L127) +- [backend/modelscope_studio/components/antd/button/**init**.py:139-156](file://backend/modelscope_studio/components/antd/button/__init__.py#L139-L156) +- [backend/modelscope_studio/components/antd/form/**init**.py:114-132](file://backend/modelscope_studio/components/antd/form/__init__.py#L114-L132) + +## Conclusion + +Through a unified base class hierarchy, clear event and slot conventions, strict frontend-backend directory mapping, and data conversion standards, ModelScope Studio's backend component development achieves a highly cohesive, loosely coupled, and easily extensible architecture. By following the structural conventions and implementation steps in this document, you can quickly create high-quality components that integrate seamlessly with the frontend Svelte ecosystem. + +## Appendix + +- Quick Reference + - Component Base Classes: `ModelScopeComponent` / `ModelScopeLayoutComponent` / `ModelScopeDataLayoutComponent` + - Key Properties: `EVENTS`, `SLOTS`, `FRONTEND_DIR`, `skip_api`, `preprocess`/`postprocess`, `example_payload`/`example_value` + - Registration Path: Family-level `components.py` → `components/__init__.py` + - Example Components: `antd/button`, `antd/form`, `base/text` diff --git a/.wiki/en/Development Guide/Component Development/Component Development Best Practices.md b/.wiki/en/Development Guide/Component Development/Component Development Best Practices.md new file mode 100644 index 00000000..37bfbb9f --- /dev/null +++ b/.wiki/en/Development Guide/Component Development/Component Development Best Practices.md @@ -0,0 +1,407 @@ +# Component Development Best Practices + + +**Files Referenced in This Document** +- [frontend/package.json](file://frontend/package.json) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/form/form.tsx](file://frontend/antd/form/form.tsx) +- [frontend/base/text/text.tsx](file://frontend/base/text/text.tsx) +- [frontend/antd/layout/layout.base.tsx](file://frontend/antd/layout/layout.base.tsx) +- [frontend/antd/grid/context.ts](file://frontend/antd/grid/context.ts) +- [frontend/antd/config-provider/config-provider.tsx](file://frontend/antd/config-provider/config-provider.tsx) +- [frontend/antd/form/context.ts](file://frontend/antd/form/context.ts) +- [frontend/utils/hooks/useFunction.ts](file://frontend/utils/hooks/useFunction.ts) +- [frontend/utils/hooks/useMemoizedFn.ts](file://frontend/utils/hooks/useMemoizedFn.ts) +- [frontend/utils/createFunction.ts](file://frontend/utils/createFunction.ts) +- [frontend/utils/createItemsContext.tsx](file://frontend/utils/createItemsContext.tsx) +- [frontend/antd/table/table.tsx](file://frontend/antd/table/table.tsx) +- [frontend/antd/modal/modal.tsx](file://frontend/antd/modal/modal.tsx) +- [eslint.config.mjs](file://eslint.config.mjs) +- [prettier.config.mjs](file://prettier.config.mjs) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This guide is intended for engineers developing components within the ModelScope Studio frontend ecosystem. It systematically summarizes design principles and coding conventions, covering naming conventions, file organization, code style, performance optimization, reusability design, error handling and edge cases, internationalization and accessibility, and cross-browser compatibility — with refactoring recommendations and best practices drawn from real component implementations in the repository. + +## Project Structure + +This project uses a multi-package workspace (pnpm workspace) structure, with the frontend centered on the Svelte 5 + React ecosystem, bridging the Ant Design component library through a preprocessing layer to form a unified component system. Components are layered by domain: modules such as `antd`, `antdx`, `base`, and `pro`, where each component typically consists of a Svelte entry file and a corresponding React wrapper, with utility functions and context for high cohesion and low coupling. + +```mermaid +graph TB +subgraph "Frontend Package" +Pkg["package.json
Dependency Declaration"] +end +subgraph "Component Layer" +AntD["antd/* Components"] +AntDX["antdx/* Components"] +Base["base/* Base Components"] +Pro["pro/* Pro Components"] +end +subgraph "Utilities and Context" +Utils["utils/* Utility Functions"] +Ctx["createItemsContext.tsx
Generic Items Context"] +end +Pkg --> AntD +Pkg --> AntDX +Pkg --> Base +Pkg --> Pro +AntD --> Utils +AntDX --> Utils +Base --> Utils +Pro --> Utils +Utils --> Ctx +``` + +Diagram Sources + +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) + +Section Sources + +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) + +## Core Components + +This section focuses on key patterns and conventions for component development, including: + +- Unified entry and wrapping: The Svelte entry handles prop forwarding, lazy loading, and slot rendering; the React wrapper handles lifecycle and state management. +- Configurable internationalization and theming: Use `ConfigProvider` to manage language, theme algorithm, and container strategy. +- Highly cohesive context: `createItemsContext` abstracts "item collections" and "sub-item handlers", supporting complex component scenarios such as dynamic columns, row selection, and expand. +- Functional capabilities: `useFunction`, `useMemoizedFn`, and `createFunction` safely convert string or functional configurations into runtime functions. + +Section Sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/utils/hooks/useFunction.ts:1-13](file://frontend/utils/hooks/useFunction.ts#L1-L13) +- [frontend/utils/hooks/useMemoizedFn.ts:1-11](file://frontend/utils/hooks/useMemoizedFn.ts#L1-L11) +- [frontend/utils/createFunction.ts:1-38](file://frontend/utils/createFunction.ts#L1-L38) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +## Architecture Overview + +The diagram below shows the critical path from entry to rendering, as well as the relationships with utility functions and context. + +```mermaid +sequenceDiagram +participant Svelte as "Svelte Entry (Index.svelte)" +participant Preprocess as "Preprocess Bridge" +participant ReactComp as "React Wrapper (.tsx)" +participant Util as "Utility Functions (useFunction/createFunction)" +participant Ctx as "Context (createItemsContext)" +Svelte->>Preprocess : "importComponent lazy load" +Preprocess-->>Svelte : "Awaited component" +Svelte->>ReactComp : "processProps forward props/slots" +ReactComp->>Util : "useFunction/createFunction safe execution" +ReactComp->>Ctx : "withItemsContextProvider/ItemHandler" +ReactComp-->>Svelte : "Render final UI" +``` + +Diagram Sources + +- [frontend/antd/button/Index.svelte:10-73](file://frontend/antd/button/Index.svelte#L10-L73) +- [frontend/antd/form/form.tsx:15-76](file://frontend/antd/form/form.tsx#L15-L76) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/createFunction.ts:10-37](file://frontend/utils/createFunction.ts#L10-L37) +- [frontend/utils/createItemsContext.tsx:171-184](file://frontend/utils/createItemsContext.tsx#L171-L184) + +## Detailed Component Analysis + +### Component Naming and File Organization + +- Naming Conventions + - Component directories and file names use lowerCamelCase or kebab-case, e.g., `button`, `date-picker`, `config-provider`. + - Svelte entries are uniformly named `Index.svelte`; the corresponding component source file is named `componentName.tsx` or `componentName.svelte`. +- File Organization + - Each component contains: an entry file (`Index.svelte`), component implementation (`*.tsx`), styles (`*.less`), and configuration (`package.json`, `gradio.config.js`). + - Complex components are split into sub-modules (e.g., `column`, `row-selection`, `expandable` for `table`), aggregated via context. + +Section Sources + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) +- [frontend/antd/table/table.tsx:1-200](file://frontend/antd/table/table.tsx#L1-L200) + +### Prop Forwarding and Lazy Loading + +- Lazy Loading: Use `importComponent` for on-demand loading, preventing initial bundle bloat. +- Prop Forwarding: `processProps` filters internal fields and retains external-facing props such as visibility, style, class names, and IDs. +- Slot Rendering: `getSlots` retrieves default slots and renders custom nodes in conjunction with `ReactSlot`. + +```mermaid +flowchart TD +Start(["Enter Component"]) --> Load["Lazy load React component"] +Load --> Props["processProps filter/merge props"] +Props --> Slots["getSlots parse slots"] +Slots --> Visible{"visible is true?"} +Visible --> |Yes| Render["Render component with props/slots"] +Visible --> |No| Hide["Do not render"] +Render --> End(["Complete"]) +Hide --> End +``` + +Diagram Sources + +- [frontend/antd/button/Index.svelte:12-56](file://frontend/antd/button/Index.svelte#L12-L56) + +Section Sources + +- [frontend/antd/button/Index.svelte:12-74](file://frontend/antd/button/Index.svelte#L12-L74) + +### Form Component: State Synchronization and Action Dispatch + +- Action Dispatch: Triggers the corresponding behavior based on `formAction` (reset/submit/validate), then resets the action flag upon completion. +- Value Synchronization: Sets form values when `value` changes; resets fields when not provided. +- Slots and Callbacks: `requiredMark` and `feedbackIcons` prefer slots; otherwise fall back to functions or static values; `onValuesChange` syncs external state. + +```mermaid +sequenceDiagram +participant UI as "Caller" +participant Form as "Form Component" +participant AntD as "Antd Form" +UI->>Form : "Pass value / formAction" +Form->>AntD : "Initialize Form instance" +alt formAction = reset +Form->>AntD : "resetFields()" +else formAction = submit +Form->>AntD : "submit()" +else formAction = validate +Form->>AntD : "validateFields()" +end +Form->>UI : "onResetFormAction()" +UI->>Form : "value change" +Form->>AntD : "setFieldsValue(value)" +``` + +Diagram Sources + +- [frontend/antd/form/form.tsx:32-53](file://frontend/antd/form/form.tsx#L32-L53) +- [frontend/antd/form/form.tsx:15-76](file://frontend/antd/form/form.tsx#L15-L76) + +Section Sources + +- [frontend/antd/form/form.tsx:1-79](file://frontend/antd/form/form.tsx#L1-L79) + +### Layout Base Component: Dynamic Selector + +- The Base component dynamically selects Header/Footer/Content/Layout based on the `component` parameter and uniformly injects a class prefix for style isolation. + +Section Sources + +- [frontend/antd/layout/layout.base.tsx:1-40](file://frontend/antd/layout/layout.base.tsx#L1-L40) + +### Internationalization and Theming: ConfigProvider + +- Theme Algorithm: Supports dark and compact algorithm combinations, switching based on `themeMode`. +- Language Switching: Formats the `navigator` language as an available locale code and dynamically loads `antd` and `dayjs` localization resources. +- Container Strategy: `getPopupContainer`/`getTargetContainer` supports strings or functions; functions are safely executed via `useFunction`. +- Slot Injection: Supports converting slots like `renderEmpty` to React nodes. + +```mermaid +flowchart TD +Init["Initialize ConfigProvider"] --> Locale["Parse locale code"] +Locale --> LoadRes["Async load language resources"] +LoadRes --> ApplyTheme["Compute algorithm array"] +ApplyTheme --> Render["Render subtree"] +``` + +Diagram Sources + +- [frontend/antd/config-provider/config-provider.tsx:85-105](file://frontend/antd/config-provider/config-provider.tsx#L85-L105) +- [frontend/antd/config-provider/config-provider.tsx:127-143](file://frontend/antd/config-provider/config-provider.tsx#L127-L143) + +Section Sources + +- [frontend/antd/config-provider/config-provider.tsx:1-154](file://frontend/antd/config-provider/config-provider.tsx#L1-L154) + +### Context and Item Collections: createItemsContext + +- Purpose: Provides a collection and passing mechanism for "item collections" in complex components (e.g., tables, form item rules). +- Key Capabilities + - `withItemsContextProvider`: Wraps the subtree to establish context. + - `ItemHandler`: Writes child items (props/slots/children) to the context, supporting memoization and deduplication. + - `useItems`: Reads the current item collection and triggers the `onChange` callback. +- Use Cases: Table columns, expandable items, row selection, form item rules, etc. + +```mermaid +classDiagram +class ItemsContextProvider { ++allowedSlots ++onChange(items) ++setItem(slotKey, index, item) +} +class ItemHandler { ++itemIndex ++itemSlotKey ++itemProps(props, items) ++itemChildren(items) ++slots +} +class useItems { ++items ++initial ++setItem(...) +} +ItemsContextProvider --> useItems : "Provides" +ItemHandler --> ItemsContextProvider : "Write item" +useItems --> ItemsContextProvider : "Read item" +``` + +Diagram Sources + +- [frontend/utils/createItemsContext.tsx:108-170](file://frontend/utils/createItemsContext.tsx#L108-L170) +- [frontend/utils/createItemsContext.tsx:190-261](file://frontend/utils/createItemsContext.tsx#L190-L261) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) + +Section Sources + +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) +- [frontend/antd/grid/context.ts:1-7](file://frontend/antd/grid/context.ts#L1-L7) +- [frontend/antd/form/context.ts:1-10](file://frontend/antd/form/context.ts#L1-L10) + +### Table Component: Columns, Expand, Row Selection, and Function Configuration + +- Columns and Expand: Aggregates column and expand configurations via context, supporting default columns and built-in placeholders (`EXPAND_COLUMN`, `SELECTION_COLUMN`). +- Function Configuration: `getPopupContainer`, `rowKey`, `rowClassName`, `sticky`, `showSorterTooltip`, `summary`/`footer`, etc. all support strings or functions, executed safely via `createFunction`/`useFunction`. +- Slots: `loading`, `pagination`, `tooltip`, `summary`, etc. support parameterized slot rendering. + +Section Sources + +- [frontend/antd/table/table.tsx:41-200](file://frontend/antd/table/table.tsx#L41-L200) + +### Modal Component: Slots and Functional Configuration + +- Slot Priority: `okText`, `cancelText`, `footer`, `title`, `closeIcon`, `okButtonProps.icon`, `cancelButtonProps.icon`, `closable.closeIcon`, `modalRender`, etc. prefer slots. +- Function Fallback: When slots are unavailable, `useFunction` converts strings or functions into executable functions. +- Container Strategy: `getContainer` supports string selectors or functions. + +Section Sources + +- [frontend/antd/modal/modal.tsx:1-107](file://frontend/antd/modal/modal.tsx#L1-L107) + +### Base Text Component: Minimal Implementation + +- Receives only `value` and renders it; inserts an empty placeholder element if empty, ensuring stable DOM structure. + +Section Sources + +- [frontend/base/text/text.tsx:1-11](file://frontend/base/text/text.tsx#L1-L11) + +## Dependency Analysis + +- Dependency Sources: `package.json` centrally declares dependencies related to Ant Design, React, Svelte, internationalization, and multimedia. +- Inter-Component Coupling: Coupling is reduced through the preprocessing bridge and utility functions; complex components are decoupled via context. +- External Integration: `ConfigProvider` works with `dayjs` for language switching; `StyleProvider` controls style hash priority. + +```mermaid +graph LR +AntD["antd"] --> Comp["Component Implementation (.tsx)"] +React["react + react-dom"] --> Comp +Svelte["svelte"] --> Entry["Entry (Index.svelte)"] +Entry --> Comp +Utils["Utility Functions"] --> Comp +Ctx["createItemsContext"] --> Comp +``` + +Diagram Sources + +- [frontend/package.json:8-40](file://frontend/package.json#L8-L40) +- [frontend/antd/button/Index.svelte:6-10](file://frontend/antd/button/Index.svelte#L6-L10) +- [frontend/utils/createItemsContext.tsx:1-274](file://frontend/utils/createItemsContext.tsx#L1-L274) + +Section Sources + +- [frontend/package.json:1-59](file://frontend/package.json#L1-L59) + +## Performance Considerations + +- Lazy Loading and On-Demand Rendering + - Use `importComponent` for on-demand loading, avoiding initial blocking from importing too many components at once. + - Svelte conditional rendering with the `visible` field reduces mounting of invalid nodes. +- Function and Object Stability + - `useFunction`/`useMemoizedFn`/`createFunction` convert string or functional configurations into stable functions, avoiding repeated closure creation. + - `useMemo`/`useMemoizedEqualValue` cache expensive calculations and equality comparisons in context. +- Slots and Hidden Rendering + - Complex components often render actual content in a hidden state, only exposing placeholders, to reduce initial layout jitter. +- Theming and Styles + - `StyleProvider` configures hash priority to prevent repaints caused by style conflicts. +- Events and Callbacks + - Use `useMemoizedFn` to cache references for high-frequency callbacks, reducing the probability of child component re-renders. + +Section Sources + +- [frontend/antd/button/Index.svelte:59-73](file://frontend/antd/button/Index.svelte#L59-L73) +- [frontend/antd/form/form.tsx:28-30](file://frontend/antd/form/form.tsx#L28-L30) +- [frontend/utils/hooks/useFunction.ts:5-12](file://frontend/utils/hooks/useFunction.ts#L5-L12) +- [frontend/utils/hooks/useMemoizedFn.ts:3-10](file://frontend/utils/hooks/useMemoizedFn.ts#L3-L10) +- [frontend/utils/createFunction.ts:10-37](file://frontend/utils/createFunction.ts#L10-L37) +- [frontend/antd/config-provider/config-provider.tsx:110-110](file://frontend/antd/config-provider/config-provider.tsx#L110-L110) + +## Troubleshooting Guide + +- Slot Not Taking Effect + - Check that the slot key is correct (e.g., `footer`, `title`, `okText`); confirm that it is wrapped with `ReactSlot`. + - For slots requiring parameters, use `renderParamsSlot` for rendering. +- Function Configuration Anomaly + - If a string function is passed, ensure the format is valid; use `createFunction`/`useFunction` for safe execution. +- Theme or Language Not Taking Effect + - Confirm the `themeMode` and `locale` settings; check that language resource loading succeeded. +- Context Items Not Updating + - Ensure `ItemHandler`'s `itemIndex` and `itemSlotKey` are correct; check that `setItem` is being called. +- Performance Issues + - Check for unnecessary prop changes; use `useMemoizedFn` for callbacks; avoid creating new functions inside `render`. + +Section Sources + +- [frontend/antd/modal/modal.tsx:40-95](file://frontend/antd/modal/modal.tsx#L40-L95) +- [frontend/antd/config-provider/config-provider.tsx:96-105](file://frontend/antd/config-provider/config-provider.tsx#L96-L105) +- [frontend/utils/createFunction.ts:10-37](file://frontend/utils/createFunction.ts#L10-L37) +- [frontend/utils/createItemsContext.tsx:234-254](file://frontend/utils/createItemsContext.tsx#L234-L254) + +## Conclusion + +Based on existing component implementations in the repository, this guide summarizes the design principles and engineering practices for component development: using the Svelte entry + React wrapper bridging pattern for a unified ecosystem; achieving high cohesion and low coupling through context and utility functions; improving performance and extensibility through lazy loading, function stabilization, and the slot mechanism. Following these best practices will enhance component quality and maintainability while ensuring consistency. + +## Appendix + +### Design Principles and Coding Standards + +- Naming and Organization + - Component directories and file names use lowerCamelCase or kebab-case; entries are uniformly `Index.svelte`; implementations are `*.tsx`. + - Complex components are split into sub-modules and aggregated via context. +- Props and Slots + - Clearly distinguish between external and internal props; forward external props via `processProps`; slots take priority over static values. +- Functions and Callbacks + - All string functions are executed safely via `createFunction`/`useFunction`; high-frequency callbacks are cached with `useMemoizedFn`. +- Internationalization and Theming + - Use `ConfigProvider` to manage language and theme; load language resources on demand; container strategy supports both strings and functions. +- Styles and Theming + - Use `StyleProvider` to control style hash priority; inject unified prefix class names for different component types. +- Error Handling and Edge Cases + - Return `undefined` and degrade gracefully for unrecognized function strings; provide reasonable default values when slots are missing. +- Accessibility and Compatibility + - Maintain semantic tags and accessible attributes; avoid relying solely on color to convey information; test on mainstream browsers and mobile devices. + +Section Sources + +- [frontend/antd/button/Index.svelte:24-52](file://frontend/antd/button/Index.svelte#L24-L52) +- [frontend/antd/config-provider/config-provider.tsx:110-149](file://frontend/antd/config-provider/config-provider.tsx#L110-L149) +- [frontend/utils/createFunction.ts:10-37](file://frontend/utils/createFunction.ts#L10-L37) +- [eslint.config.mjs:1-9](file://eslint.config.mjs#L1-L9) +- [prettier.config.mjs:1-26](file://prettier.config.mjs#L1-L26) diff --git a/.wiki/en/Development Guide/Component Development/Component Development.md b/.wiki/en/Development Guide/Component Development/Component Development.md new file mode 100644 index 00000000..6aa46510 --- /dev/null +++ b/.wiki/en/Development Guide/Component Development/Component Development.md @@ -0,0 +1,366 @@ +# Component Development + + +**Files referenced in this document** +- [backend/modelscope_studio/components/__init__.py](file://backend/modelscope_studio/components/__init__.py) +- [backend/modelscope_studio/components/base/__init__.py](file://backend/modelscope_studio/components/base/__init__.py) +- [backend/modelscope_studio/components/antd/__init__.py](file://backend/modelscope_studio/components/antd/__init__.py) +- [backend/modelscope_studio/components/pro/__init__.py](file://backend/modelscope_studio/components/pro/__init__.py) +- [backend/modelscope_studio/utils/dev/component.py](file://backend/modelscope_studio/utils/dev/component.py) +- [frontend/svelte-preprocess-react/index.ts](file://frontend/svelte-preprocess-react/index.ts) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts](file://frontend/svelte-preprocess-react/sveltify.svelte.ts) +- [frontend/svelte-preprocess-react/react-slot.tsx](file://frontend/svelte-preprocess-react/react-slot.tsx) +- [frontend/utils/renderSlot.tsx](file://frontend/utils/renderSlot.tsx) +- [frontend/utils/patchProps.tsx](file://frontend/utils/patchProps.tsx) +- [frontend/antd/button/Index.svelte](file://frontend/antd/button/Index.svelte) +- [frontend/antd/form/Index.svelte](file://frontend/antd/form/Index.svelte) +- [frontend/antd/button/button.tsx](file://frontend/antd/button/button.tsx) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This guide is intended for engineers and product teams developing components in ModelScope Studio. It covers backend Python component implementation, frontend Svelte component development, React component bridging and slot system usage, as well as component structure conventions, property definitions, event handling, testing, and documentation best practices. By analyzing the backend component base classes and frontend bridging mechanisms in parallel, this guide helps you quickly extend existing components or create entirely new component types. + +## Project Structure + +The ModelScope Studio component system consists of three layers: + +- Backend Python component layer: Uniformly inherits from Gradio's component metaclass, providing common lifecycle, events, and slot capabilities. +- Frontend Svelte layer: Each component loads its corresponding React implementation as a Svelte wrapper, responsible for prop passing, event bridging, and slot rendering. +- React bridging layer: Bridges Ant Design and other React components to be usable as Svelte components via `sveltify`, supporting slot and style passing. + +```mermaid +graph TB +subgraph "Backend Python" +PY_BASE["ModelScopeComponent
ModelScopeLayoutComponent
ModelScopeDataLayoutComponent"] +end +subgraph "Frontend Svelte" +SV_WRAPPER["Svelte Wrapper
Index.svelte"] +SV_SLOT["Slot Rendering Utility
renderSlot.tsx"] +end +subgraph "React Bridge" +REACT_SVELTIFY["sveltify Bridge
sveltify.svelte.ts"] +REACT_SLOT["ReactSlot Bridge
react-slot.tsx"] +PATCH_PROPS["Props Patch Utility
patchProps.tsx"] +end +PY_BASE --> SV_WRAPPER +SV_WRAPPER --> REACT_SVELTIFY +SV_WRAPPER --> SV_SLOT +SV_SLOT --> REACT_SLOT +REACT_SVELTIFY --> PATCH_PROPS +``` + +**Diagram Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) + +**Section Sources** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) + +## Core Components + +- Backend component base classes + - ModelScopeComponent: For data components, supports common props like `visible`, `elem_id`, `elem_classes`, `elem_style`, `value`, `key`, `inputs`, `load_fn`, etc.; exposes API by default. + - ModelScopeLayoutComponent: For layout components, supports `as_item`, `visible`, `elem_id`, `elem_classes`, `elem_style`, `render`, etc.; skips API export by default. + - ModelScopeDataLayoutComponent: Data + layout hybrid component, has BlockContext capability and layout marker to avoid duplicate rendering. +- Frontend bridging and slots + - sveltify: Wraps React components as Svelte components, supporting slots parameter declaration and slot tree construction. + - ReactSlot: Clones and mounts Svelte slot content into React subtrees, supporting prop and event passing, and MutationObserver observation. + - renderSlot: Convenient entry point for context-wrapped rendering based on whether forced cloning or parameterized rendering is needed. + - patchProps/applyPatchToProps: Compatibility conversion of internal fields like `key`, ensuring stable React rendering. + +**Section Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) + +## Architecture Overview + +The diagram below shows the call chain from backend component to frontend Svelte wrapper to React component, and how the slot system reuses Svelte slot content in React subtrees. + +```mermaid +sequenceDiagram +participant PY as "Backend Component
ModelScopeComponent" +participant SV as "Svelte Wrapper
Index.svelte" +participant BR as "Bridge
sveltify.svelte.ts" +participant RX as "React Component
button.tsx" +participant RS as "Slot Bridge
ReactSlot" +PY->>SV : Initialize and inject props/values +SV->>BR : importComponent loads React implementation +BR->>RX : Create Svelte node tree and mount +RX->>RS : Render slots using slots and ReactSlot +RS-->>RX : Clone and mount slot DOM (with events) +RX-->>SV : Event callback triggers updateProps +SV-->>PY : Update backend state (e.g., value, form_action) +``` + +**Diagram Sources** + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) + +## Detailed Component Analysis + +### Backend Component Base Classes and Lifecycle + +- Inheritance relationships + - ModelScopeComponent: Base data component, supports `value`, `visible`, `elem_*`, `key`, `inputs`, `load_fn`, etc. + - ModelScopeLayoutComponent: Layout component, supports `as_item`, `visible`, `elem_*`, `render`. + - ModelScopeDataLayoutComponent: Combines data and layout characteristics, marks layout on enter/exit to avoid duplicate rendering. +- Key behaviors + - Automatically records parent component child node indexes for positioning and updates. + - Supports skipping API export (`skip_api`), used for layout components. + - Works with AppContext to ensure application context exists. + +```mermaid +classDiagram +class ModelScopeComponent { ++EVENTS ++skip_api ++__init__(...) +} +class ModelScopeLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__exit__(...) +} +class ModelScopeDataLayoutComponent { ++EVENTS ++SLOTS ++skip_api ++__exit__(...) +} +ModelScopeLayoutComponent --|> ModelScopeComponent +ModelScopeDataLayoutComponent --|> ModelScopeComponent +``` + +**Diagram Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +**Section Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) + +### Frontend Svelte Wrapper and Prop Handling + +- Typical flow + - Asynchronously load the corresponding React component via `importComponent`. + - Extract and transform props using `getProps`/`processProps`, mapping names (e.g., `fields_change` → `fieldsChange`). + - Retrieve the slot collection via `getSlots` and pass to the React component. + - Render with visibility control, passing `children` as the default slot. +- Event bridging + - For mutable value components (e.g., Form), listen to `onValueChange` and call `updateProps` to update backend state. + +```mermaid +flowchart TD +Start(["Enter Svelte Wrapper"]) --> Load["importComponent loads React component"] +Load --> Extract["getProps/processProps extract and transform props"] +Extract --> Slots["getSlots retrieves slot collection"] +Slots --> Visible{"visible is true?"} +Visible --> |Yes| Render["Render React component with slots/value/events"] +Visible --> |No| Skip["Skip rendering"] +Render --> Events["Bind event callbacks (e.g., onValueChange)"] +Events --> Update["updateProps updates backend state"] +Update --> End(["Complete"]) +Skip --> End +``` + +**Diagram Sources** + +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + +**Section Sources** + +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + +### React Component Bridging and Slot System + +- sveltify + - Accepts React component and optional slots declarations, returns a Sveltified component. + - Internally maintains shared root nodes and Portals, creating Bridge render trees on demand. + - Supports ignoring certain nodes for complex scenario optimization. +- ReactSlot + - Clones Svelte slots into React subtrees, preserving event listeners and child nodes. + - Supports force cloning (`forceClone`), parameterized rendering (`params`), and attribute observation (`observeAttributes`). + - Uses ContextPropsProvider and patchProps utilities to ensure internal fields like `key` are correctly passed. +- Slot rendering pipeline + - `renderSlot` decides whether to wrap with ContextPropsProvider based on options. + - `patchProps`/`applyPatchToProps` corrects the `key` field before and after bridging to avoid React warnings. + +```mermaid +sequenceDiagram +participant SV as "Svelte Component" +participant BR as "sveltify" +participant RD as "Bridge/ReactDOM" +participant RS as "ReactSlot" +participant RX as "Antd Component" +SV->>BR : sveltify(ReactComp, { slots }) +BR->>RD : Create shared root node and Portal +RD-->>BR : Initialization complete +BR-->>SV : Return renderable Sveltified component +SV->>RS : Pass slots and props +RS->>RS : Clone slot DOM (with events) +RS-->>RX : Render slot content +``` + +**Diagram Sources** + +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) + +**Section Sources** + +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/svelte-preprocess-react/react-slot.tsx:1-224](file://frontend/svelte-preprocess-react/react-slot.tsx#L1-L224) +- [frontend/utils/renderSlot.tsx:1-29](file://frontend/utils/renderSlot.tsx#L1-L29) +- [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) + +### Component Structure Conventions and Prop Definitions + +- Structure conventions + - Each component directory contains: `Index.svelte` (wrapper), corresponding React implementation (e.g., `button.tsx`), `package.json`, and `gradio.config.js`. + - Wrappers handle prop extraction, event bridging, and slot passing. +- Prop definitions + - Common props: `visible`, `elem_id`, `elem_classes`, `elem_style`, `as_item`, `_internal.layout`, etc. + - Business props: e.g., Form's `formAction`, `name`, Button's `target`, `loading.icon`, etc. + - Mapping rules: `processProps` supports name mapping (e.g., `fields_change` → `fieldsChange`). +- Event handling + - Data components write back to backend via `onValueChange`/`updateProps`. + - Behavior components trigger backend actions via native events like `onClick`/`onSubmit`. +- Slot system + - Named slots like `slots.icon`, `slots['loading.icon']` inject ReactSlot. + - Supports `children` default slot and parameterized slots (`params`). + +**Section Sources** + +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) + +### Extending Existing Components and Creating New Component Types + +- Extending existing components + - Backend: Based on `ModelScopeComponent`/`ModelScopeLayoutComponent`, add props and events, rewrite `__exit__`/`__enter__` as needed. + - Frontend: Extend `getProps`/`processProps` mappings in the Svelte wrapper, add event callbacks and slots. + - React: Use sveltify to add slot declarations, render slots with ReactSlot. +- Creating new component types + - Backend: Choose appropriate base class, define `EVENTS`/`SLOTS`, set `skip_api`. + - Frontend: Create new `Index.svelte`, import `importComponent` and `getSlots`, configure `processProps`. + - React: Implement sveltify wrapping, handle slots and styles, export default component. + +**Section Sources** + +- [backend/modelscope_studio/utils/dev/component.py:11-169](file://backend/modelscope_studio/utils/dev/component.py#L11-L169) +- [frontend/svelte-preprocess-react/sveltify.svelte.ts:1-119](file://frontend/svelte-preprocess-react/sveltify.svelte.ts#L1-L119) +- [frontend/antd/button/Index.svelte:1-74](file://frontend/antd/button/Index.svelte#L1-L74) + +## Dependency Analysis + +- Component classification entry points + - Backend `components/__init__.py` aggregates components from antd, antdx, base, and pro modules. + - `antd/__init__.py` lists numerous Ant Design component aliases for unified importing. + - `base/__init__.py` aggregates base layout and text components. + - `pro/__init__.py` aggregates professional components (e.g., Chatbot, Monaco Editor). +- Frontend bridging entry point + - `svelte-preprocess-react/index.ts` exposes sveltify and internal types for use in component wrappers. + +```mermaid +graph TB +A["backend/modelscope_studio/components/__init__.py"] --> B["antd/__init__.py"] +A --> C["antdx/__init__.py"] +A --> D["base/__init__.py"] +A --> E["pro/__init__.py"] +F["frontend/svelte-preprocess-react/index.ts"] --> G["sveltify.svelte.ts"] +F --> H["react-slot.tsx"] +``` + +**Diagram Sources** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [backend/modelscope_studio/components/antd/**init**.py:1-150](file://backend/modelscope_studio/components/antd/__init__.py#L1-L150) +- [backend/modelscope_studio/components/base/**init**.py:1-11](file://backend/modelscope_studio/components/base/__init__.py#L1-L11) +- [backend/modelscope_studio/components/pro/**init**.py:1-7](file://backend/modelscope_studio/components/pro/__init__.py#L1-L7) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) + +**Section Sources** + +- [backend/modelscope_studio/components/**init**.py:1-5](file://backend/modelscope_studio/components/__init__.py#L1-L5) +- [frontend/svelte-preprocess-react/index.ts:1-8](file://frontend/svelte-preprocess-react/index.ts#L1-L8) + +## Performance Considerations + +- Avoid duplicate rendering + - Use the `layout` marker of `ModelScopeDataLayoutComponent` to reduce duplicate BlockContext rendering. +- Slot cloning strategy + - ReactSlot supports force cloning (`clone`/`forceClone`) to maintain event and structure consistency during complex DOM changes. + - Uses MutationObserver to observe slot changes and redraw on demand, reducing full update costs. +- Prop passing optimization + - Only transform fields like `key` via `patchProps`/`applyPatchToProps` when necessary to reduce React diff overhead. +- Async loading + - Svelte wrappers use `importComponent` to asynchronously load React components to avoid first-screen blocking. + +## Troubleshooting Guide + +- Slots not working + - Check whether the Svelte wrapper correctly calls `getSlots` and passes them to the React component's slots. + - Confirm whether the ReactSlot's `slot` parameter points to the correct DOM node. +- Events not being passed back + - Confirm whether the component listens to `onValueChange` or other callbacks and calls `updateProps` to update backend state. + - For form components, check whether `formAction` has been cleared or reset. +- Style and class name abnormalities + - Check whether `elem_id`, `elem_classes`, `elem_style` are correctly passed to the React component. + - Confirm whether ReactSlot correctly applies `className` and inline styles. +- Key conflicts or warnings + - Use `patchProps`/`applyPatchToProps` to handle internal `key` fields to avoid React errors. + +**Section Sources** + +- [frontend/antd/form/Index.svelte:1-99](file://frontend/antd/form/Index.svelte#L1-L99) +- [frontend/antd/button/button.tsx:1-39](file://frontend/antd/button/button.tsx#L1-L39) +- [frontend/utils/patchProps.tsx:1-39](file://frontend/utils/patchProps.tsx#L1-L39) + +## Conclusion + +Through the coordination of backend component base classes and frontend bridging mechanisms, ModelScope Studio implements a complete component chain from Python to Svelte to React. By following this guide's structure conventions, prop definitions, and event handling practices, you can efficiently extend existing components or create entirely new component types, and use the slot system to achieve flexible content reuse and style passing. + +## Appendix + +- Component Development Checklist + - Backend: Choose appropriate base class, define EVENTS/SLOTS, set skip_api, rewrite lifecycle as needed. + - Frontend: Write Index.svelte, configure getProps/processProps and getSlots, handle event callbacks. + - React: Use sveltify wrapping, declare slots, render slots via ReactSlot, apply styles and props. + - Testing: Cover prop mapping, event passing, slot rendering, and error boundaries. + - Documentation: Write following each component README template under docs/components, provide minimal usable examples and parameter descriptions. diff --git a/.wiki/en/Development Guide/Component Development/Component Documentation Writing.md b/.wiki/en/Development Guide/Component Development/Component Documentation Writing.md new file mode 100644 index 00000000..3873098b --- /dev/null +++ b/.wiki/en/Development Guide/Component Development/Component Documentation Writing.md @@ -0,0 +1,345 @@ +# Component Documentation Writing + + +**Files Referenced in This Document** +- [Docs.py](file://docs/helper/Docs.py) +- [Site.py](file://docs/helper/Site.py) +- [app.py](file://docs/app.py) +- [README.md](file://docs/README.md) +- [FAQ.md](file://docs/FAQ.md) +- [parse_markdown.py](file://docs/helper/parse_markdown.py) +- [button/README.md](file://docs/components/antd/button/README.md) +- [button/app.py](file://docs/components/antd/button/app.py) +- [chatbot/README.md](file://docs/layout_templates/chatbot/README.md) +- [chatbot/app.py](file://docs/layout_templates/chatbot/app.py) +- [example.py](file://docs/demos/example.py) +- [basic.py (button example)](file://docs/components/antd/button/demos/basic.py) +- [basic.py (chatbot template example)](file://docs/layout_templates/chatbot/demos/basic.py) + + +## Table of Contents + +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendix](#appendix) + +## Introduction + +This guide is intended for developers writing complete documentation for ModelScope Studio components, covering the following topics: + +- Writing conventions and metadata configuration for README.md +- Organization structure of the `demos` directory and naming conventions for example files +- Configuration methods for `app.py` and site navigation construction +- Features and usage of the documentation generation tools `Docs.py` and `Site.py` +- Layered conventions for example code: basic usage, advanced configuration, and FAQs +- How to organize component categories and navigation structures +- Template and example path references to help you get started quickly + +## Project Structure + +The documentation system consists of three parts: "component documentation," "layout templates," and "helper utilities," with a unified entry point `app.py` that builds site navigation and content rendering. + +```mermaid +graph TB +A["docs/app.py
Site Entry & Navigation"] --> B["docs/components//
Component Documentation Directory"] +A --> C["docs/layout_templates/