From 4f746842a561ec593d5097235ee377105064e909 Mon Sep 17 00:00:00 2001 From: Phantom <59059173+EurFelux@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:17:17 +0800 Subject: [PATCH] refactor: migrate Flex from antd to custom Flex component (#10083) * refactor(components): rename HStack and VStack to RowFlex and ColFlex for clarity rename HStack to RowFlex and VStack to ColFlex across all components to better reflect their purpose as flex containers with row and column directions. This improves code readability and maintainability while keeping the same functionality. All references to these components have been updated accordingly. * refactor(layout): migrate layout components from .ts to .tsx The layout components have been moved from TypeScript (.ts) to TypeScript with JSX (.tsx) to better support JSX syntax and improve type safety. The functionality remains unchanged. * refactor(Layout): convert styled Box component to functional component Improve maintainability by converting styled-component to a functional component with explicit style props. This provides better type safety through CSSProperties interface and makes the component easier to debug. * refactor(Layout): restructure Box component and convert styled components to functional - Replace styled-components with functional components for Stack and Center - Rename style variable to _style in Box component to avoid naming conflict - Add style prop to Box component to allow external style overrides * refactor(components): rename HSpaceBetweenStack to SpaceBetweenRowFlex for clarity * refactor(Layout): pass through props in Stack components Allow additional props to be passed to Stack and its variants for better flexibility. Convert RowFlex from styled component to regular component for consistency. * refactor(Layout): convert SpaceBetweenRowFlex from styled to component Improve maintainability by converting styled component to a regular component that explicitly passes justifyContent prop * refactor(Layout): convert ColFlex to component and type RowFlex props Improve type safety by explicitly omitting flexDirection from StackProps and convert ColFlex from styled component to regular component for consistency * refactor(Layout): convert BaseTypography from styled to component Improve type safety and maintainability by converting styled component to regular React component with TypeScript interface * refactor(Layout): remove unused BaseTypography component * refactor(Layout): remove unused Container component and interface * refactor(layout): rename Stack to Flex and use CSSProperties types The Stack component was renamed to Flex to better reflect its purpose and align with common naming conventions. The interface properties were also updated to use CSSProperties types for better type safety and consistency with CSS standards. * refactor(Layout): move FlexProps interface and comment out unused ButtonProps Clean up component interfaces by moving FlexProps closer to its usage and commenting out unused ButtonProps interface to reduce clutter * refactor(layout): standardize flex props from alignItems/justifyContent to align/justify The changes standardize the flex-related props in the Layout component and across multiple files from using alignItems/justifyContent to the shorter align/justify. This improves consistency and reduces verbosity in the codebase while maintaining the same functionality. All instances of alignItems have been replaced with align and justifyContent with justify in Flex, RowFlex, ColFlex and related components. The changes are purely syntactic and do not affect the actual layout behavior. This refactoring makes the code more maintainable by using a consistent naming convention for flex properties throughout the application. * refactor(Layout): extend BoxProps with React div props * feat(Layout): add flexWrap prop to Flex component interface Add flexWrap property to FlexProps interface to support CSS flex-wrap functionality. Also replace antd Flex with custom Flex component in TagFilterSection. * refactor(components): replace antd Flex with custom Layout components Consolidate Flex component usage across multiple files by replacing antd's Flex with custom Layout components (Flex, ColFlex, RowFlex) for better maintainability and consistency * refactor(components): migrate antd Flex tu custom Flex * refactor(components): update layout component usage for consistency replace RowFlex with ColFlex where appropriate and align prop names * refactor(tests): rename HStack to RowFlex in test components Update test snapshots and mock components to reflect the component name change from HStack to RowFlex Remove unused data-vertical attribute from preview container * refactor(Layout): pass through props and merge styles in Box and Flex components Improve component flexibility by allowing additional props to pass through and properly merging style objects in both Box and Flex components * refactor(Layout): make Flex component props optional with undefined defaults * test: update TagFilterSection snapshot to include wrap style * perf(Layout): optimize Box component style calculation with useMemo * docs: fix typo in Layout component comment * refactor(Layout): update BoxProps to use CSSProperties types Standardize prop types by using CSSProperties for style-related props to improve type safety and consistency with React's style system * feat(Layout): add wrap prop to Flex component * style(TagFilterSection): update snapshot styling to use flex-wrap property * refactor(Layout): simplify layout components by using Tailwind CSS classes Remove custom style calculations and props in favor of Tailwind utility classes * refactor: replace inline styles with Tailwind CSS classes for consistent styling style: update spacing and alignment utilities across components * refactor(tests): update test snapshots to use tailwind classes Replace inline styles with tailwind classes in test snapshots and update test assertions to match. This improves consistency with the codebase's styling approach. * style: adjust spacing and gaps in UI components for consistency * style: replace inline styles with tailwind classes for consistency Refactor various components to use tailwind classes instead of inline styles to maintain consistency and improve readability. Changes include: - Replacing style attributes with tailwind classes for spacing, margins, and padding - Standardizing gap sizes across components - Using tailwind for width, height, and other layout properties - Updating test files to match new class names * style(settings): replace inline styles with tailwind classes for consistency Refactor settings components to use tailwind gap utility instead of inline styles for better maintainability and consistency across the codebase * refactor(styles): replace inline styles with tailwind classes for consistency * feat(eslint): add rule to restrict antd Flex imports Enforce using custom Layout components instead of antd's Flex by adding a restricted import rule * refactor: migrate flex layout from antd props to tailwind classes - Replace antd Flex component props with tailwind classes for consistency - Update gap and alignment values to use tailwind's spacing scale - Remove unused antd Flex imports to clean up dependencies * style(settings): adjust spacing and layout in various settings components - Add gap spacing between elements in multiple settings components - Remove redundant flex class in some components - Standardize gap sizes across related components * refactor(ui): replace inline styles with tailwind classes for consistency Replace various inline style attributes with equivalent tailwind classes across multiple components to maintain consistent styling approach. Changes include margin, padding, width, and flex properties. - Convert style attributes to tailwind classes - Standardize spacing values using tailwind's spacing scale - Improve maintainability by using utility classes * style(ui): adjust spacing in model list group header * style(css): wrap base styles in @layer for better organization * style(css): fix indentation and nesting in global styles * style(settings): adjust spacing in model list and convert subtitle to cn Refactor SettingSubtitle to use cn utility for better className handling Add gap spacing between model list items for improved layout * style(css): move some styles from base layer to outer in index.css * refactor(components): replace HStack with RowFlex for consistency Update layout components to use RowFlex instead of HStack to maintain consistent naming * style: reorder imports in useAppInit and BaseApiClient files * fix(MinAppTabsPool): wrong import path * refactor: update style file extensions from scss to css Update file extensions and comments to reflect the change from SCSS to CSS stylesheets * feat(layout): add Flex component and its variants Introduce new Flex component with Box, RowFlex, SpaceBetweenRowFlex, ColFlex and Center variants to provide reusable layout components * refactor: migrate layout components to @cherrystudio/ui package This commit updates all imports of layout components (Box, Flex, RowFlex, ColFlex, etc.) from '@renderer/components/Layout' to '@cherrystudio/ui' across the codebase. The change also includes updating related test files and eslint configuration to reflect this migration. This refactoring aims to centralize layout components in a shared package for better maintainability and consistency. * docs(eslint): update comment and restricted imports rule Update comment to clarify the purpose of the rule and add a TODO note for future migration * docs(ui): update migration status for layout components Mark Layout/* components as migrated and refactored in both Chinese and English documentation * docs: update migration status for Layout components --- eslint.config.mjs | 20 +++ packages/ui/MIGRATION_STATUS.md | 130 +++++++------- packages/ui/MIGRATION_STATUS_EN.md | 130 +++++++------- packages/ui/src/components/index.ts | 1 + .../ui/src/components/layout/Flex/index.tsx | 63 +++++++ src/renderer/src/assets/styles/index.css | 15 +- .../components/CodeBlockView/StatusBar.tsx | 2 +- .../__tests__/CodeToolbar.test.tsx | 6 +- .../src/components/CodeToolbar/toolbar.tsx | 4 +- .../HealthStatusIndicator/indicator.tsx | 5 +- .../HealthStatusIndicator/useHealthStatus.tsx | 4 +- src/renderer/src/components/Layout/index.ts | 159 ------------------ .../src/components/NutstorePathSelector.tsx | 15 +- .../components/Popups/AddAssistantPopup.tsx | 10 +- .../Popups/ApiKeyListPopup/item.tsx | 9 +- .../Popups/ApiKeyListPopup/list.tsx | 5 +- .../src/components/Popups/PromptPopup.tsx | 4 +- .../Popups/SaveToKnowledgePopup.tsx | 12 +- .../SelectModelPopup/TagFilterSection.tsx | 4 +- .../TagFilterSection.test.tsx.snap | 110 ++++++------ .../Popups/SelectModelPopup/searchbar.tsx | 6 +- .../src/components/Popups/TemplatePopup.tsx | 4 +- .../src/components/Popups/UserPopup.tsx | 12 +- .../components/Preview/ImagePreviewLayout.tsx | 2 +- .../ImagePreviewLayout.test.tsx.snap | 1 - src/renderer/src/components/Preview/styles.ts | 2 +- .../src/components/QuickPanel/view.tsx | 14 +- .../RichEditor/components/ImageUploader.tsx | 23 +-- .../RichEditor/components/LinkEditor.tsx | 7 +- .../RichEditor/components/MathInputDialog.tsx | 5 +- src/renderer/src/components/TopView/index.tsx | 6 +- src/renderer/src/pages/agents/AgentsPage.tsx | 18 +- .../agents/components/ImportAgentPopup.tsx | 5 +- .../agents/components/ManageAgentsPopup.tsx | 8 +- src/renderer/src/pages/files/FileItem.tsx | 6 +- src/renderer/src/pages/files/FilesPage.tsx | 7 +- .../src/pages/history/HistoryPage.tsx | 6 +- .../history/components/SearchMessage.tsx | 6 +- .../history/components/TopicMessages.tsx | 6 +- .../history/components/TopicsHistory.tsx | 6 +- src/renderer/src/pages/home/Chat.tsx | 13 +- src/renderer/src/pages/home/ChatNavbar.tsx | 10 +- .../pages/home/Inputbar/AttachmentPreview.tsx | 7 +- .../src/pages/home/Inputbar/TokenCount.tsx | 30 ++-- .../home/Messages/Blocks/MainTextBlock.tsx | 4 +- .../Blocks/__tests__/MainTextBlock.test.tsx | 11 +- .../pages/home/Messages/MessageContent.tsx | 4 +- .../home/Messages/MessageGroupMenuBar.tsx | 6 +- .../home/Messages/MessageGroupModelList.tsx | 4 +- .../src/pages/home/Messages/MessageHeader.tsx | 6 +- .../home/Messages/Tools/MessageMcpTool.tsx | 4 +- src/renderer/src/pages/home/Navbar.tsx | 10 +- .../src/pages/home/Tabs/SettingsTab.tsx | 6 +- .../Tabs/components/AssistantTagsPopup.tsx | 4 +- .../src/pages/knowledge/KnowledgeContent.tsx | 10 +- .../__tests__/KnowledgeBaseFormModal.test.tsx | 4 +- .../KnowledgeBaseFormModal.test.tsx.snap | 2 +- .../components/EditKnowledgeBasePopup.tsx | 6 +- .../components/KnowledgeSearchPopup.tsx | 6 +- .../KnowledgeBaseFormModal.tsx | 6 +- .../src/pages/memory/settings-modal.tsx | 5 +- src/renderer/src/pages/notes/HeaderNavbar.tsx | 6 +- src/renderer/src/pages/notes/NotesEditor.tsx | 12 +- .../src/pages/paintings/AihubmixPage.tsx | 6 +- .../src/pages/paintings/DmxapiPage.tsx | 18 +- .../src/pages/paintings/SiliconPage.tsx | 10 +- .../src/pages/paintings/ZhipuPage.tsx | 6 +- .../src/pages/settings/AboutSettings.tsx | 6 +- .../AssistantKnowledgeBaseSettings.tsx | 6 +- .../AssistantMCPSettings.tsx | 2 +- .../AssistantMemorySettings.tsx | 2 +- .../AssistantModelSettings.tsx | 26 +-- .../AssistantPromptSettings.tsx | 20 +-- .../AssistantRegularPromptsSettings.tsx | 5 +- .../settings/AssistantSettings/index.tsx | 6 +- .../AgentsSubscribeUrlSettings.tsx | 8 +- .../settings/DataSettings/DataSettings.tsx | 30 ++-- .../settings/DataSettings/JoplinSettings.tsx | 12 +- .../DataSettings/LocalBackupSettings.tsx | 14 +- .../DataSettings/MarkdownExportSettings.tsx | 6 +- .../settings/DataSettings/NotionSettings.tsx | 16 +- .../DataSettings/NutstoreSettings.tsx | 18 +- .../DataSettings/ObsidianSettings.tsx | 6 +- .../settings/DataSettings/S3Settings.tsx | 10 +- .../settings/DataSettings/SiyuanSettings.tsx | 21 +-- .../settings/DataSettings/WebDavSettings.tsx | 10 +- .../settings/DataSettings/YuqueSettings.tsx | 11 +- .../DisplaySettings/DisplaySettings.tsx | 10 +- .../OcrProviderSettings.tsx | 5 +- .../DocProcessSettings/OcrSystemSettings.tsx | 5 +- .../OcrTesseractSettings.tsx | 5 +- .../PreprocessProviderSettings.tsx | 7 +- .../src/pages/settings/GeneralSettings.tsx | 15 +- .../settings/MCPSettings/InstallNpxUv.tsx | 10 +- .../pages/settings/MCPSettings/McpPrompt.tsx | 15 +- .../settings/MCPSettings/McpResource.tsx | 9 +- .../settings/MCPSettings/McpSettings.tsx | 9 +- .../MCPSettings/McpSettingsNavbar.tsx | 6 +- .../pages/settings/MCPSettings/McpTool.tsx | 21 +-- .../pages/settings/MCPSettings/NpxSearch.tsx | 11 +- .../MemorySettings/MemorySettings.tsx | 23 +-- .../settings/MemorySettings/UserSelector.tsx | 6 +- .../DefaultAssistantSettings.tsx | 23 +-- .../settings/ModelSettings/ModelSettings.tsx | 26 +-- .../ModelSettings/QuickModelPopup.tsx | 14 +- .../ProviderSettings/AddProviderPopup.tsx | 8 +- .../ApiOptionsSettings/ApiOptionsSettings.tsx | 16 +- .../ProviderSettings/AwsBedrockSettings.tsx | 6 +- .../EditModelPopup/ModelEditContent.tsx | 11 +- .../EditModelPopup/ModelTypeSelector.tsx | 5 +- .../ModelList/AddModelPopup.tsx | 9 +- .../ModelList/HealthCheckPopup.tsx | 31 ++-- .../ModelList/ManageModelsList.tsx | 9 +- .../ModelList/ManageModelsPopup.tsx | 9 +- .../ProviderSettings/ModelList/ModelList.tsx | 31 ++-- .../ModelList/ModelListGroup.tsx | 5 +- .../ModelList/ModelListItem.tsx | 14 +- .../ModelList/NewApiAddModelPopup.tsx | 9 +- .../ModelList/NewApiBatchAddModelPopup.tsx | 9 +- .../ProviderSettings/ProviderOAuth.tsx | 6 +- .../ProviderSettings/ProviderSetting.tsx | 11 +- .../ProviderSettings/UrlSchemaInfoPopup.tsx | 5 +- .../ProviderSettings/VertexAISettings.tsx | 6 +- .../pages/settings/QuickAssistantSettings.tsx | 22 +-- .../pages/settings/QuickPhraseSettings.tsx | 5 +- .../src/pages/settings/ShortcutSettings.tsx | 18 +- .../CustomLanguageSettings.tsx | 6 +- .../TranslatePromptSettings.tsx | 6 +- .../WebSearchSettings/AddSubscribePopup.tsx | 7 +- .../WebSearchProviderSetting.tsx | 12 +- src/renderer/src/pages/settings/index.tsx | 20 ++- .../src/pages/translate/TranslateHistory.tsx | 23 +-- .../src/pages/translate/TranslatePage.tsx | 5 +- .../src/pages/translate/TranslateSettings.tsx | 33 ++-- src/renderer/src/trace/pages/SpanDetail.tsx | 4 +- src/renderer/src/utils/style.ts | 2 +- 136 files changed, 924 insertions(+), 968 deletions(-) create mode 100644 packages/ui/src/components/layout/Flex/index.tsx delete mode 100644 src/renderer/src/components/Layout/index.ts diff --git a/eslint.config.mjs b/eslint.config.mjs index 8eda2e6fa8..19b4efcd31 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -110,6 +110,26 @@ export default defineConfig([ 'i18n/no-template-in-t': 'warn' } }, + { + // Component Rules - prevent importing antd components when migration completed + files: ['src/**/*.{ts,tsx,js,jsx}'], + rules: { + 'no-restricted-imports': [ + 'error', + { + paths: [ + { + name: 'antd', + // TODO: migrate message again + importNames: ['Flex'], + message: + '❌ Do not import Flex from antd. Use our custom Layout components instead: import { Flex } from "@cherrystudio/ui"' + } + ] + } + ] + } + }, { ignores: [ 'node_modules/**', diff --git a/packages/ui/MIGRATION_STATUS.md b/packages/ui/MIGRATION_STATUS.md index 59c9ed0835..4206242b91 100644 --- a/packages/ui/MIGRATION_STATUS.md +++ b/packages/ui/MIGRATION_STATUS.md @@ -55,71 +55,71 @@ function MyComponent() { ## 组件状态表 -| Category | Component Name | Migration Status | Refactoring Status | Description | -|----------|----------------|------------------|--------------------|-------------| -| **base** | | | | 基础组件 | -| | CopyButton | ✅ | ✅ | 复制按钮 | -| | CustomTag | ✅ | ✅ | 自定义标签 | -| | DividerWithText | ✅ | ✅ | 带文本的分隔线 | -| | EmojiIcon | ✅ | ✅ | 表情图标 | -| | ErrorBoundary | ✅ | ✅ | 错误边界 (通过 props 解耦) | -| | StatusTag | ✅ | ✅ | 统一状态标签(合并了 ErrorTag、SuccessTag、WarnTag、InfoTag)| -| | IndicatorLight | ✅ | ✅ | 指示灯 | -| | Spinner | ✅ | ✅ | 加载动画 | -| | TextBadge | ✅ | ✅ | 文本徽标 | -| | CustomCollapse | ✅ | ✅ | 自定义折叠面板 | -| **display** | | | | 显示组件 | -| | Ellipsis | ✅ | ✅ | 文本省略 | -| | ExpandableText | ✅ | ✅ | 可展开文本 | -| | ThinkingEffect | ✅ | ✅ | 思考效果动画 | -| | EmojiAvatar | ✅ | ✅ | 表情头像 | -| | ListItem | ✅ | ✅ | 列表项 | -| | MaxContextCount | ✅ | ✅ | 最大上下文数显示 | -| | ProviderAvatar | ✅ | ✅ | 提供者头像 | -| | CodeViewer | ❌ | ❌ | 代码查看器 (外部依赖) | -| | OGCard | ❌ | ❌ | OG 卡片 | -| | MarkdownShadowDOMRenderer | ❌ | ❌ | Markdown 渲染器 | -| | Preview/* | ❌ | ❌ | 预览组件 | -| **layout** | | | | 布局组件 | -| | HorizontalScrollContainer | ✅ | ❌ | 水平滚动容器 | -| | Scrollbar | ✅ | ❌ | 滚动条 | -| | Layout/* | ❌ | ❌ | 布局组件 | -| | Tab/* | ❌ | ❌ | 标签页 (Redux 依赖) | -| | TopView | ❌ | ❌ | 顶部视图 (window.api 依赖) | -| **icons** | | | | 图标组件 | -| | Icon | ✅ | ✅ | 图标工厂函数和预定义图标(合并了 CopyIcon、DeleteIcon、EditIcon、RefreshIcon、ResetIcon、ToolIcon、VisionIcon、WebSearchIcon、WrapIcon、UnWrapIcon、OcrIcon)| -| | FileIcons | ✅ | ❌ | 文件图标 (FileSvgIcon、FilePngIcon) | -| | ReasoningIcon | ✅ | ❌ | 推理图标 | -| | SvgSpinners180Ring | ✅ | ❌ | 旋转加载图标 | -| | ToolsCallingIcon | ✅ | ❌ | 工具调用图标 | -| **interactive** | | | | 交互组件 | -| | InfoTooltip | ✅ | ❌ | 信息提示 | -| | HelpTooltip | ✅ | ❌ | 帮助提示 | -| | WarnTooltip | ✅ | ❌ | 警告提示 | -| | EditableNumber | ✅ | ❌ | 可编辑数字 | -| | InfoPopover | ✅ | ❌ | 信息弹出框 | -| | CollapsibleSearchBar | ✅ | ❌ | 可折叠搜索栏 | -| | ImageToolButton | ✅ | ❌ | 图片工具按钮 | -| | DraggableList | ✅ | ❌ | 可拖拽列表 | -| | CodeEditor | ✅ | ❌ | 代码编辑器 | -| | EmojiPicker | ❌ | ❌ | 表情选择器 (useTheme 依赖) | -| | Selector | ✅ | ❌ | 选择器 (i18n 依赖) | -| | ModelSelector | ❌ | ❌ | 模型选择器 (Redux 依赖) | -| | LanguageSelect | ❌ | ❌ | 语言选择 | -| | TranslateButton | ❌ | ❌ | 翻译按钮 (window.api 依赖) | -| **composite** | | | | 复合组件 | -| | - | - | - | 暂无复合组件 | -| **未分类** | | | | 需要分类的组件 | -| | Popups/* (16+ 文件) | ❌ | ❌ | 弹窗组件 (业务耦合) | -| | RichEditor/* (30+ 文件) | ❌ | ❌ | 富文本编辑器 | -| | MarkdownEditor/* | ❌ | ❌ | Markdown 编辑器 | -| | MinApp/* | ❌ | ❌ | 迷你应用 (Redux 依赖) | -| | Avatar/* | ❌ | ❌ | 头像组件 | -| | ActionTools/* | ❌ | ❌ | 操作工具 | -| | CodeBlockView/* | ❌ | ❌ | 代码块视图 (window.api 依赖) | -| | ContextMenu | ❌ | ❌ | 右键菜单 (Electron API) | -| | WindowControls | ❌ | ❌ | 窗口控制 (Electron API) | -| | ErrorBoundary | ❌ | ❌ | 错误边界 (window.api 依赖) | +| Category | Component Name | Migration Status | Refactoring Status | Description | +| --------------- | ------------------------- | ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **base** | | | | 基础组件 | +| | CopyButton | ✅ | ✅ | 复制按钮 | +| | CustomTag | ✅ | ✅ | 自定义标签 | +| | DividerWithText | ✅ | ✅ | 带文本的分隔线 | +| | EmojiIcon | ✅ | ✅ | 表情图标 | +| | ErrorBoundary | ✅ | ✅ | 错误边界 (通过 props 解耦) | +| | StatusTag | ✅ | ✅ | 统一状态标签(合并了 ErrorTag、SuccessTag、WarnTag、InfoTag) | +| | IndicatorLight | ✅ | ✅ | 指示灯 | +| | Spinner | ✅ | ✅ | 加载动画 | +| | TextBadge | ✅ | ✅ | 文本徽标 | +| | CustomCollapse | ✅ | ✅ | 自定义折叠面板 | +| **display** | | | | 显示组件 | +| | Ellipsis | ✅ | ✅ | 文本省略 | +| | ExpandableText | ✅ | ✅ | 可展开文本 | +| | ThinkingEffect | ✅ | ✅ | 思考效果动画 | +| | EmojiAvatar | ✅ | ✅ | 表情头像 | +| | ListItem | ✅ | ✅ | 列表项 | +| | MaxContextCount | ✅ | ✅ | 最大上下文数显示 | +| | ProviderAvatar | ✅ | ✅ | 提供者头像 | +| | CodeViewer | ❌ | ❌ | 代码查看器 (外部依赖) | +| | OGCard | ❌ | ❌ | OG 卡片 | +| | MarkdownShadowDOMRenderer | ❌ | ❌ | Markdown 渲染器 | +| | Preview/* | ❌ | ❌ | 预览组件 | +| **layout** | | | | 布局组件 | +| | HorizontalScrollContainer | ✅ | ❌ | 水平滚动容器 | +| | Scrollbar | ✅ | ❌ | 滚动条 | +| | Layout/* | ✅ | ✅ | 布局组件 | +| | Tab/* | ❌ | ❌ | 标签页 (Redux 依赖) | +| | TopView | ❌ | ❌ | 顶部视图 (window.api 依赖) | +| **icons** | | | | 图标组件 | +| | Icon | ✅ | ✅ | 图标工厂函数和预定义图标(合并了 CopyIcon、DeleteIcon、EditIcon、RefreshIcon、ResetIcon、ToolIcon、VisionIcon、WebSearchIcon、WrapIcon、UnWrapIcon、OcrIcon) | +| | FileIcons | ✅ | ❌ | 文件图标 (FileSvgIcon、FilePngIcon) | +| | ReasoningIcon | ✅ | ❌ | 推理图标 | +| | SvgSpinners180Ring | ✅ | ❌ | 旋转加载图标 | +| | ToolsCallingIcon | ✅ | ❌ | 工具调用图标 | +| **interactive** | | | | 交互组件 | +| | InfoTooltip | ✅ | ❌ | 信息提示 | +| | HelpTooltip | ✅ | ❌ | 帮助提示 | +| | WarnTooltip | ✅ | ❌ | 警告提示 | +| | EditableNumber | ✅ | ❌ | 可编辑数字 | +| | InfoPopover | ✅ | ❌ | 信息弹出框 | +| | CollapsibleSearchBar | ✅ | ❌ | 可折叠搜索栏 | +| | ImageToolButton | ✅ | ❌ | 图片工具按钮 | +| | DraggableList | ✅ | ❌ | 可拖拽列表 | +| | CodeEditor | ✅ | ❌ | 代码编辑器 | +| | EmojiPicker | ❌ | ❌ | 表情选择器 (useTheme 依赖) | +| | Selector | ✅ | ❌ | 选择器 (i18n 依赖) | +| | ModelSelector | ❌ | ❌ | 模型选择器 (Redux 依赖) | +| | LanguageSelect | ❌ | ❌ | 语言选择 | +| | TranslateButton | ❌ | ❌ | 翻译按钮 (window.api 依赖) | +| **composite** | | | | 复合组件 | +| | - | - | - | 暂无复合组件 | +| **未分类** | | | | 需要分类的组件 | +| | Popups/* (16+ 文件) | ❌ | ❌ | 弹窗组件 (业务耦合) | +| | RichEditor/* (30+ 文件) | ❌ | ❌ | 富文本编辑器 | +| | MarkdownEditor/* | ❌ | ❌ | Markdown 编辑器 | +| | MinApp/* | ❌ | ❌ | 迷你应用 (Redux 依赖) | +| | Avatar/* | ❌ | ❌ | 头像组件 | +| | ActionTools/* | ❌ | ❌ | 操作工具 | +| | CodeBlockView/* | ❌ | ❌ | 代码块视图 (window.api 依赖) | +| | ContextMenu | ❌ | ❌ | 右键菜单 (Electron API) | +| | WindowControls | ❌ | ❌ | 窗口控制 (Electron API) | +| | ErrorBoundary | ❌ | ❌ | 错误边界 (window.api 依赖) | ## 迁移步骤 diff --git a/packages/ui/MIGRATION_STATUS_EN.md b/packages/ui/MIGRATION_STATUS_EN.md index 4fe4471173..8c62e36bc7 100644 --- a/packages/ui/MIGRATION_STATUS_EN.md +++ b/packages/ui/MIGRATION_STATUS_EN.md @@ -54,71 +54,71 @@ When submitting PRs, please place components in the correct directory based on t ## Component Status Table -| Category | Component Name | Migration Status | Refactoring Status | Description | -|----------|----------------|------------------|--------------------|-------------| -| **base** | | | | Base components | -| | CopyButton | ✅ | ✅ | Copy button | -| | CustomTag | ✅ | ✅ | Custom tag | -| | DividerWithText | ✅ | ✅ | Divider with text | -| | EmojiIcon | ✅ | ✅ | Emoji icon | -| | ErrorBoundary | ✅ | ✅ | Error boundary (decoupled via props) | -| | StatusTag | ✅ | ✅ | Unified status tag (merged ErrorTag, SuccessTag, WarnTag, InfoTag) | -| | IndicatorLight | ✅ | ✅ | Indicator light | -| | Spinner | ✅ | ✅ | Loading spinner | -| | TextBadge | ✅ | ✅ | Text badge | -| | CustomCollapse | ✅ | ✅ | Custom collapse panel | -| **display** | | | | Display components | -| | Ellipsis | ✅ | ✅ | Text ellipsis | -| | ExpandableText | ✅ | ✅ | Expandable text | -| | ThinkingEffect | ✅ | ✅ | Thinking effect animation | -| | EmojiAvatar | ✅ | ✅ | Emoji avatar | -| | ListItem | ✅ | ✅ | List item | -| | MaxContextCount | ✅ | ✅ | Max context count display | -| | ProviderAvatar | ✅ | ✅ | Provider avatar | -| | CodeViewer | ❌ | ❌ | Code viewer (external deps) | -| | OGCard | ❌ | ❌ | OG card | -| | MarkdownShadowDOMRenderer | ❌ | ❌ | Markdown renderer | -| | Preview/* | ❌ | ❌ | Preview components | -| **layout** | | | | Layout components | -| | HorizontalScrollContainer | ✅ | ❌ | Horizontal scroll container | -| | Scrollbar | ✅ | ❌ | Scrollbar | -| | Layout/* | ❌ | ❌ | Layout components | -| | Tab/* | ❌ | ❌ | Tab (Redux dependency) | -| | TopView | ❌ | ❌ | Top view (window.api dependency) | -| **icons** | | | | Icon components | -| | Icon | ✅ | ✅ | Icon factory function and predefined icons (merged CopyIcon, DeleteIcon, EditIcon, RefreshIcon, ResetIcon, ToolIcon, VisionIcon, WebSearchIcon, WrapIcon, UnWrapIcon, OcrIcon) | -| | FileIcons | ✅ | ❌ | File icons (FileSvgIcon, FilePngIcon) | -| | ReasoningIcon | ✅ | ❌ | Reasoning icon | -| | SvgSpinners180Ring | ✅ | ❌ | Spinner loading icon | -| | ToolsCallingIcon | ✅ | ❌ | Tools calling icon | -| **interactive** | | | | Interactive components | -| | InfoTooltip | ✅ | ❌ | Info tooltip | -| | HelpTooltip | ✅ | ❌ | Help tooltip | -| | WarnTooltip | ✅ | ❌ | Warning tooltip | -| | EditableNumber | ✅ | ❌ | Editable number | -| | InfoPopover | ✅ | ❌ | Info popover | -| | CollapsibleSearchBar | ✅ | ❌ | Collapsible search bar | -| | ImageToolButton | ✅ | ❌ | Image tool button | -| | DraggableList | ✅ | ❌ | Draggable list | -| | CodeEditor | ✅ | ❌ | Code editor | -| | EmojiPicker | ❌ | ❌ | Emoji picker (useTheme dependency) | -| | Selector | ✅ | ❌ | Selector (i18n dependency) | -| | ModelSelector | ❌ | ❌ | Model selector (Redux dependency) | -| | LanguageSelect | ❌ | ❌ | Language select | -| | TranslateButton | ❌ | ❌ | Translate button (window.api dependency) | -| **composite** | | | | Composite components | -| | - | - | - | No composite components yet | -| **Uncategorized** | | | | Components needing categorization | -| | Popups/* (16+ files) | ❌ | ❌ | Popup components (business coupled) | -| | RichEditor/* (30+ files) | ❌ | ❌ | Rich text editor | -| | MarkdownEditor/* | ❌ | ❌ | Markdown editor | -| | MinApp/* | ❌ | ❌ | Mini app (Redux dependency) | -| | Avatar/* | ❌ | ❌ | Avatar components | -| | ActionTools/* | ❌ | ❌ | Action tools | -| | CodeBlockView/* | ❌ | ❌ | Code block view (window.api dependency) | -| | ContextMenu | ❌ | ❌ | Context menu (Electron API) | -| | WindowControls | ❌ | ❌ | Window controls (Electron API) | -| | ErrorBoundary | ❌ | ❌ | Error boundary (window.api dependency) | +| Category | Component Name | Migration Status | Refactoring Status | Description | +| ----------------- | ------------------------- | ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **base** | | | | Base components | +| | CopyButton | ✅ | ✅ | Copy button | +| | CustomTag | ✅ | ✅ | Custom tag | +| | DividerWithText | ✅ | ✅ | Divider with text | +| | EmojiIcon | ✅ | ✅ | Emoji icon | +| | ErrorBoundary | ✅ | ✅ | Error boundary (decoupled via props) | +| | StatusTag | ✅ | ✅ | Unified status tag (merged ErrorTag, SuccessTag, WarnTag, InfoTag) | +| | IndicatorLight | ✅ | ✅ | Indicator light | +| | Spinner | ✅ | ✅ | Loading spinner | +| | TextBadge | ✅ | ✅ | Text badge | +| | CustomCollapse | ✅ | ✅ | Custom collapse panel | +| **display** | | | | Display components | +| | Ellipsis | ✅ | ✅ | Text ellipsis | +| | ExpandableText | ✅ | ✅ | Expandable text | +| | ThinkingEffect | ✅ | ✅ | Thinking effect animation | +| | EmojiAvatar | ✅ | ✅ | Emoji avatar | +| | ListItem | ✅ | ✅ | List item | +| | MaxContextCount | ✅ | ✅ | Max context count display | +| | ProviderAvatar | ✅ | ✅ | Provider avatar | +| | CodeViewer | ❌ | ❌ | Code viewer (external deps) | +| | OGCard | ❌ | ❌ | OG card | +| | MarkdownShadowDOMRenderer | ❌ | ❌ | Markdown renderer | +| | Preview/* | ❌ | ❌ | Preview components | +| **layout** | | | | Layout components | +| | HorizontalScrollContainer | ✅ | ❌ | Horizontal scroll container | +| | Scrollbar | ✅ | ❌ | Scrollbar | +| | Layout/* | ✅ | ✅ | Layout components | +| | Tab/* | ❌ | ❌ | Tab (Redux dependency) | +| | TopView | ❌ | ❌ | Top view (window.api dependency) | +| **icons** | | | | Icon components | +| | Icon | ✅ | ✅ | Icon factory function and predefined icons (merged CopyIcon, DeleteIcon, EditIcon, RefreshIcon, ResetIcon, ToolIcon, VisionIcon, WebSearchIcon, WrapIcon, UnWrapIcon, OcrIcon) | +| | FileIcons | ✅ | ❌ | File icons (FileSvgIcon, FilePngIcon) | +| | ReasoningIcon | ✅ | ❌ | Reasoning icon | +| | SvgSpinners180Ring | ✅ | ❌ | Spinner loading icon | +| | ToolsCallingIcon | ✅ | ❌ | Tools calling icon | +| **interactive** | | | | Interactive components | +| | InfoTooltip | ✅ | ❌ | Info tooltip | +| | HelpTooltip | ✅ | ❌ | Help tooltip | +| | WarnTooltip | ✅ | ❌ | Warning tooltip | +| | EditableNumber | ✅ | ❌ | Editable number | +| | InfoPopover | ✅ | ❌ | Info popover | +| | CollapsibleSearchBar | ✅ | ❌ | Collapsible search bar | +| | ImageToolButton | ✅ | ❌ | Image tool button | +| | DraggableList | ✅ | ❌ | Draggable list | +| | CodeEditor | ✅ | ❌ | Code editor | +| | EmojiPicker | ❌ | ❌ | Emoji picker (useTheme dependency) | +| | Selector | ✅ | ❌ | Selector (i18n dependency) | +| | ModelSelector | ❌ | ❌ | Model selector (Redux dependency) | +| | LanguageSelect | ❌ | ❌ | Language select | +| | TranslateButton | ❌ | ❌ | Translate button (window.api dependency) | +| **composite** | | | | Composite components | +| | - | - | - | No composite components yet | +| **Uncategorized** | | | | Components needing categorization | +| | Popups/* (16+ files) | ❌ | ❌ | Popup components (business coupled) | +| | RichEditor/* (30+ files) | ❌ | ❌ | Rich text editor | +| | MarkdownEditor/* | ❌ | ❌ | Markdown editor | +| | MinApp/* | ❌ | ❌ | Mini app (Redux dependency) | +| | Avatar/* | ❌ | ❌ | Avatar components | +| | ActionTools/* | ❌ | ❌ | Action tools | +| | CodeBlockView/* | ❌ | ❌ | Code block view (window.api dependency) | +| | ContextMenu | ❌ | ❌ | Context menu (Electron API) | +| | WindowControls | ❌ | ❌ | Window controls (Electron API) | +| | ErrorBoundary | ❌ | ❌ | Error boundary (window.api dependency) | ## Migration Steps diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index ab1d3d40bd..c5f3727e34 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -22,6 +22,7 @@ export { ProviderAvatar } from './display/ProviderAvatar' export { default as ThinkingEffect } from './display/ThinkingEffect' // Layout Components +export { Box, Center, ColFlex, Flex, RowFlex, SpaceBetweenRowFlex } from './layout/Flex' export { default as HorizontalScrollContainer } from './layout/HorizontalScrollContainer' export { default as Scrollbar } from './layout/Scrollbar' diff --git a/packages/ui/src/components/layout/Flex/index.tsx b/packages/ui/src/components/layout/Flex/index.tsx new file mode 100644 index 0000000000..522a5574d7 --- /dev/null +++ b/packages/ui/src/components/layout/Flex/index.tsx @@ -0,0 +1,63 @@ +import React from 'react' + +import { cn } from '../../../utils' + +export interface BoxProps extends React.ComponentProps<'div'> {} + +export const Box = ({ children, className, ...props }: BoxProps & { children?: React.ReactNode }) => { + return ( +
+ {children} +
+ ) +} + +export interface FlexProps extends BoxProps {} + +export const Flex = ({ children, className, ...props }: FlexProps & { children?: React.ReactNode }) => { + return ( + + {children} + + ) +} + +export const RowFlex = ({ children, className, ...props }: FlexProps & { children?: React.ReactNode }) => { + return ( + + {children} + + ) +} + +export const SpaceBetweenRowFlex = ({ children, className, ...props }: FlexProps & { children?: React.ReactNode }) => { + return ( + + {children} + + ) +} +export const ColFlex = ({ children, className, ...props }: FlexProps & { children?: React.ReactNode }) => { + return ( + + {children} + + ) +} + +export const Center = ({ children, className, ...props }: FlexProps & { children?: React.ReactNode }) => { + return ( + + {children} + + ) +} + +export default { + Box, + Flex, + RowFlex, + SpaceBetweenRowFlex, + ColFlex, + Center +} diff --git a/src/renderer/src/assets/styles/index.css b/src/renderer/src/assets/styles/index.css index b344e60ae6..d48eb615d1 100644 --- a/src/renderer/src/assets/styles/index.css +++ b/src/renderer/src/assets/styles/index.css @@ -11,18 +11,19 @@ @import '../fonts/ubuntu/ubuntu.css'; @import '../fonts/country-flag-fonts/flag.css'; -*, -*::before, -*::after { - box-sizing: border-box; - /* margin: 0; */ - font-weight: normal; +@layer base { + *, + *::before, + *::after { + box-sizing: border-box; + /* margin: 0; */ + font-weight: normal; + } } *:focus { outline: none; } - * { -webkit-tap-highlight-color: transparent; } diff --git a/src/renderer/src/components/CodeBlockView/StatusBar.tsx b/src/renderer/src/components/CodeBlockView/StatusBar.tsx index 72589b9045..6824ba5e42 100644 --- a/src/renderer/src/components/CodeBlockView/StatusBar.tsx +++ b/src/renderer/src/components/CodeBlockView/StatusBar.tsx @@ -1,4 +1,4 @@ -import { Flex } from 'antd' +import { Flex } from '@cherrystudio/ui' import type { FC, ReactNode } from 'react' import { memo } from 'react' import styled from 'styled-components' diff --git a/src/renderer/src/components/CodeToolbar/__tests__/CodeToolbar.test.tsx b/src/renderer/src/components/CodeToolbar/__tests__/CodeToolbar.test.tsx index 4f75409c8a..681f9fd753 100644 --- a/src/renderer/src/components/CodeToolbar/__tests__/CodeToolbar.test.tsx +++ b/src/renderer/src/components/CodeToolbar/__tests__/CodeToolbar.test.tsx @@ -19,7 +19,7 @@ const mocks = vi.hoisted(() => ({ {children} )), - HStack: vi.fn(({ children, className }) => ( + RowFlex: vi.fn(({ children, className }) => (
{children}
@@ -43,8 +43,8 @@ vi.mock('antd', () => ({ Tooltip: mocks.Tooltip })) -vi.mock('@renderer/components/Layout', () => ({ - HStack: mocks.HStack +vi.mock('@cherrystudio/ui', () => ({ + RowFlex: mocks.RowFlex })) vi.mock('./styles', () => ({ diff --git a/src/renderer/src/components/CodeToolbar/toolbar.tsx b/src/renderer/src/components/CodeToolbar/toolbar.tsx index 7b78d8e536..a87cce5b19 100644 --- a/src/renderer/src/components/CodeToolbar/toolbar.tsx +++ b/src/renderer/src/components/CodeToolbar/toolbar.tsx @@ -1,5 +1,5 @@ +import { RowFlex } from '@cherrystudio/ui' import type { ActionTool } from '@renderer/components/ActionTools' -import { HStack } from '@renderer/components/Layout' import { Tooltip } from 'antd' import { EllipsisVertical } from 'lucide-react' import { memo, useMemo, useState } from 'react' @@ -61,7 +61,7 @@ const StickyWrapper = styled.div` z-index: 10; ` -const ToolbarWrapper = styled(HStack)` +const ToolbarWrapper = styled(RowFlex)` position: absolute; align-items: center; bottom: 0.3rem; diff --git a/src/renderer/src/components/HealthStatusIndicator/indicator.tsx b/src/renderer/src/components/HealthStatusIndicator/indicator.tsx index 2807549e28..9b65d58f29 100644 --- a/src/renderer/src/components/HealthStatusIndicator/indicator.tsx +++ b/src/renderer/src/components/HealthStatusIndicator/indicator.tsx @@ -1,5 +1,6 @@ import { CheckCircleFilled, CloseCircleFilled, ExclamationCircleFilled, LoadingOutlined } from '@ant-design/icons' -import { Flex, Tooltip, Typography } from 'antd' +import { Flex } from '@cherrystudio/ui' +import { Tooltip, Typography } from 'antd' import React, { memo } from 'react' import styled from 'styled-components' @@ -48,7 +49,7 @@ const HealthStatusIndicator: React.FC = ({ } return ( - + {latencyText && {latencyText}} {icon} diff --git a/src/renderer/src/components/HealthStatusIndicator/useHealthStatus.tsx b/src/renderer/src/components/HealthStatusIndicator/useHealthStatus.tsx index 1027324eeb..4ecedb18c9 100644 --- a/src/renderer/src/components/HealthStatusIndicator/useHealthStatus.tsx +++ b/src/renderer/src/components/HealthStatusIndicator/useHealthStatus.tsx @@ -1,5 +1,5 @@ +import { Flex } from '@cherrystudio/ui' import { HealthStatus } from '@renderer/types/healthCheck' -import { Flex } from 'antd' import React from 'react' import { useTranslation } from 'react-i18next' @@ -77,7 +77,7 @@ export const useHealthStatus = ({ results, showLatency = false }: UseHealthStatu return (
  • - + {statusText} {result.label} diff --git a/src/renderer/src/components/Layout/index.ts b/src/renderer/src/components/Layout/index.ts deleted file mode 100644 index 6ebc5788c5..0000000000 --- a/src/renderer/src/components/Layout/index.ts +++ /dev/null @@ -1,159 +0,0 @@ -import styled from 'styled-components' - -interface ContainerProps { - padding?: string -} - -type PxValue = number | string - -export interface BoxProps { - width?: PxValue - height?: PxValue - w?: PxValue - h?: PxValue - color?: string - background?: string - flex?: string | number - position?: string - left?: PxValue - top?: PxValue - right?: PxValue - bottom?: PxValue - opacity?: string | number - borderRadius?: PxValue - border?: string - gap?: PxValue - mt?: PxValue - marginTop?: PxValue - mb?: PxValue - marginBottom?: PxValue - ml?: PxValue - marginLeft?: PxValue - mr?: PxValue - marginRight?: PxValue - m?: string - margin?: string - pt?: PxValue - paddingTop?: PxValue - pb?: PxValue - paddingBottom?: PxValue - pl?: PxValue - paddingLeft?: PxValue - pr?: PxValue - paddingRight?: PxValue - p?: string - padding?: string -} - -export interface StackProps extends BoxProps { - justifyContent?: 'center' | 'flex-start' | 'flex-end' | 'space-between' - alignItems?: 'center' | 'flex-start' | 'flex-end' | 'space-between' - flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse' -} - -export interface ButtonProps extends StackProps { - color?: string - isDisabled?: boolean - isLoading?: boolean - background?: string - border?: string - fontSize?: string -} - -const cssRegex = /(px|vw|vh|%|auto)$/g - -const getElementValue = (value?: PxValue) => { - if (!value) { - return value - } - - if (typeof value === 'number') { - return value + 'px' - } - - if (value.match(cssRegex)) { - return value - } - - return value + 'px' -} - -export const Box = styled.div` - width: ${(props) => (props.width || props.w ? getElementValue(props.width ?? props.w) : 'auto')}; - height: ${(props) => (props.height || props.h ? getElementValue(props.height || props.h) : 'auto')}; - color: ${(props) => props.color || 'default'}; - background: ${(props) => props.background || 'default'}; - flex: ${(props) => props.flex || 'none'}; - position: ${(props) => props.position || 'default'}; - left: ${(props) => getElementValue(props.left) || 'auto'}; - right: ${(props) => getElementValue(props.right) || 'auto'}; - bottom: ${(props) => getElementValue(props.bottom) || 'auto'}; - top: ${(props) => getElementValue(props.top) || 'auto'}; - gap: ${(p) => (p.gap ? getElementValue(p.gap) : 0)}; - opacity: ${(props) => props.opacity ?? 1}; - border-radius: ${(props) => getElementValue(props.borderRadius) || 0}; - box-sizing: border-box; - border: ${(props) => props?.border || 'none'}; - gap: ${(p) => (p.gap ? getElementValue(p.gap) : 0)}; - margin: ${(props) => (props.m || props.margin ? (props.m ?? props.margin) : 'none')}; - margin-top: ${(props) => (props.mt || props.marginTop ? getElementValue(props.mt || props.marginTop) : 'default')}; - margin-bottom: ${(props) => - props.mb || props.marginBottom ? getElementValue(props.mb ?? props.marginBottom) : 'default'}; - margin-left: ${(props) => (props.ml || props.marginLeft ? getElementValue(props.ml ?? props.marginLeft) : 'default')}; - margin-right: ${(props) => - props.mr || props.marginRight ? getElementValue(props.mr ?? props.marginRight) : 'default'}; - padding: ${(props) => (props.p || props.padding ? (props.p ?? props.padding) : 'none')}; - padding-top: ${(props) => (props.pt || props.paddingTop ? getElementValue(props.pt ?? props.paddingTop) : 'auto')}; - padding-bottom: ${(props) => - props.pb || props.paddingBottom ? getElementValue(props.pb ?? props.paddingBottom) : 'auto'}; - padding-left: ${(props) => (props.pl || props.paddingLeft ? getElementValue(props.pl ?? props.paddingLeft) : 'auto')}; - padding-right: ${(props) => - props.pr || props.paddingRight ? getElementValue(props.pr ?? props.paddingRight) : 'auto'}; -` - -export const Stack = styled(Box)` - display: flex; - justify-content: ${(props) => props.justifyContent ?? 'flex-start'}; - align-items: ${(props) => props.alignItems ?? 'flex-start'}; - flex-direction: ${(props) => props.flexDirection ?? 'row'}; -` - -export const Center = styled(Stack)` - justify-content: center; - align-items: center; -` - -export const HStack = styled(Stack)` - flex-direction: row; -` - -export const HSpaceBetweenStack = styled(HStack)` - justify-content: space-between; -` - -export const VStack = styled(Stack)` - flex-direction: column; -` - -export const BaseTypography = styled(Box)<{ - fontSize?: number - lineHeight?: string - fontWeigth?: number | string - color?: string - textAlign?: string -}>` - font-size: ${(props) => (props.fontSize ? getElementValue(props.fontSize) : '16px')}; - line-height: ${(props) => (props.lineHeight ? getElementValue(props.lineHeight) : 'normal')}; - font-weight: ${(props) => props.fontWeigth || 'normal'}; - color: ${(props) => props.color || '#fff'}; - text-align: ${(props) => props.textAlign || 'left'}; -` - -export const Container = styled.main` - display: flex; - flex-direction: column; - width: 100%; - box-sizing: border-box; - flex: 1; - padding: ${(p) => p.padding ?? '0 18px'}; -` diff --git a/src/renderer/src/components/NutstorePathSelector.tsx b/src/renderer/src/components/NutstorePathSelector.tsx index 6393bad4c1..531dc086bf 100644 --- a/src/renderer/src/components/NutstorePathSelector.tsx +++ b/src/renderer/src/components/NutstorePathSelector.tsx @@ -1,3 +1,4 @@ +import { RowFlex } from '@cherrystudio/ui' import { loggerService } from '@logger' import { FolderIcon as NutstoreFolderIcon } from '@renderer/components/Icons/NutstoreIcons' import { Button, Input } from 'antd' @@ -5,8 +6,6 @@ import { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' -import { HStack } from './Layout' - interface NewFolderProps { onConfirm: (name: string) => void onCancel: () => void @@ -215,7 +214,7 @@ export function NutstorePathSelector(props: Props) { ) } -const FooterContainer = styled(HStack)` +const FooterContainer = styled(RowFlex)` background: transparent; margin-top: 12px; padding: 0; @@ -233,21 +232,21 @@ interface FooterProps { export function NustorePathSelectorFooter(props: FooterProps) { const { t } = useTranslation() return ( - - + + - - + + - + ) } diff --git a/src/renderer/src/components/Popups/AddAssistantPopup.tsx b/src/renderer/src/components/Popups/AddAssistantPopup.tsx index e891b87818..0d39ff4197 100644 --- a/src/renderer/src/components/Popups/AddAssistantPopup.tsx +++ b/src/renderer/src/components/Popups/AddAssistantPopup.tsx @@ -1,3 +1,4 @@ +import { RowFlex } from '@cherrystudio/ui' import { TopView } from '@renderer/components/TopView' import { useAgents } from '@renderer/hooks/useAgents' import { useAssistants, useDefaultAssistant } from '@renderer/hooks/useAssistant' @@ -16,7 +17,6 @@ import { useTranslation } from 'react-i18next' import styled from 'styled-components' import EmojiIcon from '../EmojiIcon' -import { HStack } from '../Layout' import Scrollbar from '../Scrollbar' interface Props { @@ -174,7 +174,7 @@ const PopupContainer: React.FC = ({ resolve }) => { }} closeIcon={null} footer={null}> - + @@ -191,7 +191,7 @@ const PopupContainer: React.FC = ({ resolve }) => { variant="borderless" size="middle" /> - + {take(agents, 100).map((agent, index) => ( @@ -200,10 +200,10 @@ const PopupContainer: React.FC = ({ resolve }) => { onClick={() => onCreateAssistant(agent)} className={`agent-item ${agent.id === 'default' ? 'default' : ''} ${index === selectedIndex ? 'keyboard-selected' : ''}`} onMouseEnter={() => setSelectedIndex(index)}> - + {agent.name} - + {agent.id === 'default' && {t('agents.tag.system')}} {agent.type === 'agent' && {t('agents.tag.agent')}} {agent.id === 'new' && {t('agents.tag.new')}} diff --git a/src/renderer/src/components/Popups/ApiKeyListPopup/item.tsx b/src/renderer/src/components/Popups/ApiKeyListPopup/item.tsx index 3ddcc383cd..e85d8093e5 100644 --- a/src/renderer/src/components/Popups/ApiKeyListPopup/item.tsx +++ b/src/renderer/src/components/Popups/ApiKeyListPopup/item.tsx @@ -1,10 +1,11 @@ +import { Flex } from '@cherrystudio/ui' import { type HealthResult, HealthStatusIndicator } from '@renderer/components/HealthStatusIndicator' import { EditIcon } from '@renderer/components/Icons' import { StreamlineGoodHealthAndWellBeing } from '@renderer/components/Icons/SVGIcon' import type { ApiKeyWithStatus } from '@renderer/types/healthCheck' import { maskApiKey } from '@renderer/utils/api' import type { InputRef } from 'antd' -import { Button, Flex, Input, List, Popconfirm, Tooltip, Typography } from 'antd' +import { Button, Input, List, Popconfirm, Tooltip, Typography } from 'antd' import { Check, Minus, X } from 'lucide-react' import type { FC } from 'react' import { memo, useEffect, useRef, useState } from 'react' @@ -104,7 +105,7 @@ const ApiKeyItem: FC = ({ spellCheck={false} disabled={disabled} /> - + - - - - - - + + models.filter.by_tag + + + + + + + + + `; diff --git a/src/renderer/src/components/Popups/SelectModelPopup/searchbar.tsx b/src/renderer/src/components/Popups/SelectModelPopup/searchbar.tsx index 8f8b981704..93d216b553 100644 --- a/src/renderer/src/components/Popups/SelectModelPopup/searchbar.tsx +++ b/src/renderer/src/components/Popups/SelectModelPopup/searchbar.tsx @@ -1,4 +1,4 @@ -import { HStack } from '@renderer/components/Layout' +import { RowFlex } from '@cherrystudio/ui' import type { InputRef } from 'antd' import { Input } from 'antd' import { Search } from 'lucide-react' @@ -34,7 +34,7 @@ const SelectModelSearchBar: React.FC = ({ onSearch }) }, []) return ( - + @@ -59,7 +59,7 @@ const SelectModelSearchBar: React.FC = ({ onSearch }) } }} /> - + ) } diff --git a/src/renderer/src/components/Popups/TemplatePopup.tsx b/src/renderer/src/components/Popups/TemplatePopup.tsx index 67dc50febf..1c5b880e26 100644 --- a/src/renderer/src/components/Popups/TemplatePopup.tsx +++ b/src/renderer/src/components/Popups/TemplatePopup.tsx @@ -1,4 +1,4 @@ -import { Box } from '@renderer/components/Layout' +import { Box } from '@cherrystudio/ui' import { TopView } from '@renderer/components/TopView' import { Modal } from 'antd' import { useState } from 'react' @@ -37,7 +37,7 @@ const PopupContainer: React.FC = ({ title, resolve }) => { afterClose={onClose} transitionName="animation-move-down" centered> - Name + Name ) } diff --git a/src/renderer/src/components/Popups/UserPopup.tsx b/src/renderer/src/components/Popups/UserPopup.tsx index 210bd7b013..24c6eb47e7 100644 --- a/src/renderer/src/components/Popups/UserPopup.tsx +++ b/src/renderer/src/components/Popups/UserPopup.tsx @@ -1,3 +1,4 @@ +import { Center, ColFlex, RowFlex } from '@cherrystudio/ui' import { cacheService } from '@data/CacheService' import { usePreference } from '@data/hooks/usePreference' import DefaultAvatar from '@renderer/assets/images/avatar.png' @@ -11,7 +12,6 @@ import { useTranslation } from 'react-i18next' import styled from 'styled-components' import EmojiPicker from '../EmojiPicker' -import { Center, HStack, VStack } from '../Layout' import { TopView } from '../TopView' interface Props { @@ -128,8 +128,8 @@ const PopupContainer: React.FC = ({ resolve }) => { afterClose={onClose} transitionName="animation-move-down" centered> -
    - +
    + = ({ resolve }) => { )} - +
    - + = ({ resolve }) => { style={{ flex: 1, textAlign: 'center', width: '100%' }} maxLength={30} /> - + ) } diff --git a/src/renderer/src/components/Preview/ImagePreviewLayout.tsx b/src/renderer/src/components/Preview/ImagePreviewLayout.tsx index 2c1b7c4287..9b4c607ba0 100644 --- a/src/renderer/src/components/Preview/ImagePreviewLayout.tsx +++ b/src/renderer/src/components/Preview/ImagePreviewLayout.tsx @@ -48,7 +48,7 @@ const ImagePreviewLayout = ({ return ( }> - + {error && {error}} {children} {!error && enableToolbar && } diff --git a/src/renderer/src/components/Preview/__tests__/__snapshots__/ImagePreviewLayout.test.tsx.snap b/src/renderer/src/components/Preview/__tests__/__snapshots__/ImagePreviewLayout.test.tsx.snap index 13e847fc31..b0899aef12 100644 --- a/src/renderer/src/components/Preview/__tests__/__snapshots__/ImagePreviewLayout.test.tsx.snap +++ b/src/renderer/src/components/Preview/__tests__/__snapshots__/ImagePreviewLayout.test.tsx.snap @@ -7,7 +7,6 @@ exports[`ImagePreviewLayout > should match snapshot 1`] = ` >
    Test Content diff --git a/src/renderer/src/components/Preview/styles.ts b/src/renderer/src/components/Preview/styles.ts index 521b96e225..8fadd0eee5 100644 --- a/src/renderer/src/components/Preview/styles.ts +++ b/src/renderer/src/components/Preview/styles.ts @@ -1,4 +1,4 @@ -import { Flex } from 'antd' +import { Flex } from '@cherrystudio/ui' import { styled } from 'styled-components' export const PreviewError = styled.div` diff --git a/src/renderer/src/components/QuickPanel/view.tsx b/src/renderer/src/components/QuickPanel/view.tsx index 9426687ae5..fbb9414436 100644 --- a/src/renderer/src/components/QuickPanel/view.tsx +++ b/src/renderer/src/components/QuickPanel/view.tsx @@ -1,10 +1,10 @@ import { RightOutlined } from '@ant-design/icons' +import { Flex } from '@cherrystudio/ui' import { DynamicVirtualList, type DynamicVirtualListRef } from '@renderer/components/VirtualList' import { isMac } from '@renderer/config/constant' import { useTimer } from '@renderer/hooks/useTimer' import useUserTheme from '@renderer/hooks/useUserTheme' import { classNames } from '@renderer/utils' -import { Flex } from 'antd' import { t } from 'i18next' import { debounce } from 'lodash' import { Check } from 'lucide-react' @@ -608,13 +608,11 @@ export const QuickPanelView: React.FC = ({ setInputText }) => { ESC {t('settings.quickPanel.close')} - - ▲▼ {t('settings.quickPanel.select')} - + ▲▼ {t('settings.quickPanel.select')} {footerWidth >= 500 && ( <> - + {ASSISTIVE_KEY} @@ -622,7 +620,7 @@ export const QuickPanelView: React.FC = ({ setInputText }) => { {canForwardAndBackward && ( - + {ASSISTIVE_KEY} @@ -632,9 +630,7 @@ export const QuickPanelView: React.FC = ({ setInputText }) => { )} - - ↩︎ {t('settings.quickPanel.confirm')} - + ↩︎ {t('settings.quickPanel.confirm')} diff --git a/src/renderer/src/components/RichEditor/components/ImageUploader.tsx b/src/renderer/src/components/RichEditor/components/ImageUploader.tsx index 02a9b73885..e74607d73c 100644 --- a/src/renderer/src/components/RichEditor/components/ImageUploader.tsx +++ b/src/renderer/src/components/RichEditor/components/ImageUploader.tsx @@ -1,5 +1,6 @@ import { InboxOutlined, LinkOutlined, LoadingOutlined, UploadOutlined } from '@ant-design/icons' -import { Button, Flex, Input, message, Modal, Spin, Tabs, Upload } from 'antd' +import { Flex } from '@cherrystudio/ui' +import { Button, Input, message, Modal, Spin, Tabs, Upload } from 'antd' const { Dragger } = Upload import type { RcFile } from 'antd/es/upload' @@ -24,20 +25,20 @@ const TabContent = styled.div` const UrlInput = styled(Input)` .ant-input { - padding: 12px 16px - font-size: 14px - border-radius: 4px - border: 1px solid #dadce0 - transition: all 0.2s ease - background: #ffffff + padding: 12px 16px; + font-size: 14px; + border-radius: 4px; + border: 1px solid #dadce0; + transition: all 0.2s ease; + background: #ffffff; &:hover { - border-color: #4285f4 + border-color: #4285f4; } &:focus { - border-color: #4285f4 - box-shadow: 0 0 0 1px rgba(66, 133, 244, 0.3) + border-color: #4285f4; + box-shadow: 0 0 0 1px rgba(66, 133, 244, 0.3); } } ` @@ -164,7 +165,7 @@ export const ImageUploader: React.FC = ({ onImageSelect, vis ), children: ( - + = ({ setHref(e.target.value)} size="small" />
    - +
    {showRemove && ( )}
    - + diff --git a/src/renderer/src/components/RichEditor/components/MathInputDialog.tsx b/src/renderer/src/components/RichEditor/components/MathInputDialog.tsx index 93a864a3a6..9f6c402cfd 100644 --- a/src/renderer/src/components/RichEditor/components/MathInputDialog.tsx +++ b/src/renderer/src/components/RichEditor/components/MathInputDialog.tsx @@ -1,5 +1,6 @@ +import { Flex } from '@cherrystudio/ui' import { useTheme } from '@renderer/context/ThemeProvider' -import { Button, Flex, Input } from 'antd' +import { Button, Input } from 'antd' import React, { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -146,7 +147,7 @@ const MathInputDialog: React.FC = ({ onKeyDown={handleKeyDown} style={{ marginBottom: 12, fontFamily: 'monospace' }} /> - + diff --git a/src/renderer/src/components/TopView/index.tsx b/src/renderer/src/components/TopView/index.tsx index cd1dff1436..6823b6b9a7 100644 --- a/src/renderer/src/components/TopView/index.tsx +++ b/src/renderer/src/components/TopView/index.tsx @@ -1,4 +1,5 @@ // import { loggerService } from '@logger' +import { Box } from '@cherrystudio/ui' import TopViewMinappContainer from '@renderer/components/MinApp/TopViewMinappContainer' import { useAppInit } from '@renderer/hooks/useAppInit' import { useShortcuts } from '@renderer/hooks/useShortcuts' @@ -6,7 +7,6 @@ import { Modal } from 'antd' import type { PropsWithChildren } from 'react' import React, { useCallback, useEffect, useRef, useState } from 'react' -import { Box } from '../Layout' import { getToastUtilities } from './toast' let onPop = () => {} @@ -72,8 +72,8 @@ const TopViewContainer: React.FC = ({ children }) => { const FullScreenContainer: React.FC = useCallback(({ children }) => { return ( - - + + {children} ) diff --git a/src/renderer/src/pages/agents/AgentsPage.tsx b/src/renderer/src/pages/agents/AgentsPage.tsx index 9c2cf57132..ca73650b21 100644 --- a/src/renderer/src/pages/agents/AgentsPage.tsx +++ b/src/renderer/src/pages/agents/AgentsPage.tsx @@ -1,6 +1,6 @@ import { ImportOutlined, PlusOutlined } from '@ant-design/icons' +import { ColFlex, Flex, RowFlex } from '@cherrystudio/ui' import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' -import { HStack } from '@renderer/components/Layout' import ListItem from '@renderer/components/ListItem' import Scrollbar from '@renderer/components/Scrollbar' import CustomTag from '@renderer/components/Tags/CustomTag' @@ -9,7 +9,7 @@ import { useNavbarPosition } from '@renderer/hooks/useNavbar' import { createAssistantFromAgent } from '@renderer/services/AssistantService' import type { Agent } from '@renderer/types' import { uuid } from '@renderer/utils' -import { Button, Empty, Flex, Input } from 'antd' +import { Button, Empty, Input } from 'antd' import { omit } from 'lodash' import { Search } from 'lucide-react' import type { FC } from 'react' @@ -71,7 +71,7 @@ const AgentsPage: FC = () => { window.modal.confirm({ title: agent.name, content: ( - + {agent.description && {agent.description}} {agent.prompt && ( @@ -79,7 +79,7 @@ const AgentsPage: FC = () => { {agent.prompt} )} - + ), width: 600, icon: null, @@ -206,17 +206,17 @@ const AgentsPage: FC = () => { active={activeGroup === group && !search.trim()} key={group} title={ - - + + {getLocalizedGroupName(group)} { - + {agentGroups[group].length} - + } } @@ -246,7 +246,7 @@ const AgentsPage: FC = () => { } - + {isSearchExpanded ? ( = ({ resolve }) => { onCancel={onCancel} maskClosable={false} footer={ - + - + diff --git a/src/renderer/src/pages/history/components/TopicMessages.tsx b/src/renderer/src/pages/history/components/TopicMessages.tsx index 0fa06292fc..69cb365f94 100644 --- a/src/renderer/src/pages/history/components/TopicMessages.tsx +++ b/src/renderer/src/pages/history/components/TopicMessages.tsx @@ -1,6 +1,6 @@ import { MessageOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import { HStack } from '@renderer/components/Layout' import SearchPopup from '@renderer/components/Popups/SearchPopup' import { MessageEditingProvider } from '@renderer/context/MessageEditingContext' import { modelGenerating } from '@renderer/hooks/useModel' @@ -75,11 +75,11 @@ const TopicMessages: FC = ({ topic: _topic, ...props }) => { ))} {isEmpty && } {!isEmpty && ( - + - + )} diff --git a/src/renderer/src/pages/history/components/TopicsHistory.tsx b/src/renderer/src/pages/history/components/TopicsHistory.tsx index d307200ce5..d13cd70949 100644 --- a/src/renderer/src/pages/history/components/TopicsHistory.tsx +++ b/src/renderer/src/pages/history/components/TopicsHistory.tsx @@ -1,5 +1,5 @@ import { SearchOutlined } from '@ant-design/icons' -import { VStack } from '@renderer/components/Layout' +import { ColFlex } from '@cherrystudio/ui' import useScrollPosition from '@renderer/hooks/useScrollPosition' import { selectAllTopics } from '@renderer/store/assistants' import type { Topic } from '@renderer/types' @@ -38,12 +38,12 @@ const TopicsHistory: React.FC = ({ keywords, onClick, onSearch, ...props if (isEmpty(filteredTopics)) { return ( - + - + ) } diff --git a/src/renderer/src/pages/home/Chat.tsx b/src/renderer/src/pages/home/Chat.tsx index 18c3c08854..2d6997b624 100644 --- a/src/renderer/src/pages/home/Chat.tsx +++ b/src/renderer/src/pages/home/Chat.tsx @@ -1,8 +1,8 @@ +import { ColFlex, RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' import type { ContentSearchRef } from '@renderer/components/ContentSearch' import { ContentSearch } from '@renderer/components/ContentSearch' -import { HStack } from '@renderer/components/Layout' import MultiSelectActionPopup from '@renderer/components/Popups/MultiSelectionPopup' import PromptPopup from '@renderer/components/Popups/PromptPopup' import { QuickPanelProvider } from '@renderer/components/QuickPanel' @@ -15,7 +15,6 @@ import { useTimer } from '@renderer/hooks/useTimer' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import type { Assistant, Topic } from '@renderer/types' import { classNames } from '@renderer/utils' -import { Flex } from 'antd' import { debounce } from 'lodash' import { AnimatePresence, motion } from 'motion/react' import type { FC } from 'react' @@ -152,13 +151,11 @@ const Chat: FC = (props) => { position="left" /> )} - +
    = (props) => { )} - + ) } @@ -230,7 +227,7 @@ const Container = styled.div` } ` -const Main = styled(Flex)` +const Main = styled(ColFlex)` [navbar-position='left'] & { height: calc(100vh - var(--navbar-height)); } diff --git a/src/renderer/src/pages/home/ChatNavbar.tsx b/src/renderer/src/pages/home/ChatNavbar.tsx index 7545583d03..24173b9f6f 100644 --- a/src/renderer/src/pages/home/ChatNavbar.tsx +++ b/src/renderer/src/pages/home/ChatNavbar.tsx @@ -1,6 +1,6 @@ +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { NavbarHeader } from '@renderer/components/app/Navbar' -import { HStack } from '@renderer/components/Layout' import SearchPopup from '@renderer/components/Popups/SearchPopup' import { useAssistant } from '@renderer/hooks/useAssistant' import { modelGenerating } from '@renderer/hooks/useModel' @@ -66,7 +66,7 @@ const HeaderNavbar: FC = ({ activeAssistant, setActiveAssistant, activeTo return ( - + {showAssistants && ( @@ -95,8 +95,8 @@ const HeaderNavbar: FC = ({ activeAssistant, setActiveAssistant, activeTo )} - - + + @@ -122,7 +122,7 @@ const HeaderNavbar: FC = ({ activeAssistant, setActiveAssistant, activeTo )} - + ) } diff --git a/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx b/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx index 23787f4d0c..5aef4ba3c6 100644 --- a/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx +++ b/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx @@ -12,12 +12,13 @@ import { GlobalOutlined, LinkOutlined } from '@ant-design/icons' +import { ColFlex } from '@cherrystudio/ui' import CustomTag from '@renderer/components/Tags/CustomTag' import { useAttachment } from '@renderer/hooks/useAttachment' import FileManager from '@renderer/services/FileManager' import type { FileMetadata } from '@renderer/types' import { formatFileSize } from '@renderer/utils' -import { Flex, Image, Tooltip } from 'antd' +import { Image, Tooltip } from 'antd' import { isEmpty } from 'lodash' import type { FC } from 'react' import { useState } from 'react' @@ -101,7 +102,7 @@ export const FileNameRender: FC<{ file: FileMetadata }> = ({ file }) => { }} fresh title={ - + {isImage(file.ext) && ( = ({ file }) => { )} {fullName} {formatFileSize(file.size)} - + }> { diff --git a/src/renderer/src/pages/home/Inputbar/TokenCount.tsx b/src/renderer/src/pages/home/Inputbar/TokenCount.tsx index 3c209305f9..a358334d80 100644 --- a/src/renderer/src/pages/home/Inputbar/TokenCount.tsx +++ b/src/renderer/src/pages/home/Inputbar/TokenCount.tsx @@ -1,5 +1,5 @@ +import { ColFlex, RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import { HStack, VStack } from '@renderer/components/Layout' import MaxContextCount from '@renderer/components/MaxContextCount' import { Divider, Popover } from 'antd' import { ArrowUp, MenuIcon } from 'lucide-react' @@ -23,44 +23,44 @@ const TokenCount: FC = ({ estimateTokenCount, inputTokenCount, contextCou const PopoverContent = () => { return ( - - + + {t('chat.input.context_count.tip')} - + {contextCount.current} / - + - + - + {t('chat.input.estimated_tokens.tip')} {estimateTokenCount} - - + + ) } return ( - - + + {contextCount.current} / - + - + {inputTokenCount} / {estimateTokenCount} - - + + ) diff --git a/src/renderer/src/pages/home/Messages/Blocks/MainTextBlock.tsx b/src/renderer/src/pages/home/Messages/Blocks/MainTextBlock.tsx index 35bea65dd6..eff3a8d444 100644 --- a/src/renderer/src/pages/home/Messages/Blocks/MainTextBlock.tsx +++ b/src/renderer/src/pages/home/Messages/Blocks/MainTextBlock.tsx @@ -1,3 +1,4 @@ +import { Flex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { getModelUniqId } from '@renderer/services/ModelService' import type { RootState } from '@renderer/store' @@ -5,7 +6,6 @@ import { selectFormattedCitationsByBlockId } from '@renderer/store/messageBlock' import { type Model } from '@renderer/types' import type { MainTextMessageBlock, Message } from '@renderer/types/newMessage' import { determineCitationSource, withCitationTags } from '@renderer/utils/citation' -import { Flex } from 'antd' import React, { useCallback } from 'react' import { useSelector } from 'react-redux' import styled from 'styled-components' @@ -44,7 +44,7 @@ const MainTextBlock: React.FC = ({ block, citationBlockId, role, mentions <> {/* Render mentions associated with the message */} {mentions && mentions.length > 0 && ( - + {mentions.map((m) => ( {'@' + m.name} ))} diff --git a/src/renderer/src/pages/home/Messages/Blocks/__tests__/MainTextBlock.test.tsx b/src/renderer/src/pages/home/Messages/Blocks/__tests__/MainTextBlock.test.tsx index 1193cd8169..08d0463c33 100644 --- a/src/renderer/src/pages/home/Messages/Blocks/__tests__/MainTextBlock.test.tsx +++ b/src/renderer/src/pages/home/Messages/Blocks/__tests__/MainTextBlock.test.tsx @@ -262,12 +262,11 @@ describe('MainTextBlock', () => { const mentionElement = screen.getByText('@Test Model') expect(mentionElement).toHaveStyle({ color: 'var(--color-link)' }) - // Check container layout - const container = mentionElement.closest('[style*="gap"]') - expect(container).toHaveStyle({ - gap: '8px', - marginBottom: '10px' - }) + // Check container layout - now using Tailwind classes + const container = mentionElement.closest('.gap-2') + expect(container).toHaveClass('gap-2') + expect(container).toHaveClass('flex-wrap') + expect(container).toHaveClass('mb-2.5') }) }) diff --git a/src/renderer/src/pages/home/Messages/MessageContent.tsx b/src/renderer/src/pages/home/Messages/MessageContent.tsx index 420cd7d466..31cf9aa0ed 100644 --- a/src/renderer/src/pages/home/Messages/MessageContent.tsx +++ b/src/renderer/src/pages/home/Messages/MessageContent.tsx @@ -1,6 +1,6 @@ +import { Flex } from '@cherrystudio/ui' import { getModelUniqId } from '@renderer/services/ModelService' import type { Message } from '@renderer/types/newMessage' -import { Flex } from 'antd' import { isEmpty } from 'lodash' import React from 'react' import styled from 'styled-components' @@ -14,7 +14,7 @@ const MessageContent: React.FC = ({ message }) => { return ( <> {!isEmpty(message.mentions) && ( - + {message.mentions?.map((model) => ( {'@' + model.name} ))} diff --git a/src/renderer/src/pages/home/Messages/MessageGroupMenuBar.tsx b/src/renderer/src/pages/home/Messages/MessageGroupMenuBar.tsx index ded587c528..e93418715b 100644 --- a/src/renderer/src/pages/home/Messages/MessageGroupMenuBar.tsx +++ b/src/renderer/src/pages/home/Messages/MessageGroupMenuBar.tsx @@ -6,7 +6,7 @@ import { NumberOutlined, ReloadOutlined } from '@ant-design/icons' -import { HStack } from '@renderer/components/Layout' +import { RowFlex } from '@cherrystudio/ui' import { useAssistant } from '@renderer/hooks/useAssistant' import { useMessageOperations } from '@renderer/hooks/useMessageOperations' import type { Topic } from '@renderer/types' @@ -102,7 +102,7 @@ const MessageGroupMenuBar: FC = ({ return ( - + {(['fold', 'vertical', 'horizontal', 'grid'] as const).map((layout) => ( = ({ /> )} {multiModelMessageStyle === 'grid' && } - + {hasFailedMessages && (
    - + {/* 使用selected base导致修改设置后没有响应式更新 */} base && KnowledgeSearchPopup.show({ base: base })}> - + @@ -181,9 +181,9 @@ export const KnowledgeEmptyView = () => { return ( - + - + ) } diff --git a/src/renderer/src/pages/knowledge/__tests__/KnowledgeBaseFormModal.test.tsx b/src/renderer/src/pages/knowledge/__tests__/KnowledgeBaseFormModal.test.tsx index 4c9229cfcb..8219cba00b 100644 --- a/src/renderer/src/pages/knowledge/__tests__/KnowledgeBaseFormModal.test.tsx +++ b/src/renderer/src/pages/knowledge/__tests__/KnowledgeBaseFormModal.test.tsx @@ -12,8 +12,8 @@ const mocks = vi.hoisted(() => ({ })) // Mock HStack component -vi.mock('@renderer/components/Layout', () => ({ - HStack: ({ children, ...props }: any) => ( +vi.mock('@cherrystudio/ui', () => ({ + RowFlex: ({ children, ...props }: any) => (
    {children}
    diff --git a/src/renderer/src/pages/knowledge/__tests__/__snapshots__/KnowledgeBaseFormModal.test.tsx.snap b/src/renderer/src/pages/knowledge/__tests__/__snapshots__/KnowledgeBaseFormModal.test.tsx.snap index 3e6ec8336a..979ea42695 100644 --- a/src/renderer/src/pages/knowledge/__tests__/__snapshots__/KnowledgeBaseFormModal.test.tsx.snap +++ b/src/renderer/src/pages/knowledge/__tests__/__snapshots__/KnowledgeBaseFormModal.test.tsx.snap @@ -84,8 +84,8 @@ exports[`KnowledgeBaseFormModal > basic rendering > should match snapshot 1`] = data-testid="modal-body" >
    = ({ base: _base, resolve }) window.modal.confirm({ title: t('knowledge.migrate.confirm.title'), content: ( - + {t('knowledge.migrate.confirm.content')} {t('knowledge.embedding_model')}: {`${t('knowledge.migrate.source_model')}: ${base.model.name}`} @@ -80,7 +80,7 @@ const PopupContainer: React.FC = ({ base: _base, resolve }) style={{ paddingLeft: '1em' }}>{`${t('knowledge.migrate.target_dimensions')}: ${newBase.dimensions}`} - + ), okText: t('knowledge.migrate.confirm.ok'), centered: true, diff --git a/src/renderer/src/pages/knowledge/components/KnowledgeSearchPopup.tsx b/src/renderer/src/pages/knowledge/components/KnowledgeSearchPopup.tsx index a48b9b8225..81e7986a94 100644 --- a/src/renderer/src/pages/knowledge/components/KnowledgeSearchPopup.tsx +++ b/src/renderer/src/pages/knowledge/components/KnowledgeSearchPopup.tsx @@ -1,5 +1,5 @@ +import { RowFlex } from '@cherrystudio/ui' import { loggerService } from '@logger' -import { HStack } from '@renderer/components/Layout' import { TopView } from '@renderer/components/TopView' import { searchKnowledgeBase } from '@renderer/services/KnowledgeService' import type { FileMetadata, KnowledgeBase, KnowledgeSearchResult } from '@renderer/types' @@ -96,7 +96,7 @@ const PopupContainer: React.FC = ({ base, resolve }) => { padding: 0 } }}> - + = ({ base, resolve }) => { onChange={(e) => setSearchKeyword(e.target.value)} onPressEnter={() => handleSearch(searchKeyword)} /> - + diff --git a/src/renderer/src/pages/knowledge/components/KnowledgeSettings/KnowledgeBaseFormModal.tsx b/src/renderer/src/pages/knowledge/components/KnowledgeSettings/KnowledgeBaseFormModal.tsx index 6ea885da76..6643eef90a 100644 --- a/src/renderer/src/pages/knowledge/components/KnowledgeSettings/KnowledgeBaseFormModal.tsx +++ b/src/renderer/src/pages/knowledge/components/KnowledgeSettings/KnowledgeBaseFormModal.tsx @@ -1,4 +1,4 @@ -import { HStack } from '@renderer/components/Layout' +import { RowFlex } from '@cherrystudio/ui' import type { ModalProps } from 'antd' import { Menu, Modal } from 'antd' import React, { useState } from 'react' @@ -42,7 +42,7 @@ const KnowledgeBaseFormModal: React.FC = ({ panels, } }} {...rest}> - + = ({ panels, /> {activePanel} - + ) } diff --git a/src/renderer/src/pages/memory/settings-modal.tsx b/src/renderer/src/pages/memory/settings-modal.tsx index 996baebd1d..b07051cf65 100644 --- a/src/renderer/src/pages/memory/settings-modal.tsx +++ b/src/renderer/src/pages/memory/settings-modal.tsx @@ -1,3 +1,4 @@ +import { Flex } from '@cherrystudio/ui' import { loggerService } from '@logger' import AiProvider from '@renderer/aiCore' import InputEmbeddingDimension from '@renderer/components/InputEmbeddingDimension' @@ -9,7 +10,7 @@ import { useProviders } from '@renderer/hooks/useProvider' import { getModelUniqId } from '@renderer/services/ModelService' import { selectMemoryConfig, updateMemoryConfig } from '@renderer/store/memory' import type { Model } from '@renderer/types' -import { Flex, Form, Modal } from 'antd' +import { Form, Modal } from 'antd' import { t } from 'i18next' import type { FC } from 'react' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -167,7 +168,7 @@ const MemoriesSettingsModal: FC = ({ visible, onSubm return ( + {t('memory.embedding_dimensions')} diff --git a/src/renderer/src/pages/notes/HeaderNavbar.tsx b/src/renderer/src/pages/notes/HeaderNavbar.tsx index 0798d7ded9..242ca0cb27 100644 --- a/src/renderer/src/pages/notes/HeaderNavbar.tsx +++ b/src/renderer/src/pages/notes/HeaderNavbar.tsx @@ -1,7 +1,7 @@ +import { RowFlex } from '@cherrystudio/ui' import { BreadcrumbItem, Breadcrumbs } from '@heroui/react' import { loggerService } from '@logger' import { NavbarCenter, NavbarHeader, NavbarRight } from '@renderer/components/app/Navbar' -import { HStack } from '@renderer/components/Layout' import { useActiveNode } from '@renderer/hooks/useNotesQuery' import { useNotesSettings } from '@renderer/hooks/useNotesSettings' import { useShowWorkspace } from '@renderer/hooks/useShowWorkspace' @@ -161,7 +161,7 @@ const HeaderNavbar = ({ notesTree, getCurrentNoteContent, onToggleStar }) => { - + {showWorkspace && ( @@ -176,7 +176,7 @@ const HeaderNavbar = ({ notesTree, getCurrentNoteContent, onToggleStar }) => { )} - + diff --git a/src/renderer/src/pages/notes/NotesEditor.tsx b/src/renderer/src/pages/notes/NotesEditor.tsx index 60e098ada7..1cf4647894 100644 --- a/src/renderer/src/pages/notes/NotesEditor.tsx +++ b/src/renderer/src/pages/notes/NotesEditor.tsx @@ -1,5 +1,5 @@ -import { CodeEditor } from '@cherrystudio/ui' -import { HSpaceBetweenStack } from '@renderer/components/Layout' +import { SpaceBetweenRowFlex } from '@cherrystudio/ui' +import CodeEditor from '@renderer/components/CodeEditor' import RichEditor from '@renderer/components/RichEditor' import type { RichEditorRef } from '@renderer/components/RichEditor/types' import Selector from '@renderer/components/Selector' @@ -69,7 +69,7 @@ const NotesEditor: FC = memo( value={currentContent} language="markdown" onChange={onMarkdownChange} - height="100%" + className="h-full" expanded={false} style={{ height: '100%' @@ -88,14 +88,14 @@ const NotesEditor: FC = memo( showTableOfContents={settings.showTableOfContents} enableContentSearch className="notes-rich-editor" - isFullWidth={settings.isFullWidth} + isFullWidth fontFamily={settings.fontFamily} fontSize={settings.fontSize} /> )} - + {t('notes.characters')}: {tokenCount} @@ -117,7 +117,7 @@ const NotesEditor: FC = memo( ]} />
    - + ) diff --git a/src/renderer/src/pages/paintings/AihubmixPage.tsx b/src/renderer/src/pages/paintings/AihubmixPage.tsx index 60a49664c9..e5f06b8e52 100644 --- a/src/renderer/src/pages/paintings/AihubmixPage.tsx +++ b/src/renderer/src/pages/paintings/AihubmixPage.tsx @@ -1,11 +1,11 @@ import { PlusOutlined, RedoOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' import AiProvider from '@renderer/aiCore' import IcImageUp from '@renderer/assets/images/paintings/ic_ImageUp.svg' import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar' -import { HStack } from '@renderer/components/Layout' import Scrollbar from '@renderer/components/Scrollbar' import TranslateButton from '@renderer/components/TranslateButton' import { isMac } from '@renderer/config/constant' @@ -745,12 +745,12 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { ) case 'switch': return ( - + updatePaintingState({ [item.key!]: checked })} /> - + ) case 'image': { return ( diff --git a/src/renderer/src/pages/paintings/DmxapiPage.tsx b/src/renderer/src/pages/paintings/DmxapiPage.tsx index 115da30f96..df2c833d56 100644 --- a/src/renderer/src/pages/paintings/DmxapiPage.tsx +++ b/src/renderer/src/pages/paintings/DmxapiPage.tsx @@ -1,8 +1,8 @@ import { PlusOutlined, RedoOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import DMXAPIToImg from '@renderer/assets/images/providers/DMXAPI-to-img.webp' import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar' -import { HStack } from '@renderer/components/Layout' import Scrollbar from '@renderer/components/Scrollbar' import { isMac } from '@renderer/config/constant' import { getProviderLogo } from '@renderer/config/providers' @@ -872,9 +872,9 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => { return modelImageSizes.map((size) => { return ( - + {size.label} - + ) }) @@ -882,9 +882,9 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => { {/* 检查当前模型是否支持自定义尺寸 */} {allModels.find((m) => m.id === painting.model)?.is_custom_size && ( - + {t('paintings.custom_size')} - + )} @@ -892,7 +892,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => { {/* 自定义尺寸输入框 */} {isCustomSize && allModels.find((m) => m.id === painting.model)?.is_custom_size && (
    - + = ({ Options }) => { style={{ width: 80, flex: 1 }} /> px - +
    )} @@ -959,9 +959,9 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => { - + onChangeAutoCreate(checked)} /> - + diff --git a/src/renderer/src/pages/paintings/SiliconPage.tsx b/src/renderer/src/pages/paintings/SiliconPage.tsx index 9271a51cb7..173c8ab5b6 100644 --- a/src/renderer/src/pages/paintings/SiliconPage.tsx +++ b/src/renderer/src/pages/paintings/SiliconPage.tsx @@ -1,4 +1,5 @@ import { PlusOutlined, RedoOutlined } from '@ant-design/icons' +import { ColFlex, RowFlex } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' @@ -10,7 +11,6 @@ import ImageSize3_4 from '@renderer/assets/images/paintings/image-size-3-4.svg' import ImageSize9_16 from '@renderer/assets/images/paintings/image-size-9-16.svg' import ImageSize16_9 from '@renderer/assets/images/paintings/image-size-16-9.svg' import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar' -import { HStack, VStack } from '@renderer/components/Layout' import Scrollbar from '@renderer/components/Scrollbar' import TranslateButton from '@renderer/components/TranslateButton' import { isMac } from '@renderer/config/constant' @@ -389,10 +389,10 @@ const SiliconPage: FC<{ Options: string[] }> = ({ Options }) => { style={{ display: 'flex' }}> {IMAGE_SIZES.map((size) => ( - + {size.label} - + ))} @@ -483,12 +483,12 @@ const SiliconPage: FC<{ Options: string[] }> = ({ Options }) => { - + updatePaintingState({ promptEnhancement: checked })} /> - + = ({ Options }) => { {/* 自定义尺寸输入框 */} {isCustomSize && (
    - + = ({ Options }) => { style={{ width: 80, flex: 1 }} /> px - +
    长宽均需满足512px-2048px之间, 需被16整除, 并保证最大像素数不超过2^21px
    diff --git a/src/renderer/src/pages/settings/AboutSettings.tsx b/src/renderer/src/pages/settings/AboutSettings.tsx index c90fc66feb..1751c5d949 100644 --- a/src/renderer/src/pages/settings/AboutSettings.tsx +++ b/src/renderer/src/pages/settings/AboutSettings.tsx @@ -1,7 +1,7 @@ import { GithubOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import IndicatorLight from '@renderer/components/IndicatorLight' -import { HStack } from '@renderer/components/Layout' import { APP_NAME, AppLogo } from '@renderer/config/env' import { useTheme } from '@renderer/context/ThemeProvider' import { useAppUpdateState } from '@renderer/hooks/useAppUpdate' @@ -186,11 +186,11 @@ const AboutSettings: FC = () => { {t('settings.about.title')} - + - + diff --git a/src/renderer/src/pages/settings/AssistantSettings/AssistantKnowledgeBaseSettings.tsx b/src/renderer/src/pages/settings/AssistantSettings/AssistantKnowledgeBaseSettings.tsx index 0013050d05..ff086e7722 100644 --- a/src/renderer/src/pages/settings/AssistantSettings/AssistantKnowledgeBaseSettings.tsx +++ b/src/renderer/src/pages/settings/AssistantSettings/AssistantKnowledgeBaseSettings.tsx @@ -1,5 +1,5 @@ import { CheckOutlined } from '@ant-design/icons' -import { Box } from '@renderer/components/Layout' +import { Box } from '@cherrystudio/ui' import { useAppSelector } from '@renderer/store' import type { Assistant, AssistantSettings } from '@renderer/types' import type { SelectProps } from 'antd' @@ -31,9 +31,7 @@ const AssistantKnowledgeBaseSettings: React.FC = ({ assistant, updateAssi return ( - - {t('common.knowledge_base')} - + {t('common.knowledge_base')} - + ) diff --git a/src/renderer/src/pages/settings/DataSettings/DataSettings.tsx b/src/renderer/src/pages/settings/DataSettings/DataSettings.tsx index 7ced28884b..253675a1e1 100644 --- a/src/renderer/src/pages/settings/DataSettings/DataSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/DataSettings.tsx @@ -5,10 +5,10 @@ import { LoadingOutlined, YuqueOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import DividerWithText from '@renderer/components/DividerWithText' import { NutstoreIcon } from '@renderer/components/Icons/NutstoreIcons' -import { HStack } from '@renderer/components/Layout' import ListItem from '@renderer/components/ListItem' import BackupPopup from '@renderer/components/Popups/BackupPopup' import RestorePopup from '@renderer/components/Popups/RestorePopup' @@ -600,14 +600,14 @@ const DataSettings: FC = () => { {t('settings.general.backup.title')} - + - + @@ -630,9 +630,9 @@ const DataSettings: FC = () => { {appInfo?.appDataPath} handleOpenPath(appInfo?.appDataPath)} style={{ flexShrink: 0 }} /> - + - + @@ -643,19 +643,19 @@ const DataSettings: FC = () => { {appInfo?.logsPath} handleOpenPath(appInfo?.logsPath)} style={{ flexShrink: 0 }} /> - + - + {t('settings.data.app_knowledge.label')} - + - + @@ -663,18 +663,18 @@ const DataSettings: FC = () => { {t('settings.data.clear_cache.title')} {cacheSize && ({cacheSize}MB)} - + - + {t('settings.general.reset.title')} - + - + @@ -696,7 +696,7 @@ const DataSettings: FC = () => { ) } -const Container = styled(HStack)` +const Container = styled(RowFlex)` flex: 1; ` @@ -751,7 +751,7 @@ const PathText = styled(Typography.Text)` cursor: pointer; ` -const PathRow = styled(HStack)` +const PathRow = styled(RowFlex)` min-width: 0; flex: 1; width: 0; diff --git a/src/renderer/src/pages/settings/DataSettings/JoplinSettings.tsx b/src/renderer/src/pages/settings/DataSettings/JoplinSettings.tsx index 807bcedd6a..2aaf86e249 100644 --- a/src/renderer/src/pages/settings/DataSettings/JoplinSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/JoplinSettings.tsx @@ -1,6 +1,6 @@ import { InfoCircleOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import { HStack } from '@renderer/components/Layout' import { useTheme } from '@renderer/context/ThemeProvider' import { useMinappPopup } from '@renderer/hooks/useMinappPopup' import { Button, Space, Switch, Tooltip } from 'antd' @@ -80,16 +80,16 @@ const JoplinSettings: FC = () => { {t('settings.data.joplin.url')} - + - + @@ -102,7 +102,7 @@ const JoplinSettings: FC = () => { /> - + { /> - + diff --git a/src/renderer/src/pages/settings/DataSettings/LocalBackupSettings.tsx b/src/renderer/src/pages/settings/DataSettings/LocalBackupSettings.tsx index a8e2dc163e..1b369e2dc2 100644 --- a/src/renderer/src/pages/settings/DataSettings/LocalBackupSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/LocalBackupSettings.tsx @@ -1,7 +1,7 @@ import { DeleteOutlined, FolderOpenOutlined, SaveOutlined, SyncOutlined, WarningOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' -import { HStack } from '@renderer/components/Layout' import { LocalBackupManager } from '@renderer/components/LocalBackupManager' import { LocalBackupModal, useLocalBackupModal } from '@renderer/components/LocalBackupModals' import Selector from '@renderer/components/Selector' @@ -151,7 +151,7 @@ const LocalBackupSettings: React.FC = () => { } return ( - + {localBackupSync.syncing && } {!localBackupSync.syncing && localBackupSync.lastSyncError && ( @@ -163,7 +163,7 @@ const LocalBackupSettings: React.FC = () => { {t('settings.data.local.lastSync')}: {dayjs(localBackupSync.lastSyncTime).format('HH:mm:ss')} )} - + ) } @@ -184,7 +184,7 @@ const LocalBackupSettings: React.FC = () => { {t('settings.data.local.directory.label')} - + setLocalBackupDir(e.target.value)} @@ -198,19 +198,19 @@ const LocalBackupSettings: React.FC = () => { - + {t('settings.general.backup.title')} - + - + diff --git a/src/renderer/src/pages/settings/DataSettings/MarkdownExportSettings.tsx b/src/renderer/src/pages/settings/DataSettings/MarkdownExportSettings.tsx index cc88a4a258..ed1dff4f1b 100644 --- a/src/renderer/src/pages/settings/DataSettings/MarkdownExportSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/MarkdownExportSettings.tsx @@ -1,6 +1,6 @@ import { DeleteOutlined, FolderOpenOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import { HStack } from '@renderer/components/Layout' import { useTheme } from '@renderer/context/ThemeProvider' import { Button, Switch } from 'antd' import Input from 'antd/es/input/Input' @@ -72,7 +72,7 @@ const MarkdownExportSettings: FC = () => { {t('settings.data.markdown_export.path')} - + { - + {t('settings.data.markdown_export.help')} diff --git a/src/renderer/src/pages/settings/DataSettings/NotionSettings.tsx b/src/renderer/src/pages/settings/DataSettings/NotionSettings.tsx index cf044fe939..6139372eb1 100644 --- a/src/renderer/src/pages/settings/DataSettings/NotionSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/NotionSettings.tsx @@ -1,7 +1,7 @@ import { InfoCircleOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { Client } from '@notionhq/client' -import { HStack } from '@renderer/components/Layout' import { useTheme } from '@renderer/context/ThemeProvider' import { useMinappPopup } from '@renderer/hooks/useMinappPopup' import { Button, Space, Switch, Tooltip } from 'antd' @@ -84,35 +84,33 @@ const NotionSettings: FC = () => { {t('settings.data.notion.database_id')} - + - + {t('settings.data.notion.page_name_key')} - + - + {t('settings.data.notion.api_key')} - + { /> - + diff --git a/src/renderer/src/pages/settings/DataSettings/NutstoreSettings.tsx b/src/renderer/src/pages/settings/DataSettings/NutstoreSettings.tsx index 86440bff97..99891f728f 100644 --- a/src/renderer/src/pages/settings/DataSettings/NutstoreSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/NutstoreSettings.tsx @@ -1,6 +1,6 @@ import { CheckOutlined, FolderOutlined, LoadingOutlined, SyncOutlined, WarningOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import { HStack } from '@renderer/components/Layout' import NutstorePathPopup from '@renderer/components/Popups/NutsorePathPopup' import Selector from '@renderer/components/Selector' import { WebdavBackupManager } from '@renderer/components/WebdavBackupManager' @@ -173,7 +173,7 @@ const NutstoreSettings: FC = () => { } return ( - + {nutstoreSyncState.syncing && } {!nutstoreSyncState.syncing && nutstoreSyncState.lastSyncError && ( @@ -185,7 +185,7 @@ const NutstoreSettings: FC = () => { {t('settings.data.webdav.lastSync')}: {dayjs(nutstoreSyncState.lastSyncTime).format('HH:mm:ss')} )} - + ) } @@ -208,7 +208,7 @@ const NutstoreSettings: FC = () => { {isLogin ? t('settings.data.nutstore.isLogin') : t('settings.data.nutstore.notLogin')} {isLogin ? ( - + - + ) : ( )} @@ -241,7 +241,7 @@ const NutstoreSettings: FC = () => { {t('settings.data.nutstore.path.label')} - + { - + {t('settings.general.backup.title')} - + - + diff --git a/src/renderer/src/pages/settings/DataSettings/ObsidianSettings.tsx b/src/renderer/src/pages/settings/DataSettings/ObsidianSettings.tsx index 3910b7d4a1..fbf41f54d0 100644 --- a/src/renderer/src/pages/settings/DataSettings/ObsidianSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/ObsidianSettings.tsx @@ -1,6 +1,6 @@ +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' -import { HStack } from '@renderer/components/Layout' import { Empty, Select, Spin } from 'antd' import type { FC } from 'react' import { useEffect, useState } from 'react' @@ -62,7 +62,7 @@ const ObsidianSettings: FC = () => { {t('settings.data.obsidian.default_vault')} - + {vaults.length > 0 ? ( - + @@ -107,7 +106,7 @@ const SiyuanSettings: FC = () => { /> - + { /> - + {t('settings.data.siyuan.box_id')} - + - + {t('settings.data.siyuan.root_path')} - + - + ) diff --git a/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx b/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx index 695b083d12..c9db62dac6 100644 --- a/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx @@ -1,6 +1,6 @@ import { FolderOpenOutlined, SaveOutlined, SyncOutlined, WarningOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import { HStack } from '@renderer/components/Layout' import Selector from '@renderer/components/Selector' import { WebdavBackupManager } from '@renderer/components/WebdavBackupManager' import { useWebdavBackupModal, WebdavBackupModal } from '@renderer/components/WebdavModals' @@ -67,7 +67,7 @@ const WebDavSettings: FC = () => { } return ( - + {webdavSync.syncing && } {!webdavSync.syncing && webdavSync.lastSyncError && ( @@ -79,7 +79,7 @@ const WebDavSettings: FC = () => { {t('settings.data.webdav.lastSync')}: {dayjs(webdavSync.lastSyncTime).format('HH:mm:ss')} )} - + ) } @@ -145,14 +145,14 @@ const WebDavSettings: FC = () => { {t('settings.general.backup.title')} - + - + diff --git a/src/renderer/src/pages/settings/DataSettings/YuqueSettings.tsx b/src/renderer/src/pages/settings/DataSettings/YuqueSettings.tsx index aef5bc3d6e..0de4c592a2 100644 --- a/src/renderer/src/pages/settings/DataSettings/YuqueSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/YuqueSettings.tsx @@ -1,6 +1,6 @@ import { InfoCircleOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import { HStack } from '@renderer/components/Layout' import { useTheme } from '@renderer/context/ThemeProvider' import { useMinappPopup } from '@renderer/hooks/useMinappPopup' import { Button, Space, Tooltip } from 'antd' @@ -76,15 +76,14 @@ const YuqueSettings: FC = () => { {t('settings.data.yuque.repo_url')} - + - + @@ -97,7 +96,7 @@ const YuqueSettings: FC = () => { /> - + { /> - + ) diff --git a/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx b/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx index 3bc8fdbafe..24abdcc8a2 100644 --- a/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx +++ b/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx @@ -1,7 +1,7 @@ +import { RowFlex } from '@cherrystudio/ui' import { CodeEditor } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { ResetIcon } from '@renderer/components/Icons' -import { HStack } from '@renderer/components/Layout' import TextBadge from '@renderer/components/TextBadge' import { isMac, THEME_COLOR_PRESETS } from '@renderer/config/constant' import { useCodeStyle } from '@renderer/context/CodeStyleProvider' @@ -196,8 +196,8 @@ const DisplaySettings: FC = () => { {t('settings.theme.color_primary')} - - + + {THEME_COLOR_PRESETS.map((color) => ( { /> ))} - + { } ]} /> - + {isMac && ( <> diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx index 2b72658f7e..0fa53e8d6d 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx @@ -1,11 +1,12 @@ // import { loggerService } from '@logger' +import { Flex } from '@cherrystudio/ui' import { ErrorBoundary } from '@renderer/components/ErrorBoundary' import { isMac, isWin } from '@renderer/config/constant' import { useTheme } from '@renderer/context/ThemeProvider' import { useOcrProviders } from '@renderer/hooks/useOcrProvider' import type { OcrProvider } from '@renderer/types' import { isBuiltinOcrProvider, isOcrSystemProvider } from '@renderer/types' -import { Divider, Flex } from 'antd' +import { Divider } from 'antd' import styled from 'styled-components' import { SettingGroup, SettingTitle } from '..' @@ -47,7 +48,7 @@ const OcrProviderSettings = ({ provider }: Props) => { return ( - + {getOcrProviderName(provider)} diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrSystemSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrSystemSettings.tsx index bd24326e2f..e066f49dea 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrSystemSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrSystemSettings.tsx @@ -1,4 +1,5 @@ // import { loggerService } from '@logger' +import { Flex } from '@cherrystudio/ui' import { SuccessTag } from '@renderer/components/Tags/SuccessTag' import { InfoTooltip } from '@renderer/components/TooltipIcons' import { isMac, isWin } from '@renderer/config/constant' @@ -6,7 +7,7 @@ import { useOcrProvider } from '@renderer/hooks/useOcrProvider' import useTranslate from '@renderer/hooks/useTranslate' import type { TranslateLanguageCode } from '@renderer/types' import { BuiltinOcrProviderIds, isOcrSystemProvider } from '@renderer/types' -import { Flex, Select } from 'antd' +import { Select } from 'antd' import { startTransition, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -54,7 +55,7 @@ export const OcrSystemSettings = () => { <> - + {t('settings.tool.ocr.common.langs')} {isWin && } diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx index 3c284656ab..bbdde27594 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx @@ -1,4 +1,5 @@ // import { loggerService } from '@logger' +import { Flex } from '@cherrystudio/ui' import CustomTag from '@renderer/components/Tags/CustomTag' import { InfoTooltip } from '@renderer/components/TooltipIcons' import { TESSERACT_LANG_MAP } from '@renderer/config/ocr' @@ -6,7 +7,7 @@ import { useOcrProvider } from '@renderer/hooks/useOcrProvider' import useTranslate from '@renderer/hooks/useTranslate' import type { TesseractLangCode } from '@renderer/types' import { BuiltinOcrProviderIds, isOcrTesseractProvider } from '@renderer/types' -import { Flex, Select } from 'antd' +import { Select } from 'antd' import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -63,7 +64,7 @@ export const OcrTesseractSettings = () => { <> - + {t('settings.tool.ocr.common.langs')} diff --git a/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx index 0e44b36f42..75cab3f202 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx @@ -1,10 +1,11 @@ import { ExportOutlined } from '@ant-design/icons' +import { Flex } from '@cherrystudio/ui' import { ApiKeyListPopup } from '@renderer/components/Popups/ApiKeyListPopup' import { getPreprocessProviderLogo, PREPROCESS_PROVIDER_CONFIG } from '@renderer/config/preprocessProviders' import { usePreprocessProvider } from '@renderer/hooks/usePreprocess' import type { PreprocessProvider } from '@renderer/types' import { formatApiKeys, hasObjectKey } from '@renderer/utils' -import { Avatar, Button, Divider, Flex, Input, Tooltip } from 'antd' +import { Avatar, Button, Divider, Input, Tooltip } from 'antd' import Link from 'antd/es/typography/Link' import { List } from 'lucide-react' import type { FC } from 'react' @@ -70,7 +71,7 @@ const PreprocessProviderSettings: FC = ({ provider: _provider }) => { return ( <> - + {preprocessProvider.name} @@ -97,7 +98,7 @@ const PreprocessProviderSettings: FC = ({ provider: _provider }) => { - + ) } diff --git a/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx b/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx index bfd9992dc4..190b324502 100644 --- a/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx @@ -1,6 +1,7 @@ +import { ColFlex, Flex } from '@cherrystudio/ui' import type { MCPServer, MCPTool } from '@renderer/types' import { isToolAutoApproved } from '@renderer/utils/mcp-tools' -import { Badge, Descriptions, Empty, Flex, Switch, Table, Tag, Tooltip, Typography } from 'antd' +import { Badge, Descriptions, Empty, Switch, Table, Tag, Tooltip, Typography } from 'antd' import type { ColumnsType } from 'antd/es/table' import { Hammer, Info, Zap } from 'lucide-react' import { useTranslation } from 'react-i18next' @@ -58,7 +59,7 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M + {key} {tool.inputSchema.required?.includes(key) && ( @@ -67,8 +68,8 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M )} }> - - + + {prop.type && ( // {prop.type}
    )} - + ))} @@ -113,8 +114,8 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M onFilter: (value, record) => record.name === value, filterSearch: true, render: (_, tool) => ( - - + + {tool.name} @@ -130,12 +131,12 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M {tool.description} )} - + ) }, { title: ( - + {t('settings.mcp.tools.enable')} @@ -149,7 +150,7 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M }, { title: ( - + {t('settings.mcp.tools.autoApprove.label')} diff --git a/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx b/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx index 7db63a2419..70187c8071 100644 --- a/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx @@ -1,11 +1,12 @@ import { CheckOutlined, PlusOutlined } from '@ant-design/icons' +import { Center, RowFlex } from '@cherrystudio/ui' +import { Flex } from '@cherrystudio/ui' import { nanoid } from '@reduxjs/toolkit' import logo from '@renderer/assets/images/cherry-text-logo.svg' -import { Center, HStack } from '@renderer/components/Layout' import { useMCPServers } from '@renderer/hooks/useMCPServers' import type { MCPServer } from '@renderer/types' import { getMcpConfigSampleFromReadme } from '@renderer/utils' -import { Button, Card, Flex, Input, Space, Spin, Tag, Typography } from 'antd' +import { Button, Card, Input, Space, Spin, Tag, Typography } from 'antd' import { npxFinder } from 'npx-scope-finder' import { type FC, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -103,7 +104,7 @@ const NpxSearch: FC = () => {
    -
    +
    npm
    @@ -116,7 +117,7 @@ const NpxSearch: FC = () => { styles={{ input: { borderRadius: 100 } }} /> - + {npmScopes.map((scope) => ( { {scope} ))} - +
    {searchLoading && ( diff --git a/src/renderer/src/pages/settings/MemorySettings/MemorySettings.tsx b/src/renderer/src/pages/settings/MemorySettings/MemorySettings.tsx index ecf8d74b68..8784e5cec8 100644 --- a/src/renderer/src/pages/settings/MemorySettings/MemorySettings.tsx +++ b/src/renderer/src/pages/settings/MemorySettings/MemorySettings.tsx @@ -1,7 +1,8 @@ import { ExclamationCircleOutlined } from '@ant-design/icons' +import { RowFlex } from '@cherrystudio/ui' +import { Flex } from '@cherrystudio/ui' import { loggerService } from '@logger' import { DeleteIcon, EditIcon, LoadingIcon, RefreshIcon } from '@renderer/components/Icons' -import { HStack } from '@renderer/components/Layout' import TextBadge from '@renderer/components/TextBadge' import { useTheme } from '@renderer/context/ThemeProvider' import { useModel } from '@renderer/hooks/useModel' @@ -15,7 +16,7 @@ import { setGlobalMemoryEnabled } from '@renderer/store/memory' import type { MemoryItem } from '@types' -import { Badge, Button, Dropdown, Empty, Flex, Form, Input, Modal, Pagination, Space, Spin, Switch } from 'antd' +import { Badge, Button, Dropdown, Empty, Form, Input, Modal, Pagination, Space, Spin, Switch } from 'antd' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { Brain, Calendar, MenuIcon, PlusIcon, Settings2, UserRound, UserRoundMinus, UserRoundPlus } from 'lucide-react' @@ -88,7 +89,7 @@ const AddMemoryModal: React.FC = ({ visible, onCancel, onAd onOk={() => form.submit()} okButtonProps={{ loading: loading }} title={ - + {t('memory.add_memory')} @@ -146,7 +147,7 @@ const EditMemoryModal: React.FC = ({ visible, memory, onCa return ( + {t('memory.edit_memory')} @@ -244,7 +245,7 @@ const AddUserModal: React.FC = ({ visible, onCancel, onAdd, e } }} title={ - + {t('memory.add_user')} @@ -581,16 +582,16 @@ const MemorySettings = () => { {/* Memory Settings */} - - + + {t('memory.global_memory')} - - + + @@ -140,7 +141,7 @@ const AssistantSettings: FC = () => { onChange={handleNameChange} style={{ flex: 1 }} /> - + {t('common.prompt')}