@via-profit/ui-kit 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/Accordion/AccordionActions.d.ts +1 -1
  2. package/Accordion/AccordionActions.js +2 -1
  3. package/Accordion/AccordionContainer.d.ts +1 -1
  4. package/Accordion/AccordionContainer.js +2 -14
  5. package/Accordion/AccordionContent.d.ts +1 -1
  6. package/Accordion/AccordionContent.js +5 -1
  7. package/Accordion/AccordionHeader.d.ts +2 -2
  8. package/Accordion/AccordionHeader.js +6 -2
  9. package/Accordion/index.d.ts +9 -9
  10. package/Accordion/index.js +18 -9
  11. package/Autocomplete/AutocompleteContainer.d.ts +2 -2
  12. package/Autocomplete/AutocompleteContainer.js +17 -7
  13. package/Autocomplete/AutocompleteItem.js +2 -1
  14. package/Autocomplete/context.d.ts +3 -3
  15. package/Autocomplete/index.d.ts +2 -2
  16. package/Avatar/AvatarContainer.d.ts +2 -2
  17. package/Avatar/AvatarPicture.d.ts +2 -2
  18. package/Avatar/index.js +1 -2
  19. package/Badge/BadgeBase.d.ts +1 -1
  20. package/Badge/BadgeContainer.d.ts +1 -1
  21. package/Badge/BadgeDeleteButton.d.ts +2 -2
  22. package/Badge/BadgeStyled.js +1 -1
  23. package/Badge/index.d.ts +1 -1
  24. package/Badge/index.js +1 -2
  25. package/Button/ButtonBase.d.ts +2 -2
  26. package/Button/ButtonContainer.d.ts +4 -4
  27. package/Button/ButtonContainer.js +22 -5
  28. package/Button/ButtonIconWrapper.d.ts +1 -1
  29. package/Button/ButtonStyled.d.ts +1 -1
  30. package/Button/ButtonTextWrapper.d.ts +1 -1
  31. package/Button/buttonVariants.d.ts +1 -1
  32. package/Button/buttonVariants.js +3 -2
  33. package/Button/index.d.ts +1 -1
  34. package/Button/index.js +1 -20
  35. package/ButtonGroup/index.js +4 -3
  36. package/CHANGELOG.md +49 -1
  37. package/Calendar/CalendarComponent.js +18 -9
  38. package/Calendar/CalendarControlButton.d.ts +2 -2
  39. package/Calendar/CalendarPaper.js +1 -1
  40. package/Calendar/CalendarWeekDayLabel.d.ts +2 -2
  41. package/Calendar/CalendarWeekRowButton.d.ts +1 -1
  42. package/Calendar/IconChevronDown.js +17 -7
  43. package/Calendar/index.d.ts +1 -1
  44. package/Calendar/index.js +17 -7
  45. package/Checkbox/CheckboxAsterisk.js +17 -7
  46. package/Checkbox/CheckboxBox.d.ts +2 -2
  47. package/Checkbox/CheckboxBox.js +1 -1
  48. package/Checkbox/CheckboxContainer.d.ts +2 -2
  49. package/Checkbox/CheckboxErrorText.js +17 -7
  50. package/Checkbox/index.d.ts +10 -10
  51. package/Checkbox/index.js +1 -2
  52. package/Checkbox/useCheckboxColor.d.ts +1 -1
  53. package/ClickOutside/index.js +5 -2
  54. package/DatePicker/index.d.ts +1 -1
  55. package/ErrorBoundary/RenderError.js +17 -7
  56. package/ErrorBoundary/index.d.ts +1 -1
  57. package/Grid/index.d.ts +17 -5
  58. package/Grid/index.js +7 -2
  59. package/Highlighted/index.js +1 -2
  60. package/LoadingIndicator/LoadingOverlay.js +17 -7
  61. package/LoadingIndicator/Spinner.js +17 -7
  62. package/LoadingIndicator/SpinnerCircle.d.ts +2 -3
  63. package/Menu/MenuContainer.d.ts +2 -2
  64. package/Menu/MenuContainer.js +19 -10
  65. package/Menu/MenuItem.js +5 -1
  66. package/Menu/MenuList.js +1 -1
  67. package/Menu/context.d.ts +1 -1
  68. package/Menu/index.d.ts +1 -1
  69. package/Modal/BaseModal/ModalInner.js +2 -0
  70. package/Modal/BaseModal/ModalWrapper.js +30 -37
  71. package/Modal/BaseModal/context.d.ts +1 -1
  72. package/Modal/BaseModal/index.js +1 -2
  73. package/Modal/ConfirmBox/ConfirmBoxContent.js +5 -1
  74. package/Modal/ConfirmBox/ConfirmBoxFooter.js +5 -1
  75. package/Modal/ConfirmBox/ConfirmBoxHeader.js +5 -1
  76. package/Modal/ConfirmBox/index.js +1 -2
  77. package/Modal/Dialog/DialogInner.js +5 -1
  78. package/Modal/Dialog/index.js +18 -9
  79. package/Modal/Drawer/DrawerCloseIcon.js +17 -7
  80. package/Modal/Drawer/DrawerFooter.js +5 -1
  81. package/Modal/Drawer/DrawerHeader.d.ts +4 -4
  82. package/Modal/Drawer/DrawerHeader.js +5 -1
  83. package/Modal/Drawer/index.js +18 -9
  84. package/Modal/MessageBox/MessageBoxContent.js +5 -1
  85. package/Modal/MessageBox/MessageBoxFooter.js +5 -1
  86. package/Modal/MessageBox/MessageBoxHeader.js +5 -1
  87. package/Modal/MessageBox/index.js +18 -9
  88. package/Modal/index.js +17 -7
  89. package/Pagination/PaginationContainer.d.ts +9 -0
  90. package/Pagination/PaginationContainer.js +34 -0
  91. package/Pagination/PaginationGap.d.ts +4 -0
  92. package/Pagination/PaginationGap.js +22 -0
  93. package/Pagination/PaginationIcons.d.ts +6 -0
  94. package/Pagination/PaginationIcons.js +21 -0
  95. package/Pagination/PaginationItem.d.ts +44 -0
  96. package/Pagination/PaginationItem.js +59 -0
  97. package/Pagination/getPaginationItems.d.ts +22 -0
  98. package/Pagination/getPaginationItems.js +42 -0
  99. package/Pagination/index.d.ts +104 -0
  100. package/Pagination/index.js +98 -0
  101. package/Pagination/usePagination.d.ts +105 -0
  102. package/Pagination/usePagination.js +66 -0
  103. package/PhoneField/CountryFlagComponent.d.ts +1 -1
  104. package/PhoneField/UnknownFlag.d.ts +0 -1
  105. package/PhoneField/flags/BY.js +17 -7
  106. package/PhoneField/flags/CN.js +17 -7
  107. package/PhoneField/flags/IL.js +17 -7
  108. package/PhoneField/flags/JP.js +17 -7
  109. package/PhoneField/flags/KZ.js +17 -7
  110. package/PhoneField/flags/RU.js +17 -7
  111. package/PhoneField/flags/UA.js +17 -7
  112. package/PhoneField/flags/US.js +17 -7
  113. package/PhoneField/flags/Unknown.js +17 -7
  114. package/PhoneField/templates.d.ts +2 -2
  115. package/Popper/Popper.js +1 -2
  116. package/Radio/RadioBox.d.ts +1 -1
  117. package/Radio/RadioBox.js +1 -1
  118. package/Radio/RadioContainer.d.ts +2 -2
  119. package/Radio/index.d.ts +5 -5
  120. package/Radio/index.js +1 -2
  121. package/Radio/useRadioColor.d.ts +1 -1
  122. package/RadioGroup/RadioGroupAsterisk.js +17 -7
  123. package/RadioGroup/RadioGroupErrorText.js +17 -7
  124. package/RadioGroup/RadioGroupItems.d.ts +1 -1
  125. package/RadioGroup/index.d.ts +11 -11
  126. package/RadioGroup/index.js +1 -2
  127. package/Selectbox/SelectboxButton.d.ts +4 -4
  128. package/Selectbox/SelectboxButton.js +25 -10
  129. package/Selectbox/SelectboxButtonWrapper.d.ts +2 -2
  130. package/Selectbox/SelectboxButtonWrapper.js +19 -10
  131. package/Selectbox/SelectboxMenu.d.ts +2 -2
  132. package/Selectbox/SelectboxMenu.js +17 -7
  133. package/Selectbox/index.d.ts +2 -2
  134. package/Selectbox/index.js +18 -9
  135. package/Slider/SliderRail.d.ts +1 -1
  136. package/Slider/SliderThumb.d.ts +1 -1
  137. package/Slider/SliderTrack.d.ts +1 -1
  138. package/Slider/index.js +1 -2
  139. package/Slider/useSliderColor.d.ts +1 -1
  140. package/Stack/index.d.ts +18 -6
  141. package/Stack/index.js +7 -2
  142. package/Surface/SurfaceContainer.d.ts +3 -3
  143. package/Surface/SurfaceContainer.js +1 -1
  144. package/Surface/SurfaceContent.d.ts +2 -2
  145. package/Surface/SurfaceContent.js +18 -11
  146. package/Surface/SurfaceFooter.d.ts +2 -2
  147. package/Surface/SurfaceFooter.js +5 -1
  148. package/Surface/SurfaceHeader.d.ts +2 -2
  149. package/Surface/SurfaceHeader.js +6 -2
  150. package/Surface/SurfaceSubheader.d.ts +2 -2
  151. package/Surface/SurfaceSubheader.js +6 -2
  152. package/Surface/index.d.ts +10 -10
  153. package/Surface/index.js +18 -9
  154. package/Swiper/Swiper.d.ts +83 -15
  155. package/Swiper/Swiper.js +285 -143
  156. package/Swiper/SwiperContainer.d.ts +2 -2
  157. package/Swiper/SwiperSlide.js +20 -7
  158. package/Swiper/SwiperSlidesRenderer.d.ts +4 -0
  159. package/Swiper/SwiperSlidesRenderer.js +19 -8
  160. package/Swiper/SwiperTrack.d.ts +22 -2
  161. package/Swiper/SwiperTrack.js +45 -12
  162. package/Swiper/SwiperWrapper.d.ts +5 -2
  163. package/Swiper/SwiperWrapper.js +22 -11
  164. package/Switch/SwitchAsterisk.js +17 -7
  165. package/Switch/SwitchContainer.d.ts +2 -2
  166. package/Switch/SwitchDot.d.ts +1 -1
  167. package/Switch/SwitchDot.js +2 -4
  168. package/Switch/SwitchErrorText.js +17 -7
  169. package/Switch/SwitchTrack.d.ts +1 -1
  170. package/Switch/index.d.ts +9 -9
  171. package/Switch/index.js +1 -2
  172. package/Switch/useSwitchColor.d.ts +1 -1
  173. package/Table/Table.d.ts +1 -1
  174. package/Table/Table.js +1 -1
  175. package/Table/TableCaption.js +5 -1
  176. package/Table/TableCell.js +6 -2
  177. package/Table/TableFooter.js +2 -1
  178. package/Table/TableHeaderCell.js +6 -2
  179. package/Tabs/Tab.js +4 -1
  180. package/Tabs/TabPanel.d.ts +1 -1
  181. package/Tabs/Tabs.d.ts +7 -7
  182. package/Tabs/Tabs.js +1 -2
  183. package/Tabs/useTabsColor.d.ts +1 -1
  184. package/TextArea/TextAreaIconWrapper.d.ts +3 -3
  185. package/TextArea/TextAreaIconWrapper.js +17 -7
  186. package/TextArea/TextAreaInput.js +23 -8
  187. package/TextArea/index.js +18 -9
  188. package/TextField/TextFieldContainer.js +17 -7
  189. package/TextField/TextFieldErrorText.js +17 -7
  190. package/TextField/TextFieldIconWrapper.d.ts +3 -3
  191. package/TextField/TextFieldIconWrapper.js +17 -7
  192. package/TextField/TextFieldInput.js +23 -8
  193. package/TextField/TextFieldInputWrapper.d.ts +5 -5
  194. package/TextField/TextFieldInputWrapper.js +22 -9
  195. package/TextField/TextFieldLabel.js +17 -7
  196. package/TextField/TextFieldLabelAsterisk.js +17 -7
  197. package/TextField/index.d.ts +1 -1
  198. package/TextField/index.js +18 -9
  199. package/ThemeProvider/createTheme.js +7 -3
  200. package/ThemeProvider/index.d.ts +45 -12
  201. package/ThemeProvider/index.js +1 -4
  202. package/ThemeProvider/tokens.d.ts +54 -3
  203. package/ThemeProvider/tokens.js +61 -3
  204. package/Toast/ToastCard.js +5 -2
  205. package/Toast/ToastContainer.js +1 -2
  206. package/Tooltip/TooltipContainer.js +2 -0
  207. package/Tooltip/index.js +3 -4
  208. package/Typography/Base.d.ts +2 -3
  209. package/Typography/Blockquote.d.ts +2 -3
  210. package/Typography/List.d.ts +6 -7
  211. package/Typography/Paragraph.d.ts +1 -1
  212. package/Typography/Paragraph.js +17 -7
  213. package/Typography/SectionDescription.d.ts +2 -3
  214. package/Typography/U.d.ts +2 -3
  215. package/esm/Accordion/AccordionActions.js +2 -1
  216. package/esm/Accordion/AccordionContainer.js +2 -14
  217. package/esm/Accordion/AccordionContent.js +5 -1
  218. package/esm/Accordion/AccordionHeader.js +7 -3
  219. package/esm/Accordion/index.js +1 -2
  220. package/esm/Autocomplete/AutocompleteItem.js +2 -1
  221. package/esm/Avatar/index.js +1 -2
  222. package/esm/Badge/BadgeStyled.js +2 -2
  223. package/esm/Badge/index.js +1 -2
  224. package/esm/Button/ButtonContainer.js +23 -6
  225. package/esm/Button/buttonVariants.js +3 -2
  226. package/esm/Button/index.js +1 -20
  227. package/esm/ButtonGroup/index.js +4 -3
  228. package/esm/Calendar/CalendarComponent.js +1 -2
  229. package/esm/Calendar/CalendarPaper.js +1 -1
  230. package/esm/Checkbox/CheckboxBox.js +2 -2
  231. package/esm/Checkbox/index.js +1 -2
  232. package/esm/ClickOutside/index.js +5 -2
  233. package/esm/Grid/index.js +7 -2
  234. package/esm/Highlighted/index.js +1 -2
  235. package/esm/Menu/MenuContainer.js +2 -3
  236. package/esm/Menu/MenuItem.js +5 -1
  237. package/esm/Menu/MenuList.js +1 -1
  238. package/esm/Modal/BaseModal/ModalInner.js +2 -0
  239. package/esm/Modal/BaseModal/ModalWrapper.js +30 -37
  240. package/esm/Modal/BaseModal/index.js +1 -2
  241. package/esm/Modal/ConfirmBox/ConfirmBoxContent.js +5 -1
  242. package/esm/Modal/ConfirmBox/ConfirmBoxFooter.js +5 -1
  243. package/esm/Modal/ConfirmBox/ConfirmBoxHeader.js +5 -1
  244. package/esm/Modal/ConfirmBox/index.js +1 -2
  245. package/esm/Modal/Dialog/DialogInner.js +5 -1
  246. package/esm/Modal/Dialog/index.js +1 -2
  247. package/esm/Modal/Drawer/DrawerFooter.js +5 -1
  248. package/esm/Modal/Drawer/DrawerHeader.js +5 -1
  249. package/esm/Modal/Drawer/index.js +1 -2
  250. package/esm/Modal/MessageBox/MessageBoxContent.js +5 -1
  251. package/esm/Modal/MessageBox/MessageBoxFooter.js +5 -1
  252. package/esm/Modal/MessageBox/MessageBoxHeader.js +5 -1
  253. package/esm/Modal/MessageBox/index.js +1 -2
  254. package/esm/Pagination/PaginationContainer.js +29 -0
  255. package/esm/Pagination/PaginationGap.js +17 -0
  256. package/esm/Pagination/PaginationIcons.js +15 -0
  257. package/esm/Pagination/PaginationItem.js +54 -0
  258. package/esm/Pagination/getPaginationItems.js +40 -0
  259. package/esm/Pagination/index.js +77 -0
  260. package/esm/Pagination/usePagination.js +61 -0
  261. package/esm/Popper/Popper.js +1 -2
  262. package/esm/Radio/RadioBox.js +2 -2
  263. package/esm/Radio/index.js +1 -2
  264. package/esm/RadioGroup/index.js +1 -2
  265. package/esm/Selectbox/SelectboxButton.js +8 -3
  266. package/esm/Selectbox/SelectboxButtonWrapper.js +2 -3
  267. package/esm/Selectbox/index.js +1 -2
  268. package/esm/Slider/index.js +1 -2
  269. package/esm/Stack/index.js +7 -2
  270. package/esm/Surface/SurfaceContainer.js +1 -1
  271. package/esm/Surface/SurfaceContent.js +18 -11
  272. package/esm/Surface/SurfaceFooter.js +5 -1
  273. package/esm/Surface/SurfaceHeader.js +6 -2
  274. package/esm/Surface/SurfaceSubheader.js +6 -2
  275. package/esm/Surface/index.js +1 -2
  276. package/esm/Swiper/Swiper.js +268 -136
  277. package/esm/Swiper/SwiperSlide.js +3 -0
  278. package/esm/Swiper/SwiperSlidesRenderer.js +2 -1
  279. package/esm/Swiper/SwiperTrack.js +28 -5
  280. package/esm/Swiper/SwiperWrapper.js +5 -4
  281. package/esm/Switch/SwitchDot.js +2 -4
  282. package/esm/Switch/index.js +1 -2
  283. package/esm/Table/Table.js +1 -1
  284. package/esm/Table/TableCaption.js +5 -1
  285. package/esm/Table/TableCell.js +6 -2
  286. package/esm/Table/TableFooter.js +2 -1
  287. package/esm/Table/TableHeaderCell.js +6 -2
  288. package/esm/Tabs/Tab.js +5 -2
  289. package/esm/Tabs/Tabs.js +1 -2
  290. package/esm/TextArea/TextAreaInput.js +6 -1
  291. package/esm/TextArea/index.js +1 -2
  292. package/esm/TextField/TextFieldInput.js +6 -1
  293. package/esm/TextField/TextFieldInputWrapper.js +5 -2
  294. package/esm/TextField/index.js +1 -2
  295. package/esm/ThemeProvider/createTheme.js +7 -3
  296. package/esm/ThemeProvider/index.js +0 -2
  297. package/esm/ThemeProvider/tokens.js +55 -2
  298. package/esm/Toast/ToastCard.js +6 -3
  299. package/esm/Toast/ToastContainer.js +1 -2
  300. package/esm/Tooltip/TooltipContainer.js +2 -0
  301. package/esm/Tooltip/index.js +3 -4
  302. package/esm/utils/getElementRef.js +13 -0
  303. package/package.json +46 -11
  304. package/utils/getElementRef.d.ts +8 -0
  305. package/utils/getElementRef.js +18 -0
  306. package/ThemeProvider/components.d.ts +0 -79
  307. package/ThemeProvider/components.js +0 -3
  308. package/ThemeProvider/useThemeProps.d.ts +0 -7
  309. package/ThemeProvider/useThemeProps.js +0 -34
  310. package/esm/ThemeProvider/components.js +0 -2
  311. package/esm/ThemeProvider/useThemeProps.js +0 -29
