@hh.ru/magritte-ui-scrollable-container 6.5.2 → 6.5.3

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.
Files changed (44) hide show
  1. package/ObservableValue.js +17 -17
  2. package/ObservableValue.js.map +1 -1
  3. package/ScrollStateProvider.d.ts +2 -2
  4. package/ScrollStateProvider.js +11 -11
  5. package/ScrollStateProvider.js.map +1 -1
  6. package/ScrollableContainer.d.ts +8 -8
  7. package/ScrollableContainer.js +99 -60
  8. package/ScrollableContainer.js.map +1 -1
  9. package/ScrollableContainerButton.d.ts +1 -1
  10. package/ScrollableContainerButton.js +15 -12
  11. package/ScrollableContainerButton.js.map +1 -1
  12. package/ScrollableContainerDefaultLayout.d.ts +1 -1
  13. package/ScrollableContainerDefaultLayout.js +130 -68
  14. package/ScrollableContainerDefaultLayout.js.map +1 -1
  15. package/ScrollableContainerDotPages.d.ts +1 -1
  16. package/ScrollableContainerDotPages.js +59 -47
  17. package/ScrollableContainerDotPages.js.map +1 -1
  18. package/ScrollableContainerGallery.d.ts +1 -1
  19. package/ScrollableContainerGallery.js +85 -54
  20. package/ScrollableContainerGallery.js.map +1 -1
  21. package/ScrollableItem.d.ts +1 -1
  22. package/ScrollableItem.js +22 -12
  23. package/ScrollableItem.js.map +1 -1
  24. package/index.css +19 -19
  25. package/index.d.ts +6 -6
  26. package/index.js +1 -1
  27. package/index.mock.d.ts +4 -4
  28. package/index.mock.js +21 -21
  29. package/index.mock.js.map +1 -1
  30. package/package.json +6 -6
  31. package/scrollableContainer-CWsF-84M.js +5 -0
  32. package/scrollableContainer-CWsF-84M.js.map +1 -0
  33. package/types.js +1 -1
  34. package/types.js.map +1 -1
  35. package/useScrollContainer.js +181 -157
  36. package/useScrollContainer.js.map +1 -1
  37. package/useScrollableControls.d.ts +2 -2
  38. package/useScrollableControls.js +90 -72
  39. package/useScrollableControls.js.map +1 -1
  40. package/utils.d.ts +2 -2
  41. package/utils.js +157 -254
  42. package/utils.js.map +1 -1
  43. package/scrollableContainer-C0a8z9uL.js +0 -5
  44. package/scrollableContainer-C0a8z9uL.js.map +0 -1
