|
| 1 | +--- |
| 2 | +status: complete |
| 3 | +created: '2025-11-20' |
| 4 | +tags: |
| 5 | + - ui |
| 6 | + - ux |
| 7 | + - lessons-learned |
| 8 | +priority: medium |
| 9 | +created_at: '2025-11-20T02:27:35.059Z' |
| 10 | +completed_at: '2025-11-20T02:30:00.000Z' |
| 11 | +updated_at: '2025-11-20T02:29:11.195Z' |
| 12 | +completed: '2025-11-20' |
| 13 | +--- |
| 14 | + |
| 15 | +# UI/UX Refinements - Spec Detail & List Views |
| 16 | + |
| 17 | +> **Status**: ✅ Complete · **Priority**: Medium · **Created**: 2025-11-20 · **Tags**: ui, ux, lessons-learned |
| 18 | +
|
| 19 | +**Project**: lean-spec |
| 20 | +**Team**: Core Development |
| 21 | + |
| 22 | +## Overview |
| 23 | + |
| 24 | +This spec documents the refinements made to the Spec Detail page and Specs List/Board views to improve navigation, readability, and layout flexibility. The changes focus on Table of Contents (TOC) accessibility, precise anchor navigation, and enhanced list management controls. |
| 25 | + |
| 26 | +### Key Improvements |
| 27 | +1. **Responsive TOC Layout**: Replaced the floating button with a persistent sidebar on large screens. |
| 28 | +2. **Precise Anchor Navigation**: Fixed offset issues caused by sticky headers. |
| 29 | +3. **Visual Polish**: Implemented auto-hiding scrollbars to reduce visual clutter. |
| 30 | +4. **Specs List Enhancements**: Added "Wide Mode" toggle and improved filter layout. |
| 31 | + |
| 32 | +## Current State |
| 33 | + |
| 34 | +### 1. Hybrid TOC Layout (Spec Detail) |
| 35 | +- **Desktop (≥1280px)**: A sticky right sidebar displays the TOC. This utilizes the available screen real estate and allows users to scan the document structure without clicking a button. |
| 36 | +- **Mobile/Tablet (<1280px)**: Retains the floating action button (FAB) to open the TOC in a dialog, preserving screen space for content. |
| 37 | + |
| 38 | +### 2. Dynamic Scroll Padding (Spec Detail) |
| 39 | +- **Problem**: Sticky headers obscured section titles when navigating to anchors. |
| 40 | +- **Solution**: Implemented dynamic `scroll-padding-top` calculation in `SpecDetailClient`. |
| 41 | + - Calculates the exact height of the sticky header (navbar + spec header). |
| 42 | + - Applies this value to `document.documentElement.style.scrollPaddingTop`. |
| 43 | + - Updates on window resize and content changes. |
| 44 | + - **Fine-tuning**: Adjusted the offset (Header Height - 12px) to align the text baseline perfectly, accounting for heading margins. |
| 45 | + |
| 46 | +### 3. Auto-Hiding Scrollbars |
| 47 | +- **Problem**: The TOC sidebar introduced a second vertical scrollbar next to the main page scrollbar, creating visual noise. |
| 48 | +- **Solution**: Created a `.scrollbar-auto-hide` utility class. |
| 49 | + - The scrollbar is invisible by default. |
| 50 | + - A thin, subtle thumb appears only on hover. |
| 51 | + - Applied to the TOC sidebar container. |
| 52 | + |
| 53 | +### 4. Specs List & Board Enhancements |
| 54 | +- **Wide Mode Toggle**: Added a maximize/minimize button to toggle the container width between `max-w-7xl` and `w-full`. This is particularly useful for the Kanban board view with many columns. |
| 55 | +- **Improved Header Layout**: |
| 56 | + - Reorganized filters and search into a scrollable row for better mobile responsiveness. |
| 57 | + - Updated View Switcher (List/Board) to a segmented control style. |
| 58 | +- **View Persistence**: View mode preference (List vs Board) is now persisted in `localStorage` and synchronized with the URL. |
| 59 | + |
| 60 | +## Lessons Learned |
| 61 | + |
| 62 | +### Sticky Headers & Anchor Navigation |
| 63 | +- **`scroll-padding-top` vs `scroll-margin-top`**: |
| 64 | + - `scroll-margin-top` on individual headings is brittle when header heights change (e.g., wrapping tags). |
| 65 | + - `scroll-padding-top` on the `<html>` element is superior as it can be dynamically updated via JavaScript to match the exact current header height. |
| 66 | +- **Navigation Method**: |
| 67 | + - `element.scrollIntoView({ behavior: 'smooth', block: 'start' })` respects `scroll-padding-top` automatically. |
| 68 | + - Manual `window.scrollTo` calculations are error-prone and should be avoided when native APIs suffice. |
| 69 | + |
| 70 | +### Visual Refinements |
| 71 | +- **Scrollbar UX**: "Double scrollbars" are a common UI smell in sidebars. Auto-hiding them is a clean pattern that maintains functionality without clutter. |
| 72 | +- **Offset Tuning**: Mathematical exactness (Header Height + Padding) doesn't always equal visual correctness. Small adjustments (e.g., `-12px`) are often needed to account for line-heights and margins. |
| 73 | + |
| 74 | +## Implementation Details |
| 75 | + |
| 76 | +### Files Modified |
| 77 | +- `packages/ui/src/components/spec-detail-client.tsx`: Layout changes, scroll padding logic. |
| 78 | +- `packages/ui/src/components/table-of-contents.tsx`: Refactored to support both Sidebar and Dialog modes. |
| 79 | +- `packages/ui/src/app/globals.css`: Added `.scrollbar-auto-hide` utility. |
| 80 | +- `packages/ui/src/app/specs/specs-client.tsx`: Added Wide Mode, updated header layout, view persistence. |
| 81 | + |
| 82 | +### Code Snippet: Dynamic Scroll Padding |
| 83 | +```typescript |
| 84 | +// Handle scroll padding for sticky header |
| 85 | +React.useEffect(() => { |
| 86 | + const updateScrollPadding = () => { |
| 87 | + const navbarHeight = 56; |
| 88 | + let offset = navbarHeight; |
| 89 | + |
| 90 | + if (window.innerWidth >= 1024 && headerRef.current) { |
| 91 | + offset += headerRef.current.offsetHeight; |
| 92 | + // Reduce offset slightly to avoid visual gap due to heading margins |
| 93 | + offset -= 12; |
| 94 | + } |
| 95 | + |
| 96 | + document.documentElement.style.scrollPaddingTop = `${offset}px`; |
| 97 | + }; |
| 98 | + // ... observers and event listeners |
| 99 | +}, [spec, tags]); |
| 100 | +``` |
| 101 | + |
| 102 | +## Plan |
| 103 | + |
| 104 | +- [x] Refactor `TableOfContents` to support sidebar mode |
| 105 | +- [x] Update `SpecDetailClient` layout for desktop sidebar |
| 106 | +- [x] Implement dynamic `scroll-padding-top` logic |
| 107 | +- [x] Add auto-hiding scrollbar styles |
| 108 | +- [x] Implement Wide Mode in `SpecsClient` |
| 109 | +- [x] Refine Specs List header layout |
| 110 | +- [x] Verify navigation precision |
| 111 | + |
| 112 | +## Test |
| 113 | + |
| 114 | +- [x] **Desktop View**: TOC appears as sidebar. |
| 115 | +- [x] **Mobile View**: TOC appears as floating button. |
| 116 | +- [x] **Anchor Click**: Page scrolls smoothly to section. |
| 117 | +- [x] **Alignment**: Section title is not obscured by header and has correct visual spacing. |
| 118 | +- [x] **Scrollbar**: Sidebar scrollbar is hidden until hovered. |
| 119 | +- [x] **Wide Mode**: Toggling expands the container to full width. |
| 120 | +- [x] **View Persistence**: Refreshing the page remembers the last selected view (List/Board). |
0 commit comments