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

10 KiB
Raw Blame History

4.1 — Sidebar & File Organization

Previous Step:Tab Bar Next Step:Templates


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%

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.


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