-
-
Notifications
You must be signed in to change notification settings - Fork 193
/
useEmblaCarousel.ts
71 lines (60 loc) · 1.84 KB
/
useEmblaCarousel.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { useRef, useEffect, useState, useCallback } from 'react'
import {
areOptionsEqual,
arePluginsEqual,
canUseDOM
} from 'embla-carousel-reactive-utils'
import EmblaCarousel, {
EmblaCarouselType,
EmblaOptionsType,
EmblaPluginType
} from 'embla-carousel'
export type EmblaViewportRefType = <ViewportElement extends HTMLElement>(
instance: ViewportElement | null
) => void
export type UseEmblaCarouselType = [
EmblaViewportRefType,
EmblaCarouselType | undefined
]
function useEmblaCarousel(
options: EmblaOptionsType = {},
plugins: EmblaPluginType[] = []
): UseEmblaCarouselType {
const storedOptions = useRef(options)
const storedPlugins = useRef(plugins)
const [emblaApi, setEmblaApi] = useState<EmblaCarouselType>()
const [viewport, setViewport] = useState<HTMLElement>()
const reInit = useCallback(() => {
if (emblaApi) emblaApi.reInit(storedOptions.current, storedPlugins.current)
}, [emblaApi])
useEffect(() => {
if (areOptionsEqual(storedOptions.current, options)) return
storedOptions.current = options
reInit()
}, [options, reInit])
useEffect(() => {
if (arePluginsEqual(storedPlugins.current, plugins)) return
storedPlugins.current = plugins
reInit()
}, [plugins, reInit])
useEffect(() => {
if (canUseDOM() && viewport) {
EmblaCarousel.globalOptions = useEmblaCarousel.globalOptions
const newEmblaApi = EmblaCarousel(
viewport,
storedOptions.current,
storedPlugins.current
)
setEmblaApi(newEmblaApi)
return () => newEmblaApi.destroy()
} else {
setEmblaApi(undefined)
}
}, [viewport, setEmblaApi])
return [<EmblaViewportRefType>setViewport, emblaApi]
}
declare namespace useEmblaCarousel {
let globalOptions: EmblaOptionsType | undefined
}
useEmblaCarousel.globalOptions = undefined
export default useEmblaCarousel