> ## Documentation Index
> Fetch the complete documentation index at: https://dndkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pointer Sensor

> Detect pointer events to initiate drag and drop operations.

## Overview

The Pointer sensor responds to [Pointer events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events) for mouse, touch, and pen input. It is enabled by default in the [DragDropManager](/concepts/drag-drop-manager).

## Usage

```ts theme={null}
import {DragDropManager} from '@dnd-kit/dom';
import {PointerSensor, PointerActivationConstraints} from '@dnd-kit/dom';

const manager = new DragDropManager({
  sensors: [
    PointerSensor.configure({
      activationConstraints: [
        // Start dragging after moving 5px
        new PointerActivationConstraints.Distance({value: 5}),
        // Or after holding for 200ms with 10px tolerance
        new PointerActivationConstraints.Delay({value: 200, tolerance: 10}),
      ],
    }),
  ],
});
```

## Activation Constraints

The Pointer sensor supports composable activation constraints through the `PointerActivationConstraints` class. Multiple constraints can be combined to create sophisticated activation behaviors.

### Distance Constraint

Activates dragging after the pointer moves a certain distance:

```ts theme={null}
import {PointerActivationConstraints} from '@dnd-kit/dom';

PointerSensor.configure({
  activationConstraints: [
    new PointerActivationConstraints.Distance({
      // Required distance in pixels
      value: 5,
      // Optional tolerance - aborts if exceeded
      tolerance: 10,
    }),
  ],
});
```

The `tolerance` option defines a movement threshold that, if exceeded, will abort the activation. This is useful for distinguishing between intentional drags and accidental movements.

### Delay Constraint

Activates dragging after holding the pointer for a duration:

```ts theme={null}
import {PointerActivationConstraints} from '@dnd-kit/dom';

PointerSensor.configure({
  activationConstraints: [
    new PointerActivationConstraints.Delay({
      // Required hold duration in ms
      value: 200,
      // Movement tolerance during delay (in pixels)
      tolerance: 5,
    }),
  ],
});
```

The `tolerance` option specifies how much the pointer can move during the delay period before the activation is aborted.

### Combining Constraints

Multiple constraints can be combined in an array. The drag operation activates when any constraint is satisfied:

```ts theme={null}
PointerSensor.configure({
  activationConstraints: [
    // Activate after 200ms delay OR 5px movement
    new PointerActivationConstraints.Delay({value: 200, tolerance: 10}),
    new PointerActivationConstraints.Distance({value: 5}),
  ],
});
```

## Default Behavior

By default, the Pointer sensor uses different activation constraints based on the pointer type and context:

* **Mouse on handle**: Immediate activation
* **Touch**: 250ms delay with 5px tolerance
* **Text inputs**: 200ms delay with 0px tolerance
* **Other pointers**: 200ms delay with 10px tolerance + 5px distance

You can customize this behavior by providing a function that returns constraints based on the event and source:

```ts theme={null}
import {PointerActivationConstraints} from '@dnd-kit/dom';

PointerSensor.configure({
  activationConstraints(event, source) {
    const {pointerType, target} = event;

    // Custom constraints based on pointer type
    switch (pointerType) {
      case 'mouse':
        return [
          new PointerActivationConstraints.Distance({value: 5}),
        ];
      case 'touch':
        return [
          new PointerActivationConstraints.Delay({value: 250, tolerance: 5}),
        ];
      default:
        return [
          new PointerActivationConstraints.Delay({value: 200, tolerance: 10}),
          new PointerActivationConstraints.Distance({value: 5}),
        ];
    }
  },
});
```

## API Reference

### Options

