0.3.3 • Published 5 months ago

draggables v0.3.3

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

License: MIT ts Build Status

draggables

Draggable elements.

Basic Usage

$ npm install draggables
<!-- HTML -->
<body>
   <div data-drag-role="draggable"></div>
</body>
// js / ts
import {draggables} from 'draggables';

draggables(contextElm, options);

Section Links:

Context Element

Default - document.body

NOTE: The context element is not necessarily a draggable element.

The context element is the element that listens to pointerdown events for all draggable elements within it. Each instance binds a single event listener to the context element, or to the <body> element, if ommited.

Boundary Element

To prevent draggable elements from being moved off-screen and lost, they are always confined within a boundary.

By default, this boundary is the <body> element. However, you can define a different element as the draggables container by setting it with the data-drag-zone attribute. A draggable element will be restricted to its closest ancestor with data-drag-zone or the <body> element.

During a drag, text selection is disabled by applying a user-select: none style to the boundary element.

Setting Initial Position

Draggable elements are moved using CSS translate(x, y) which offsets them relative to their natural position in the DOM (in pixels) and continuously updates as the element is dragged.

If you want a draggable element to start at a specific position (e.g. restoring a saved position after a page reload), you should set its translate style manually when rendering the element for the first time.

<div
   data-drag-role="draggable"
   style="translate: 30px -4px;"
>...</div>

Data Attributes

You can control the dragging behavior by using different data attributes.

NOTE: Boolean attributes are true when present (key only) and false when omitted.
No value is needed, simply including the attribute enables it.

Attribute NameValue
data-drag-role"draggable" | "grip"
data-drag-zoneBoolean

The following attributes can only be set on an elements that have data-drag-role set to "draggable":

Attribute NameValue
data-drag-axis"x" | "y"
data-drag-disabledBoolean

 

Details

Click to expand:

  • data-drag-axis
  • data-drag-disabled



Must be used on an element with data-drag-role="draggable"

By default you can drag elements freely on both axes. You can Limit an element's movement to a single axis.

  • "x" - Limit dragging movment along the x axis.
  • "y" - Limit dragging movment along the y axis.

Must be used on an element with data-drag-role="draggable"

Set this attribute when you need to toggle draggability of a draggable element.
This for toggling draggability of a single draggable element. If you want to disable all draggables in a context see .disable() below.


 

Example:

<div
   class="card"
   data-drag-role="draggable"
   data-drag-axis="x"
   data-drag-disabled="false"
>
   <div class="card-title" data-drag-role="grip">
      Grab here!
   </div>
   <div class="card-body">
      Grab the title to move the card
   </div>
</div>

Instance API

draggables(contextElement, options)

arguments

  • contextElement: HTMLElement = optional. See Context Element section above.
  • options: DraggablesOptions = optional. The instance's configuration object, applied for all draggable elements within the context element: padding: number - Prevents dragging if the element was grabbed within this number of pixels from any side edge. Default is 0. cornerPadding: number - Prevents dragging if the element was grabbed within this number of pixels from a corner. Default is 0.

Padding options are useful for draggable elements that are also resizable, preventing unintended drags when grabbing edges or corners.

draggables();             // -->  <body>
draggables({padding: 8}); // -->  <body>
draggables(myElm);
draggables(myElm, {padding: 8});

Returns a Draggables instance:

const d = draggables();

It has the following methods:

.enable() / .disable()

Toggle draggability for all draggable elements within the context. When disabled, the main element gets a 'drag-disabled' classname.

const d = draggables();
// draggability is enabled on construction

d.disable();
d.enable();

Note: Calling .disable() on an instance disables draggability for all draggable elements withing the context element. You can disable specific draggable elements using the disable data attribute. See Data Attributes.

.on(eventName, callback) / .off(eventName)

Start and stop listening to drag events:

  • 'grab' - fires on pointerdown on a draggable element.
  • 'dragStart' - drag started, fires on the first pointermove that crosses the threshold (3px, hardcoded).
  • 'dragging' - dragging around, fires on every pointermove except the first one.
  • 'dragEnd' - dragging ended, fires on pointerup.

A Draggables instance can only hold a single event listener for each event (unlike an EventEmitter):

const doSomething = () => {...}
const doSomethingElse = () => {...}
const stopDoingThing = () => {...}

const d = draggables()
   .on('dragStart', doSomething)     // <-- this is replaced
   .on('dragStart', doSomethingElse) // <-- by this (same event)
   .on('dragEnd', stopDoingThing)

d.off('dragStart');

Event Handlers
The event handlers get called with a DragEventWrapper object which holds 3 properties:

  • ev - the vanilla pointer event (type PointerEvent)
  • elm - the draggable element, which is not always the ev.target (type HTMLElement),
  • relPos - the draggable element's relative position (in pixels), that is, relative to its pre-drag position (type [x: number, y: number])
draggables().on('dragging', (dragEv: DragEventWrapper) => {
   console.log(
      dragEv.elm,       // e.g. <div data-drag-role="draggable">
      dragEv.ev.target, // e.g. <div data-drag-role="grip">
      dragEv.relPos     // e.g. [3, -8] (on 'grab' events it's always [0,0])
   );
});

.destroy()

Kills the Draggables instance for good, unbinds event listeners, releases element references. Once destroyed, an instance cannot be revived. Use it when the context element is removed from the DOM.

0.3.3

5 months ago

0.3.0

6 months ago

0.3.2

6 months ago

0.3.1

6 months ago

0.2.2

7 months ago

0.2.1

7 months ago

0.2.0

7 months ago