Skip to content

<CoarPageBuilder> Preview

The visual-editor half of @cocoar/vue-page-builder. Renders a three-panel layout — outline tree on the left, canvas with palette in the centre, properties panel on the right — and emits a PageNode JSON tree as v-model. The same tree is consumed by <CoarPageRenderer> at runtime.

All three panels are resizable via drag handles and collapsible.

Props

PropTypeDefaultDescription
modelValue / v-modelPageNodeempty pageThe page schema. Bound two-way; every edit updates the ref.
configPageConfigAllowed elements, available actions, asset callbacks. The same value must be passed to the renderer.

Features

  • Palette toolbar — drag containers (Stack, Card, Section) and elements onto the canvas. Hidden types per config.allowedElements.
  • Outline tree — hierarchical node list with selection, drag-to-reorder, inline add/delete. Stacks display "Column" or "Row" based on direction. Warning icons (⚠ / ⛔) mark nodes with validation issues.
  • Canvas — real component previews with dashed selection borders. Switches to live preview in the Preview tab and to a paste-and-apply JSON editor in the JSON tab.
  • Properties panel — per-element configuration. Each element type ships its own props component. Validation issues for the selected node are surfaced at the top with colored banners.
  • Stack direction toggle — change a stack from column to row direction without re-creating it. Children stay put.
  • Asset picker entry point — when config.pickAsset is set, the image element shows a thumbnail + "Choose…" button that defers to your own picker UI.
  • Responsive preview — Desktop · Tablet · 768 · Mobile · 375 segmented toggle in the Preview tab. The render area is capped and centered so you can verify the design at common breakpoints.
  • Undo / redoCtrl+Z / Ctrl+Y (or Cmd+Z / Cmd+Shift+Z), also via toolbar buttons.
  • KeyboardDelete / Backspace removes the selected node (when focus is not in an input).
  • JSON paste migration — legacy column / row types are auto-coerced to stack on import; other non-page root types are auto-wrapped in a page.

Builder-side validation

The builder runs schema-level validation reactively and surfaces issues at two layers:

  • Outline — a warning icon next to the affected node row (red ⛔ for errors, yellow ⚠ for warnings). Hover the icon for the full message.
  • Props panel — a colored banner at the top of the selected node's properties listing every issue for that node.

Built-in rules:

RuleSeverity
Button / link has no Actionwarning
Action ID is not in config.availableActionswarning
Image has no Asset IDerror
Two named inputs share the same nameerror

Validation is a builder UX scaffold — it does not affect what the renderer does. The renderer is governed by allowedElements (the hard security boundary) and by which handlers exist in the actions map.

Per-element architecture

Each element type brings its own props component, registered in a single map:

packages/page-builder/src/builder/props/
├── registry.ts        ← ElementType → { component, sectionTitle }
├── StackProps.vue
├── CardProps.vue
├── HeadingProps.vue
├── ButtonProps.vue
├── ImageProps.vue
├── …
└── StyleProps.vue     ← universal Gap/Padding/Width/Align

The main BuilderPropsPanel.vue is a thin shell that resolves the registry entry and renders <component :is="entry.component" :node :patch />. Adding a new element type requires creating one new <Type>Props.vue file and adding one line to the registry — no central files are touched.

Pairing with the renderer

The builder's Preview tab uses <CoarPageRenderer> internally, passing through config.assetResolver so thumbnails work without extra wiring. For the actual runtime page (outside the builder), you mount the renderer yourself — see <CoarPageRenderer> and the integration walkthrough.

Released under the Apache-2.0 License.