@react-hive/honey-utils 3.16.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1631,75 +1631,47 @@ __webpack_require__.r(__webpack_exports__);
1631
1631
  /* harmony import */ var _geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ~/geometry */ "./src/geometry/index.ts");
1632
1632
 
1633
1633
  /**
1634
- * Advances a value by one inertia step using velocity, friction, and hard bounds.
1634
+ * Advances a value by a single inertial step using velocity,
1635
+ * elapsed time, exponential friction, and hard bounds.
1635
1636
  *
1636
- * This utility models **inertial motion** (momentum + decay) on top of
1637
- * {@link resolveBoundedDelta}, which acts as the authoritative constraint layer.
1637
+ * This function models **momentum-driven motion** and delegates
1638
+ * boundary enforcement to {@link resolveBoundedDelta}, which guarantees:
1639
+ * - no overshoot
1640
+ * - no jitter at bounds
1641
+ * - deterministic stopping behavior
1638
1642
  *
1639
- * The function:
1640
- * - Integrates velocity over the elapsed time to produce a movement delta
1641
- * - Resolves that delta against fixed bounds
1642
- * - Applies exponential friction to gradually reduce velocity
1643
- * - Stops immediately when a bound is hit or velocity falls below a threshold
1643
+ * ---
1644
1644
  *
1645
- * ⚠️ This function performs **one step only** and is intended to be called
1646
- * repeatedly from an animation loop (e.g. `requestAnimationFrame`).
1645
+ * ### Termination conditions
1646
+ * Inertia stops immediately when:
1647
+ * - the absolute velocity falls below `minVelocityPxMs`, or
1648
+ * - movement in the current direction is blocked by a bound
1649
+ *
1650
+ * ---
1651
+ *
1652
+ * ⚠️ **Single-step function**
1653
+ * This function performs **one inertia step only**.
1654
+ * It must be called repeatedly from an animation loop
1655
+ * (e.g. `requestAnimationFrame`) to produce continuous motion.
1656
+ *
1657
+ * ---
1647
1658
  *
1648
1659
  * ### Common use cases
1649
1660
  * - Synthetic scrolling with momentum
1661
+ * - Drag-to-scroll interactions
1650
1662
  * - Carousels and sliders
1651
1663
  * - Timelines and scrubbers
1652
- * - Drag-to-scroll interactions with inertia
1653
- *
1654
- * @param value - Current value before applying inertia (e.g. translate position).
1655
- * @param min - Minimum allowed value (inclusive).
1656
- * @param max - Maximum allowed value (inclusive).
1657
- * @param velocity - Current velocity in units per millisecond (e.g. px/ms).
1658
- * @param deltaTime - Time elapsed since the previous step, in milliseconds.
1659
- * @param friction - Exponential friction coefficient controlling decay rate.
1660
- * @param minVelocity - Minimum velocity below which inertia stops.
1661
- *
1662
- * @returns An object containing the updated value and velocity,
1663
- * or `null` when inertia has completed or movement is no longer possible.
1664
- *
1665
- * @example
1666
- * ```ts
1667
- * let value = translateX;
1668
- * let velocity = releaseVelocity; // px/ms from drag end
1669
- * let lastTime = performance.now();
1670
- *
1671
- * const step = (time: number) => {
1672
- * const deltaTime = time - lastTime;
1673
- * lastTime = time;
1674
- *
1675
- * const result = applyInertiaStep({
1676
- * value,
1677
- * velocity,
1678
- * min: -maxOverflow,
1679
- * max: 0,
1680
- * deltaTime,
1681
- * });
1682
1664
  *
1683
- * if (!result) {
1684
- * return; // inertia finished
1685
- * }
1686
- *
1687
- * value = result.value;
1688
- * velocity = result.velocity;
1689
- *
1690
- * container.style.transform = `translateX(${value}px)`;
1691
- * requestAnimationFrame(step);
1692
- * };
1693
- *
1694
- * requestAnimationFrame(step);
1695
- * ```
1665
+ * @returns An {@link InertiaStepResult} when inertia is still active,
1666
+ * or `null` when inertia has completed or further movement
1667
+ * is not possible.
1696
1668
  */
