@hh.ru/magritte-ui-scrollable-container 6.1.1 → 6.2.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.
@@ -23,12 +23,6 @@ export interface ScrollState {
23
23
  rightCorrection: ObservableValue<number>;
24
24
  /** индекс элемента для отложенного скролла */
25
25
  indexForDeferScroll: number;
26
- /**
27
- * флаг наличия взаимодействия с компонентом (скролл или подскролл к какому-либо элементу).
28
- * Используется для пересчета размеров в случае, когда родительский контейнер открывается с анимацией (например, в modal)
29
- * Если взаимодействие было, то пересчитывать размеры не нужно (считаем, что анимации появления родительского контейнера)
30
- */
31
- wasContainerInteracted: boolean;
32
26
  }
33
27
  export declare const createScrollState: () => ScrollState;
34
28
  export declare const ScrollStateContext: import("react").Context<ScrollState>;
@@ -12,7 +12,6 @@ const createScrollState = () => ({
12
12
  leftCorrection: new ObservableValue(0),
13
13
  rightCorrection: new ObservableValue(0),
14
14
  indexForDeferScroll: -1,
15
- wasContainerInteracted: false,
16
15
  scrollSnapAlign: 'none',
17
16
  });
18
17
  const ScrollStateContext = createContext(createScrollState());
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollStateProvider.js","sources":["../src/ScrollStateProvider.tsx"],"sourcesContent":["import { type RefObject, createContext, useContext } from 'react';\nimport { MotionValue } from 'motion/react';\n\nimport { ObservableValue } from '@hh.ru/magritte-ui-scrollable-container/ObservableValue';\nimport { type ItemWithOffset, type ScrollSnapAlign } from '@hh.ru/magritte-ui-scrollable-container/types';\n\nexport interface ScrollState {\n /** ширина контента, которая складывается из ширины элементов галереи */\n contentWidth: ObservableValue<number>;\n /** ширина вьюпорта для просмотра галереи */\n viewportWidth: ObservableValue<number>;\n /** элементы галереи */\n items: ObservableValue<RefObject<HTMLElement & ItemWithOffset>[]>;\n /** текущая позиция */\n scrollPosition: MotionValue<number>;\n /** Определяет, как ближайший элемент будет размещён во вьюпорте при автоматическом скролле */\n scrollSnapAlign: ScrollSnapAlign;\n /**\n * флаг коррекции \"по умолчанию\"\n * возникает при использовании \"стандартных\" (по спеке) кнопок в fade\n */\n defaultButtonsCorrection: ObservableValue<number>;\n /** значения коррекции */\n leftCorrection: ObservableValue<number>;\n rightCorrection: ObservableValue<number>;\n /** индекс элемента для отложенного скролла */\n indexForDeferScroll: number;\n /**\n * флаг наличия взаимодействия с компонентом (скролл или подскролл к какому-либо элементу).\n * Используется для пересчета размеров в случае, когда родительский контейнер открывается с анимацией (например, в modal)\n * Если взаимодействие было, то пересчитывать размеры не нужно (считаем, что анимации появления родительского контейнера)\n */\n wasContainerInteracted: boolean;\n}\n\nexport const createScrollState = (): ScrollState => ({\n contentWidth: new ObservableValue(0),\n viewportWidth: new ObservableValue(0),\n items: new ObservableValue<RefObject<HTMLElement & ItemWithOffset>[]>([]),\n scrollPosition: new MotionValue(0),\n defaultButtonsCorrection: new ObservableValue(0),\n leftCorrection: new ObservableValue(0),\n rightCorrection: new ObservableValue(0),\n indexForDeferScroll: -1,\n wasContainerInteracted: false,\n scrollSnapAlign: 'none',\n});\n\nexport const ScrollStateContext = createContext<ScrollState>(createScrollState());\n\nexport const useScrollState = (): ScrollState => useContext(ScrollStateContext);\n"],"names":[],"mappings":";;;;AAmCa,MAAA,iBAAiB,GAAG,OAAoB;AACjD,IAAA,YAAY,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AACpC,IAAA,aAAa,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AACrC,IAAA,KAAK,EAAE,IAAI,eAAe,CAA4C,EAAE,CAAC;AACzE,IAAA,cAAc,EAAE,IAAI,WAAW,CAAC,CAAC,CAAC;AAClC,IAAA,wBAAwB,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AAChD,IAAA,cAAc,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AACtC,IAAA,eAAe,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,CAAC;AACvB,IAAA,sBAAsB,EAAE,KAAK;AAC7B,IAAA,eAAe,EAAE,MAAM;AAC1B,CAAA,EAAE;MAEU,kBAAkB,GAAG,aAAa,CAAc,iBAAiB,EAAE,EAAE;AAErE,MAAA,cAAc,GAAG,MAAmB,UAAU,CAAC,kBAAkB;;;;"}
1
+ {"version":3,"file":"ScrollStateProvider.js","sources":["../src/ScrollStateProvider.tsx"],"sourcesContent":["import { type RefObject, createContext, useContext } from 'react';\nimport { MotionValue } from 'motion/react';\n\nimport { ObservableValue } from '@hh.ru/magritte-ui-scrollable-container/ObservableValue';\nimport { type ItemWithOffset, type ScrollSnapAlign } from '@hh.ru/magritte-ui-scrollable-container/types';\n\nexport interface ScrollState {\n /** ширина контента, которая складывается из ширины элементов галереи */\n contentWidth: ObservableValue<number>;\n /** ширина вьюпорта для просмотра галереи */\n viewportWidth: ObservableValue<number>;\n /** элементы галереи */\n items: ObservableValue<RefObject<HTMLElement & ItemWithOffset>[]>;\n /** текущая позиция */\n scrollPosition: MotionValue<number>;\n /** Определяет, как ближайший элемент будет размещён во вьюпорте при автоматическом скролле */\n scrollSnapAlign: ScrollSnapAlign;\n /**\n * флаг коррекции \"по умолчанию\"\n * возникает при использовании \"стандартных\" (по спеке) кнопок в fade\n */\n defaultButtonsCorrection: ObservableValue<number>;\n /** значения коррекции */\n leftCorrection: ObservableValue<number>;\n rightCorrection: ObservableValue<number>;\n /** индекс элемента для отложенного скролла */\n indexForDeferScroll: number;\n}\n\nexport const createScrollState = (): ScrollState => ({\n contentWidth: new ObservableValue(0),\n viewportWidth: new ObservableValue(0),\n items: new ObservableValue<RefObject<HTMLElement & ItemWithOffset>[]>([]),\n scrollPosition: new MotionValue(0),\n defaultButtonsCorrection: new ObservableValue(0),\n leftCorrection: new ObservableValue(0),\n rightCorrection: new ObservableValue(0),\n indexForDeferScroll: -1,\n scrollSnapAlign: 'none',\n});\n\nexport const ScrollStateContext = createContext<ScrollState>(createScrollState());\n\nexport const useScrollState = (): ScrollState => useContext(ScrollStateContext);\n"],"names":[],"mappings":";;;;AA6Ba,MAAA,iBAAiB,GAAG,OAAoB;AACjD,IAAA,YAAY,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AACpC,IAAA,aAAa,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AACrC,IAAA,KAAK,EAAE,IAAI,eAAe,CAA4C,EAAE,CAAC;AACzE,IAAA,cAAc,EAAE,IAAI,WAAW,CAAC,CAAC,CAAC;AAClC,IAAA,wBAAwB,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AAChD,IAAA,cAAc,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;AACtC,IAAA,eAAe,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,CAAC;AACvB,IAAA,eAAe,EAAE,MAAM;AAC1B,CAAA,EAAE;MAEU,kBAAkB,GAAG,aAAa,CAAc,iBAAiB,EAAE,EAAE;AAErE,MAAA,cAAc,GAAG,MAAmB,UAAU,CAAC,kBAAkB;;;;"}
@@ -11,7 +11,7 @@ import { ScrollableContainerGallery } from './ScrollableContainerGallery.js';
11
11
  import { ScrollableItem } from './ScrollableItem.js';
