mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-04 03:40:33 +08:00
fix: add responsive design for sidebar tabs to prevent content cutoff (#9913)
* fix: add responsive design for sidebar tabs to prevent content cutoff at minimum width - Add responsive CSS variables and media queries for narrow screens - Update Container, AssistantItem, and TopicListItem to use responsive widths - Ensures settings tab content remains visible at minimum window width (520px) - Addresses issue where right sidebar content gets cut off on smaller screens Fixes #9894 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Pleasure1234 <Pleasurecruise@users.noreply.github.com> * fix(i18n): Auto update translations for PR #9913 * feat(样式): 添加响应式断点配置和媒体查询工具 添加 breakpoints.scss 文件定义断点变量和 CSS 变量 在 style.ts 中新增 breakpoints 配置和 media 工具函数,用于生成响应式媒体查询 * style: 添加 breakpoints.scss 到主样式文件 * style(styles): 添加响应式断点变量并更新引用 将 breakpoints.scss 重命名为 responsive.scss 并添加断点变量定义 更新 index.scss 中的引用以使用新的文件名 * style(color.scss): 移除未使用的窄屏幕助手宽度变量 * refactor(styles): 将布局变量从color.scss移动到responsive.scss并添加响应式设计 将布局相关的CSS变量从color.scss迁移到responsive.scss以更好地组织代码 添加针对大屏幕的响应式布局调整 * refactor(布局): 简化容器宽度设置并添加过渡动画 移除响应式宽度媒体查询,统一使用变量控制宽度 为容器和标签内容添加宽度过渡动画效果 调整导航栏图标顺序和样式 * style: 移除响应式宽度媒体查询以简化样式 * fix(style): 将媒体查询条件从min-width改为max-width * refactor(style): 移除未使用的响应式样式工具代码 清理不再使用的断点常量和媒体查询工具函数,这些代码当前未被项目使用 --------- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: Pleasure1234 <Pleasurecruise@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
8b7776b545
commit
c4e22a23ea
@ -58,16 +58,6 @@
|
|||||||
--navbar-background-mac: rgba(20, 20, 20, 0.55);
|
--navbar-background-mac: rgba(20, 20, 20, 0.55);
|
||||||
--navbar-background: #1f1f1f;
|
--navbar-background: #1f1f1f;
|
||||||
|
|
||||||
--navbar-height: 44px;
|
|
||||||
--sidebar-width: 50px;
|
|
||||||
--status-bar-height: 40px;
|
|
||||||
--input-bar-height: 100px;
|
|
||||||
|
|
||||||
--assistants-width: 275px;
|
|
||||||
--topic-list-width: 275px;
|
|
||||||
--settings-width: 250px;
|
|
||||||
--scrollbar-width: 5px;
|
|
||||||
|
|
||||||
--chat-background: transparent;
|
--chat-background: transparent;
|
||||||
--chat-background-user: rgba(255, 255, 255, 0.08);
|
--chat-background-user: rgba(255, 255, 255, 0.08);
|
||||||
--chat-background-assistant: transparent;
|
--chat-background-assistant: transparent;
|
||||||
@ -146,11 +136,6 @@
|
|||||||
--chat-text-user: var(--color-text);
|
--chat-text-user: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
[navbar-position='left'] {
|
|
||||||
--navbar-height: 42px;
|
|
||||||
--list-item-border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
[navbar-position='left'][theme-mode='light'] {
|
[navbar-position='left'][theme-mode='light'] {
|
||||||
--color-list-item: #eee;
|
--color-list-item: #eee;
|
||||||
--color-list-item-hover: #f5f5f5;
|
--color-list-item-hover: #f5f5f5;
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
@use './container.scss';
|
@use './container.scss';
|
||||||
@use './animation.scss';
|
@use './animation.scss';
|
||||||
@use './richtext.scss';
|
@use './richtext.scss';
|
||||||
|
@use './responsive.scss';
|
||||||
@import '../fonts/icon-fonts/iconfont.css';
|
@import '../fonts/icon-fonts/iconfont.css';
|
||||||
@import '../fonts/ubuntu/ubuntu.css';
|
@import '../fonts/ubuntu/ubuntu.css';
|
||||||
@import '../fonts/country-flag-fonts/flag.css';
|
@import '../fonts/country-flag-fonts/flag.css';
|
||||||
|
|||||||
27
src/renderer/src/assets/styles/responsive.scss
Normal file
27
src/renderer/src/assets/styles/responsive.scss
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// xl, xxl, default style
|
||||||
|
:root {
|
||||||
|
--navbar-height: 44px;
|
||||||
|
--sidebar-width: 50px;
|
||||||
|
--status-bar-height: 40px;
|
||||||
|
--input-bar-height: 100px;
|
||||||
|
|
||||||
|
--assistants-width: 275px;
|
||||||
|
--topic-list-width: 275px;
|
||||||
|
--settings-width: 250px;
|
||||||
|
|
||||||
|
--scrollbar-width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
[navbar-position='left'] {
|
||||||
|
--navbar-height: 42px;
|
||||||
|
--list-item-border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lg
|
||||||
|
@media (max-width: 1080px) {
|
||||||
|
:root {
|
||||||
|
--assistants-width: 210px;
|
||||||
|
--topic-list-width: 210px;
|
||||||
|
--settings-width: 210px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -98,16 +98,16 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveAssistant, activeTo
|
|||||||
</HStack>
|
</HStack>
|
||||||
<HStack alignItems="center" gap={8}>
|
<HStack alignItems="center" gap={8}>
|
||||||
<UpdateAppButton />
|
<UpdateAppButton />
|
||||||
<Tooltip title={t('chat.assistant.search.placeholder')} mouseEnterDelay={0.8}>
|
|
||||||
<NarrowIcon onClick={() => SearchPopup.show()}>
|
|
||||||
<Search size={18} />
|
|
||||||
</NarrowIcon>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title={t('navbar.expand')} mouseEnterDelay={0.8}>
|
<Tooltip title={t('navbar.expand')} mouseEnterDelay={0.8}>
|
||||||
<NarrowIcon onClick={handleNarrowModeToggle}>
|
<NarrowIcon onClick={handleNarrowModeToggle}>
|
||||||
<i className="iconfont icon-icon-adaptive-width"></i>
|
<i className="iconfont icon-icon-adaptive-width"></i>
|
||||||
</NarrowIcon>
|
</NarrowIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip title={t('chat.assistant.search.placeholder')} mouseEnterDelay={0.8}>
|
||||||
|
<NavbarIcon onClick={() => SearchPopup.show()}>
|
||||||
|
<Search size={18} />
|
||||||
|
</NavbarIcon>
|
||||||
|
</Tooltip>
|
||||||
{topicPosition === 'right' && !showTopics && (
|
{topicPosition === 'right' && !showTopics && (
|
||||||
<Tooltip title={t('navbar.show_sidebar')} mouseEnterDelay={2}>
|
<Tooltip title={t('navbar.show_sidebar')} mouseEnterDelay={2}>
|
||||||
<NavbarIcon onClick={toggleShowTopics}>
|
<NavbarIcon onClick={toggleShowTopics}>
|
||||||
|
|||||||
@ -389,6 +389,7 @@ const Container = styled.div`
|
|||||||
border-radius: var(--list-item-border-radius);
|
border-radius: var(--list-item-border-radius);
|
||||||
border: 0.5px solid transparent;
|
border: 0.5px solid transparent;
|
||||||
width: calc(var(--assistants-width) - 20px);
|
width: calc(var(--assistants-width) - 20px);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--color-list-item-hover);
|
background-color: var(--color-list-item-hover);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -153,8 +153,8 @@ const HomeTabs: FC<Props> = ({
|
|||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: var(--assistants-width);
|
width: var(--assistants-width);
|
||||||
min-width: var(--assistants-width);
|
transition: width 0.3s;
|
||||||
height: calc(100vh - var(--navbar-height));
|
height: calc(100vh - var(--navbar-height));
|
||||||
|
|
||||||
&.right {
|
&.right {
|
||||||
@ -179,6 +179,7 @@ const Container = styled.div`
|
|||||||
|
|
||||||
const TabContent = styled.div`
|
const TabContent = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
transition: width 0.3s;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
|||||||
@ -141,3 +141,63 @@ export function getForegroundColor(backgroundColor: HexColor): HexColor {
|
|||||||
|
|
||||||
return luminance > 0.179 ? '#000000' : '#FFFFFF'
|
return luminance > 0.179 ? '#000000' : '#FFFFFF'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用于ts方式控制响应式样式,暂时没用上
|
||||||
|
// 目前应该设计到lg就足够
|
||||||
|
// 应该和 file://./../assets/styles/responsive.scss 保持一致
|
||||||
|
/**
|
||||||
|
* 断点配置对象,定义了不同屏幕尺寸的最小宽度(单位:像素)
|
||||||
|
*
|
||||||
|
* @property {number} xs - 超小屏幕断点,起始于 0px
|
||||||
|
* @property {number} sm - 小屏幕断点,起始于 576px
|
||||||
|
* @property {number} md - 中等屏幕断点,起始于 768px
|
||||||
|
* @property {number} lg - 大屏幕断点,起始于 1080px
|
||||||
|
* @property {number} xl - 超大屏幕断点,起始于 1200px
|
||||||
|
* @property {number} xxl - 超超大屏幕断点,起始于 1400px
|
||||||
|
*/
|
||||||
|
// export const breakpoints = {
|
||||||
|
// xs: 0,
|
||||||
|
// sm: 576,
|
||||||
|
// md: 768,
|
||||||
|
// lg: 1080,
|
||||||
|
// xl: 1200,
|
||||||
|
// xxl: 1400
|
||||||
|
// } as const
|
||||||
|
|
||||||
|
// type MediaQueryFunction = (styles: string) => string
|
||||||
|
// type MediaQueries = Record<keyof typeof breakpoints, MediaQueryFunction>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 媒体查询工具对象,用于生成响应式样式的媒体查询字符串
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // 使用示例:
|
||||||
|
* ```ts
|
||||||
|
* const styles = {
|
||||||
|
* color: 'red',
|
||||||
|
* [media.md]: `
|
||||||
|
* color: blue;
|
||||||
|
* `,
|
||||||
|
* [media.lg]: `
|
||||||
|
* color: green;
|
||||||
|
* `
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 生成的CSS将包含:
|
||||||
|
* ```css
|
||||||
|
* color: red;
|
||||||
|
* @media (max-width: 768px) { color: blue; }
|
||||||
|
* @media (max-width: 992px) { color: green; }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
// Not using for now
|
||||||
|
// export const media = objectKeys(breakpoints).reduce<MediaQueries>((acc, label) => {
|
||||||
|
// const key = label
|
||||||
|
// acc[key] = (styles: string): string => `
|
||||||
|
// @media (max-width: ${breakpoints[key]}px) {
|
||||||
|
// ${styles}
|
||||||
|
// }
|
||||||
|
// `
|
||||||
|
// return acc
|
||||||
|
// }, {} as MediaQueries)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user