Files
calctext/_bmad-output/C-UX-Scenarios/04-file-organization/4.1-sidebar/4.1-sidebar.md
C. Cassel 0d38bd3108 feat(web): implement complete workspace with themes, tabs, sidebar, and mobile
Transform CalcText from a single-document calculator into a full workspace
application with multi-document support, theming, and responsive mobile experience.

- Theme system: 5 presets (Light, Dark, Matrix, Midnight, Warm) + accent colors
- Document model with localStorage persistence and auto-save
- Tab bar with keyboard shortcuts (Ctrl+N/W/Tab/1-9), rename, close
- Sidebar with search, recent, favorites, folders, templates, drag-and-drop
- 5 templates: Budget, Invoice, Unit Converter, Trip Planner, Loan Calculator
- Status bar with cursor position, engine status, dedication to Igor Cassel
- Results panel: type-specific colors, click-to-copy, error hints
- Format toolbar: H, B, I, //, color labels with live preview toggle
- Syntax highlighting using theme CSS variables
- Error hover tooltips
- Mobile: bottom results tray, sidebar drawer, touch targets, safe areas
- Docker multi-stage build (Rust WASM + Vite + Nginx)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 09:12:05 -04:00

329 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 4.1 — Sidebar & File Organization
**Previous Step:** ← [Tab Bar](../../03-document-management/3.1-tab-bar/3.1-tab-bar.md)
**Next Step:** → [Templates](../4.2-templates/4.2-templates.md)
---
## Page Metadata
| Property | Value |
|----------|-------|
| **Scenario** | 04 — File Organization |
| **Page Number** | 4.1 |
| **Platform** | Web (PWA), portable to macOS/Windows |
| **Page Type** | Collapsible Side Panel (within App Shell) |
---
## Overview
**Page Purpose:** Organize and navigate calctext documents. The sidebar provides a persistent file tree with folders, recent files, favorites, and templates — transforming CalcText from a single-use calculator into a workspace where calculations are organized and retrievable.
**Success Criteria:**
- Users find any document in < 3 seconds
- Folder hierarchy is intuitive (create, nest, rename, delete)
- Recent and Favorites provide quick access without browsing
- Sidebar never feels cluttered even with 50+ documents
---
## Layout Structure
```
┌──────────────────────┐
│ 🔍 Search... │ 32px — search bar
├──────────────────────┤
│ │
│ ▸ Recent │ section header (collapsible)
│ 📄 Budget │
│ 📄 Quick Math │
│ 📄 Invoice #42 │
│ │
│ ▸ Favorites │ section header
│ ⭐ Monthly Budget │
│ ⭐ Tax Calculator │
│ │
│ ▾ Files │ section header (expanded)
│ 📁 Work │ folder
│ │ 📄 Budget │ file in folder
│ │ 📄 Invoice │
│ 📁 Personal │ folder
│ │ 📁 Travel │ nested folder
│ │ │ 📄 Trip Cost │
│ 📄 Scratch │ root-level file
│ │
│ ▸ Templates │ section header
│ │
├──────────────────────┤
│ [+ Doc] [+ Folder] │ sticky footer
└──────────────────────┘
```
---
## Spacing
| Property | Token | Pixels |
|----------|-------|--------|
| Sidebar padding top | space-xs | 6px |
| Search bar height | | 32px |
| Search bar margin | space-xs | 6px all sides |
| Section header height | | 28px |
| Section header padding left | space-sm | 8px |
| File item height | | 28px |
| File item padding left (root) | space-md | 12px |
| File item indent per depth | | 16px |
| File icon size | | 16px |
| File icon-to-label gap | space-xs | 6px |
| Section gap | space-xs | 6px |
| Footer height | | 40px |
| Footer padding | space-xs | 6px |
---
## Typography
| Element | Size | Weight | Color |
|---------|------|--------|-------|
| Search placeholder | text-xs | 400 | var(--text) at 50% |
| Section header | text-2xs | 600 | var(--text) at 70% |
| File name | text-xs | 400 | var(--text) |
| File name (active) | text-xs | 500 | var(--text-h) |
| Folder name | text-xs | 500 | var(--text) |
| Footer buttons | text-2xs | 400 | var(--text), hover var(--accent) |
| File count badge | text-3xs | 400 | var(--text) at 40% |
---
## Search Bar
**OBJECT ID:** `sidebar-search`
| Property | Value |
|----------|-------|
| Placeholder | "Search documents..." |
| Background | var(--bg) |
| Border | 1px solid var(--border), focus var(--accent-border) |
| Border radius | 4px |
| Icon | 🔍 magnifier, 14px, var(--text) at 40% |
| Padding | 4px 8px 4px 28px (icon offset) |
| Behavior | Filters file tree in real-time as user types |
| Clear | × button appears when text entered |
| Keyboard | Ctrl/Cmd+P opens/focuses search (like VS Code quick open) |
| Results | Flat list of matching files, ranked by recency. Highlights matching text. |
| Empty state | "No documents match '{query}'" |
---
## Section: Recent
**OBJECT ID:** `sidebar-recent`
| Property | Value |
|----------|-------|
| Content | Last 5 opened documents, sorted by lastOpened timestamp |
| Collapsible | Yes, chevron toggle |
| Default state | Expanded on first launch, remembers toggle |
| Item display | File icon + name only (no folder path) |
| Empty state | "No recent documents" in text-3xs, muted |
| Update trigger | Opening any document pushes it to top, bumps oldest |
---
## Section: Favorites
**OBJECT ID:** `sidebar-favorites`
| Property | Value |
|----------|-------|
| Content | User-pinned documents, ordered manually (drag) |
| Collapsible | Yes |
| Default state | Collapsed if empty, expanded if has items |
| Item display | icon + name |
| Add to favorites | Right-click file "Add to Favorites", or drag file into section |
| Remove | Right-click "Remove from Favorites" |
| Empty state | "Drag files here or right-click Add to Favorites" |
---
## Section: Files (Tree)
**OBJECT ID:** `sidebar-files`
| Property | Value |
|----------|-------|
| Content | Complete folder tree with all documents |
| Collapsible | Yes (section level) |
| Default state | Expanded |
| Sort | Folders first, then files. Alphabetical within each group |
| Max depth | 3 levels (root folder subfolder files). Prevents over-nesting |
### Folder Item
**OBJECT ID:** `sidebar-folder`
| Property | Value |
|----------|-------|
| Icon | 📁 (closed) / 📂 (open) or chevron ▸/▾ |
| Click | Toggle expand/collapse |
| Double-click | Rename inline |
| Right-click | Context menu |
| Drag | Reorder within parent. Drop files into folder. |
| Drop target | Highlight with var(--accent-bg) + 2px dashed var(--accent) border |
| Badge | File count in parentheses: `Work (3)` text-3xs, muted |
### File Item
**OBJECT ID:** `sidebar-file`
| Property | Value |
|----------|-------|
| Icon | 📄 (default) could be themed per type later |
| Click | Open in tab (or switch to existing tab if already open) |
| Double-click | Open + rename inline |
| Hover | var(--accent-bg) background |
| Active | var(--accent-bg) + left 2px solid var(--accent) border |
| Active = | Currently open in active tab |
| Open indicator | Subtle dot or underline if open in any tab (even if not active) |
| Drag | Move between folders. Drag to tab bar to open. |
| Right-click | Context menu |
### File Context Menu
| Item | Action |
|------|--------|
| Open | Open in new tab |
| Open in New Tab | Open without closing current |
| | separator |
| Rename | Inline rename |
| Duplicate | Copy with "(copy)" suffix |
| Add to Favorites | Toggle |
| | separator |
| Move to... | Submenu with folder list |
| | separator |
| Delete | Confirm dialog 5-second undo toast |
### Folder Context Menu
| Item | Action |
|------|--------|
| New Document Here | Create file inside this folder |
| New Subfolder | Create nested folder (max depth 3) |
| | separator |
| Rename | Inline rename |
| | separator |
| Delete Folder | Must be empty. If not: "Move contents to root first." |
---
## Section: Templates
**OBJECT ID:** `sidebar-templates`
| Property | Value |
|----------|-------|
| Collapsible | Yes |
| Default state | Expanded on first launch |
| Content | Pre-built starting documents |
Full specification in [4.2 — Templates](../4.2-templates/4.2-templates.md).
---
## Sidebar Footer
**OBJECT ID:** `sidebar-footer`
| Property | Value |
|----------|-------|
| Position | Sticky bottom |
| Background | var(--bg-secondary) |
| Border top | 1px solid var(--border) |
| Layout | Two buttons side-by-side |
| Buttons | `[+ Document]` `[+ Folder]` ghost style |
| New Document | Creates at root level, opens in tab |
| New Folder | Creates at root level, inline rename active |
---
## Drag and Drop
| Drag Source | Drop Target | Behavior |
|-------------|-------------|----------|
| File | Folder | Move file into folder |
| File | Between files | Reorder within same folder |
| File | Tab bar | Open file in new tab |
| File | Favorites section | Add to favorites |
| Folder | Between folders | Reorder at same depth |
| Tab | Sidebar folder | Move document to folder |
### Drop Visual Feedback
| State | Appearance |
|-------|------------|
| Valid target hover | var(--accent-bg) background, 2px dashed var(--accent) border |
| Invalid target | No visual change (drop not accepted) |
| Insertion line | 2px solid var(--accent) horizontal line at insertion point |
| Dragging item | 60% opacity, subtle shadow |
---
## Resize Handle
| Property | Value |
|----------|-------|
| Position | Right edge of sidebar |
| Width | 1px visible, 8px hit area |
| Cursor | col-resize |
| Color | var(--border), hover/drag var(--accent) |
| Constraints | Min 180px, max 400px |
| Double-click | Reset to default 240px |
| Persistence | Width stored in localStorage |
---
## Responsive Behavior
| Breakpoint | Behavior |
|------------|----------|
| >= 1024px | Persistent side panel, resizable |
| 7681023px | Overlay drawer, hamburger toggle in header |
| < 768px | Full-screen drawer (85vw, max 320px) |
### Mobile Drawer
| Property | Value |
|----------|-------|
| Trigger | Hamburger menu (≡) in header |
| Width | 85vw, max 320px |
| Overlay | 50% black backdrop |
| Animation | Slide from left, 200ms ease-out |
| Close | Tap backdrop, swipe left, or × button top-right |
| File tap | Opens document, auto-closes drawer |
---
## Page States
| State | When | Behavior |
|-------|------|----------|
| **Empty** | No documents or folders | Show: "Welcome! Create your first document or pick a template." + prominent buttons |
| **Few files** (<5) | Early usage | All sections visible, Templates expanded to encourage exploration |
| **Many files** (>20) | Power user | Search becomes critical. Sections collapsed by default except Files |
| **Search active** | User typed in search | Tree replaced by flat filtered list. Sections hidden. |
| **Dragging** | File/folder being moved | Drop targets highlighted. Invalid areas dimmed. |
---
## Technical Notes
- **Virtual scrolling:** Not needed until 500+ items. Standard DOM rendering is fine for typical usage.
- **Folder persistence:** `folders: Folder[]` in localStorage with `parentId` for tree structure.
- **Sort stability:** Alphabetical sort is stable — user manual ordering within a folder stored as `order` field.
- **Cross-platform:** Maps to NSOutlineView (macOS), Tree widget (iced/Windows). Same data model.
---
_Created using Whiteport Design Studio (WDS) methodology_