Files
calctext/_bmad-output/C-UX-Scenarios/03-document-management/3.1-tab-bar/3.1-tab-bar.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

8.2 KiB
Raw Blame History

3.1 — Tab Bar & Document Lifecycle

Next Step:Sidebar


Page Metadata

Property Value
Scenario 03 — Document Management
Page Number 3.1
Platform Web (PWA), portable to macOS/Windows
Page Type Embedded Strip (within App Shell, between header and editor)

Overview

Page Purpose: Enable multi-document workflow. Users can open, create, close, reorder, and rename documents via tabs. The tab bar is the primary navigation between open documents.

Success Criteria:

  • Switching tabs feels instant (< 50ms)
  • Users never lose work (auto-save before switch)
  • Tab state survives page reload
  • 15+ tabs remain usable (horizontal scroll)

Layout Structure

┌──────────────────────────────────────────────────────────┐
│ [● Budget ×] [  Invoice ×] [  Unit Conv ×]  [+]    ··· │  36px
└──────────────────────────────────────────────────────────┘
  ● = unsaved changes dot
  Active tab: connected to editor (no bottom border)
  [+] = new document button
  ··· = overflow gradient when scrollable

Spacing

Property Token Pixels
Tab bar height 36px
Tab padding horizontal space-sm 8px
Tab gap 0px (tabs are flush, separated by 1px border)
Tab min width 100px
Tab max width 200px
Close button size 16px × 16px
Close button margin-left space-xs 6px
Modified dot size 6px
Modified dot margin-right space-2xs 4px
New tab button width 36px (square)

Typography

Element Size Weight Color
Tab label (active) text-xs 500 var(--text-h)
Tab label (inactive) text-xs 400 var(--text)
Close × text-xs 400 var(--text) at 50%, hover → var(--text)
New + icon text-sm 300 var(--text), hover → var(--accent)

Tab States

Active Tab

Property Value
Background var(--bg) — same as editor, creates visual connection
Border bottom None — tab "opens into" the editor
Border left/right 1px solid var(--border)
Border top 2px solid var(--accent) — active indicator
Label Weight 500, var(--text-h)
Close button Always visible

Inactive Tab

Property Value
Background var(--bg-secondary)
Border bottom 1px solid var(--border) — closed off from editor
Border left/right 1px solid var(--border)
Border top 2px solid transparent
Label Weight 400, var(--text)
Close button Visible on hover only

Hover (Inactive)

Property Value
Background Blend between bg-secondary and bg (subtle lighten)
Transition background 0.1s

Dragging

Property Value
Appearance Tab lifts with subtle shadow (0 2px 8px rgba(0,0,0,0.15))
Opacity 90%
Placeholder 2px var(--accent) vertical line at insertion point
Cursor grabbing

Interactions

Action Behavior
Click tab Switch to document. Auto-save current. Restore editor state (content, cursor, scroll, undo).
Click + Create "Untitled" doc, open in new tab, focus editor.
Click × Close tab. If unsaved and modified, no prompt (auto-saved). Remove from openTabIds.
Middle-click tab Close tab (same as ×).
Double-click tab Inline rename — label becomes input field, Enter confirms, Esc cancels.
Drag tab Reorder. Drop position shown by accent line indicator.
Ctrl/Cmd+Tab Next tab (wraps).
Ctrl/Cmd+Shift+Tab Previous tab (wraps).
Ctrl/Cmd+W Close active tab. If last tab, create new "Untitled".
Ctrl/Cmd+N New document + tab.
Ctrl/Cmd+19 Jump to tab by position.
Mouse wheel on tab bar Horizontal scroll when tabs overflow.

Tab Overflow

Property Value
Trigger Total tab width > container width
Scroll Horizontal, smooth, via mouse wheel or trackpad
Indicators 16px fade gradient on left/right edges when scrollable
Active tab Auto-scrolls into view when selected via keyboard
New tab button Sticky right — always visible outside scroll area

Document Lifecycle

Create

Trigger Behavior
Click [+] New doc: { id: uuid(), title: "Untitled", content: "", folderId: null }
Sidebar template click New doc with template content and suggested title
Ctrl/Cmd+N Same as [+]

Title auto-increments: "Untitled", "Untitled 2", "Untitled 3"...

Rename

Trigger Behavior
Double-click tab Label becomes <input>, pre-selected text, 200px max width
Sidebar right-click → Rename Same inline editing in sidebar
Enter Confirm rename, update document and sidebar
Esc Cancel, revert to previous name
Blur Confirm (same as Enter)
Empty name Revert to "Untitled"

Delete

Trigger Behavior
Sidebar right-click → Delete Confirmation: "Delete '{title}'? This cannot be undone."
Confirm Remove from documents[], close tab if open, remove from folder
Cancel No action
Undo 5-second toast: "Document deleted. [Undo]" — restores document if clicked

Duplicate

Trigger Behavior
Sidebar right-click → Duplicate New doc: same content, title = "{original} (copy)", same folder
Opens in new tab automatically

Auto-Save

Property Value
Trigger Document content change
Debounce 500ms after last keystroke
Storage localStorage (calctext-documents)
Indicator Modified dot (●) appears immediately on change, disappears on save
Manual save Ctrl/Cmd+S shows brief checkmark animation in tab (visual confirmation)

Modified Indicator

Property Value
Shape Filled circle, 6px
Color var(--text) at 60%
Position Before tab label, 4px gap
Appears On first character change
Disappears On auto-save completion (500ms debounce)
Animation Fade in 0.2s

Context Menu (Right-Click Tab)

Item Action
Close Close this tab
Close Others Close all tabs except this one
Close to the Right Close all tabs to the right
(separator)
Rename Inline rename
Duplicate Duplicate document
(separator)
Reveal in Sidebar Scroll sidebar to show this file

Mobile Adaptations

Property Value
Tab bar Horizontal scroll, touch-friendly
Tab height 40px (larger touch target)
Close button Hidden — swipe left on tab to reveal close
New tab [+] button at far right
Rename Long-press → context menu → Rename
Reorder Long-press + drag

Page States

State When Behavior
Single tab Only one document open Tab still shown (establishes pattern). Close creates new "Untitled".
Many tabs (>10) Heavy usage Horizontal scroll. Active tab auto-scrolls into view.
All tabs closed User closed everything Auto-create "Untitled" tab (workspace never empty).
First launch No localStorage Single "Welcome" tab with demo content.

Technical Notes

  • Tab switching performance: Store EditorState per tab in memory. On switch: destroy current EditorView, create new with stored state. Content swap < 20ms.
  • Tab order persistence: openTabIds: string[] in localStorage maintains order.
  • Cross-platform: Maps to native tab bars. macOS: NSTabView or custom tab strip. Windows: iced tabs widget.
  • Max tabs: Soft limit at 20 with performance hint in status bar. No hard limit.

Created using Whiteport Design Studio (WDS) methodology