package/Swiper/Swiper.js CHANGED
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
36
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
37
  };
@@ -46,47 +56,66 @@ const SwiperContainer_1 = __importDefault(require("./SwiperContainer"));
46
56
  const SwiperWrapper_1 = __importDefault(require("./SwiperWrapper"));
47
57
  const SwiperTrack_1 = __importDefault(require("./SwiperTrack"));
48
58
  const SwiperSlidesRenderer_1 = __importDefault(require("./SwiperSlidesRenderer"));
49
- const useThemeProps_1 = __importDefault(require("../ThemeProvider/useThemeProps"));
50
59
  __exportStar(require("./SwiperSlide"), exports);
51
60
  const defaultSlideLabel = (index, total) => `${index + 1} / ${total}`;
61
+ const prefersReducedMotion = () => typeof window !== 'undefined' &&
62
+ typeof window.matchMedia === 'function' &&
63
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
52
64
  exports.Swiper = React.forwardRef((props, ref) => {
53
- const _a = (0, useThemeProps_1.default)('Swiper', props), { children, dragThreshold = 240, snap = true, draggable = true, overrides, initialIndex = 0, infinite = false, onSlideChange, autoplay = false, autoplayInterval = 3000, pauseOnHover = true, threshold = 20, resistance = true, slidesPerView = 1, keyboardControl = true, slideLabel = defaultSlideLabel } = _a, restProps = __rest(_a, ["children", "dragThreshold", "snap", "draggable", "overrides", "initialIndex", "infinite", "onSlideChange", "autoplay", "autoplayInterval", "pauseOnHover", "threshold", "resistance", "slidesPerView", "keyboardControl", "slideLabel"]);
65
+ const { children, dragThreshold = 240, snap = true, draggable: draggableProp = true, overrides, initialIndex = 0, infinite = false, onSlideChange, autoplay = false, autoplayInterval = 3000, pauseOnHover = true, threshold = 20, resistance = true, slidesPerView: slidesPerViewProp = 1, centered = false, direction = 'horizontal', effect = 'slide', speed = 300, autoScroll, keyboardControl: keyboardControlProp = true, slideLabel = defaultSlideLabel } = props, restProps = __rest(props, ["children", "dragThreshold", "snap", "draggable", "overrides", "initialIndex", "infinite", "onSlideChange", "autoplay", "autoplayInterval", "pauseOnHover", "threshold", "resistance", "slidesPerView", "centered", "direction", "effect", "speed", "autoScroll", "keyboardControl", "slideLabel"]);
66
+ const isFade = effect === 'fade';
67
+ const isTicker = typeof autoScroll === 'number' && autoScroll > 0 && !isFade;
68
+ const isVertical = direction === 'vertical';
69
+ const slidesPerView = isFade ? 1 : Math.max(slidesPerViewProp, 0.1);
70
+ const draggable = draggableProp && !isTicker;
71
+ const keyboardControl = keyboardControlProp && !isTicker;
72
+ // The current slide is moved to the middle of the view by this number of slides
73
+ const centerShift = centered && !isFade ? (slidesPerView - 1) / 2 : 0;
54
74
  // #region Slides
55
- const slides = React.useMemo(() => {
75
+ const { slides, clones } = React.useMemo(() => {
56
76
  // toArray skips null/false and keeps the user keys (prefixed), so the slides are not remounted
57
77
  // when a slide is added to the start
58
78
  const childrenSlides = React.Children.toArray(children).filter(React.isValidElement);
59
- if (infinite) {
60
- if (childrenSlides.length < 2) {
61
- console.error('To infinite loop counts of the slides must be greater than 2');
62
- return childrenSlides;
63
- }
64
- if (childrenSlides.length < slidesPerView + 1) {
65
- console.error(`For infinite loop with slidesPerView=${slidesPerView}, need at least ${slidesPerView + 1} slides`);
66
- return childrenSlides;
67
- }
68
- // Используем стабильные ключи без Date.now()
69
- const headClones = childrenSlides.slice(-slidesPerView).map((slide, i) => React.cloneElement(slide, {
70
- key: `clone-head-${i}`,
71
- 'data-clone': 'head',
72
- }));
73
- const tailClones = childrenSlides.slice(0, slidesPerView).map((slide, i) => React.cloneElement(slide, {
74
- key: `clone-tail-${i}`,
75
- 'data-clone': 'tail',
76
- }));
77
- return [...headClones, ...childrenSlides, ...tailClones];
78
- }
79
- return childrenSlides;
80
- }, [children, infinite, slidesPerView]);
79
+ // The fade effect does not move the track, the loop does not need the copies
80
+ if (!(infinite || isTicker) || isFade) {
81
+ return { slides: childrenSlides, clones: 0 };
82
+ }
83
+ // The copies on each side cover the whole view (also its partially visible slides)
84
+ // and the part of the view in front of the centered slide
85
+ const count = Math.ceil(slidesPerView) + Math.ceil(centerShift);
86
+ if (childrenSlides.length < Math.max(2, count)) {
87
+ console.error(`For infinite loop with slidesPerView=${slidesPerView}${centered ? ' and centered' : ''}, need at least ${Math.max(2, count)} slides`);
88
+ return { slides: childrenSlides, clones: 0 };
89
+ }
90
+ const headClones = childrenSlides.slice(-count).map((slide, i) => React.cloneElement(slide, {
91
+ key: `clone-head-${i}`,
92
+ 'data-clone': 'head',
93
+ }));
94
+ const tailClones = childrenSlides.slice(0, count).map((slide, i) => React.cloneElement(slide, {
95
+ key: `clone-tail-${i}`,
96
+ 'data-clone': 'tail',
97
+ }));
98
+ return { slides: [...headClones, ...childrenSlides, ...tailClones], clones: count };
99
+ }, [children, infinite, isTicker, isFade, slidesPerView, centerShift, centered]);
100
+ // The infinite loop by the copies of the slides (slide effect and ticker)
101
+ const isLoop = clones > 0;
102
+ // The fade effect loops by the index alone
103
+ const isFadeLoop = isFade && infinite && slides.length > 1;
81
104
  const total = slides.length;
82
- const realSlidesCount = infinite ? total - 2 * slidesPerView : total;
83
- const maxIndex = Math.max(0, total - slidesPerView);
105
+ const realSlidesCount = total - 2 * clones;
106
+ // Without the loop the last position shows the last slide at the end of the view
107
+ // (in the middle of the view when centered). With a fractional slidesPerView it is not a whole
108
+ // slide: the index goes up to the next whole number and the track stops at the last position
109
+ const lastPosition = isFade || centerShift > 0 ? Math.max(0, total - 1) : Math.max(0, total - slidesPerView);
110
+ const maxIndex = Math.ceil(lastPosition - 0.001);
111
+ // The index while the track is between the slides (drag, free mode) without the loop
112
+ const maxFreeIndex = Math.floor(lastPosition + 0.001);
84
113
  // #region States
85
114
  const [index, setIndex] = React.useState(() => {
86
- if (!infinite) {
115
+ if (!isLoop) {
87
116
  return Math.max(0, Math.min(initialIndex, maxIndex));
88
117
  }
89
- return initialIndex + slidesPerView;
118
+ return initialIndex + clones;
90
119
  });
91
120
  const [offset, setOffset] = React.useState(0);
92
121
  // The long decelerating transition after a free swipe (snap=false)
@@ -100,8 +129,8 @@ exports.Swiper = React.forwardRef((props, ref) => {
100
129
  const isPaused = isPausedByApi || isHovered || isFocused;
101
130
  // #region Refs
102
131
  const dragging = React.useRef(false);
103
- const startX = React.useRef(0);
104
- const lastX = React.useRef(0);
132
+ const startCoord = React.useRef(0);
133
+ const lastCoord = React.useRef(0);
105
134
  const lastTime = React.useRef(0);
106
135
  const velocity = React.useRef(0);
107
136
  const wrapperRef = React.useRef(null);
@@ -109,12 +138,13 @@ exports.Swiper = React.forwardRef((props, ref) => {
109
138
  const isAnimating = React.useRef(false);
110
139
  const mounted = React.useRef(true);
111
140
  const suppressClick = React.useRef(false);
141
+ const getCoord = React.useCallback((e) => (isVertical ? e.clientY : e.clientX), [isVertical]);
112
142
  // #region Real Index
113
143
  const realIndex = React.useMemo(() => {
114
- if (!infinite) {
144
+ if (!isLoop) {
115
145
  return index;
116
146
  }
117
- const realIndex = index - slidesPerView;
147
+ const realIndex = index - clones;
118
148
  if (realIndex < 0) {
119
149
  return realSlidesCount + realIndex;
120
150
  }
@@ -123,7 +153,7 @@ exports.Swiper = React.forwardRef((props, ref) => {
123
153
  }
124
154
  // In the infinite mode any slide can be the first visible one, so there is no clamp
125
155
  return realIndex;
126
- }, [index, infinite, slidesPerView, realSlidesCount]);
156
+ }, [index, isLoop, clones, realSlidesCount]);
127
157
  const prevRealIndex = React.useRef(realIndex);
128
158
  // #region Effects
129
159
  React.useEffect(() => {
@@ -136,18 +166,18 @@ exports.Swiper = React.forwardRef((props, ref) => {
136
166
  if (!mounted.current)
137
167
  return;
138
168
  // The slides were removed: keep the index inside the allowed range
139
- const lastIndex = infinite ? total - slidesPerView : maxIndex;
169
+ const lastIndex = isLoop ? total - clones : maxIndex;
140
170
  if (index > lastIndex) {
141
- setIndex(infinite ? slidesPerView : maxIndex);
171
+ setIndex(isLoop ? clones : maxIndex);
142
172
  setOffset(0);
143
173
  }
144
- }, [index, infinite, total, slidesPerView, maxIndex]);
174
+ }, [index, isLoop, total, clones, maxIndex]);
145
175
  // #region Normalization
146
176
  const normalizeIndex = React.useCallback(() => {
147
- if (!infinite || !mounted.current)
177
+ if (!isLoop || !mounted.current)
148
178
  return;
149
- const firstRealIndex = slidesPerView;
150
- const lastRealIndex = total - slidesPerView - 1;
179
+ const firstRealIndex = clones;
180
+ const lastRealIndex = total - clones - 1;
151
181
  if (index < firstRealIndex || index > lastRealIndex) {
152
182
  // A clone position shows the same slides as the real position shifted by the slides count.
153
183
  // Not always the first/last real slide: after several fast clicks the index may be deeper in the clones
@@ -167,7 +197,7 @@ exports.Swiper = React.forwardRef((props, ref) => {
167
197
  });
168
198
  });
169
199
  }
170
- }, [index, infinite, slidesPerView, total, realSlidesCount]);
200
+ }, [index, isLoop, clones, total, realSlidesCount]);
171
201
  // #region Navigation API
172
202
  const indexRef = React.useRef(index);
173
203
  React.useEffect(() => {
@@ -176,13 +206,13 @@ exports.Swiper = React.forwardRef((props, ref) => {
176
206
  const goToIndex = React.useCallback((i) => {
177
207
  // In the infinite mode the index is normalized after the transition, so wait for it.
178
208
  // In the regular mode the transition is simply retargeted
179
- if (infinite && isAnimating.current)
209
+ if (isLoop && isAnimating.current)
180
210
  return;
181
211
  let targetIndex = i;
182
- if (infinite) {
183
- targetIndex = i + slidesPerView;
184
- const minIndex = slidesPerView;
185
- const maxIndex = slidesPerView + realSlidesCount - 1;
212
+ if (isLoop) {
213
+ targetIndex = i + clones;
214
+ const minIndex = clones;
215
+ const maxIndex = clones + realSlidesCount - 1;
186
216
  targetIndex = Math.max(minIndex, Math.min(maxIndex, targetIndex));
187
217
  }
188
218
  else {
@@ -196,17 +226,20 @@ exports.Swiper = React.forwardRef((props, ref) => {
196
226
  setOffset(0);
197
227
  setIndex(targetIndex);
198
228
  isAnimating.current = true;
199
- }, [infinite, slidesPerView, realSlidesCount, maxIndex]);
229
+ }, [isLoop, clones, realSlidesCount, maxIndex]);
200
230
  const next = React.useCallback(() => {
201
231
  setDisableAnimation(false);
202
232
  setIsMomentum(false);
203
233
  setOffset(0);
204
234
  setIndex(prev => {
205
235
  let nextIndex;
206
- if (infinite) {
236
+ if (isLoop) {
207
237
  // The last position is the first tail clone: it mirrors the first real slide.
208
238
  // Further positions would show the empty space when slidesPerView > 1
209
- nextIndex = Math.min(prev + 1, total - slidesPerView);
239
+ nextIndex = Math.min(prev + 1, total - clones);
240
+ }
241
+ else if (isFadeLoop) {
242
+ nextIndex = (prev + 1) % total;
210
243
  }
211
244
  else {
212
245
  nextIndex = Math.min(prev + 1, maxIndex);
@@ -218,50 +251,61 @@ exports.Swiper = React.forwardRef((props, ref) => {
218
251
  isAnimating.current = true;
219
252
  return nextIndex;
220
253
  });
221
- }, [infinite, maxIndex, total, slidesPerView]);
254
+ }, [isLoop, isFadeLoop, maxIndex, total, clones]);
222
255
  const prev = React.useCallback(() => {
223
256
  setDisableAnimation(false);
224
257
  setIsMomentum(false);
225
258
  setOffset(0);
226
259
  setIndex(prev => {
227
- const nextIndex = Math.max(prev - 1, 0);
260
+ const nextIndex = isFadeLoop ? (prev - 1 + total) % total : Math.max(prev - 1, 0);
228
261
  if (nextIndex === prev) {
229
262
  return prev;
230
263
  }
231
264
  isAnimating.current = true;
232
265
  return nextIndex;
233
266
  });
234
- }, []);
267
+ }, [isFadeLoop, total]);
235
268
  // #region Position
236
- // The position is the distance in pixels from the start of the track to the left edge of the view.
237
- // The state keeps it as index (whole slides) + offset (pixels), the track is translated by both
238
- const getSlideWidth = React.useCallback(() => { var _a; return (((_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) || 0) / slidesPerView; }, [slidesPerView]);
269
+ // The position is the distance in pixels from the start of the track to the start of the view
270
+ // without the centering shift. The state keeps it as index (whole slides) + offset (pixels)
271
+ const getSlideSize = React.useCallback(() => {
272
+ const wrapper = wrapperRef.current;
273
+ const size = (isVertical ? wrapper === null || wrapper === void 0 ? void 0 : wrapper.clientHeight : wrapper === null || wrapper === void 0 ? void 0 : wrapper.clientWidth) || 0;
274
+ return size / slidesPerView;
275
+ }, [isVertical, slidesPerView]);
239
276
  // The last allowed position. In the infinite mode it is the first tail clone
240
- const maxPosition = React.useCallback(() => (infinite ? total - slidesPerView : maxIndex) * getSlideWidth(), [infinite, total, slidesPerView, maxIndex, getSlideWidth]);
277
+ const maxPosition = React.useCallback(() => (isLoop ? total - clones : lastPosition) * getSlideSize(), [isLoop, total, clones, lastPosition, getSlideSize]);
278
+ // The index of the track: without the loop the track stops at the last position
279
+ // even if the index is the next whole number
280
+ const trackIndex = (isLoop ? index : Math.min(index, lastPosition)) - centerShift;
241
281
  // The position on the screen right now, also in the middle of a transition
242
282
  const readPosition = React.useCallback(() => {
243
283
  const track = trackRef.current;
284
+ const size = getSlideSize();
244
285
  if (track && typeof DOMMatrixReadOnly !== 'undefined') {
245
286
  const { transform } = getComputedStyle(track);
246
287
  if (transform && transform !== 'none') {
247
- return -new DOMMatrixReadOnly(transform).m41;
288
+ const matrix = new DOMMatrixReadOnly(transform);
289
+ return -(isVertical ? matrix.m42 : matrix.m41) + centerShift * size;
248
290
  }
249
291
  }
250
- return index * getSlideWidth() - offset;
251
- }, [index, offset, getSlideWidth]);
292
+ return (trackIndex + centerShift) * size - offset;
293
+ }, [trackIndex, centerShift, offset, getSlideSize, isVertical]);
252
294
  // Infinite mode: the same view is shown by the real slides and by the clones,
253
295
  // so the position is moved by the whole slides count when it comes close to the edge of the track
254
296
  const wrapPosition = React.useCallback((position) => {
255
- const width = getSlideWidth();
256
- const span = realSlidesCount * width;
257
- if (!infinite || width === 0)
297
+ const size = getSlideSize();
298
+ const span = realSlidesCount * size;
299
+ if (!isLoop || size === 0)
258
300
  return 0;
259
- if (position < width * 0.5)
301
+ if (position < size * 0.5)
260
302
  return span;
261
- if (position > maxPosition() - width * 0.5)
303
+ if (position > maxPosition() - size * 0.5)
262
304
  return -span;
263
305
  return 0;
264
- }, [infinite, realSlidesCount, getSlideWidth, maxPosition]);
306
+ }, [isLoop, realSlidesCount, getSlideSize, maxPosition]);
307
+ // Without the loop the index between the slides does not go past the last position
308
+ const clampFreeIndex = React.useCallback((i) => (isLoop ? i : Math.max(0, Math.min(maxFreeIndex, i))), [isLoop, maxFreeIndex]);
265
309
  const dragBasePosition = React.useRef(0);
266
310
  const dragAnchorIndex = React.useRef(0);
267
311
  const dragPosition = React.useRef(0);
@@ -272,49 +316,61 @@ exports.Swiper = React.forwardRef((props, ref) => {
272
316
  // Only the main mouse button, the touch or the pen
273
317
  if (e.pointerType === 'mouse' && e.button !== 0)
274
318
  return;
275
- const width = getSlideWidth();
319
+ suppressClick.current = false;
320
+ dragging.current = true;
321
+ startCoord.current = getCoord(e);
322
+ lastCoord.current = getCoord(e);
323
+ lastTime.current = performance.now();
324
+ velocity.current = 0;
325
+ // The capture fails for a pointer that is already gone: the drag still works without it
326
+ try {
327
+ e.target.setPointerCapture(e.pointerId);
328
+ }
329
+ catch (_a) {
330
+ // nothing
331
+ }
332
+ // The fade does not move the track: the slide changes after the release
333
+ if (isFade)
334
+ return;
335
+ const size = getSlideSize();
276
336
  // Grab the track where it is now: a running transition stops under the finger instead of jumping
277
337
  let position = readPosition();
278
338
  position += wrapPosition(position);
279
- const anchor = width > 0 ? Math.round(position / width) : index;
339
+ const anchor = clampFreeIndex(size > 0 ? Math.round(position / size) : index);
280
340
  dragBasePosition.current = position;
281
341
  dragPosition.current = position;
282
342
  dragAnchorIndex.current = anchor;
283
- suppressClick.current = false;
284
- dragging.current = true;
285
343
  isAnimating.current = false;
286
344
  setDisableAnimation(true);
287
345
  setIsMomentum(false);
288
346
  setIsDragging(true);
289
347
  setIndex(anchor);
290
- setOffset(anchor * width - position);
291
- startX.current = e.clientX;
292
- lastX.current = e.clientX;
293
- lastTime.current = performance.now();
294
- velocity.current = 0;
295
- e.target.setPointerCapture(e.pointerId);
296
- }, [draggable, getSlideWidth, readPosition, wrapPosition, index]);
348
+ setOffset(anchor * size - position);
349
+ }, [draggable, isFade, getCoord, getSlideSize, readPosition, wrapPosition, clampFreeIndex, index]);
297
350
  const onPointerMove = React.useCallback((e) => {
298
351
  if (!dragging.current)
299
352
  return;
353
+ const coord = getCoord(e);
300
354
  const now = performance.now();
301
- const dx = e.clientX - lastX.current;
355
+ const delta = coord - lastCoord.current;
302
356
  const dt = now - lastTime.current;
303
357
  if (dt > 0) {
304
- velocity.current = dx / dt;
358
+ velocity.current = delta / dt;
305
359
  }
306
- lastX.current = e.clientX;
360
+ lastCoord.current = coord;
307
361
  lastTime.current = now;
308
- const width = getSlideWidth();
309
- let position = dragBasePosition.current - (e.clientX - startX.current);
362
+ if (isFade)
363
+ return;
364
+ const size = getSlideSize();
365
+ let position = dragBasePosition.current - (coord - startCoord.current);
310
366
  // Endless drag in the infinite mode: move the base together with the position
311
367
  const shift = wrapPosition(position);
312
368
  if (shift !== 0) {
313
369
  dragBasePosition.current += shift;
314
- dragAnchorIndex.current += Math.round(shift / width);
370
+ dragAnchorIndex.current += Math.round(shift / size);
315
371
  position += shift;
316
372
  }
317
- if (!infinite) {
373
+ if (!isLoop) {
318
374
  const max = maxPosition();
319
375
  if (position < 0) {
320
376
  position = resistance ? position * 0.3 : 0;
@@ -326,27 +382,55 @@ exports.Swiper = React.forwardRef((props, ref) => {
326
382
  dragPosition.current = position;
327
383
  // snap: the index stays the same during the drag, the slide changes after the release.
328
384
  // free: the index follows the position, so onSlideChange reports the slide under the view
329
- const nextIndex = snap ? dragAnchorIndex.current : Math.round(position / width);
385
+ const nextIndex = snap
386
+ ? dragAnchorIndex.current
387
+ : clampFreeIndex(Math.round(position / size));
330
388
  setIndex(nextIndex);
331
- setOffset(nextIndex * width - position);
332
- }, [getSlideWidth, wrapPosition, infinite, maxPosition, resistance, snap]);
389
+ setOffset(nextIndex * size - position);
390
+ }, [
391
+ getCoord,
392
+ isFade,
393
+ getSlideSize,
394
+ wrapPosition,
395
+ isLoop,
396
+ maxPosition,
397
+ resistance,
398
+ snap,
399
+ clampFreeIndex,
400
+ ]);
333
401
  const onPointerUp = React.useCallback((e) => {
334
402
  if (!dragging.current)
335
403
  return;
336
- const width = getSlideWidth();
337
- const position = dragPosition.current;
338
- const delta = lastX.current - startX.current;
339
- // The pointer stopped before the release: no inertia
340
- const v = performance.now() - lastTime.current > 100 ? 0 : velocity.current;
341
- const lastIndex = infinite ? total - slidesPerView : maxIndex;
404
+ const delta = lastCoord.current - startCoord.current;
342
405
  // It was a drag, not a click: the click on a link or a button inside the slide must not fire
343
406
  if (Math.abs(delta) > threshold) {
344
407
  suppressClick.current = true;
345
408
  }
409
+ dragging.current = false;
410
+ try {
411
+ e.target.releasePointerCapture(e.pointerId);
412
+ }
413
+ catch (_a) {
414
+ // nothing
415
+ }
416
+ if (isFade) {
417
+ if (delta < -threshold) {
418
+ next();
419
+ }
420
+ else if (delta > threshold) {
421
+ prev();
422
+ }
423
+ return;
424
+ }
425
+ const size = getSlideSize();
426
+ const position = dragPosition.current;
427
+ // The pointer stopped before the release: no inertia
428
+ const v = performance.now() - lastTime.current > 100 ? 0 : velocity.current;
429
+ const lastIndex = isLoop ? total - clones : maxIndex;
346
430
  setDisableAnimation(false);
347
431
  if (snap) {
348
432
  const anchor = dragAnchorIndex.current;
349
- const displacement = position - anchor * width;
433
+ const displacement = position - anchor * size;
350
434
  const velocityFactor = Math.min(Math.abs(v) * 250, 0.65);
351
435
  const dynamicThreshold = Math.max(threshold, Math.min(dragThreshold * (1 - velocityFactor), dragThreshold));
352
436
  let nextIndex = anchor;
@@ -354,37 +438,42 @@ exports.Swiper = React.forwardRef((props, ref) => {
354
438
  // At least one slide, more if the slide was dragged further
355
439
  nextIndex =
356
440
  displacement > 0
357
- ? Math.max(anchor + 1, Math.round(position / width))
358
- : Math.min(anchor - 1, Math.round(position / width));
441
+ ? Math.max(anchor + 1, Math.round(position / size))
442
+ : Math.min(anchor - 1, Math.round(position / size));
359
443
  }
360
444
  nextIndex = Math.max(0, Math.min(lastIndex, nextIndex));
361
445
  setIndex(nextIndex);
362
446
  setOffset(0);
363
447
  // A click without movement does not start a transition, so transitionend never comes
364
448
  // and the flag would block autoplay and goToIndex forever
365
- isAnimating.current = Math.abs(nextIndex * width - position) > 0.5;
449
+ const target = (isLoop ? nextIndex : Math.min(nextIndex, lastPosition)) * size;
450
+ isAnimating.current = Math.abs(target - position) > 0.5;
366
451
  }
367
452
  else {
368
453
  // Free mode: the track keeps moving by inertia and stops where it stops
369
- const projected = Math.max(0, Math.min(lastIndex * width, position - v * 300));
370
- const nextIndex = width > 0 ? Math.round(projected / width) : index;
454
+ const maxProjected = (isLoop ? lastIndex : lastPosition) * size;
455
+ const projected = Math.max(0, Math.min(maxProjected, position - v * 300));
456
+ const nextIndex = clampFreeIndex(size > 0 ? Math.round(projected / size) : index);
371
457
  setIsMomentum(true);
372
458
  setIndex(nextIndex);
373
- setOffset(nextIndex * width - projected);
459
+ setOffset(nextIndex * size - projected);
374
460
  isAnimating.current = Math.abs(projected - position) > 0.5;
375
461
  }
376
- dragging.current = false;
377
462
  setIsDragging(false);
378
- e.target.releasePointerCapture(e.pointerId);
379
463
  }, [
380
- getSlideWidth,
381
- infinite,
464
+ isFade,
465
+ next,
466
+ prev,
467
+ getSlideSize,
468
+ isLoop,
382
469
  total,
383
- slidesPerView,
470
+ clones,
384
471
  maxIndex,
472
+ lastPosition,
385
473
  threshold,
386
474
  snap,
387
475
  dragThreshold,
476
+ clampFreeIndex,
388
477
  index,
389
478
  ]);
390
479
  const onLostPointerCapture = React.useCallback((e) => {
@@ -396,7 +485,7 @@ exports.Swiper = React.forwardRef((props, ref) => {
396
485
  const autoplayStep = React.useRef(() => undefined);
397
486
  autoplayStep.current = () => {
398
487
  // Without the infinite loop the autoplay returns to the first slide instead of stopping at the end
399
- if (!infinite && indexRef.current >= maxIndex) {
488
+ if (!isLoop && !isFadeLoop && indexRef.current >= maxIndex) {
400
489
  goToIndex(0);
401
490
  }
402
491
  else {
@@ -406,7 +495,7 @@ exports.Swiper = React.forwardRef((props, ref) => {
406
495
  const pause = React.useCallback(() => setIsPausedByApi(true), []);
407
496
  const resume = React.useCallback(() => setIsPausedByApi(false), []);
408
497
  React.useEffect(() => {
409
- if (!autoplay || isPaused)
498
+ if (!autoplay || isTicker || isPaused)
410
499
  return undefined;
411
500
  const timer = setInterval(() => {
412
501
  if (!dragging.current && !isAnimating.current && mounted.current) {
@@ -414,13 +503,57 @@ exports.Swiper = React.forwardRef((props, ref) => {
414
503
  }
415
504
  }, autoplayInterval);
416
505
  return () => clearInterval(timer);
417
- }, [autoplay, autoplayInterval, isPaused]);
506
+ }, [autoplay, isTicker, autoplayInterval, isPaused]);
507
+ // #region Ticker
508
+ // The continuous scroll writes the transform directly: 60 renders per second are not needed for it.
509
+ // The position is kept in slides, so it stays in place when the size of the swiper changes
510
+ const tickerPosition = React.useRef(null);
511
+ React.useEffect(() => {
512
+ const track = trackRef.current;
513
+ if (!isTicker || !isLoop || !track)
514
+ return undefined;
515
+ if (isPaused || prefersReducedMotion())
516
+ return undefined;
517
+ let frame = 0;
518
+ let last = performance.now();
519
+ const step = (now) => {
520
+ var _a;
521
+ const size = getSlideSize();
522
+ if (size > 0) {
523
+ let position = (_a = tickerPosition.current) !== null && _a !== void 0 ? _a : clones;
524
+ position += ((autoScroll || 0) * (now - last)) / 1000 / size;
525
+ if (position >= clones + realSlidesCount) {
526
+ position -= realSlidesCount;
527
+ }
528
+ tickerPosition.current = position;
529
+ const translate = -(position - centerShift) * size;
530
+ track.style.transition = 'none';
531
+ track.style.transform = isVertical
532
+ ? `translateY(${translate}px)`
533
+ : `translateX(${translate}px)`;
534
+ }
535
+ last = now;
536
+ frame = requestAnimationFrame(step);
537
+ };
538
+ frame = requestAnimationFrame(step);
539
+ return () => cancelAnimationFrame(frame);
540
+ }, [
541
+ isTicker,
542
+ isLoop,
543
+ isPaused,
544
+ autoScroll,
545
+ getSlideSize,
546
+ realSlidesCount,
547
+ clones,
548
+ centerShift,
549
+ isVertical,
550
+ ]);
418
551
  // #region Hover and focus
419
552
  // The autoplay pauses while the pointer is over the swiper (pauseOnHover)
420
553
  // and always while the focus is inside it, so the keyboard user is not interrupted
421
554
  React.useEffect(() => {
422
555
  const wrapper = wrapperRef.current;
423
- if (!autoplay || !wrapper)
556
+ if (!(autoplay || isTicker) || !wrapper)
424
557
  return undefined;
425
558
  const handleMouseEnter = () => pauseOnHover && setIsHovered(true);
426
559
  const handleMouseLeave = () => setIsHovered(false);
@@ -440,7 +573,7 @@ exports.Swiper = React.forwardRef((props, ref) => {
440
573
  wrapper.removeEventListener('focusin', handleFocusIn);
441
574
  wrapper.removeEventListener('focusout', handleFocusOut);
442
575
  };
443
- }, [autoplay, pauseOnHover]);
576
+ }, [autoplay, isTicker, pauseOnHover]);
444
577
  // #region Keyboard
445
578
  const onKeyDown = React.useCallback((event) => {
446
579
  if (!keyboardControl)
@@ -449,15 +582,15 @@ exports.Swiper = React.forwardRef((props, ref) => {
449
582
  const target = event.target;
450
583
  if (target.closest('input, textarea, select, [contenteditable="true"]'))
451
584
  return;
452
- if (event.key === 'ArrowLeft') {
585
+ if (event.key === (isVertical ? 'ArrowUp' : 'ArrowLeft')) {
453
586
  event.preventDefault();
454
587
  prev();
455
588
  }
456
- if (event.key === 'ArrowRight') {
589
+ if (event.key === (isVertical ? 'ArrowDown' : 'ArrowRight')) {
457
590
  event.preventDefault();
458
591
  next();
459
592
  }
460
- }, [keyboardControl, prev, next]);
593
+ }, [keyboardControl, isVertical, prev, next]);
461
594
  const onClickCapture = React.useCallback((event) => {
462
595
  if (suppressClick.current) {
463
596
  suppressClick.current = false;
@@ -476,14 +609,16 @@ exports.Swiper = React.forwardRef((props, ref) => {
476
609
  const track = trackRef.current;
477
610
  if (!track)
478
611
  return;
612
+ // The fade changes the opacity of the slides, the event bubbles up to the track
613
+ const property = isFade ? 'opacity' : 'transform';
479
614
  const handleTransitionEnd = (e) => {
480
- if (e.propertyName !== 'transform')
615
+ if (e.propertyName !== property)
481
616
  return;
482
617
  isAnimating.current = false;
483
- normalizeIndex(); // <-- вот здесь
618
+ normalizeIndex();
484
619
  };
485
620
  const handleTransitionCancel = (e) => {
486
- if (e.propertyName !== 'transform')
621
+ if (e.propertyName !== property)
487
622
  return;
488
623
  isAnimating.current = false;
489
624
  };
@@ -493,7 +628,7 @@ exports.Swiper = React.forwardRef((props, ref) => {
493
628
  track.removeEventListener('transitionend', handleTransitionEnd);
494
629
  track.removeEventListener('transitioncancel', handleTransitionCancel);
495
630
  };
496
- }, [normalizeIndex]);
631
+ }, [normalizeIndex, isFade]);
497
632
  // #region Mount
498
633
  React.useEffect(() => {
499
634
  mounted.current = true;
@@ -518,34 +653,41 @@ exports.Swiper = React.forwardRef((props, ref) => {
518
653
  Wrapper: (overrides === null || overrides === void 0 ? void 0 : overrides.Wrapper) || SwiperWrapper_1.default,
519
654
  }), [overrides]);
520
655
  const getSlideRealIndex = React.useCallback((domIndex) => {
521
- if (!infinite) {
656
+ if (!isLoop) {
522
657
  return domIndex;
523
658
  }
524
- const totalSlides = realSlidesCount;
525
- if (domIndex < slidesPerView) {
526
- return totalSlides - slidesPerView + domIndex;
659
+ if (domIndex < clones) {
660
+ return realSlidesCount - clones + domIndex;
527
661
  }
528
- if (domIndex >= total - slidesPerView) {
529
- return domIndex - (total - slidesPerView);
662
+ if (domIndex >= total - clones) {
663
+ return domIndex - (total - clones);
530
664
  }
531
- return domIndex - slidesPerView;
532
- }, [infinite, realSlidesCount, slidesPerView, total]);
665
+ return domIndex - clones;
666
+ }, [isLoop, realSlidesCount, clones, total]);
533
667
  // The slides at least partially in the view: they are not inert, so a partially visible slide
534
- // can be clicked. Between the slides (drag, free mode) one more slide is partially visible
535
- const slideWidth = wrapperRef.current ? wrapperRef.current.clientWidth / slidesPerView : 0;
536
- let firstVisibleDomIndex = index;
537
- let visibleCount = slidesPerView;
538
- if (slideWidth > 0 && Math.abs(offset) > 0.5) {
539
- const position = index * slideWidth - offset;
540
- firstVisibleDomIndex = Math.floor(position / slideWidth + 0.001);
541
- const lastVisibleDomIndex = Math.ceil((position + slidesPerView * slideWidth) / slideWidth - 0.001) - 1;
542
- visibleCount = lastVisibleDomIndex - firstVisibleDomIndex + 1;
668
+ // can be clicked. Between the slides (drag, free mode), with a fractional slidesPerView
669
+ // and with the centering one more slide is partially visible
670
+ const wrapper = wrapperRef.current;
671
+ const slideSize = wrapper
672
+ ? (isVertical ? wrapper.clientHeight : wrapper.clientWidth) / slidesPerView
673
+ : 0;
674
+ const viewPosition = slideSize > 0 ? trackIndex - offset / slideSize : trackIndex;
675
+ let firstVisibleDomIndex = Math.floor(viewPosition + 0.001);
676
+ let visibleCount = Math.ceil(viewPosition + slidesPerView - 0.001) - firstVisibleDomIndex;
677
+ if (isFade) {
678
+ firstVisibleDomIndex = index;
679
+ visibleCount = 1;
543
680
  }
544
681
  firstVisibleDomIndex = Math.max(0, Math.min(total - 1, firstVisibleDomIndex));
682
+ // The ticker moves without the state: all the slides are rendered
683
+ if (isTicker) {
684
+ firstVisibleDomIndex = clones;
685
+ visibleCount = realSlidesCount;
686
+ }
545
687
  return (React.createElement(overridesMap.Container, Object.assign({ role: "region", "aria-roledescription": "carousel" }, restProps),
546
- React.createElement(overridesMap.Wrapper, { ref: wrapperRef, draggable: draggable, slidesPerView: slidesPerView, tabIndex: keyboardControl ? 0 : undefined, "aria-live": autoplay && !isPaused ? 'off' : 'polite', onKeyDown: onKeyDown, onClickCapture: onClickCapture, onDragStart: onDragStart, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onLostPointerCapture: onLostPointerCapture },
547
- React.createElement(overridesMap.Track, { ref: trackRef, dragging: isDragging, index: index, offset: offset, disableAnimation: disableAnimation, momentum: isMomentum, slidesPerView: slidesPerView },
548
- React.createElement(SwiperSlidesRenderer_1.default, { slides: slides, slidesPerView: slidesPerView, realIndex: realIndex, firstVisibleIndex: getSlideRealIndex(firstVisibleDomIndex), visibleCount: visibleCount, realSlidesCount: realSlidesCount, getSlideRealIndex: getSlideRealIndex, slideLabel: slideLabel })))));
688
+ React.createElement(overridesMap.Wrapper, { ref: wrapperRef, draggable: draggable, slidesPerView: slidesPerView, vertical: isVertical, tabIndex: keyboardControl ? 0 : undefined, "aria-live": (autoplay || isTicker) && !isPaused ? 'off' : 'polite', onKeyDown: onKeyDown, onClickCapture: onClickCapture, onDragStart: onDragStart, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onLostPointerCapture: onLostPointerCapture },
689
+ React.createElement(overridesMap.Track, { ref: trackRef, dragging: isDragging, index: isFade ? 0 : trackIndex, offset: isFade ? 0 : offset, disableAnimation: disableAnimation, momentum: isMomentum, slidesPerView: slidesPerView, vertical: isVertical, effect: effect, speed: speed },
690
+ React.createElement(SwiperSlidesRenderer_1.default, { slides: slides, slidesPerView: slidesPerView, realIndex: realIndex, firstVisibleIndex: getSlideRealIndex(firstVisibleDomIndex), visibleCount: visibleCount, realSlidesCount: realSlidesCount, getSlideRealIndex: getSlideRealIndex, slideLabel: slideLabel, activeDomIndex: isFade ? index : null })))));
549
691
  });
550
692
  exports.Swiper.displayName = 'Swiper';
551
693
  exports.default = exports.Swiper;