• Stars
    star
    165
  • Rank 227,664 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 7 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

πŸ”₯ React Drag To Select component (tiny, touch friendly, and no dependencies!)

React DS

Tiny (7KB) React Drag-to-Select component (with no dependencies! with support for touch devices!

Travis npm Coverage Status npm npm Codacy grade

react-ds gif

I wrote this library because I couldn't find any existing one to do selections without having to wrap the items in their component.

In some cases you really need an unobtrusive way to make items selectable, this will do just that.

Installation

$ npm i react-ds

Or if you prefer yarn

$ yarn add react-ds

Usage

import Selection from 'react-ds';

// target (ref) is the parent component (so that selects only happen when clicking and dragging on it)
// elements (refs[]) is an array of refs to the components that are selectable
<Selection
    target={ ref }
    elements={ refs[] }
    onSelectionChange={ this.handleSelection }
/>

Props

target

Element where the selection should be applied to. This is to scope the mouse/touch event handlers and make sure that it doesn't affect your whole web app.

It must be a React ref, it should also exist, so you may want to check if it's already initialized before rendering the Selection component.

elements

Array of refs to the elements that are selectable. The Selection component will use this to get their location and sizes to determine whether they are within the selection area.

The should exist before rendering the Selection component.

onSelectionChange

Function that will be executed when the selection changes. An array of element indexes will be passed (with the same indexes as the elements prop).

This is where you want to update your state, to highlight them as selected for example.

onHighlightChange

While dragging, onHighlightChange is called only when the highlighted elements have changed.

When the mouse is released, it will be called with an empty array.

onHighlightChange Example

offset (Optional)

This is used to calculate the coordinates of the mouse when drawing the Selection box, since the mouse events gives coordinates relative to the document, but the Selection box may have a different parent.

Essentially you need to pass the offset of the parent element where the Selection is being rendered. If it's rendered in the same component as the items to be selected then the default value will work fine.

If passing your own offset keep in mind that getBoundingClientRect() depends on the scroll, so you may want to do something like this:

const boundingBox = target.getBoundingClientRect();
const offset = {
  top: boundingBox.top + window.scrollY,
  left: boundingBox.left + window.scrollX,
};

style (Optional)

If you want to override the styles for the selection area, you can either pass any styles here, or use css and declare any styles on the .react-ds-border class.

The styles are merged, so you can override just one property if you need (typically the zIndex).

The default styles are:

const style = {
  position: 'absolute',
  background: 'rgba(159, 217, 255, 0.3)',
  border: 'solid 1px rgba(123, 123, 123, 0.61)',
  zIndex: 9,
  cursor: 'crosshair',
}

ignoreTargets (Optional)

Specify an array of CSS3 selectors for DOM targets that should be ignored when initiating a selection. i.e. ['div', 'div > p', '#someId']

This is specially useful because react-ds uses native browser events that bypass React's event queue, so you won't be able to stopPropagation as usual.

<Selection
    target={ this.state.ref}
    elements={ this.state.elRefs }
    onSelectionChange={ this.handleSelection }
    ignoreTargets={ ['.handle'] }
/>

Example

This example was taken from example/app/src/Example.js which you can see running at https://aurbano.eu/react-ds/

import React from 'react';
import PropTypes from 'prop-types';
import Selection from 'react-ds';

export default class Example extends React.PureComponent {

  constructor() {
    super();

    this.state = {
      ref: null,
      elRefs: [],
      selectedElements: [], // track the elements that are selected
    };
  }

  handleSelection = (indexes) => {
    this.setState({
      selectedElements: indexes,
    });
  };

  getStyle = (index) => {
    if (this.state.selectedElements.indexOf(index) > -1) {
      // Selected state
      return {
        background: '#2185d0',
        borderColor: '#2185d0',
        color: 'white',
      };
    }
    return {};
  };

  addElementRef = (ref) => {
    const elRefs = this.state.elRefs;
    elRefs.push(ref);
    this.setState({
      elRefs,
    });
  };

  renderSelection() {
    if (!this.state.ref || !this.state.elRefs) {
      return null;
    }
    return (
      <Selection
        target={ this.state.ref}
        elements={ this.state.elRefs }
        onSelectionChange={ this.handleSelection }
        style={ this.props.style }
      />
    );
  }

  render() {
    const selectableElements = [
      'one',
      'another',
      'hey there',
      'item',
      'two',
      'three',
      'something longer?',
      'last'
    ];
    return (
      <div ref={ (ref) => { this.setState({ ref }); } } className='item-container'>
        { selectableElements.map((el, index) => (
          <div
            key={ el }
            ref={ this.addElementRef }
            style={ this.getStyle(index) }
            className='item'
          >
            { el }
          </div>
        )) }
        { this.renderSelection() }
      </div>
    );
  }
}

Example.PropTypes = {
  style: PropTypes.object,
};

Contributing

Only edit the files in the src folder. I'll update dist manually before publishing new versions to npm.

To run the tests simply run npm test. Add tests as you see fit to the test folder, they must be called {string}.test.js.

Meta

Copyright Β© Alejandro U. Alvarez 2017. MIT Licensed.

More Repositories

1

robinhood-node

πŸ“ˆ NodeJS client for Robinhood Trading πŸ”₯
JavaScript
696
star
2

photojshop

🎨 Photo editing JavaScript library
JavaScript
141
star
3

regex101-osx

Regex101 packaged as an offline Mac OSX application
JavaScript
76
star
4

smart-area

πŸ“ Textareas on Steroids - AngularJS 1 directive
HTML
66
star
5

nuophoto

πŸ“· Web based image editor
JavaScript
61
star
6

TreeGenerator

🌲 Trees with JavaScript, just because why not?
JavaScript
25
star
7

sonar.css

CSS3/Sass Animated Attention Seekers
CSS
17
star
8

Nebula

An HTML5+JS nebulosa effect, it displays text by making circles float inside it.
JavaScript
12
star
9

node-timespan

πŸ• Simple npm package to get human readable timespans
TypeScript
11
star
10

react-undo

React Component for easy undo/redo on any component's props
JavaScript
9
star
11

ng-multiselect

Angular directive for multiselect elements with a nice UX
JavaScript
8
star
12

bananajs

Get colors from words (give it banana, get yellow)
JavaScript
8
star
13

typesafe-fetch

Type-Safe version of fetch that uses OpenAPI TypeScript definitions to check API calls at compile type. This is really AWESOME if you call APIs from a JS frontend πŸ”₯
TypeScript
7
star
14

SplineJS

JavaScript library for numerical computing and plotting
JavaScript
5
star
15

aurbano-theme

My personal color scheme for IDEs (IntelliJ IDEA & VS Code)
5
star
16

line-art

A little experiment with animated lines trying to create an elegant visual experience.
JavaScript
5
star
17

asciimg

πŸ’» Images on your terminal - Command line tool written in Perl
Perl
5
star
18

react-dragger

Tiny React Dragging library (mobile ready)
JavaScript
5
star
19

Spirographjs

JavaScript Spirograph rendering
JavaScript
4
star
20

angular-timespan

Simple directive to get human readable timespans from any two dates
JavaScript
4
star
21

Wikiline

A global timeline created from Wikipedia
PHP
4
star
22

ash

🐚 a(lex)sh(ell) -- Remaking bash to practice modern C++ :)
C++
4
star
23

