From 602a6a5f662591bde375b790ffa57ece9eb0e05d Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Sat, 8 Mar 2025 00:34:02 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20refactor(UI):=20Consolidate=20dr?= =?UTF-8?q?opdown=20styles=20and=20remove=20global=20styles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove global style components from MentionModelsButton and MCPToolsButton - Move dropdown styles to a centralized SCSS file - Refactor components to use styled-components for localized styling - Improve code organization and reduce redundant styling - Adjust table column widths in MCPSettings for better layout - Simplify dropdown rendering by removing unnecessary fragments --- src/renderer/src/assets/styles/ant.scss | 139 +++++++++++++ .../pages/home/Inputbar/MCPToolsButton.tsx | 186 +++++++----------- .../home/Inputbar/MentionModelsButton.tsx | 178 ++--------------- .../src/pages/settings/MCPSettings.tsx | 19 +- 4 files changed, 238 insertions(+), 284 deletions(-) diff --git a/src/renderer/src/assets/styles/ant.scss b/src/renderer/src/assets/styles/ant.scss index 81635257..bb4ac895 100644 --- a/src/renderer/src/assets/styles/ant.scss +++ b/src/renderer/src/assets/styles/ant.scss @@ -53,3 +53,142 @@ background-color: initial !important; } } + +.mention-models-dropdown { + &.ant-dropdown { + background: rgba(var(--color-base-rgb), 0.65) !important; + backdrop-filter: blur(35px) saturate(150%) !important; + animation-duration: 0.15s !important; + } + + /* 移动其他样式到 mention-models-dropdown 类下 */ + .ant-slide-up-enter .ant-dropdown-menu, + .ant-slide-up-appear .ant-dropdown-menu, + .ant-slide-up-leave .ant-dropdown-menu, + .ant-slide-up-enter-active .ant-dropdown-menu, + .ant-slide-up-appear-active .ant-dropdown-menu, + .ant-slide-up-leave-active .ant-dropdown-menu { + background: rgba(var(--color-base-rgb), 0.65) !important; + backdrop-filter: blur(35px) saturate(150%) !important; + } + + .ant-dropdown-menu { + /* 保持原有的下拉菜单样式,但限定在 mention-models-dropdown 类下 */ + max-height: 400px; + overflow-y: auto; + overflow-x: hidden; + padding: 4px 12px; + position: relative; + background: rgba(var(--color-base-rgb), 0.65) !important; + backdrop-filter: blur(35px) saturate(150%) !important; + border: 0.5px solid rgba(var(--color-border-rgb), 0.3); + border-radius: 10px; + box-shadow: + 0 0 0 0.5px rgba(0, 0, 0, 0.15), + 0 4px 16px rgba(0, 0, 0, 0.15), + 0 2px 8px rgba(0, 0, 0, 0.12), + inset 0 0 0 0.5px rgba(255, 255, 255, var(--inner-glow-opacity, 0.1)); + transform-origin: top; + will-change: transform, opacity; + transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1); + margin-bottom: 0; + + &.no-scrollbar { + padding-right: 12px; + } + + &.has-scrollbar { + padding-right: 2px; + } + + // Scrollbar styles + &::-webkit-scrollbar { + width: 14px; + height: 6px; + } + + &::-webkit-scrollbar-thumb { + border: 4px solid transparent; + background-clip: padding-box; + border-radius: 7px; + background-color: var(--color-scrollbar-thumb); + min-height: 50px; + transition: all 0.2s; + } + + &:hover::-webkit-scrollbar-thumb { + background-color: var(--color-scrollbar-thumb); + } + + &::-webkit-scrollbar-thumb:hover { + background-color: var(--color-scrollbar-thumb-hover); + } + + &::-webkit-scrollbar-thumb:active { + background-color: var(--color-scrollbar-thumb-hover); + } + + &::-webkit-scrollbar-track { + background: transparent; + border-radius: 7px; + } + } + + .ant-dropdown-menu-item-group { + margin-bottom: 4px; + + &:not(:first-child) { + margin-top: 4px; + } + + .ant-dropdown-menu-item-group-title { + padding: 5px 12px; + color: var(--color-text-3); + font-size: 12px; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.03em; + opacity: 0.7; + } + } + + // Handle no-results case margin + .no-results { + padding: 8px 12px; + color: var(--color-text-3); + cursor: default; + font-size: 13px; + opacity: 0.8; + margin-bottom: 40px; + + &:hover { + background: none; + } + } + + .ant-dropdown-menu-item { + padding: 5px 12px; + margin: 0 -12px; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + align-items: center; + gap: 8px; + border-radius: 6px; + font-size: 13px; + + &:hover { + background: rgba(var(--color-hover-rgb), 0.5); + } + + &.ant-dropdown-menu-item-selected { + background-color: rgba(var(--color-primary-rgb), 0.12); + color: var(--color-primary); + } + + .ant-dropdown-menu-item-icon { + margin-right: 0; + opacity: 0.9; + } + } +} diff --git a/src/renderer/src/pages/home/Inputbar/MCPToolsButton.tsx b/src/renderer/src/pages/home/Inputbar/MCPToolsButton.tsx index eaa7699c..a0d63d40 100644 --- a/src/renderer/src/pages/home/Inputbar/MCPToolsButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/MCPToolsButton.tsx @@ -3,7 +3,7 @@ import { MCPServer } from '@renderer/types' import { Dropdown, Switch, Tooltip } from 'antd' import { FC, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import { createGlobalStyle } from 'styled-components' +import styled from 'styled-components' interface Props { enabledMCPs: MCPServer[] @@ -43,7 +43,7 @@ const MCPToolsButton: FC = ({ enabledMCPs, onEnableMCP, ToolbarButton }) const menu = (
-
+

{t('settings.mcp.title')}

@@ -51,12 +51,12 @@ const MCPToolsButton: FC = ({ enabledMCPs, onEnableMCP, ToolbarButton })
-
+ {mcpServers.length > 0 ? ( mcpServers .filter((s) => s.isActive) .map((server) => ( -
+
{server.name}
{server.description && ( @@ -67,7 +67,7 @@ const MCPToolsButton: FC = ({ enabledMCPs, onEnableMCP, ToolbarButton }) {server.baseUrl &&
{server.baseUrl}
}
onEnableMCP(server)} /> -
+ )) ) : (
@@ -78,125 +78,81 @@ const MCPToolsButton: FC = ({ enabledMCPs, onEnableMCP, ToolbarButton }) ) return ( - <> - - menu} - trigger={['click']} - open={isOpen} - onOpenChange={setIsOpen} - overlayClassName="mention-models-dropdown"> - - - - - - - + menu} + trigger={['click']} + open={isOpen} + onOpenChange={setIsOpen} + overlayClassName="mention-models-dropdown"> + + + + + + ) } -const DropdownMenuStyle = createGlobalStyle` - .mention-models-dropdown { - .ant-dropdown-menu { - max-height: 400px; - overflow-y: auto; - overflow-x: hidden; - padding: 4px 0; - margin-bottom: 40px; - position: relative; +const McpServerItems = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 12px; - &::-webkit-scrollbar { - width: 6px; - height: 6px; - } + .server-info { + flex: 1; + overflow: hidden; - &::-webkit-scrollbar-thumb { - border-radius: 10px; - background: var(--color-scrollbar-thumb); + .server-name { + font-weight: 500; + font-size: 14px; + color: var(--color-text-1); + } - &:hover { - background: var(--color-scrollbar-thumb-hover); - } - } + .server-description { + font-size: 12px; + color: var(--color-text-3); + margin-top: 2px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } - &::-webkit-scrollbar-track { - background: transparent; - } + .server-url { + font-size: 11px; + color: var(--color-text-4); + margin-top: 2px; + } + } +` - .no-results { - padding: 8px 12px; - color: var(--color-text-3); - cursor: default; - font-size: 14px; - - &:hover { - background: none; - } - } +const DropdownHeader = styled.div` + padding: 8px 12px; + border-bottom: 1px solid var(--color-border); + margin-bottom: 4px; - .dropdown-header { - padding: 8px 12px; - border-bottom: 1px solid var(--color-border); - margin-bottom: 4px; - - .header-content { - display: flex; - justify-content: space-between; - align-items: center; - } - - h4 { - margin: 0; - color: var(--color-text-1); - font-size: 14px; - font-weight: 500; - } - - .enable-all-container { - display: flex; - align-items: center; - gap: 8px; - - .enable-all-label { - font-size: 12px; - color: var(--color-text-3); - } - } - } - - .mcp-server-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 12px; - - .server-info { - flex: 1; - overflow: hidden; - - .server-name { - font-weight: 500; - font-size: 14px; - color: var(--color-text-1); - } - - .server-description { - font-size: 12px; - color: var(--color-text-3); - margin-top: 2px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .server-url { - font-size: 11px; - color: var(--color-text-4); - margin-top: 2px; - } - } - } + .header-content { + display: flex; + justify-content: space-between; + align-items: center; + gap: 12px; + } + + h4 { + margin: 0; + color: var(--color-text-1); + font-size: 14px; + font-weight: 500; + } + + .enable-all-container { + display: flex; + align-items: center; + gap: 8px; + + .enable-all-label { + font-size: 12px; + color: var(--color-text-3); } } ` diff --git a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx index ba23c2a9..71eb504c 100644 --- a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx @@ -10,7 +10,7 @@ import { Avatar, Dropdown, Tooltip } from 'antd' import { first, sortBy } from 'lodash' import { FC, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import styled, { createGlobalStyle } from 'styled-components' +import styled from 'styled-components' interface Props { mentionModels: Model[] @@ -348,169 +348,25 @@ const MentionModelsButton: FC = ({ mentionModels, onMentionModel: onSelec ) return ( - <> - - menu} - trigger={['click']} - open={isOpen} - onOpenChange={(open) => { - setIsOpen(open) - open && setFromKeyboard(false) // Set fromKeyboard to false when opened by button click - }} - overlayClassName="mention-models-dropdown"> - - - - - - - + menu} + trigger={['click']} + open={isOpen} + onOpenChange={(open) => { + setIsOpen(open) + open && setFromKeyboard(false) // Set fromKeyboard to false when opened by button click + }} + overlayClassName="mention-models-dropdown"> + + + + + + ) } -const DropdownMenuStyle = createGlobalStyle` - /* 将样式限定在 mention-models-dropdown 类下 */ - .mention-models-dropdown { - &.ant-dropdown { - background: rgba(var(--color-base-rgb), 0.65) !important; - backdrop-filter: blur(35px) saturate(150%) !important; - animation-duration: 0.15s !important; - } - - /* 移动其他样式到 mention-models-dropdown 类下 */ - .ant-slide-up-enter .ant-dropdown-menu, - .ant-slide-up-appear .ant-dropdown-menu, - .ant-slide-up-leave .ant-dropdown-menu, - .ant-slide-up-enter-active .ant-dropdown-menu, - .ant-slide-up-appear-active .ant-dropdown-menu, - .ant-slide-up-leave-active .ant-dropdown-menu { - background: rgba(var(--color-base-rgb), 0.65) !important; - backdrop-filter: blur(35px) saturate(150%) !important; - } - - .ant-dropdown-menu { - /* 保持原有的下拉菜单样式,但限定在 mention-models-dropdown 类下 */ - max-height: 400px; - overflow-y: auto; - overflow-x: hidden; - padding: 4px 12px; - position: relative; - background: rgba(var(--color-base-rgb), 0.65) !important; - backdrop-filter: blur(35px) saturate(150%) !important; - border: 0.5px solid rgba(var(--color-border-rgb), 0.3); - border-radius: 10px; - box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.15), - 0 4px 16px rgba(0, 0, 0, 0.15), - 0 2px 8px rgba(0, 0, 0, 0.12), - inset 0 0 0 0.5px rgba(255, 255, 255, var(--inner-glow-opacity, 0.1)); - transform-origin: top; - will-change: transform, opacity; - transition: all 0.15s cubic-bezier(0.4, 0.0, 0.2, 1); - margin-bottom: 0; - - &.no-scrollbar { - padding-right: 12px; - } - - &.has-scrollbar { - padding-right: 2px; - } - - // Scrollbar styles - &::-webkit-scrollbar { - width: 14px; - height: 6px; - } - - &::-webkit-scrollbar-thumb { - border: 4px solid transparent; - background-clip: padding-box; - border-radius: 7px; - background-color: var(--color-scrollbar-thumb); - min-height: 50px; - transition: all 0.2s; - } - - &:hover::-webkit-scrollbar-thumb { - background-color: var(--color-scrollbar-thumb); - } - - &::-webkit-scrollbar-thumb:hover { - background-color: var(--color-scrollbar-thumb-hover); - } - - &::-webkit-scrollbar-thumb:active { - background-color: var(--color-scrollbar-thumb-hover); - } - - &::-webkit-scrollbar-track { - background: transparent; - border-radius: 7px; - } - } - - .ant-dropdown-menu-item-group { - margin-bottom: 4px; - - &:not(:first-child) { - margin-top: 4px; - } - - .ant-dropdown-menu-item-group-title { - padding: 5px 12px; - color: var(--color-text-3); - font-size: 12px; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.03em; - opacity: 0.7; - } - } - - // Handle no-results case margin - .no-results { - padding: 8px 12px; - color: var(--color-text-3); - cursor: default; - font-size: 13px; - opacity: 0.8; - margin-bottom: 40px; - - &:hover { - background: none; - } - } - - .ant-dropdown-menu-item { - padding: 5px 12px; - margin: 0 -12px; - cursor: pointer; - transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1); - display: flex; - align-items: center; - gap: 8px; - border-radius: 6px; - font-size: 13px; - - &:hover { - background: rgba(var(--color-hover-rgb), 0.5); - } - - &.ant-dropdown-menu-item-selected { - background-color: rgba(var(--color-primary-rgb), 0.12); - color: var(--color-primary); - } - - .ant-dropdown-menu-item-icon { - margin-right: 0; - opacity: 0.9; - } - } - } -` - const ModelItem = styled.div` display: flex; align-items: center; diff --git a/src/renderer/src/pages/settings/MCPSettings.tsx b/src/renderer/src/pages/settings/MCPSettings.tsx index 9e9bba71..31dec368 100644 --- a/src/renderer/src/pages/settings/MCPSettings.tsx +++ b/src/renderer/src/pages/settings/MCPSettings.tsx @@ -189,20 +189,20 @@ const MCPSettings: FC = () => { title: t('settings.mcp.name'), dataIndex: 'name', key: 'name', - width: '10%', + width: '300px', render: (text: string, record: MCPServer) => {text} }, { title: t('settings.mcp.type'), key: 'type', - width: '5%', + width: '100px', render: (_: any, record: MCPServer) => {record.baseUrl ? 'SSE' : 'STDIO'} }, { title: t('settings.mcp.description'), dataIndex: 'description', key: 'description', - width: '50%', + width: 'auto', render: (text: string) => { if (!text) { return ( @@ -231,7 +231,7 @@ const MCPSettings: FC = () => { title: t('settings.mcp.active'), dataIndex: 'isActive', key: 'isActive', - width: '5%', + width: '100px', render: (isActive: boolean, record: MCPServer) => ( handleToggleActive(record.name, checked)} /> ) @@ -239,7 +239,7 @@ const MCPSettings: FC = () => { { title: t('settings.mcp.actions'), key: 'actions', - width: '10%', + width: '100px', render: (_: any, record: MCPServer) => ( @@ -283,7 +283,10 @@ const MCPSettings: FC = () => {
- + { -