Skip to content

V4.0.0#555

Open
prc5 wants to merge 45 commits intomasterfrom
v4.0.0
Open

V4.0.0#555
prc5 wants to merge 45 commits intomasterfrom
v4.0.0

Conversation

@prc5
Copy link
Copy Markdown
Collaborator

@prc5 prc5 commented Apr 6, 2026

No description provided.

prc5 added 15 commits April 6, 2026 13:49
Deterministic test harness with uniform interpolation for velocity,
9 regression spec files covering all testable open bugs.

Results: 21 FAILING (active bugs), 25 PASSING (fixed in v4).
11 bugs remain N/A (not testable in jsdom).

Closes #168
Closes #241
Closes #250
Closes #286
Closes #323
Closes #364
Closes #392
Closes #404
Closes #406
Closes #408
Closes #423
Closes #427
Closes #431
Closes #432
Closes #463
Closes #479
Closes #483
Closes #487
Closes #495
Closes #498
Closes #524
Closes #547
Ref #112
Ref #283
Ref #316
Ref #363
Ref #396
Ref #418
Ref #434
Ref #437
Ref #438
Ref #439
Ref #443
Ref #460
Ref #462
Ref #467
Ref #506
Ref #508
Ref #516
Ref #529
Ref #538
Ref #545
Ref #553

Made-with: Cursor
handleZoomToViewCenter and resetTransformations now emit
onZoomStart, onZoom, and onZoomStop callbacks, matching the
sequence fired by user-driven wheel/pinch gestures.

Also assigns ref context on init for stable ref API access.

Closes #369
Ref #553

Made-with: Cursor
117 tests across 18 spec files covering every leaf prop on
ReactZoomPanPinchProps (TransformWrapper), TransformComponent,
MiniMap, and KeepScale — children, ref, disabled, initial transform,
bounds/positions, scale limits, rendering, wheel, panning, pinch,
trackpad panning, double-click, zoom animation, auto alignment,
velocity animation, and all callbacks.

Made-with: Cursor
… lock, double-click, wheel-while-pan, zoom-to-element

- pan.bounds: limitToBounds edge clamping, min/maxPosition, autoAlignment
  snap-back, axis lock, velocity with bounds
- pan-touch.bounds: touch panning bounds and axis lock
- pan-track-pad.bounds: trackpad panning bounds and axis lock
- zoom.wheel-while-pan: wheel suppression during active pan, ctrl+wheel,
  activationKeys
- zoom.double-click: step, mode (reset, toggle), excluded elements
- zoom-to-element: zoomToElement focuses child, handler exists on ref

Made-with: Cursor
…ols suites

Add new test suites for minimap (rendering, panning, sync), controls
(callbacks, limits, ref, state), and extreme edge cases (extreme sizes
and bounds for pan, pinch, zoom). Expand existing tests across base,
positions, pan-touch, pan-track-pad, and exclusion features for broader
coverage.

Made-with: Cursor
…unds calculation

Bounds calculation now honours the disablePadding flag (locks content
when it fits the wrapper) and applies minPositionX/maxPositionX/
minPositionY/maxPositionY prop overrides. Pinch and wheel handlers
enforce these explicit bounds via hasExplicitPositionBounds. Initial
state creation clamps scale to minScale/maxScale and respects position
bounds.

Also includes:
- src/ added to published package files for source maps
- ResizeObserver mock in jest.setup for centerOnInit flows
- Test assertions updated for synchronous setTransform calls and
  correct pan directions
- Storybook enhanced with bounds overlay, cinema venue example, and
  mixed-content demos

Made-with: Cursor
…m drift

setState was rounding scale to 2 decimal places and position to 3 decimal
places via parseFloat(toFixed(N)). During rapid trackpad pinch-to-zoom
(many small sequential wheel events), this quantization compounded
frame-over-frame, causing the zoom center to visibly tremble and drift.

Also removes stale hasExplicitPositionBounds reference from wheel.logic
(already deleted from bounds.utils).

Made-with: Cursor
When the library runs inside an iframe, mouseup and keyup events fired
in the parent frame never reach the iframe listeners, causing pan jumps
and stuck activation keys.

