Repository: exadel-inc/esl
Pull request #2419 (2024-05-21 10:03:32)

chore(deps-dev): bump ts-jest from 29.1.2 to 29.1.3
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.2 to 29.1.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/kulshekhar/ts-jest/releases">ts-jest's releases</a>.</em></p>
<blockquote>
<h2>v29.1.3</h2>
<p>Please refer to <a href="https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md">CHANGELOG.md</a> for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md">ts-jest's changelog</a>.</em></p>
<blockquote>
<h2><a href="https://github.com/kulshekhar/ts-jest/compare/v29.1.2...v29.1.3">29.1.3</a> (2024-05-21)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>add <code>@jest/transform</code> as an optional peer dependency (<a href="https://github.com/kulshekhar/ts-jest/commit/0ba7f861c3e1905de5627b4e5d2a2cadad011b67">0ba7f86</a>)</li>
<li>bring back Node 14 support (<a href="https://github.com/kulshekhar/ts-jest/commit/eda56a779789d70963b7572e2914b2a3a25ac43a">eda56a7</a>)</li>
</ul>
<h3>Performance Improvements</h3>
<ul>
<li>remove ts resolved module cache file (<a href="https://github.com/kulshekhar/ts-jest/commit/4c88da58991b000aa90ea489acfa6aed39b36120">4c88da5</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/f23d9ff1b1e79e4c55eee0b04ca0e006817c05f8"><code>f23d9ff</code></a> chore(release): 29.1.3</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/eda56a779789d70963b7572e2914b2a3a25ac43a"><code>eda56a7</code></a> fix: bring back Node 14 support</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/287a5a761c8288d3aba5f1e640331aeac64fab70"><code>287a5a7</code></a> build(deps): Update babel monorepo to ^7.24.5</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/7b4c9cac01018ea52c0875f41975eb25baa54a65"><code>7b4c9ca</code></a> build(deps): Update React e2e packages</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/fc9e82509b8c5586b7319bd757a8812c1d277b00"><code>fc9e825</code></a> build(deps): Update actions/setup-node action to v3.8.2</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/f3718817c2ef9a612ef9f6ce9cfb677c6b63b07d"><code>f371881</code></a> build(deps): Update Jest packages</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/1de11e2c797b98a6e48ba00991e4986260c47706"><code>1de11e2</code></a> build(deps): Update JamesIves/github-pages-deploy-action action to v4.6.1</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/f04fbfea5a74085cacec823e42644d30a295abec"><code>f04fbfe</code></a> build(deps): Update <a href="https://github.com/types"><code>@​types</code></a> packages</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/d4edc09c39faed2257fb1b97dbab20c772de81a6"><code>d4edc09</code></a> build(deps): Update docusaurus monorepo to ^2.4.3</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/1a6c276dcb998d781874290df9ce1cfe52faa0a1"><code>1a6c276</code></a> build(deps): Update dependency semver to v7.6.2</li>
<li>Additional commits viewable in <a href="https://github.com/kulshekhar/ts-jest/compare/v29.1.2...v29.1.3">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ts-jest&package-manager=npm_and_yarn&previous-version=29.1.2&new-version=29.1.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

ala-n: @dependabot recreate

Patch:
diff --git a/package-lock.json b/package-lock.json
index 3930bbe87..1d32f6ccd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -54,7 +54,7 @@
         "smoothscroll-polyfill": "^0.4.4",
         "stylelint": "^16.5.0",
         "stylelint-prettier": "^5.0.0",
-        "ts-jest": "^29.1.2",
+        "ts-jest": "^29.1.3",
         "typescript": "5.4.5"
       }
     },