1697
- const applyInertiaStep = ({ value, min, max, velocity, deltaTime, friction = 0.002, minVelocity = 0.01, }) => {
1698
- if (Math.abs(velocity) < minVelocity) {
1669
+ const applyInertiaStep = ({ value, min, max, velocityPxMs, deltaTimeMs, friction = 0.002, minVelocityPxMs = 0.01, }) => {
1670
+ if (Math.abs(velocityPxMs) < minVelocityPxMs) {
1699
1671
  return null;
1700
1672
  }
1701
1673
  // Distance we want to move this frame
1702
- const delta = velocity * deltaTime;
1674
+ const delta = velocityPxMs * deltaTimeMs;
1703
1675
  const nextValue = (0,_geometry__WEBPACK_IMPORTED_MODULE_0__.resolveBoundedDelta)({
1704
1676
  delta,
1705
1677
  value,
@@ -1711,11 +1683,11 @@ const applyInertiaStep = ({ value, min, max, velocity, deltaTime, friction = 0.0
1711
1683
  return null;
1712
1684
  }
1713
1685
  // Apply exponential friction
1714
- const decay = Math.exp(-friction * deltaTime);
1715
- const nextVelocity = velocity * decay;
1686
+ const decay = Math.exp(-friction * deltaTimeMs);
1687
+ const nextVelocityPxMs = velocityPxMs * decay;
1716
1688
  return {
1717
1689
  value: nextValue,
1718
- velocity: nextVelocity,
1690
+ velocityPxMs: nextVelocityPxMs,
1719
1691
  };
1720
1692
  };
1721
1693
 
@@ -2471,20 +2443,20 @@ __webpack_require__.r(__webpack_exports__);
2471
2443
  * ⚠️ Character comparison is performed at the UTF-16 code unit level
2472
2444
  * (`String.charCodeAt`), not by Unicode grapheme clusters.
2473
2445
  *
2474
- * @param inputString - The string to scan.
2446
+ * @param input - The string to scan.
2475
2447
  * @param targetChar - A single character to search for.
2476
2448
  *
2477
2449
  * @returns An array of zero-based indices for each occurrence of `targetChar`.
2478
2450
  * Returns an empty array if no matches are found.
2479
2451
  */
2480
- const findCharIndices = (inputString, targetChar) => {
2481
- if (inputString.length === 0) {
2452
+ const findCharIndices = (input, targetChar) => {
2453
+ if (input.length === 0) {
2482
2454
  return [];
2483
2455
  }
2484
2456
  const targetCode = targetChar.charCodeAt(0);
2485
2457
  const indices = [];
2486
- for (let i = 0; i < inputString.length; i++) {
2487
- if (inputString.charCodeAt(i) === targetCode) {
2458
+ for (let i = 0; i < input.length; i++) {
2459
+ if (input.charCodeAt(i) === targetCode) {
2488
2460
  indices.push(i);
2489
2461
  }
2490
2462
  }
@@ -2534,6 +2506,43 @@ const forEachChar = (input, onChar, shouldSkipChar) => {
2534
2506
  };
2535
2507
 
2536
2508
 
2509
+ /***/ }),
2510
+
2511
+ /***/ "./src/string/get-words-initials.ts":
2512
+ /*!******************************************!*\
2513
+ !*** ./src/string/get-words-initials.ts ***!
2514
+ \******************************************/
2515
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2516
+
2517
+ __webpack_require__.r(__webpack_exports__);
2518
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2519
+ /* harmony export */ getWordsInitials: () => (/* binding */ getWordsInitials)
2520
+ /* harmony export */ });
2521
+ /* harmony import */ var _split_string_into_words__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./split-string-into-words */ "./src/string/split-string-into-words.ts");
2522
+
2523
+ /**
2524
+ * Returns the uppercase initials of the words in a string.
2525
+ *
2526
+ * The first character of each word is extracted, concatenated, and uppercased.
2527
+ *
2528
+ * @param input - The input string.
2529
+ * @param maxWords - Maximum number of words to include when generating initials.
2530
+ * Defaults to `Infinity`.
2531
+ *
2532
+ * @returns A string containing the uppercase initials of the selected words.
2533
+ */
2534
+ const getWordsInitials = (input, maxWords = Infinity) => {
2535
+ if (input.length === 0) {
2536
+ return '';
2537
+ }
2538
+ return (0,_split_string_into_words__WEBPACK_IMPORTED_MODULE_0__.splitStringIntoWords)(input)
2539
+ .slice(0, maxWords)
2540
+ .map(word => word[0])
2541
+ .join('')
2542
+ .toUpperCase();
2543
+ };
2544
+
2545
+
2537
2546
  /***/ }),
2538
2547
 
2539
2548
  /***/ "./src/string/index.ts":
@@ -2548,6 +2557,7 @@ __webpack_require__.r(__webpack_exports__);
2548
2557
  /* harmony export */ camelToWords: () => (/* reexport safe */ _camel_to_words__WEBPACK_IMPORTED_MODULE_3__.camelToWords),
2549
2558
  /* harmony export */ findCharIndices: () => (/* reexport safe */ _find_char_indices__WEBPACK_IMPORTED_MODULE_7__.findCharIndices),
2550
2559
  /* harmony export */ forEachChar: () => (/* reexport safe */ _for_each_char__WEBPACK_IMPORTED_MODULE_8__.forEachChar),
2560
+ /* harmony export */ getWordsInitials: () => (/* reexport safe */ _get_words_initials__WEBPACK_IMPORTED_MODULE_9__.getWordsInitials),
2551
2561
  /* harmony export */ isNilOrEmptyString: () => (/* reexport safe */ _is_nil_or_empty_string__WEBPACK_IMPORTED_MODULE_5__.isNilOrEmptyString),
2552
2562
  /* harmony export */ isString: () => (/* reexport safe */ _is_string__WEBPACK_IMPORTED_MODULE_0__.isString),
2553
2563
  /* harmony export */ parseFileName: () => (/* reexport safe */ _parse_file_name__WEBPACK_IMPORTED_MODULE_6__.parseFileName),
@@ -2563,6 +2573,8 @@ __webpack_require__.r(__webpack_exports__);
2563
2573
  /* harmony import */ var _parse_file_name__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./parse-file-name */ "./src/string/parse-file-name.ts");
2564
2574
  /* harmony import */ var _find_char_indices__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./find-char-indices */ "./src/string/find-char-indices.ts");
2565
2575
  /* harmony import */ var _for_each_char__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./for-each-char */ "./src/string/for-each-char.ts");
