Release: unified-editor redesign — palette, stylus signatures, annotate & placement upgrades#127
Merged
Conversation
…ng fix Placement & sizing UX upgrade across the canvas editor: - Shared resize-handles module (resize-handles.ts): 8-handle hit-test, free + aspect-locked corner resize, selection chrome. AnnotateTool refactored onto it (behaviour-identical). - Signature: place then drag a corner to resize (aspect-locked, no slider); Background switch (ink-only/transparent default vs opaque colour) with a WYSIWYG preview (transparency checker, no misleading white); fixed a placed signature being invisible on tool return yet still applied. - QR / barcode: converted to a place-then-drag-resize canvas tool (addCodeStampAt burns explicit-rect vector art); "Same spot on all N pages" replicates a code to every page, still movable per page. - Page numbers / Header & footer / Bates: live on-canvas preview (Stage) mirroring each writer's geometry; state moved to the tool slice; Apply unchanged. - Auto-fill: fix focus ring clipped on the left inside the scrollable field list (overflow-y-auto also clips x) by padding the scroll box; audited the other scroll/overflow containers (all already padded). Tests: resize-handles + addCodeStampAt unit tests; place-resize (desktop + mobile) and editor-features (every fixture PDF) e2e harnesses. vp check, 306 unit tests, both editor smokes, and vp build all pass.
…ge handling for signatures
…, accent dedup, pdf robustness - Toggle now renders the shared pill Switch everywhere (one binary-toggle look across panels); drop ExportModal's duplicate Switch and import the shared one. - PrimaryAction + OCR 'Make searchable' show a Loader2 + aria-busy while running, matching every other busy button (no more spinner-less 'Working…'). - Consolidate the duplicated ACCENT='#2563eb' (signature/QR/annotate) into one exported constant in resize-handles.ts — single source for overlay chrome. - metadata: empty Keywords clears the entry (no blank ['']); read tolerates encrypted files (ignoreEncryption) like its siblings. - addSignature skips stale/out-of-range page indices instead of hard-throwing. - DigitalSignature 'checking…' status gets role=status. Add metadata unit tests.
…e move/resize - New 'Icons' tool in Annotate stamps vector glyphs for filling printed forms by hand — tick a checkbox, cross a box, fill a radio dot, circle a choice. - Shared unit-square geometry (annotate.ts) drives BOTH the canvas preview and the pdf-lib burn, so what you place is exactly what exports. - Unified Icon mode mirrors the signature/QR model: tap empty page to stamp (sticky, for many ticks in a row); tap a placed glyph to select, drag to move, pull a CORNER to resize (aspect-locked — never distorts); recolor/retype a selected one from the palette. Delete removes it. - Add icon unit tests (geometry + burn round-trip).
- The editor route's Suspense fallback is now a full-screen CENTERED spinner matching EditorShell's own 'Opening PDF…' spinner, so the chunk-load → parse handoff shows ONE loader in ONE place (was a top spinner then a centered one). - README: reflect the real 22 editor tools / 7 utilities and the new icons; drop the stale '18 tools' comment in App.tsx.
CodeQL js/missing-origin-check (medium): the dedicated worker's onmessage accessed e.data without checking the event origin. A dedicated worker only receives messages from the same-origin parent that spawned it (origin is the empty string), so reject any foreign-origin message before touching the payload — defence in depth that also clears the alert.
- js/insecure-temporary-file (high ×2): the place-resize e2e scripts wrote fixtures/screenshots to predictable paths in the shared OS temp dir. Default SHOT_DIR to a per-run unique dir via mkdtempSync(tmpdir()/'cloakpdf-e2e-*'). - js/useless-assignment-to-local (warning): drop the dead 'nh = nw / aspect' in resizeBBoxAspect — nh is unconditionally recomputed from the clamped width two lines later, so the intermediate assignment was never read. Behaviour unchanged (11 resize-handles unit tests still green).
Editor: drag-resize placement, signatures, annotate icons + audit pass
The warm-cache return-visit step failed reproducibly as 'composer never enabled / stuck at Preparing'. Root cause was the TEST, not the product: after the reload the home grid paints first and the Ask-PDF card-click navigation is async, so the bare `input[type=file]` selector matched the HOME drop zone (still in the DOM during the view transition). Uploading there opens the EDITOR, not Ask PDF, so the composer never appears. Fix: before grabbing the input, wait for the tool-only 'drop a PDF to start chatting' hint (not the home card's 'runs entirely on-device' description) to pin us to the Ask PDF tool with models ready, then take the last file input. Verified: the warm path re-hydrates models from CacheStorage and the cached index from IndexedDB and answers correctly — full `pnpm test:e2e` now passes end to end (cold + warm overview, phone/email/address extraction, tier swap).
Adds editor-level keyboard control, the connective tissue for navigating a 23-tool editor that previously had button-only undo/redo and no quick switcher. - ⌘/Ctrl-K opens a command palette that searches every tool by name, family, and description (token-based, order-independent) and leads with the global actions (undo/redo/reset) when available; full keyboard nav + click select. - ⌘/Ctrl-Z undo, ⌘/Ctrl-(Shift-)Z / ⌘/Ctrl-Y redo at the editor level, guarded so native text undo wins inside input/textarea/contenteditable fields. - A Search affordance pinned atop the tool rail makes the palette discoverable. - Mirrors the home ⌘K idiom; HomeScreen unmounts in-editor so no conflict. Verified: vp check, vp test (312), vp build, plus a new headless e2e (command-palette.e2e.ts) and a no-regression run of editor-smoke.
Makes the signature pad feel like real pen on paper, and lets digital styluses drive it natively. - "Realistic ink" toggle (Draw mode, off by default): stroke weight modulates and a soft low-alpha blurred copy under the crisp ink simulates bleed into paper, via an offscreen buffer so overlapping segments don't darken the halo. - Pad input migrated from Mouse+Touch to the Pointer Events API — one path for mouse, touchpad, finger, and styluses (Apple Pencil, Wacom, Android/S-Pen, Surface Pen). Real `pressure` drives the realistic weight when present, with a speed-based fallback for pressure-less devices (mouse/touch). High-rate coalesced samples for pens, pointer capture so a stroke survives leaving the canvas, and pen-priority palm rejection (a stray finger is ignored mid-pen). - Per-point pressure stored with the stroke paths, so colour/ink-mode replays keep the pen look. Canvas `filter` feature-detected (weight-only fallback). Verified: vp check, vp test (312), vp build, a new e2e (signature-pen.e2e.ts) exercising pen-with-pressure / mouse / touch / palm rejection over CDP, and a no-regression run of editor-smoke (which drives the pad via mouse).
Selecting a tool from the command palette (⌘K) could target one below the fold of the scrollable rail, leaving the active tool selected but off-screen. On active-tool change, scroll its rail button into view with `block: "nearest"` (minimal scroll, no-op when already visible, e.g. a normal rail click) and honour prefers-reduced-motion. Also hardens the command-palette e2e: wait for the filtered "Page numbers" row to render before clicking (was racing React's re-render), and add a step that asserts a bottom tool (Attach) scrolls into view on selection.
Palette search reached descriptions, so "attach" surfaced Scrub (its blurb says "…attachments…") above the Attach tool. Add a relevance score that ranks a match in the tool NAME above one only in the hint/description — exact name > name prefix > name substring, then per-token name > hint > description — and sort the filtered results by it (roster order on ties). Description matches still appear, just below name matches. e2e updated to assert the ordering: "page numbers" tops Strip furniture and "attach" tops Scrub, each selectable with a plain Enter.
Reflect the recent editor work in "What it does": signatures now support a real-pen ink feel and pressure-sensitive styluses (Apple Pencil / Wacom / S-Pen), and the editor has a ⌘K command palette plus undo/redo shortcuts.
Editor: ⌘K command palette, keyboard shortcuts & realistic-ink/stylus signatures
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
cloakpdf | 5722186 | Commit Preview URL Branch Preview URL |
Jun 23 2026, 06:43 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promotes the accumulated
devwork tomain(covers merged PRs #119 and #126).Highlights
Unified editor — navigation & keyboard
Signatures
Annotate & placement
Hardening & housekeeping
Testing
vp check,vp test(312 passing),vp build— green across the included work.🤖 Generated with Claude Code