Skip to content

Remove Hammer.js dependency, replace with native Pointer/Touch Events#17359

Draft
Copilot wants to merge 4 commits into
masterfrom
copilot/remove-hammerjs-dependency
Draft

Remove Hammer.js dependency, replace with native Pointer/Touch Events#17359
Copilot wants to merge 4 commits into
masterfrom
copilot/remove-hammerjs-dependency

Conversation

Copilot AI commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Hammer.js is unmaintained (last release 2019), requires extra setup in consuming apps, and wraps APIs now universally available in browsers. This PR removes the hammerjs / @types/hammerjs peer dependency entirely and replaces all gesture handling with native Pointer Events.

Shared gesture manager

A single zoneless IgxTouchManager (in igniteui-angular/core, core/src/core/touch.ts) consolidates the pan/swipe/tap recognition that was previously duplicated across components. It is built on native Pointer Events and exposes a small callback API (panStart, panMove, panEnd, panCancel, tap, swipe), computing deltaX/deltaY/distance/velocity/center along with preventDefault/resetOrigin helpers. It is configurable via pointerTypes, setPointerCapture, tapThreshold, and swipeVelocityThreshold (default 0.3 px/ms).

The manager does not depend on NgZone — it attaches plain native listeners and consumers mutate their own state inside the callbacks. The library stays zoneless; no NgZone is injected into the gesture consumers.

Component migrations

  • Carousel — consumes IgxTouchManager; pointerdown/pointermove/pointerup with velocity calculation replaces tap, panleft/right/up/down, panend. Axis routing (onPan) preserves the vertical/horizontal pan guards.
  • Navigation Drawer — consumes IgxTouchManager on the document; pointer listeners replicate swipe, panstart, panmove, panend with the same internal event shape
  • List Item — consumes IgxTouchManager; @HostListener('panstart/panmove/panend/pancancel')pointerdown/pointermove/pointerup with setPointerCapture
  • Time Picker (IgxItemListDirective) — consumes IgxTouchManager; vertical pan → threshold-based pointermove delta tracking
  • Grid Cells (base + 3 subclasses) — doubletap Hammer event → native touchend double-tap detection (300ms threshold, iOS only)

Mouse events are excluded where the original Hammer config only handled touch input.

Infrastructure removal

  • Core exports: HammerGesturesManager, HammerInput, HammerStatic, HammerManager, HammerOptions no longer exported from igniteui-angular/core (the dead touch-annotations.ts is removed); the new IgxTouchManager is exported instead
  • ng-add schematic: removed addHammer prompt/option and addHammerToConfig logic from dependency-handler.ts
  • Karma configs (8 files): removed hammerjs/hammer.min.js and hammer-simulator script patterns
  • angular.json: removed hammerjs from polyfills arrays
  • tsconfig.spec.json (2 files): removed hammerjs from types
  • package.json: removed hammerjs, @types/hammerjs, hammer-simulator from root devDependencies; removed peer deps from library package.json

Test updates

Removed all Hammer-specific imports, mocks, spies, and test cases from the affected spec files, and updated the gesture specs to dispatch native PointerEvents instead of Hammer simulator events. Navigation drawer gesture handler unit tests are preserved — they call the same private methods with plain objects instead of HammerInput. All affected suites pass (list, carousel, time-picker, navigation-drawer).

Breaking change

Documented in CHANGELOG under 22.0.0 > Breaking Changes. Apps that imported hammerjs solely for Ignite UI can remove it from dependencies, angular.json scripts/polyfills, and any import 'hammerjs' statements.

Copilot AI added 2 commits June 25, 2026 14:46
Replace HammerGesturesManager with native pointer events in all components:
- Carousel: native pointerdown/pointermove/pointerup for pan/swipe/tap
- Navigation Drawer: native pointer events on document for swipe/pan
- List Item: native pointer events replacing @HostListener pan bindings
- Time Picker: native pointer events for vertical pan scrolling
- Grid Cells: native touchend-based double-tap detection for iOS

Infrastructure cleanup:
- Remove HammerGesturesManager and touch-annotations exports from core
- Remove hammerjs/@types/hammerjs from package.json dependencies
- Remove hammer from all karma configs, angular.json, tsconfig files
- Update ng-add schematic: remove addHammer option and install logic
- Clean up igniteui-angular-extras ng-package.json

Closes #17358
Update test files to remove HammerGesturesManager, HammerInput,
HammerOptions imports and mocking. Remove hammer-specific test cases
from ng-add schematic tests. Update navigation drawer gesture handler
tests to use plain objects instead of HammerInput type.

Also update CHANGELOG.md with breaking change note for Hammer.js removal.
Copilot AI changed the title [WIP] Remove Hammer.js dependency and implement native gesture support Remove Hammer.js dependency, replace with native Pointer/Touch Events Jun 25, 2026
Copilot AI requested a review from ChronosSF June 25, 2026 15:00
@ChronosSF

Copy link
Copy Markdown
Member

@copilot , the lib needs to be zoneless. Why are you injecting ngzone everywhere? Also can't you combine the implementation logic into a separate touch manager so that we don't repeat the same pan/swipe logic between all files?

Copilot AI commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@copilot , the lib needs to be zoneless. Why are you injecting ngzone everywhere? Also can't you combine the implementation logic into a separate touch manager so that we don't repeat ...

Addressed in aed8dce.

  • The shared pan/swipe/tap logic now lives in a single IgxTouchManager class in core (core/src/core/touch.ts). Carousel, Navigation Drawer, List Item and Time Picker all consume it via callbacks, so the gesture recognition is no longer duplicated per component.
  • IgxTouchManager is zoneless — it attaches plain native pointer listeners and does not touch NgZone. I removed the NgZone injections I had added to those four components; consumers just mutate their own state inside the callbacks.

All affected suites pass (list 40/40, carousel 45/45, time-picker 58/58, nav-drawer 36/36).

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.

2 participants