UNPKG

oneie

Version:

Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.

250 lines (178 loc) 8.52 kB
--- title: Layout dimension: things category: plans tags: ai related_dimensions: groups scope: global created: 2025-11-03 updated: 2025-11-03 version: 1.0.0 ai_context: | This document is part of the things dimension in the plans category. Location: one/things/plans/layout.md Purpose: Documents sidebar layout fix - comprehensive analysis Related dimensions: groups For AI agents: Read this to understand layout. --- # Sidebar Layout Fix - Comprehensive Analysis ## Problem Statement The sidebar is overlapping the main content instead of pushing it to the right. Content is being hidden behind the fixed sidebar. ## Root Cause Analysis ### How shadcn Sidebar SHOULD Work From analyzing the official dashboard-01 example, the shadcn sidebar uses a **three-part layout system**: 1. **SidebarProvider** - Creates a flex container wrapper ```tsx <div className="group/sidebar-wrapper flex min-h-svh w-full"> ``` 2. **Sidebar Component** - Has TWO nested divs: - **Spacer div**: Takes up space in the flex layout (`w-[--sidebar-width]`) - **Fixed overlay**: The actual visible sidebar (`fixed inset-y-0`) 3. **SidebarInset** - The main content area with `flex-1 w-full` ### The Mechanism ``` ┌─────────────────────────────────────────────────────┐ │ SidebarProvider (flex container) │ │ ┌──────────┬────────────────────────────────────┐ │ │ │ Sidebar │ SidebarInset │ │ │ │ ┌──────┐ │ ┌────────────────────────────────┐ │ │ │ │ │Spacer│ │ │ Main Content │ │ │ │ │ │16rem │ │ │ (flex-1 takes remaining space) │ │ │ │ │ └──────┘ │ │ │ │ │ │ │ ┌──────┐ │ │ │ │ │ │ │ │Fixed │ │ │ │ │ │ │ │ │Overlay│ │ │ │ │ │ │ │ └──────┘ │ │ │ │ │ │ └──────────┴────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘ ``` - **Spacer**: `w-[--sidebar-width]` (16rem when expanded, 3rem when collapsed) - **Fixed Overlay**: Position fixed, visually overlays the spacer - **Content**: `flex-1` grows to fill remaining space after spacer ## Current Issues in Our Implementation ### Issue 1: Spacer Div Missing `flex-shrink: 0` **Location**: `src/components/ui/sidebar.tsx` line 234-243 Current: ```tsx <div className={cn( "relative h-svh w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear", // ... )} /> ``` **Problem**: Without `shrink-0`, the spacer can shrink to accommodate `SidebarInset`'s `w-full`, making it collapse to 0 width. ### Issue 2: SidebarInset Using Both `w-full` and `flex-1` **Location**: `src/components/ui/sidebar.tsx` line 334 Current: ```tsx className={cn( 'relative flex w-full flex-1 flex-col bg-background', 'peer-data-[state=collapsed]:pl-[--sidebar-width-icon] peer-data-[state=expanded]:pl-[--sidebar-width]', // ... )} ``` **Problem**: 1. `w-full` (width: 100%) conflicts with flex layout 2. The padding-left I added is WRONG - the spacer should handle positioning, not padding 3. CSS custom properties in arbitrary values `pl-[--sidebar-width]` don't work in Tailwind ### Issue 3: User Modifications to Sidebar Component **Location**: `src/components/ui/sidebar.tsx` line 227, 246 The user (or formatter) changed: - Line 227: `hidden md:block``block` - Line 246: `hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex``flex h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear` This removes the mobile/desktop breakpoint behavior. ## Solution Plan ### Step 1: Fix Spacer Div - Add `shrink-0` The spacer MUST NOT shrink. It should hold its width to push content. **Change in `sidebar.tsx` line 236**: ```tsx 'relative h-svh w-[--sidebar-width] shrink-0 bg-transparent transition-[width] duration-200 ease-linear', ``` ### Step 2: Remove Incorrect Padding from SidebarInset The SidebarInset should NOT have padding-left. Let flex layout handle positioning. **Change in `sidebar.tsx` line 334**: ```tsx 'relative flex min-w-0 flex-1 flex-col bg-background', // Remove: w-full (causes width issues) // Remove: peer-data padding classes I added // Add: min-w-0 (allows flex item to shrink below content size if needed) ``` ### Step 3: Restore Mobile Behavior (Optional) If we want proper mobile/desktop behavior, restore the breakpoints: **Line 227**: Change back to `hidden text-sidebar-foreground md:block` **Line 246**: Add `md:` prefix to `flex` ### Step 4: Verify CSS Variables Are Set Ensure SidebarProvider sets the CSS variables: ```tsx style={{ '--sidebar-width': SIDEBAR_WIDTH, // 16rem '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, // 3rem }} ``` ## Expected Outcome After fixes: 1. **Expanded**: Spacer is 16rem, content starts at 16rem from left 2. **Collapsed**: Spacer is 3rem, content starts at 3rem from left 3. **Mobile**: Sidebar is offcanvas overlay (if breakpoints restored) 4. **Transitions**: Smooth width changes on toggle ## Implementation Order 1. ✅ Research complete 2. ✅ Create this plan document 3. ✅ Fix spacer div with `shrink-0` 4. ✅ Fix SidebarInset - remove `w-full` and padding, add `min-w-0` 5. ✅ Restore mobile breakpoints (`hidden md:block` and `hidden md:flex`) 6. ✅ Verify CSS variables are set correctly 7. ⏳ Test in browser at http://localhost:4321 8. ⏳ Verify responsive behavior across breakpoints ## Key Learnings 1. **Flex layout is key**: The spacer takes up space, content fills remaining 2. **No padding needed**: Content positioning is automatic via flex 3. **`shrink-0` is critical**: Prevents spacer from collapsing 4. **CSS custom properties**: Must be set via inline styles, can't use in Tailwind arbitrary classes 5. **`w-full` breaks flex**: Use `flex-1` and `min-w-0` instead for flex items ## Implementation Summary ### Files Modified **`src/components/ui/sidebar.tsx`** #### Change 1: Sidebar Container (Line 229) ```tsx // Before: className="group peer block text-sidebar-foreground" // After: className="group peer hidden text-sidebar-foreground md:block" ``` Restores mobile responsiveness - sidebar hidden on mobile, uses Sheet component instead. #### Change 2: Spacer Div (Line 238) ```tsx // Before: 'relative h-svh w-[--sidebar-width] bg-transparent ...' // After: 'relative h-svh w-[--sidebar-width] shrink-0 bg-transparent ...' ``` Added `shrink-0` to prevent the spacer from collapsing in flex layout. #### Change 3: Fixed Overlay (Line 248) ```tsx // Before: 'fixed inset-y-0 z-10 flex h-svh w-[--sidebar-width] ...' // After: 'fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] ... md:flex' ``` Restores mobile responsiveness - fixed overlay hidden on mobile. #### Change 4: SidebarInset (Line 336) ```tsx // Before: 'relative flex w-full flex-1 flex-col bg-background' // 'peer-data-[state=collapsed]:pl-[--sidebar-width-icon] ...' // After: 'relative flex min-w-0 flex-1 flex-col bg-background' ``` - Removed `w-full` (conflicts with flex layout) - Removed incorrect padding classes - Added `min-w-0` (allows proper flex shrinking) ### CSS Variables Verified (Lines 143-144) ```tsx '--sidebar-width': SIDEBAR_WIDTH, // 16rem '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, // 3rem ``` ## Testing Checklist - [ ] Sidebar visible on desktop - [ ] Content positioned correctly (not overlapping) - [ ] Smooth transition when toggling sidebar - [ ] Collapsed state shows icons only (3rem width) - [ ] Expanded state shows full sidebar (16rem width) - [ ] Content width adjusts automatically - [ ] Mobile: Sidebar uses Sheet overlay (hidden by default) - [ ] No horizontal scrollbar - [ ] Keyboard shortcut 'b' works for toggle