Pattern · CANDIDATE
Editor Sidebar
editor-sidebar · v0.1.0
Persistent property panel beside a canvas so editing controls do not cover the object being edited.
Use when
- A document, slide, canvas, or preview stays visible while properties are edited
- The product needs a professional editor shell with a persistent sidebar
- Inspecting a selected element in a property panel beside the working surface
Avoid when
- A simple single-column form or settings page with no canvas
- A modal wizard where the working object should not remain visible
- Treating this CANDIDATE as CANONICAL before real product evaluation
Invariants
- Must not contain product-specific business logic or Lesson Forge / Document Studio terminology in the pattern API.
- On viewports below md, the sidebar must not shrink the canvas into unusability; it opens as an overlay.
- On md and wider, the canvas and sidebar are visible together.
- Open/close state applies to overlay mode; docked mode keeps the sidebar visible.
- Consuming apps own persistence of width and open state. The pattern must not write localStorage.
- Status remains CANDIDATE until real products exercise the pattern and a human promotes it.
Variants
- Docked: Side-by-side canvas and sidebar from the md breakpoint upward.
- Overlay: Narrow viewports use a right-hand overlay drawer with a labeled open/close control.
States
- default
- hover
- focus-visible
- open
- closed
- disabled
- narrow/mobile
- tablet
- desktop
- reduced-motion
- keyboard-only navigation
Anatomy
- editor-shell: Flex workspace that keeps content and sidebar in one editor surface.
- content-region: Primary canvas, document, or preview. Remains reachable when the overlay is closed.
- sidebar-region: Complementary property panel. Docked on md+; overlay drawer on narrow viewports.
- sidebar-header: Panel title row and overlay close control.
- sidebar-body: Scrollable slot for consumer-owned controls. No product business logic lives here.
- sidebar-footer: Optional actions that stay pinned to the bottom of the panel.
- resize-handle: Optional, docked-only labeled control that changes width within token min/max.
- mobile-trigger: Labeled control that opens the overlay sidebar on narrow viewports.
Responsive
Narrow: Below md (768px) the sidebar becomes a right overlay drawer. The canvas stays full width. Open/close is required. Escape and backdrop dismiss the overlay. Focus is trapped while open and returned to the trigger on close.
Medium: From md to lg the layout is still side-by-side. The sidebar uses the token width and may be resized. The canvas remains visible.
Wide: From lg upward the sidebar stays persistently docked. It must not cover the canvas. Width is constrained by component-alias tokens.
Accessibility
Roles: region, complementary, slider
Keyboard
- Tab reaches the overlay trigger, panel controls, and docked resize handle.
- Escape closes the overlay and returns focus to the trigger.
- The docked resize control is a labeled slider. ArrowLeft/ArrowRight (Shift for larger steps), Home, and End change width within token min/max.
Labeling: The content region and complementary sidebar require accessible names. Overlay trigger uses aria-expanded and aria-controls. Resize handle exposes valuemin/valuemax/valuenow.
Contrast: Panel surface, border, and focus ring resolve through semantic tokens.
Reduced motion: Overlay transform duration uses motion tokens that collapse to 0ms under prefers-reduced-motion.
Extension points
- content, header, body, and footer children
- sidebarLabel and contentLabel
- controlled or uncontrolled open and width
- resizable=false to disable the docked resize handle
- className on root, content, and panel
- trigger and close labels
Implementation
@c2c-ui-forge/patterns · EditorSidebar
packages/patterns/src/editor-sidebar.tsx