sudoku_py

Sudoku Solver in Python
Python
4
star
24

language-graph

Directed World languages graph (Only Indo-European languages for now)
JavaScript
4
star
25

html5-business-simulator

HTML5 Business Simulators for an e-Learning course
JavaScript
4
star
26

react-component-starter

Starter kit to release React components
CSS
3
star
27

ui-grid-css

Improved CSS for UI-Grid (Available as Sass or CSS)
CSS
3
star
28

angular-requirejs-seed

Starter project with Angularjs Requirejs Bower Grunt and Bootstrap
JavaScript
3
star
29

dotfiles

copy of my dotfiles
Vim Script
3
star
30

resource-path

πŸ”— Tiny module to generate /resource/:paths for APIs
JavaScript
3
star
31

HTML-Clock

⌚ Clock made with HTML5+CSS3+JS
JavaScript
3
star
32

flocking-simulation

Flock Behavior Simulation rendered in WebGL
JavaScript
3
star
33

WebVisualizer

Watch the web using WebGL (Under development)
JavaScript
3
star
34

enigma_py

Python implementation of the Enigma machine
Python
2
star
35

aurbano.eu

Personal website and blog
JavaScript
2
star
36

Runaudio

iOS app that will play music at the BPM you're currently walking/running
Swift
2
star
37

procedural-maps

Procedural Map Generator Playground
JavaScript
2
star
38

backbone-demo

Backbone, Mustache and Underscore demo
JavaScript
2
star
39

evolving-beings

ML/Reinforcement learning applied to the evolution of simple "beings"
Jupyter Notebook
2
star
40

Cloudclient

☁️ Web client for cloud services like Dropbox
PHP
2
star
41

randchess

Chess, but every piece can be customised
TypeScript
1
star
42

CaveGame

The very typical cave/chopper game, ported to iOS using iPad's Codea app
C
1
star
43

express-session-postgres

Store an Express session in Postgres (type-safe)
1
star
44

SubtitledVideo

Subtitled flv video player for the TTLM1 schema
HTML
1
star
45

QuePiensas

[Archived] Social network I worked on back in 2009
PHP
1
star
46

blink

[Under development] Real-time, unopinionated, modern web framework for node
JavaScript
1
star
47

irc-gui-java

IRC Client GUI implemented in Java
Java
1
star
48

Swarm-SimuLTE

Robotic Swarm simulation using Omnet++ and SimuLTE
1
star
49

global-npx

Run npx commands from within a Nodejs application
JavaScript
1
star
50

ios-uaf-authenticator

UAF Authenticator for iOS with TouchID support
Swift
1
star