@@ -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 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 const jumpToIndex = useCallback(\n (index: number) => {\n if (!ensureItemReadyForScroll(scrollState, index, 'instant')) {\n return;\n }\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, index);\n const { scrollPosition, springScrollPosition, viewportWidth, contentWidth } = scrollState;\n if (target === null) {\n return;\n }\n const clampedTarget = clamp(target, viewportWidth.get() - contentWidth.get(), 0);\n const isScrollPositionReached = scrollPosition.get() === clampedTarget;\n const isSpringScrollPositionReached = !springScrollPosition || springScrollPosition.get() === clampedTarget;\n if (isScrollPositionReached && isSpringScrollPositionReached) {\n return;\n }\n scrollPosition.jump(clampedTarget);\n springScrollPosition?.jump(clampedTarget);\n },\n [scrollState]\n );\n\n const jumpBy = useCallback(\n (delta: number) => {\n const { scrollPosition, springScrollPosition, viewportWidth, contentWidth } = scrollState;\n const target = clamp(scrollPosition.get() + delta, viewportWidth.get() - contentWidth.get(), 0);\n const clampedDelta = target - scrollPosition.get();\n if (clampedDelta === 0) {\n return;\n }\n scrollPosition.jump(target);\n springScrollPosition?.jump(springScrollPosition.get() + clampedDelta);\n },\n [scrollState]\n );\n\n return {\n scrollLeft: () => scrollSide(),\n scrollRight: () => scrollSide(true),\n scrollToFirstItem,\n scrollToLastItem,\n scrollToIndex,\n scrollToItem,\n jumpToIndex,\n jumpBy,\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 const jumpToIndex = useCallback(\n (index: number) => {\n if (!ensureItemReadyForScroll(scrollState, index, 'instant')) {\n return;\n }\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, index);\n const { scrollPosition, springScrollPosition, viewportWidth, contentWidth } = scrollState;\n if (target === null) {\n return;\n }\n const clampedTarget = clamp(target, viewportWidth.get() - contentWidth.get(), 0);\n const isScrollPositionReached = scrollPosition.get() === clampedTarget;\n const isSpringScrollPositionReached = !springScrollPosition || springScrollPosition.get() === clampedTarget;\n if (isScrollPositionReached && isSpringScrollPositionReached) {\n return;\n }\n scrollPosition.jump(clampedTarget);\n springScrollPosition?.jump(clampedTarget);\n },\n [scrollState]\n );\n\n const jumpBy = useCallback(\n (delta: number) => {\n const { scrollPosition, springScrollPosition, viewportWidth, contentWidth } = scrollState;\n const target = clamp(scrollPosition.get() + delta, viewportWidth.get() - contentWidth.get(), 0);\n const clampedDelta = target - scrollPosition.get();\n if (clampedDelta === 0) {\n return;\n }\n scrollPosition.jump(target);\n springScrollPosition?.jump(springScrollPosition.get() + clampedDelta);\n },\n [scrollState]\n );\n\n return {\n scrollLeft: () => scrollSide(),\n scrollRight: () => scrollSide(true),\n scrollToFirstItem,\n scrollToLastItem,\n scrollToIndex,\n scrollToItem,\n jumpToIndex,\n jumpBy,\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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"}
package/utils.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';
2
- import { type ScrollState, type BehaviorScrollType } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';
3
- import { type SpacingCorrectionProps, type ScrollDisableState, type ItemOffset } from '@hh.ru/magritte-ui-scrollable-container/types';
2
+ import { type ScrollState, type BehaviorScrollType } from './ScrollStateProvider';
3
+ import { type SpacingCorrectionProps, type ScrollDisableState, type ItemOffset } from './types';
4
4
  export declare const BREAKPOINTS_LIST: Breakpoint[];
5
5
  export declare const NO_BUTTONS_START_FROM_BREAKPOINT = Breakpoint.S;
6
6
  export declare function debounce<T extends unknown[]>(callback: (...args: T) => void, waitMs: number): typeof callback;
package/utils.js CHANGED
@@ -6,291 +6,194 @@ import { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';
6
6
  import { OFFSET_ATTR } from './types.js';
7
7
 
8
8
  const BREAKPOINTS_LIST = [
9
- Breakpoint.XS,
10
- Breakpoint.S,
11
- Breakpoint.M,
12
- Breakpoint.L,
13
- Breakpoint.XL,
14
- Breakpoint.XXL,
9
+ Breakpoint.XS,
10
+ Breakpoint.S,
11
+ Breakpoint.M,
12
+ Breakpoint.L,
13
+ Breakpoint.XL,
14
+ Breakpoint.XXL
15
15
  ];
16
16
  const NO_BUTTONS_START_FROM_BREAKPOINT = Breakpoint.S;
17
17
  function debounce(callback, waitMs) {
18
- let timeout = 0;
19
- return (...args) => {
20
- clearTimeout(timeout);
21
- timeout = setTimeout(() => {
22
- callback(...args);
23
- }, waitMs);
24
- };
18
+ let timeout = 0;
19
+ return (...args) => {
20
+ clearTimeout(timeout);
21
+ timeout = setTimeout(() => {
22
+ callback(...args);
23
+ }, waitMs);
24
+ };
25
25
  }
26
- /**
27
- * По переданным параметрам коррекции возвращает значения отступов для текущего брейкпоинта
28
- * @param props Параметры коррекции
29
- * @param breakpoint Текуший брейкпоинт
30
- * @returns Объект содержащий значения отступов
31
- */
32
26
  const getActualCorrection = (props, breakpoint) => {
33
- const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint);
34
- let leftCorrection;
35
- let rightCorrection;
36
- // Проходимся по всем брейкпоинтам, начиная с текущего в сторону меньших разрешений
37
- for (let i = breakpointIndex; i >= 0; i--) {
38
- const breakpointName = BREAKPOINTS_LIST[i].toUpperCase();
39
- // Ключи, которые могут быть в параметрах коррекции (SpacingCorrectionProps)
40
- const leftCorrectionKey = `correctionLeft${breakpointName}`;
41
- const rightCorrectionKey = `correctionRight${breakpointName}`;
42
- const commonCorrectionKey = `correction${breakpointName}`;
43
- // Если для текущего брейкпоинта есть параметры коррекции для левой/правой стороны, то берем их
44
- props[leftCorrectionKey] !== undefined &&
45
- leftCorrection === undefined &&
46
- (leftCorrection = props[leftCorrectionKey]);
47
- props[rightCorrectionKey] !== undefined &&
48
- rightCorrection === undefined &&
49
- (rightCorrection = props[rightCorrectionKey]);
50
- // Если для левой или правой стороны не найден параметр коррекции, то пробуем взять параметр correction для
51
- // брейкпоинта который сейчас обрабатываем в цикле, например correctionM
52
- if (props[commonCorrectionKey] !== undefined) {
53
- leftCorrection === undefined && (leftCorrection = props[commonCorrectionKey]);
54
- rightCorrection === undefined && (rightCorrection = props[commonCorrectionKey]);
55
- }
56
- // Если нашли значения для обеих сторон - возращаем
57
- if (leftCorrection !== undefined && rightCorrection !== undefined) {
58
- return { leftCorrection, rightCorrection };
59
- }
27
+ const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint);
28
+ let leftCorrection;
29
+ let rightCorrection;
30
+ for (let i = breakpointIndex; i >= 0; i--) {
31
+ const breakpointName = BREAKPOINTS_LIST[i].toUpperCase();
32
+ const leftCorrectionKey = `correctionLeft${breakpointName}`;
33
+ const rightCorrectionKey = `correctionRight${breakpointName}`;
34
+ const commonCorrectionKey = `correction${breakpointName}`;
35
+ props[leftCorrectionKey] !== void 0 && leftCorrection === void 0 && (leftCorrection = props[leftCorrectionKey]);
36
+ props[rightCorrectionKey] !== void 0 && rightCorrection === void 0 && (rightCorrection = props[rightCorrectionKey]);
37
+ if (props[commonCorrectionKey] !== void 0) {
38
+ leftCorrection === void 0 && (leftCorrection = props[commonCorrectionKey]);
39
+ rightCorrection === void 0 && (rightCorrection = props[commonCorrectionKey]);
60
40
  }
61
- // Если не нашли значение для какой то из сторон, то берем значение из correction, без уточнения брейкпоинта
62
- return {
63
- leftCorrection: leftCorrection === undefined ? props.correction || 0 : leftCorrection,
64
- rightCorrection: rightCorrection === undefined ? props.correction || 0 : rightCorrection,
65
- };
41
+ if (leftCorrection !== void 0 && rightCorrection !== void 0) {
42
+ return { leftCorrection, rightCorrection };
43
+ }
44
+ }
45
+ return {
46
+ leftCorrection: leftCorrection === void 0 ? props.correction || 0 : leftCorrection,
47
+ rightCorrection: rightCorrection === void 0 ? props.correction || 0 : rightCorrection
48
+ };
66
49
  };
67
50
  const useInitOnce = (func) => {
68
- const initializedRef = useRef(undefined);
69
- if (initializedRef.current === undefined) {
70
- initializedRef.current = func();
71
- }
72
- return initializedRef.current;
51
+ const initializedRef = useRef(void 0);
52
+ if (initializedRef.current === void 0) {
53
+ initializedRef.current = func();
54
+ }
55
+ return initializedRef.current;
73
56
  };
74
- /**
75
- * Отдает метрики элемента галереи
76
- * @param scrollState стейт скролла
77
- * @param index индекс элемента
78
- * @returns метрики элемента, либо null (если элемента нет или его размеры еще не посчитаны)
79
- */
80
57
  const getItemOffset = (scrollState, index) => scrollState.items.get()[index]?.current?.[OFFSET_ATTR] ?? null;
81
- /**
82
- * На основе стейта расчитывает флаги скрола
83
- * @param scrollState стейт скролла
84
- * @returns cостояние блокировки скролла
85
- */
86
58
  const getDisableState = (scrollState) => {
87
- const { scrollPosition, viewportWidth, contentWidth } = scrollState;
88
- return {
89
- isScrollLeftDisabled: scrollPosition.get() >= 0,
90
- isScrollRightDisabled: Math.abs(scrollPosition.get()) + viewportWidth.get() >= contentWidth.get(),
91
- };
59
+ const { scrollPosition, viewportWidth, contentWidth } = scrollState;
60
+ return {
61
+ isScrollLeftDisabled: scrollPosition.get() >= 0,
62
+ isScrollRightDisabled: Math.abs(scrollPosition.get()) + viewportWidth.get() >= contentWidth.get()
63
+ };
92
64
  };
93
- /**
94
- * Анимирует scrollPosition с учетом границ контенера
95
- * @param scrollState стейт скролла
96
- * @param position новая позиция
97
- * @returns void
98
- */
99
65
  const animateScrollToPosition = (scrollState, position) => {
100
- const { scrollPosition, viewportWidth, contentWidth } = scrollState;
101
- if (position === null || scrollPosition.get() === position) {
102
- return;
103
- }
104
- const clampedPosition = clamp(position, viewportWidth.get() - contentWidth.get(), 0);
105
- animate(scrollPosition, clampedPosition, {
106
- velocity: Math.max(scrollPosition.getVelocity(), 1),
107
- });
66
+ const { scrollPosition, viewportWidth, contentWidth } = scrollState;
67
+ if (position === null || scrollPosition.get() === position) {
68
+ return;
69
+ }
70
+ const clampedPosition = clamp(position, viewportWidth.get() - contentWidth.get(), 0);
71
+ animate(scrollPosition, clampedPosition, {
72
+ velocity: Math.max(scrollPosition.getVelocity(), 1)
73
+ });
108
74
  };
109
- /**
110
- * scrollTo* может быть вызвана раньше чем появяться метрики элементов
111
- * например, scrollToIndex функция может вызвана в useEffect в tabs
112
- * запоминаем индекс и вызовем скролл, когда метрики будут посчитаны
113
- */
114
- const ensureItemReadyForScroll = (scrollState, index, behaviorScrollType = 'animate') => {
115
- const { items } = scrollState;
116
- const item = items.get()[index]?.current;
117
- if (!item || !item[OFFSET_ATTR]) {
118
- scrollState.indexForDeferScroll = index;
119
- scrollState.behaviorScrollTypeDeferScroll = behaviorScrollType;
120
- return false;
121
- }
122
- return true;
75
+ const ensureItemReadyForScroll = (scrollState, index, behaviorScrollType = "animate") => {
76
+ const { items } = scrollState;
77
+ const item = items.get()[index]?.current;
78
+ if (!item || !item[OFFSET_ATTR]) {
79
+ scrollState.indexForDeferScroll = index;
80
+ scrollState.behaviorScrollTypeDeferScroll = behaviorScrollType;
81
+ return false;
82
+ }
83
+ return true;
123
84
  };
124
- /**
125
- * Возвращает якорную точку отрезка в зависимости от scrollSnapAlign.
126
- *
127
- * start — левая граница элемента
128
- * center — центр элемента
129
- * end — правая граница элемента
130
- *
131
- * @param left левая граница элемента
132
- * @param right правая граница элемента
133
- * @param align режим выравнивания (scroll-snap-align)
134
- * @returns координата якорной точки элемента
135
- */
136
85
  const getAnchorPoint = (left, right, align) => {
137
- let point = 0;
138
- switch (align) {
139
- case 'center':
140
- point = (left + right) / 2;
141
- break;
142
- case 'end':
143
- point = right;
144
- break;
145
- case 'start':
146
- default:
147
- point = left;
148
- }
149
- return point;
86
+ let point = 0;
87
+ switch (align) {
88
+ case "center":
89
+ point = (left + right) / 2;
90
+ break;
91
+ case "end":
92
+ point = right;
93
+ break;
94
+ case "start":
95
+ default:
96
+ point = left;
97
+ }
98
+ return point;
150
99
  };
151
- /**
152
- * Вычисляет целевую точку прокрутки в зависимости от режима scroll-snap выравнивания.
153
- *
154
- * В качестве базовой позиции используется текущее значение scrollLeft,
155
- * к которому добавляется смещение, зависящее от `scrollSnapAlign`:
156
- * - start — начало области просмотра
157
- * - center — центр области просмотра
158
- * - end — конец области просмотра
159
- *
160
- * @param state Текущее состояние скролл
161
- * @returns Координата целевой точки прокрутки
162
- */
163
100
  const getTargetPoint = (state) => {
164
- const scrollLeft = Math.abs(state.scrollPosition.get());
165
- let point = 0;
166
- switch (state.scrollSnapAlign) {
167
- case 'center':
168
- point = scrollLeft + state.viewportWidth.get() / 2;
169
- break;
170
- case 'end':
171
- point = scrollLeft + state.viewportWidth.get();
172
- break;
173
- case 'start':
174
- default:
175
- point = scrollLeft;
176
- }
177
- return point;
101
+ const scrollLeft = Math.abs(state.scrollPosition.get());
102
+ let point = 0;
103
+ switch (state.scrollSnapAlign) {
104
+ case "center":
105
+ point = scrollLeft + state.viewportWidth.get() / 2;
106
+ break;
107
+ case "end":
108
+ point = scrollLeft + state.viewportWidth.get();
109
+ break;
110
+ case "start":
111
+ default:
112
+ point = scrollLeft;
113
+ }
114
+ return point;
178
115
  };
179
- /**
180
- * На основе позиции, находит ближайший элемент к центру viewport
181
- * @param scrollState стейт скролла
182
- * @returns индекс найденого элемента
183
- */
184
116
  const findIndexNearestToSnapPoint = (state) => {
185
- const items = state.items.get();
186
- if (items.length === 0) {
187
- return 0;
188
- }
189
- const targetPoint = getTargetPoint(state);
190
- let idx = 0;
191
- let minDist = Infinity;
192
- for (let key = 0; key < items.length; key++) {
193
- const element = items[key]?.current;
194
- if (element && element[OFFSET_ATTR]) {
195
- const { left, right } = element[OFFSET_ATTR];
196
- const anchor = getAnchorPoint(left, right, state.scrollSnapAlign);
197
- const dist = Math.abs(targetPoint - anchor);
198
- if (dist < minDist) {
199
- minDist = dist;
200
- idx = key;
201
- }
202
- }
117
+ const items = state.items.get();
118
+ if (items.length === 0) {
119
+ return 0;
120
+ }
121
+ const targetPoint = getTargetPoint(state);
122
+ let idx = 0;
123
+ let minDist = Infinity;
124
+ for (let key = 0; key < items.length; key++) {
125
+ const element = items[key]?.current;
126
+ if (element && element[OFFSET_ATTR]) {
127
+ const { left, right } = element[OFFSET_ATTR];
128
+ const anchor = getAnchorPoint(left, right, state.scrollSnapAlign);
129
+ const dist = Math.abs(targetPoint - anchor);
130
+ if (dist < minDist) {
131
+ minDist = dist;
132
+ idx = key;
133
+ }
203
134
  }
204
- return idx;
135
+ }
136
+ return idx;
205
137
  };
206
- /**
207
- * Определят позицию, при которой элемент будет находится на левой границе viewport
208
- * @param scrollState стейт скролла
209
- * @param index индекс элемента
210
- * @returns новая позиция
211
- */
212
138
  const computeStartPositionForIndex = (scrollState, index) => {
213
- const { items, defaultButtonsCorrection } = scrollState;
214
- const itemRef = items.get()[index];
215
- if (!itemRef?.current) {
216
- return null;
217
- }
218
- const offset = itemRef.current[OFFSET_ATTR];
219
- return -offset.left + defaultButtonsCorrection.get();
139
+ const { items, defaultButtonsCorrection } = scrollState;
140
+ const itemRef = items.get()[index];
141
+ if (!itemRef?.current) {
142
+ return null;
143
+ }
144
+ const offset = itemRef.current[OFFSET_ATTR];
145
+ return -offset.left + defaultButtonsCorrection.get();
220
146
  };
221
- /**
222
- * Определят позицию, при которой элемент будет находится на правой границе viewport
223
- * @param scrollState стейт скролла
224
- * @param index индекс элемента
225
- * @returns новая позиция
226
- */
227
147
  const computeEndPositionForIndex = (scrollState, index) => {
228
- const { items, defaultButtonsCorrection, viewportWidth } = scrollState;
229
- const itemRef = items.get()[index];
230
- if (!itemRef?.current) {
231
- return null;
232
- }
233
- const offset = itemRef.current[OFFSET_ATTR];
234
- return -offset.right + viewportWidth.get() - defaultButtonsCorrection.get();
148
+ const { items, defaultButtonsCorrection, viewportWidth } = scrollState;
149
+ const itemRef = items.get()[index];
150
+ if (!itemRef?.current) {
151
+ return null;
152
+ }
153
+ const offset = itemRef.current[OFFSET_ATTR];
154
+ return -offset.right + viewportWidth.get() - defaultButtonsCorrection.get();
235
155
  };
236
- /**
237
- * Определят позицию, при которой элемент будет в центре viewport
238
- * @param scrollState стейт скролла
239
- * @param index индекс элемента
240
- * @returns новая позиция
241
- */
242
156
  const computeCenterPositionForIndex = (scrollState, index) => {
243
- const { items, viewportWidth } = scrollState;
244
- const itemRef = items.get()[index];
245
- if (!itemRef?.current) {
246
- return null;
247
- }
248
- const offset = itemRef.current[OFFSET_ATTR];
249
- const itemWidth = offset.right - offset.left;
250
- const itemCenter = offset.left + itemWidth / 2;
251
- const viewportCenter = viewportWidth.get() / 2;
252
- return viewportCenter - itemCenter;
157
+ const { items, viewportWidth } = scrollState;
158
+ const itemRef = items.get()[index];
159
+ if (!itemRef?.current) {
160
+ return null;
161
+ }
162
+ const offset = itemRef.current[OFFSET_ATTR];
163
+ const itemWidth = offset.right - offset.left;
164
+ const itemCenter = offset.left + itemWidth / 2;
165
+ const viewportCenter = viewportWidth.get() / 2;
166
+ return viewportCenter - itemCenter;
253
167
  };
254
- /**
255
- * Определят позицию, при которой элемент будет находится во viewport (с учетом боковых кнопок в fade)
256
- * @param scrollState стейт скролла
257
- * @param index индекс элемента
258
- * @returns новая позиция
259
- */
260
168
  const computePositionForIndex = (scrollState, index) => {
261
- const { items, viewportWidth, scrollPosition, defaultButtonsCorrection } = scrollState;
262
- const itemRef = items.get()[index];
263
- if (!itemRef?.current) {
264
- return null;
265
- }
266
- const offset = itemRef.current[OFFSET_ATTR];
267
- const viewportLeft = -scrollPosition.get() + defaultButtonsCorrection.get();
268
- const viewportRight = viewportLeft + viewportWidth.get() - defaultButtonsCorrection.get();
269
- if (offset.left >= viewportLeft && offset.right <= viewportRight) {
270
- return scrollPosition.get();
271
- }
272
- if (offset.left < viewportLeft) {
273
- return -(offset.left - defaultButtonsCorrection.get());
274
- }
275
- return viewportWidth.get() - offset.right - defaultButtonsCorrection.get();
169
+ const { items, viewportWidth, scrollPosition, defaultButtonsCorrection } = scrollState;
170
+ const itemRef = items.get()[index];
171
+ if (!itemRef?.current) {
172
+ return null;
173
+ }
174
+ const offset = itemRef.current[OFFSET_ATTR];
175
+ const viewportLeft = -scrollPosition.get() + defaultButtonsCorrection.get();
176
+ const viewportRight = viewportLeft + viewportWidth.get() - defaultButtonsCorrection.get();
177
+ if (offset.left >= viewportLeft && offset.right <= viewportRight) {
178
+ return scrollPosition.get();
179
+ }
180
+ if (offset.left < viewportLeft) {
181
+ return -(offset.left - defaultButtonsCorrection.get());
182
+ }
183
+ return viewportWidth.get() - offset.right - defaultButtonsCorrection.get();
276
184
  };
277
- /**
278
- * Определят поведение "подскрола" ближайшего элемента
279
- * @param scrollState стейт скролла
280
- * @returns StrategyPosition
281
- */
282
185
  const computeScrollSnapBehavior = (scrollState) => {
283
- switch (scrollState.scrollSnapAlign) {
284
- case 'center':
285
- return computeCenterPositionForIndex;
286
- case 'start':
287
- return computeStartPositionForIndex;
288
- case 'end':
289
- return computeEndPositionForIndex;
290
- case 'none':
291
- default:
292
- return computePositionForIndex;
293
- }
186
+ switch (scrollState.scrollSnapAlign) {
187
+ case "center":
188
+ return computeCenterPositionForIndex;
189
+ case "start":
190
+ return computeStartPositionForIndex;
191
+ case "end":
192
+ return computeEndPositionForIndex;
193
+ case "none":
194
+ default:
195
+ return computePositionForIndex;
196
+ }
294
197
  };
295
198
 
296
199
  export { BREAKPOINTS_LIST, NO_BUTTONS_START_FROM_BREAKPOINT, animateScrollToPosition, computeCenterPositionForIndex, computeEndPositionForIndex, computePositionForIndex, computeScrollSnapBehavior, computeStartPositionForIndex, debounce, ensureItemReadyForScroll, findIndexNearestToSnapPoint, getActualCorrection, getDisableState, getItemOffset, useInitOnce };
package/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["src/utils.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { animate } from 'motion/react';\n\nimport { clamp } from '@hh.ru/magritte-internal-custom-scroll';\nimport { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { type ScrollState, type BehaviorScrollType } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport {\n type SpacingCorrectionProps,\n type ScrollDisableState,\n type ScrollSnapAlign,\n OFFSET_ATTR,\n type ItemOffset,\n} from '@hh.ru/magritte-ui-scrollable-container/types';\n\nexport const BREAKPOINTS_LIST = [\n Breakpoint.XS,\n Breakpoint.S,\n Breakpoint.M,\n Breakpoint.L,\n Breakpoint.XL,\n Breakpoint.XXL,\n];\nexport const NO_BUTTONS_START_FROM_BREAKPOINT = Breakpoint.S;\n\nexport function debounce<T extends unknown[]>(callback: (...args: T) => void, waitMs: number): typeof callback {\n let timeout = 0;\n return (...args: T) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => {\n callback(...args);\n }, waitMs) as unknown as number;\n };\n}\n\ninterface ActualCorrection {\n leftCorrection: number;\n rightCorrection: number;\n}\n\n/**\n * По переданным параметрам коррекции возвращает значения отступов для текущего брейкпоинта\n * @param props Параметры коррекции\n * @param breakpoint Текуший брейкпоинт\n * @returns Объект содержащий значения отступов\n */\nexport const getActualCorrection = (props: SpacingCorrectionProps, breakpoint: Breakpoint): ActualCorrection => {\n const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint);\n let leftCorrection: number | undefined;\n let rightCorrection: number | undefined;\n // Проходимся по всем брейкпоинтам, начиная с текущего в сторону меньших разрешений\n for (let i = breakpointIndex; i >= 0; i--) {\n const breakpointName = BREAKPOINTS_LIST[i].toUpperCase();\n // Ключи, которые могут быть в параметрах коррекции (SpacingCorrectionProps)\n const leftCorrectionKey = `correctionLeft${breakpointName}` as keyof SpacingCorrectionProps;\n const rightCorrectionKey = `correctionRight${breakpointName}` as keyof SpacingCorrectionProps;\n const commonCorrectionKey = `correction${breakpointName}` as keyof SpacingCorrectionProps;\n // Если для текущего брейкпоинта есть параметры коррекции для левой/правой стороны, то берем их\n props[leftCorrectionKey] !== undefined &&\n leftCorrection === undefined &&\n (leftCorrection = props[leftCorrectionKey]);\n props[rightCorrectionKey] !== undefined &&\n rightCorrection === undefined &&\n (rightCorrection = props[rightCorrectionKey]);\n\n // Если для левой или правой стороны не найден параметр коррекции, то пробуем взять параметр correction для\n // брейкпоинта который сейчас обрабатываем в цикле, например correctionM\n if (props[commonCorrectionKey] !== undefined) {\n leftCorrection === undefined && (leftCorrection = props[commonCorrectionKey]);\n rightCorrection === undefined && (rightCorrection = props[commonCorrectionKey]);\n }\n\n // Если нашли значения для обеих сторон - возращаем\n if (leftCorrection !== undefined && rightCorrection !== undefined) {\n return { leftCorrection, rightCorrection };\n }\n }\n // Если не нашли значение для какой то из сторон, то берем значение из correction, без уточнения брейкпоинта\n return {\n leftCorrection: leftCorrection === undefined ? props.correction || 0 : leftCorrection,\n rightCorrection: rightCorrection === undefined ? props.correction || 0 : rightCorrection,\n };\n};\n\nexport const useInitOnce = <T>(func: () => T): T => {\n const initializedRef = useRef<T | undefined>(undefined);\n if (initializedRef.current === undefined) {\n initializedRef.current = func();\n }\n return initializedRef.current;\n};\n\n/**\n * Отдает метрики элемента галереи\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns метрики элемента, либо null (если элемента нет или его размеры еще не посчитаны)\n */\nexport const getItemOffset = (scrollState: ScrollState, index: number): ItemOffset | null =>\n scrollState.items.get()[index]?.current?.[OFFSET_ATTR] ?? null;\n\n/**\n * На основе стейта расчитывает флаги скрола\n * @param scrollState стейт скролла\n * @returns cостояние блокировки скролла\n */\nexport const getDisableState = (scrollState: ScrollState): ScrollDisableState => {\n const { scrollPosition, viewportWidth, contentWidth } = scrollState;\n return {\n isScrollLeftDisabled: scrollPosition.get() >= 0,\n isScrollRightDisabled: Math.abs(scrollPosition.get()) + viewportWidth.get() >= contentWidth.get(),\n };\n};\n\n/**\n * Анимирует scrollPosition с учетом границ контенера\n * @param scrollState стейт скролла\n * @param position новая позиция\n * @returns void\n */\nexport const animateScrollToPosition = (scrollState: ScrollState, position: number | null): void => {\n const { scrollPosition, viewportWidth, contentWidth } = scrollState;\n if (position === null || scrollPosition.get() === position) {\n return;\n }\n const clampedPosition = clamp(position, viewportWidth.get() - contentWidth.get(), 0);\n animate(scrollPosition, clampedPosition, {\n velocity: Math.max(scrollPosition.getVelocity(), 1),\n });\n};\n\n/**\n * scrollTo* может быть вызвана раньше чем появяться метрики элементов\n * например, scrollToIndex функция может вызвана в useEffect в tabs\n * запоминаем индекс и вызовем скролл, когда метрики будут посчитаны\n */\nexport const ensureItemReadyForScroll = (\n scrollState: ScrollState,\n index: number,\n behaviorScrollType: BehaviorScrollType = 'animate'\n): boolean => {\n const { items } = scrollState;\n const item = items.get()[index]?.current;\n if (!item || !item[OFFSET_ATTR]) {\n scrollState.indexForDeferScroll = index;\n scrollState.behaviorScrollTypeDeferScroll = behaviorScrollType;\n return false;\n }\n return true;\n};\n\n/**\n * Возвращает якорную точку отрезка в зависимости от scrollSnapAlign.\n *\n * start — левая граница элемента\n * center — центр элемента\n * end — правая граница элемента\n *\n * @param left левая граница элемента\n * @param right правая граница элемента\n * @param align режим выравнивания (scroll-snap-align)\n * @returns координата якорной точки элемента\n */\nconst getAnchorPoint = (left: number, right: number, align: ScrollSnapAlign): number => {\n let point = 0;\n switch (align) {\n case 'center':\n point = (left + right) / 2;\n break;\n case 'end':\n point = right;\n break;\n case 'start':\n default:\n point = left;\n }\n return point;\n};\n\n/**\n * Вычисляет целевую точку прокрутки в зависимости от режима scroll-snap выравнивания.\n *\n * В качестве базовой позиции используется текущее значение scrollLeft,\n * к которому добавляется смещение, зависящее от `scrollSnapAlign`:\n * - start — начало области просмотра\n * - center — центр области просмотра\n * - end — конец области просмотра\n *\n * @param state Текущее состояние скролл\n * @returns Координата целевой точки прокрутки\n */\nconst getTargetPoint = (state: ScrollState): number => {\n const scrollLeft = Math.abs(state.scrollPosition.get());\n let point = 0;\n switch (state.scrollSnapAlign) {\n case 'center':\n point = scrollLeft + state.viewportWidth.get() / 2;\n break;\n case 'end':\n point = scrollLeft + state.viewportWidth.get();\n break;\n case 'start':\n default:\n point = scrollLeft;\n }\n return point;\n};\n\n/**\n * На основе позиции, находит ближайший элемент к центру viewport\n * @param scrollState стейт скролла\n * @returns индекс найденого элемента\n */\nexport const findIndexNearestToSnapPoint = (state: ScrollState): number => {\n const items = state.items.get();\n if (items.length === 0) {\n return 0;\n }\n const targetPoint = getTargetPoint(state);\n let idx = 0;\n let minDist = Infinity;\n for (let key = 0; key < items.length; key++) {\n const element = items[key]?.current;\n if (element && element[OFFSET_ATTR]) {\n const { left, right } = element[OFFSET_ATTR];\n const anchor = getAnchorPoint(left, right, state.scrollSnapAlign);\n const dist = Math.abs(targetPoint - anchor);\n if (dist < minDist) {\n minDist = dist;\n idx = key;\n }\n }\n }\n return idx;\n};\n\ninterface ScrollBehavior {\n (scrollState: ScrollState, index: number): number | null;\n}\n\n/**\n * Определят позицию, при которой элемент будет находится на левой границе viewport\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computeStartPositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, defaultButtonsCorrection } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n return -offset.left + defaultButtonsCorrection.get();\n};\n\n/**\n * Определят позицию, при которой элемент будет находится на правой границе viewport\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computeEndPositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, defaultButtonsCorrection, viewportWidth } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n return -offset.right + viewportWidth.get() - defaultButtonsCorrection.get();\n};\n\n/**\n * Определят позицию, при которой элемент будет в центре viewport\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computeCenterPositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, viewportWidth } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n const itemWidth = offset.right - offset.left;\n const itemCenter = offset.left + itemWidth / 2;\n const viewportCenter = viewportWidth.get() / 2;\n return viewportCenter - itemCenter;\n};\n\n/**\n * Определят позицию, при которой элемент будет находится во viewport (с учетом боковых кнопок в fade)\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computePositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, viewportWidth, scrollPosition, defaultButtonsCorrection } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n const viewportLeft = -scrollPosition.get() + defaultButtonsCorrection.get();\n const viewportRight = viewportLeft + viewportWidth.get() - defaultButtonsCorrection.get();\n if (offset.left >= viewportLeft && offset.right <= viewportRight) {\n return scrollPosition.get();\n }\n if (offset.left < viewportLeft) {\n return -(offset.left - defaultButtonsCorrection.get());\n }\n return viewportWidth.get() - offset.right - defaultButtonsCorrection.get();\n};\n\n/**\n * Определят поведение \"подскрола\" ближайшего элемента\n * @param scrollState стейт скролла\n * @returns StrategyPosition\n */\nexport const computeScrollSnapBehavior = (scrollState: ScrollState): ScrollBehavior => {\n switch (scrollState.scrollSnapAlign) {\n case 'center':\n return computeCenterPositionForIndex;\n case 'start':\n return computeStartPositionForIndex;\n case 'end':\n return computeEndPositionForIndex;\n case 'none':\n default:\n return computePositionForIndex;\n }\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["src/utils.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { animate } from 'motion/react';\n\nimport { clamp } from '@hh.ru/magritte-internal-custom-scroll';\nimport { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { type ScrollState, type BehaviorScrollType } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport {\n type SpacingCorrectionProps,\n type ScrollDisableState,\n type ScrollSnapAlign,\n OFFSET_ATTR,\n type ItemOffset,\n} from '@hh.ru/magritte-ui-scrollable-container/types';\n\nexport const BREAKPOINTS_LIST = [\n Breakpoint.XS,\n Breakpoint.S,\n Breakpoint.M,\n Breakpoint.L,\n Breakpoint.XL,\n Breakpoint.XXL,\n];\nexport const NO_BUTTONS_START_FROM_BREAKPOINT = Breakpoint.S;\n\nexport function debounce<T extends unknown[]>(callback: (...args: T) => void, waitMs: number): typeof callback {\n let timeout = 0;\n return (...args: T) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => {\n callback(...args);\n }, waitMs) as unknown as number;\n };\n}\n\ninterface ActualCorrection {\n leftCorrection: number;\n rightCorrection: number;\n}\n\n/**\n * По переданным параметрам коррекции возвращает значения отступов для текущего брейкпоинта\n * @param props Параметры коррекции\n * @param breakpoint Текуший брейкпоинт\n * @returns Объект содержащий значения отступов\n */\nexport const getActualCorrection = (props: SpacingCorrectionProps, breakpoint: Breakpoint): ActualCorrection => {\n const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint);\n let leftCorrection: number | undefined;\n let rightCorrection: number | undefined;\n // Проходимся по всем брейкпоинтам, начиная с текущего в сторону меньших разрешений\n for (let i = breakpointIndex; i >= 0; i--) {\n const breakpointName = BREAKPOINTS_LIST[i].toUpperCase();\n // Ключи, которые могут быть в параметрах коррекции (SpacingCorrectionProps)\n const leftCorrectionKey = `correctionLeft${breakpointName}` as keyof SpacingCorrectionProps;\n const rightCorrectionKey = `correctionRight${breakpointName}` as keyof SpacingCorrectionProps;\n const commonCorrectionKey = `correction${breakpointName}` as keyof SpacingCorrectionProps;\n // Если для текущего брейкпоинта есть параметры коррекции для левой/правой стороны, то берем их\n props[leftCorrectionKey] !== undefined &&\n leftCorrection === undefined &&\n (leftCorrection = props[leftCorrectionKey]);\n props[rightCorrectionKey] !== undefined &&\n rightCorrection === undefined &&\n (rightCorrection = props[rightCorrectionKey]);\n\n // Если для левой или правой стороны не найден параметр коррекции, то пробуем взять параметр correction для\n // брейкпоинта который сейчас обрабатываем в цикле, например correctionM\n if (props[commonCorrectionKey] !== undefined) {\n leftCorrection === undefined && (leftCorrection = props[commonCorrectionKey]);\n rightCorrection === undefined && (rightCorrection = props[commonCorrectionKey]);\n }\n\n // Если нашли значения для обеих сторон - возращаем\n if (leftCorrection !== undefined && rightCorrection !== undefined) {\n return { leftCorrection, rightCorrection };\n }\n }\n // Если не нашли значение для какой то из сторон, то берем значение из correction, без уточнения брейкпоинта\n return {\n leftCorrection: leftCorrection === undefined ? props.correction || 0 : leftCorrection,\n rightCorrection: rightCorrection === undefined ? props.correction || 0 : rightCorrection,\n };\n};\n\nexport const useInitOnce = <T>(func: () => T): T => {\n const initializedRef = useRef<T | undefined>(undefined);\n if (initializedRef.current === undefined) {\n initializedRef.current = func();\n }\n return initializedRef.current;\n};\n\n/**\n * Отдает метрики элемента галереи\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns метрики элемента, либо null (если элемента нет или его размеры еще не посчитаны)\n */\nexport const getItemOffset = (scrollState: ScrollState, index: number): ItemOffset | null =>\n scrollState.items.get()[index]?.current?.[OFFSET_ATTR] ?? null;\n\n/**\n * На основе стейта расчитывает флаги скрола\n * @param scrollState стейт скролла\n * @returns cостояние блокировки скролла\n */\nexport const getDisableState = (scrollState: ScrollState): ScrollDisableState => {\n const { scrollPosition, viewportWidth, contentWidth } = scrollState;\n return {\n isScrollLeftDisabled: scrollPosition.get() >= 0,\n isScrollRightDisabled: Math.abs(scrollPosition.get()) + viewportWidth.get() >= contentWidth.get(),\n };\n};\n\n/**\n * Анимирует scrollPosition с учетом границ контенера\n * @param scrollState стейт скролла\n * @param position новая позиция\n * @returns void\n */\nexport const animateScrollToPosition = (scrollState: ScrollState, position: number | null): void => {\n const { scrollPosition, viewportWidth, contentWidth } = scrollState;\n if (position === null || scrollPosition.get() === position) {\n return;\n }\n const clampedPosition = clamp(position, viewportWidth.get() - contentWidth.get(), 0);\n animate(scrollPosition, clampedPosition, {\n velocity: Math.max(scrollPosition.getVelocity(), 1),\n });\n};\n\n/**\n * scrollTo* может быть вызвана раньше чем появяться метрики элементов\n * например, scrollToIndex функция может вызвана в useEffect в tabs\n * запоминаем индекс и вызовем скролл, когда метрики будут посчитаны\n */\nexport const ensureItemReadyForScroll = (\n scrollState: ScrollState,\n index: number,\n behaviorScrollType: BehaviorScrollType = 'animate'\n): boolean => {\n const { items } = scrollState;\n const item = items.get()[index]?.current;\n if (!item || !item[OFFSET_ATTR]) {\n scrollState.indexForDeferScroll = index;\n scrollState.behaviorScrollTypeDeferScroll = behaviorScrollType;\n return false;\n }\n return true;\n};\n\n/**\n * Возвращает якорную точку отрезка в зависимости от scrollSnapAlign.\n *\n * start — левая граница элемента\n * center — центр элемента\n * end — правая граница элемента\n *\n * @param left левая граница элемента\n * @param right правая граница элемента\n * @param align режим выравнивания (scroll-snap-align)\n * @returns координата якорной точки элемента\n */\nconst getAnchorPoint = (left: number, right: number, align: ScrollSnapAlign): number => {\n let point = 0;\n switch (align) {\n case 'center':\n point = (left + right) / 2;\n break;\n case 'end':\n point = right;\n break;\n case 'start':\n default:\n point = left;\n }\n return point;\n};\n\n/**\n * Вычисляет целевую точку прокрутки в зависимости от режима scroll-snap выравнивания.\n *\n * В качестве базовой позиции используется текущее значение scrollLeft,\n * к которому добавляется смещение, зависящее от `scrollSnapAlign`:\n * - start — начало области просмотра\n * - center — центр области просмотра\n * - end — конец области просмотра\n *\n * @param state Текущее состояние скролл\n * @returns Координата целевой точки прокрутки\n */\nconst getTargetPoint = (state: ScrollState): number => {\n const scrollLeft = Math.abs(state.scrollPosition.get());\n let point = 0;\n switch (state.scrollSnapAlign) {\n case 'center':\n point = scrollLeft + state.viewportWidth.get() / 2;\n break;\n case 'end':\n point = scrollLeft + state.viewportWidth.get();\n break;\n case 'start':\n default:\n point = scrollLeft;\n }\n return point;\n};\n\n/**\n * На основе позиции, находит ближайший элемент к центру viewport\n * @param scrollState стейт скролла\n * @returns индекс найденого элемента\n */\nexport const findIndexNearestToSnapPoint = (state: ScrollState): number => {\n const items = state.items.get();\n if (items.length === 0) {\n return 0;\n }\n const targetPoint = getTargetPoint(state);\n let idx = 0;\n let minDist = Infinity;\n for (let key = 0; key < items.length; key++) {\n const element = items[key]?.current;\n if (element && element[OFFSET_ATTR]) {\n const { left, right } = element[OFFSET_ATTR];\n const anchor = getAnchorPoint(left, right, state.scrollSnapAlign);\n const dist = Math.abs(targetPoint - anchor);\n if (dist < minDist) {\n minDist = dist;\n idx = key;\n }\n }\n }\n return idx;\n};\n\ninterface ScrollBehavior {\n (scrollState: ScrollState, index: number): number | null;\n}\n\n/**\n * Определят позицию, при которой элемент будет находится на левой границе viewport\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computeStartPositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, defaultButtonsCorrection } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n return -offset.left + defaultButtonsCorrection.get();\n};\n\n/**\n * Определят позицию, при которой элемент будет находится на правой границе viewport\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computeEndPositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, defaultButtonsCorrection, viewportWidth } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n return -offset.right + viewportWidth.get() - defaultButtonsCorrection.get();\n};\n\n/**\n * Определят позицию, при которой элемент будет в центре viewport\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computeCenterPositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, viewportWidth } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n const itemWidth = offset.right - offset.left;\n const itemCenter = offset.left + itemWidth / 2;\n const viewportCenter = viewportWidth.get() / 2;\n return viewportCenter - itemCenter;\n};\n\n/**\n * Определят позицию, при которой элемент будет находится во viewport (с учетом боковых кнопок в fade)\n * @param scrollState стейт скролла\n * @param index индекс элемента\n * @returns новая позиция\n */\nexport const computePositionForIndex: ScrollBehavior = (scrollState, index) => {\n const { items, viewportWidth, scrollPosition, defaultButtonsCorrection } = scrollState;\n const itemRef = items.get()[index];\n if (!itemRef?.current) {\n return null;\n }\n const offset = itemRef.current[OFFSET_ATTR];\n const viewportLeft = -scrollPosition.get() + defaultButtonsCorrection.get();\n const viewportRight = viewportLeft + viewportWidth.get() - defaultButtonsCorrection.get();\n if (offset.left >= viewportLeft && offset.right <= viewportRight) {\n return scrollPosition.get();\n }\n if (offset.left < viewportLeft) {\n return -(offset.left - defaultButtonsCorrection.get());\n }\n return viewportWidth.get() - offset.right - defaultButtonsCorrection.get();\n};\n\n/**\n * Определят поведение \"подскрола\" ближайшего элемента\n * @param scrollState стейт скролла\n * @returns StrategyPosition\n */\nexport const computeScrollSnapBehavior = (scrollState: ScrollState): ScrollBehavior => {\n switch (scrollState.scrollSnapAlign) {\n case 'center':\n return computeCenterPositionForIndex;\n case 'start':\n return computeStartPositionForIndex;\n case 'end':\n return computeEndPositionForIndex;\n case 'none':\n default:\n return computePositionForIndex;\n }\n};\n"],"names":[],"mappings":"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"}