Transmat

Seamless cross web interactions
Enable users to transfer data to external apps, and open your webapp to receive external data.

View on GitHub Star

Multiple payloads in a single transmit Transmat is a small library around the DataTransfer API that eases transmitting and receiving data in your web app using drag-drop and copy-paste interactions.

The DataTransfer API has the ability to transfer multiple string data payloads to any other application on the user's device. This technique is compatible with all modern desktop browsers (everything after IE11) and can be used today. It will bring your PWA to parity with native applications.

Transmat is something for you, if you...

Demo

Transmat only works on desktop browsers. Watch the demo video below.

Drag or copy the element below to a new browser window, a text editor or WYSIWYG editor.

Drag or copy me!
Containing HTML, Text, URL and JSON data.

Drop or paste here!

Getting started

  1. Install the library from NPM (version 0.2.1).

    npm install transmat

    Alternatively, you can load the index.umd.js UMD build from a JavaScript CDN like UNPKG. The library is exported to the transmat object namespace.

    <script src="https://unpkg.com/transmat/lib/index.umd.js"></script>
    <script>
      // Use transmat.addListeners, transmat.Transmat, etc...
    </script>
    

  2. Add a draggable and focusable element to your webpage.
    <div id="myElement" draggable="true" tabindex="0">
      Transmitter and receiver
    </div>
  3. Listen for transmit events on the element.
    Create a new Transmat instance for the event, and provide a object with mime-type / data.
    import {Transmat, addListeners} from 'transmat';
    
    addListeners(myElement, 'transmit', event => {
      const transmat = new Transmat(event);
      transmat.setData({
        'text/plain': 'Hello world!',
        'text/html': '<h1>Hello world!</h1>',
        'text/uri-list': 'http://example.com',
        'application/json': {foo:'bar'}
      });
    });
  4. Listen for receiving events on the element.
    Create a Transmat instance for the event, and, in this case, only accept application/json payload.
    import {Transmat, addListeners} from 'transmat';
    
    addListeners(myElement, 'receive', event => {
      const transmat = new Transmat(event);
      if (transmat.hasType('application/json') && transmit.accept()) {
        const payload = transmat.getData('application/json');
        console.log(JSON.parse(payload));
      }
    });
web.dev

Read the DataTransfer article on web.dev

Explaining the used transferring technique in detail, listing some concerns and opportunities for your applications. Learn more.


Observing transfer events

You can make use of the included TransmatObserver class to respond to drag activity. An example is at the this webpage, where the drop targets respond to the drag events.

import {TransmatObserver, Transmat} from 'transmat';

const obs = new TransmatObserver(entries => {
  for (const entry of entries) {
    const transmat = new Transmat(entry.event);
    if(transmat.hasMimeType(myCustomMimeType)) {
      entry.target.classList.toggle('drag-over', entry.isTarget);
      entry.target.classList.toggle('drag-active', entry.isActive);
    }
  }
});
obs.observe(myElement);

Minimal drag image

By default, HTML5 Drag and Drop API drag image is showing the rendered source element. When applying Transmat on top of existing drag-drop interactions you might want something more subtle instead.

Transmat comes with a small function that replaces this with a minimal alternative that still gives the feeling of dragging an object. Drag me for an example, and notice the checkered rectangle.

import {Transmat, addListeners} from 'transmat';
import {setMinimalDragImage} from 'transmat/lib/data_transfer';

addListeners(myElement, 'transmit', event => {
  const transmat = new Transmat(event);
  setMinimalDragImage(transmat.dataTransfer);
});

Connecting the web, with JSON-LD

While custom payloads are useful for communication between applications you have in your control, it also limits the ability to transfer data to external apps. JSON-LD (Linked Data) is a great universal standard for this;

JSON-LD might sound scarier than it is. Hereโ€™s an example of what this looks like for a Person:

const person = {
  '@context': 'https://schema.org',
  '@type': 'Person',
  name: 'Rory Gilmore',
  image: 'https://example.com/rory.jpg',
  address: {
    '@type': 'PostalAddress',
    addressCountry: 'USA',
    addressRegion: 'Connecticut',
    addressLocality: 'Stars Hollow'
  },
};
transmat.setData('application/ld+json', person);

Transmat comes with several JSON-LD utilities to ease common interactions with the data.

By using JSON-LD data, you will support a connected and open web. Think of all the possibilities when you could transfer elements to other applications to continue your work. That would be great, right? This starts with you! ๐Ÿ™Œ


Learn more

More documentation and examples at the GitHub repository.

This is not an officially supported Google product.