docs: add Phase 2 builder upgrade design document

Covers drag & drop, side-by-side preview, and snapshot-based undo/redo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Luca Oelfke 2026-02-13 15:30:01 +01:00
parent bad48e5f5e
commit b8f275e78d

View file

@ -0,0 +1,135 @@
# Phase 2 — Builder Upgrade Design
**Status:** Approved
**Date:** 2026-02-13
**Scope:** Drag & drop field reordering, side-by-side live preview, snapshot-based undo/redo
---
## Overview
Phase 2 upgrades the FormBuilderModal with three features that transform it from a basic editor into a polished builder experience. All changes are scoped to `form-builder.ts` and `styles.css`, with no new modules needed.
---
## 1. Drag & Drop Field Reordering
### Implementation
Native HTML5 Drag & Drop on `.ff-builder-field` elements:
- Each field gets `draggable="true"` and a drag handle (`⠿` gripper icon) in the header
- `dragstart`: Stores source index in instance variable `dragSourceIndex`
- `dragover`: Calculates drop position (above/below element center), shows CSS indicator
- `dragleave`: Removes drop indicator
- `drop`: Reorders `draft.fields` array, calls `this.render()`
- Instance variable `dragSourceIndex: number | null` tracks the dragged field
### Existing Up/Down buttons remain
They serve as accessibility fallback for keyboard-only users.
### CSS Classes
- `.ff-drag-handle` — Gripper icon, `cursor: grab`, left of field number
- `.ff-builder-field.ff-dragging``opacity: 0.4` during drag
- `.ff-builder-field.ff-drop-above` — Blue top border indicator line
- `.ff-builder-field.ff-drop-below` — Blue bottom border indicator line
---
## 2. Side-by-Side Live Preview
### Layout
The `render()` method creates a two-column grid layout:
```
┌─────────────────────────────────────────────┐
│ Form Settings (h2) │
├──────────────────────┬──────────────────────┤
│ Editor (left) │ Preview (right) │
│ - General settings │ - Form title │
│ - Fields list │ - Rendered fields │
│ - Add field button │ - Submit button │
├──────────────────────┴──────────────────────┤
│ Footer: Undo/Redo | Cancel | Save │
└─────────────────────────────────────────────┘
```
### Preview Panel
- Calls existing `renderField()` from `field-renderers.ts` for each field
- Fields are fully interactive (users can test how they feel)
- Shows form title and a disabled pseudo-submit button
- Automatically updates on every `render()` call (no separate mechanism)
- Uses `this.app` for note-link and folder-picker autocomplete
### CSS Changes
- `.ff-builder-layout``display: grid; grid-template-columns: 1fr 1fr; gap: 24px`
- `.ff-builder-preview``border-left`, `padding-left`, sticky "Preview" header
- `.ff-builder-modal``max-width` increased from 700px to 1100px
- Footer spans full width below the grid
---
## 3. Snapshot-Based Undo/Redo
### State
New instance variables on `FormBuilderModal`:
```typescript
private history: FormDefinition[] = [];
private historyIndex: number = 0;
```
### Methods
- `pushSnapshot()``structuredClone(this.draft)` pushed to history. Truncates forward history (everything after `historyIndex`). Max 30 entries.
- `undo()` — Decrements `historyIndex`, restores draft from snapshot, calls `render()`
- `redo()` — Increments `historyIndex`, restores draft from snapshot, calls `render()`
### When snapshots are pushed
Before mutations that trigger `render()`:
- Add field
- Delete field
- Move field (drag & drop, up/down)
- Change field type
- Change form mode (create/update)
NOT on every keystroke — only on `change` events (blur/enter) for text inputs.
### Keyboard Shortcuts
- `Ctrl+Z` / `Cmd+Z` → undo
- `Ctrl+Shift+Z` / `Cmd+Shift+Z` → redo
- Keydown listener on `contentEl`
### Visual Indicators
- Undo (`↩`) and Redo (`↪`) buttons in footer, left-aligned (before Cancel/Save)
- Buttons are disabled when at start/end of history stack
### Initialization
Constructor pushes first snapshot of original form state.
---
## Files Changed
| File | Change |
|------|--------|
| `src/ui/form-builder.ts` | Drag & drop, preview panel, undo/redo — major rewrite |
| `styles.css` | DnD indicators, grid layout, preview panel, undo/redo buttons |
## Out of Scope
- Undo for individual text keystrokes (browser-native handles this)
- External undo manager utility
- Drag & drop between forms
- Preview in a separate modal/window
- Collapsible preview panel