<ParamField path="activationConstraints" type="ActivationConstraints<PointerEvent> | (event: PointerEvent, source: Draggable) => ActivationConstraints<PointerEvent> | undefined">
  Configure when dragging should start using an array of constraint instances:

  ```ts theme={null}
  import {PointerActivationConstraints} from '@dnd-kit/dom';

  // Array of constraint instances
  type ActivationConstraints<E extends Event> = ActivationConstraint<E>[];

  // Distance type
  type Distance = number | {x?: number; y?: number};

  // Distance constraint
  new PointerActivationConstraints.Distance({
    value: number;        // Required distance in pixels
    tolerance?: Distance; // Optional abort threshold
  });

  // Delay constraint
  new PointerActivationConstraints.Delay({
    value: number;        // Required duration in ms
    tolerance: Distance;  // Movement tolerance
  });
  ```

  Can be a fixed array of constraints, a function that returns constraints based on the event and source, or `undefined` to fall back to the [defaults](#default-behavior).
</ParamField>

<ParamField path="activatorElements" type="(Element | undefined)[] | (source: Draggable) => (Element | undefined)[]">
  The elements that should listen for `pointerdown` events to initiate a drag. By default, the sensor binds to the draggable's `handle` if set, otherwise to its `element`. Use this to designate one or more alternative elements (or compute them from the source) — for example, a separate "drag" button rendered outside the draggable element.

  ```ts theme={null}
  PointerSensor.configure({
    activatorElements: (source) => [source.element?.querySelector('[data-drag-handle]')],
  });
  ```
</ParamField>

<ParamField path="preventActivation" type="(event: PointerEvent, source: Draggable) => boolean">
  Return `true` to prevent the sensor from activating for a given pointer event. Useful when you want to allow native interactions (text selection, button clicks, form input) inside a draggable element without starting a drag.

  By default, the sensor prevents activation when the pointer target is an [interactive element](https://developer.mozilla.org/en-US/docs/Web/HTML/Content_categories#interactive_content) (like `<button>`, `<input>`, `<a>`) that isn't the draggable's handle or contained by it.

  ```ts theme={null}
  PointerSensor.configure({
    preventActivation: (event, source) => {
      // Allow drags from anywhere except elements with [data-no-drag]
      return event.target instanceof Element && event.target.closest('[data-no-drag]') !== null;
    },
  });
  ```
</ParamField>

### Built-in constraints

The `PointerActivationConstraints` class provides built-in constraint primitives. You can also create your own custom activation constraints by extending the `ActivationConstraint` class.

#### Distance

Activates dragging after the pointer moves a certain distance.

##### Options for `Distance`

<ParamField path="value" type="number" required>
  Required distance in pixels.
</ParamField>

<ParamField path="tolerance" type="number | {x?: number; y?: number}" optional>
  If specified, aborts activation if movement exceeds this threshold. Can be a number or an object with optional x and y properties.
</ParamField>

#### Delay

Activates dragging after holding the pointer for a duration.

##### Options

<ParamField path="value" type="number" required>
  Required hold duration in milliseconds.
</ParamField>

<ParamField path="tolerance" type="number | {x?: number; y?: number}" optional>
  Maximum movement allowed during delay. Can be a number or an object with optional x and y properties. Exceeding this aborts activation.
</ParamField>

### Events

The Pointer sensor handles these events:

* `pointerdown`: Initial pointer contact
* `pointermove`: Pointer movement
* `pointerup`: Pointer release

The sensor automatically binds listeners across all same-origin documents, enabling drag operations across same-origin iframes.

## Touch and mobile

The Pointer sensor handles touch input on mobile devices by default — no additional setup is required.

On touch devices, dragging activates after a **250ms delay** with **5px movement tolerance**. This prevents accidental drags when scrolling. You can customize these constraints for your use case:

```ts theme={null}
PointerSensor.configure({
  activationConstraints(event) {
    if (event.pointerType === 'touch') {
      return [
        new PointerActivationConstraints.Delay({
          value: 150,    // Shorter delay for faster touch response
          tolerance: 10, // More tolerance for finger movement
        }),
      ];
    }

    return undefined; // Use defaults for mouse/pen
  },
});
```

### Best Practices

1. Use appropriate constraints for different input types:
   * Shorter delays for mouse
   * Longer delays with tolerance for touch
   * Distance constraints for precision

2. Consider accessibility:
   * Don't rely solely on hover
   * Provide clear activation feedback
   * Support keyboard input via [KeyboardSensor](/extend/sensors/keyboard-sensor)
