Feat/canvas preview overlay#66
Merged
Merged
Conversation
Replaces the separate-window LabelPreviewModal with an in-canvas overlay so the user can flip between the editor and the Labelary- rendered output at the same scale, position and rotation as a true 1:1 comparison. Store: `previewMode` is a state machine (idle, loading, active, error) with `enterPreviewMode` (async; runs ZPL emit + Labelary fetch) and `exitPreviewMode`. The fetched blob URL lives in the active state and is revoked on exit. Persistence whitelist already excludes `previewMode`, so reloading drops to idle. Canvas: the rendered KImage swaps in for the editor leaves at the same `labelOffset*` / `labelWidthPx`/`HeightPx` coordinates, which means viewRotation and zoom apply naturally to both views. The Transformer, lasso, guides, ghost-drop, rotation button and visibleLeaves all skip when the overlay is on. Mouse handlers (pan, lasso, stage click), keyboard handlers (delete, arrow keys, all useGlobalShortcuts entries) and palette drop guard on `selectPreviewLocksEditor` so the design cannot drift away from the frozen snapshot under the user's hands. PaginationControl disables its next/prev/delete for the same reason. ZPLOutput: the existing "Preview" button is now a toggle. First- press still flows through `LabelaryNoticeModal` for the privacy acknowledgement; subsequent activations fetch directly. Error state surfaces as an in-canvas amber banner with a close button (calls `exitPreviewMode`). Deletes `LabelPreview.tsx` — the modal had no remaining caller.
Swaps the label's default drop-shadow for a symmetric amber halo while `previewMode` is locking the editor, so the mode signal sits at the user's locus of attention (the paper) instead of only in the toolbar button at the bottom of the screen. Replaces (not stacks on) the existing shadow because layering an amber glow over the dark drop-shadow reads as a passive theme drift rather than an active mode change. Amber matches the colour the app already uses for Labelary-related warnings, so the colour language stays consistent. Glow is outward- only with `shadowOffsetY: 0` so it does not bleed into the preview image itself.
Two affordances for the editor-locked state introduced by the preview overlay: * Cursor shows `not-allowed` while `selectPreviewLocksEditor` holds. Signals the locked state at the user's locus of attention (the canvas) instead of leaving the toolbar button as the only state feedback, so an attempted edit no longer silent-fails. * Escape key now exits the overlay. Bound globally so the user can return to the editor from anywhere; the existing useGlobalShortcuts guard already short-circuits other shortcut bindings while preview locks, so there is no collision. Click-to-exit was deliberately not added — hidden affordance, risks accidental exits, and removes the option to inspect the preview without leaving the mode.
Until now the preview overlay's "freeze the editor" invariant was enforced piecemeal at the UI surfaces: canvas mouse and keyboard handlers, palette drop, useGlobalShortcuts and PaginationControl each checked `selectPreviewLocksEditor` and short-circuited. The gap: PropertiesPanel inputs, LayersPanel toggles, header undo/redo and any future caller that goes straight to a store action could still drift the design under the frozen Labelary snapshot. Move the load-bearing guard to the store. Every design-mutating action now checks the lock at entry; selection, view settings, locale, theme and the preview controls themselves stay open. The existing UI guards become defense-in-depth and keep their value for the cursor / disabled-state UX they also provide. Also wraps zundo's `useHistory` so undo and redo become no-ops while locked — header buttons would otherwise rewind state without going through the store mutator path.
There was a problem hiding this comment.
Code Review
This pull request replaces the previous modal-based Labelary preview with an integrated canvas overlay that locks the editor during active preview sessions. The implementation includes a new previewMode state in the store that prevents design mutations, disables keyboard shortcuts, and restricts pagination to ensure the preview remains in sync with the design. Visually, the canvas now displays a frozen Labelary snapshot with an amber glow and a "not-allowed" cursor to indicate the locked state. Review feedback focuses on optimizing the useHistory hook by memoizing its return value to maintain referential identity and avoid unnecessary re-renders while the editor is locked.
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.
No description provided.