@hh.ru/magritte-ui-scrollable-container 5.3.0 → 6.0.1

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