Skip to content

Commit 42db0ee

Browse files
committed
Add SSR support to Fade plugin
1 parent 196cbdf commit 42db0ee

File tree

15 files changed

+254
-105
lines changed

15 files changed

+254
-105
lines changed

packages/embla-carousel-auto-height/src/components/AutoHeight.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { OptionsType } from './Options'
1+
import { defaultOptions, OptionsType } from './Options'
22
import {
33
EmblaEventType,
44
CreatePluginType,
@@ -17,23 +17,41 @@ export type AutoHeightType = CreatePluginType<{}, OptionsType>
1717
export type AutoHeightOptionsType = AutoHeightType['options']
1818

1919
function AutoHeight(userOptions: AutoHeightOptionsType = {}): AutoHeightType {
20+
let options: OptionsType
2021
let emblaApi: EmblaCarouselType
22+
let isSsr = false
23+
let destroyed = false
24+
2125
let slideHeights: number[] = []
2226
const heightEvents: EmblaEventType[] = ['select', 'slidefocus']
2327

28+
function pluginIsActive(): boolean {
29+
if (isSsr) return false
30+
if (destroyed) return false
31+
return options.active
32+
}
33+
2434
function init(
2535
emblaApiInstance: EmblaCarouselType,
26-
_: OptionsHandlerType,
27-
isSsr: boolean
36+
optionsHandler: OptionsHandlerType
2837
): void {
2938
emblaApi = emblaApiInstance
3039

40+
const { mergeOptions, optionsAtMedia } = optionsHandler
41+
const optionsBase = mergeOptions(defaultOptions, AutoHeight.globalOptions)
42+
const allOptions = mergeOptions(optionsBase, userOptions)
43+
44+
destroyed = false
45+
options = optionsAtMedia(allOptions)
46+
isSsr = emblaApi.internalEngine().isSsr
47+
3148
const {
3249
options: { axis },
3350
slideRects
3451
} = emblaApi.internalEngine()
3552

36-
if (isSsr || axis === 'y') return
53+
if (!pluginIsActive()) return
54+
if (axis === 'y') return
3755

3856
slideHeights = slideRects.map((slideRect) => slideRect.height)
3957

@@ -42,10 +60,13 @@ function AutoHeight(userOptions: AutoHeightOptionsType = {}): AutoHeightType {
4260
}
4361

4462
function destroy(): void {
63+
if (!pluginIsActive()) return
64+
4565
heightEvents.forEach((evt) => emblaApi.off(evt, setContainerHeight))
4666
const container = emblaApi.containerNode()
4767
container.style.height = ''
48-
if (!container.getAttribute('style')) container.removeAttribute('style')
68+
69+
destroyed = true
4970
}
5071

5172
function highestInView(): number | null {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
import { CreateOptionsType } from 'embla-carousel'
22

33
export type OptionsType = CreateOptionsType<{}>
4+
5+
export const defaultOptions: OptionsType = {
6+
active: true,
7+
breakpoints: {}
8+
}

packages/embla-carousel-auto-scroll/src/components/AutoScroll.ts

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,37 @@ export type AutoScrollOptionsType = AutoScrollType['options']
3939
function AutoScroll(userOptions: AutoScrollOptionsType = {}): AutoScrollType {
4040
let options: OptionsType
4141
let emblaApi: EmblaCarouselType
42-
let destroyed: boolean
42+
let isSsr = false
43+
let destroyed = false
44+
4345
let startDelay: number
4446
let timerId = 0
45-
let autoScrollActive = false
47+
let autoScrollRunning = false
4648
let mouseIsOver = false
4749
let defaultScrollBehaviour: ScrollBodyType
4850

51+
function pluginIsActive(): boolean {
52+
if (isSsr) return false
53+
if (destroyed) return false
54+
return options.active
55+
}
56+
4957
function init(
5058
emblaApiInstance: EmblaCarouselType,
51-
optionsHandler: OptionsHandlerType,
52-
isSsr: boolean
59+
optionsHandler: OptionsHandlerType
5360
): void {
5461
emblaApi = emblaApiInstance
5562

5663
const { mergeOptions, optionsAtMedia } = optionsHandler
5764
const optionsBase = mergeOptions(defaultOptions, AutoScroll.globalOptions)
5865
const allOptions = mergeOptions(optionsBase, userOptions)
66+
67+
destroyed = false
5968
options = optionsAtMedia(allOptions)
69+
isSsr = emblaApi.internalEngine().isSsr
6070

61-
if (isSsr || emblaApi.snapList().length <= 1) return
71+
if (!pluginIsActive()) return
72+
if (emblaApi.snapList().length <= 1) return
6273

6374
startDelay = options.startDelay
6475
destroyed = false
@@ -96,6 +107,8 @@ function AutoScroll(userOptions: AutoScrollOptionsType = {}): AutoScrollType {
96107
}
97108

98109
function destroy(): void {
110+
if (!pluginIsActive()) return
111+
99112
emblaApi
100113
.off('pointerdown', onPointerDown)
101114
.off('pointerup', onPointerUp)
@@ -104,40 +117,42 @@ function AutoScroll(userOptions: AutoScrollOptionsType = {}): AutoScrollType {
104117

105118
stopAutoScroll()
106119
destroyed = true
107-
autoScrollActive = false
120+
autoScrollRunning = false
108121
}
109122

110123
function startAutoScroll(): void {
124+
if (!pluginIsActive()) return
125+
111126
const engine = emblaApi.internalEngine()
112127
const { ownerWindow } = engine.nodeHandler
113128

114129
if (!ownerWindow) return
115-
if (destroyed) return
116-
if (autoScrollActive) return
130+
if (autoScrollRunning) return
117131
emblaApi.emit('autoscroll:play', null)
118132

119133
timerId = ownerWindow.setTimeout(() => {
120134
engine.scrollBody = createAutoScrollBehaviour(engine)
121135
engine.animation.start()
122136
}, startDelay)
123137

124-
autoScrollActive = true
138+
autoScrollRunning = true
125139
}
126140

127141
function stopAutoScroll(): void {
142+
if (!pluginIsActive()) return
143+
128144
const engine = emblaApi.internalEngine()
129145
const { ownerWindow } = engine.nodeHandler
130146

131147
if (!ownerWindow) return
132-
if (destroyed) return
133-
if (!autoScrollActive) return
148+
if (!autoScrollRunning) return
134149
emblaApi.emit('autoscroll:stop', null)
135150

136151
engine.scrollBody = defaultScrollBehaviour
137152
ownerWindow.clearTimeout(timerId)
138153
timerId = 0
139154

140-
autoScrollActive = false
155+
autoScrollRunning = false
141156
}
142157

143158
function createAutoScrollBehaviour(engine: EngineType): ScrollBodyType {
@@ -248,18 +263,18 @@ function AutoScroll(userOptions: AutoScrollOptionsType = {}): AutoScrollType {
248263
}
249264

250265
function stop(): void {
251-
if (autoScrollActive) stopAutoScroll()
266+
if (autoScrollRunning) stopAutoScroll()
252267
}
253268

254269
function reset(): void {
255-
if (autoScrollActive) {
270+
if (autoScrollRunning) {
256271
stopAutoScroll()
257272
startAutoScrollOnSettle()
258273
}
259274
}
260275

261276
function isPlaying(): boolean {
262-
return autoScrollActive
277+
return autoScrollRunning
263278
}
264279

265280
const self: AutoScrollType = {

packages/embla-carousel-autoplay/src/components/Autoplay.ts

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,41 @@ export type AutoplayOptionsType = AutoplayType['options']
4444
function Autoplay(userOptions: AutoplayOptionsType = {}): AutoplayType {
4545
let options: OptionsType
4646
let emblaApi: EmblaCarouselType
47-
let destroyed: boolean
47+
let isSsr = false
48+
let destroyed = false
49+
4850
let delay: ReturnType<EmblaCarouselType['snapList']>
4951
let timerStartTime: null | number = null
5052
let timerId = 0
51-
let autoplayActive = false
53+
let autoplayRunning = false
5254
let mouseIsOver = false
5355
let playOnDocumentVisible = false
5456
let jump = false
5557

58+
function pluginIsActive(): boolean {
59+
if (isSsr) return false
60+
if (destroyed) return false
61+
return options.active
62+
}
63+
5664
function init(
5765
emblaApiInstance: EmblaCarouselType,
58-
optionsHandler: OptionsHandlerType,
59-
isSsr: boolean
66+
optionsHandler: OptionsHandlerType
6067
): void {
6168
emblaApi = emblaApiInstance
6269

6370
const { mergeOptions, optionsAtMedia } = optionsHandler
6471
const optionsBase = mergeOptions(defaultOptions, Autoplay.globalOptions)
6572
const allOptions = mergeOptions(optionsBase, userOptions)
73+
74+
destroyed = false
6675
options = optionsAtMedia(allOptions)
76+
isSsr = emblaApi.internalEngine().isSsr
6777

68-
if (isSsr || emblaApi.snapList().length <= 1) return
78+
if (!pluginIsActive()) return
79+
if (emblaApi.snapList().length <= 1) return
6980

7081
jump = options.jump
71-
destroyed = false
7282
delay = normalizeDelay(emblaApi, options.delay)
7383

7484
const { eventStore, nodeHandler } = emblaApi.internalEngine()
@@ -108,14 +118,16 @@ function Autoplay(userOptions: AutoplayOptionsType = {}): AutoplayType {
108118
}
109119

110120
function destroy(): void {
121+
if (!pluginIsActive()) return
122+
111123
emblaApi
112124
.off('pointerdown', onPointerDown)
113125
.off('pointerup', onPointerUp)
114126
.off('slidefocusstart', stopAutoplay)
115127

116128
stopAutoplay()
117129
destroyed = true
118-
autoplayActive = false
130+
autoplayRunning = false
119131
}
120132

121133
function setTimer(): void {
@@ -139,28 +151,28 @@ function Autoplay(userOptions: AutoplayOptionsType = {}): AutoplayType {
139151
}
140152

141153
function startAutoplay(): void {
142-
if (destroyed) return
154+
if (!pluginIsActive()) return
143155
if (documentIsHidden()) {
144156
playOnDocumentVisible = true
145157
return
146158
}
147-
if (!autoplayActive) emblaApi.emit('autoplay:play', null)
159+
if (!autoplayRunning) emblaApi.emit('autoplay:play', null)
148160

149161
setTimer()
150-
autoplayActive = true
162+
autoplayRunning = true
151163
}
152164

153165
function stopAutoplay(): void {
154-
if (destroyed) return
155-
if (autoplayActive) emblaApi.emit('autoplay:stop', null)
166+
if (!pluginIsActive()) return
167+
if (autoplayRunning) emblaApi.emit('autoplay:stop', null)
156168

157169
clearTimer()
158-
autoplayActive = false
170+
autoplayRunning = false
159171
}
160172

161173
function onVisibilityChange(): void {
162174
if (documentIsHidden()) {
163-
playOnDocumentVisible = autoplayActive
175+
playOnDocumentVisible = autoplayRunning
164176
return stopAutoplay()
165177
}
166178

@@ -197,15 +209,15 @@ function Autoplay(userOptions: AutoplayOptionsType = {}): AutoplayType {
197209
}
198210

199211
function stop(): void {
200-
if (autoplayActive) stopAutoplay()
212+
if (autoplayRunning) stopAutoplay()
201213
}
202214

203215
function reset(): void {
204-
if (autoplayActive) startAutoplay()
216+
if (autoplayRunning) startAutoplay()
205217
}
206218

207219
function isPlaying(): boolean {
208-
return autoplayActive
220+
return autoplayRunning
209221
}
210222

211223
function next(): void {
@@ -227,6 +239,7 @@ function Autoplay(userOptions: AutoplayOptionsType = {}): AutoplayType {
227239
}
228240

229241
function timeUntilNext(): number | null {
242+
if (!pluginIsActive()) return null
230243
if (!timerStartTime) return null
231244
const currentDelay = delay[emblaApi.selectedSnap()]
232245
const timePastSinceStart = new Date().getTime() - timerStartTime

packages/embla-carousel-class-names/src/components/ClassNames.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ export type ClassNamesOptionsType = ClassNamesType['options']
2020
function ClassNames(userOptions: ClassNamesOptionsType = {}): ClassNamesType {
2121
let options: OptionsType
2222
let emblaApi: EmblaCarouselType
23+
let isSsr = false
24+
let destroyed = false
25+
2326
let root: HTMLElement
2427
let slides: HTMLElement[]
2528
let snappedIndexes: number[] = []
@@ -36,19 +39,27 @@ function ClassNames(userOptions: ClassNamesOptionsType = {}): ClassNamesType {
3639
loop: []
3740
}
3841

42+
function pluginIsActive(): boolean {
43+
if (isSsr) return false
44+
if (destroyed) return false
45+
return options.active
46+
}
47+
3948
function init(
4049
emblaApiInstance: EmblaCarouselType,
41-
optionsHandler: OptionsHandlerType,
42-
isSsr: boolean
50+
optionsHandler: OptionsHandlerType
4351
): void {
4452
emblaApi = emblaApiInstance
4553

4654
const { mergeOptions, optionsAtMedia } = optionsHandler
4755
const optionsBase = mergeOptions(defaultOptions, ClassNames.globalOptions)
4856
const allOptions = mergeOptions(optionsBase, userOptions)
57+
58+
destroyed = false
4959
options = optionsAtMedia(allOptions)
60+
isSsr = emblaApi.internalEngine().isSsr
5061

51-
if (isSsr) return
62+
if (!pluginIsActive()) return
5263

5364
root = emblaApi.rootNode()
5465
slides = emblaApi.slideNodes()
@@ -84,6 +95,8 @@ function ClassNames(userOptions: ClassNamesOptionsType = {}): ClassNamesType {
8495
}
8596

8697
function destroy(): void {
98+
if (!pluginIsActive()) return
99+
87100
draggingEvents.forEach((evt) => emblaApi.off(evt, toggleDraggingClass))
88101
selectedEvents.forEach((evt) => emblaApi.off(evt, toggleSnappedClasses))
89102
inViewEvents.forEach((evt) => emblaApi.off(evt, toggleInViewClasses))
@@ -98,6 +111,8 @@ function ClassNames(userOptions: ClassNamesOptionsType = {}): ClassNamesType {
98111
const key = <keyof ClassNamesListType>classNameKey
99112
classNames[key] = []
100113
})
114+
115+
destroyed = true
101116
}
102117

103118
function toggleDraggingClass(

0 commit comments

Comments
 (0)