feat(UI): Enhance ListItem and DataSettings with icons and styling improvements

- Add titleStyle prop to ListItem for custom text styling
- Reduce gap in ListItem and MenuList components
- Integrate icons for DataSettings menu items
- Add Notion icon to iconfont
- Improve visual hierarchy and spacing in settings navigation
This commit is contained in:
kangfenmao 2025-03-12 09:42:19 +08:00
parent f5d3c07161
commit ee653b1032
5 changed files with 42 additions and 26 deletions

View File

@ -1,6 +1,6 @@
@font-face {
font-family: 'iconfont'; /* Project id 4753420 */
src: url('iconfont.woff2?t=1738750230250') format('woff2');
src: url('iconfont.woff2?t=1741743579060') format('woff2');
}
.iconfont {
@ -11,6 +11,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-notion:before {
content: '\e690';
}
.icon-thinking:before {
content: '\e65b';
}
@ -19,10 +23,6 @@
content: '\e623';
}
.icon-mcp:before {
content: '\e78e';
}
.icon-icon-adaptive-width:before {
content: '\e87a';
}
@ -31,10 +31,6 @@
content: '\e630';
}
.icon-a-darkmode:before {
content: '\e6cd';
}
.icon-ai-model:before {
content: '\e827';
}

View File

@ -6,16 +6,17 @@ interface ListItemProps {
icon?: ReactNode
title: string
subtitle?: string
titleStyle?: React.CSSProperties
onClick?: () => void
}
const ListItem = ({ active, icon, title, subtitle, onClick }: ListItemProps) => {
const ListItem = ({ active, icon, title, subtitle, titleStyle, onClick }: ListItemProps) => {
return (
<ListItemContainer className={active ? 'active' : ''} onClick={onClick}>
<ListItemContent>
{icon && <IconWrapper>{icon}</IconWrapper>}
<TextContainer>
<TitleText>{title}</TitleText>
<TitleText style={titleStyle}>{title}</TitleText>
{subtitle && <SubtitleText>{subtitle}</SubtitleText>}
</TextContainer>
</ListItemContent>
@ -48,7 +49,7 @@ const ListItemContainer = styled.div`
const ListItemContent = styled.div`
display: flex;
align-items: center;
gap: 8px;
gap: 5px;
overflow: hidden;
font-size: 13px;
`

View File

@ -104,21 +104,21 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
const assistantMessages = findAssistantMessages()
if (userMessages.length === 0 && assistantMessages.length === 0) {
window.message.info({ content: t('chat.navigation.last'), key: 'navigation-info' })
// window.message.info({ content: t('chat.navigation.last'), key: 'navigation-info' })
return scrollToBottom()
}
const visibleIndex = getCurrentVisibleIndex('down')
if (visibleIndex === -1) {
window.message.info({ content: t('chat.navigation.last'), key: 'navigation-info' })
// window.message.info({ content: t('chat.navigation.last'), key: 'navigation-info' })
return scrollToBottom()
}
const targetIndex = visibleIndex - 1
if (targetIndex < 0) {
window.message.info({ content: t('chat.navigation.last'), key: 'navigation-info' })
// window.message.info({ content: t('chat.navigation.last'), key: 'navigation-info' })
return scrollToBottom()
}
@ -130,21 +130,21 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
const userMessages = findUserMessages()
const assistantMessages = findAssistantMessages()
if (userMessages.length === 0 && assistantMessages.length === 0) {
window.message.info({ content: t('chat.navigation.first'), key: 'navigation-info' })
// window.message.info({ content: t('chat.navigation.first'), key: 'navigation-info' })
return scrollToTop()
}
const visibleIndex = getCurrentVisibleIndex('up')
if (visibleIndex === -1) {
window.message.info({ content: t('chat.navigation.first'), key: 'navigation-info' })
// window.message.info({ content: t('chat.navigation.first'), key: 'navigation-info' })
return scrollToTop()
}
const targetIndex = visibleIndex + 1
if (targetIndex >= userMessages.length) {
window.message.info({ content: t('chat.navigation.first'), key: 'navigation-info' })
// window.message.info({ content: t('chat.navigation.first'), key: 'navigation-info' })
return scrollToTop()
}

View File

@ -1,4 +1,12 @@
import { FileSearchOutlined, FolderOpenOutlined, SaveOutlined } from '@ant-design/icons'
import {
CloudSyncOutlined,
DatabaseOutlined,
FileMarkdownOutlined,
FileSearchOutlined,
FolderOpenOutlined,
SaveOutlined,
YuqueOutlined
} from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import ListItem from '@renderer/components/ListItem'
import BackupPopup from '@renderer/components/Popups/BackupPopup'
@ -27,11 +35,15 @@ const DataSettings: FC = () => {
const [menu, setMenu] = useState<string>('data')
const menuItems = [
{ key: 'data', title: 'settings.data.data.title' },
{ key: 'webdav', title: 'settings.data.webdav.title' },
{ key: 'markdown_export', title: 'settings.data.markdown_export.title' },
{ key: 'notion', title: 'settings.data.notion.title' },
{ key: 'yuque', title: 'settings.data.yuque.title' }
{ key: 'data', title: 'settings.data.data.title', icon: <DatabaseOutlined style={{ fontSize: 16 }} /> },
{ key: 'webdav', title: 'settings.data.webdav.title', icon: <CloudSyncOutlined style={{ fontSize: 16 }} /> },
{
key: 'markdown_export',
title: 'settings.data.markdown_export.title',
icon: <FileMarkdownOutlined style={{ fontSize: 16 }} />
},
{ key: 'notion', title: 'settings.data.notion.title', icon: <i className="iconfont icon-notion" /> },
{ key: 'yuque', title: 'settings.data.yuque.title', icon: <YuqueOutlined style={{ fontSize: 16 }} /> }
]
useEffect(() => {
@ -88,7 +100,14 @@ const DataSettings: FC = () => {
<Container>
<MenuList>
{menuItems.map((item) => (
<ListItem key={item.key} title={t(item.title)} active={menu === item.key} onClick={() => setMenu(item.key)} />
<ListItem
key={item.key}
title={t(item.title)}
active={menu === item.key}
onClick={() => setMenu(item.key)}
titleStyle={{ fontWeight: 500 }}
icon={item.icon}
/>
))}
</MenuList>
<SettingContainer theme={theme} style={{ display: 'flex', flex: 1 }}>
@ -183,7 +202,7 @@ const StyledIcon = styled(FileSearchOutlined)`
const MenuList = styled.div`
display: flex;
flex-direction: column;
gap: 10px;
gap: 5px;
width: var(--settings-width);
padding: 12px;
border-right: 0.5px solid var(--color-border);