@faststore/ui 2.0.122-alpha.0 → 2.0.128-alpha.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 (44) hide show
  1. package/dist/index.d.ts +0 -6
  2. package/dist/index.js +0 -4
  3. package/dist/index.js.map +1 -1
  4. package/package.json +2 -2
  5. package/src/components/molecules/Carousel/styles.scss +83 -57
  6. package/src/components/molecules/NavbarLinks/styles.scss +1 -1
  7. package/src/components/organisms/ProductShelf/styles.scss +2 -3
  8. package/src/index.ts +0 -16
  9. package/dist/components/molecules/Bullets/Bullets.d.ts +0 -35
  10. package/dist/components/molecules/Bullets/Bullets.js +0 -12
  11. package/dist/components/molecules/Bullets/Bullets.js.map +0 -1
  12. package/dist/components/molecules/Bullets/index.d.ts +0 -2
  13. package/dist/components/molecules/Bullets/index.js +0 -2
  14. package/dist/components/molecules/Bullets/index.js.map +0 -1
  15. package/dist/components/molecules/Carousel/Arrows.d.ts +0 -12
  16. package/dist/components/molecules/Carousel/Arrows.js +0 -6
  17. package/dist/components/molecules/Carousel/Arrows.js.map +0 -1
  18. package/dist/components/molecules/Carousel/Carousel.d.ts +0 -54
  19. package/dist/components/molecules/Carousel/Carousel.js +0 -183
  20. package/dist/components/molecules/Carousel/Carousel.js.map +0 -1
  21. package/dist/components/molecules/Carousel/CarouselItem.d.ts +0 -11
  22. package/dist/components/molecules/Carousel/CarouselItem.js +0 -18
  23. package/dist/components/molecules/Carousel/CarouselItem.js.map +0 -1
  24. package/dist/components/molecules/Carousel/hooks/useSlideVisibility.d.ts +0 -9
  25. package/dist/components/molecules/Carousel/hooks/useSlideVisibility.js +0 -29
  26. package/dist/components/molecules/Carousel/hooks/useSlideVisibility.js.map +0 -1
  27. package/dist/components/molecules/Carousel/index.d.ts +0 -2
  28. package/dist/components/molecules/Carousel/index.js +0 -3
  29. package/dist/components/molecules/Carousel/index.js.map +0 -1
  30. package/dist/hooks/useSlider/index.d.ts +0 -2
  31. package/dist/hooks/useSlider/index.js +0 -3
  32. package/dist/hooks/useSlider/index.js.map +0 -1
  33. package/dist/hooks/useSlider/useSlider.d.ts +0 -64
  34. package/dist/hooks/useSlider/useSlider.js +0 -103
  35. package/dist/hooks/useSlider/useSlider.js.map +0 -1
  36. package/src/components/molecules/Bullets/Bullets.tsx +0 -88
  37. package/src/components/molecules/Bullets/index.ts +0 -2
  38. package/src/components/molecules/Carousel/Arrows.tsx +0 -58
  39. package/src/components/molecules/Carousel/Carousel.tsx +0 -387
  40. package/src/components/molecules/Carousel/CarouselItem.tsx +0 -54
  41. package/src/components/molecules/Carousel/hooks/useSlideVisibility.ts +0 -59
  42. package/src/components/molecules/Carousel/index.ts +0 -2
  43. package/src/hooks/useSlider/index.ts +0 -2
  44. package/src/hooks/useSlider/useSlider.ts +0 -209
