From 4eaeefbdf5b979fb777884df24090740bd2a3ef3 Mon Sep 17 00:00:00 2001 From: Seefs <40468931+seefs001@users.noreply.github.com> Date: Tue, 11 Aug 2026 13:50:39 +0800 Subject: [PATCH] fix: mobile sidebar (#6760) * fix: mobile sidebar * fix(web): prevent iOS sidebar taps from being swallowed --- .../layout/components/chat-presets-item.tsx | 4 +++ .../layout/components/nav-group.tsx | 28 +++++++++++++------ .../layout/components/sidebar-view-header.tsx | 3 +- web/src/components/ui/sidebar.tsx | 14 ++++------ 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/web/src/components/layout/components/chat-presets-item.tsx b/web/src/components/layout/components/chat-presets-item.tsx index da4c3417..f1e20693 100644 --- a/web/src/components/layout/components/chat-presets-item.tsx +++ b/web/src/components/layout/components/chat-presets-item.tsx @@ -61,12 +61,14 @@ function ChatMenuItem({ loading, onOpen, onNavigate, + preload, }: { preset: ChatPreset active: boolean loading: boolean onOpen: (preset: ChatPreset) => void | Promise onNavigate: () => void + preload?: false }) { if (preset.type === 'web') { return ( @@ -77,6 +79,7 @@ function ChatMenuItem({ } @@ -277,6 +280,7 @@ export function ChatPresetsItem({ item }: { item: NavChatPresets }) { loading={loadingPresetId === preset.id} onOpen={handleOpenExternal} onNavigate={() => setOpenMobile(false)} + preload={isMobile ? false : undefined} /> ))} diff --git a/web/src/components/layout/components/nav-group.tsx b/web/src/components/layout/components/nav-group.tsx index be6a1521..5cf10de7 100644 --- a/web/src/components/layout/components/nav-group.tsx +++ b/web/src/components/layout/components/nav-group.tsx @@ -48,11 +48,11 @@ import { } from '@/components/ui/sidebar' import { checkIsActive } from '../lib/url-utils' -import { - type NavCollapsible, - type NavChatPresets, - type NavLink, - type NavGroup as NavGroupProps, +import type { + NavCollapsible, + NavChatPresets, + NavLink, + NavGroup as NavGroupProps, } from '../types' import { ChatPresetsItem } from './chat-presets-item' @@ -121,13 +121,19 @@ function NavBadge({ children }: { children: ReactNode }) { * Sidebar menu link item */ function SidebarMenuLink({ item, href }: { item: NavLink; href: string }) { - const { setOpenMobile } = useSidebar() + const { isMobile, setOpenMobile } = useSidebar() return ( setOpenMobile(false)} />} + render={ + setOpenMobile(false)} + /> + } > {item.icon && } {item.title} @@ -147,7 +153,7 @@ function SidebarMenuCollapsible({ item: NavCollapsible href: string }) { - const { setOpenMobile } = useSidebar() + const { isMobile, setOpenMobile } = useSidebar() // 检查当前路径是否匹配子菜单项 const isSubItemActive = checkIsActive(href, item) // 使用受控状态,初始值基于当前路径是否匹配 @@ -184,7 +190,11 @@ function SidebarMenuCollapsible({ setOpenMobile(false)} /> + setOpenMobile(false)} + /> } > {subItem.icon && } diff --git a/web/src/components/layout/components/sidebar-view-header.tsx b/web/src/components/layout/components/sidebar-view-header.tsx index b0be5966..6cf08aaa 100644 --- a/web/src/components/layout/components/sidebar-view-header.tsx +++ b/web/src/components/layout/components/sidebar-view-header.tsx @@ -43,7 +43,7 @@ type SidebarViewHeaderProps = { */ export function SidebarViewHeader(props: SidebarViewHeaderProps) { const { t } = useTranslation() - const { setOpenMobile } = useSidebar() + const { isMobile, setOpenMobile } = useSidebar() return ( @@ -58,6 +58,7 @@ export function SidebarViewHeader(props: SidebarViewHeaderProps) { render={ setOpenMobile(false)} /> } diff --git a/web/src/components/ui/sidebar.tsx b/web/src/components/ui/sidebar.tsx index 36a113f6..db465a62 100644 --- a/web/src/components/ui/sidebar.tsx +++ b/web/src/components/ui/sidebar.tsx @@ -207,7 +207,7 @@ function Sidebar({ data-sidebar='sidebar' data-slot='sidebar' data-mobile='true' - className='bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden' + className='bg-sidebar text-sidebar-foreground pointer-events-auto z-60 w-(--sidebar-width) p-0 [&>button]:hidden' style={ { '--sidebar-width': SIDEBAR_WIDTH_MOBILE, @@ -530,6 +530,7 @@ function SidebarMenuButton({ tooltip?: string | React.ComponentProps } & VariantProps) { const { isMobile, state } = useSidebar() + const tooltipEnabled = Boolean(tooltip) && !isMobile && state === 'collapsed' const comp = useRender({ defaultTagName: 'button', props: mergeProps<'button'>( @@ -538,7 +539,7 @@ function SidebarMenuButton({ }, props ), - render: !tooltip ? render : , + render: tooltipEnabled ? : render, state: { slot: 'sidebar-menu-button', sidebar: 'menu-button', @@ -547,7 +548,7 @@ function SidebarMenuButton({ }, }) - if (!tooltip) { + if (!tooltipEnabled || !tooltip) { return comp } @@ -561,12 +562,7 @@ function SidebarMenuButton({ {comp} - )