npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tim-soft/react-with-gesture

v4.0.9

Published

hoc for receiving gestures

Downloads

3

Readme

npm install react-with-gesture

Ever thought about doing that sidebar pull-out, a view pager, some slider, any gesture on the web basically, and dropped the idea because it's too hard? In that case, this is your lib.

React-with-gesture is a small utility that lets you bind richer mouse and touch events to any component or view. With the data you receive it becomes trivial to set up gestures, and often takes no more than a few lines of code.

You can use it stand-alone, but to make the most of it you should combine it with an animation library like react-spring, though you can most certainly use any other.

Api

import { useGesture, withGesture, Gesture } from 'react-with-gesture'

The api is straight forward. You can use React-hooks, render-props or higher-order-components. You bind handlers to your view (done for you if you use render-props or hoc's), and you will receive events when you click/drag/pull/release it. Hooks however are preferred, since they allow gestures to be re-used for more than one view (you can use the same bind() function multiple times!).

// Full config with event handler
const bind = useGesture({ onAction: event => eventHandler, ...config })
return <div {...bind(optionalArgs)} />

// Short cut with event handler (becomes onAction + default config)
const bind = useGesture(event => eventHandler)
return <div {...bind(optionalArgs)} />

// Without onAction it will re-render the component on event changes with fresh props
const [bind, props] = useGesture({ ...config })
return <div {...bind(optionalArgs)} />

Render-props and Higher-order-components

render() {
  return (
    <Gesture {...config}>
      {event => <div />}
    </Gesture>
  )
}

@withGesture(config)
class extends React.Component {
  render() {
    const event = this.props.event
    return <div />
  }
}

withGesture(config)(Component)

Config

{ 
  touch: true,                  // accept touch input
  mouse: true,                  // accept mouse input
  passive: { passive: true },   // event handler 3rd argument input, passive by default
  onAction: undefined           // event => eventHandler, respond to events outside React's render cycle
  onMove: undefined             // event => eventHandler, respond to mousemove/touchmove events within React's render cycle
  onUp: undefined               // event => eventHandler, respond to mouseup/touchend events within React's render cycle
  onDown: undefined             // event => eventHandler, respond to touchstart/mousedown events within React's render cycle
}

Event data

{
  event,                        // source event
  target,                       // dom node
  time,                         // time tag
  initial,                      // click coordinates (vec2)
  xy,                           // page coordinates (vec2)
  previous,                     // previous page coordinates (vec2)
  delta,                        // delta offset (xy - initial) (vec2)
  direction,                    // direction normal (vec2)
  local,                        // delta with book-keeping (vec2)
  velocity,                     // drag momentuum / speed
  distance,                     // delta distance
  down,                         // mouse / touch down
  first,                        // marks first event (mouse / touch down)
  args,                         // arguments optionally passed to bind(a,b,c,d,..)
  temp,                         // arguments optionally returned by onActions eventHandler
  shiftKey,                     // shift pressed (true/false)
}

Examples

React hooks (basic drag/n/drop)

Demo: https://codesandbox.io/embed/l2wy87l28l

In this example we use useGesture's default syntax, where each change ends up re-rendering the component so that we get fresh props that we simply stick into the view. In this case we fetch local off the gesture event, which keeps track of delta positions after release. Deltas are especially important in this lib, because they make it possible to use transitions for positioning, instead of doing complex getBoundingClientRect() calculations to figure out where a node went on the screen.

const [bind, { local: [x, y] }] = useGesture()
return <div {...bind()} style={{ transform: `translate3d(${x}px,${y}px,0)` }} />

React hooks with onAction (and react-spring) (basic pull & release)

Demo: https://codesandbox.io/embed/r24mzvo3q

Re-rendering on every event can be taxing, but it can be avoided. If you are using an animation lib that can update the view outside of React (for instance react-spring or animated), then you can use the onAction syntax, which gives you a callback in which you receive events.

const [{ xy }, set] = useSpring(() => ({ xy: [0, 0] }))
const bind = useGesture(({ down, delta }) => set({ xy: down ? delta : [0, 0] }))
return (
  <animated.div
    {...bind()}
    style={{ transform: xy.interpolate((x, y) => `translate3d(${x}px,${y}px,0)`) }}
  />
)

React hooks with onAction (and react-spring) (decay)

Demo: https://codesandbox.io/embed/zq19y1xr9m

This demo reads out further data like velocity and direction to calculate decay. temp in this case is a simple storage that picks up whatever value you (optionally) return inside the event handler. It's valid as long as the gesture is active. Without this you would need to store the initial xy value somewhere else and conditionally update it when the gesture begins.

const [{ xy }, set] = useSpring(() => ({ xy: [0, 0] }))
const bind = useGesture(({ down, delta, velocity, direction, temp = xy.getValue() }) => {
  set({ 
    xy: add(delta, temp),
    immediate: down,
    config: { velocity: scale(direction, velocity), decay: true }
  })
  return temp
})
return (
  <animated.div
    {...bind()}
    style={{ transform: xy.interpolate((x, y) => `translate3d(${x}px,${y}px,0)`) }}
  />
)