@@ -1,387 +0,0 @@
1
- import type {
2
- UIEvent,
3
- ReactNode,
4
- CSSProperties,
5
- KeyboardEvent,
6
- PropsWithChildren,
7
- } from 'react'
8
- import React, { useMemo, useRef } from 'react'
9
- import type { SwipeableProps } from 'react-swipeable'
10
-
11
- import { RightArrowIcon, LeftArrowIcon } from './Arrows'
12
- import CarouselItem from './CarouselItem'
13
- import useSlider from '../../../hooks/useSlider/useSlider'
14
- import Bullets from '../Bullets'
15
- import { IconButton } from '../../../'
16
-
17
- const createTransformValues = (infinite: boolean, totalItems: number) => {
18
- const transformMap: Record<number, number> = {}
19
- const slideWidth = 100 / totalItems
20
-
21
- for (let idx = 0; idx < totalItems; ++idx) {
22
- const currIdx = infinite ? idx - 1 : idx
23
- const transformValue = -(slideWidth * idx)
24
-
25
- transformMap[currIdx] = transformValue
26
- }
27
-
28
- return transformMap
29
- }
30
-
31
- export interface CarouselProps extends SwipeableProps {
32
- /**
33
- * ID of the current instance of the component.
34
- */
35
- id?: string
36
- /**
37
- * ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
38
- */
39
- testId?: string
40
- /**
41
- * Returns the value of element's class content attribute.
42
- */
43
- className?: string
44
- /**
45
- * Whether or not the Carousel is infinite slide/scroll. Only for the `slide` variant.
46
- * @default true
47
- */
48
- infiniteMode?: boolean
49
- /**
50
- * Specifies which navigation elements should be visible.
51
- * @default complete
52
- */
53
- controls?: 'complete' | 'navigationArrows' | 'paginationBullets'
54
- /**
55
- * Specifies the slide transition. Only for the `slide` variant
56
- */
57
- transition?: {
58
- duration: number
59
- property: string
60
- delay?: number
61
- timing?: string
62
- }
63
- /**
64
- * Specifies the number of items per page.
65
- * @default 1
66
- */
67
- itemsPerPage?: number
68
- /**
69
- * Specifies the Carousel track variant.
70
- * @default slide
71
- */
72
- variant?: 'slide' | 'scroll'
73
- /**
74
- * Specifies the navigation icons.
75
- */
76
- navigationIcons?: {
77
- left?: ReactNode
78
- right?: ReactNode
79
- }
80
- }
81
-
82
- function Carousel({
83
- infiniteMode = true,
84
- controls = 'complete',
85
- testId = 'store-carousel',
86
- transition = {
87
- duration: 400,
88
- property: 'transform',
89
- },
90
- children,
91
- className,
92
- id = 'store-carousel',
93
- variant = 'slide',
94
- itemsPerPage = 1,
95
- navigationIcons = undefined,
96
- ...swipeableConfigOverrides
97
- }: PropsWithChildren<CarouselProps>) {
98
- const carouselTrackRef = useRef<HTMLUListElement>(null)
99
- const isSlideCarousel = variant === 'slide'
100
- const isScrollCarousel = variant === 'scroll'
101
- const childrenArray = React.Children.toArray(children)
102
- const childrenCount = childrenArray.length
103
- const numberOfSlides = infiniteMode ? childrenCount + 2 : childrenCount
104
- const slidingTransition = `${transition.property} ${transition.duration}ms ${
105
- transition.timing ?? ''
106
- } ${transition.delay ?? ''}`
107
-
108
- const showNavigationArrows =
109
- controls === 'complete' || controls === 'navigationArrows'
110
-
111
- const showPaginationBullets =
112
- controls === 'complete' || controls === 'paginationBullets'
113
-
114
- const transformValues = useMemo(
115
- () => createTransformValues(infiniteMode, numberOfSlides),
116
- [numberOfSlides, infiniteMode]
117
- )
118
-
119
- const { handlers, slide, sliderState, sliderDispatch } = useSlider({
120
- itemsPerPage,
121
- infiniteMode,
122
- totalItems: childrenCount,
123
- shouldSlideOnSwipe: isSlideCarousel,
124
- ...swipeableConfigOverrides,
125
- })
126
-
127
- const postRenderedSlides =
128
- infiniteMode && children ? childrenArray.slice(0, 1) : []
129
-
130
- const preRenderedSlides =
131
- infiniteMode && children ? childrenArray.slice(childrenCount - 1) : []
132
-
133
- const slides = preRenderedSlides.concat(
134
- (children as any) ?? [],
135
- postRenderedSlides
136
- )
137
-
138
- const slideCarouselTrackStyle: CSSProperties = useMemo(
139
- () => ({
140
- display: 'flex',
141
- width: `${numberOfSlides * 100}%`,
142
- transition: sliderState.sliding ? slidingTransition : undefined,
143
- transform: `translate3d(${
144
- transformValues[sliderState.currentPage]
145
- }%, 0, 0)`,
146
- }),
147
- [
148
- numberOfSlides,
149
- transformValues,
150
- slidingTransition,
151
- sliderState.sliding,
152
- sliderState.currentPage,
153
- ]
154
- )
155
-
156
- const scrollCarouselTrackStyle: CSSProperties = useMemo(
157
- () => ({
158
- width: '100%',
159
- display: 'block',
160
- overflowX: 'scroll',
161
- whiteSpace: 'nowrap',
162
- }),
163
- []
164
- )
165
-
166
- const carouselTrackStyle =
167
- ((isSlideCarousel && slideCarouselTrackStyle) as CSSProperties) ||
168
- ((isScrollCarousel && scrollCarouselTrackStyle) as CSSProperties)
169
-
170
- const slidePrevious = () => {
171
- if (
172
- sliderState.sliding ||
173
- (!infiniteMode && sliderState.currentPage === 0)
174
- ) {
175
- return
176
- }
177
-
178
- slide('previous', sliderDispatch)
179
- }
180
-
181
- const slideNext = () => {
182
- if (
183
- sliderState.sliding ||
184
- (!infiniteMode && sliderState.currentPage === childrenCount - 1)
185
- ) {
186
- return
187
- }
188
-
189
- slide('next', sliderDispatch)
190
- }
191
-
192
- const onScrollTrack = (event: UIEvent) => {
193
- if (isSlideCarousel || itemsPerPage > 1) {
194
- return
195
- }
196
-
197
- const itemWidth = Number(event.currentTarget.firstElementChild?.scrollWidth)
198
- const scrollOffset = event.currentTarget?.scrollLeft
199
- const formatter = scrollOffset > itemWidth / 2 ? Math.round : Math.floor
200
- const page = formatter(scrollOffset / itemWidth)
201
-
202
- slide(page, sliderDispatch)
203
- }
204
-
205
- const onTransitionTrackEnd = () => {
206
- sliderDispatch({
207
- type: 'STOP_SLIDE',
208
- })
209
-
210
- if (infiniteMode && sliderState.currentItem >= childrenCount) {
211
- sliderDispatch({
212
- type: 'GO_TO_PAGE',
213
- payload: {
214
- pageIndex: 0,
215
- shouldSlide: false,
216
- },
217
- })
218
- }
219
-
220
- if (infiniteMode && sliderState.currentItem < 0) {
221
- sliderDispatch({
222
- type: 'GO_TO_PAGE',
223
- payload: {
224
- pageIndex: sliderState.totalPages - 1,
225
- shouldSlide: false,
226
- },
227
- })
228
- }
229
- }
230
-
231
- const onScrollPagination = async (
232
- index: number,
233
- slideDirection?: 'previous' | 'next'
234
- ) => {
235
- if (slideDirection === 'previous' && sliderState.currentPage === 0) {
236
- return
237
- }
238
-
239
- if (
240
- slideDirection === 'next' &&
241
- sliderState.currentPage === sliderState.totalPages - 1
242
- ) {
243
- return
244
- }
245
-
246
- let scrollOffset
247
- const carouselItemsWidth = Number(
248
- carouselTrackRef.current?.firstElementChild?.clientWidth
249
- )
250
-
251
- if (itemsPerPage > 1) {
252
- scrollOffset = index * carouselItemsWidth * itemsPerPage
253
- } else {
254
- scrollOffset = index * carouselItemsWidth - carouselItemsWidth * 0.125
255
- }
256
-
257
- carouselTrackRef.current?.scrollTo({
258
- left: scrollOffset,
259
- behavior: 'smooth',
260
- })
261
-
262
- slide(index, sliderDispatch)
263
- }
264
-
265
- // accessible behavior for tablist
266
- const handleBulletsKeyDown = (event: KeyboardEvent) => {
267
- switch (event.key) {
268
- case 'ArrowLeft': {
269
- isSlideCarousel && slidePrevious()
270
- isScrollCarousel &&
271
- onScrollPagination(sliderState.currentPage - 1, 'previous')
272
- break
273
- }
274
-
275
- case 'ArrowRight': {
276
- isSlideCarousel && slideNext()
277
- isScrollCarousel &&
278
- onScrollPagination(sliderState.currentPage + 1, 'next')
279
- break
280
- }
281
-
282
- case 'Home': {
283
- slide(0, sliderDispatch)
284
- break
285
- }
286
-
287
- case 'End': {
288
- slide(childrenCount - 1, sliderDispatch)
289
- break
290
- }
291
-
292
- default:
293
- }
294
- }
295
-
296
- return (
297
- <section
298
- id={id}
299
- data-fs-carousel
300
- className={className}
301
- data-testid={testId}
302
- aria-label="carousel"
303
- aria-roledescription="carousel"
304
- >
305
- <div
306
- data-fs-carousel-track-container
307
- style={{
308
- width: '100%',
309
- overflow: 'hidden',
310
- display: isScrollCarousel ? 'block' : undefined,
311
- }}
312
- {...handlers}
313
- >
314
- <ul
315
- aria-live="polite"
316
- ref={carouselTrackRef}
317
- style={carouselTrackStyle}
318
- data-fs-carousel-track
319
- onScroll={onScrollTrack}
320
- onTransitionEnd={onTransitionTrackEnd}
321
- >
322
- {slides.map((currentSlide, idx) => (
323
- <CarouselItem
324
- index={idx}
325
- key={String(idx)}
326
- state={sliderState}
327
- totalItems={childrenCount}
328
- infiniteMode={infiniteMode}
329
- isScrollCarousel={isScrollCarousel}
330
- >
331
- {currentSlide}
332
- </CarouselItem>
333
- ))}
334
- </ul>
335
- </div>
336
-
337
- {showNavigationArrows && (
338
- <div data-fs-carousel-controls>
339
- <IconButton
340
- data-fs-carousel-control="left"
341
- aria-controls={id}
342
- aria-label="previous"
343
- icon={navigationIcons?.left ?? <LeftArrowIcon />}
344
- onClick={() => {
345
- isSlideCarousel && slidePrevious()
346
- isScrollCarousel &&
347
- onScrollPagination(sliderState.currentPage - 1, 'previous')
348
- }}
349
- />
350
- <IconButton
351
- data-fs-carousel-control="right"
352
- aria-controls={id}
353
- aria-label="next"
354
- icon={navigationIcons?.right ?? <RightArrowIcon />}
355
- onClick={() => {
356
- isSlideCarousel && slideNext()
357
- isScrollCarousel &&
358
- onScrollPagination(sliderState.currentPage + 1, 'next')
359
- }}
360
- />
361
- </div>
362
- )}
363
-
364
- {showPaginationBullets && (
365
- <div data-fs-carousel-bullets>
366
- <Bullets
367
- tabIndex={0}
368
- activeBullet={sliderState.currentPage}
369
- totalQuantity={Math.ceil(childrenCount / sliderState.itemsPerPage)}
370
- onKeyDown={handleBulletsKeyDown}
371
- onClick={async (_, idx) => {
372
- isSlideCarousel &&
373
- !sliderState.sliding &&
374
- slide(idx, sliderDispatch)
375
-
376
- isScrollCarousel && onScrollPagination(idx)
377
- }}
378
- onFocus={(event) => event.currentTarget.focus()}
379
- ariaControlsGenerator={(idx) => `carousel-item-${idx}`}
380
- />
381
- </div>
382
- )}
383
- </section>
384
- )
385
- }
386
-
387
- export default Carousel
@@ -1,54 +0,0 @@
1
- import React from 'react'
2
- import type { CSSProperties, PropsWithChildren, HTMLAttributes } from 'react'
3
- import type { SliderState } from '../../../hooks/useSlider/useSlider'
4
-
5
- import useSlideVisibility from './hooks/useSlideVisibility'
6
-
7
- interface CarouselItemProps extends HTMLAttributes<HTMLLIElement> {
8
- index: number
9
- totalItems: number
10
- state: SliderState
11
- infiniteMode: boolean
12
- isScrollCarousel: boolean
13
- }
14
-
15
- function CarouselItem({
16
- index,
17
- state,
18
- children,
19
- totalItems,
20
- infiniteMode,
21
- isScrollCarousel,
22
- }: PropsWithChildren<CarouselItemProps>) {
23
- const { isItemVisible, shouldRenderItem } = useSlideVisibility({
24
- totalItems,
25
- currentSlide: state.currentItem,
26
- itemsPerPage: state.itemsPerPage,
27
- })
28
-
29
- const style =
30
- ((!isScrollCarousel && { width: '100%' }) as CSSProperties) ||
31
- ((isScrollCarousel && {
32
- maxWidth: '80%',
33
- display: 'inline-block',
34
- }) as CSSProperties)
35
-
36
- const shouldDisplayItem =
37
- isScrollCarousel || shouldRenderItem(index - Number(infiniteMode))
38
-
39
- return (
40
- <li
41
- style={style}
42
- data-fs-carousel-item
43
- aria-roledescription="slide"
44
- id={`carousel-item-${index}`}
45
- data-fs-carousel-item-visible={
46
- isItemVisible(index - Number(infiniteMode)) || undefined
47
- }
48
- >
49
- {shouldDisplayItem ? children : null}
50
- </li>
51
- )
52
- }
53
-
54
- export default CarouselItem
@@ -1,59 +0,0 @@
1
- import { useRef, useEffect } from 'react'
2
-
3
- export interface UseSlideVisibilityArgs {
4
- currentSlide: number
5
- itemsPerPage: number
6
- totalItems: number
7
- }
8
-
9
- interface IsSlideVisibleArgs {
10
- itemsPerPage: number
11
- currentSlide: number
12
- slideIdx: number
13
- totalItems: number
14
- }
15
-
16
- function isSlideVisible({
17
- itemsPerPage,
18
- currentSlide,
19
- slideIdx,
20
- totalItems,
21
- }: IsSlideVisibleArgs) {
22
- const isClonedSlide = currentSlide < 0 || currentSlide >= totalItems
23
- const isVisible =
24
- slideIdx >= currentSlide && slideIdx < currentSlide + itemsPerPage
25
-
26
- return isClonedSlide || isVisible
27
- }
28
-
29
- export default function useSlideVisibility({
30
- currentSlide,
31
- itemsPerPage,
32
- totalItems,
33
- }: UseSlideVisibilityArgs) {
34
- /** Keeps track of slides that have been visualized before.
35
- * We want to keep rendering them because the issue is mostly rendering
36
- * slides that might never be viewed; On the other hand, hiding slides
37
- * that were visible causes visual glitches */
38
- const visitedSlides = useRef<Set<number>>(new Set())
39
-
40
- useEffect(() => {
41
- for (let i = 0; i < itemsPerPage; i++) {
42
- visitedSlides.current.add(currentSlide + i)
43
- }
44
- }, [currentSlide, itemsPerPage])
45
-
46
- const isItemVisible = (index: number) =>
47
- isSlideVisible({
48
- slideIdx: index,
49
- currentSlide,
50
- itemsPerPage,
51
- totalItems,
52
- })
53
-
54
- const shouldRenderItem = (index: number) => {
55
- return visitedSlides.current.has(index) || isItemVisible(index)
56
- }
57
-
58
- return { shouldRenderItem, isItemVisible }
59
- }
@@ -1,2 +0,0 @@
1
- export { default } from './Carousel'
2
- export * from './Carousel'
@@ -1,2 +0,0 @@
1
- export { default } from './useSlider'
2
- export * from './useSlider'
@@ -1,209 +0,0 @@
1
- import type { Dispatch } from 'react'
2
- import { useReducer } from 'react'
3
- import type { SwipeableProps } from 'react-swipeable'
4
- import { useSwipeable } from 'react-swipeable'
5
-
6
- export type SlideDirection = 'next' | 'previous'
7
-
8
- interface NextPageAction {
9
- type: 'NEXT_PAGE'
10
- }
11
-
12
- interface PreviousPageAction {
13
- type: 'PREVIOUS_PAGE'
14
- }
15
-
16
- interface GoToPageAction {
17
- type: 'GO_TO_PAGE'
18
- payload: {
19
- pageIndex: number
20
- shouldSlide: boolean
21
- }
22
- }
23
-
24
- interface StopSlideAction {
25
- type: 'STOP_SLIDE'
26
- }
27
-
28
- export type Action =
29
- | NextPageAction
30
- | PreviousPageAction
31
- | StopSlideAction
32
- | GoToPageAction
33
-
34
- export type SliderDispatch = Dispatch<Action>
35
-
36
- export interface SliderState {
37
- /**
38
- * The `currentItem` in a Slider with multiple items in a single page is
39
- * always **the one with the lowest index** in the current page.
40
- */
41
- currentItem: number
42
- /** Currently active page */
43
- currentPage: number
44
- /**
45
- * Whether or not the Slider is currently sliding. This is useful to
46
- * manipulate the `transition` property in a component.
47
- */
48
- sliding: boolean
49
- /** The direction in which the Slider is sliding. */
50
- slideDirection: SlideDirection
51
- /** The total number of unique items in the slider. */
52
- totalItems: number
53
- /** The number of items in a single page. */
54
- itemsPerPage: number
55
- /** The total number of pages in the slider. */
56
- totalPages: number
57
- /** Whether or not the slider is infinite. */
58
- infinite: boolean
59
- }
60
-
61
- export const nextPage = (current: number, total: number) =>
62
- (current + 1) % total
63
-
64
- export const previousPage = (current: number, total: number) =>
65
- (total - ((total - current + 1) % total)) % total
66
-
67
- function reducer(state: SliderState, action: Action): SliderState {
68
- switch (action.type) {
69
- case 'NEXT_PAGE': {
70
- // If `state.infinite` is true, we need to take into account an extra
71
- // page in the calculation. This extra page is a clone of the first page.
72
- const adjustedTotalPages = state.infinite
73
- ? state.totalPages + 1
74
- : state.totalPages
75
-
76
- const nextPageIndex = nextPage(state.currentPage, adjustedTotalPages)
77
-
78
- const nextItemIndex =
79
- (nextPageIndex % adjustedTotalPages) * state.itemsPerPage
80
-
81
- return {
82
- ...state,
83
- sliding: true,
84
- slideDirection: 'next',
85
- currentItem: nextItemIndex,
86
- currentPage: nextPageIndex,
87
- }
88
- }
89
-
90
- case 'PREVIOUS_PAGE': {
91
- // If `state.infinite` is true, we need to take into account an extra
92
- // page in the calculation. This extra page is a clone of the first page.
93
- const adjustedTotalPages = state.infinite
94
- ? state.totalPages + 1
95
- : state.totalPages
96
-
97
- // If `state.infinite` is true and we're currently on page 0, we need to
98
- // let the slider go to page -1. This -1 page is a clone of the last page.
99
- const shouldGoToClone = state.infinite && state.currentPage === 0
100
- const previousPageIndex = shouldGoToClone
101
- ? -1
102
- : previousPage(state.currentPage, state.totalPages)
103
-
104
- return {
105
- ...state,
106
- sliding: true,
107
- slideDirection: 'previous',
108
- currentItem:
109
- (previousPageIndex % adjustedTotalPages) * state.itemsPerPage,
110
- currentPage: previousPageIndex,
111
- }
112
- }
113
-
114
- case 'GO_TO_PAGE': {
115
- if (action.payload.pageIndex === state.currentPage) {
116
- return state
117
- }
118
-
119
- return {
120
- ...state,
121
- sliding: action.payload.shouldSlide,
122
- slideDirection:
123
- action.payload.pageIndex > state.currentPage ? 'next' : 'previous',
124
- currentItem:
125
- (action.payload.pageIndex % state.totalPages) * state.itemsPerPage,
126
- currentPage: action.payload.pageIndex,
127
- }
128
- }
129
-
130
- case 'STOP_SLIDE':
131
- return { ...state, sliding: false }
132
-
133
- default:
134
- return state
135
- }
136
- }
137
-
138
- const defaultSliderState = (
139
- totalItems: number,
140
- itemsPerPage: number,
141
- infinite: boolean
142
- ): SliderState => ({
143
- currentItem: 0,
144
- currentPage: 0,
145
- sliding: false,
146
- slideDirection: 'next',
147
- totalItems,
148
- itemsPerPage,
149
- totalPages: Math.ceil(totalItems / itemsPerPage),
150
- infinite,
151
- })
152
-
153
- const slide = (page: SlideDirection | number, dispatch: Dispatch<Action>) => {
154
- if (page === 'next') {
155
- dispatch({ type: 'NEXT_PAGE' })
156
- }
157
-
158
- if (page === 'previous') {
159
- dispatch({ type: 'PREVIOUS_PAGE' })
160
- }
161
-
162
- if (typeof page === 'number') {
163
- dispatch({
164
- type: 'GO_TO_PAGE',
165
- payload: {
166
- pageIndex: page,
167
- shouldSlide: true,
168
- },
169
- })
170
- }
171
- }
172
-
173
- export interface UseSliderArgs extends SwipeableProps {
174
- /** The total number of unique items in the slider. */
175
- totalItems: number
176
- /** The number of items in a single slider page. */
177
- itemsPerPage?: number
178
- /** Whether or not the slider is infinite. */
179
- infiniteMode?: boolean
180
- /** Whether or not slide after swiping left/right. */
181
- shouldSlideOnSwipe?: boolean
182
- }
183
-
184
- export default function useSlider({
185
- totalItems,
186
- itemsPerPage = 1,
187
- infiniteMode = false,
188
- shouldSlideOnSwipe = true,
189
- ...swipeableConfigOverrides
190
- }: UseSliderArgs) {
191
- const [sliderState, sliderDispatch] = useReducer(reducer, undefined, () =>
192
- defaultSliderState(totalItems, itemsPerPage, infiniteMode)
193
- )
194
-
195
- const handlers = useSwipeable({
196
- onSwipedRight: () =>
197
- shouldSlideOnSwipe && slide('previous', sliderDispatch),
198
- onSwipedLeft: () => shouldSlideOnSwipe && slide('next', sliderDispatch),
199
- trackMouse: true,
200
- ...swipeableConfigOverrides,
201
- })
202
-
203
- return {
204
- handlers,
205
- slide,
206
- sliderState,
207
- sliderDispatch,
208
- }
209
- }