@@ -19389,9 +19389,9 @@
       }
     },
     "node_modules/ts-jest": {
-      "version": "29.1.2",
-      "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz",
-      "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==",
+      "version": "29.1.3",
+      "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.3.tgz",
+      "integrity": "sha512-6L9qz3ginTd1NKhOxmkP0qU3FyKjj5CPoY+anszfVn6Pmv/RIKzhiMCsH7Yb7UvJR9I2A64rm4zQl531s2F1iw==",
       "dev": true,
       "dependencies": {
         "bs-logger": "0.x",
@@ -19407,10 +19407,11 @@
         "ts-jest": "cli.js"
       },
       "engines": {
-        "node": "^16.10.0 || ^18.0.0 || >=20.0.0"
+        "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
       },
       "peerDependencies": {
         "@babel/core": ">=7.0.0-beta.0 <8",
+        "@jest/transform": "^29.0.0",
         "@jest/types": "^29.0.0",
         "babel-jest": "^29.0.0",
         "jest": "^29.0.0",
@@ -19420,6 +19421,9 @@
         "@babel/core": {
           "optional": true
         },
+        "@jest/transform": {
+          "optional": true
+        },
         "@jest/types": {
           "optional": true
         },
diff --git a/package.json b/package.json
index 472bac9c3..96fb2c13e 100644
--- a/package.json
+++ b/package.json
@@ -126,7 +126,7 @@
     "smoothscroll-polyfill": "^0.4.4",
     "stylelint": "^16.5.0",
     "stylelint-prettier": "^5.0.0",
-    "ts-jest": "^29.1.2",
+    "ts-jest": "^29.1.3",
     "typescript": "5.4.5"
   },
   "browserslist": [
diff --git a/src/modules/esl-popup/core/esl-popup.ts b/src/modules/esl-popup/core/esl-popup.ts
index 0ffb6d4bd..9e2e17ae4 100644
--- a/src/modules/esl-popup/core/esl-popup.ts
+++ b/src/modules/esl-popup/core/esl-popup.ts
@@ -153,7 +153,7 @@ export class ESLPopup extends ESLToggleable {
   /** Get offsets arrow ratio */
   @memoize()
   protected get offsetArrowRatio(): number {
-    const offset = parseNumber(this.offsetArrow, DEFAULT_OFFSET_ARROW) || DEFAULT_OFFSET_ARROW;
+    const offset = parseNumber(this.offsetArrow, DEFAULT_OFFSET_ARROW);
     const offsetNormalized = Math.max(0, Math.min(offset, 100));
     const ratio = offsetNormalized / 100;
     return isRTL(this) ? 1 - ratio : ratio;
diff --git a/src/modules/esl-scrollbar/core/esl-scrollbar.less b/src/modules/esl-scrollbar/core/esl-scrollbar.less
index 24c5b707a..6f3feeefe 100644
--- a/src/modules/esl-scrollbar/core/esl-scrollbar.less
+++ b/src/modules/esl-scrollbar/core/esl-scrollbar.less
@@ -56,6 +56,7 @@
         width: 100%;
         height: 33.33%;
         min-height: 10px;
+        touch-action: pan-x;
       }
     }
 
@@ -75,6 +76,7 @@
         height: 100%;
         width: 33.33%;
         min-width: 10px;
+        touch-action: pan-y;
       }
     }
   }
diff --git a/src/modules/esl-scrollbar/core/esl-scrollbar.ts b/src/modules/esl-scrollbar/core/esl-scrollbar.ts
index 35d275377..db9f63bf5 100644
--- a/src/modules/esl-scrollbar/core/esl-scrollbar.ts
+++ b/src/modules/esl-scrollbar/core/esl-scrollbar.ts
@@ -3,7 +3,7 @@ import {ExportNs} from '../../esl-utils/environment/export-ns';
 import {isElement} from '../../esl-utils/dom/api';
 import {isRelativeNode} from '../../esl-utils/dom/traversing';
 import {isRTL, RTLScroll, normalizeScrollLeft} from '../../esl-utils/dom/rtl';
-import {isMouseEvent, isTouchEvent, getTouchPoint, getOffsetPoint} from '../../esl-utils/dom/events';
+import {getTouchPoint, getOffsetPoint} from '../../esl-utils/dom/events';
 import {bind, ready, attr, boolAttr, listen} from '../../esl-utils/decorators';
 import {rafDecorator} from '../../esl-utils/async/raf';
 import {ESLTraversingQuery} from '../../esl-traversing-query/core';
@@ -223,8 +223,8 @@ export class ESLScrollbar extends ESLBaseElement {
     this.$$fire('esl:change:scroll', {bubbles: false});
   }
 
