- SUMMARY.md: document field-ID-keyed text fill and click-to-select interaction - STATE.md: advance to Phase 12.1 Plan 1 complete; add 3 key decisions - ROADMAP.md: update phase 12.1 progress (1/2 plans complete) - REQUIREMENTS.md: mark TXTF-01 and TXTF-03 complete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.7 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 12.1-per-field-text-editing-and-quick-fill | 01 | pdf-generation, document-editor |
|
|
|
|
|
|
Phase 12.1 Plan 01: Per-Field Text Fill and Click-to-Select Summary
One-liner: Field-ID-keyed UUID text drawing in preparePdf with Strategy A/B removed; click-to-select inline input overlay on text fields in FieldPlacer; prop chain PdfViewerWrapper -> PdfViewer -> FieldPlacer wired and ready for Plan 02.
Tasks Completed
| # | Task | Commit | Files |
|---|---|---|---|
| 1 | Replace positional text fill with field-ID-keyed lookup in preparePdf | df02a1e |
prepare-document.ts |
| 2 | Add optional text-edit props to PdfViewerWrapper, PdfViewer, FieldPlacer click-to-select | eaf377d |
PdfViewerWrapper.tsx, PdfViewer.tsx, FieldPlacer.tsx |
What Was Built
Task 1: preparePdf field-ID-keyed text fill
Replaced the broken positional text assignment pipeline in prepare-document.ts:
- Removed AcroForm Strategy A:
pdfDoc.getForm(),form.getTextField(),form.flatten(),acroFilledKeys,hasAcroForm - Removed positional sort loop:
remainingEntries,textFields_sorted,fieldConsumedKeys,textFields_sorted.forEach() - Removed Strategy B top-of-page stamp:
unstampedEntries,firstPage.drawText(${key}: ${value}, ...) - Added Phase 12.1 field-ID loop:
textFields[field.id]direct UUID lookup, draws atfield.x+4, field.y+4with font 6-11pt clamped to field height
The textFields parameter type (Record<string, string>) is unchanged — backward-compatible. Calling routes pass body.textFillData which will now be { [fieldId]: value } once Plan 02 wires the UI.
Task 2: Optional prop chain and click-to-select
PdfViewerWrapper.tsx and PdfViewer.tsx: Added 4 optional props to each and forwarded them down the chain:
selectedFieldId?: string | nulltextFillData?: Record<string, string>onFieldSelect?: (fieldId: string | null) => voidonFieldValueChange?: (fieldId: string, value: string) => void
PdfViewer also calls onFieldSelect?.(null) on Prev/Next page button clicks to deselect on page change.
FieldPlacer.tsx:
- Extended
FieldPlacerPropswith the 4 new optional props DroppableZonenow acceptsonClick?: (e: React.MouseEvent<HTMLDivElement>) => void— background clicks deselect viaonFieldSelect?.(null)when target is not inside[data-field-id]- Per-field div gets
onClickhandler: text fields callonFieldSelect?.(field.id)withe.stopPropagation()to prevent DroppableZone deselect; non-text fields callonFieldSelect?.(null) renderFields()computesisSelected = selectedFieldId === field.idandcurrentValue = textFillData?.[field.id] ?? ''- Text field content:
isSelectedshows<input data-no-move autoFocus>with transparent styling; not selected shows value or label in truncating<span> - Cursor set to
'text'for text fields (vs'grab'for others) - BoxShadow ring
0 0 0 2px {fieldColor}66when text field is selected
Deviations from Plan
None — plan executed exactly as written.
Verification
npx tsc --noEmitpasses with zero errorsprepare-document.tscontainstextFields[field.id]and does NOT containremainingEntries,unstampedEntries,fieldConsumedKeys,getForm(), orform.flatten()FieldPlacer.tsxexportsFieldPlacerwith all 4 new optional props inFieldPlacerPropsPdfViewerWrapper.tsxandPdfViewer.tsxaccept and forward the 4 new optional props- Plan 02 can wire
selectedFieldId,textFillData,onFieldSelect,onFieldValueChangestate fromDocumentPageClientwithout any additional changes to these files