#49 : Separate handlers for touchable and non toachable devices

This commit is contained in:
Vadim
2021-08-06 22:25:02 +03:00
parent ab3a66e06a
commit b66ab30a0d
7 changed files with 68 additions and 21 deletions

View File

@@ -1,25 +1,31 @@
import { createDispatcher } from '../../utils/event' import { createDispatcher } from '../../utils/event'
import { get } from '../../utils/object'
import { import {
addFocusinEventListener, addFocusinEventListener,
removeFocusinEventListener, removeFocusinEventListener,
addFocusoutEventListener, addFocusoutEventListener,
removeFocusoutEventListener, removeFocusoutEventListener
} from './event' } from './event'
export function focusable(node) { /**
const dispatch = createDispatcher(node) * focusable events are for mouse events only
*/
export function focusable(node, options) {
// pass custom dispatch fn in order to re-translate dispatched event
const dispatch = get(options, 'dispatch', createDispatcher(node))
function handleFocusin() { function handleFocusin() {
addFocusoutEventListener(node, handleFocusout)
dispatch('focused', { value: true }) dispatch('focused', { value: true })
} }
function handleFocusout() { function handleFocusout() {
dispatch('focused', { value: false }) dispatch('focused', { value: false })
removeFocusoutEventListener(node, handleFocusout)
} }
addFocusinEventListener(node, handleFocusin) addFocusinEventListener(node, handleFocusin)
addFocusoutEventListener(node, handleFocusout)
return { return {
destroy() { destroy() {
removeFocusinEventListener(node, handleFocusin) removeFocusinEventListener(node, handleFocusin)

View File

@@ -0,0 +1 @@
export * from './pausable'

View File

@@ -0,0 +1,27 @@
import { createDispatcher, getIsTouchable } from '../../utils/event'
import { focusable } from '../focusable'
import { tappable } from '../tappable'
export function pausable(node) {
const dispatch = createDispatcher(node)
if (getIsTouchable()) {
return tappable(node, {
dispatch: (_, payload) => {
dispatch('pausedToggle', {
isTouchable: true,
...payload
})
}
})
}
return focusable(node, {
dispatch: (_, payload) => {
dispatch('pausedToggle', {
isTouchable: false,
...payload
})
}
})
}

View File

@@ -1,4 +1,5 @@
import { createDispatcher } from '../../utils/event' import { createDispatcher } from '../../utils/event'
import { get } from '../../utils/object'
import { import {
addFocusinEventListener, addFocusinEventListener,
removeFocusinEventListener, removeFocusinEventListener,
@@ -7,23 +8,29 @@ import {
} from './event' } from './event'
import { TAP_DURATION_MS } from '../../units' import { TAP_DURATION_MS } from '../../units'
export function tappable(node) { /**
const dispatch = createDispatcher(node) * tappable events are for touchable devices only
*/
export function tappable(node, options) {
// pass custom dispatch fn in order to re-translate dispatched event
const dispatch = get(options, 'dispatch', createDispatcher(node))
let tapStartedAt = 0 let tapStartedAt = 0
function handleTapstart() { function handleTapstart() {
tapStartedAt = Date.now() tapStartedAt = Date.now()
addFocusoutEventListener(node, handleTapend)
} }
function handleTapend() { function handleTapend() {
removeFocusoutEventListener(node, handleTapend)
if (Date.now() - tapStartedAt <= TAP_DURATION_MS) { if (Date.now() - tapStartedAt <= TAP_DURATION_MS) {
dispatch('tapped') dispatch('tapped')
} }
} }
addFocusinEventListener(node, handleTapstart) addFocusinEventListener(node, handleTapstart)
addFocusoutEventListener(node, handleTapend)
return { return {
destroy() { destroy() {
removeFocusinEventListener(node, handleTapstart) removeFocusinEventListener(node, handleTapstart)

View File

@@ -6,8 +6,7 @@
import Progress from '../Progress/Progress.svelte' import Progress from '../Progress/Progress.svelte'
import { NEXT, PREV } from '../../direction' import { NEXT, PREV } from '../../direction'
import { swipeable } from '../../actions/swipeable' import { swipeable } from '../../actions/swipeable'
import { focusable } from '../../actions/focusable' import { pausable } from '../../actions/pausable'
import { tappable } from '../../actions/tappable'
import { import {
addResizeEventListener, addResizeEventListener,
removeResizeEventListener removeResizeEventListener
@@ -304,12 +303,13 @@
showPage(currentPageIndex) showPage(currentPageIndex)
} }
function handleFocused(event) { function handlePausedToggle(event) {
if (event.detail.isTouchable) {
focused = !focused
return
}
focused = event.detail.value focused = event.detail.value
} }
function handleTapped() {
focused = !focused
}
</script> </script>
<div class="sc-carousel__carousel-container"> <div class="sc-carousel__carousel-container">
@@ -328,11 +328,9 @@
<div <div
class="sc-carousel__pages-window" class="sc-carousel__pages-window"
bind:this={pageWindowElement} bind:this={pageWindowElement}
use:focusable
on:focused={handleFocused}
use:tappable use:pausable
on:tapped={handleTapped} on:pausedToggle={handlePausedToggle}
> >
<div <div
class="sc-carousel__pages-container" class="sc-carousel__pages-container"

View File

@@ -1,3 +1,3 @@
export const TAP_DURATION_MS = 200 export const TAP_DURATION_MS = 110
export const SWIPE_MIN_DURATION_MS = 201 export const SWIPE_MIN_DURATION_MS = 111
export const SWIPE_MIN_DISTANCE_PX = 20 export const SWIPE_MIN_DISTANCE_PX = 20

View File

@@ -16,3 +16,11 @@ export function createDispatcher(source) {
} }
return dispatch return dispatch
} }
export function getIsTouchable() {
return (
('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0)
)
}