@composi/gestures:

Usage

Gestures for Mobile and Desktop

@composi/gestures is a cross-platform gesture library for desktop and mobile. Gzipped, @composi/gestures is only 1KB. It's smaller than most images you will use in your app.

@composi/gestures provides normalized events and gestures for use in your app.

Normalized Events

@composi/core provides normalized events so you don't have to worry about mousedown, touchstart, pointerdown, etc. There are four events for use:

You use these just like you would use any other event with an event listener:

const btn = document.querySelector('button')
btn.addEventListener(eventstart, () => { alert('The event started!') })

Although these enable you to use one event for desktop and touch devices, it's almost always better to use gestures. This is especially so for tap since this responds to both a click and a finger or stylus tap. This better represents what users are accumstomed to doing.

Gestures

On mobile devices users expect to be able to tap and swipe. @composi/gestures provides taps and swipes that work on both mobile and desktop, ensuring an consitent user experience across platforms. With @composi/gestures you don't have to have separate events for desktop and mobile. @composi/core provides the following gestures:

There are two ways you can use gestures, as inline events or as event listeners.

Inline Gestures

import { gestures } from '@composi/gestures'
// Initialize the gestures:
gestures()

// Define event callbacks:
function announceTap() {
  alert('You just tapped!')
}

function announceSwipe() {
  alert('You just swiped!')
}

// Define inline events:
function TappableButton(props) {
  return (
    <button ontap={() => announceTap()}>Tap</button>
  )
},

function SwipableButton(props) {
  return (
    <button onswipe={() => announceSwipe()}>Swipe</button>
  )
}

Gestures with Event Listeners

You can also use gestures with event listeners. You use them just as you would any other standard DOM event:

import { gestures } from '@composi/gestures'
// Initialize the gestures:
gestures()

const tappableBtn = document.querySelector('#tappableBtn')
tappableBtn.addEventListener('tap', function() {
  alert('You just tapped the button!')
})

About Swipe

Besides swipeleft, swiperight, swipeup and swipedown there is also a generic gesture for swipe. When you use the generic swipe event, it gets passed a data value indicating what direction the swipe was. You can use this data to determine how to handle the swipe. According to which direction the user swiped, the value will be "left", "right", "up" or "down". Notice in the following example how we announce the swipe direction through the event data attribute:

import { gestures } from '@composi/gestures'
// Initialize the gestures:
gestures()

function SwipeTest() {
  function announceSwipe(e) {
    // The swipe direction gets passed with the event
    // as the value of the property `data`:
    alert(`The swipe direction was: ${e.data}.`)
  }
  return (
    
announceSwipe(e)}>Swipe on me!
) }

By capturing and checking the event data, you can have a single swipe event handle different directions. You might do that with a toggle switch. Attach a swipe gesture to it, and when the event data is `left`, turn it on, else turn it off.

Swipes and Text Selection

If you register a swipe on an element and it or its children have any text, when the user tried to swipe it will result in a text selection. You can avoid this glitch by using @composi/gestures's `disableTextSelection` function. You import it in and the pass it the element to disable text selection on. Below we show how to do this with React. We disable text selection on the button when the `componentDidMount` lifecycle hook executes:

import { React } from 'react'
import { gestures, disableTextSelection } from '@composi/gestures'
// Initialize gestures:
gestures()

class Button extends React.Component {
  constructor(props) {
    super(props)
    this.button  = React.createRef();
  }
  render() {
    return (
      
    )
  }
  handleSwipe(e) {
    // Handle the swipe here...
  }
  componentDidMount() {
    // Disable text selection on the button:
    disableTextSelection(this.button.current)
  }
}

If you wish to disable text selection on any element, say all button tags or all elements of a class, you can use the selector followed by a second truthy value:

disableTextSelection('button', true)
// or (any string is truthy)
disableTextSelection('.swipable', 'all')

Re-enabling Text Selection

If you want to later re-enable text selection on an element that you disabled, you can import and use the `enableTextSelection` function. Import it and pass it the element to enable:

enableTextSelection('#user-list')

To re-enable many elements of the same type, you use it the same as `disableTextSelection` by passing in a tag selector or class, followed by a second truth value:

enableTextSelection('button', true)
// or (any string is truthy)
enableTextSelection('.swipable', 'yes')