use-gesture

website·Indexed 29 days ago

https://use-gesture.netlify.app/

A library for binding mouse and touch events to any node, making complex gestures such as drag, pinch, move, wheel, and scroll easy to configure. Available for both React and Vanilla JS, it provides a set of gesture handlers and utility functions to simplify mobile-friendly UI development.

Tokens
9.2K
Snippets
46
Records
78
Agent score
74%

What's inside use-gesture

  1. Overview of @use-gesture library

    @use-gesture is a gesture library for React designed to implement advanced UI interactions such as moving, zooming, dragging, scrolling, and pinching with minimal code. It is highly configurable and compatible with any animation framework, specifically operating well with React Spring and React Three Fiber.
  2. Overview of @use-gesture capabilities

    @use-gesture is a library designed to simplify the configuration of complex gestures such as dragging and pinching. It provides a high-level API (e.g., onDrag) that is as easy to implement as native mouse events while maintaining full control over the gesture logic.

    Key benefits include:

    • Kinematics Augmentation: Provides additional attributes not found in native browser events, such as velocity, distance, and delta.
    • Event Optimization: Automatically debounces scroll, wheel, and move events.
    • Lifecycle Management: Built-in capacity to trigger specific logic when a gesture starts or ends.
  3. Optimize gesture performance using react-spring

    To avoid performance degradation caused by re-rendering components on every gesture frame, use react-spring instead of React.useState. react-spring allows for animating components without triggering React render cycles.
  4. Migrate to useGesture Hooks API (v5.0.0+)

    Starting with version 5.0.0, use-gesture dropped support for Higher-Order Components (HOC) and render-props, requiring React 16.8+. The API shifted from a return-array syntax to a single return value for better performance. The config object must now be passed as the second argument rather than inside the actions object.
    // OLD: [bind, props] = useGesture({ onAction: () => {}, config })
    
    // NEW: 
    const bind = useGesture({ onDrag: () => { /* handler */ } }, { /* config options */ });
  5. Enable dragging for images and links

    Dragging images or links often interferes with native browser drag-and-drop behavior. To fix this, apply specific CSS to disable user selection and browser dragging, and call event.preventDefault() within the gesture handler.
    img.drag {
      touch-action: none;
      -moz-user-select: none;
      -webkit-user-drag: none;
      user-select: none;
    }
    useDrag(({ event, ...state }) => {
      event.preventDefault()
      // rest of your gesture logic
    })
  6. Imperatively cancel a gesture

    The cancel() function can be called within a handler to stop the current gesture. This is only supported for drag and pinch gestures.
    function CancelExample() {
      const [{ x }, api] = useSpring(() => ({ x: 0 }))
      const bind = useDrag(({ active, movement: [mx], cancel }) => {
        if (mx > 200) cancel()
        api.start({ x: active ? mx : 0, immediate: active })
      })
      return <animated.div {...bind()} style={{ x }} />
    }
    
  7. Migrate from react-use-gesture to @use-gesture/react

    The react-use-gesture package has been replaced by @use-gesture/react. While the API remains largely the same (approximately 95% compatibility), users must update their package imports and account for specific breaking changes in the configuration options.
  8. Create a custom useGesture hook for React to reduce bundle size

    To avoid importing all available gestures and reduce the gzipped JavaScript bundle size, you can create a custom useGesture hook by passing only the specific actions you need to createUseGesture. The resulting hook accepts a configuration object with event handlers (e.g., onDrag, onDragStart, onDragEnd) and an optional config object for gesture-specific settings.
    import { createUseGesture, dragAction, pinchAction } from '@use-gesture/react'
    
    // Create a custom hook with only drag and pinch support
    const useGesture = createUseGesture([dragAction, pinchAction])
    
    function MyComponent() {
      const bind = useGesture(
        {
          onDrag: (state) => doSomethingWith(state),
          onDragStart: (state) => doSomethingWith(state),
          onDragEnd: (state) => doSomethingWith(state),
          onPinch: (state) => doSomethingWith(state),
          onPinchStart: (state) => doSomethingWith(state),
          onPinchEnd: (state) => doSomethingWith(state)
        },
        { drag: dragConfig, pinch: pinchConfig }
      )
    
      return <div {...bind()} />
    }
  9. Migrate useGesture configuration to version 7.0.0

    Version 7.0.0 introduced a full rewrite that changes how options are structured. Options for useGesture are now separated per gesture, and event options have been restructured. Specifically, dragDelay has been renamed to delay and moved inside the drag configuration object.
    // BEFORE (v6)
    useGesture(fn, {
      enabled: true,
      event: { passive: true, capture: false },
      pointerEvents: true,
      wheel: false,
      dragDelay: 100
    })
    
    // AFTER (v7)
    useGesture(fn, {
      enabled: true,
      eventOptions: { passive: true, capture: false, pointer: true },
      wheel: {
        enabled: false
      },
      drag: {
        delay: 100
      }
    })
    
    // Alternatively, using the shorthand hook:
    useDrag(fn, {
      eventOptions: { passive: true, capture: false, pointer: true },
      delay: 100
    })
  10. Import useGesture in React projects

    As of version 5.0.0-beta.8, the default export was removed to align with TypeScript imports. You must use a named import from the @use-gesture/react package.
    import { useGesture } from '@use-gesture/react';
  11. Differentiate between movement and offset

    Relative values are preferred for CSS transforms.

    • movement: The displacement of the current gesture. It resets to [0,0] every time a new gesture starts. Use this when an element should snap back to its original position after release.
    • offset: The cumulative sum of all gesture movements on the same component. Use this when an element should stay where the user left it.
    // Example: Component stays where you left it using offset
    function OffsetExample() {
      const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 }))
      const bind = useDrag(({ offset: [x, y] }) => api.start({ x, y }))
      return <animated.div {...bind()} style={{ x, y }} />
    }
    
  12. Disable body scrolling for overlays with body-scroll-lock

    When implementing menu overlays or modals where the body should not scroll while the overlay is active, use the body-scroll-lock library. It is recommended to first check if the issue can be solved using the CSS touch-action property before introducing this library.