12
12
  import { useScrollableControlsWithState } from './useScrollableControls.js';
13
13
  import { getActualCorrection, useInitOnce } from './utils.js';
14
- import { s as styles } from './scrollableContainer-D9wH7sLu.js';
14
+ import { s as styles } from './scrollableContainer-O2o9Rhhs.js';
15
15
  import 'motion/react';
16
16
  import './ObservableValue.js';
17
17
  import '@hh.ru/magritte-common-use-translation';
@@ -9,7 +9,7 @@ import { ChevronLeftOutlinedSize24, ChevronRightOutlinedSize24 } from '@hh.ru/ma
9
9
  import { useScrollState } from './ScrollStateProvider.js';
10
10
  import { ScrollableContainerLeft, ScrollableContainerRight } from './ScrollableContainerButton.js';
11
11
  import { BREAKPOINTS_LIST, NO_BUTTONS_START_FROM_BREAKPOINT, useInitOnce } from './utils.js';
12
- import { s as styles } from './scrollableContainer-D9wH7sLu.js';
12
+ import { s as styles } from './scrollableContainer-O2o9Rhhs.js';
13
13
  import './ObservableValue.js';
14
14
  import './useScrollableControls.js';
15
15
  import '@hh.ru/magritte-internal-custom-scroll';
@@ -7,7 +7,7 @@ import { useScrollState } from './ScrollStateProvider.js';
7
7
  import { OFFSET_ATTR } from './types.js';
8
8
  import { useInitOnce, findIndexNearestToSnapPoint } from './utils.js';
9
9
  import { VSpacing } from '@hh.ru/magritte-ui-spacing';
10
- import { s as styles } from './scrollableContainer-D9wH7sLu.js';
10
+ import { s as styles } from './scrollableContainer-O2o9Rhhs.js';
11
11
  import 'motion/react';
12
12
  import './ObservableValue.js';
13
13
  import '@hh.ru/magritte-internal-custom-scroll';
@@ -6,7 +6,7 @@ import { clamp } from '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers
6
6
  import { useScrollState } from './ScrollStateProvider.js';
7
7
  import { useScrollContainer } from './useScrollContainer.js';
8
8
  import { getDisableState, findIndexNearestToSnapPoint, computeScrollSnapBehavior } from './utils.js';
9
- import { s as styles } from './scrollableContainer-D9wH7sLu.js';
9
+ import { s as styles } from './scrollableContainer-O2o9Rhhs.js';
10
10
  import './ObservableValue.js';
11
11
  import '@hh.ru/magritte-common-func-utils';
12
12
  import '@hh.ru/magritte-internal-custom-scroll';
package/ScrollableItem.js CHANGED
@@ -13,7 +13,7 @@ import '@hh.ru/magritte-internal-custom-scroll';
13
13
  import './types.js';
14
14
  import './utils.js';
15
15
  import '@hh.ru/magritte-ui-breakpoint';
16
- import './scrollableContainer-D9wH7sLu.js';
16
+ import './scrollableContainer-O2o9Rhhs.js';
17
17
 
