Skip to content

Live CSS Preview Implementation Plan

Status: COMPLETED (2026-03-24)

Goal: Provide instant visual feedback in the preview iframe during scrub drag by updating DataStore directly instead of full engine rebuild.

Architecture: During scrub, LocalBuildPreview sends block data to the iframe via a creative-block-update CustomEvent. preview-iframe.ts deep-merges into DataStore.creativeSettings.creativeBlocks, and Vue 3's deep reactivity automatically regenerates the affected block's CSS. One full rebuild fires on mouseup.

Tech Stack: Vue 3 reactivity (Creative Engine), Vue 2 Options API (Application-Frontend), CustomEvent for iframe communication.

Spec: docs/superpowers/specs/2026-03-24-live-css-preview-design.md

Key finding: DataStore.creativeSettings was a plain {} — wrapping it in reactive() was the critical missing piece that made the entire approach work.


File Structure

FileRepoChangePurpose
src/services/dataStore.tsCreative-EngineModify (1 line)Wrap creativeSettings in reactive()
src/entry.tsCreative-EngineAlready exportedDataStore export
src/preview-iframe.tsApplication-FrontendModify (~30 lines)Handle creative-block-update event with deep-merge
src/pages/.../Preview/LocalBuildPreview.vueApplication-FrontendModify (~30 lines)Send block updates during scrub, MutationObserver for scrub end

Task 1: Export DataStore from Creative Engine

  • [x] Step 1: Add DataStore export — already present in entry.ts
  • [x] Step 2: Verify build — clean
  • [x] Step 3: Commitfeat: export DataStore for live preview integration

Task 2: Make creativeSettings reactive

  • [x] Step 1: Wrap in reactive()creativeSettings: reactive({} as CreativeSettings) in dataStore.ts:52
  • [x] Step 2: Verify build — clean (tsc --noEmit exit 0)
  • [x] Step 3: Commitfeat: make creativeSettings reactive for live preview support

Task 3: Add block update event handler in preview-iframe

  • [x] Step 1: Add DataStore import
  • [x] Step 2: Add event listener + deepMergeReactive
  • [x] Step 3: Verify build — clean
  • [x] Step 4: Commitfeat: handle creative-block-update event for live CSS preview + refactor: use deep-merge for block update to preserve reactive proxies

Task 4: Send block updates from LocalBuildPreview during scrub

  • [x] Step 1: Add lodash get import
  • [x] Step 2: Add selectedBlockPath to mapState
  • [x] Step 3: Update watcher to send block update during scrub
  • [x] Step 4: Add sendBlockUpdate method
  • [x] Step 5: Add MutationObserver for scrub-end rebuild
  • [x] Step 6: Verify build — clean
  • [x] Step 7: Commitfeat: send block updates to iframe for live CSS preview during scrub

Task 5: Manual verification

  • [x] Tested and confirmed working by user (2026-03-24)

Internal documentation