Layout Composition

Live Preview Wizard

A two-column onboarding layout with a stepped form on the left and a live preview canvas on the right — input morphs into the preview instantly, and step changes slide the form directionally while the preview cross-fades.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add live-preview-wizard.en

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

Active edited usageDefault props
<LivePreviewWizard/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add https://webberui.com/r/live-preview-wizard.en.json

Or, once registries are configured in components.json, install it as @webberui/live-preview-wizard.

Usage

Declare each step's form fields with <LivePreviewWizardStep>, and supply the right-hand live preview through preview. Fields inside a step read and write the shared values through useLivePreviewWizard, so input is reflected in the preview instantly.

import {
  LivePreviewWizard,
  LivePreviewWizardStep,
  useLivePreviewWizard,
} from "@/components/ui/live-preview-wizard";

type Form = {
  name: string;
};

function NameField() {
  const { values, setValue } = useLivePreviewWizard<Form>();
  return (
    <input
      value={values.name}
      onChange={(e) => setValue("name", e.target.value)}
    />
  );
}

function Preview() {
  const { values } = useLivePreviewWizard<Form>();
  return <h1>{values.name || "Your product"}</h1>;
}

export function Example() {
  return (
    <LivePreviewWizard<Form>
      defaultValues={{ name: "" }}
      preview={<Preview />}
      onComplete={(values) => console.log(values)}
    >
      <LivePreviewWizardStep label="Brand">
        <NameField />
      </LivePreviewWizardStep>
    </LivePreviewWizard>
  );
}

Props

LivePreviewWizard

PropTypeDefaultDescription
childrenReactNode—Step declarations, all <LivePreviewWizardStep>
previewReactNode | (ctx) => ReactNode—Default live preview content, used when a step does not supply its own
valuesT—Controlled form data; when omitted, the component manages it internally (uncontrolled)
defaultValuesT{}Initial data in uncontrolled mode
onValuesChange(values: T) => void—Fires when the data changes, with the latest complete data
stepnumber—Controlled current step index; when omitted, the component manages it internally
defaultStepnumber0Initial step in uncontrolled mode
onStepChange(step, direction) => void—Fires when the step changes (direction: 1 forward, -1 back)
onComplete(values: T) => void—Fires when "Complete" is pressed on the last step
progress"dots" | "bar" | false"dots"Progress indicator style; false hides it
controlsbooleantrueWhether to render the built-in back / next control bar
previewSide"left" | "right""right"Which side the preview canvas sits on for wide screens
previewLabelstring"preview.app"Text in the preview frame's faux address bar
backLabel / nextLabel / completeLabelstringBack / Next / DoneControl bar button text
classNamestring—Appended to the outer grid's className

LivePreviewWizardStep

PropTypeDefaultDescription
labelstring—Step title shown in the progress indicator
childrenReactNode—This step's form fields
previewReactNode | (ctx) => ReactNode—Preview specific to this step, overriding the container's preview
classNamestring—Appended to the step container's className

useLivePreviewWizard<T>()

Returns the current values, setValue(key, value), setValues(partial), plus navigation state such as step / total / direction / isFirst / isLast / goTo / next / back. It must be called inside <LivePreviewWizard>.

How it works

  • Both modes: values and step each support controlled (pass the prop) and uncontrolled (defaultValues / defaultStep) usage.
  • Live morph: fields write into the shared values through setValue, and the preview repaints instantly within the same step; for color changes, pair it with CSS transition-colors to make the morph smoother.
  • Direction aware: next / back / goTo derive the switch direction, so the form slides horizontally and the preview cross-fades.
  • Per-step preview: setting preview on a <LivePreviewWizardStep> lets different steps emphasize different things, cross-fading naturally as you move between them.

Accessibility

  • The progress dots / bar carry role and aria-* attributes; steps you have already reached are clickable to jump to, and the ones you have not are disabled.
  • Step blocks carry aria-roledescription="Steps" (step) and an aria-label, and the current step is announced through aria-live="polite".
  • The preview canvas carries aria-label="Instant Preview" (live preview); the control bar buttons are all keyboard operable and have focus styling.
  • When the user has "reduce motion" enabled, the slide becomes a fade in / fade out and the spring transitions are disabled, with no impact on the layout structure.