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
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 |
| 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 |
| 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 |
| 768–1023px |
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