Skip to content

Commit

Permalink
Finish watchFocus feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjerleke committed Aug 19, 2024
1 parent 6d65558 commit 57326ab
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ function AutoScroll(userOptions: AutoScrollOptionsType = {}): AutoScrollType {
}

if (options.stopOnFocusIn) {
eventStore.add(container, 'focusin', () => {
stopScroll()
emblaApi.scrollTo(emblaApi.selectedScrollSnap(), true)
})
emblaApi.on('slideFocusStart', stopScroll)

if (!options.stopOnInteraction) {
eventStore.add(container, 'focusout', startScroll)
Expand All @@ -100,6 +97,7 @@ function AutoScroll(userOptions: AutoScrollOptionsType = {}): AutoScrollType {
emblaApi
.off('pointerDown', stopScroll)
.off('pointerUp', startScrollOnSettle)
.off('slideFocusStart', stopScroll)
.off('settle', onSettle)
stopScroll()
destroyed = true
Expand Down
7 changes: 5 additions & 2 deletions packages/embla-carousel-autoplay/src/components/Autoplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function Autoplay(userOptions: AutoplayOptionsType = {}): AutoplayType {
}

if (options.stopOnFocusIn) {
eventStore.add(container, 'focusin', stopTimer)
emblaApi.on('slideFocusStart', stopTimer)

if (!options.stopOnInteraction) {
eventStore.add(container, 'focusout', startTimer)
Expand All @@ -92,7 +92,10 @@ function Autoplay(userOptions: AutoplayOptionsType = {}): AutoplayType {
}

function destroy(): void {
emblaApi.off('pointerDown', stopTimer).off('pointerUp', startTimer)
emblaApi
.off('pointerDown', stopTimer)
.off('pointerUp', startTimer)
.off('slideFocusStart', stopTimer)
stopTimer()
destroyed = true
playing = false
Expand Down
2 changes: 1 addition & 1 deletion packages/embla-carousel/src/components/EmblaCarousel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function EmblaCarousel(
engine.translate.to(engine.location.get())
engine.animation.init()
engine.slidesInView.init()
engine.slideFocus.init()
engine.slideFocus.init(self)
engine.eventHandler.init(self)
engine.resizeHandler.init(self)
engine.slidesHandler.init(self)
Expand Down
1 change: 1 addition & 0 deletions packages/embla-carousel/src/components/EventHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface EmblaEventListType {
destroy: 'destroy'
reInit: 'reInit'
resize: 'resize'
slideFocusStart: 'slideFocusStart'
slideFocus: 'slideFocus'
}

Expand Down
46 changes: 28 additions & 18 deletions packages/embla-carousel/src/components/SlideFocus.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { EmblaCarouselType } from './EmblaCarousel'
import { EventHandlerType } from './EventHandler'
import { EventStoreType } from './EventStore'
import { ScrollBodyType } from './ScrollBody'
import { ScrollToType } from './ScrollTo'
import { SlideRegistryType } from './SlideRegistry'
import { isBoolean, isNumber } from './utils'

type FocusHandlerCallbackType = () => void
type FocusHandlerCallbackType = (
emblaApi: EmblaCarouselType,
evt: FocusEvent
) => boolean | void

export type FocusHandlerOptionType = boolean | FocusHandlerCallbackType

export type SlideFocusType = {
init: () => void
init: (emblaApi: EmblaCarouselType) => void
}

export function SlideFocus(
Expand All @@ -23,45 +27,51 @@ export function SlideFocus(
eventHandler: EventHandlerType,
watchFocus: FocusHandlerOptionType
): SlideFocusType {
const focusListenerOptions = { passive: true, capture: true }
let lastTabPressTime = 0

function init(): void {
function init(emblaApi: EmblaCarouselType): void {
if (!watchFocus) return

eventStore.add(document, 'keydown', registerTabPress, false)
slides.forEach(addSlideFocusEvent)
}

function registerTabPress(event: KeyboardEvent): void {
if (event.code === 'Tab') lastTabPressTime = new Date().getTime()
}

function addSlideFocusEvent(slide: HTMLElement): void {
const defaultFocusHandler = (): void => {
const defaultCallback = (index: number): void => {
const nowTime = new Date().getTime()
const diffTime = nowTime - lastTabPressTime

if (diffTime > 10) return

eventHandler.emit('slideFocusStart')
root.scrollLeft = 0
const index = slides.indexOf(slide)

const group = slideRegistry.findIndex((group) => group.includes(index))

if (!isNumber(group)) return

scrollBody.useDuration(0)
scrollTo.index(group, 0)

eventHandler.emit('slideFocus')
}

const focus = isBoolean(watchFocus) ? defaultFocusHandler : watchFocus
eventStore.add(document, 'keydown', registerTabPress, false)

eventStore.add(slide, 'focus', focus, {
passive: true,
capture: true
slides.forEach((slide, slideIndex) => {
eventStore.add(
slide,
'focus',
(evt: FocusEvent) => {
if (isBoolean(watchFocus) || watchFocus(emblaApi, evt)) {
defaultCallback(slideIndex)
}
},
focusListenerOptions
)
})
}

function registerTabPress(event: KeyboardEvent): void {
if (event.code === 'Tab') lastTabPressTime = new Date().getTime()
}

const self: SlideFocusType = {
init
}
Expand Down

0 comments on commit 57326ab

Please sign in to comment.