- Detect missed mouseup by checking event.buttons === 0 on mousemove
- Clear pressedKeys and isPanning on window blur
- Sync modifier keys (Ctrl, Meta, Shift, Alt) from mouse/wheel events
  so activation keys work without requiring focus/keydown
- Scale explicit position bounds (minPositionX, etc.) with zoom level
  so the same content-space region stays reachable at every scale

Updates all test mouse events to include the buttons property matching
real browser behavior, adds iframe and bounds-scaling regression tests,
and improves the cinema story with a seat map widget.

Made-with: Cursor
The velocity guards (isVelocityCalculationAllowed, isVelocityAllowed,
handlePanningEnd) incorrectly gated on `scale > 1`, preventing inertia
for natively large content at default zoom. Replaced with an actual
content-vs-wrapper overflow check using offsetWidth/offsetHeight.

Also fixed a click-after-zoom snap bug where tiny mouse jitter (<=5px)
during a click would trigger velocity panning, flinging the viewport.
A minimum displacement threshold now distinguishes clicks from real pans.

Additional changes:
- Round scale in CSS transform to strip binary float noise
- Fix incorrect || logic in isVelocityAllowed (should be &&)
- Refactor storybook Controls with icon buttons and glassmorphism UI
- Fix pinch direction in test utility
- Expand and simplify test suites

Closes #363

Made-with: Cursor
- syncModifierKeys: only set keys to true, never clear them; clearing
  is handled by keyup and handleWindowBlur (fixes activation key tests)
- onTouchPanning: guard preventDefault with event.cancelable check
- checkZoomBounds: restore padding logic so trackpad pinch can
  temporarily overshoot minScale/maxScale with rubberband snap-back
- handleAlignToScaleBounds: handle both below-minScale and
  above-maxScale snap-back after gesture ends
- calculatePinchZoom: wire pinch.step into scale calculation and round
  to avoid IEEE 754 epsilon
- createState: clamp initialScale to minScale/maxScale and apply
  boundLimiter to initialPositionX/Y
- instance.update: skip bounds calculation when components not mounted
- getControls / ReactZoomPanPinchContentRef: expose state on the
  ref so useImperativeHandle re-renders don't lose it
- Test harness: patch HTMLElement.prototype offsetWidth/Height to
  derive dimensions from inline styles (jsdom polyfill); add zoom
  helper precision snap with activation-key and maxScale guards
- Fix test expectations for pan direction, centering, and resize
- Add 10 elastic zoom bounds tests covering overshoot, snap-back,
  disablePadding, zoomAnimation.disabled, and mouse-wheel strictness

Closes #396
Closes #438
Closes #516
Closes #553

Made-with: Cursor
…of keyDown

Test helpers now propagate ctrlKey/shiftKey/etc. through synthesized
mouse and wheel events rather than dispatching separate keyDown events.
This mirrors how syncModifierKeys reads modifier state from interaction
events, making tests more realistic—especially for iframe scenarios
where keydown never fires.

Also simplifies Storybook controls: replaces custom CSS tooltips with
native title attributes and collapses multi-line SVG attributes.

Made-with: Cursor
syncModifierKeys now writes both true and false states from event
modifier flags instead of only setting keys to true. This prevents
stale pressed-key state when keyup never fires (e.g. unfocused iframe).

Also passes the actual clamped scale from this.state.scale to the
onTransform callback instead of the pre-clamp local variable.

Made-with: Cursor
syncModifierKeys reads ctrlKey/metaKey from the event itself (required
for iframe support), so fireEvent.keyDown alone is insufficient — the
subsequent WheelEvent must carry the modifier flag just like a real
browser would. Also adds a positive assertion for the predicate-based
activationKeys test.

Made-with: Cursor
Rewrite the introduction and MDX docs with clearer copy, modern TSX snippets, and updated links. Consolidate the separate image size stories into one image example, add a padding example, and align hooks and example components with the new structure.

Restyle the story Code helper for inline snippets and declare .jpeg/.png modules for typed image imports in examples.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant