From d865e27d5856013e3464f8e539286a046d634295 Mon Sep 17 00:00:00 2001 From: CanisMinor Date: Sat, 27 Dec 2025 23:51:21 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20refactor=20sta?= =?UTF-8?q?tic=20style=20(#11010)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style * refactor: refactor static style --- .../createStaticStyles_migration_guide.md | 959 ++++++++++++++++++ package.json | 15 +- .../src/client/Render/UpdatePrompt.tsx | 37 +- .../src/client/Intervention/ExecuteTask.tsx | 23 +- .../src/client/Render/ExecuteTask/index.tsx | 15 +- .../src/client/Intervention/ClearTodos.tsx | 15 +- .../src/client/Render/TodoList.tsx | 12 +- .../SortableTodoList/AddItemRow.tsx | 5 +- .../SortableTodoList/TodoItemRow.tsx | 11 +- .../client/Render/ReadKnowledge/FileCard.tsx | 108 +- .../Render/SearchKnowledgeBase/Item/index.tsx | 11 +- .../Render/SearchKnowledgeBase/Item/style.ts | 28 +- .../Render/CreateDocument/DocumentCard.tsx | 73 +- .../src/client/Inspector/EditTitle/index.tsx | 40 +- .../client/Inspector/GetPageContent/index.tsx | 36 +- .../src/client/Inspector/InitPage/index.tsx | 46 +- .../client/Inspector/ModifyNodes/index.tsx | 52 +- .../client/Inspector/ReplaceText/index.tsx | 52 +- src/app/[variants]/(auth)/_layout/index.tsx | 36 +- src/app/[variants]/(auth)/_layout/style.ts | 47 + .../(auth)/next-auth/signin/AuthSignInBox.tsx | 21 +- .../[uid]/components/OAuthApplicationLogo.tsx | 9 +- .../(auth)/signin/SignInPasswordStep.tsx | 5 +- .../(main)/_layout/DesktopLayoutContainer.tsx | 50 +- .../_layout/DesktopLayoutContainer/style.ts | 27 + src/app/[variants]/(main)/_layout/index.tsx | 9 +- src/app/[variants]/(main)/_layout/style.ts | 14 + .../_layout/Sidebar/Topic/List/Item/index.tsx | 14 +- .../ThreadList/ThreadItem/index.tsx | 7 +- .../[variants]/(main)/chat/_layout/index.tsx | 13 +- .../[variants]/(main)/chat/_layout/style.ts | 10 + .../AgentWelcome/OpeningQuestions.tsx | 10 +- .../AgentWelcome/ToolAuthAlert.tsx | 5 +- .../features/Conversation/Header/index.tsx | 7 +- .../chat/features/Portal/_layout/Mobile.tsx | 14 +- .../chat/features/Portal/features/Portal.tsx | 9 +- .../chat/features/TelemetryNotification.tsx | 12 +- .../features/ProfileEditor/AgentTool.tsx | 10 +- .../MentionList/MentionDropdown.tsx | 15 +- .../MentionList/useMentionItems.tsx | 6 +- .../features/ProfileEditor/PluginTag.tsx | 20 +- .../community/(detail)/_layout/Header.tsx | 14 +- .../(detail)/_layout/Header/style.ts | 8 + .../community/(detail)/_layout/index.tsx | 14 +- .../community/(detail)/_layout/style.ts | 18 + .../Details/Capabilities/KnowledgeItem.tsx | 12 +- .../Details/Capabilities/PluginItem.tsx | 13 +- .../assistant/features/Details/Nav.tsx | 11 +- .../features/Details/Overview/TagList.tsx | 7 +- .../features/Details/SystemRole/TagList.tsx | 7 +- .../features/Details/SystemRole/index.tsx | 7 +- .../features/Details/Versions/index.tsx | 5 +- .../(detail)/assistant/features/Header.tsx | 28 +- .../Sidebar/ActionButton/AddAgent.tsx | 6 +- .../features/Sidebar/Related/Item.tsx | 9 +- .../features/Sidebar/Summary/index.tsx | 5 +- .../community/(detail)/features/Back.tsx | 9 +- .../community/(detail)/features/Block.tsx | 8 +- .../(detail)/features/Breadcrumb.tsx | 9 +- .../(detail)/features/HighlightBlock.tsx | 16 +- .../(detail)/features/ShareButton.tsx | 31 +- .../(detail)/features/Toc/Heading.tsx | 50 +- .../community/(detail)/features/Toc/index.tsx | 14 +- .../mcp/features/Details/Versions/index.tsx | 5 +- .../features/Sidebar/ActionButton/index.tsx | 5 +- .../mcp/features/Sidebar/Related/Item.tsx | 9 +- .../(detail)/model/features/Details/Nav.tsx | 11 +- .../Details/Overview/ProviderList/index.tsx | 7 +- .../Details/Parameter/ParameterItem.tsx | 5 +- .../(detail)/model/features/Header.tsx | 13 +- .../Sidebar/ActionButton/ChatWithModel.tsx | 7 +- .../model/features/Sidebar/Related/Item.tsx | 9 +- .../Sidebar/RelatedProviders/Item.tsx | 9 +- .../provider/features/Details/Nav.tsx | 11 +- .../Details/Overview/ModelList/index.tsx | 7 +- .../(detail)/provider/features/Header.tsx | 25 +- .../Sidebar/ActionButton/ProviderConfig.tsx | 5 +- .../features/Sidebar/Related/Item.tsx | 9 +- .../features/Sidebar/RelatedModels/Item.tsx | 9 +- .../(detail)/user/features/Header/Banner.tsx | 13 +- .../(detail)/user/features/Header/index.tsx | 5 +- .../(detail)/user/features/UserAgentCard.tsx | 25 +- .../user/features/UserFavoriteAgents.tsx | 25 +- .../user/features/UserFavoritePlugins.tsx | 19 +- .../community/(detail)/user/loading.tsx | 5 +- .../community/(list)/_layout/Footer.tsx | 44 +- .../community/(list)/_layout/Header.tsx | 13 +- .../community/(list)/_layout/Header/style.ts | 8 + .../(main)/community/(list)/_layout/index.tsx | 9 +- .../(main)/community/(list)/_layout/style.ts | 20 + .../(list)/assistant/_layout/index.tsx | 3 +- .../(list)/assistant/_layout/style.ts | 8 + .../(list)/assistant/features/List/Item.tsx | 21 +- .../assistant/features/List/TokenTag.tsx | 13 +- .../community/(list)/features/Pagination.tsx | 15 +- .../community/(list)/mcp/_layout/index.tsx | 3 +- .../community/(list)/mcp/_layout/style.ts | 8 + .../mcp/features/List/ConnectionTypeTag.tsx | 11 +- .../(list)/mcp/features/List/Item.tsx | 21 +- .../community/(list)/model/_layout/index.tsx | 5 +- .../community/(list)/model/_layout/style.ts | 8 + .../(list)/model/features/List/Item.tsx | 19 +- .../model/features/List/ModelTypeIcon.tsx | 5 +- .../(list)/provider/features/List/Item.tsx | 23 +- .../(main)/community/_layout/Header.tsx | 23 +- .../(main)/community/_layout/Header/style.ts | 11 + .../(main)/community/_layout/index.tsx | 13 +- .../(main)/community/_layout/style.ts | 10 + .../community/components/CardBanner.tsx | 10 +- .../community/components/CategoryMenu.tsx | 8 +- .../community/components/GridLoadingCard.tsx | 9 +- .../community/components/ListLoading.tsx | 13 +- .../components/SearchResultCount.tsx | 7 +- .../(main)/community/components/Statistic.tsx | 7 +- .../(main)/community/components/Title.tsx | 17 +- .../(main)/community/features/LikeButton.tsx | 3 +- .../(main)/community/features/Search.tsx | 8 +- .../(main)/community/features/Title.tsx | 7 +- .../Sidebar/AddGroupMemberModal/AgentItem.tsx | 15 +- .../AvailableAgentList.tsx | 11 +- .../AddGroupMemberModal/SelectedAgentList.tsx | 9 +- .../Sidebar/AddGroupMemberModal/index.tsx | 11 +- .../Sidebar/GroupConfig/AgentProfilePopup.tsx | 19 +- .../_layout/Sidebar/GroupConfig/GroupRole.tsx | 3 +- .../_layout/Sidebar/GroupConfig/style.ts | 10 +- .../_layout/Sidebar/Topic/List/Item/index.tsx | 14 +- .../ThreadList/ThreadItem/index.tsx | 7 +- .../[variants]/(main)/group/_layout/index.tsx | 13 +- .../[variants]/(main)/group/_layout/style.ts | 10 + .../AgentWelcome/OpeningQuestions.tsx | 10 +- .../features/Conversation/ChatItem/Thread.tsx | 18 +- .../Conversation/ChatItem/ThreadItem.tsx | 11 +- .../features/Conversation/Header/index.tsx | 5 +- .../group/features/Portal/_layout/Mobile.tsx | 14 +- .../group/features/Portal/features/Portal.tsx | 9 +- .../group/features/TelemetryNotification.tsx | 12 +- .../profile/features/AgentBuilder/index.tsx | 5 +- .../features/ProfileEditor/AgentTool.tsx | 9 +- .../MentionList/MentionDropdown.tsx | 15 +- .../MentionList/useMentionItems.tsx | 6 +- .../features/ProfileEditor/PluginTag.tsx | 20 +- .../Body/Agent/List/AgentGroupItem/index.tsx | 7 +- .../Body/Agent/List/AgentItem/index.tsx | 8 +- .../_layout/Body/Agent/List/Group/Item.tsx | 5 +- .../Modals/ConfigGroupModal/GroupItem.tsx | 5 +- .../Agent/Modals/ConfigGroupModal/index.tsx | 9 +- .../_layout/CreateGroupModal/AgentItem.tsx | 15 +- .../CreateGroupModal/AvailableAgentList.tsx | 11 +- .../CreateGroupModal/SelectedAgentList.tsx | 9 +- .../home/_layout/CreateGroupModal/index.tsx | 11 +- .../_layout/Header/components/AddButton.tsx | 6 +- .../home/_layout/Header/components/User.tsx | 7 +- .../hooks/useSessionGroupMenuItems.tsx | 5 +- .../_layout/hooks/useSessionItemMenuItems.tsx | 5 +- .../[variants]/(main)/home/_layout/index.tsx | 33 +- .../[variants]/(main)/home/_layout/style.ts | 25 + .../home/features/CommunityAgents/Item.tsx | 14 +- .../home/features/FeaturedPlugins/Item.tsx | 8 +- .../home/features/FeaturedPlugins/index.tsx | 5 +- .../home/features/InputArea/ModeHeader.tsx | 13 +- .../home/features/InputArea/StarterList.tsx | 17 +- .../(main)/home/features/RecentPage/Item.tsx | 10 +- .../home/features/RecentResource/Item.tsx | 8 +- .../(main)/home/features/RecentTopic/Item.tsx | 10 +- .../home/features/WelcomeText/index.tsx | 5 +- .../features/components/GroupBlock/index.tsx | 11 +- .../features/components/GroupSkeleton.tsx | 5 +- .../ScrollShadowWithButton/index.tsx | 13 +- .../(main)/image/NotSupportClient.tsx | 26 +- .../components/AspectRatioSelect/index.tsx | 10 +- .../ConfigPanel/components/ImageNum.tsx | 54 +- .../ConfigPanel/components/ImageUpload.tsx | 104 +- .../components/ModelSelect/ImageModelItem.tsx | 40 +- .../components/ModelSelect/index.tsx | 14 +- .../MultiImagesUpload/ImageManageModal.tsx | 55 +- .../components/MultiImagesUpload/index.tsx | 126 +-- .../components/ResolutionSelect.tsx | 29 +- .../ConfigPanel/components/Select/index.tsx | 12 +- .../(main)/image/_layout/ConfigPanel/style.ts | 8 +- .../(main)/image/_layout/Topics/TopicItem.tsx | 5 +- .../[variants]/(main)/image/_layout/index.tsx | 23 +- .../[variants]/(main)/image/_layout/style.ts | 16 + .../features/GenerationFeed/BatchItem.tsx | 13 +- .../GenerationItem/ActionButtons.tsx | 3 +- .../GenerationItem/ErrorState.tsx | 6 +- .../GenerationItem/LoadingState.tsx | 4 +- .../GenerationItem/SuccessState.tsx | 4 +- .../GenerationFeed/GenerationItem/styles.ts | 10 +- .../GenerationFeed/ReferenceImages.tsx | 20 +- .../image/features/PromptInput/Title.tsx | 7 +- .../image/features/PromptInput/index.tsx | 25 +- .../(home)/features/RoleTagCloud/index.tsx | 5 +- .../(main)/memory/_layout/index.tsx | 14 +- .../[variants]/(main)/memory/_layout/style.ts | 10 + .../contexts/features/ContextRightPanel.tsx | 7 +- .../features/List/GridView/ContextCard.tsx | 7 +- .../features/ExperienceRightPanel.tsx | 15 +- .../memory/features/EditableModal/Typobar.tsx | 5 +- .../memory/features/GridView/GridCard.tsx | 13 +- .../(main)/memory/features/HashTags.tsx | 5 +- .../memory/features/HighlightedContent.tsx | 5 +- .../(main)/memory/features/Loading.tsx | 12 +- .../(main)/memory/features/ProgressIcon.tsx | 5 +- .../(main)/memory/features/SourceLink.tsx | 5 +- .../features/TimeLineView/PeriodGroup.tsx | 16 +- .../features/TimeLineView/TimeLineCard.tsx | 7 +- .../memory/features/TimeLineView/index.tsx | 13 +- .../features/PreferenceRightPanel.tsx | 7 +- .../[variants]/(main)/page/_layout/index.tsx | 14 +- .../[variants]/(main)/page/_layout/style.ts | 10 + .../_layout/Body/LibraryList/EmptyStatus.tsx | 9 +- .../Body/LibraryList/List/Item/index.tsx | 7 +- .../(main)/resource/(home)/_layout/index.tsx | 14 +- .../(main)/resource/(home)/_layout/style.ts | 10 + .../resource/features/DndContextWrapper.tsx | 23 +- .../(main)/resource/features/FileDetail.tsx | 5 +- .../features/modal/FullscreenModal.tsx | 88 +- .../library/_layout/Header/LibraryHead.tsx | 21 +- .../(main)/resource/library/_layout/index.tsx | 14 +- .../(main)/resource/library/_layout/style.ts | 10 + .../(main)/settings/_layout/index.tsx | 14 +- .../(main)/settings/_layout/style.ts | 10 + .../settings/about/features/ItemCard.tsx | 5 +- .../settings/about/features/ItemLink.tsx | 6 +- .../settings/about/features/Version.tsx | 7 +- .../(main)/settings/about/index.tsx | 7 +- .../(main)/settings/apikey/Client.tsx | 11 +- .../apikey/features/EditableCell/index.tsx | 7 +- .../common/features/Appearance/Preview.tsx | 64 +- .../common/features/ChatAppearance/index.tsx | 5 +- .../(main)/settings/profile/Client.tsx | 17 +- .../settings/provider/(list)/Footer.tsx | 11 +- .../provider/(list)/ProviderGrid/Card.tsx | 15 +- .../provider/(list)/ProviderGrid/style.ts | 53 +- .../ProviderMenu/SortProviderModal/index.tsx | 9 +- .../settings/provider/ProviderMenu/index.tsx | 13 +- .../provider/_layout/Desktop/index.tsx | 9 +- .../provider/_layout/Desktop/style.ts | 8 + .../settings/provider/detail/azure/index.tsx | 9 +- .../settings/provider/detail/github/index.tsx | 9 +- .../provider/detail/ollama/Container.tsx | 11 +- .../provider/detail/vertexai/index.tsx | 9 +- .../features/ModelList/EmptyModels.tsx | 19 +- .../provider/features/ModelList/ModelItem.tsx | 12 +- .../features/ModelList/ModelTitle/index.tsx | 5 +- .../features/ModelList/SkeletonList.tsx | 8 +- .../ModelList/SortModelModal/index.tsx | 9 +- .../provider/features/ModelList/index.tsx | 5 +- .../features/ProviderConfig/Checker.tsx | 9 +- .../features/ProviderConfig/EnableSwitch.tsx | 6 +- .../features/ProviderConfig/index.tsx | 25 +- .../security/features/ClerkProfile.tsx | 16 +- .../(main)/settings/security/index.tsx | 4 +- .../settings/stats/features/AiHeatmaps.tsx | 10 +- .../stats/features/ShareButton/Preview.tsx | 35 +- .../stats/features/ShareButton/ShareModal.tsx | 7 +- .../stats/features/ShareButton/TotalCard.tsx | 8 +- .../settings/stats/features/TimeLabel.tsx | 5 +- .../settings/stats/features/TopicsRank.tsx | 5 +- .../stats/features/TotalAssistants.tsx | 5 +- .../settings/stats/features/TotalMessages.tsx | 5 +- .../settings/stats/features/TotalTopics.tsx | 5 +- .../settings/stats/features/Welcome.tsx | 5 +- .../UsageCards/ActiveModels/ModelTable.tsx | 7 +- .../UsageCards/ActiveModels/index.tsx | 7 +- .../usage/features/UsageCards/MonthSpend.tsx | 5 +- .../usage/features/UsageCards/TodaySpend.tsx | 5 +- .../settings/usage/features/UsageTable.tsx | 5 +- .../(mobile)/(home)/_layout/MobileLayout.tsx | 3 +- .../(home)/_layout/MobileLayout/style.ts | 9 + .../(mobile)/(home)/_layout/SessionHeader.tsx | 4 +- .../(home)/_layout/SessionHeader/style.ts | 8 + .../CollapseGroup/Actions.tsx | 5 +- .../CollapseGroup/index.tsx | 19 +- .../SessionListContent/List/Item/Actions.tsx | 5 +- .../SessionListContent/List/index.tsx | 5 +- .../SessionListContent/ListItem/index.tsx | 7 +- .../Modals/ConfigGroupModal/GroupItem.tsx | 5 +- .../Modals/ConfigGroupModal/index.tsx | 9 +- .../(mobile)/(home)/features/SkeletonList.tsx | 14 +- .../[variants]/(mobile)/_layout/NavBar.tsx | 8 +- .../(mobile)/chat/_layout/index.tsx | 4 +- .../[variants]/(mobile)/chat/_layout/style.ts | 8 + .../features/ChatHeader/ChatHeaderTitle.tsx | 7 +- .../Topic/features/AgentConfig/SystemRole.tsx | 7 +- .../features/Topic/features/ConfigLayout.tsx | 11 +- .../(mobile)/chat/settings/index.tsx | 5 +- .../community/(list)/_layout/Header.tsx | 7 +- .../(mobile)/community/(list)/_layout/Nav.tsx | 15 +- .../community/(list)/_layout/index.tsx | 3 +- .../community/(list)/_layout/style.ts | 9 + .../(mobile)/me/(home)/features/Header.tsx | 8 +- .../[variants]/onboarding/_layout/index.tsx | 36 +- .../[variants]/onboarding/_layout/style.ts | 47 + .../components/KlavisServerItem.tsx | 8 +- .../components/ServerIcon.tsx | 6 +- .../components/ServerStatusControl.tsx | 9 +- .../onboarding/features/FullNameStep.tsx | 7 +- .../onboarding/features/InterestsStep.tsx | 18 +- .../onboarding/features/ModeSelectionStep.tsx | 125 +-- .../onboarding/features/ProSettingsStep.tsx | 9 +- .../features/ResponseLanguageStep.tsx | 5 +- .../onboarding/features/TelemetryStep.tsx | 50 +- src/components/BrandWatermark/index.tsx | 9 +- .../Branding/ProductLogo/Custom.tsx | 8 +- src/components/BubblesLoading/index.tsx | 5 +- src/components/Cell/Divider.tsx | 21 +- src/components/Cell/index.tsx | 12 +- src/components/ChangelogModal/VersionTag.tsx | 8 +- .../ChatGroupWizard/ChatGroupWizard.tsx | 47 +- src/components/CircleLoader/index.tsx | 40 +- src/components/DataStyleModal/index.tsx | 35 +- src/components/Descriptions/index.tsx | 24 +- src/components/DragUpload/index.tsx | 24 +- src/components/DragUploadZone/index.tsx | 27 +- src/components/FeatureList/index.tsx | 41 +- .../FileParsingStatus/EmbeddingStatus.tsx | 24 +- src/components/FileParsingStatus/index.tsx | 22 +- src/components/FormAction/index.tsx | 16 +- .../FunctionModal/createModalHooks.ts | 3 +- src/components/FunctionModal/style.tsx | 14 +- src/components/GalleyGrid/Grid.tsx | 25 +- src/components/GalleyGrid/style.ts | 41 +- src/components/GoBack/index.tsx | 11 +- src/components/GroupIcon/index.tsx | 10 +- src/components/GuideModal/index.tsx | 31 +- src/components/GuideVideo/index.tsx | 5 +- src/components/HtmlPreview/PreviewDrawer.tsx | 5 +- src/components/ImageItem/index.tsx | 13 +- src/components/IndexCard/index.tsx | 27 +- src/components/InfoTooltip/index.tsx | 5 +- src/components/InitProgress/index.tsx | 6 +- src/components/InlineTable/index.tsx | 9 +- src/components/InvalidAPIKey/Bedrock.tsx | 5 +- src/components/InvalidAPIKey/ComfyUIForm.tsx | 14 +- src/components/KeyValueEditor/index.tsx | 15 +- src/components/LabsModal/Hero.tsx | 9 +- src/components/LabsModal/LabCard.tsx | 20 +- src/components/LibIcon/index.tsx | 6 +- .../Loading/SkeletonLoading/index.tsx | 10 +- src/components/MCPDepsIcon/index.tsx | 5 +- .../MemberSelectionModal.tsx | 40 +- src/components/Menu/index.tsx | 21 +- src/components/ModelSelect/index.tsx | 14 +- src/components/NProgress/index.tsx | 5 +- src/components/Notification/index.tsx | 31 +- src/components/OllamaSetupGuide/index.tsx | 16 +- src/components/PanelTitle/index.tsx | 8 +- src/components/Plugins/PluginAvatar.tsx | 4 +- src/components/ProgressItem/index.tsx | 13 +- src/components/PublishedTime.tsx | 7 +- src/components/SidebarHeader/index.tsx | 6 +- src/components/Statistic/index.tsx | 5 +- .../StatisticCard/TitleWithPercentage.tsx | 15 +- src/components/StatisticCard/index.tsx | 323 +++--- src/components/StopLoading.tsx | 12 +- src/components/TipGuide/index.tsx | 15 +- src/components/TodoList.tsx | 36 +- src/features/AgentBuilder/TopicSelector.tsx | 7 +- src/features/AgentInfo/index.tsx | 10 +- .../AgentMeta/AutoGenerateAvatar.tsx | 11 +- .../AgentSetting/AgentModal/index.tsx | 5 +- .../AgentOpening/OpeningMessage.tsx | 11 +- .../AgentOpening/OpeningQuestions.tsx | 7 +- .../AgentTTS/SelectWithTTSPreview.tsx | 7 +- src/features/AlertBanner/CloudBanner.tsx | 21 +- .../ChatInput/ActionBar/Model/index.tsx | 21 +- .../ChatInput/ActionBar/Params/Controls.tsx | 9 +- .../ChatInput/ActionBar/STT/common.tsx | 7 +- .../ChatInput/ActionBar/Search/Controls.tsx | 23 +- .../ActionBar/Search/FCSearchModel.tsx | 11 +- .../FunctionCallingModelSelect/index.tsx | 8 +- .../ChatInput/ActionBar/Search/index.tsx | 5 +- .../ActionBar/Token/TokenProgress.tsx | 9 +- .../ChatInput/ActionBar/Token/TokenTag.tsx | 23 +- .../ActionBar/Token/TokenTagForGroupChat.tsx | 23 +- .../ChatInput/ActionBar/Tools/index.tsx | 19 +- .../ChatInput/ActionBar/Tools/useControls.tsx | 6 +- .../ActionBar/components/ActionDropdown.tsx | 7 +- .../ActionBar/components/ActionPopover.tsx | 9 +- src/features/ChatInput/ActionBar/styles.ts | 6 +- .../ContextContainer/ContextItem/Content.tsx | 6 +- .../ContextContainer/ContextItem/index.tsx | 16 +- .../Desktop/ContextContainer/ContextList.tsx | 5 +- .../ContextContainer/SelectionItem.tsx | 5 +- .../Desktop/FilePreview/FileItem/Content.tsx | 6 +- .../Desktop/FilePreview/FileItem/index.tsx | 11 +- .../Desktop/FilePreview/FileList.tsx | 5 +- .../MentionedUsers/MentionedUserItem.tsx | 19 +- .../Desktop/MentionedUsers/index.tsx | 9 +- src/features/ChatInput/Desktop/index.tsx | 6 +- .../Mobile/FilePreview/FileItem/File.tsx | 14 +- .../Mobile/FilePreview/FileItem/Image.tsx | 13 +- .../ChatInput/Mobile/FilePreview/index.tsx | 5 +- src/features/ChatInput/Mobile/index.tsx | 8 +- .../ChatInput/SendArea/ShortcutHint.tsx | 8 +- src/features/ChatInput/TypoBar/index.tsx | 5 +- .../components/UploadDetail/UploadStatus.tsx | 5 +- .../components/UploadDetail/index.tsx | 5 +- src/features/ChatMiniMap/MinimapIndicator.tsx | 5 +- src/features/ChatMiniMap/index.tsx | 5 +- src/features/ChatMiniMap/styles.ts | 22 +- src/features/CommandMenu/AskAIMenu.tsx | 3 +- src/features/CommandMenu/SearchResults.tsx | 3 +- src/features/CommandMenu/ThemeMenu.tsx | 3 +- .../CommandMenu/components/CommandFooter.tsx | 37 +- .../CommandMenu/components/CommandInput.tsx | 31 +- .../CommandMenu/components/CommandItem.tsx | 3 +- src/features/CommandMenu/index.tsx | 36 +- src/features/CommandMenu/styles.ts | 171 ++-- .../Conversation/ChatItem/ChatItem.tsx | 8 +- .../ChatItem/components/Loading.tsx | 6 +- .../components/MessageContent/Typobar.tsx | 5 +- .../components/MessageContent/index.tsx | 11 +- src/features/Conversation/ChatItem/style.ts | 10 +- .../ChatList/components/BackBottom/index.tsx | 5 +- .../ChatList/components/BackBottom/style.ts | 10 +- src/features/Conversation/Error/style.tsx | 18 +- .../plugins/LobeArtifact/Render/Icon.tsx | 45 +- .../plugins/LobeArtifact/Render/index.tsx | 25 +- .../Markdown/plugins/Mention/Render.tsx | 11 +- .../components/ScrollShadowWithButton.tsx | 13 +- .../Tool/Inspector/StatusIndicator.tsx | 15 +- .../Tool/Inspector/ToolTitle.tsx | 20 +- .../Tool/Render/Arguments/index.tsx | 16 +- .../Render/Intervention/KeyValueEditor.tsx | 11 +- .../Tool/Render/Intervention/ModeSelector.tsx | 21 +- .../Tool/Render/PluginSettings.tsx | 10 +- .../Tool/Render/RejectedResponse.tsx | 11 +- .../AssistantGroup/components/Group.tsx | 5 +- .../components/MessageContent.tsx | 7 +- .../Task/TaskDetailPanel/CompletedState.tsx | 17 +- .../Task/TaskDetailPanel/ErrorState.tsx | 21 +- .../TaskDetailPanel/InitializingState.tsx | 57 +- .../Task/TaskDetailPanel/ProcessingState.tsx | 71 +- .../Messages/Task/TaskDetailPanel/index.tsx | 8 +- .../Messages/components/Extras/Translate.tsx | 5 +- .../Extras/Usage/UsageDetail/ModelCard.tsx | 9 +- .../Usage/UsageDetail/TokenProgress.tsx | 7 +- .../Extras/Usage/UsageDetail/index.tsx | 37 +- .../components/Extras/Usage/index.tsx | 12 +- .../components/FileChunks/ChunkItem.tsx | 7 +- .../Messages/components/FileChunks/index.tsx | 24 +- .../Messages/components/FileChunks/style.ts | 28 +- .../components/IntentUnderstanding.tsx | 10 +- .../Messages/components/MessageBranch.tsx | 17 +- .../Messages/components/SearchGrounding.tsx | 56 +- src/features/Conversation/Messages/index.tsx | 7 +- .../Conversation/components/ContextMenu.tsx | 7 +- .../Conversation/components/History/index.tsx | 11 +- .../ShareMessageModal/ShareImage/Preview.tsx | 12 +- .../ShareMessageModal/ShareImage/index.tsx | 3 +- .../ShareMessageModal/ShareImage/style.ts | 36 +- .../ShareMessageModal/ShareText/Preview.tsx | 3 +- .../ShareMessageModal/ShareText/index.tsx | 3 +- .../components/ShareMessageModal/style.ts | 56 +- .../components/Thinking/StatusIndicator.tsx | 9 +- .../components/Thinking/Title.tsx | 10 +- .../components/Thinking/index.tsx | 9 +- src/features/DataImporter/FileUploading.tsx | 10 +- src/features/DataImporter/ImportDetail.tsx | 47 +- src/features/DataImporter/Loading.tsx | 171 ++-- src/features/DataImporter/SuccessResult.tsx | 7 +- src/features/DataImporter/index.tsx | 9 +- src/features/DataImporter/style.ts | 4 +- src/features/DesktopOnboarding/Navigation.tsx | 10 +- .../DesktopOnboarding/OnboardingContainer.tsx | 12 +- .../DesktopOnboarding/common/AuthResult.tsx | 24 +- .../DesktopOnboarding/common/LogoBrand.tsx | 10 +- .../DesktopOnboarding/common/TitleSection.tsx | 13 +- .../DesktopOnboarding/effects/LightRays.tsx | 3 +- .../DesktopOnboarding/screens/Screen1.tsx | 21 +- .../DesktopOnboarding/screens/Screen2.tsx | 46 +- .../DesktopOnboarding/screens/Screen3.tsx | 39 +- .../DesktopOnboarding/screens/Screen4.tsx | 29 +- .../DesktopOnboarding/screens/Screen5.tsx | 63 +- .../DesktopOnboarding/styles/index.ts | 35 +- .../DesktopOnboarding/styles/layout.ts | 4 +- .../DesktopOnboarding/styles/media.ts | 4 +- .../DesktopOnboarding/styles/spacing.ts | 28 +- .../DesktopOnboarding/styles/typography.ts | 28 +- .../DevPanel/FeatureFlagViewer/Form.tsx | 9 +- .../DevPanel/MetadataViewer/index.tsx | 7 +- src/features/DevPanel/features/FloatPanel.tsx | 34 +- src/features/DevPanel/features/Header.tsx | 7 +- .../DevPanel/features/Table/index.tsx | 34 +- .../Connection/ConnectionMode.tsx | 15 +- .../ElectronTitlebar/Connection/Option.tsx | 26 +- .../ElectronTitlebar/Connection/Waiting.tsx | 31 +- .../Connection/WaitingAnim.tsx | 18 +- .../ElectronTitlebar/Connection/index.tsx | 7 +- .../ElectronTitlebar/UpdateNotification.tsx | 28 +- .../hooks/useWatchThemeUpdate.ts | 9 +- src/features/FileSidePanel/index.tsx | 8 +- src/features/FileViewer/NotSupport/index.tsx | 9 +- .../FileViewer/Renderer/JavaScript/index.tsx | 9 +- .../FileViewer/Renderer/Markdown/index.tsx | 9 +- .../FileViewer/Renderer/PDF/index.tsx | 3 +- src/features/FileViewer/Renderer/PDF/style.ts | 8 +- .../FileViewer/Renderer/TXT/index.tsx | 9 +- .../FileViewer/Renderer/Video/index.tsx | 18 +- src/features/Follow/index.tsx | 9 +- src/features/GroupAvatar/index.tsx | 7 +- src/features/GroupChatSettings/AgentCard.tsx | 35 +- .../AgentTeamMembersSettings.tsx | 5 +- .../GroupChatSettings/HostMemberCard.tsx | 26 +- src/features/GroupInfo/index.tsx | 10 +- .../HotkeyHelperPanel/HotkeyContent.tsx | 9 +- src/features/ImageSidePanel/index.tsx | 7 +- src/features/ImageTopicPanel/index.tsx | 10 +- .../AssignKnowledgeBase/Item/MasonryItem.tsx | 20 +- .../AssignKnowledgeBase/Item/PluginTag.tsx | 24 +- .../AssignKnowledgeBase/Item/index.tsx | 10 +- .../AssignKnowledgeBase/MasonrySkeleton.tsx | 11 +- .../AssignKnowledgeBase/ViewSwitcher.tsx | 5 +- src/features/LocalFile/LocalFile.tsx | 11 +- src/features/LocalFile/LocalFolder.tsx | 11 +- .../InstallError/ErrorDetails.tsx | 5 +- .../MCP/MCPInstallProgress/MCPConfigForm.tsx | 25 +- .../MCPDependenciesGuide.tsx | 51 +- src/features/MCP/MCPInstallProgress/index.tsx | 6 +- src/features/MCP/Scores.tsx | 48 +- src/features/MCPPluginDetail/CollapseDesc.tsx | 14 +- .../Deployment/Platform/index.tsx | 5 +- .../MCPPluginDetail/Deployment/index.tsx | 31 +- src/features/MCPPluginDetail/Header.tsx | 17 +- src/features/MCPPluginDetail/Nav.tsx | 11 +- .../MCPPluginDetail/Overview/TagList.tsx | 7 +- .../MCPPluginDetail/Schema/Prompts.tsx | 10 +- .../MCPPluginDetail/Schema/Resources.tsx | 6 +- src/features/MCPPluginDetail/Schema/Tools.tsx | 10 +- src/features/MCPPluginDetail/Schema/style.ts | 6 +- .../Score/GithubBadge/index.tsx | 5 +- .../MCPPluginDetail/Score/ScoreItem.tsx | 9 +- .../MCPPluginDetail/Score/TotalScore.tsx | 59 +- src/features/MobileTabBar/index.tsx | 8 +- .../ModelParamsControl/FrequencyPenalty.tsx | 12 +- .../ModelParamsControl/PresencePenalty.tsx | 8 +- .../ModelParamsControl/Temperature.tsx | 7 +- src/features/ModelParamsControl/TopP.tsx | 10 +- src/features/ModelSelect/index.tsx | 8 +- src/features/ModelSwitchPanel/index.tsx | 35 +- src/features/NavPanel/SideBarDrawer.tsx | 12 +- src/features/NavPanel/SideBarHeaderLayout.tsx | 11 +- src/features/NavPanel/components/BackNav.tsx | 9 +- src/features/NavPanel/components/NavItem.tsx | 12 +- .../NavPanel/components/SkeletonList.tsx | 8 +- src/features/NavPanel/index.tsx | 18 +- src/features/OllamaModelDownloader/index.tsx | 12 +- src/features/OllamaSetupGuide/Desktop.tsx | 5 +- src/features/PageEditor/Body/Title.tsx | 5 +- src/features/PageEditor/Body/index.tsx | 7 +- src/features/PageEditor/Copilot/Toolbar.tsx | 5 +- src/features/PageEditor/DiffAllToolbar.tsx | 32 +- .../PageEditor/EditorCanvas/InlineToolbar.tsx | 12 +- src/features/PageEditor/Header/Breadcrumb.tsx | 15 +- src/features/PageEditor/Header/useMenu.tsx | 6 +- src/features/PageEditor/PageEditor.tsx | 6 +- .../PageExplorer/PageExplorerPlaceholder.tsx | 29 +- src/features/PlanIcon/index.tsx | 13 +- .../MCPManifestForm/CollapsibleSection.tsx | 19 +- .../MCPManifestForm/MCPTypeSelect.tsx | 44 +- .../PluginPreview/ApiVisualizer.tsx | 22 +- .../PluginPreview/EmptyState.tsx | 23 +- .../PluginDevModal/PluginPreview/index.tsx | 7 +- src/features/PluginSettings/index.tsx | 7 +- .../Detail/CustomPluginEmptyState.tsx | 23 +- .../PluginStore/InstalledList/index.tsx | 6 +- .../PluginStore/McpList/Detail/Loading.tsx | 5 +- .../McpList/Detail/Settings/index.tsx | 95 +- .../PluginStore/McpList/Detail/index.tsx | 2 +- src/features/PluginStore/McpList/index.tsx | 6 +- .../PluginList/Detail/EmptyState.tsx | 21 +- .../PluginStore/PluginList/Detail/Header.tsx | 13 +- .../PluginList/Detail/InstallDetail/Nav.tsx | 11 +- .../PluginStore/PluginList/Detail/Loading.tsx | 5 +- .../PluginStore/PluginList/Detail/TagList.tsx | 7 +- .../PluginStore/PluginList/List/Item.tsx | 5 +- src/features/PluginStore/PluginList/index.tsx | 6 +- src/features/PluginStore/VirtuosoLoading.tsx | 5 +- src/features/PluginsUI/Render/Loading.tsx | 37 +- src/features/Portal/Document/Body.tsx | 6 +- .../Portal/GroupThread/Header/index.tsx | 5 +- .../Portal/Home/Body/Files/FileList/Item.tsx | 9 +- .../Portal/Home/Body/Files/FileList/index.tsx | 7 +- .../Body/Plugins/ArtifactList/Item/index.tsx | 4 +- .../Body/Plugins/ArtifactList/Item/style.ts | 18 +- .../Home/Body/Plugins/ArtifactList/index.tsx | 7 +- src/features/Portal/Notebook/Body.tsx | 11 +- src/features/Portal/Notebook/DocumentItem.tsx | 11 +- src/features/Portal/Thread/Header/Active.tsx | 7 +- src/features/Portal/Thread/Header/index.tsx | 5 +- .../InstallPlugin/ConfigDisplay.tsx | 59 +- .../ChunkDrawer/ChunkList/ChunkItem.tsx | 10 +- .../ChunkDrawer/SimilaritySearchList/Item.tsx | 12 +- .../components/ChunkDrawer/index.tsx | 5 +- .../components/Editor/index.tsx | 6 +- .../components/Explorer/EmptyPlaceholder.tsx | 28 +- .../components/Explorer/Header/Breadcrumb.tsx | 15 +- .../components/Explorer/Header/index.tsx | 5 +- .../Explorer/ListView/ListItem/index.tsx | 28 +- .../components/Explorer/ListView/index.tsx | 27 +- .../MasonryFileItem/DefaultFileItem.tsx | 17 +- .../MasonryFileItem/ImageFileItem.tsx | 31 +- .../MasonryFileItem/MarkdownFileItem.tsx | 43 +- .../MasonryFileItem/NoteFileItem.tsx | 33 +- .../MasonryView/MasonryFileItem/index.tsx | 35 +- .../Explorer/MasonryView/Skeleton.tsx | 33 +- .../ToolBar/ActionIconWithChevron.tsx | 8 +- .../Explorer/ToolBar/MultiSelectActions.tsx | 24 +- .../components/FolderTree/index.tsx | 14 +- .../components/Tree/TreeSkeleton.tsx | 8 +- .../ResourceManager/components/Tree/index.tsx | 11 +- .../components/UploadDock/Item.tsx | 9 +- .../components/UploadDock/index.tsx | 71 +- src/features/ResourceManager/index.tsx | 4 +- src/features/RightPanel/index.tsx | 5 +- src/features/Setting/Footer.tsx | 9 +- src/features/Setting/SettingContainer.tsx | 7 +- .../ShareModal/ShareImage/Preview.tsx | 22 +- src/features/ShareModal/ShareImage/index.tsx | 3 +- src/features/ShareModal/ShareImage/style.ts | 36 +- src/features/ShareModal/ShareJSON/Preview.tsx | 10 +- src/features/ShareModal/ShareJSON/index.tsx | 3 +- .../ShareModal/SharePdf/PdfPreview.tsx | 33 +- src/features/ShareModal/SharePdf/index.tsx | 10 +- src/features/ShareModal/ShareText/Preview.tsx | 10 +- src/features/ShareModal/ShareText/index.tsx | 3 +- src/features/ShareModal/style.ts | 55 +- src/features/ShareModal/useContainerStyles.ts | 44 + src/features/User/DataStatistics.tsx | 17 +- src/features/User/PlanTag.tsx | 5 +- src/features/User/UserAvatar.tsx | 11 +- src/features/User/UserInfo.tsx | 5 +- src/features/User/UserPanel/index.tsx | 5 +- src/features/WideScreenContainer/index.tsx | 7 +- src/features/ZenModeToast/Toast.tsx | 15 +- .../AuthProvider/Clerk/useAppearance.ts | 194 ++-- .../MarketAuth/MarketAuthConfirmModal.tsx | 35 +- .../MarketAuth/ProfileSetupModal.tsx | 35 +- src/layout/GlobalProvider/AppTheme.tsx | 12 +- src/styles/index.ts | 1 + src/styles/loading.ts | 48 +- .../Render/components/ResultFileItem.tsx | 38 +- .../code-interpreter-draft/Render/index.tsx | 9 +- .../Inspector/ExecuteCode/index.tsx | 16 +- .../Intervention/MoveLocalFiles/index.tsx | 7 +- .../Render/EditLocalFile/index.tsx | 13 +- .../Render/ExecuteCode/index.tsx | 8 +- .../Render/ExportFile/index.tsx | 11 +- .../Render/ListFiles/index.tsx | 20 +- .../Render/MoveLocalFiles/index.tsx | 20 +- .../Render/ReadLocalFile/index.tsx | 12 +- .../Render/RunCommand/index.tsx | 11 +- .../Render/SearchFiles/index.tsx | 18 +- .../Render/WriteFile/index.tsx | 11 +- .../Inspector/EditLocalFile/index.tsx | 14 +- .../Inspector/GlobLocalFiles/index.tsx | 14 +- .../Inspector/GrepContent/index.tsx | 14 +- .../Inspector/ReadLocalFile/index.tsx | 14 +- .../Inspector/RunCommand/index.tsx | 14 +- .../Inspector/SearchLocalFiles/index.tsx | 14 +- .../MoveLocalFiles/MoveFileItem.tsx | 13 +- .../local-system/Placeholder/SearchFiles.tsx | 14 +- .../Render/MoveLocalFiles/MoveFileItem.tsx | 13 +- .../Render/ReadLocalFile/ReadFileSkeleton.tsx | 10 +- .../Render/ReadLocalFile/ReadFileView.tsx | 49 +- .../Render/RenameLocalFile/index.tsx | 10 +- .../local-system/Render/RunCommand/index.tsx | 7 +- .../SearchFiles/SearchQuery/SearchView.tsx | 16 +- .../local-system/components/FileItem.tsx | 17 +- .../Inspector/CrawlMultiPages/index.tsx | 14 +- .../Inspector/CrawlSinglePage/index.tsx | 14 +- .../web-browsing/Inspector/Search/index.tsx | 14 +- src/tools/web-browsing/Placeholder/Search.tsx | 13 +- .../web-browsing/Portal/PageContent/index.tsx | 31 +- .../ResultList/SearchItem/CategoryAvatar.tsx | 8 +- .../Search/ResultList/SearchItem/Video.tsx | 20 +- .../Search/ResultList/SearchItem/index.tsx | 15 +- .../Render/PageContent/Loading.tsx | 18 +- .../Render/PageContent/Result.tsx | 25 +- .../Render/Search/ConfigForm/style.tsx | 12 +- .../Render/Search/SearchQuery/SearchView.tsx | 16 +- .../Search/SearchResult/SearchResultItem.tsx | 12 +- .../Render/Search/SearchResult/ShowMore.tsx | 9 +- .../components/CategoryAvatar.tsx | 5 +- .../web-browsing/components/EngineAvatar.tsx | 5 +- 687 files changed, 6542 insertions(+), 5726 deletions(-) create mode 100644 .cursor/docs/createStaticStyles_migration_guide.md create mode 100644 src/app/[variants]/(auth)/_layout/style.ts create mode 100644 src/app/[variants]/(main)/_layout/DesktopLayoutContainer/style.ts create mode 100644 src/app/[variants]/(main)/_layout/style.ts create mode 100644 src/app/[variants]/(main)/chat/_layout/style.ts create mode 100644 src/app/[variants]/(main)/community/(detail)/_layout/Header/style.ts create mode 100644 src/app/[variants]/(main)/community/(detail)/_layout/style.ts create mode 100644 src/app/[variants]/(main)/community/(list)/_layout/Header/style.ts create mode 100644 src/app/[variants]/(main)/community/(list)/_layout/style.ts create mode 100644 src/app/[variants]/(main)/community/(list)/assistant/_layout/style.ts create mode 100644 src/app/[variants]/(main)/community/(list)/mcp/_layout/style.ts create mode 100644 src/app/[variants]/(main)/community/(list)/model/_layout/style.ts create mode 100644 src/app/[variants]/(main)/community/_layout/Header/style.ts create mode 100644 src/app/[variants]/(main)/community/_layout/style.ts create mode 100644 src/app/[variants]/(main)/group/_layout/style.ts create mode 100644 src/app/[variants]/(main)/home/_layout/style.ts create mode 100644 src/app/[variants]/(main)/image/_layout/style.ts create mode 100644 src/app/[variants]/(main)/memory/_layout/style.ts create mode 100644 src/app/[variants]/(main)/page/_layout/style.ts create mode 100644 src/app/[variants]/(main)/resource/(home)/_layout/style.ts create mode 100644 src/app/[variants]/(main)/resource/library/_layout/style.ts create mode 100644 src/app/[variants]/(main)/settings/_layout/style.ts create mode 100644 src/app/[variants]/(main)/settings/provider/_layout/Desktop/style.ts create mode 100644 src/app/[variants]/(mobile)/(home)/_layout/MobileLayout/style.ts create mode 100644 src/app/[variants]/(mobile)/(home)/_layout/SessionHeader/style.ts create mode 100644 src/app/[variants]/(mobile)/chat/_layout/style.ts create mode 100644 src/app/[variants]/(mobile)/community/(list)/_layout/style.ts create mode 100644 src/app/[variants]/onboarding/_layout/style.ts create mode 100644 src/features/ShareModal/useContainerStyles.ts diff --git a/.cursor/docs/createStaticStyles_migration_guide.md b/.cursor/docs/createStaticStyles_migration_guide.md new file mode 100644 index 0000000000..0cff4438ee --- /dev/null +++ b/.cursor/docs/createStaticStyles_migration_guide.md @@ -0,0 +1,959 @@ +# createStaticStyles 迁移指南 + +## 📖 概述 + +`createStaticStyles` 是 `antd-style` 提供的静态样式创建函数,相比 `createStyles`(hook 方案)具有零运行时开销的优势。样式在模块加载时计算一次,而不是每次组件渲染时计算。 + +## 🎯 适用场景 + +### ✅ 可以优化的场景 + +1. **纯静态样式**:不依赖运行时动态值 +2. **使用标准 token**:所有 token 都在 `cssVar.json` 中有对应项 +3. **简单的条件逻辑**:可以通过静态样式拆分处理 + +### ❌ 无法优化的场景 + +1. **JS 计算函数**:`readableColor()`, `chroma()`, `mix()`, `calc()` 中使用 token 数值 +2. **复杂的动态 props**:需要运行时计算的复杂逻辑 +3. **动态 prefixCls**:需要运行时传入的类名前缀(但可以硬编码为 `'ant'`) + +## 🔄 基本转换步骤 + +### 1. 样式文件转换 + +**之前(createStyles):** + +```typescript +import { createStyles } from 'antd-style'; + +export const useStyles = createStyles(({ css, token }) => { + return { + root: css` + color: ${token.colorText}; + font-size: ${token.fontSize}px; + `, + }; +}); +``` + +**之后(createStaticStyles):** + +```typescript +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => { + return { + root: css` + color: ${cssVar.colorText}; + font-size: ${cssVar.fontSize}; + `, + }; +}); +``` + +### 2. 组件文件转换 + +**之前:** + +```typescript +import { useStyles } from './style'; + +const Component = () => { + const { styles, cx } = useStyles(); + return
; +}; +``` + +**之后:** + +```typescript +import { cx } from 'antd-style'; +import { styles } from './style'; + +const Component = () => { + return
; +}; +``` + +## 🛠️ 常见场景处理 + +### 场景 1: Token 转换 + +**规则:** + +- `token.xxx` → `cssVar.xxx` +- 注意:`cssVar.fontSize` 已经包含 `px` 单位,不需要再加 `px` + +**示例:** + +```typescript +// ❌ 错误 +font-size: ${cssVar.fontSize}px; // cssVar.fontSize 已经是 "14px" + +// ✅ 正确 +font-size: ${cssVar.fontSize}; // 直接使用 +``` + +**特殊情况 - calc ():** + +```typescript +// ❌ 错误 +calc(${token.fontSize}px * 2.5) + +// ✅ 正确 +calc(${cssVar.fontSize} * 2.5) // cssVar.fontSize 已经包含单位 +``` + +### 场景 2: 动态 Props → CSS 变量 + +**适用:** 数值、字符串类型的 props + +**步骤:** + +1. 在样式文件中使用 CSS 变量(带默认值) +2. 在组件中通过 `style` prop 设置 CSS 变量 + +**示例:** + +**样式文件:** + +```typescript +export const styles = createStaticStyles(({ css }) => { + return { + root: css` + width: var(--component-size, 24px); + height: var(--component-size, 24px); + `, + }; +}); +``` + +**组件文件:** + +```typescript +import { useMemo } from 'react'; + +const Component = ({ size = 24, style, ...rest }) => { + const cssVariables = useMemo>( + () => ({ + '--component-size': `${size}px`, + }), + [size], + ); + + return ( +
+ ); +}; +``` + +**已优化示例:** + +- `Video`: `maxHeight`, `maxWidth`, `minHeight`, `minWidth` +- `ScrollShadow`: `size` +- `MaskShadow`: `size` +- `ColorSwatches`: `size` +- `Grid`: `rows`, `maxItemWidth`, `gap` +- `Layout`: `headerHeight` +- `Footer`: `contentMaxWidth` + +### 场景 3: 布尔值 Props → 静态样式拆分 + +**适用:** 简单的布尔值 props(2-3 个) + +**步骤:** + +1. 创建所有可能的组合样式 +2. 运行时使用 `cx` 组合 + +**示例:** + +**样式文件:** + +```typescript +export const styles = createStaticStyles(({ css }) => { + return { + root: css` + /* base styles */ + `, + root_closable_true: css` + /* closable styles */ + `, + root_closable_false: css` + /* no closable styles */ + `, + root_hasTitle_true: css` + /* has title styles */ + `, + root_hasTitle_false: css` + /* no title styles */ + `, + }; +}); +``` + +**组件文件:** + +```typescript +const Component = ({ closable, hasTitle }) => { + const className = cx( + styles.root, + styles[`root_closable_${!!closable}`], + styles[`root_hasTitle_${!!hasTitle}`], + ); + return
; +}; +``` + +**已优化示例:** + +- `Alert`: `closable`, `hasTitle`, `showIcon` → 8 个组合(2×2×2) +- `Image`: `alwaysShowActions` → 2 个样式 +- `StoryBook`: `noPadding` → 2 个样式 + +### 场景 4: isDarkMode → 静态样式拆分 + +**适用:** 依赖 `isDarkMode` 的条件样式 + +**有两种处理方式:** + +#### 方式 A: 直接条件选择(简单场景) + +**步骤:** + +1. 创建 `Dark` 和 `Light` 两个静态样式 +2. 运行时根据 `theme.isDarkMode` 选择 + +**示例:** + +**样式文件:** + +```typescript +export const styles = createStaticStyles(({ css, cssVar }) => { + return { + rootDark: css` + background: ${cssVar.colorFillTertiary}; + color: ${cssVar.colorTextLightSolid}; + `, + rootLight: css` + background: ${cssVar.colorFillQuaternary}; + color: ${cssVar.colorText}; + `, + }; +}); +``` + +**组件文件:** + +```typescript +import { useThemeMode } from 'antd-style'; + +const Component = () => { + const { isDarkMode } = useThemeMode(); + return ( +
+ ); +}; +``` + +#### 方式 B: 使用 cva 将 isDarkMode 作为 variant(推荐,适用于复杂场景) + +**步骤:** + +1. 创建 `Dark` 和 `Light` 两个静态样式 +2. 在 `cva` 中将 `isDarkMode` 作为 variant prop +3. 运行时直接传入 `isDarkMode` 值 + +**示例:** + +**样式文件:** + +```typescript +import { createStaticStyles } from 'antd-style'; +import { cva } from 'class-variance-authority'; + +export const styles = createStaticStyles(({ css, cssVar }) => { + return { + filledDark: css` + background: ${cssVar.colorFillTertiary}; + color: ${cssVar.colorTextLightSolid}; + `, + filledLight: css` + background: ${cssVar.colorFillQuaternary}; + color: ${cssVar.colorText}; + `, + outlined: css` + border: 1px solid ${cssVar.colorBorder}; + `, + root: css` + /* base styles */ + `, + }; +}); + +export const variants = cva(styles.root, { + defaultVariants: { + isDarkMode: false, + variant: 'filled', + }, + variants: { + isDarkMode: { + false: null, + true: null, // isDarkMode 本身不添加样式,通过 compoundVariants 组合 + }, + variant: { + filled: null, // variant 本身不添加样式,通过 compoundVariants 组合 + outlined: styles.outlined, + }, + }, + compoundVariants: [ + { + class: styles.filledDark, + isDarkMode: true, + variant: 'filled', + }, + { + class: styles.filledLight, + isDarkMode: false, + variant: 'filled', + }, + ], +}); +``` + +**组件文件:** + +```typescript +import { useThemeMode } from 'antd-style'; +import { variants } from './style'; + +const Component = ({ variant = 'filled' }) => { + const { isDarkMode } = useThemeMode(); + return ( +
+ ); +}; +``` + +**优势:** + +- ✅ 不需要 `useMemo` 动态创建 variants +- ✅ 更符合 `cva` 的设计理念 +- ✅ 代码更简洁,性能更好 +- ✅ 类型安全,IDE 自动补全 + +**已优化示例:** + +- `TypewriterEffect`: `textDark` / `textLight`(方式 A) +- `Collapse`: `filledDark` / `filledLight`(可优化为方式 B) +- `Hotkey`: `inverseThemeDark` / `inverseThemeLight`(可优化为方式 B) +- `GuideCard`: `filledDark` / `filledLight`(可优化为方式 B) +- `GradientButton`: `buttonDark` / `buttonLight`(方式 A) + +### 场景 5: responsive → 静态 responsive + +**适用:** 使用响应式断点 + +**步骤:** + +1. 导入静态 `responsive` from `antd-style` +2. 使用 `responsive.sm` 替代 `responsive.mobile` +3. 从 `createStyles` 参数中移除 `responsive` + +**示例:** + +**之前:** + +```typescript +import { createStyles } from 'antd-style'; + +export const useStyles = createStyles(({ css, responsive }) => ({ + root: css` + ${responsive.mobile} { + padding: 12px; + } + `, +})); +``` + +**之后:** + +```typescript +import { createStaticStyles } from 'antd-style'; +import { responsive } from 'antd-style'; + +export const styles = createStaticStyles(({ css }) => ({ + root: css` + ${responsive.sm} { + padding: 12px; + } + `, +})); +``` + +**注意:** + +- `responsive.mobile` → `responsive.sm` +- 静态 `responsive` 提供:`xs`, `sm`, `md`, `lg`, `xl`, `xxl` + +**已优化示例:** + +- `Header`: `responsive.mobile` → `responsive.sm` +- `FormModal`: `responsive.mobile` → `responsive.sm` +- `Hero`: `responsive.mobile` → `responsive.sm` + +### 场景 6: stylish → lobeStaticStylish + +**适用:** 使用自定义 `stylish` 工具 + +**步骤:** + +1. 导入 `lobeStaticStylish` from `@/styles` +2. 替换 `stylish.xxx` → `lobeStaticStylish.xxx` + +**示例:** + +**之前:** + +```typescript +import { createStyles } from 'antd-style'; + +export const useStyles = createStyles(({ css, stylish }) => ({ + root: css` + ${stylish.blur}; + ${stylish.variantFilled}; + `, +})); +``` + +**之后:** + +```typescript +import { createStaticStyles } from 'antd-style'; + +import { lobeStaticStylish } from '@/styles'; + +export const styles = createStaticStyles(({ css }) => ({ + root: css` + ${lobeStaticStylish.blur}; + ${lobeStaticStylish.variantFilled}; + `, +})); +``` + +**已优化示例:** + +- `Button`: `stylish.blur` → `lobeStaticStylish.blur` +- `Hero`: `stylish.gradientAnimation` → `lobeStaticStylish.gradientAnimation` + +### 场景 7: prefixCls → 硬编码 + +**适用:** 使用动态 `prefixCls` 参数 + +**步骤:** + +1. 在文件顶部硬编码 `const prefixCls = 'ant'` +2. 从 `createStyles` 参数中移除 `prefixCls` + +**示例:** + +**之前:** + +```typescript +export const useStyles = createStyles(({ css }, prefixCls: string) => ({ + root: css` + .${prefixCls}-button { + /* styles */ + } + `, +})); +``` + +**之后:** + +```typescript +const prefixCls = 'ant'; + +export const styles = createStaticStyles(({ css }) => ({ + root: css` + .${prefixCls}-button { + /* styles */ + } + `, +})); +``` + +**已优化示例:** + +- `Alert`, `Collapse`, `FormModal`, `Image`, `Burger`, `DraggablePanel`, `DraggableSideNav`, `Toc`, `ColorSwatches`, `EmojiPicker`, `Form`, `awesome/Features` + +### 场景 8: readableColor () → Token 替换 + +**适用:** 使用 `readableColor()` 计算对比色 + +**规则:** + +- `readableColor(token.colorPrimary)` → `cssVar.colorTextLightSolid`(主色背景用白色文字) +- `readableColor(token.colorTextQuaternary)` → `cssVar.colorText`(浅色背景用深色文字) + +**示例:** + +**之前:** + +```typescript +import { readableColor } from 'polished'; + +export const useStyles = createStyles(({ css, token }) => ({ + checked: css` + background-color: ${token.colorPrimary}; + color: ${readableColor(token.colorPrimary)}; + `, +})); +``` + +**之后:** + +```typescript +export const styles = createStaticStyles(({ css, cssVar }) => ({ + checked: css` + background-color: ${cssVar.colorPrimary}; + color: ${cssVar.colorTextLightSolid}; + `, +})); +``` + +**已优化示例:** + +- `Checkbox`: `readableColor(token.colorPrimary)` → `cssVar.colorTextLightSolid` + +### 场景 9: rgba () → color-mix () + +**适用:** 使用 `rgba()` 设置透明度 + +**步骤:** + +1. 使用 CSS 原生的 `color-mix()` 函数 +2. 格式:`color-mix(in srgb, ${cssVar.xxx} alpha%, transparent)` + +**示例:** + +**之前:** + +```typescript +import { rgba } from 'polished'; + +export const useStyles = createStyles(({ css, token }) => ({ + root: css` + background-color: ${rgba(token.colorBgLayout, 0.4)}; + `, +})); +``` + +**之后:** + +```typescript +export const styles = createStaticStyles(({ css, cssVar }) => ({ + root: css` + background-color: color-mix(in srgb, ${cssVar.colorBgLayout} 40%, transparent); + `, +})); +``` + +**已优化示例:** + +- `Header`: `rgba(cssVar.colorBgLayout, 0.4)` → `color-mix(...)` +- `FormModal`: `rgba(cssVar.colorBgContainer, 0)` → `color-mix(...)` + +### 场景 10: keyframes → css + +**适用:** 使用 `keyframes` 创建动画 + +**步骤:** + +1. 在 `createStaticStyles` 外部定义 `keyframes` +2. 在样式内部使用 + +**示例:** + +**之前:** + +```typescript +export const useStyles = createStyles(({ css, keyframes }) => { + const spin = keyframes` + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + `; + return { + icon: css` + animation: ${spin} 1s linear infinite; + `, + }; +}); +``` + +**之后:** + +```typescript +import { keyframes } from 'antd-style'; + +const spin = keyframes` + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +`; + +export const styles = createStaticStyles(({ css }) => ({ + icon: css` + animation: ${spin} 1s linear infinite; + `, +})); +``` + +**已优化示例:** + +- `Icon`: `keyframes` 动画 +- `Skeleton`: `keyframes` shimmer 动画 + +## ⚠️ 反模式:避免使用 createVariants (isDarkMode) + +**不推荐的做法:** + +```typescript +// ❌ 不推荐:在组件中动态创建 variants +export const createVariants = (isDarkMode: boolean) => + cva(styles.root, { + variants: { + variant: { + filled: isDarkMode ? styles.filledDark : styles.filledLight, + }, + }, + }); + +// 组件中 +const variants = useMemo(() => createVariants(isDarkMode), [isDarkMode]); +``` + +**推荐的做法:** + +将 `isDarkMode` 作为 `cva` 的 variant prop(见场景 4 方式 B),这样: + +- ✅ 不需要 `useMemo` 动态创建 +- ✅ 更符合 `cva` 的设计理念 +- ✅ 代码更简洁,性能更好 +- ✅ 类型安全,IDE 自动补全 + +```typescript +// ✅ 推荐:将 isDarkMode 作为 variant prop +export const variants = cva(styles.root, { + variants: { + isDarkMode: { + false: null, + true: null, + }, + variant: { + filled: null, + }, + }, + compoundVariants: [ + { + class: styles.filledDark, + isDarkMode: true, + variant: 'filled', + }, + { + class: styles.filledLight, + isDarkMode: false, + variant: 'filled', + }, + ], +}); + +// 组件中 +const { isDarkMode } = useThemeMode(); +const className = variants({ isDarkMode, variant: 'filled' }); +``` + +## ⚠️ 无法优化的场景 + +### 1. JS 计算函数 + +**无法优化:** + +- `chroma()` - 颜色计算库 +- `readableColor()` - 需要运行时计算(但可以用 token 替代) +- `mix()` - 颜色混合计算 +- `calc()` 中使用 token 数值进行复杂计算 + +**示例:** + +```typescript +// ❌ 无法优化 +const scale = chroma.bezier([token.colorText, backgroundColor]).scale().colors(6); +``` + +### 2. 复杂的动态 Props + +**无法优化:** + +- 需要复杂计算的 props +- 对象 / 数组类型的 props +- 函数类型的 props + +### 3. useTheme Hook + +**无法优化:** + +- 直接使用 `useTheme()` hook 获取运行时值 +- 例如:`awesome/Giscus/style.ts` 使用 `useTheme()` 获取主题值 + +## 📋 迁移检查清单 + +### 样式文件检查 + +- [ ] `createStyles` → `createStaticStyles` +- [ ] `token.xxx` → `cssVar.xxx` +- [ ] 移除 `px` 后缀(`cssVar` 已包含单位) +- [ ] `responsive.mobile` → `responsive.sm`(如果使用) +- [ ] `stylish.xxx` → `lobeStaticStylish.xxx`(如果使用) +- [ ] `rgba()` → `color-mix()`(如果使用) +- [ ] `readableColor()` → token 替换(如果使用) +- [ ] `prefixCls` 参数 → 硬编码 `const prefixCls = 'ant'`(如果使用) +- [ ] `isDarkMode` → 静态样式拆分(如果使用) +- [ ] 动态 props → CSS 变量(如果使用) + +### 组件文件检查 + +- [ ] `useStyles()` → `import { styles } from './style'` +- [ ] `import { cx } from 'antd-style'`(如果需要) +- [ ] `import { useTheme } from 'antd-style'`(如果需要 `theme.isDarkMode`) +- [ ] 动态 props → CSS 变量设置(如果使用) +- [ ] `isDarkMode` 条件 → `theme.isDarkMode` 判断(如果使用) + +## 🎯 优化优先级 + +### 高优先级(简单优化) + +1. ✅ 纯静态样式(无动态 props) +2. ✅ `isDarkMode` 拆分 +3. ✅ `responsive.mobile` → `responsive.sm` +4. ✅ `stylish` → `lobeStaticStylish` +5. ✅ `readableColor()` → token 替换 + +### 中优先级(需要转换) + +6. ✅ 简单的动态 props → CSS 变量(1-2 个) +7. ✅ 布尔值 props → 静态样式拆分(2-3 个) + +### 低优先级(复杂优化) + +8. ⚠️ 多个动态 props → CSS 变量(3+ 个) +9. ⚠️ 复杂的条件逻辑拆分 + +## 📚 参考示例 + +### 完整示例 1: 简单组件 + +**样式文件:** + +```typescript +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + root: css` + padding: ${cssVar.padding}; + color: ${cssVar.colorText}; + border-radius: ${cssVar.borderRadius}; + `, +})); +``` + +**组件文件:** + +```typescript +import { cx } from 'antd-style'; +import { styles } from './style'; + +const Component = ({ className }) => { + return
; +}; +``` + +### 完整示例 2: 带动态 Props + +**样式文件:** + +```typescript +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + root: css` + width: var(--component-size, 24px); + height: var(--component-size, 24px); + background: ${cssVar.colorBgContainer}; + `, +})); +``` + +**组件文件:** + +```typescript +import { cx } from 'antd-style'; +import { useMemo } from 'react'; +import { styles } from './style'; + +const Component = ({ size = 24, className, style, ...rest }) => { + const cssVariables = useMemo>( + () => ({ + '--component-size': `${size}px`, + }), + [size], + ); + + return ( +
+ ); +}; +``` + +### 完整示例 3: 带 isDarkMode + +**样式文件:** + +```typescript +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + rootDark: css` + background: ${cssVar.colorFillTertiary}; + color: ${cssVar.colorTextLightSolid}; + `, + rootLight: css` + background: ${cssVar.colorFillQuaternary}; + color: ${cssVar.colorText}; + `, +})); +``` + +**组件文件:** + +```typescript +import { cx, useTheme } from 'antd-style'; +import { styles } from './style'; + +const Component = ({ className }) => { + const { theme } = useTheme(); + return ( +
+ ); +}; +``` + +## 🔍 验证步骤 + +1. **类型检查:** `pnpm run type-check` +2. **运行时测试:** 确保视觉效果一致 +3. **性能验证:** 检查样式计算是否在模块加载时完成 + +## 📊 优化效果 + +- ✅ **零运行时开销**:样式在模块加载时计算一次 +- ✅ **减少重新渲染**:组件不再依赖样式 hook +- ✅ **更好的性能**:减少每次渲染的计算开销 +- ✅ **代码更简洁**:直接导入样式对象 + +## 🔧 场景 11: useTheme () → useThemeMode () /cssVar + +**适用:** 组件中只使用 `theme.isDarkMode` 或其他 token 值 + +**规则:** + +- 如果只使用 `theme.isDarkMode`,使用 `const { isDarkMode } = useThemeMode()` 替代 +- 如果使用其他 token(如 `theme.colorText`, `theme.borderRadius` 等),使用 `cssVar` 替代 +- `useThemeMode()` 比 `useTheme()` 更轻量,只返回 `isDarkMode` 值 + +**示例:** + +**之前:** + +```typescript +import { useTheme } from 'antd-style'; + +const Component = () => { + const theme = useTheme(); + return ( +
+ {theme.colorText} +
+ ); +}; +``` + +**之后:** + +```typescript +import { cssVar, useThemeMode } from 'antd-style'; + +const Component = () => { + const { isDarkMode } = useThemeMode(); + return ( +
+ {cssVar.colorText} +
+ ); +}; +``` + +**已优化示例:** + +- `AuroraBackground`, `Select`, `Input`, `Button`, `DatePicker`, `AutoComplete`, `InputNumber`, `InputPassword`, `InputOPT`, `TextArea`, `SpotlightCardItem`, `Spotlight`, `HotkeyInput` - 只使用 `isDarkMode` → `useThemeMode()` +- `Image`, `GradientButton`, `Empty`, `FileTypeIcon`, `FormSubmitFooter`, `CodeEditor`, `LobeChat`, `Drawer`, `Modal`, `Avatar`, `AvatarGroup`, `SkeletonAvatar`, `SkeletonButton`, `SkeletonTags`, `Callout`, `LobeHub`, `GridBackground`, `FolderIcon`, `FileIcon`, `TokenTag`, `ChatSendButton`, `AvatarUploader` - 使用 token → `cssVar` + +**无法优化的文件(需要保留 `useTheme()`):** + +- `useMermaid`, `useStreamMermaid`, `useHighlight`, `useStreamHighlight` - 需要完整的 theme 对象传给第三方库 +- `Alert`, `Tag`, `Menu`, `EmojiPicker` - 需要实际颜色值传给颜色计算函数 +- `SkeletonTitle`, `SkeletonTags` - 需要数值进行数学运算 +- `GridShowcase`, `GridBackground/demos` - 需要实际颜色值传给 `rgba()` 函数 +- `CustomFonts` - 需要实际字符串值进行字符串拼接 +- `Giscus/style.ts` - 需要实际颜色值传给 `readableColor()` 和 `rgba()` 函数(其他 token 已优化为 `cssVar`) + +**注意事项:** + +- `useThemeMode()` 只返回 `{ isDarkMode }`,不返回完整的 theme 对象 +- `cssVar` 的值是字符串(如 `"14px"`, `"#ffffff"`),可以直接在 JSX 中使用 +- 如果 token 需要用于数值计算(如 `Math.round(theme.fontSize * 1.5)`),需要保留 `useTheme()` + +## 🎉 总结 + +`createStaticStyles` 迁移是一个渐进式的优化过程。对于简单的静态样式,可以直接转换;对于复杂的动态场景,需要根据具体情况选择合适的优化策略。关键是要理解每种场景的处理方式,并灵活运用 CSS 变量、静态样式拆分等技术。 + +### useTheme () 优化总结 + +- ✅ **使用 `useThemeMode()`**:当组件只使用 `theme.isDarkMode` 时 +- ✅ **使用 `cssVar`**:当组件使用其他 token 值(颜色、尺寸等)时 +- ⚠️ **保留 `useTheme()`**:当 token 需要用于数值计算或传给第三方库时 diff --git a/package.json b/package.json index ccbcec1cec..df9882ba67 100644 --- a/package.json +++ b/package.json @@ -132,6 +132,8 @@ ] }, "overrides": { + "@lobehub/ui": "^4.3.11", + "antd-style": "^4.1.0", "stylelint-config-clean-order": "7.0.0" }, "dependencies": { @@ -195,15 +197,15 @@ "@lobechat/utils": "workspace:*", "@lobechat/web-crawler": "workspace:*", "@lobehub/analytics": "^1.6.0", - "@lobehub/charts": "^4.0.0", + "@lobehub/charts": "^4.0.2", "@lobehub/chat-plugin-sdk": "^1.32.4", "@lobehub/chat-plugins-gateway": "^1.9.0", "@lobehub/desktop-ipc-typings": "workspace:*", - "@lobehub/editor": "^3.1.1", - "@lobehub/icons": "^4.0.0", + "@lobehub/editor": "^3.2.1", + "@lobehub/icons": "^4.0.2", "@lobehub/market-sdk": "^0.25.0", - "@lobehub/tts": "^4.0.0", - "@lobehub/ui": "^4.3.1", + "@lobehub/tts": "^4.0.2", + "@lobehub/ui": "^4.3.11", "@modelcontextprotocol/sdk": "^1.25.1", "@neondatabase/serverless": "^1.0.2", "@next/third-parties": "^16.1.0", @@ -232,13 +234,14 @@ "@zumer/snapdom": "^1.9.14", "ahooks": "^3.9.6", "antd": "^6.1.1", - "antd-style": "^3.7.1", + "antd-style": "^4.1.0", "async-retry": "^1.3.3", "bcryptjs": "^3.0.3", "better-auth": "^1.4.7", "better-auth-harmony": "^1.2.5", "brotli-wasm": "^3.0.1", "chroma-js": "^3.2.0", + "class-variance-authority": "^0.7.1", "cmdk": "^1.1.1", "cookie": "^1.1.1", "countries-and-timezones": "^3.8.0", diff --git a/packages/builtin-tool-agent-builder/src/client/Render/UpdatePrompt.tsx b/packages/builtin-tool-agent-builder/src/client/Render/UpdatePrompt.tsx index 04563d1c14..41a6d5cc40 100644 --- a/packages/builtin-tool-agent-builder/src/client/Render/UpdatePrompt.tsx +++ b/packages/builtin-tool-agent-builder/src/client/Render/UpdatePrompt.tsx @@ -1,45 +1,47 @@ import { BuiltinRenderProps } from '@lobechat/types'; import { Flexbox } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles } from 'antd-style'; import { CheckCircle, FileText } from 'lucide-react'; import { memo } from 'react'; import type { UpdatePromptParams, UpdatePromptState } from '../../types'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ container: css` font-size: 13px; `, fileIcon: css` - color: ${token.colorTextTertiary}; + color: ${cssVar.colorTextTertiary}; `, promptCard: css` - background: ${token.colorFillTertiary}; - border-left: 3px solid ${token.colorSuccess}; - margin-left: 12px; + margin-inline-start: 12px; padding: 12px; + border-inline-start: 3px solid ${cssVar.colorSuccess}; + background: ${cssVar.colorFillTertiary}; `, promptContent: css` - color: ${token.colorText}; + overflow: auto; + + max-height: 200px; + margin-inline: -12px; + margin-inline-start: 20px; + padding-inline: 12px; + font-size: 13px; line-height: 1.6; - margin-left: 20px; - max-height: 200px; - overflow: auto; - white-space: pre-wrap; + color: ${cssVar.colorText}; word-break: break-word; - margin-inline: -12px; - padding-inline: 12px; + white-space: pre-wrap; `, promptLabel: css` - color: ${token.colorTextSecondary}; font-size: 12px; font-weight: 500; + color: ${cssVar.colorTextSecondary}; `, statusRow: css` - color: ${token.colorSuccess}; - margin-left: 9px; - margin-bottom: 6px; + margin-block-end: 6px; + margin-inline-start: 9px; + color: ${cssVar.colorSuccess}; `, statusText: css` font-weight: 500; @@ -49,7 +51,6 @@ const useStyles = createStyles(({ css, token }) => ({ const UpdatePrompt = memo>( ({ pluginState }) => { const { newPrompt } = pluginState || {}; - const { styles } = useStyles(); return ( diff --git a/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTask.tsx b/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTask.tsx index d1cd264bbf..7f8d04d6c8 100644 --- a/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTask.tsx +++ b/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTask.tsx @@ -1,9 +1,9 @@ 'use client'; import { BuiltinInterventionProps } from '@lobechat/types'; -import { Avatar, Flexbox , Tooltip } from '@lobehub/ui'; +import { Avatar, Flexbox, Tooltip } from '@lobehub/ui'; import { Input, InputNumber } from 'antd'; -import { createStyles } from 'antd-style'; +import { createStaticStyles } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { Clock } from 'lucide-react'; import { ChangeEvent, memo, useCallback, useEffect, useState } from 'react'; @@ -14,11 +14,11 @@ import { agentGroupSelectors } from '@/store/agentGroup/selectors'; import type { ExecuteTaskParams } from '../../types'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ agentCard: css` padding: 4px; - border-radius: ${token.borderRadius}px; - background: ${token.colorFillTertiary}; + border-radius: ${cssVar.borderRadius}; + background: ${cssVar.colorFillTertiary}; `, agentDescription: css` overflow: hidden; @@ -28,16 +28,16 @@ const useStyles = createStyles(({ css, token }) => ({ font-size: 12px; line-height: 1.4; - color: ${token.colorTextSecondary}; + color: ${cssVar.colorTextSecondary}; `, agentTitle: css` font-size: 14px; font-weight: 600; - color: ${token.colorText}; + color: ${cssVar.colorText}; `, container: css` padding-block: 12px; - border-radius: ${token.borderRadius}px; + border-radius: ${cssVar.borderRadius}; `, header: css` font-size: 14px; @@ -50,11 +50,11 @@ const useStyles = createStyles(({ css, token }) => ({ width: 32px; height: 32px; - border-radius: ${token.borderRadius}px; + border-radius: ${cssVar.borderRadius}; - color: ${token.colorPrimary}; + color: ${cssVar.colorPrimary}; - background: ${token.colorPrimaryBg}; + background: ${cssVar.colorPrimaryBg}; `, timeoutInput: css` width: 100px; @@ -70,7 +70,6 @@ const DEFAULT_TIMEOUT = 1_800_000; // 30 minutes */ const ExecuteTaskIntervention = memo>( ({ args, onArgsChange, registerBeforeApprove }) => { - const { styles } = useStyles(); const { t } = useTranslation('tool'); // Get agent info from store diff --git a/packages/builtin-tool-group-management/src/client/Render/ExecuteTask/index.tsx b/packages/builtin-tool-group-management/src/client/Render/ExecuteTask/index.tsx index 58018413a6..a6a2e76624 100644 --- a/packages/builtin-tool-group-management/src/client/Render/ExecuteTask/index.tsx +++ b/packages/builtin-tool-group-management/src/client/Render/ExecuteTask/index.tsx @@ -2,7 +2,7 @@ import { BuiltinRenderProps } from '@lobechat/types'; import { Avatar, Flexbox, Text } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles } from 'antd-style'; import { Clock } from 'lucide-react'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -12,23 +12,23 @@ import { agentGroupSelectors } from '@/store/agentGroup/selectors'; import type { ExecuteTaskParams, ExecuteTaskState } from '../../../types'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ agentTitle: css` - color: ${token.colorTextSecondary}; + color: ${cssVar.colorTextSecondary}; `, container: css` padding-block: 12px; - border-radius: ${token.borderRadius}px; + border-radius: ${cssVar.borderRadius}; `, taskContent: css` padding-block: 8px; padding-inline: 12px; - border-radius: ${token.borderRadius}px; - background: ${token.colorFillTertiary}; + border-radius: ${cssVar.borderRadius}; + background: ${cssVar.colorFillTertiary}; `, timeout: css` font-size: 12px; - color: ${token.colorTextTertiary}; + color: ${cssVar.colorTextTertiary}; `, })); @@ -38,7 +38,6 @@ const useStyles = createStyles(({ css, token }) => ({ */ const ExecuteTaskRender = memo>( ({ args }) => { - const { styles } = useStyles(); const { t } = useTranslation('tool'); // Get agent info from store diff --git a/packages/builtin-tool-gtd/src/client/Intervention/ClearTodos.tsx b/packages/builtin-tool-gtd/src/client/Intervention/ClearTodos.tsx index 38ed06c05d..c70c5ccdc3 100644 --- a/packages/builtin-tool-gtd/src/client/Intervention/ClearTodos.tsx +++ b/packages/builtin-tool-gtd/src/client/Intervention/ClearTodos.tsx @@ -3,29 +3,29 @@ import { BuiltinInterventionProps } from '@lobechat/types'; import { Flexbox } from '@lobehub/ui'; import { Radio, RadioChangeEvent } from 'antd'; -import { createStyles } from 'antd-style'; +import { createStaticStyles } from 'antd-style'; import { Trash2 } from 'lucide-react'; import { memo, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { ClearTodosParams } from '../../types'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ container: css` padding: 12px; - border-radius: ${token.borderRadius}px; - background: ${token.colorFillTertiary}; + border-radius: ${cssVar.borderRadius}; + background: ${cssVar.colorFillTertiary}; `, dangerText: css` font-size: 13px; - color: ${token.colorError}; + color: ${cssVar.colorError}; `, header: css` - color: ${token.colorWarning}; + color: ${cssVar.colorWarning}; `, label: css` font-size: 13px; - color: ${token.colorTextSecondary}; + color: ${cssVar.colorTextSecondary}; `, normalText: css` font-size: 13px; @@ -38,7 +38,6 @@ const useStyles = createStyles(({ css, token }) => ({ */ const ClearTodosIntervention = memo>( ({ args, onArgsChange }) => { - const { styles } = useStyles(); const { t } = useTranslation('tool'); const [mode, setMode] = useState(args?.mode || 'completed'); diff --git a/packages/builtin-tool-gtd/src/client/Render/TodoList.tsx b/packages/builtin-tool-gtd/src/client/Render/TodoList.tsx index 702db8f0bb..6c81453332 100644 --- a/packages/builtin-tool-gtd/src/client/Render/TodoList.tsx +++ b/packages/builtin-tool-gtd/src/client/Render/TodoList.tsx @@ -2,7 +2,7 @@ import { type BuiltinRenderProps } from '@lobechat/types'; import { Block, Checkbox } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cssVar } from 'antd-style'; import { memo } from 'react'; import type { TodoItem, TodoList as TodoListType } from '../../types'; @@ -12,19 +12,19 @@ export interface TodoListRenderState { } // Styles matching TodoItemRow in SortableTodoList -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ itemRow: css` width: 100%; padding-block: 10px; padding-inline: 12px; - border-block-end: 1px dashed ${token.colorBorderSecondary}; + border-block-end: 1px dashed ${cssVar.colorBorderSecondary}; &:last-child { border-block-end: none; } `, textChecked: css` - color: ${token.colorTextQuaternary}; + color: ${cssVar.colorTextQuaternary}; text-decoration: line-through; `, })); @@ -38,11 +38,9 @@ interface ReadOnlyTodoItemProps { * Read-only todo item row, matching the style of TodoItemRow in SortableTodoList */ const ReadOnlyTodoItem = memo(({ text, completed }) => { - const { styles, theme } = useStyles(); - return ( ({ +const styles = createStaticStyles(({ css }) => ({ addRow: css` padding-block: 10px; padding-inline: 12px; @@ -26,7 +26,6 @@ interface AddItemRowProps { } const AddItemRow = memo(({ placeholder, showDragHandle = true, className }) => { - const { styles, cx } = useStyles(); const { t } = useTranslation('tool'); const inputRef = useRef(null); const defaultPlaceholder = placeholder || t('lobe-gtd.addTodo.placeholder'); diff --git a/packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx b/packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx index 4d3ecdaf6a..98ce69588c 100644 --- a/packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx +++ b/packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx @@ -2,14 +2,14 @@ import { ActionIcon, Checkbox, Flexbox, SortableList } from '@lobehub/ui'; import { Input, InputRef } from 'antd'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cssVar, cx } from 'antd-style'; import { Trash2 } from 'lucide-react'; import { ChangeEvent, KeyboardEvent, memo, useCallback, useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { useTodoListStore } from './store'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ deleteIcon: css` flex-shrink: 0; opacity: 0; @@ -25,7 +25,7 @@ const useStyles = createStyles(({ css, token }) => ({ width: 100%; padding-block: 10px; padding-inline: 4px 12px; - border-block-end: 1px dashed ${token.colorBorderSecondary}; + border-block-end: 1px dashed ${cssVar.colorBorderSecondary}; &:hover { .drag-handle, @@ -35,7 +35,7 @@ const useStyles = createStyles(({ css, token }) => ({ } `, textChecked: css` - color: ${token.colorTextQuaternary}; + color: ${cssVar.colorTextQuaternary}; text-decoration: line-through; `, })); @@ -46,7 +46,6 @@ interface TodoItemRowProps { } const TodoItemRow = memo(({ id, placeholder }) => { - const { styles, cx, theme } = useStyles(); const { t } = useTranslation('tool'); const inputRef = useRef(null); const defaultPlaceholder = placeholder || t('lobe-gtd.todoItem.placeholder'); @@ -125,7 +124,7 @@ const TodoItemRow = memo(({ id, placeholder }) => { { - return { - cardBody: css` - padding-block: 12px 8px; - padding-inline: 16px; - `, - container: css` - overflow: hidden; +const styles = createStaticStyles(({ css, cssVar }) => ({ + cardBody: css` + padding-block: 12px 8px; + padding-inline: 16px; + `, + container: css` + overflow: hidden; - min-width: 360px; - max-width: 360px; - border: 1px solid ${token.colorBorderSecondary}; - border-radius: 12px; - `, - description: css` - margin-block: 0 4px !important; - color: ${token.colorTextTertiary}; - `, - footer: css` - padding-block: 8px; - padding-inline: 16px; - border-radius: 8px; + min-width: 360px; + max-width: 360px; + border: 1px solid ${cssVar.colorBorderSecondary}; + border-radius: 12px; + `, + description: css` + margin-block: 0 4px !important; + color: ${cssVar.colorTextTertiary}; + `, + footer: css` + padding-block: 8px; + padding-inline: 16px; + border-radius: 8px; - text-align: center; + text-align: center; - background-color: ${token.colorFillQuaternary}; - `, - footerText: css` - font-size: 12px !important; - color: ${token.colorTextTertiary} !important; - `, - icon: css` - color: ${token.colorTextSecondary}; - `, - preview: css` - overflow: hidden; + background-color: ${cssVar.colorFillQuaternary}; + `, + footerText: css` + font-size: 12px !important; + color: ${cssVar.colorTextTertiary} !important; + `, + icon: css` + color: ${cssVar.colorTextSecondary}; + `, + preview: css` + overflow: hidden; - max-height: 80px; - padding: 8px; - border-radius: 6px; + max-height: 80px; + padding: 8px; + border-radius: 6px; - font-family: ${token.fontFamilyCode}; - font-size: 12px; - line-height: 1.5; - color: ${token.colorTextSecondary}; - `, - title: css` - overflow: hidden; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 1; + font-family: ${cssVar.fontFamilyCode}; + font-size: 12px; + line-height: 1.5; + color: ${cssVar.colorTextSecondary}; + `, + title: css` + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; - margin-block-end: 0; - `, - titleRow: css` - color: ${token.colorText}; - `, - }; -}); + margin-block-end: 0; + `, + titleRow: css` + color: ${cssVar.colorText}; + `, +})); interface FileCardProps { FileIcon: ComponentType<{ fileName: string; size: number }>; @@ -77,8 +75,6 @@ interface FileCardProps { } const FileCard = memo(({ file, FileIcon, labels }) => { - const { styles } = useStyles(); - if (file.error) { return ( diff --git a/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx b/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx index 26f67f77aa..91dc917f49 100644 --- a/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx +++ b/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx @@ -2,9 +2,10 @@ import { FileSearchResult } from '@lobechat/types'; import { Center, Flexbox, Text, Tooltip } from '@lobehub/ui'; +import { cx, useThemeMode } from 'antd-style'; import { ComponentType, memo } from 'react'; -import { useStyles } from './style'; +import { styles } from './style'; export interface FileItemProps extends FileSearchResult { FileIcon: ComponentType<{ @@ -19,7 +20,7 @@ export interface FileItemProps extends FileSearchResult { const FileItem = memo( ({ fileId, fileName, relevanceScore, topChunks, FileIcon, isMobile, onFileClick }) => { - const { styles, cx } = useStyles(); + const { isDarkMode } = useThemeMode(); // Use the first chunk for preview const firstChunk = topChunks[0]; @@ -27,7 +28,11 @@ const FileItem = memo( return ( ({ +export const styles = createStaticStyles(({ css, cssVar }) => ({ badge: css` padding-block: 4px; padding-inline: 6px; @@ -9,9 +8,9 @@ export const useStyles = createStyles(({ css, token, isDarkMode }) => ({ font-size: 12px; line-height: 12px; - color: ${token.colorTextSecondary}; + color: ${cssVar.colorTextSecondary}; - background: ${token.colorFillSecondary}; + background: ${cssVar.colorFillSecondary}; `, container: css` @@ -23,16 +22,25 @@ export const useStyles = createStyles(({ css, token, isDarkMode }) => ({ padding-inline-end: 12px; border-radius: 8px; - color: ${token.colorText}; + color: ${cssVar.colorText}; - background: ${lighten(0.1, token.colorBgElevated)}; - box-shadow: ${token.boxShadowTertiary}; + background: color-mix(in srgb, ${cssVar.colorBgElevated} 90%, white); + box-shadow: ${cssVar.boxShadowTertiary}; transition: all 0.2s; &:hover { - background: ${isDarkMode ? lighten(0.15, token.colorBgElevated) : ''}; - box-shadow: ${token.boxShadowSecondary}; + box-shadow: ${cssVar.boxShadowSecondary}; + } + `, + containerDark: css` + &:hover { + background: color-mix(in srgb, ${cssVar.colorBgElevated} 85%, white); + } + `, + containerLight: css` + &:hover { + background: color-mix(in srgb, ${cssVar.colorBgElevated} 90%, white); } `, filename: css` diff --git a/packages/builtin-tool-notebook/src/client/Render/CreateDocument/DocumentCard.tsx b/packages/builtin-tool-notebook/src/client/Render/CreateDocument/DocumentCard.tsx index e0718b15c0..645fa3c5f3 100644 --- a/packages/builtin-tool-notebook/src/client/Render/CreateDocument/DocumentCard.tsx +++ b/packages/builtin-tool-notebook/src/client/Render/CreateDocument/DocumentCard.tsx @@ -1,7 +1,7 @@ 'use client'; import { Flexbox, Tag, Text } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles } from 'antd-style'; import { FileText, NotebookText } from 'lucide-react'; import { memo } from 'react'; @@ -9,54 +9,51 @@ import { useChatStore } from '@/store/chat'; import { NotebookDocument } from '../../../types'; -const useStyles = createStyles(({ token, css }) => { - return { - container: css` - cursor: pointer; +const styles = createStaticStyles(({ css, cssVar }) => ({ + container: css` + cursor: pointer; - overflow: hidden; + overflow: hidden; - width: 100%; - padding-block: 12px; - padding-inline: 12px; - border: 1px solid ${token.colorBorderSecondary}; - border-radius: 8px; + width: 100%; + padding-block: 12px; + padding-inline: 12px; + border: 1px solid ${cssVar.colorBorderSecondary}; + border-radius: 8px; - background: ${token.colorBgElevated}; + background: ${cssVar.colorBgElevated}; - &:hover { - background: ${token.colorFillSecondary}; - } - `, - description: css` - font-size: 12px; - line-height: 1.5; - color: ${token.colorTextSecondary}; - `, - icon: css` - color: ${token.colorPrimary}; - `, - title: css` - overflow: hidden; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 1; + &:hover { + background: ${cssVar.colorFillSecondary}; + } + `, + description: css` + font-size: 12px; + line-height: 1.5; + color: ${cssVar.colorTextSecondary}; + `, + icon: css` + color: ${cssVar.colorPrimary}; + `, + title: css` + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; - font-weight: 500; - color: ${token.colorText}; - `, - typeTag: css` - font-size: 11px; - `, - }; -}); + font-weight: 500; + color: ${cssVar.colorText}; + `, + typeTag: css` + font-size: 11px; + `, +})); interface DocumentCardProps { document: NotebookDocument; } const DocumentCard = memo(({ document }) => { - const { styles } = useStyles(); const openDocument = useChatStore((s) => s.openDocument); const handleClick = () => { diff --git a/packages/builtin-tool-page-agent/src/client/Inspector/EditTitle/index.tsx b/packages/builtin-tool-page-agent/src/client/Inspector/EditTitle/index.tsx index 8b8f5a4c8e..7ec9afbddc 100644 --- a/packages/builtin-tool-page-agent/src/client/Inspector/EditTitle/index.tsx +++ b/packages/builtin-tool-page-agent/src/client/Inspector/EditTitle/index.tsx @@ -1,18 +1,19 @@ 'use client'; import type { BuiltinInspectorProps } from '@lobechat/types'; -import { createStyles } from 'antd-style'; -import { rgba } from 'polished'; +import { createStaticStyles, cx } from 'antd-style'; import { memo } from 'react'; import { Trans, useTranslation } from 'react-i18next'; +import { shinyTextStyles } from '@/styles'; + import type { EditTitleArgs, EditTitleState } from '../../../types'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ highlight: css` padding-block-end: 1px; - color: ${token.colorText}; - background: linear-gradient(to top, ${token.gold3} 40%, transparent 40%); + color: ${cssVar.colorText}; + background: linear-gradient(to top, ${cssVar.gold3} 40%, transparent 40%); `, root: css` overflow: hidden; @@ -20,43 +21,18 @@ const useStyles = createStyles(({ css, token }) => ({ -webkit-box-orient: vertical; -webkit-line-clamp: 1; - color: ${token.colorTextSecondary}; - `, - shinyText: css` - color: ${rgba(token.colorText, 0.45)}; - - background: linear-gradient( - 120deg, - ${rgba(token.colorTextBase, 0)} 40%, - ${token.colorTextSecondary} 50%, - ${rgba(token.colorTextBase, 0)} 60% - ); - background-clip: text; - background-size: 200% 100%; - - animation: shine 1.5s linear infinite; - - @keyframes shine { - 0% { - background-position: 100%; - } - - 100% { - background-position: -100%; - } - } + color: ${cssVar.colorTextSecondary}; `, })); export const EditTitleInspector = memo>( ({ args, partialArgs, isArgumentsStreaming }) => { const { t } = useTranslation('plugin'); - const { styles, cx } = useStyles(); const title = args?.title || partialArgs?.title; return ( -
+
{title ? ( }} diff --git a/packages/builtin-tool-page-agent/src/client/Inspector/GetPageContent/index.tsx b/packages/builtin-tool-page-agent/src/client/Inspector/GetPageContent/index.tsx index 040cc5f64f..4d1e93ca74 100644 --- a/packages/builtin-tool-page-agent/src/client/Inspector/GetPageContent/index.tsx +++ b/packages/builtin-tool-page-agent/src/client/Inspector/GetPageContent/index.tsx @@ -1,52 +1,28 @@ 'use client'; import type { BuiltinInspectorProps } from '@lobechat/types'; -import { createStyles } from 'antd-style'; -import { rgba } from 'polished'; +import { createStaticStyles, cx } from 'antd-style'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; -const useStyles = createStyles(({ css, token }) => ({ +import { shinyTextStyles } from '@/styles'; + +const styles = createStaticStyles(({ css, cssVar }) => ({ root: css` overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; - color: ${token.colorTextDescription}; - `, - shinyText: css` - color: ${rgba(token.colorText, 0.45)}; - - background: linear-gradient( - 120deg, - ${rgba(token.colorTextBase, 0)} 40%, - ${token.colorTextSecondary} 50%, - ${rgba(token.colorTextBase, 0)} 60% - ); - background-clip: text; - background-size: 200% 100%; - - animation: shine 1.5s linear infinite; - - @keyframes shine { - 0% { - background-position: 100%; - } - - 100% { - background-position: -100%; - } - } + color: ${cssVar.colorTextDescription}; `, })); export const GetPageContentInspector = memo(({ isArgumentsStreaming }) => { const { t } = useTranslation('plugin'); - const { styles, cx } = useStyles(); return ( -
+
{t('builtins.lobe-page-agent.apiName.getPageContent')}
); diff --git a/packages/builtin-tool-page-agent/src/client/Inspector/InitPage/index.tsx b/packages/builtin-tool-page-agent/src/client/Inspector/InitPage/index.tsx index ceb21204f0..c98f031070 100644 --- a/packages/builtin-tool-page-agent/src/client/Inspector/InitPage/index.tsx +++ b/packages/builtin-tool-page-agent/src/client/Inspector/InitPage/index.tsx @@ -2,23 +2,24 @@ import type { BuiltinInspectorProps } from '@lobechat/types'; import { Icon } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cx } from 'antd-style'; import { Plus } from 'lucide-react'; -import { rgba } from 'polished'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; +import { shinyTextStyles } from '@/styles'; + import type { InitDocumentArgs, InitDocumentState } from '../../../types'; import { AnimatedNumber } from '../../components/AnimatedNumber'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ chars: css` - font-family: ${token.fontFamilyCode}; - color: ${token.colorTextDescription}; + font-family: ${cssVar.fontFamilyCode}; + color: ${cssVar.colorTextDescription}; `, lines: css` - font-family: ${token.fontFamilyCode}; - color: ${token.colorSuccess}; + font-family: ${cssVar.fontFamilyCode}; + color: ${cssVar.colorSuccess}; `, root: css` overflow: hidden; @@ -26,40 +27,15 @@ const useStyles = createStyles(({ css, token }) => ({ -webkit-box-orient: vertical; -webkit-line-clamp: 1; `, - shinyText: css` - color: ${rgba(token.colorText, 0.45)}; - - background: linear-gradient( - 120deg, - ${rgba(token.colorTextBase, 0)} 40%, - ${token.colorTextSecondary} 50%, - ${rgba(token.colorTextBase, 0)} 60% - ); - background-clip: text; - background-size: 200% 100%; - - animation: shine 1.5s linear infinite; - - @keyframes shine { - 0% { - background-position: 100%; - } - - 100% { - background-position: -100%; - } - } - `, title: css` margin-inline-end: 8px; - color: ${token.colorText}; + color: ${cssVar.colorText}; `, })); export const InitPageInspector = memo>( ({ args, partialArgs, isArgumentsStreaming, pluginState }) => { const { t } = useTranslation('plugin'); - const { styles, cx } = useStyles(); // Calculate lines and chars from markdown content const markdown = args?.markdown || partialArgs?.markdown || ''; @@ -73,14 +49,14 @@ export const InitPageInspector = memo +
{t('builtins.lobe-page-agent.apiName.initPage')}
); } return ( -
+
{t('builtins.lobe-page-agent.apiName.initPage.result')} diff --git a/packages/builtin-tool-page-agent/src/client/Inspector/ModifyNodes/index.tsx b/packages/builtin-tool-page-agent/src/client/Inspector/ModifyNodes/index.tsx index e0da71e121..e3d7fee383 100644 --- a/packages/builtin-tool-page-agent/src/client/Inspector/ModifyNodes/index.tsx +++ b/packages/builtin-tool-page-agent/src/client/Inspector/ModifyNodes/index.tsx @@ -2,26 +2,27 @@ import type { BuiltinInspectorProps } from '@lobechat/types'; import { Icon } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cx } from 'antd-style'; import { DiffIcon, Minus, Plus } from 'lucide-react'; -import { rgba } from 'polished'; import { type ReactNode, memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import { shinyTextStyles } from '@/styles'; + import type { ModifyNodesArgs, ModifyNodesState } from '../../../types'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ insert: css` - font-family: ${token.fontFamilyCode}; - color: ${token.colorSuccess}; + font-family: ${cssVar.fontFamilyCode}; + color: ${cssVar.colorSuccess}; `, modify: css` - font-family: ${token.fontFamilyCode}; - color: ${token.colorWarning}; + font-family: ${cssVar.fontFamilyCode}; + color: ${cssVar.colorWarning}; `, remove: css` - font-family: ${token.fontFamilyCode}; - color: ${token.colorError}; + font-family: ${cssVar.fontFamilyCode}; + color: ${cssVar.colorError}; `, root: css` overflow: hidden; @@ -31,42 +32,17 @@ const useStyles = createStyles(({ css, token }) => ({ `, separator: css` margin-inline: 2px; - color: ${token.colorTextQuaternary}; - `, - shinyText: css` - color: ${rgba(token.colorText, 0.45)}; - - background: linear-gradient( - 120deg, - ${rgba(token.colorTextBase, 0)} 40%, - ${token.colorTextSecondary} 50%, - ${rgba(token.colorTextBase, 0)} 60% - ); - background-clip: text; - background-size: 200% 100%; - - animation: shine 1.5s linear infinite; - - @keyframes shine { - 0% { - background-position: 100%; - } - - 100% { - background-position: -100%; - } - } + color: ${cssVar.colorTextQuaternary}; `, title: css` margin-inline-end: 8px; - color: ${token.colorText}; + color: ${cssVar.colorText}; `, })); export const ModifyNodesInspector = memo>( ({ args, partialArgs, isArgumentsStreaming }) => { const { t } = useTranslation('plugin'); - const { styles, cx } = useStyles(); // Count operations by type const counts = useMemo(() => { @@ -101,7 +77,7 @@ export const ModifyNodesInspector = memo +
{t('builtins.lobe-page-agent.apiName.modifyNodes.init')}
); @@ -135,7 +111,7 @@ export const ModifyNodesInspector = memo +
{t('builtins.lobe-page-agent.apiName.modifyNodes')} {statsParts.length > 0 && ( <> diff --git a/packages/builtin-tool-page-agent/src/client/Inspector/ReplaceText/index.tsx b/packages/builtin-tool-page-agent/src/client/Inspector/ReplaceText/index.tsx index 609fff0bd3..6026264069 100644 --- a/packages/builtin-tool-page-agent/src/client/Inspector/ReplaceText/index.tsx +++ b/packages/builtin-tool-page-agent/src/client/Inspector/ReplaceText/index.tsx @@ -2,27 +2,28 @@ import type { BuiltinInspectorProps } from '@lobechat/types'; import { Icon } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cx } from 'antd-style'; import { ArrowRight } from 'lucide-react'; -import { rgba } from 'polished'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; +import { shinyTextStyles } from '@/styles'; + import type { ReplaceTextArgs, ReplaceTextState } from '../../../types'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ arrow: css` margin-inline: 4px; - color: ${token.colorTextQuaternary}; + color: ${cssVar.colorTextQuaternary}; `, from: css` - color: ${token.colorTextSecondary}; + color: ${cssVar.colorTextSecondary}; text-decoration: line-through; `, highlight: css` padding-block-end: 1px; - color: ${token.colorText}; - background: linear-gradient(to top, ${token.gold3} 40%, transparent 40%); + color: ${cssVar.colorText}; + background: linear-gradient(to top, ${cssVar.gold3} 40%, transparent 40%); `, root: css` overflow: hidden; @@ -30,46 +31,21 @@ const useStyles = createStyles(({ css, token }) => ({ -webkit-box-orient: vertical; -webkit-line-clamp: 1; - color: ${token.colorTextSecondary}; - `, - shinyText: css` - color: ${rgba(token.colorText, 0.45)}; - - background: linear-gradient( - 120deg, - ${rgba(token.colorTextBase, 0)} 40%, - ${token.colorTextSecondary} 50%, - ${rgba(token.colorTextBase, 0)} 60% - ); - background-clip: text; - background-size: 200% 100%; - - animation: shine 1.5s linear infinite; - - @keyframes shine { - 0% { - background-position: 100%; - } - - 100% { - background-position: -100%; - } - } + color: ${cssVar.colorTextSecondary}; `, stats: css` - font-family: ${token.fontFamilyCode}; - color: ${token.colorTextSecondary}; + font-family: ${cssVar.fontFamilyCode}; + color: ${cssVar.colorTextSecondary}; `, title: css` margin-inline-end: 8px; - color: ${token.colorText}; + color: ${cssVar.colorText}; `, })); export const ReplaceTextInspector = memo>( ({ args, partialArgs, isArgumentsStreaming, pluginState }) => { const { t } = useTranslation('plugin'); - const { styles, cx } = useStyles(); const from = args?.searchText || partialArgs?.searchText; const to = args?.newText ?? partialArgs?.newText; @@ -77,7 +53,7 @@ export const ReplaceTextInspector = memo +
{t('builtins.lobe-page-agent.apiName.replaceText.init')}
); @@ -87,7 +63,7 @@ export const ReplaceTextInspector = memo +
{t('builtins.lobe-page-agent.apiName.replaceText')} {hasResult && ( <> diff --git a/src/app/[variants]/(auth)/_layout/index.tsx b/src/app/[variants]/(auth)/_layout/index.tsx index 62098ec0d9..c9d41fa044 100644 --- a/src/app/[variants]/(auth)/_layout/index.tsx +++ b/src/app/[variants]/(auth)/_layout/index.tsx @@ -2,33 +2,22 @@ import { Center, Flexbox, Text } from '@lobehub/ui'; import { Divider } from 'antd'; -import { useTheme } from 'antd-style'; -import { type PropsWithChildren, memo } from 'react'; +import { cx, useThemeMode } from 'antd-style'; +import type { FC, PropsWithChildren } from 'react'; import { ProductLogo } from '@/components/Branding'; import LangButton from '@/features/User/UserPanel/LangButton'; import ThemeButton from '@/features/User/UserPanel/ThemeButton'; -const AuthContainer = memo(({ children }: PropsWithChildren) => { - const theme = useTheme(); +import { styles } from './style'; + +const AuthContainer: FC = ({ children }) => { + const { isDarkMode } = useThemeMode(); return ( - + { - + @@ -62,7 +46,7 @@ const AuthContainer = memo(({ children }: PropsWithChildren) => { ); -}); +}; AuthContainer.displayName = 'AuthContainer'; diff --git a/src/app/[variants]/(auth)/_layout/style.ts b/src/app/[variants]/(auth)/_layout/style.ts new file mode 100644 index 0000000000..8580421276 --- /dev/null +++ b/src/app/[variants]/(auth)/_layout/style.ts @@ -0,0 +1,47 @@ +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + + +// Divider 样式 +divider: css` + height: 24px; + `, + + + + +// 内层容器 - 深色模式 +innerContainerDark: css` + position: relative; + + overflow: hidden; + + border: 1px solid ${cssVar.colorBorderSecondary}; + border-radius: ${cssVar.borderRadius}; + + background: ${cssVar.colorBgContainer}; + `, + + + + +// 内层容器 - 浅色模式 +innerContainerLight: css` + position: relative; + + overflow: hidden; + + border: 1px solid ${cssVar.colorBorder}; + border-radius: ${cssVar.borderRadius}; + + background: ${cssVar.colorBgContainer}; + `, + + + +// 外层容器 +outerContainer: css` + position: relative; + `, +})); diff --git a/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx b/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx index aa2287d9e9..836bc38b50 100644 --- a/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +++ b/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx @@ -5,7 +5,7 @@ import { DOCUMENTS_REFER_URL, PRIVACY_URL, TERMS_URL } from '@lobechat/const'; import { Button, Skeleton, Text } from '@lobehub/ui'; import { LobeHub } from '@lobehub/ui/brand'; import { Col, Flex, Row } from 'antd'; -import { createStyles } from 'antd-style'; +import { createStaticStyles } from 'antd-style'; import { AuthError } from 'next-auth'; import { signIn } from 'next-auth/react'; import { useRouter, useSearchParams } from 'next/navigation'; @@ -16,15 +16,15 @@ import BrandWatermark from '@/components/BrandWatermark'; import AuthIcons from '@/components/NextAuth/AuthIcons'; import { useUserStore } from '@/store/user'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ button: css` text-transform: capitalize; `, container: css` min-width: 360px; - border: 1px solid ${token.colorBorder}; - border-radius: ${token.borderRadiusLG}px; - background: ${token.colorBgContainer}; + border: 1px solid ${cssVar.colorBorder}; + border-radius: ${cssVar.borderRadiusLG}px; + background: ${cssVar.colorBgContainer}; `, contentCard: css` padding-block: 2.5rem; @@ -32,23 +32,23 @@ const useStyles = createStyles(({ css, token }) => ({ `, description: css` margin: 0; - color: ${token.colorTextSecondary}; + color: ${cssVar.colorTextSecondary}; `, footer: css` padding: 1rem; - border-block-start: 1px solid ${token.colorBorder}; + border-block-start: 1px solid ${cssVar.colorBorder}; border-radius: 0 0 8px 8px; - color: ${token.colorTextDescription}; + color: ${cssVar.colorTextDescription}; - background: ${token.colorBgElevated}; + background: ${cssVar.colorBgElevated}; `, text: css` text-align: center; `, title: css` margin: 0; - color: ${token.colorTextHeading}; + color: ${cssVar.colorTextHeading}; `, })); @@ -68,7 +68,6 @@ const BtnListLoading = memo(() => { * ref: https://authjs.dev/guides/pages/signin */ export default memo(() => { - const { styles } = useStyles(); const { t } = useTranslation('clerk'); const router = useRouter(); const [loadingProvider, setLoadingProvider] = useState(null); diff --git a/src/app/[variants]/(auth)/oauth/consent/[uid]/components/OAuthApplicationLogo.tsx b/src/app/[variants]/(auth)/oauth/consent/[uid]/components/OAuthApplicationLogo.tsx index 72f104eea8..2e9fafe655 100644 --- a/src/app/[variants]/(auth)/oauth/consent/[uid]/components/OAuthApplicationLogo.tsx +++ b/src/app/[variants]/(auth)/oauth/consent/[uid]/components/OAuthApplicationLogo.tsx @@ -1,11 +1,11 @@ import { Avatar, Center, Flexbox, FluentEmoji, Icon } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cssVar } from 'antd-style'; import { Link2Icon } from 'lucide-react'; import React, { memo } from 'react'; import { ProductLogo } from '@/components/Branding'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ connector: css` width: 40px; height: 40px; @@ -18,7 +18,7 @@ const useStyles = createStyles(({ css, token }) => ({ connectorLine: css` width: 24px; height: 1px; - background-color: ${token.colorBorderSecondary}; + background-color: ${cssVar.colorBorderSecondary}; @media (max-width: 768px) { width: 24px; @@ -35,7 +35,6 @@ interface OAuthApplicationLogoProps { const OAuthApplicationLogo = memo( ({ isFirstParty, clientDisplayName, logoUrl, size = 72 }) => { - const { styles, theme } = useStyles(); return isFirstParty ? ( ) : ( @@ -47,7 +46,7 @@ const OAuthApplicationLogo = memo( )}
- +
diff --git a/src/app/[variants]/(auth)/signin/SignInPasswordStep.tsx b/src/app/[variants]/(auth)/signin/SignInPasswordStep.tsx index 1a040b7f17..f60b9b256d 100644 --- a/src/app/[variants]/(auth)/signin/SignInPasswordStep.tsx +++ b/src/app/[variants]/(auth)/signin/SignInPasswordStep.tsx @@ -1,7 +1,7 @@ import { Button, Icon, InputPassword, Text } from '@lobehub/ui'; import { Form } from 'antd'; import type { FormInstance, InputRef } from 'antd'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import { ChevronLeft, ChevronRight, Lock } from 'lucide-react'; import { useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; @@ -25,7 +25,6 @@ export const SignInPasswordStep = ({ onForgotPassword, onSubmit, }: SignInPasswordStepProps) => { - const theme = useTheme(); const { t } = useTranslation('auth'); const passwordInputRef = useRef(null); @@ -90,7 +89,7 @@ export const SignInPasswordStep = ({ icon={ChevronRight} loading={loading} onClick={() => form.submit()} - style={{ color: theme.colorPrimary }} + style={{ color: cssVar.colorPrimary }} title={t('betterAuth.signin.submit')} variant={'filled'} /> diff --git a/src/app/[variants]/(main)/_layout/DesktopLayoutContainer.tsx b/src/app/[variants]/(main)/_layout/DesktopLayoutContainer.tsx index 308f4ad5ed..998ab6de1f 100644 --- a/src/app/[variants]/(main)/_layout/DesktopLayoutContainer.tsx +++ b/src/app/[variants]/(main)/_layout/DesktopLayoutContainer.tsx @@ -1,40 +1,50 @@ import { Flexbox } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; -import { type FC, type PropsWithChildren } from 'react'; +import { cssVar, useThemeMode } from 'antd-style'; +import { type FC, type PropsWithChildren, useMemo } from 'react'; import { isDesktop } from '@/const/version'; import { useGlobalStore } from '@/store/global'; import { systemStatusSelectors } from '@/store/global/selectors'; +import { styles } from './DesktopLayoutContainer/style'; + const DesktopLayoutContainer: FC = ({ children }) => { - const theme = useTheme(); + const { isDarkMode } = useThemeMode(); const [expand] = useGlobalStore((s) => [systemStatusSelectors.showLeftPanel(s)]); + // CSS 变量用于动态样式 + const outerCssVariables = useMemo>( + () => ({ + '--container-padding-left': expand ? '0px' : '8px', + '--container-padding-top': isDesktop ? '0px' : '8px', + }), + [expand, isDesktop], + ); + + const innerCssVariables = useMemo>(() => { + const borderRadius = + typeof window !== 'undefined' && (window.lobeEnv?.darwinMajorVersion ?? 0) >= 25 + ? '12px' + : cssVar.borderRadius; + + return { + '--container-border-color': isDarkMode ? cssVar.colorBorderSecondary : cssVar.colorBorder, + '--container-border-radius': borderRadius, + }; + }, [isDarkMode]); + return ( = 25 - ? 12 - : theme.borderRadius, - overflow: 'hidden', - position: 'relative', - }} + style={innerCssVariables} width={'100%'} > {children} diff --git a/src/app/[variants]/(main)/_layout/DesktopLayoutContainer/style.ts b/src/app/[variants]/(main)/_layout/DesktopLayoutContainer/style.ts new file mode 100644 index 0000000000..1fae59bb32 --- /dev/null +++ b/src/app/[variants]/(main)/_layout/DesktopLayoutContainer/style.ts @@ -0,0 +1,27 @@ +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + // 内层容器 + innerContainer: css` + position: relative; + + overflow: hidden; + + border: 1px solid var(--container-border-color, ${cssVar.colorBorder}); + border-radius: var(--container-border-radius, ${cssVar.borderRadius}); + + background: ${cssVar.colorBgContainer}; + `, + + // 外层容器 + outerContainer: css` + position: relative; + + overflow: hidden; + + padding-block-start: var(--container-padding-top, 8px); + padding-inline-start: var(--container-padding-left, 8px); + + background: ${cssVar.colorBgLayout}; + `, +})); diff --git a/src/app/[variants]/(main)/_layout/index.tsx b/src/app/[variants]/(main)/_layout/index.tsx index 197e2ba817..68047543b4 100644 --- a/src/app/[variants]/(main)/_layout/index.tsx +++ b/src/app/[variants]/(main)/_layout/index.tsx @@ -2,7 +2,7 @@ import { ENABLE_BUSINESS_FEATURES } from '@lobechat/business-const'; import { Flexbox } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; +import { cx } from 'antd-style'; import dynamic from 'next/dynamic'; import { type FC, Suspense } from 'react'; import { HotkeysProvider } from 'react-hotkeys-hook'; @@ -28,12 +28,12 @@ import DesktopHomeLayout from '../home/_layout'; import DesktopAutoOidcOnFirstOpen from './DesktopAutoOidcOnFirstOpen'; import DesktopLayoutContainer from './DesktopLayoutContainer'; import RegisterHotkeys from './RegisterHotkeys'; +import { styles } from './style'; const CloudBanner = dynamic(() => import('@/features/AlertBanner/CloudBanner')); const Layout: FC = () => { const { isPWA } = usePlatform(); - const theme = useTheme(); const { showCloudPromotion } = useServerConfigStore(featureFlagsSelectors); const { isChecking, loadingComponent } = useMainLayoutRenderingChecking(); @@ -51,6 +51,7 @@ const Layout: FC = () => { { : '100%' } horizontal - style={{ - borderTop: isPWA ? `1px solid ${theme.colorBorder}` : undefined, - position: 'relative', - }} width={'100%'} > diff --git a/src/app/[variants]/(main)/_layout/style.ts b/src/app/[variants]/(main)/_layout/style.ts new file mode 100644 index 0000000000..406deb46ef --- /dev/null +++ b/src/app/[variants]/(main)/_layout/style.ts @@ -0,0 +1,14 @@ +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + // 主容器 - 非 PWA 模式(无顶部边框) + mainContainer: css` + position: relative; + `, + + // 主容器 - PWA 模式(带顶部边框) + mainContainerPWA: css` + position: relative; + border-block-start: 1px solid ${cssVar.colorBorder}; + `, +})); diff --git a/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/index.tsx b/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/index.tsx index 88c4e2c552..61a0c4646e 100644 --- a/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/index.tsx +++ b/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/index.tsx @@ -1,5 +1,5 @@ import { ActionIcon, Dropdown, Flexbox, Icon, Skeleton, Tag } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import { MessageSquareDashed, Star } from 'lucide-react'; import { Suspense, memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -26,8 +26,6 @@ interface TopicItemProps { const TopicItem = memo(({ id, title, fav, active, threadId }) => { const { t } = useTranslation('topic'); - - const theme = useTheme(); const openTopicInNewWindow = useGlobalStore((s) => s.openTopicInNewWindow); const activeAgentId = useAgentStore((s) => s.activeAgentId); @@ -69,7 +67,9 @@ const TopicItem = memo(({ id, title, fav, active, threadId }) => return ( } + icon={ + + } loading={isLoading} onClick={handleClick} title={ @@ -78,7 +78,7 @@ const TopicItem = memo(({ id, title, fav, active, threadId }) => @@ -104,8 +104,8 @@ const TopicItem = memo(({ id, title, fav, active, threadId }) => disabled={editing} icon={ { e.stopPropagation(); diff --git a/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/index.tsx b/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/index.tsx index 1454db297d..abf0236ecb 100644 --- a/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/index.tsx +++ b/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/index.tsx @@ -1,6 +1,6 @@ import { Dropdown, Icon } from '@lobehub/ui'; import { TreeDownRightIcon } from '@lobehub/ui/icons'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import { memo, useCallback } from 'react'; import NavItem from '@/features/NavPanel/components/NavItem'; @@ -18,7 +18,6 @@ export interface ThreadItemProps { } const ThreadItem = memo(({ title, id }) => { - const theme = useTheme(); const [editing, activeThreadId] = useChatStore((s) => [ s.threadRenamingId === id, s.activeThreadId, @@ -57,7 +56,9 @@ const ThreadItem = memo(({ title, id }) => { actions={} active={active && !isInAgentSubRoute} disabled={editing} - icon={} + icon={ + + } onClick={handleClick} title={title} /> diff --git a/src/app/[variants]/(main)/chat/_layout/index.tsx b/src/app/[variants]/(main)/chat/_layout/index.tsx index ff4dea27b1..19b5fd79d1 100644 --- a/src/app/[variants]/(main)/chat/_layout/index.tsx +++ b/src/app/[variants]/(main)/chat/_layout/index.tsx @@ -1,5 +1,4 @@ import { Flexbox } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; import { type FC } from 'react'; import { Outlet } from 'react-router-dom'; @@ -10,23 +9,15 @@ import { useInitAgentConfig } from '@/hooks/useInitAgentConfig'; import RegisterHotkeys from './RegisterHotkeys'; import Sidebar from './Sidebar'; +import { styles } from './style'; const Layout: FC = () => { - const theme = useTheme(); useInitAgentConfig(); return ( <> - + {/* ↓ cloud slot ↓ */} diff --git a/src/app/[variants]/(main)/chat/_layout/style.ts b/src/app/[variants]/(main)/chat/_layout/style.ts new file mode 100644 index 0000000000..f668cde86b --- /dev/null +++ b/src/app/[variants]/(main)/chat/_layout/style.ts @@ -0,0 +1,10 @@ +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + // 主容器 + mainContainer: css` + position: relative; + overflow: hidden; + background: ${cssVar.colorBgContainer}; + `, +})); diff --git a/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/OpeningQuestions.tsx b/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/OpeningQuestions.tsx index 86060fd6e5..f90df17948 100644 --- a/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/OpeningQuestions.tsx +++ b/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/OpeningQuestions.tsx @@ -1,7 +1,7 @@ 'use client'; import { Block, Flexbox } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles , responsive } from 'antd-style'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -9,13 +9,13 @@ import { useConversationStore } from '@/features/Conversation'; // import { useSend } from '../../features/ChatInput/useSend'; -const useStyles = createStyles(({ css, token, responsive }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ card: css` padding-block: 8px; padding-inline: 16px; border-radius: 48px; - ${responsive.mobile} { + ${responsive.sm} { padding-block: 8px; padding-inline: 16px; } @@ -27,7 +27,7 @@ const useStyles = createStyles(({ css, token, responsive }) => ({ `, title: css` - color: ${token.colorTextDescription}; + color: ${cssVar.colorTextDescription}; `, })); @@ -40,8 +40,6 @@ const OpeningQuestions = memo(({ mobile, questions }) => const { t } = useTranslation('welcome'); const [sendMessage] = useConversationStore((s) => [s.sendMessage]); - const { styles } = useStyles(); - return (

{t('guide.questions.title')}

diff --git a/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/ToolAuthAlert.tsx b/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/ToolAuthAlert.tsx index b9055c4da4..17daeaf50c 100644 --- a/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/ToolAuthAlert.tsx +++ b/src/app/[variants]/(main)/chat/features/Conversation/AgentWelcome/ToolAuthAlert.tsx @@ -3,7 +3,7 @@ import { KLAVIS_SERVER_TYPES, type KlavisServerType } from '@lobechat/const'; import { Alert, Avatar, Button, Flexbox, Icon, Text } from '@lobehub/ui'; import { Divider } from 'antd'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { PlusIcon } from 'lucide-react'; import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; @@ -55,7 +55,6 @@ interface KlavisToolAuthItemProps { const KlavisToolAuthItem = memo(({ tool, onAuthComplete }) => { const { t } = useTranslation('chat'); - const theme = useTheme(); const [isConnecting, setIsConnecting] = useState(false); const [isWaitingAuth, setIsWaitingAuth] = useState(false); @@ -196,7 +195,7 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete if (typeof tool.icon === 'string') { return ; } - return ; + return ; }; const isLoading = isConnecting || isWaitingAuth; diff --git a/src/app/[variants]/(main)/chat/features/Conversation/Header/index.tsx b/src/app/[variants]/(main)/chat/features/Conversation/Header/index.tsx index dc0350b041..1c91add212 100644 --- a/src/app/[variants]/(main)/chat/features/Conversation/Header/index.tsx +++ b/src/app/[variants]/(main)/chat/features/Conversation/Header/index.tsx @@ -1,7 +1,7 @@ 'use client'; import { Flexbox } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import { memo } from 'react'; import NavHeader from '@/features/NavHeader'; @@ -12,16 +12,15 @@ import ShareButton from './ShareButton'; import Tags from './Tags'; const Header = memo(() => { - const theme = useTheme(); return ( + } right={ - + diff --git a/src/app/[variants]/(main)/chat/features/Portal/_layout/Mobile.tsx b/src/app/[variants]/(main)/chat/features/Portal/_layout/Mobile.tsx index 3427309b0c..9506ec10e5 100644 --- a/src/app/[variants]/(main)/chat/features/Portal/_layout/Mobile.tsx +++ b/src/app/[variants]/(main)/chat/features/Portal/_layout/Mobile.tsx @@ -1,21 +1,20 @@ 'use client'; import { Flexbox, Modal } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cx } from 'antd-style'; import { type ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import { PortalContent } from '@/features/Portal/router'; import { useChatStore } from '@/store/chat'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ container: css` - background: linear-gradient(${token.colorBgElevated}, ${token.colorBgContainer}) !important; + background: linear-gradient(${cssVar.colorBgElevated}, ${cssVar.colorBgContainer}) !important; `, })); const Layout = () => { - const { styles, cx } = useStyles(); const [showMobilePortal, isPortalThread, togglePortal] = useChatStore((s) => [ s.showPortal, !!s.portalThreadId, @@ -24,12 +23,7 @@ const Layout = () => { const { t } = useTranslation('portal'); const renderBody = (body: ReactNode) => ( - + ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ content: css` display: flex; flex-direction: column; @@ -25,17 +25,16 @@ const useStyles = createStyles(({ css, token }) => ({ drawer: css` z-index: 10; height: 100%; - background: ${token.colorBgContainer}; + background: ${cssVar.colorBgContainer}; `, panel: css` overflow: hidden; height: 100%; - background: ${token.colorBgContainer}; + background: ${cssVar.colorBgContainer}; `, })); const PortalPanel = memo(({ children }: PropsWithChildren) => { - const { styles } = useStyles(); const { md = true } = useResponsive(); const [showPortal, showToolUI, showArtifactUI, showThread] = useChatStore((s) => [ diff --git a/src/app/[variants]/(main)/chat/features/TelemetryNotification.tsx b/src/app/[variants]/(main)/chat/features/TelemetryNotification.tsx index 57b70a04fd..3b6d724f02 100644 --- a/src/app/[variants]/(main)/chat/features/TelemetryNotification.tsx +++ b/src/app/[variants]/(main)/chat/features/TelemetryNotification.tsx @@ -2,7 +2,7 @@ import { BRANDING_NAME } from '@lobechat/business-const'; import { Avatar, Button, Flexbox, Icon } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { createStaticStyles, cssVar } from 'antd-style'; import { LucideArrowUpRightFromSquare, TelescopeIcon } from 'lucide-react'; import Link from 'next/link'; import { memo } from 'react'; @@ -13,9 +13,9 @@ import { PRIVACY_URL } from '@/const/url'; import { useUserStore } from '@/store/user'; import { preferenceSelectors } from '@/store/user/selectors'; -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ desc: css` - color: ${token.colorTextSecondary}; + color: ${cssVar.colorTextSecondary}; `, title: css` font-size: 18px; @@ -24,8 +24,6 @@ const useStyles = createStyles(({ css, token }) => ({ })); const TelemetryNotification = memo<{ mobile?: boolean }>(({ mobile }) => { - const { styles, theme } = useStyles(); - const { t } = useTranslation('common'); const isPreferenceInit = useUserStore(preferenceSelectors.isPreferenceInit); @@ -46,8 +44,8 @@ const TelemetryNotification = memo<{ mobile?: boolean }>(({ mobile }) => { } - background={theme.geekblue1} - style={{ color: theme.geekblue7 }} + background={cssVar.geekblue1} + style={{ color: cssVar.geekblue7 }} /> diff --git a/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/AgentTool.tsx b/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/AgentTool.tsx index cbc51d5d5c..402ca70443 100644 --- a/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/AgentTool.tsx +++ b/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/AgentTool.tsx @@ -2,7 +2,7 @@ import { KLAVIS_SERVER_TYPES, type KlavisServerType } from '@lobechat/const'; import { Avatar, Button, Flexbox, Icon, type ItemType, Segmented } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { ArrowRight, PlusIcon, Store, ToyBrick } from 'lucide-react'; import Image from 'next/image'; @@ -36,8 +36,6 @@ type TabType = 'all' | 'installed'; * 对于 IconType 类型的 icon,使用 Icon 组件渲染,并根据主题设置填充色 */ const KlavisIcon = memo>(({ icon, label }) => { - const theme = useTheme(); - if (typeof icon === 'string') { return ( {label} @@ -45,15 +43,13 @@ const KlavisIcon = memo>(({ icon, label } // 使用主题色填充,在深色模式下自动适应 - return ; + return ; }); const AgentTool = memo(() => { const { t } = useTranslation('setting'); const config = useAgentStore(agentSelectors.currentAgentConfig, isEqual); - const theme = useTheme(); - // Plugin state management const plugins = config?.plugins || []; @@ -356,7 +352,7 @@ const AgentTool = memo(() => { icon={PlusIcon} loading={updating} size={'small'} - style={{ color: theme.colorTextSecondary }} + style={{ color: cssVar.colorTextSecondary }} type={'text'} > {t('tools.add', { defaultValue: 'Add' })} diff --git a/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/MentionList/MentionDropdown.tsx b/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/MentionList/MentionDropdown.tsx index 9a6d9f02e3..eade5c0263 100644 --- a/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/MentionList/MentionDropdown.tsx +++ b/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/MentionList/MentionDropdown.tsx @@ -1,6 +1,6 @@ import { type MenuRenderProps } from '@lobehub/editor/es/plugins/slash/react/type'; import { Flexbox } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import { type ReactNode, memo, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { type MentionListOption } from './types'; @@ -23,7 +23,6 @@ const getCursorPosition = (): { x: number; y: number } | null => { const MentionDropdown = memo( ({ activeKey, onSelect, open, options, setActiveKey }) => { - const theme = useTheme(); const activeItemRef = useRef(null); const [position, setPosition] = useState<{ x: number; y: number } | null>(null); @@ -51,10 +50,10 @@ const MentionDropdown = memo( return ( ( return (
); } @@ -93,14 +92,14 @@ const MentionDropdown = memo( paddingInline={12} ref={isActive ? activeItemRef : null} style={{ - background: isActive ? theme.colorFillSecondary : undefined, + background: isActive ? cssVar.colorFillSecondary : undefined, cursor: 'pointer', }} > {item.icon && {item?.icon as ReactNode}}
* 对于 IconType 类型的 icon,使用 Icon 组件渲染,并根据主题设置填充色 */ const KlavisIcon = memo>(({ icon, label }) => { - const theme = useTheme(); - if (typeof icon === 'string') { return {label}; } // 使用主题色填充,在深色模式下自动适应 - return ; + return ; }); const toolNameResolver = new ToolNameResolver(); diff --git a/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/PluginTag.tsx b/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/PluginTag.tsx index 16e756bb9f..5c15748b68 100644 --- a/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/PluginTag.tsx +++ b/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/PluginTag.tsx @@ -2,7 +2,7 @@ import { KLAVIS_SERVER_TYPES, type KlavisServerType } from '@lobechat/const'; import { Avatar, Icon, Tag } from '@lobehub/ui'; -import { createStyles, useTheme } from 'antd-style'; +import { createStaticStyles, cssVar, useThemeMode } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { AlertCircle, X } from 'lucide-react'; import Image from 'next/image'; @@ -23,29 +23,27 @@ import { * Klavis 服务器图标组件 */ const KlavisIcon = memo>(({ icon, label }) => { - const theme = useTheme(); - if (typeof icon === 'string') { return ( {label} ); } - return ; + return ; }); -const useStyles = createStyles(({ css, token }) => ({ +const styles = createStaticStyles(({ css, cssVar }) => ({ notInstalledTag: css` - border-color: ${token.colorWarningBorder}; - background: ${token.colorWarningBg}; + border-color: ${cssVar.colorWarningBorder}; + background: ${cssVar.colorWarningBg}; `, tag: css` height: 28px !important; - border-radius: ${token.borderRadiusSM}px !important; + border-radius: ${cssVar.borderRadiusSM} !important; `, warningIcon: css` flex-shrink: 0; - color: ${token.colorWarning}; + color: ${cssVar.colorWarning}; `, })); @@ -55,7 +53,7 @@ interface PluginTagProps { } const PluginTag = memo(({ pluginId, onRemove }) => { - const { styles, theme } = useStyles(); + const { isDarkMode } = useThemeMode(); const { t } = useTranslation('setting'); // Extract identifier @@ -167,7 +165,7 @@ const PluginTag = memo(({ pluginId, onRemove }) => { ? undefined : t('tools.notInstalledWarning', { defaultValue: 'This tool is not installed' }) } - variant={theme.isDarkMode ? 'filled' : 'outlined'} + variant={isDarkMode ? 'filled' : 'outlined'} > {!meta.isInstalled ? `${displayTitle} (${t('tools.notInstalled', { defaultValue: 'Not Installed' })})` diff --git a/src/app/[variants]/(main)/community/(detail)/_layout/Header.tsx b/src/app/[variants]/(main)/community/(detail)/_layout/Header.tsx index 8d3353d92a..b6c4302822 100644 --- a/src/app/[variants]/(main)/community/(detail)/_layout/Header.tsx +++ b/src/app/[variants]/(main)/community/(detail)/_layout/Header.tsx @@ -1,7 +1,7 @@ 'use client'; import { ActionIcon, Flexbox } from '@lobehub/ui'; -import { useTheme } from 'antd-style'; +import { cssVar } from 'antd-style'; import { ArrowLeft } from 'lucide-react'; import { memo } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; @@ -11,8 +11,9 @@ import StoreSearchBar from '@/app/[variants]/(main)/community/features/Search'; import UserAvatar from '@/app/[variants]/(main)/community/features/UserAvatar'; import NavHeader from '@/features/NavHeader'; +import { styles } from './Header/style'; + const Header = memo(() => { - const theme = useTheme(); const location = useLocation(); const navigate = useNavigate(); @@ -26,8 +27,13 @@ const Header = memo(() => { } }; + const cssVariables: Record = { + '--header-border-color': cssVar.colorBorderSecondary, + }; + return ( @@ -35,9 +41,7 @@ const Header = memo(() => { } right={} - style={{ - borderBottom: `1px solid ${theme.colorBorderSecondary}`, - }} + style={cssVariables} styles={{ left: { flex: 1 }, }} diff --git a/src/app/[variants]/(main)/community/(detail)/_layout/Header/style.ts b/src/app/[variants]/(main)/community/(detail)/_layout/Header/style.ts new file mode 100644 index 0000000000..f9704fe6a6 --- /dev/null +++ b/src/app/[variants]/(main)/community/(detail)/_layout/Header/style.ts @@ -0,0 +1,8 @@ +import { createStaticStyles } from 'antd-style'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + // Header 容器 + headerContainer: css` + border-block-end: 1px solid var(--header-border-color, ${cssVar.colorBorderSecondary}); + `, +})); diff --git a/src/app/[variants]/(main)/community/(detail)/_layout/index.tsx b/src/app/[variants]/(main)/community/(detail)/_layout/index.tsx index c1546787c0..8a577d39e7 100644 --- a/src/app/[variants]/(main)/community/(detail)/_layout/index.tsx +++ b/src/app/[variants]/(main)/community/(detail)/_layout/index.tsx @@ -9,6 +9,7 @@ import WideScreenContainer from '@/features/WideScreenContainer'; import { MAX_WIDTH, SCROLL_PARENT_ID } from '../../features/const'; import Header from './Header'; +import { styles } from './style'; /** * Desktop Discover Detail Layout @@ -18,21 +19,24 @@ const DesktopDiscoverDetailLayout = memo(() => { return ( <>
- + -
+