@synerise/ds-utils 1.6.0 → 1.7.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.7.0](https://github.com/synerise/synerise-design/compare/@synerise/ds-utils@1.6.0...@synerise/ds-utils@1.7.0) (2026-03-20)
7
+
8
+ ### Features
9
+
10
+ - **utils:** sticky sidebar util ([68714d7](https://github.com/synerise/synerise-design/commit/68714d7414839dc15c560ade6f5c0cece3edd1d5))
11
+
6
12
  # [1.6.0](https://github.com/synerise/synerise-design/compare/@synerise/ds-utils@1.5.4...@synerise/ds-utils@1.6.0) (2026-02-05)
7
13
 
8
14
  ### Features
package/README.md CHANGED
@@ -5,13 +5,29 @@ List of utils:
5
5
 
6
6
  - doubleClickListener,
7
7
  - focusWithArrowKeys,
8
- - getInitials,
9
- - escapeRegex,
8
+ - getInitials (not exported from package index),
9
+ - escapeRegEx,
10
+ - hexToRgba,
11
+ - omitKeys,
12
+ - renderWithHighlight,
10
13
  - selectColorByLetter,
11
- - testing tools,
12
14
  - toCamelCase,
15
+ - getPopupContainer,
16
+ - NOOP,
13
17
  - useBreakpoint,
18
+ - useCombinedRefs,
19
+ - useDelimiterEscape,
20
+ - useElementInView,
21
+ - useIsMounted,
22
+ - useKeyboardShortcuts,
23
+ - useLatestRef,
14
24
  - useOnClickOutside,
25
+ - useOverscrollBlock,
26
+ - usePrevious,
15
27
  - useResize,
16
28
  - useResizeObserver,
17
- - useResizeToFit.
29
+ - useResizeToFit,
30
+ - useScrollContain,
31
+ - useSearchResults,
32
+ - useStableId,
33
+ - useTraceUpdate.
package/dist/index.d.ts CHANGED
@@ -17,6 +17,7 @@ export { default as useElementInView } from './useElementInView/useElementInView
17
17
  export { default as useOverscrollBlock } from './useOverscrollBlock/useOverscrollBlock';
18
18
  export { default as useResizeToFit } from './useResizeToFit/useResizeToFit';
19
19
  export * from './useScrollContain/useScrollContain';
20
+ export * from './useStickyScroll/useStickyScroll';
20
21
  export * from './useSearchResults';
21
22
  export * from './useKeyboardShortcuts/useKeyboardShortcuts';
22
23
  export * from './omitKeys/omitKeys';
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ export { default as useElementInView } from './useElementInView/useElementInView
17
17
  export { default as useOverscrollBlock } from './useOverscrollBlock/useOverscrollBlock';
18
18
  export { default as useResizeToFit } from './useResizeToFit/useResizeToFit';
19
19
  export * from './useScrollContain/useScrollContain';
20
+ export * from './useStickyScroll/useStickyScroll';
20
21
  export * from './useSearchResults';
21
22
  export * from './useKeyboardShortcuts/useKeyboardShortcuts';
22
23
  export * from './omitKeys/omitKeys';
@@ -0,0 +1,8 @@
1
+ import { type RefObject } from 'react';
2
+ interface UseStickyScrollOptions {
3
+ scrollContainerRef: RefObject<HTMLElement>;
4
+ offsetTop?: number;
5
+ offsetBottom?: number;
6
+ }
7
+ export declare const useStickyScroll: ({ scrollContainerRef, offsetTop, offsetBottom, }: UseStickyScrollOptions) => RefObject<HTMLDivElement>;
8
+ export {};
@@ -0,0 +1,59 @@
1
+ import { useEffect, useRef } from 'react';
2
+ export var useStickyScroll = function useStickyScroll(_ref) {
3
+ var scrollContainerRef = _ref.scrollContainerRef,
4
+ _ref$offsetTop = _ref.offsetTop,
5
+ offsetTop = _ref$offsetTop === void 0 ? 0 : _ref$offsetTop,
6
+ _ref$offsetBottom = _ref.offsetBottom,
7
+ offsetBottom = _ref$offsetBottom === void 0 ? 0 : _ref$offsetBottom;
8
+ var stickyRef = useRef(null);
9
+ var lastScrollTop = useRef(0);
10
+ var topValue = useRef(0);
11
+ useEffect(function () {
12
+ var container = scrollContainerRef.current;
13
+ var sticky = stickyRef.current;
14
+ if (!container || !sticky) {
15
+ return;
16
+ }
17
+ var containerStyle = getComputedStyle(container);
18
+ var paddingTop = parseFloat(containerStyle.paddingTop);
19
+ var paddingBottom = parseFloat(containerStyle.paddingBottom);
20
+ var stickyOriginTop = sticky.offsetTop - paddingTop;
21
+ sticky.style.position = 'sticky';
22
+ sticky.style.top = offsetTop + "px";
23
+ topValue.current = offsetTop;
24
+ lastScrollTop.current = container.scrollTop;
25
+ var onScroll = function onScroll() {
26
+ var scrollTop = container.scrollTop;
27
+ var delta = scrollTop - lastScrollTop.current;
28
+ if (delta === 0) {
29
+ return;
30
+ }
31
+ var engaged = scrollTop >= stickyOriginTop - offsetTop;
32
+ if (!engaged) {
33
+ topValue.current = offsetTop;
34
+ sticky.style.top = topValue.current + "px";
35
+ lastScrollTop.current = scrollTop;
36
+ return;
37
+ }
38
+ var visibleHeight = container.clientHeight - paddingTop - paddingBottom;
39
+ var stickyHeight = sticky.offsetHeight;
40
+ if (stickyHeight <= visibleHeight - offsetTop - offsetBottom) {
41
+ topValue.current = offsetTop;
42
+ } else if (delta > 0) {
43
+ var minTop = visibleHeight - stickyHeight - offsetBottom;
44
+ topValue.current = Math.max(topValue.current - delta, minTop);
45
+ } else {
46
+ topValue.current = Math.min(topValue.current - delta, offsetTop);
47
+ }
48
+ sticky.style.top = topValue.current + "px";
49
+ lastScrollTop.current = scrollTop;
50
+ };
51
+ container.addEventListener('scroll', onScroll, {
52
+ passive: true
53
+ });
54
+ return function () {
55
+ return container.removeEventListener('scroll', onScroll);
56
+ };
57
+ }, [scrollContainerRef, offsetTop, offsetBottom]);
58
+ return stickyRef;
59
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-utils",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Utils UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "synerise/synerise-design",
@@ -42,5 +42,5 @@
42
42
  "react": ">=16.9.0 <= 18.3.1",
43
43
  "styled-components": "^5.3.3"
44
44
  },
45
- "gitHead": "ac8decd9736940735bf05198b24b3eeeb5900b18"
45
+ "gitHead": "8efc031fa688c0b87c7b3915bae93546bb63bcac"
46
46
  }