2576
+ /* harmony import */ var _get_words_initials__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./get-words-initials */ "./src/string/get-words-initials.ts");
2577
+
2566
2578
 
2567
2579
 
2568
2580
 
@@ -2681,7 +2693,12 @@ __webpack_require__.r(__webpack_exports__);
2681
2693
  *
2682
2694
  * @returns An array of words from the input string.
2683
2695
  */
2684
- const splitStringIntoWords = (input) => input.split(' ').filter(Boolean);
2696
+ const splitStringIntoWords = (input) => {
2697
+ if (input.length === 0) {
2698
+ return [];
2699
+ }
2700
+ return input.split(' ').filter(Boolean);
2701
+ };
2685
2702
 
2686
2703
 
2687
2704
  /***/ }),
@@ -2812,6 +2829,7 @@ __webpack_require__.r(__webpack_exports__);
2812
2829
  /* harmony export */ getElementOffsetRect: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.getElementOffsetRect),
2813
2830
  /* harmony export */ getFocusableHtmlElements: () => (/* reexport safe */ _a11y__WEBPACK_IMPORTED_MODULE_11__.getFocusableHtmlElements),
2814
2831
  /* harmony export */ getLocalStorageCapabilities: () => (/* reexport safe */ _env__WEBPACK_IMPORTED_MODULE_12__.getLocalStorageCapabilities),
2832
+ /* harmony export */ getWordsInitials: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.getWordsInitials),
2815
2833
  /* harmony export */ getXOverflowWidth: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.getXOverflowWidth),
2816
2834
  /* harmony export */ getYOverflowHeight: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.getYOverflowHeight),
2817
2835
  /* harmony export */ hasXOverflow: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.hasXOverflow),