refactor: sidebar full-height with logo+toggle at top, header beside sidebar
Docker Build / Build and Push Docker Image (push) Successful in 3m51s

This commit is contained in:
2026-06-15 04:02:05 +08:00
parent c52ff411a7
commit 75e608bdc8
4 changed files with 15 additions and 13 deletions
@@ -26,7 +26,6 @@ import { Search } from '@/components/search'
import { defaultTopNavLinks } from '../config/top-nav.config'
import { type TopNavLink } from '../types'
import { Header } from './header'
import { SystemBrand } from './system-brand'
import { TopNav } from './top-nav'
/**
@@ -112,8 +111,6 @@ export function AppHeader({
return (
<>
<Header>
<SystemBrand variant='inline' />
{leftContent ? (
<div className='ms-2 flex items-center'>{leftContent}</div>
) : null}
@@ -20,9 +20,10 @@ import { AnimatePresence, motion, useReducedMotion } from 'motion/react'
import { MOTION_TRANSITION, MOTION_VARIANTS } from '@/lib/motion'
import { useLayout } from '@/context/layout-provider'
import { useSidebarView } from '@/hooks/use-sidebar-view'
import { Sidebar, SidebarContent, SidebarRail } from '@/components/ui/sidebar'
import { Sidebar, SidebarContent, SidebarHeader, SidebarRail, SidebarTrigger } from '@/components/ui/sidebar'
import { NavGroup } from './nav-group'
import { SidebarViewHeader } from './sidebar-view-header'
import { SystemBrand } from './system-brand'
/**
* Application sidebar.
@@ -48,6 +49,11 @@ export function AppSidebar() {
return (
<Sidebar collapsible={collapsible} variant={variant}>
<SidebarHeader className='flex flex-row items-center gap-1 px-2'>
<SystemBrand variant='sidebar' />
<SidebarTrigger variant='ghost' className='size-8 ms-auto' />
</SidebarHeader>
{view && <SidebarViewHeader view={view} />}
<SidebarContent className='py-2'>
@@ -20,7 +20,7 @@ import { getCookie } from '@/lib/cookies'
import { cn } from '@/lib/utils'
import { LayoutProvider } from '@/context/layout-provider'
import { SearchProvider } from '@/context/search-provider'
import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'
import { AnimatedOutlet } from '@/components/page-transition'
import { SkipToMain } from '@/components/skip-to-main'
import { AppHeader } from './app-header'
@@ -36,20 +36,19 @@ export function AuthenticatedLayout(props: AuthenticatedLayoutProps) {
return (
<LayoutProvider>
<SearchProvider>
<SidebarProvider defaultOpen={defaultOpen} className='flex-col'>
<SidebarProvider defaultOpen={defaultOpen}>
<SkipToMain />
<AppHeader />
<div className='flex min-h-0 w-full flex-1'>
<AppSidebar />
<AppSidebar />
<div className='flex flex-1 flex-col'>
<AppHeader />
<SidebarInset
className={cn(
'@container/content',
'h-[calc(100svh-var(--app-header-height,0px))]',
'h-[calc(100svh-var(--app-header-height,3rem))]',
'min-h-0 overflow-hidden',
'peer-data-[variant=inset]:h-[calc(100svh-var(--app-header-height,0px)-(var(--spacing)*4))]'
'peer-data-[variant=inset]:h-[calc(100svh-var(--app-header-height,3rem)-(var(--spacing)*4))]'
)}
>
<SidebarTrigger variant='ghost' className='absolute left-1 top-1/2 z-30 size-8 -translate-y-1/2' />
{props.children ?? <AnimatedOutlet />}
</SidebarInset>
</div>
+1 -1
View File
@@ -249,7 +249,7 @@ function Sidebar({
data-slot='sidebar-container'
data-side={side}
className={cn(
'fixed top-[var(--app-header-height,0px)] bottom-0 z-10 hidden h-[calc(100svh-var(--app-header-height,0px))] w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex',
'fixed top-0 bottom-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex',
// Adjust the padding for floating and inset variants.
variant === 'floating' || variant === 'inset'
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'