react-selection Build Status npm version

Instantly make selectable React components and containers for those components. Works in any modern browser, mobile or desktop (verified for Internet Explorer 10+, Chrome 43+, Firefox 42+, Safari 6+, iOS 7.1+, Opera 12+, Android 4.1+, Windows Phone 8.1+)

A huge thanks to Browserstack for providing an environment to ensure cross-browser, cross-OS and cross-device testing on real devices

Installation

Clone this repo or download using npm

npm install react-selection-hoc --save

Usage

Turn any React component into a container for selectable things:

  require React, { Component } from 'react'
  require { Selection } from 'react-selection-hoc'
  @Selection
  class MyComponent extends Component {
    render() {
      return <div>{this.props.children}</div>
    }
  }
Or in es6:
  require React, { Component } from 'react'
  require { Selection } from 'react-selection-hoc'
  
  class MyComponentPure extends Component {
    render() {
      return <div>{this.props.children}</div>
    }
  }
  const MyComponent = Selection(MyComponentPure)

Then, turn any React component into a thing that can be selected:

  require React, { Component } from 'react'
  require { Selectable } from 'react-selection-hoc'

  class MySelectablePureComponent extends Component {
    render() {
      return <div key={this.props.index}>{this.props.value}</div>
    }
  }
  
  const MySelectableComponent = Selectable(MySelectablePureComponent, {
  key: (props) => {
    return props.index
  },
  value: (props) => {
    return props.value
  }
})

Examples

The source:

First, the pure components that will be made into a selection container and selectable items:

import { Selection, Selectable } from 'react-selection-hoc'
import React from 'react'
import ReactDOM from 'react-dom'

class Thing extends React.Component {
  static propTypes = {
    index: React.PropTypes.number.isRequired,
    thing: React.PropTypes.string.isRequired
  }
  render() {
    return <div style={{
        width: 50,
        height: 50,
        backgroundColor: (this.props.selected ? 'green' : 'red'),
        margin: 10}}
    >
      {this.props.thing}
    </div>
  }
}

class Test extends React.Component {
  render() {
    return <div style={{width: '100%', height: 200, padding: 30, backgroundColor: '#ff8888', ...this.props.style}}>
      {this.props.children}
    </div>
  }
}

And the code to make the elements selectable, used throughout the examples:

const SelectableThing = Selectable(Thing, {
  key: (props) => {
    return props.index
  },
  value: (props) => {
    return props.thing
  }
})
const Sel = Selection(Test)

This first example shows basic usage.

  ReactDOM.render((
  <Sel constantSelect selectable>
    <SelectableThing thing="hi" index={1}/>
    <SelectableThing thing="there" index={2} />
    <SelectableThing thing="foo" index={3} />
  </Sel>
), document.getElementById('example1'))

For grids, if you want the code to select elements that are adjacent, but not within the rectangle represented by the selection, use code like this example:

const generateThing = (...i) => <SelectableThing thing={`hi${i[1]}`} index={i[1]} key={i[1]} />
const things = Array(50).fill(0).map(generateThing)

const Sel2 = Selection(Test, (a, b) => Number(a) - Number(b))

ReactDOM.render((
    <Sel2 selectable constantSelect selectIntermediates style={{display: 'flex', flexFlow: 'row wrap', width: '100%'}}>
      {things}
    </Sel2>
  ), document.getElementById('example2')
)

The final example demonstrates all of the properties that can be passed into a selection container to control its behavior.

License

MIT License