-  /** Returns position from MouseEvent coordinates (not normalized) */
-  public toPosition(event: MouseEvent | TouchEvent): number {
+  /** Returns position from PointerEvent coordinates (not normalized) */
+  public toPosition(event: PointerEvent): number {
     const {horizontal, thumbOffset, trackOffset} = this;
     const point = getTouchPoint(event);
     const offset = getOffsetPoint(this.$scrollbarTrack);
@@ -235,13 +235,12 @@ export class ESLScrollbar extends ESLBaseElement {
   }
 
   // Event listeners
-  /** Handles `mousedown` / `touchstart` event to manage thumb drag start and scroll clicks */
-  @listen('mousedown touchstart')
-  protected _onPointerDown(event: MouseEvent | TouchEvent): void {
+  /** Handles `pointerdown` event to manage thumb drag start and scroll clicks */
+  @listen('pointerdown')
+  protected _onPointerDown(event: PointerEvent): void {
     this._initialPosition = this.position;
     this._pointerPosition = this.toPosition(event);
-    const point = getTouchPoint(event);
-    this._initialMousePosition = this.horizontal ? point.x : point.y;
+    this._initialMousePosition = this.horizontal ? event.pageX : event.pageY;
 
     if (event.target === this.$scrollbarThumb) {
       this._onThumbPointerDown(event); // Drag start handler
@@ -249,12 +248,7 @@ export class ESLScrollbar extends ESLBaseElement {
       this._onPointerDownTick(true); // Continuous scroll and click handler
     }
 
-    // Subscribes inverse handlers
-    isMouseEvent(event) && this.$$on({event: 'mouseup', target: window}, this._onPointerUp);
-    isTouchEvent(event) && this.$$on({event: 'touchend', target: window}, this._onPointerUp);
-
-    // Prevents default text selection, etc.
-    if (!isTouchEvent(event)) event.preventDefault();
+    this.$$on(this._onPointerUp);
   }
 
   /** Handles a scroll click / continuous scroll*/
@@ -272,17 +266,16 @@ export class ESLScrollbar extends ESLBaseElement {
 
   /** Handles thumb drag start */
   @bind
-  protected _onThumbPointerDown(event: MouseEvent | TouchEvent): void {
+  protected _onThumbPointerDown(event: PointerEvent): void {
     this.toggleAttribute('dragging', true);
     this.$target?.style.setProperty('scroll-behavior', 'auto');
     // Attaches drag listeners
     this.$$on(this._onBodyClick);
-    isMouseEvent(event) && this.$$on({event: 'mousemove', target: window}, this._onPointerMove);
-    isTouchEvent(event) && this.$$on({event: 'touchmove', target: window}, this._onPointerMove);
+    this.$$on(this._onPointerMove);
   }
 
   /** Sets position on drag */
-  protected _onPointerDrag(event: MouseEvent | TouchEvent): void {
+  protected _onPointerDrag(event: PointerEvent): void {
     const point = getTouchPoint(event);
     const mousePosition = this.horizontal ? point.x : point.y;
     const positionChange = mousePosition - this._initialMousePosition;
@@ -291,18 +284,18 @@ export class ESLScrollbar extends ESLBaseElement {
     this.position = this._initialPosition + absChange;
   }
 
-  /** `mousemove` document handler for thumb drag event. Active only if drag action is active */
-  protected _onPointerMove(event: MouseEvent | TouchEvent): void {
+  /** `pointermove` document handler for thumb drag event. Active only if drag action is active */
+  @listen({event: 'pointermove', auto: false})
+  protected _onPointerMove(event: PointerEvent): void {
     if (!this.dragging) return;
     // Request position update
     this._deferredDrag(event);
-    // Prevents default text selection, etc.
-    event.preventDefault();
-    event.stopPropagation();
+    this.setPointerCapture(event.pointerId);
   }
 
-  /** `mouseup` short-time document handler for drag end action */
-  protected _onPointerUp(event: MouseEvent | TouchEvent): void {
+  /** `pointerup` / `pointercancel` short-time document handler for drag end action */
+  @listen({event: 'pointerup pointercancel', target: window, auto: false})
+  protected _onPointerUp(event: PointerEvent): void {
     this._scrollTimer && window.clearTimeout(this._scrollTimer);
     this.toggleAttribute('dragging', false);
     this.$target?.style.removeProperty('scroll-behavior');
@@ -310,6 +303,8 @@ export class ESLScrollbar extends ESLBaseElement {
     // Unbinds drag listeners
     this.$$off(this._onPointerMove);
     this.$$off(this._onPointerUp);
+
+    if (this.hasPointerCapture(event.pointerId)) this.releasePointerCapture(event.pointerId);
   }
 
   /** Body `click` short-time handler to prevent clicks event on thumb drag. Handles capture phase */
diff --git a/src/modules/esl-utils/misc/format.ts b/src/modules/esl-utils/misc/format.ts
index fa8583ac6..5cc3aa36f 100644
--- a/src/modules/esl-utils/misc/format.ts
+++ b/src/modules/esl-utils/misc/format.ts
@@ -41,11 +41,17 @@ export const parseBoolean = (val: string | null): boolean => val !== null && val
  * Parses number with the ability to pass an alternative fallback for NaN.
  * Note: falsy values except 0 are treated as NaN
  */
-export const parseNumber = (str: string | number, nanValue?: number | undefined): number | undefined => {
+export function parseNumber(str: string | number): number | undefined;
+/**
+ * Parses number with the ability to pass an alternative fallback for NaN.
+ * Note: falsy values except 0 are treated as NaN
+*/
+export function parseNumber(str: string | number, nanValue: number): number;
+export function parseNumber(str: string | number, nanValue?: number): number | undefined {
   if (str === 0) return 0;
   const value = +(str || NaN);
   return isNaN(value) ? nanValue : value;
-};
+}
 
 /**
  * Common function that returns coefficient aspect ratio


Test patch:
diff --git a/src/modules/esl-utils/misc/test/format.test.ts b/src/modules/esl-utils/misc/test/format.test.ts
index 552083dcc..a9c22f08a 100644
--- a/src/modules/esl-utils/misc/test/format.test.ts
+++ b/src/modules/esl-utils/misc/test/format.test.ts
@@ -133,6 +133,7 @@ describe('misc/format helper tests', () => {
       [['123'], 123],
       [['123', 1], 123],
       [[0], 0],
+      [[0, 1], 0],
       [['a'], undefined],
       [['b', undefined], undefined],
       [['abc', NaN], NaN],