Visual Editor
The Visual Editor (VISEDITOR epic, #958) adds direct-manipulation editing capabilities to the section preview pane in Smackz-Websites. Instead of adjusting properties through form fields in the 7-step wizard, users can click, drag, and edit elements visually in the preview.
Scope: the visual editor operates inside the section preview pane (SectionPreviewPane within PageSectionWizard). The full-page preview remains read-only.
Feature Set
Selection Overlay (VISEDITOR-01)
A click-to-select interaction layer on top of the section preview. When a user clicks an element (heading, button, media, etc.), it highlights with a Figma-style blue outline, 8 resize handles, and a role label badge.
How it works:
page-renderercomponents are annotated withdata-roleattributes (e.g.,data-role="heading",data-role="button-primary",data-role="text-container"). These attributes are inert and do not affect rendering.- A transparent
SelectionOverlaycomponent intercepts clicks and walks the DOM upward to find the nearestdata-role, identifying the element type and parent section. SelectionHighlightpositions a blue outline (#3b82f6) usinggetBoundingClientRect()relative to the preview container. CSSzoomscaling is handled automatically since the overlay is a sibling within the same container.- Hover shows a dashed blue indicator. Click shows a solid outline with handles and label. Escape or clicking outside deselects.
Key files: Smackz-Websites/src/pages/pages/components/visual-editor/ (new directory), plus data-role attributes added across page-renderer layout and content components.
Floating Toolbar (VISEDITOR-02)
When an element is selected, a contextual floating toolbar appears above it with the most relevant editing controls. This provides shortcuts for common property changes without navigating the wizard.
Controls by element type:
| Element | Available Controls |
|---|---|
| Text (heading, subheading, body) | Font size, color, alignment, font family, bold, italic |
| Primary/secondary button | Color, text color, variant (filled/outline/text), size |
| Buttons container | Alignment, "Edit in wizard" link |
| Media | Border radius, layout selector (carousel/grid/list/row) |
| Text container | Background color, opacity, "Edit in wizard" link |
| Section | Background color, "Edit in wizard" link |
The toolbar uses a dark glassmorphic style (rgba(15, 23, 42, 0.85) with blur(16px)) and flips below the element when there is not enough space above. All changes flow through the same onFieldChange callback used by the wizard forms, so the preview updates in real time.
Drag-to-Position Text Container (VISEDITOR-03)
On hero sections with background media, the selection handles on the text container become draggable. Users can reposition and resize the text container by dragging instead of adjusting the four percentage sliders (textStartPercent, textEndPercent, textTopPercent, textBottomPercent).
Features:
- All 8 handles support resize (corners resize two axes, midpoints resize one axis)
- Dragging the body moves the entire container
- Snap guides appear at 25%, 50%, 75% positions with 2% snap threshold
- A live tooltip near the cursor shows current percentage values during drag
- Zoom compensation ensures accurate coordinate math at all preview scales
- Minimum 10% width and height enforced
Phone Preview Parity (VISEDITOR-15)
The portrait device preview now matches what the SMACKZ-MOBILE React Native app renders on the selected phone model.
The problem: Non-hero section heights used browser vh units instead of the selected device's viewport height. A section set to 50% height would render at 450px in a 900px browser window instead of the correct 395px for an iPhone 14.
Three-phase fix:
- Phase 1 (shipped): Non-hero section heights now use
getSectionHeight(heightPercent, navHeight, viewportHeight)instead of${heightPercent}vh. When iPhone 14 is selected, heights calculate from 844px minus 55px nav = 789px available. - Phase 2 (planned): Render the preview frame at full device dimensions with a CSS
transform: scale()to fit. This removes thePORTRAIT_SCALE = 0.55font hack and achieves 1:1 proportional parity. - Phase 3 (planned): Fix RN-side inconsistencies where
NativeHeroSectionandNativeFeaturedMenuSectionskip nav height subtraction. Add screenshot parity testing.
Architecture
All visual editor code lives under Smackz-Websites/src/pages/pages/components/visual-editor/. The page-renderer changes are limited to adding data-role attributes -- no structural or behavioral changes.
visual-editor/
SelectionOverlay.tsx -- Click capture + hover/selection rendering
SelectionHighlight.tsx -- Blue outline + 8 handles
ElementLabel.tsx -- Role label badge
FloatingToolbar.tsx -- Contextual toolbar with positioning
DragHandles.tsx -- Draggable handles for text container
SnapGuides.tsx -- Snap guide lines during drag
useSelectionState.ts -- Selection state + coordinate math
useDragHandle.ts -- Drag state + zoom compensation
toolbar-controls/ -- Compact control components
Related Pages
- Page Renderer -- rendering engine that the visual editor operates on
- Restaurant Websites -- the app containing the visual editor