Skip to content

A Lit 3 wrapper web component that can enable robustly customizable element move operations and expose rich state data.

License

Notifications You must be signed in to change notification settings

thewebkid/lit-movable

Repository files navigation

<lit-movable> npm version License: MIT

Movable element - simple and robust. A wrapper web component that can enable customizable element move operations and expose pointer state data.

Live Demo

Since this is a Lit 3 web component, this will work inside any SPA framework. React integration docs. Framework-agnostic web components are the future!

Installation

npm i lit-movable

Basic Usage

<script type="module">
  import {LitMovable} from 'lit-movable';
</script>
<lit-movable>
  <div style="background:lightsteelblue">I am movable</div>
</lit-movable>

Attributes

  • posTop: Number - Represents the offsetTop/Left value (reflected). When set, will set the initial style.top value. Updates with move events
  • posTop: Number - Represents the offsetLeft value (reflected). When set, will set the initial style.top value. Updates with move events
  • targetSelector: String - A selector to select the element that will move. Defaults to the lit-movable (this) element, but useful when for example you want to allow a modal header to respond to pointer events but you want the entire modal to move.
  • boundsX: String: boundsX="min,max" Defaults to -Infinity,Infinity. Set to restrict movement along the x axis.
  • boundsY: String: boundsY="min,max" Defaults to -Infinity,Infinity. Set to restrict movement along the y axis.
  • vertical: String: vertical="min,max" - Will constrain horizontal (x) movement completely and allow vertical (y) movement between the specified values.
  • horizontal: String: horizontal="min,max" - Will constrain vertical (y) movement completely and allow horizontal (x) movement between the specified values.
  • grid: Number - Snaps movement to nearest grid position (defaults to 1). Initial element position represents the 0,0 position. Movement snapped to the provided value increment
  • shiftKey Bool - When enabled, holding the shift key will coerce movement to perpendicular coordinates only.
  • disabled: Bool - Disables movement behavior.
  • eventsOnly: Bool - (advanced) Only fires movement events, but will not move the element.

Events

Lit-Movable exposes events as either callback properties or the built in custom events.

Event Properties

  • onmovestart: called immediately after the pointerdown event on the element
  • onmove: called continuously while moving
  • onmoveend: called after the pointerup event on the element

Custom Events

  • movestart: fires immediately after the pointerdown event on the element
  • move: fires continuously while moving
  • moveend: fires after the pointerup event on the element

Event binding examples

<lit-movable id="myMovable"></lit-movable>
<script>
  const movableEl = document.getElementById("myMovable");
  /* Bind As property */
  movableEl.onmove = (moveState)=>{
    const {coords, clickOffset, mouseCoord, moveDist, startCoord, totalDist} = moveState;
    //all coordinates expose x,y,top,left
    console.log(coords);//Current element pos  
    console.log(clickOffset);// the position of the pointer relative to the top/left of the element
    console.log(mouseCoord); // current mouse pos on page - equivalent of pageX/pageY on a mouse event
    console.log(moveDist); //distance moved since previous move operation
    console.log(startCoord); //position of element on pointerdown
    console.log(totalDist);//distance moved from pointerdown to pointerup
  }
  /* Custom Event */
  movableEl.addEventListener('move', (event) => {
    const moveState = event.detail;
    console.log({moveState});//same state object as above
  });
</script>
 

More usage examples

Modal behavior

Parent moves when title is dragged. Used targetSelector attribute.

  <div style="height:200px;width:200px;border:solid 1px blue;" id="dialog">
    <lit-movable targetSelector="#dialog">
      <div style="background:lightsteelblue;width:100%">I am a draggable title</div>
    </lit-movable>
    I am not directly grabbable, but I will move if you grab my title.
  </div>

Horizontal only

Constrain vertical movement. Allow -50 -> 250 horizontal movement. Here are two ways to accomplish the identical behavior.

    <!-- Set horizontal movement only -->
    <lit-movable horizontal="-50,250">
      <div style="background:lightsteelblue">Move me horizontally</div>
    </lit-movable>

  <!-- OR -->
  <!-- Explicit x/y boundaries. Null string constrains an axis -->
  <lit-movable boundsX="-50,250" boundsY="null">
    <div style="background:lightsteelblue">Move me horizontally</div>
  </lit-movable>

Vertical only

Two identical ways to constrain horizontal movement, but enable broad vertical motion.

  <!-- Set vertical movement only -->
  <lit-movable vertical="-999,9999">
    <div style="background:lightsteelblue">Move me vertically</div>
  </lit-movable>
  <!-- Alternate explicit bounds (x,y) equivalent. Null = no movement enabled -->
  <lit-movable boundsY="-999,9999" boundsX="null">
    <div style="background:lightsteelblue">Move me horizontally</div>
  </lit-movable>

Snapping / shift key option enabled

Snaps to a 50px grid with shift key behavior.

  <lit-movable grid="50" shiftBehavior="true">
    <div style="background:lightsteelblue">my grid is 50 <br>(try holding shift while dragging)</div>
  </lit-movable>

Constrain both directions

Start in middle of a constrained box.

  <div style="height:200px;width:200px;border:solid 1px green;position:relative">
    <lit-movable posTop="100" posLeft="100" boundsX="-100,100" boundsY="-100,100">
      <div style="background:lightsteelblue;width:30px;margin-left:-15px;height:18px;margin-top:-9px">
        box
      </div>
    </lit-movable>
  </div>

Run local

Uses vite. Will run on node 16+ but will complain about compatibility if you are stuck on node 16 like me. Ignore this. It's fine.

git clone https://github.com/thewebkid/lit-movable.git
cd ./lit-movable
npm i
npm dev

About

A Lit 3 wrapper web component that can enable robustly customizable element move operations and expose rich state data.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published