18
18
  const ScrollableItem = ({ children, scrollToItemOnFocus, ...props }) => {
19
19
  const ref = useRef(null);
package/index.css CHANGED
@@ -1,8 +1,8 @@
1
- .magritte-scroll-wrapper___vTdZl_6-1-1{
1
+ .magritte-scroll-wrapper___vTdZl_6-2-0{
2
2
  position:relative;
3
3
  touch-action:pan-y pinch-zoom;
4
4
  }
5
- .magritte-scrollable-container___AKIUp_6-1-1{
5
+ .magritte-scrollable-container___AKIUp_6-2-0{
6
6
  display:block;
7
7
  overflow-x:hidden;
8
8
  overflow-x:clip;
@@ -18,34 +18,34 @@
18
18
  margin-left:var(--magritte-ui-scrollabe-container-ml, -4px);
19
19
  margin-right:var(--magritte-ui-scrollabe-container-mr, -4px);
20
20
  }
21
- .magritte-scroll-buttons-container___ZeI5a_6-1-1{
21
+ .magritte-scroll-buttons-container___ZeI5a_6-2-0{
22
22
  position:relative;
23
23
  }
24
- .magritte-scroll-buttons___0SjoR_6-1-1{
24
+ .magritte-scroll-buttons___0SjoR_6-2-0{
25
25
  --right-fade-mask:linear-gradient(90deg, #000 0, #000 calc(100% - 100.50399999999999px), transparent calc(100% - 36px));
26
26
  --left-fade-mask:linear-gradient(90deg, transparent 0, transparent 36px, #000 100.504px);
27
27
  --both-sides-mask:linear-gradient(90deg, transparent 0, transparent 36px, #000 100.504px, #000 calc(100% - 100.50399999999999px), transparent calc(100% - 36px));
28
28
  -webkit-mask:'none';
29
29
  mask:'none';
30
30
  }
31
- .magritte-scroll-button___4GQu3_6-1-1{
31
+ .magritte-scroll-button___4GQu3_6-2-0{
32
32
  display:none;
33
33
  position:absolute;
34
34
  top:50%;
35
35
  transform:translateY(-50%);
36
36
  }
37
- .magritte-scroll-button-left___UueEY_6-1-1{
37
+ .magritte-scroll-button-left___UueEY_6-2-0{
38
38
  z-index:1;
39
39
  left:0;
40
40
  }
41
- .magritte-scroll-button-right___wZOn-_6-1-1{
41
+ .magritte-scroll-button-right___wZOn-_6-2-0{
42
42
  right:0;
43
43
  }
44
- .magritte-position-container___1A4Bv_6-1-1{
44
+ .magritte-position-container___1A4Bv_6-2-0{
45
45
  box-sizing:border-box;
46
46
  width:100%;
47
47
  }
48
- .magritte-dot-container___ahtlG_6-1-1{
48
+ .magritte-dot-container___ahtlG_6-2-0{
49
49
  display:flex;
50
50
  justify-content:center;
51
51
  }
package/index.js CHANGED
@@ -15,7 +15,7 @@ import '@hh.ru/magritte-ui-icon/icon';
15
15
  import './utils.js';
16
16
  import '@hh.ru/magritte-internal-custom-scroll';
17
17
  import './types.js';
18
- import './scrollableContainer-D9wH7sLu.js';
18
+ import './scrollableContainer-O2o9Rhhs.js';
19
19
  import './ScrollableContainerDotPages.js';
20
20
  import '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers';
21
21
  import '@hh.ru/magritte-ui-dot-pages';
package/index.mock.js CHANGED
@@ -13,7 +13,7 @@ import 'react/jsx-runtime';
13
13
  import '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers';
14
14
  import './useScrollContainer.js';
15
15
  import '@hh.ru/magritte-common-func-utils';
16
- import './scrollableContainer-D9wH7sLu.js';
16
+ import './scrollableContainer-O2o9Rhhs.js';
17
17
  import './ObservableValue.js';
18
18
 
19
19
  const staticProps = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hh.ru/magritte-ui-scrollable-container",
3
- "version": "6.1.1",
3
+ "version": "6.2.0",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "sideEffects": [
@@ -20,14 +20,14 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@hh.ru/magritte-common-func-utils": "1.3.14",
23
- "@hh.ru/magritte-common-use-translation": "2.2.0",
24
- "@hh.ru/magritte-design-tokens": "24.3.0",
23
+ "@hh.ru/magritte-common-use-translation": "3.0.0",
24
+ "@hh.ru/magritte-design-tokens": "24.4.0",
25
25
  "@hh.ru/magritte-internal-custom-scroll": "2.1.0",
26
26
  "@hh.ru/magritte-ui-breakpoint": "6.0.6",
27
- "@hh.ru/magritte-ui-dot-pages": "4.0.16",
28
- "@hh.ru/magritte-ui-icon": "13.10.0",
27
+ "@hh.ru/magritte-ui-dot-pages": "4.0.17",
28
+ "@hh.ru/magritte-ui-icon": "13.10.1",
29
29
  "@hh.ru/magritte-ui-mock-component": "1.1.6",
30
- "@hh.ru/magritte-ui-spacing": "2.1.9"
30
+ "@hh.ru/magritte-ui-spacing": "2.1.10"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "classnames": ">=2.3.2",
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "c9930c21240dac1610236be666e8d0c45c60f4bc"
40
+ "gitHead": "f1110cfe8e2cbfed80abc26b72ebcd57cec92d7e"
41
41
  }
@@ -0,0 +1,5 @@
1
+ import './index.css';
2
+ var styles = {"scroll-wrapper":"magritte-scroll-wrapper___vTdZl_6-2-0","scrollWrapper":"magritte-scroll-wrapper___vTdZl_6-2-0","scrollable-container":"magritte-scrollable-container___AKIUp_6-2-0","scrollableContainer":"magritte-scrollable-container___AKIUp_6-2-0","scroll-buttons-container":"magritte-scroll-buttons-container___ZeI5a_6-2-0","scrollButtonsContainer":"magritte-scroll-buttons-container___ZeI5a_6-2-0","scroll-buttons":"magritte-scroll-buttons___0SjoR_6-2-0","scrollButtons":"magritte-scroll-buttons___0SjoR_6-2-0","scroll-button":"magritte-scroll-button___4GQu3_6-2-0","scrollButton":"magritte-scroll-button___4GQu3_6-2-0","scroll-button-left":"magritte-scroll-button-left___UueEY_6-2-0","scrollButtonLeft":"magritte-scroll-button-left___UueEY_6-2-0","scroll-button-right":"magritte-scroll-button-right___wZOn-_6-2-0","scrollButtonRight":"magritte-scroll-button-right___wZOn-_6-2-0","position-container":"magritte-position-container___1A4Bv_6-2-0","positionContainer":"magritte-position-container___1A4Bv_6-2-0","dot-container":"magritte-dot-container___ahtlG_6-2-0","dotContainer":"magritte-dot-container___ahtlG_6-2-0"};
3
+
4
+ export { styles as s };
5
+ //# sourceMappingURL=scrollableContainer-O2o9Rhhs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollableContainer-O2o9Rhhs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,5 +1,5 @@
1
1
  import './index.css';
2
- import { useState, useRef, useCallback, useEffect, useLayoutEffect } from 'react';
2
+ import { useState, useRef, useCallback, useEffect } from 'react';
3
3
  import { debounce, requestAnimation } from '@hh.ru/magritte-common-func-utils';
4
4
  import { clamp, initScrollHandlers } from '@hh.ru/magritte-internal-custom-scroll';
5
5
  import { useScrollState } from './ScrollStateProvider.js';
@@ -80,21 +80,6 @@ const useScrollContainer = () => {
80
80
  return () => observer.disconnect();
81
81
  // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps
82
82
  }, []);
83
- // Слушатель нужен для пересчета размеров в случае, когда родительский контейнер открывается с анимацией,
84
- // на которую не срабатывает ResizeObserver - например, Modal с transition: scale
85
- useLayoutEffect(() => {
86
- const handler = (event) => {
87
- const { containerRef } = scrollStateRef.current;
88
- if (!scrollState.wasContainerInteracted &&
89
- event.target instanceof Element &&
90
- containerRef.current &&
91
- event.target.contains(containerRef.current)) {
92
- recalculateItemPositions();
93
- }
94
- };
95
- document.addEventListener('transitionend', handler);
96
- return () => document.removeEventListener('transitionend', handler);
97
- }, [recalculateItemPositions, scrollState]);
98
83
  // Слушатель нужен, чтобы не вызывать скролл в родительском контейнере (например в bs)
99
84
  useEffect(() => {
100
85
  const wrapperRef = scrollStateRef.current.containerRef.current;
@@ -117,7 +102,6 @@ const useScrollContainer = () => {
117
102
  scrollState.scrollPosition.stop();
118
103
  }, [scrollState]);
119
104
  const onTouchMove = useCallback((event) => {
120
- scrollState.wasContainerInteracted = true;
121
105
  if (!didContainerMove.current) {
122
106
  // надо отличить тач от свайпа
123
107
  didContainerMove.current = Math.abs(event.delta) > MIN_DELTA_FOR_TOUCH;
@@ -136,7 +120,6 @@ const useScrollContainer = () => {
136
120
  }, []);
137
121
  const onWheelMove = useCallback((event) => {
138
122
  setIsTouch(false);
139
- scrollState.wasContainerInteracted = true;
140
123
  if (!didContainerHovered.current) {
141
124
  return;
142
125
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollContainer.js","sources":["../src/useScrollContainer.ts"],"sourcesContent":["import { useRef, useEffect, type RefObject, useCallback, useLayoutEffect, useState } from 'react';\n\nimport { requestAnimation, debounce } from '@hh.ru/magritte-common-func-utils';\nimport { clamp, type ScrollGestureEvent, initScrollHandlers } from '@hh.ru/magritte-internal-custom-scroll';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport { type ItemWithOffset, OFFSET_ATTR } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport { useScrollableControls } from '@hh.ru/magritte-ui-scrollable-container/useScrollableControls';\nimport {\n useInitOnce,\n findIndexNearestToSnapPoint,\n animateScrollToPosition,\n computeScrollSnapBehavior,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nconst EPSILON = 0.5;\nconst MIN_DELTA_FOR_TOUCH = 5;\nconst MAX_OFFSET = { [OFFSET_ATTR]: { left: Number.MAX_SAFE_INTEGER } };\n\n/**\n * Переменные полностью описывающие состояние скролла, хранятся в одном объекте, чтобы не плодить\n * кучу ref'ов и передавать всё состояние в функции одним аргументом, а не длинным списком переменных\n */\nexport interface ScrollInternalState {\n /** контейнер, в котором лежит positionContainer (определяет видимую область) */\n containerRef: RefObject<HTMLDivElement>;\n /** контейнер, с помощью изменения положения которого обеспечивается скролл */\n positionContainerRef: RefObject<HTMLDivElement>;\n /** размер коррекции отступов */\n correction: { leftCorrection: number; rightCorrection: number };\n /* Было ли взаимодействие с компонентом - скролл или прокрутка к элементу */\n wasInteracted: boolean;\n}\n\ninterface UseScrollContainer {\n registerItem: (ref: RefObject<HTMLElement>) => void;\n removeItem: (ref: RefObject<HTMLElement>) => void;\n initScrollHandlers: () => VoidFunction;\n containerRef: RefObject<HTMLDivElement>;\n positionContainerRef: RefObject<HTMLDivElement>;\n isTouch: boolean;\n}\n\nexport const useScrollContainer = (): UseScrollContainer => {\n const scrollState = useScrollState();\n const { scrollToIndex } = useScrollableControls();\n const [isTouch, setIsTouch] = useState(false);\n const leftCorrection = scrollState.leftCorrection.get();\n const rightCorrection = scrollState.rightCorrection.get();\n const scrollStateRef = useRef<ScrollInternalState>({\n containerRef: useRef<HTMLDivElement>(null),\n positionContainerRef: useRef<HTMLDivElement>(null),\n correction: { leftCorrection, rightCorrection },\n wasInteracted: false,\n });\n scrollStateRef.current.correction = { leftCorrection, rightCorrection };\n const resizeOberverRef = useRef<ResizeObserver | null>(null);\n\n // recalc positions + report widths into store\n const recalculateItemPositions = useCallback(() => {\n const state = scrollStateRef.current;\n const { containerRef, correction, positionContainerRef } = state;\n const { leftCorrection, rightCorrection } = correction;\n const items = scrollState.items.get();\n if (!containerRef.current || !positionContainerRef.current) {\n return;\n }\n const offsetLeft = positionContainerRef.current?.getBoundingClientRect().left ?? 0;\n items.forEach((itemRef) => {\n if (!itemRef.current) {\n return;\n }\n const rect = itemRef.current.getBoundingClientRect();\n itemRef.current[OFFSET_ATTR] = { left: rect.left - offsetLeft, right: rect.right - offsetLeft };\n });\n items.sort((a, b) => (a.current || MAX_OFFSET)[OFFSET_ATTR].left - (b.current || MAX_OFFSET)[OFFSET_ATTR].left);\n const viewportWidth = containerRef.current.offsetWidth - leftCorrection - rightCorrection;\n const contentWidth = items.reduce(\n (pos, itemRef) => Math.max(pos, itemRef.current?.[OFFSET_ATTR]?.right || 0),\n 0\n );\n scrollState.viewportWidth.set(viewportWidth);\n scrollState.contentWidth.set(contentWidth);\n scrollState.items.set(items);\n if (scrollState.indexForDeferScroll !== -1) {\n scrollToIndex(scrollState.indexForDeferScroll);\n scrollState.indexForDeferScroll = -1;\n }\n }, [scrollState, scrollToIndex]);\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const recalculateItemPositionsDebounced = useCallback(debounce(recalculateItemPositions, 10), [\n recalculateItemPositions,\n ]);\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const scrollToItemDebounced = useInitOnce(() =>\n debounce(() => {\n if (scrollState.scrollSnapAlign === 'none') {\n return;\n }\n const targetItemIndex = findIndexNearestToSnapPoint(scrollState);\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, targetItemIndex);\n animateScrollToPosition(scrollState, target);\n }, 100)\n );\n\n useEffect(() => {\n const state = scrollStateRef.current;\n const observer = new ResizeObserver(\n requestAnimation(() => {\n recalculateItemPositions();\n })\n );\n\n scrollState.items.get().forEach((item) => item.current && observer.observe(item.current));\n state.containerRef.current && observer.observe(state.containerRef.current);\n resizeOberverRef.current = observer;\n return () => observer.disconnect();\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n }, []);\n\n // Слушатель нужен для пересчета размеров в случае, когда родительский контейнер открывается с анимацией,\n // на которую не срабатывает ResizeObserver - например, Modal с transition: scale\n useLayoutEffect(() => {\n const handler = (event: TransitionEvent) => {\n const { containerRef } = scrollStateRef.current;\n if (\n !scrollState.wasContainerInteracted &&\n event.target instanceof Element &&\n containerRef.current &&\n event.target.contains(containerRef.current)\n ) {\n recalculateItemPositions();\n }\n };\n\n document.addEventListener('transitionend', handler);\n return () => document.removeEventListener('transitionend', handler);\n }, [recalculateItemPositions, scrollState]);\n\n // Слушатель нужен, чтобы не вызывать скролл в родительском контейнере (например в bs)\n useEffect(() => {\n const wrapperRef = scrollStateRef.current.containerRef.current;\n if (!wrapperRef) {\n return void 0;\n }\n const handleTouchStartHandler = (event: TouchEvent) => {\n event.stopPropagation();\n };\n wrapperRef.addEventListener('touchstart', handleTouchStartHandler);\n return () => {\n wrapperRef.removeEventListener('touchstart', handleTouchStartHandler);\n };\n }, []);\n\n // события тача\n const didContainerMove = useRef(false);\n const onTouchStart = useCallback(() => {\n setIsTouch(true);\n didContainerMove.current = false;\n scrollState.scrollPosition.stop();\n }, [scrollState]);\n\n const onTouchMove = useCallback(\n (event: ScrollGestureEvent) => {\n scrollState.wasContainerInteracted = true;\n if (!didContainerMove.current) {\n // надо отличить тач от свайпа\n didContainerMove.current = Math.abs(event.delta) > MIN_DELTA_FOR_TOUCH;\n }\n scrollState.scrollPosition.set(\n clamp(\n scrollState.scrollPosition.get() + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n )\n );\n },\n [scrollState]\n );\n\n const onTouchEnd = useCallback(() => {\n if (didContainerMove.current) {\n scrollToItemDebounced();\n }\n }, [scrollToItemDebounced]);\n\n // события мыши\n const didContainerHovered = useRef(false);\n const onMouseEnter = useCallback(() => {\n didContainerHovered.current = true;\n }, []);\n\n const onWheelMove = useCallback(\n (event: ScrollGestureEvent) => {\n setIsTouch(false);\n scrollState.wasContainerInteracted = true;\n if (!didContainerHovered.current) {\n return;\n }\n const currentPosition = scrollState.scrollPosition.get();\n const nextPosition = clamp(\n currentPosition + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n );\n if (Math.abs(nextPosition - currentPosition) > EPSILON) {\n scrollState.scrollPosition.set(nextPosition);\n scrollToItemDebounced();\n event.preventDefault();\n }\n },\n [scrollToItemDebounced, scrollState]\n );\n\n const onMouseLeave = useCallback(() => {\n didContainerHovered.current = false;\n }, []);\n\n const _initScrollHandlers = useCallback(\n () =>\n initScrollHandlers({\n axis: 'horizontal',\n wrapperRef: scrollStateRef.current.containerRef,\n onTouchStart,\n onTouchMove,\n onTouchEnd,\n onMouseEnter,\n onWheelMove,\n onMouseLeave,\n }),\n [onTouchMove, onTouchEnd, onWheelMove, onTouchStart, onMouseEnter, onMouseLeave]\n );\n\n const registerItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.get().push(ref as unknown as RefObject<HTMLElement & ItemWithOffset>);\n scrollState.items.set(scrollState.items.get());\n resizeOberverRef.current?.observe(ref.current);\n recalculateItemPositions();\n },\n [recalculateItemPositions, scrollState]\n );\n\n const removeItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.set(scrollState.items.get().filter((stored) => stored.current !== ref.current));\n resizeOberverRef.current?.unobserve(ref.current);\n recalculateItemPositionsDebounced();\n },\n [recalculateItemPositionsDebounced, scrollState]\n );\n\n return {\n registerItem,\n removeItem,\n initScrollHandlers: _initScrollHandlers,\n containerRef: scrollStateRef.current.containerRef,\n positionContainerRef: scrollStateRef.current.positionContainerRef,\n isTouch,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useScrollContainer.js","sources":["../src/useScrollContainer.ts"],"sourcesContent":["import { useRef, useEffect, type RefObject, useCallback, useState } from 'react';\n\nimport { requestAnimation, debounce } from '@hh.ru/magritte-common-func-utils';\nimport { clamp, type ScrollGestureEvent, initScrollHandlers } from '@hh.ru/magritte-internal-custom-scroll';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport { type ItemWithOffset, OFFSET_ATTR } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport { useScrollableControls } from '@hh.ru/magritte-ui-scrollable-container/useScrollableControls';\nimport {\n useInitOnce,\n findIndexNearestToSnapPoint,\n animateScrollToPosition,\n computeScrollSnapBehavior,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nconst EPSILON = 0.5;\nconst MIN_DELTA_FOR_TOUCH = 5;\nconst MAX_OFFSET = { [OFFSET_ATTR]: { left: Number.MAX_SAFE_INTEGER } };\n\n/**\n * Переменные полностью описывающие состояние скролла, хранятся в одном объекте, чтобы не плодить\n * кучу ref'ов и передавать всё состояние в функции одним аргументом, а не длинным списком переменных\n */\nexport interface ScrollInternalState {\n /** контейнер, в котором лежит positionContainer (определяет видимую область) */\n containerRef: RefObject<HTMLDivElement>;\n /** контейнер, с помощью изменения положения которого обеспечивается скролл */\n positionContainerRef: RefObject<HTMLDivElement>;\n /** размер коррекции отступов */\n correction: { leftCorrection: number; rightCorrection: number };\n /* Было ли взаимодействие с компонентом - скролл или прокрутка к элементу */\n wasInteracted: boolean;\n}\n\ninterface UseScrollContainer {\n registerItem: (ref: RefObject<HTMLElement>) => void;\n removeItem: (ref: RefObject<HTMLElement>) => void;\n initScrollHandlers: () => VoidFunction;\n containerRef: RefObject<HTMLDivElement>;\n positionContainerRef: RefObject<HTMLDivElement>;\n isTouch: boolean;\n}\n\nexport const useScrollContainer = (): UseScrollContainer => {\n const scrollState = useScrollState();\n const { scrollToIndex } = useScrollableControls();\n const [isTouch, setIsTouch] = useState(false);\n const leftCorrection = scrollState.leftCorrection.get();\n const rightCorrection = scrollState.rightCorrection.get();\n const scrollStateRef = useRef<ScrollInternalState>({\n containerRef: useRef<HTMLDivElement>(null),\n positionContainerRef: useRef<HTMLDivElement>(null),\n correction: { leftCorrection, rightCorrection },\n wasInteracted: false,\n });\n scrollStateRef.current.correction = { leftCorrection, rightCorrection };\n const resizeOberverRef = useRef<ResizeObserver | null>(null);\n\n // recalc positions + report widths into store\n const recalculateItemPositions = useCallback(() => {\n const state = scrollStateRef.current;\n const { containerRef, correction, positionContainerRef } = state;\n const { leftCorrection, rightCorrection } = correction;\n const items = scrollState.items.get();\n if (!containerRef.current || !positionContainerRef.current) {\n return;\n }\n const offsetLeft = positionContainerRef.current?.getBoundingClientRect().left ?? 0;\n items.forEach((itemRef) => {\n if (!itemRef.current) {\n return;\n }\n const rect = itemRef.current.getBoundingClientRect();\n itemRef.current[OFFSET_ATTR] = { left: rect.left - offsetLeft, right: rect.right - offsetLeft };\n });\n items.sort((a, b) => (a.current || MAX_OFFSET)[OFFSET_ATTR].left - (b.current || MAX_OFFSET)[OFFSET_ATTR].left);\n const viewportWidth = containerRef.current.offsetWidth - leftCorrection - rightCorrection;\n const contentWidth = items.reduce(\n (pos, itemRef) => Math.max(pos, itemRef.current?.[OFFSET_ATTR]?.right || 0),\n 0\n );\n scrollState.viewportWidth.set(viewportWidth);\n scrollState.contentWidth.set(contentWidth);\n scrollState.items.set(items);\n if (scrollState.indexForDeferScroll !== -1) {\n scrollToIndex(scrollState.indexForDeferScroll);\n scrollState.indexForDeferScroll = -1;\n }\n }, [scrollState, scrollToIndex]);\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const recalculateItemPositionsDebounced = useCallback(debounce(recalculateItemPositions, 10), [\n recalculateItemPositions,\n ]);\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const scrollToItemDebounced = useInitOnce(() =>\n debounce(() => {\n if (scrollState.scrollSnapAlign === 'none') {\n return;\n }\n const targetItemIndex = findIndexNearestToSnapPoint(scrollState);\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, targetItemIndex);\n animateScrollToPosition(scrollState, target);\n }, 100)\n );\n\n useEffect(() => {\n const state = scrollStateRef.current;\n const observer = new ResizeObserver(\n requestAnimation(() => {\n recalculateItemPositions();\n })\n );\n\n scrollState.items.get().forEach((item) => item.current && observer.observe(item.current));\n state.containerRef.current && observer.observe(state.containerRef.current);\n resizeOberverRef.current = observer;\n return () => observer.disconnect();\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n }, []);\n\n // Слушатель нужен, чтобы не вызывать скролл в родительском контейнере (например в bs)\n useEffect(() => {\n const wrapperRef = scrollStateRef.current.containerRef.current;\n if (!wrapperRef) {\n return void 0;\n }\n const handleTouchStartHandler = (event: TouchEvent) => {\n event.stopPropagation();\n };\n wrapperRef.addEventListener('touchstart', handleTouchStartHandler);\n return () => {\n wrapperRef.removeEventListener('touchstart', handleTouchStartHandler);\n };\n }, []);\n\n // события тача\n const didContainerMove = useRef(false);\n const onTouchStart = useCallback(() => {\n setIsTouch(true);\n didContainerMove.current = false;\n scrollState.scrollPosition.stop();\n }, [scrollState]);\n\n const onTouchMove = useCallback(\n (event: ScrollGestureEvent) => {\n if (!didContainerMove.current) {\n // надо отличить тач от свайпа\n didContainerMove.current = Math.abs(event.delta) > MIN_DELTA_FOR_TOUCH;\n }\n scrollState.scrollPosition.set(\n clamp(\n scrollState.scrollPosition.get() + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n )\n );\n },\n [scrollState]\n );\n\n const onTouchEnd = useCallback(() => {\n if (didContainerMove.current) {\n scrollToItemDebounced();\n }\n }, [scrollToItemDebounced]);\n\n // события мыши\n const didContainerHovered = useRef(false);\n const onMouseEnter = useCallback(() => {\n didContainerHovered.current = true;\n }, []);\n\n const onWheelMove = useCallback(\n (event: ScrollGestureEvent) => {\n setIsTouch(false);\n if (!didContainerHovered.current) {\n return;\n }\n const currentPosition = scrollState.scrollPosition.get();\n const nextPosition = clamp(\n currentPosition + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n );\n if (Math.abs(nextPosition - currentPosition) > EPSILON) {\n scrollState.scrollPosition.set(nextPosition);\n scrollToItemDebounced();\n event.preventDefault();\n }\n },\n [scrollToItemDebounced, scrollState]\n );\n\n const onMouseLeave = useCallback(() => {\n didContainerHovered.current = false;\n }, []);\n\n const _initScrollHandlers = useCallback(\n () =>\n initScrollHandlers({\n axis: 'horizontal',\n wrapperRef: scrollStateRef.current.containerRef,\n onTouchStart,\n onTouchMove,\n onTouchEnd,\n onMouseEnter,\n onWheelMove,\n onMouseLeave,\n }),\n [onTouchMove, onTouchEnd, onWheelMove, onTouchStart, onMouseEnter, onMouseLeave]\n );\n\n const registerItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.get().push(ref as unknown as RefObject<HTMLElement & ItemWithOffset>);\n scrollState.items.set(scrollState.items.get());\n resizeOberverRef.current?.observe(ref.current);\n recalculateItemPositions();\n },\n [recalculateItemPositions, scrollState]\n );\n\n const removeItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.set(scrollState.items.get().filter((stored) => stored.current !== ref.current));\n resizeOberverRef.current?.unobserve(ref.current);\n recalculateItemPositionsDebounced();\n },\n [recalculateItemPositionsDebounced, scrollState]\n );\n\n return {\n registerItem,\n removeItem,\n initScrollHandlers: _initScrollHandlers,\n containerRef: scrollStateRef.current.containerRef,\n positionContainerRef: scrollStateRef.current.positionContainerRef,\n isTouch,\n };\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAcA,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,UAAU,GAAG,EAAE,CAAC,WAAW,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC;AA0BjE,MAAM,kBAAkB,GAAG,MAAyB;AACvD,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;AACrC,IAAA,MAAM,EAAE,aAAa,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC;IACxD,MAAM,eAAe,GAAG,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC;IAC1D,MAAM,cAAc,GAAG,MAAM,CAAsB;AAC/C,QAAA,YAAY,EAAE,MAAM,CAAiB,IAAI,CAAC;AAC1C,QAAA,oBAAoB,EAAE,MAAM,CAAiB,IAAI,CAAC;AAClD,QAAA,UAAU,EAAE,EAAE,cAAc,EAAE,eAAe,EAAE;AAC/C,QAAA,aAAa,EAAE,KAAK;AACvB,KAAA,CAAC,CAAC;IACH,cAAc,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;AACxE,IAAA,MAAM,gBAAgB,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;;AAG7D,IAAA,MAAM,wBAAwB,GAAG,WAAW,CAAC,MAAK;AAC9C,QAAA,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC;QACrC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,GAAG,KAAK,CAAC;AACjE,QAAA,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,UAAU,CAAC;QACvD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE;YACxD,OAAO;SACV;AACD,QAAA,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC;AACnF,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,KAAI;AACtB,YAAA,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;gBAClB,OAAO;aACV;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YACrD,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,UAAU,EAAE,CAAC;AACpG,SAAC,CAAC,CAAC;AACH,QAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,EAAE,WAAW,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC;QAChH,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,GAAG,cAAc,GAAG,eAAe,CAAC;AAC1F,QAAA,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAC7B,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,WAAW,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,EAC3E,CAAC,CACJ,CAAC;AACF,QAAA,WAAW,CAAC,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC7C,QAAA,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC3C,QAAA,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC7B,QAAA,IAAI,WAAW,CAAC,mBAAmB,KAAK,CAAC,CAAC,EAAE;AACxC,YAAA,aAAa,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAC/C,YAAA,WAAW,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC;SACxC;AACL,KAAC,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;;IAGjC,MAAM,iCAAiC,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,EAAE,EAAE,CAAC,EAAE;QAC1F,wBAAwB;AAC3B,KAAA,CAAC,CAAC;;IAGH,MAAM,qBAAqB,GAAG,WAAW,CAAC,MACtC,QAAQ,CAAC,MAAK;AACV,QAAA,IAAI,WAAW,CAAC,eAAe,KAAK,MAAM,EAAE;YACxC,OAAO;SACV;AACD,QAAA,MAAM,eAAe,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;AACjE,QAAA,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,WAAW,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;AAChE,QAAA,uBAAuB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACjD,KAAC,EAAE,GAAG,CAAC,CACV,CAAC;IAEF,SAAS,CAAC,MAAK;AACX,QAAA,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAC/B,gBAAgB,CAAC,MAAK;AAClB,YAAA,wBAAwB,EAAE,CAAC;SAC9B,CAAC,CACL,CAAC;QAEF,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAC1F,QAAA,KAAK,CAAC,YAAY,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AAC3E,QAAA,gBAAgB,CAAC,OAAO,GAAG,QAAQ,CAAC;AACpC,QAAA,OAAO,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;;KAEtC,EAAE,EAAE,CAAC,CAAC;;IAGP,SAAS,CAAC,MAAK;QACX,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;QAC/D,IAAI,CAAC,UAAU,EAAE;YACb,OAAO,KAAK,CAAC,CAAC;SACjB;AACD,QAAA,MAAM,uBAAuB,GAAG,CAAC,KAAiB,KAAI;YAClD,KAAK,CAAC,eAAe,EAAE,CAAC;AAC5B,SAAC,CAAC;AACF,QAAA,UAAU,CAAC,gBAAgB,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;AACnE,QAAA,OAAO,MAAK;AACR,YAAA,UAAU,CAAC,mBAAmB,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;AAC1E,SAAC,CAAC;KACL,EAAE,EAAE,CAAC,CAAC;;AAGP,IAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACvC,IAAA,MAAM,YAAY,GAAG,WAAW,CAAC,MAAK;QAClC,UAAU,CAAC,IAAI,CAAC,CAAC;AACjB,QAAA,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC;AACjC,QAAA,WAAW,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;AACtC,KAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAElB,IAAA,MAAM,WAAW,GAAG,WAAW,CAC3B,CAAC,KAAyB,KAAI;AAC1B,QAAA,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE;;AAE3B,YAAA,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,mBAAmB,CAAC;SAC1E;AACD,QAAA,WAAW,CAAC,cAAc,CAAC,GAAG,CAC1B,KAAK,CACD,WAAW,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,EAC9C,WAAW,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,EAChE,CAAC,CACJ,CACJ,CAAC;AACN,KAAC,EACD,CAAC,WAAW,CAAC,CAChB,CAAC;AAEF,IAAA,MAAM,UAAU,GAAG,WAAW,CAAC,MAAK;AAChC,QAAA,IAAI,gBAAgB,CAAC,OAAO,EAAE;AAC1B,YAAA,qBAAqB,EAAE,CAAC;SAC3B;AACL,KAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC;;AAG5B,IAAA,MAAM,mBAAmB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1C,IAAA,MAAM,YAAY,GAAG,WAAW,CAAC,MAAK;AAClC,QAAA,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC;KACtC,EAAE,EAAE,CAAC,CAAC;AAEP,IAAA,MAAM,WAAW,GAAG,WAAW,CAC3B,CAAC,KAAyB,KAAI;QAC1B,UAAU,CAAC,KAAK,CAAC,CAAC;AAClB,QAAA,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE;YAC9B,OAAO;SACV;QACD,MAAM,eAAe,GAAG,WAAW,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC;QACzD,MAAM,YAAY,GAAG,KAAK,CACtB,eAAe,GAAG,KAAK,CAAC,KAAK,EAC7B,WAAW,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,EAChE,CAAC,CACJ,CAAC;QACF,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,eAAe,CAAC,GAAG,OAAO,EAAE;AACpD,YAAA,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC7C,YAAA,qBAAqB,EAAE,CAAC;YACxB,KAAK,CAAC,cAAc,EAAE,CAAC;SAC1B;AACL,KAAC,EACD,CAAC,qBAAqB,EAAE,WAAW,CAAC,CACvC,CAAC;AAEF,IAAA,MAAM,YAAY,GAAG,WAAW,CAAC,MAAK;AAClC,QAAA,mBAAmB,CAAC,OAAO,GAAG,KAAK,CAAC;KACvC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,mBAAmB,GAAG,WAAW,CACnC,MACI,kBAAkB,CAAC;AACf,QAAA,IAAI,EAAE,YAAY;AAClB,QAAA,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC,YAAY;QAC/C,YAAY;QACZ,WAAW;QACX,UAAU;QACV,YAAY;QACZ,WAAW;QACX,YAAY;AACf,KAAA,CAAC,EACN,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,CAAC,CACnF,CAAC;AAEF,IAAA,MAAM,YAAY,GAAG,WAAW,CAC5B,CAAC,GAA2B,KAAI;AAC5B,QAAA,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;YACd,OAAO;SACV;QACD,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAyD,CAAC,CAAC;AACxF,QAAA,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/C,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC/C,QAAA,wBAAwB,EAAE,CAAC;AAC/B,KAAC,EACD,CAAC,wBAAwB,EAAE,WAAW,CAAC,CAC1C,CAAC;AAEF,IAAA,MAAM,UAAU,GAAG,WAAW,CAC1B,CAAC,GAA2B,KAAI;AAC5B,QAAA,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;YACd,OAAO;SACV;AACD,QAAA,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAClG,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACjD,QAAA,iCAAiC,EAAE,CAAC;AACxC,KAAC,EACD,CAAC,iCAAiC,EAAE,WAAW,CAAC,CACnD,CAAC;IAEF,OAAO;QACH,YAAY;QACZ,UAAU;AACV,QAAA,kBAAkB,EAAE,mBAAmB;AACvC,QAAA,YAAY,EAAE,cAAc,CAAC,OAAO,CAAC,YAAY;AACjD,QAAA,oBAAoB,EAAE,cAAc,CAAC,OAAO,CAAC,oBAAoB;QACjE,OAAO;KACV,CAAC;AACN;;;;"}
@@ -10,7 +10,6 @@ import './types.js';
10
10
 
11
11
  const useScrollableControlsWithState = (scrollState) => {
12
12
  const scrollSide = useCallback((toRight = false) => {
13
- scrollState.wasContainerInteracted = true;
14
13
  if (scrollState.scrollSnapAlign === 'none') {
15
14
  const delta = toRight ? -scrollState.viewportWidth.get() : scrollState.viewportWidth.get();
16
15
  const position = scrollState.scrollPosition.get() + delta;
@@ -27,7 +26,6 @@ const useScrollableControlsWithState = (scrollState) => {
27
26
  animateScrollToPosition(scrollState, target);
28
27
  }, [scrollState]);
29
28
  const scrollToIndex = useCallback((index) => {
30
- scrollState.wasContainerInteracted = true;
31
29
  if (!ensureItemReadyForScroll(scrollState, index)) {
32
30
  return;
33
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollableControls.js","sources":["../src/useScrollableControls.tsx"],"sourcesContent":["import { useCallback, type RefObject } from 'react';\n\nimport { clamp } from '@hh.ru/magritte-internal-custom-scroll';\nimport { useScrollState, type ScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport type { ScrollableControls } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport {\n findIndexNearestToSnapPoint,\n animateScrollToPosition,\n ensureItemReadyForScroll,\n computeScrollSnapBehavior,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nexport const useScrollableControlsWithState: (scrollState: ScrollState) => ScrollableControls = (scrollState) => {\n const scrollSide = useCallback(\n (toRight: boolean = false) => {\n scrollState.wasContainerInteracted = true;\n if (scrollState.scrollSnapAlign === 'none') {\n const delta = toRight ? -scrollState.viewportWidth.get() : scrollState.viewportWidth.get();\n const position = scrollState.scrollPosition.get() + delta;\n animateScrollToPosition(scrollState, position);\n return;\n }\n const index = findIndexNearestToSnapPoint(scrollState);\n const nextIndex = clamp(toRight ? index + 1 : index - 1, 0, scrollState.items.get().length - 1);\n if (!ensureItemReadyForScroll(scrollState, nextIndex)) {\n return;\n }\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, nextIndex);\n animateScrollToPosition(scrollState, target);\n },\n [scrollState]\n );\n\n const scrollToIndex = useCallback(\n (index: number) => {\n scrollState.wasContainerInteracted = true;\n if (!ensureItemReadyForScroll(scrollState, index)) {\n return;\n }\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, index);\n animateScrollToPosition(scrollState, target);\n },\n [scrollState]\n );\n\n const scrollToFirstItem = useCallback(() => scrollToIndex(0), [scrollToIndex]);\n\n const scrollToLastItem = useCallback(\n () => scrollToIndex(scrollState.items.get().length - 1),\n [scrollState, scrollToIndex]\n );\n\n const scrollToItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n const index = scrollState.items.get().findIndex((item) => item.current && item.current === ref.current);\n index !== -1 && scrollToIndex(index);\n },\n [scrollState, scrollToIndex]\n );\n\n return {\n scrollLeft: () => scrollSide(),\n scrollRight: () => scrollSide(true),\n scrollToFirstItem,\n scrollToLastItem,\n scrollToIndex,\n scrollToItem,\n };\n};\n\nexport const useScrollableControls: () => ScrollableControls = () => {\n const scrollState = useScrollState();\n const controls = useScrollableControlsWithState(scrollState);\n return controls;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useScrollableControls.js","sources":["../src/useScrollableControls.tsx"],"sourcesContent":["import { useCallback, type RefObject } from 'react';\n\nimport { clamp } from '@hh.ru/magritte-internal-custom-scroll';\nimport { useScrollState, type ScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport type { ScrollableControls } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport {\n findIndexNearestToSnapPoint,\n animateScrollToPosition,\n ensureItemReadyForScroll,\n computeScrollSnapBehavior,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nexport const useScrollableControlsWithState: (scrollState: ScrollState) => ScrollableControls = (scrollState) => {\n const scrollSide = useCallback(\n (toRight: boolean = false) => {\n if (scrollState.scrollSnapAlign === 'none') {\n const delta = toRight ? -scrollState.viewportWidth.get() : scrollState.viewportWidth.get();\n const position = scrollState.scrollPosition.get() + delta;\n animateScrollToPosition(scrollState, position);\n return;\n }\n const index = findIndexNearestToSnapPoint(scrollState);\n const nextIndex = clamp(toRight ? index + 1 : index - 1, 0, scrollState.items.get().length - 1);\n if (!ensureItemReadyForScroll(scrollState, nextIndex)) {\n return;\n }\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, nextIndex);\n animateScrollToPosition(scrollState, target);\n },\n [scrollState]\n );\n\n const scrollToIndex = useCallback(\n (index: number) => {\n if (!ensureItemReadyForScroll(scrollState, index)) {\n return;\n }\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, index);\n animateScrollToPosition(scrollState, target);\n },\n [scrollState]\n );\n\n const scrollToFirstItem = useCallback(() => scrollToIndex(0), [scrollToIndex]);\n\n const scrollToLastItem = useCallback(\n () => scrollToIndex(scrollState.items.get().length - 1),\n [scrollState, scrollToIndex]\n );\n\n const scrollToItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n const index = scrollState.items.get().findIndex((item) => item.current && item.current === ref.current);\n index !== -1 && scrollToIndex(index);\n },\n [scrollState, scrollToIndex]\n );\n\n return {\n scrollLeft: () => scrollSide(),\n scrollRight: () => scrollSide(true),\n scrollToFirstItem,\n scrollToLastItem,\n scrollToIndex,\n scrollToItem,\n };\n};\n\nexport const useScrollableControls: () => ScrollableControls = () => {\n const scrollState = useScrollState();\n const controls = useScrollableControlsWithState(scrollState);\n return controls;\n};\n"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import './index.css';
2
- var styles = {"scroll-wrapper":"magritte-scroll-wrapper___vTdZl_6-1-1","scrollWrapper":"magritte-scroll-wrapper___vTdZl_6-1-1","scrollable-container":"magritte-scrollable-container___AKIUp_6-1-1","scrollableContainer":"magritte-scrollable-container___AKIUp_6-1-1","scroll-buttons-container":"magritte-scroll-buttons-container___ZeI5a_6-1-1","scrollButtonsContainer":"magritte-scroll-buttons-container___ZeI5a_6-1-1","scroll-buttons":"magritte-scroll-buttons___0SjoR_6-1-1","scrollButtons":"magritte-scroll-buttons___0SjoR_6-1-1","scroll-button":"magritte-scroll-button___4GQu3_6-1-1","scrollButton":"magritte-scroll-button___4GQu3_6-1-1","scroll-button-left":"magritte-scroll-button-left___UueEY_6-1-1","scrollButtonLeft":"magritte-scroll-button-left___UueEY_6-1-1","scroll-button-right":"magritte-scroll-button-right___wZOn-_6-1-1","scrollButtonRight":"magritte-scroll-button-right___wZOn-_6-1-1","position-container":"magritte-position-container___1A4Bv_6-1-1","positionContainer":"magritte-position-container___1A4Bv_6-1-1","dot-container":"magritte-dot-container___ahtlG_6-1-1","dotContainer":"magritte-dot-container___ahtlG_6-1-1"};
3
-
4
- export { styles as s };
5
- //# sourceMappingURL=scrollableContainer-D9wH7sLu.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scrollableContainer-D9wH7sLu.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}