Skip to content

Commit

Permalink
feat: allow slider to be initialized in empty state
Browse files Browse the repository at this point in the history
  • Loading branch information
p-m-p committed Sep 1, 2024
1 parent 6ec877f commit a9f9511
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 33 deletions.
6 changes: 6 additions & 0 deletions .changeset/shaggy-swans-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@boxslider/components': minor
'@boxslider/slider': minor
---

Core slider no longer throws error if initialized without slides and calling any transition method will not update the state or attempt to transition. Invalid calls to next or prev etc will return an immediately resolved promise.
43 changes: 38 additions & 5 deletions packages/components/src/SliderControls/SliderControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export default class SliderControls
#sliderElement!: SliderElement
#mutationObserver: MutationObserver
#hasBeenInteractedWith = false
#sliderEventListeners: Record<string, EventListener> = {}

constructor() {
super()
Expand Down Expand Up @@ -147,13 +148,45 @@ export default class SliderControls
})

this.#setPlayBtnState()
this.#sliderElement.addEventListener('play', () =>
this.#setPlayBtnState(),

if (this.#sliderEventListeners.play) {
this.#sliderElement.removeEventListener(
'play',
this.#sliderEventListeners.play,
)
}

if (this.#sliderEventListeners.reset) {
this.#sliderElement.removeEventListener(
'reset',
this.#sliderEventListeners.reset,
)
}

if (this.#sliderEventListeners.pause) {
this.#sliderElement.removeEventListener(
'pause',
this.#sliderEventListeners.pause,
)
}

this.#sliderEventListeners.play = () => this.#setPlayBtnState()
this.#sliderElement.addEventListener(
'play',
this.#sliderEventListeners.play,
)

this.#sliderEventListeners.pause = () => this.#setPlayBtnState()
this.#sliderElement.addEventListener(
'pause',
this.#sliderEventListeners.pause,
)
this.#sliderElement.addEventListener('pause', () =>
this.#setPlayBtnState(),

this.#sliderEventListeners.reset = () => this.#init()
this.#sliderElement.addEventListener(
'reset',
this.#sliderEventListeners.reset,
)
this.#sliderElement.addEventListener('reset', () => this.#init())

this.#addIndexPips()
this.#sliderElement.addEventListener(
Expand Down
27 changes: 15 additions & 12 deletions packages/components/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,12 @@ class CustomSlider extends Slider {
customElements.define('custom-slider', CustomSlider)

document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
<button id="add-slides">Add Slides</button>
<button id="add-slides">Add Slide</button>
<button id="remove-slides">Remove Slide</button>
<div class="sliders">
<bs-slider-controls>
<custom-slider auto-scroll="true" timeout="1000" speed="300" class="full-carousel" id="custom">
<div class="slide">Slide One</div>
<div class="slide">Slide Two</div>
<div class="slide">Slide Three</div>
<div class="slide">Slide Four</div>
<div class="slide">Slide Five</div>
</custom-slider>
</bs-slider-controls>
Expand Down Expand Up @@ -134,9 +130,16 @@ document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
</div>
`

setTimeout(() => {
document.getElementById('add-slides')!.addEventListener('click', () => {
const custom = document.getElementById('custom')
custom!.innerHTML += '<div class="slide">Slide Six</div>'
})
}, 1000)
let slides = 0

document.getElementById('add-slides')!.addEventListener('click', () => {
slides += 1
const custom = document.getElementById('custom')
custom!.innerHTML += `<div class="slide" id="slide-${slides}">Slide ${slides}</div>`
})

document.getElementById('remove-slides')!.addEventListener('click', () => {
const custom = document.getElementById('custom')
custom!.removeChild(document.getElementById(`slide-${slides}`)!)
slides -= 1
})
31 changes: 15 additions & 16 deletions packages/slider/src/box-slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,10 @@ export default class BoxSlider {
}
this._activeIndex = this.options.startIndex
this.init(effect)

if (this.slides.length < this.activeIndex) {
this.destroy()
throw new Error(
`Start index option is out of bounds - slides=${this.slides.length} start=${this.activeIndex}`,
)
}

this.applyEventListeners()

responder.add(this)

this.emit('init')
}

Expand Down Expand Up @@ -284,6 +278,10 @@ export default class BoxSlider {
this.slides = this.getSlides()
this.stateStore.storeAttributes([this.el, ...this.slides], ['style'])

if (this.activeIndex >= this.slides.length) {
this._activeIndex = 0
}

this.effect.initialize(
this.el,
this.slides,
Expand Down Expand Up @@ -336,17 +334,18 @@ export default class BoxSlider {
}

private transitionTo(nextIndex: number, backwards: boolean): Promise<void> {
return new Promise((resolve, reject) => {
if (this.isDestroyed || nextIndex === this.activeIndex) {
return resolve()
}
return new Promise((resolve) => {
this.stopAutoScroll()

if (nextIndex < 0 || nextIndex >= this.slides.length) {
return reject(new Error(`${nextIndex} is not a valid slide index`))
if (
this.isDestroyed ||
nextIndex === this.activeIndex ||
nextIndex < 0 ||
nextIndex >= this.slides.length
) {
return resolve()
}

this.stopAutoScroll()

const settings = {
el: this.el,
slides: this.slides,
Expand Down

0 comments on commit a9f9511

Please sign in to comment.