Giter VIP home page Giter VIP logo

react-selectable's Introduction

Selectable items for React

Allows individual or group selection of items using the mouse.

Demo

Try it out

Upgrading from 0.1 to 0.2

There have been significant changes in the 0.2 release. Please read about them here.

Getting started

npm install react-selectable
import React from 'react';
import { render } from 'react-dom';
import { SelectableGroup, createSelectable } from 'react-selectable';
import SomeComponent from './some-component';

const SelectableComponent = createSelectable(SomeComponent);

class App extends React.Component {

  constructor (props) {
  	super(props);
  	this.state = {
  		selectedKeys: []
  	};
  }

  handleSelection (selectedKeys) {
  	this.setState({ selectedKeys });
  }

  render () {
    return (
      <SelectableGroup onSelection={this.handleSelection}>
        {this.props.items.map((item, i) => {
          	let selected = this.state.selectedKeys.indexOf(item.id) > -1;
          	return (
          		<SelectableComponent key={i} selected={selected} selectableKey={item.id}>
          			{item.title}
          		</SelectableComponent>
          	);
        })}
      </SelectableGroup>
    );
  }

}

Configuration

The <SelectableGroup /> component accepts a few optional props:

  • onBeginSelection(event) (Function) Callback fired when the selection was started.
  • onSelection(items, event) (Function) Callback fired while the mouse is moving. Throttled to 50ms for performance in IE/Edge.
  • onEndSelection(items, event) (Function) Callback fired after user completes selection.
  • onNonItemClick(event) (Function) Callback fired when a click happens within the selectable group component, but not in a selectable item. Useful for clearing selection.
  • tolerance (Number) The amount of buffer to add around your <SelectableGroup /> container, in pixels.
  • component (String) The component to render. Defaults to div.
  • fixedPosition (Boolean) Whether the <SelectableGroup /> container is a fixed/absolute position element or the grandchild of one. Note: if you get an error that Value must be omitted for boolean attributes when you try <SelectableGroup fixedPosition={true} />, simply use Javascript's boolean object function: <SelectableGroup fixedPosition={Boolean(true)} />.
  • preventDefault (Boolean) Allows to enable/disable preventing the default action of the onmousedown event (with e.preventDefault). True by default. Disable if your app needs to capture this event for other functionalities.
  • enabled (Boolean) If false, all of the selectable features are disabled, and event handlers removed.
  • className (String) A CSS class to add to the containing element.
  • selectingClassName (String) A CSS class to add to the containing element when we select.

Decorators

Though they are optional, you can use decorators with this react-selectable.

A side by side comparison is the best way to illustrate the difference:

Without Decorators

class SomeComponent extends Component {

}
export default createSelectable(SomeComponent)

vs.

With Decorators

@createSelectable
export default class SomeComponent extends Component {

}

In order to enable this functionality, you will most likely need to install a plugin (depending on your build setup). For Babel, you will need to make sure you have installed and enabled babel-plugin-transform-decorators-legacy by doing the following:

  1. run npm i --save-dev babel-plugin-transform-decorators-legacy
  2. Add the following line to your .babelrc:
{
  "plugins": ["transform-decorators-legacy"]
}

react-selectable's People

Contributors

aslamplr avatar bergice avatar bortexz avatar danilvalov avatar destos avatar flamerohr avatar isaacdalmarco avatar kgantsov avatar kreozot avatar leopoldjoy avatar lukavyi avatar maxime-rainville avatar rexpan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-selectable's Issues

Click events within selectable component

Love this library, thanks so much for the hard work in it. I have a question around click events within a selectable component, in that unless you have a really steady hand it won't register the click event but instead will start drawing the bounding box.

I have previously got round this with JqueryUI by adding a "distance" attribute - one that I saw you had removed from version 1 - but not sure if its the same in that it would be the distance in pixels from when the mouse down event took place before it began drawing the bounding box. This enabled other events on the selectable item to fire.

Or have I missed something else in the docs or options that will enable the events?

Item of the selection start

Thank you for this great library! I would like to ask if it would be possible to get the item from where the selection started. As i saw right now the selectedItems[0] always returns the item from the top left corner. It could start getting the selection items from where the user started his selection.

[Suggestion] Make Component Work With SVG

Hi,
I've been trying to make this component work with SVGs and found a series of small changes to the package that would help. Of course, I could fork this repository, make my changes there, and use that but I figured I'd note my findings here in case supporting SVG is a direction the core team wants to consider.

The main roadblocks for getting SVG to work with this component are twofold.

  1. Currently the "doObjectsCollide" method only correctly handles HTMLElements despite the function being easily generalize-able to Elements, which includes SVGElements, with some minor tweaks. Those tweaks include changing "doObjectsCollide" to expect and check for instances of Elements, as well as changing "getBoundsForNode" to the below:
    image
    This change is needed because SVG doesn't support node.offsetWidth/node.offsetHeight anymore.

  2. Like the repo already allows for the component tag to be modified from "div", selectable items will need a way to change the tag of the enclosing element. This should be a reasonably simple change, as the extra "component" attribute can follow the same pattern as "selectableKey" does.

Perhaps this added functionality has already been thought of and dismissed as out of scope, though I cannot imagine why. Let me know what you think.
Thanks.

"ReferenceError: React is not defined"

Hello,

Finally got react-selectable installed this morning, however now I'm getting an error that "React is not defined" when I try to run the application. Here's the error:

can't execute file: /pathToApp/bin/server.js
error given was: ReferenceError: React is not defined
    at Object.module.exports (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:414:19)
    at __webpack_require__ (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:21:30)
    at Object._interopRequire (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:78:30)
    at __webpack_require__ (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:21:30)
    at Object._interopRequire (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:52:40)
    at __webpack_require__ (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:21:30)
    at _interopRequire (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:41:18)
    at Object.<anonymous> (/pathToApp/node_modules/react-selectable/dist/react-selectable.js:44:10)
    at Module._compile (module.js:413:34)
    at Module._extensions..js (module.js:422:10)
    at require.extensions.(anonymous function) (/pathToApp/node_modules/babel-core/lib/api/register/node.js:214:7)
    at Object._module3.default._extensions.(anonymous function) [as .js] (/pathToApp/node_modules/require-hacker/babel-transpiled-modules/require hacker.js:250:71)
further repeats of this error will be suppressed...
can't execute file: /pathToApp/bin/server.js
error given was: Error: File extension "jpeg" is already occupied by require-hacker
    at Object.extension (/pathToApp/node_modules/require-hacker/babel-transpiled-modules/require hacker.js:342:10)
    at Object.hook (/pathToApp/node_modules/require-hacker/babel-transpiled-modules/require hacker.js:202:12)
    at webpack_isomorphic_tools.register_extension (/pathToApp/node_modules/webpack-isomorphic-tools/babel-transpiled-modules/index.js:304:47)
    at webpack_isomorphic_tools.register (/pathToApp/node_modules/webpack-isomorphic-tools/babel-transpiled-modules/index.js:278:10)
    at webpack_isomorphic_tools.server (/pathToApp/node_modules/webpack-isomorphic-tools/babel-transpiled-modules/index.js:182:8)
    at Object.<anonymous> (/pathToApp/bin/server.js:27:30)
    at Module._compile (module.js:413:34)
    at normalLoader (/pathToApp/node_modules/babel-core/lib/api/register/node.js:199:5)
    at require.extensions.(anonymous function) (/pathToApp/node_modules/babel-core/lib/api/register/node.js:216:7)
    at Object._module3.default._extensions.(anonymous function) [as .js] (/pathToApp/node_modules/require-hacker/babel-transpiled-modules/require hacker.js:250:71)
further repeats of this error will be suppressed...
(node) warning: possible EventEmitter memory leak detected. 11 disconnect listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at process.addListener (events.js:252:17)
    at process.once (events.js:278:8)
    at Worker.destroy (cluster.js:678:13)
    at Worker.__dirname.Worker.options.process.on.Worker.kill (cluster.js:47:16)
    at process.<anonymous> (/pathToApp/node_modules/piping/lib/launcher.js:49:27)
    at emitOne (events.js:90:13)
    at process.emit (events.js:182:7)
    at process._fatalException (node.js:256:26)
Hash: 4dcb6f472d28ae476097
Version: webpack 1.12.13
Time: 78744ms`

Any ideas what could be causing this?

A way to select selectable Items with enzyme

Having difficulty selecting my selectable elements for testing using enzyme. If I use .find(createComponent(componentToTest)), I am told this element doesn't exist. I can only manually find selectable components using props().children on the SelectableGroup component

Unknown props `onSelection`, ...., on <div> tag. Remove these props from the element.

When creating the child element with the component specified, it throws the following warning:

Warning: Unknown props `onSelection`, `fixedPosition`, `selectOnMouseMove`, `component`, `tolerance` on <div> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop

This is because the module is passing all the props that are managed by the SelectableGroup down to the child of the original element. I have been able to fix that by doing the following:

        const newProps = Object.assign({}, this.props);
        delete newProps.onSelection;
        delete newProps.fixedPosition;
        delete newProps.selectOnMouseMove;
        delete newProps.component;
        delete newPorps.tolerance;

        return (
            <this.props.component {...newProps}>
                {this.state.isBoxSelecting &&
                  <div style={boxStyle} ref="selectbox"><span style={spanStyle}></span></div>
                }
                {this.props.children}
            </this.props.component>
        );

Object.assign() has compatibility with latest browsers, but not with IE.

Other options would be to use lodash.assign or even implement a custom method to remove the properties.

Let me know what works best for the project, and I can make a PR myself.

Unable to Install with Node 4.1.1 and NPM 3.5.3

When I try to install react-selectable into my ReactJS application using:

npm install react-selectable

I get this error:

[email protected] /pathToApp/
├─┬ [email protected]
│ └─┬ [email protected]
│   └─┬ [email protected]
│     └─┬ [email protected]
│       └─┬ [email protected]
│         └── [email protected] 
├── [email protected] 
├── [email protected] 
├── [email protected] 
├── [email protected]  extraneous
├── [email protected] 
├── [email protected]  extraneous
└── [email protected]  extraneous

npm WARN enoent ENOENT: no such file or directory, open '/pathToApp/node_modules/acorn-globals/package.json'
npm WARN enoent ENOENT: no such file or directory, open '/pathToApp/node_modules/escodegen/package.json'
npm WARN enoent ENOENT: no such file or directory, open '/pathToApp/node_modules/spawn-sync/package.json'
npm ERR! Darwin 13.2.0
npm ERR! argv "/usr/local/Cellar/node/5.5.0/bin/node" "/usr/local/bin/npm" "install" "react-selectable"
npm ERR! node v5.5.0
npm ERR! npm  v3.5.3
npm ERR! path /pathToApp/node_modules/react-selectable/node_modules/webpack/bin/webpack
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! syscall chmod

npm ERR! enoent ENOENT: no such file or directory, chmod '/pathToApp/node_modules/react-selectable/node_modules/webpack/bin/webpack'
npm ERR! enoent ENOENT: no such file or directory, chmod '/pathToApp/node_modules/react-selectable/node_modules/webpack/bin/webpack'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! Please include the following file with any support request:
npm ERR!     /pathToApp/npm-debug.log

I'm not sure why I'm getting this, any ideas?

Make e.preventDefault on mousedown optional

I have a use case where the e.preventDefault() at the end of the onmousedown handler is preventing my program to do as expected.

It's a rare use case, I need to listen to the onFocus event on the parent container, and the e.preventDefault causes it not to fire so I can't detect the onFocus.

Could we make it optional, true by default? If you want to have a look, I've already done this in my fork (https://github.com/bertofer/react-selectable). Waiting for #17 to be merged as the solution for this one assumes the previous one.

Newest version not published on npm ?

Hi,

I have been trying to use selectOnMouseMove, but it doesn't appear to have been published in the version in npm. Navigating through the _openSelector code, this line is missing at the end:

if (this.props.selectOnMouseMove) this._throttledSelect();

I am working on a File Manager application for desktop, this module saved my day! 👍

Switch component prop blacklist to a whitelist

At the moment we have:

const filteredProps = Object.assign({}, this.props);
        delete filteredProps.onSelection;
        delete filteredProps.fixedPosition;
        delete filteredProps.selectOnMouseMove;
        delete filteredProps.component;
        delete filteredProps.tolerance;
        delete filteredProps.preventDefault;

However we end up with errors still.

image

I suggest to change this to a filtered whitelist of properties that can be safely passed to any component.

wrong calculations when fixedPosition=true

After commit bb9c450 (Fix positioning of drag box) the use of fixed position is wrong.

I think that this small change is fixing the problem:

// selectable-group.js
_getInitialCoordinates() {
	if (this.props.fixedPosition) {
		return { x: 0, y: 0 }
	}
	//... rest of code ...
}

This reverses the effects of the change when using fixedPosition=true

I tested this code and it seems to work O.k

BTW it may also fix the problem in #30

ES7 decorator example request

Can I use the createSelectable(cmp) as an ES7 decorator? I need to chain the decorators as I want to use this library in combination with the react-dnd higher order component.

Dist is full example

Hi there!
I'm looking to using this in our project and I'm wondering what the best way to add it to our project is. We're excluding node_modules/ from the JSX parsing for performance (don't want to pipe all that through Babel), which means that var Selectable = require("react-selectable"); complains about unparsed JSX.
I tried doing var Selectable = require("../../../../node_modules/react-selectable/dist/bundle.js"); but that pulls in the whole example app.

Do you think it'd be a good idea to provide a ready built JS file for people to use?

Thanks!

UPDATE: this seems like a good resource on this matter: http://chadly.net/2015/04/publishing-react-to-npm/

Legacy context API

Legacy context API has been detected within a strict-mode tree.

The old API will be supported in all 16.x releases, but applications using it should migrate to the new version.

Please update the following components: n, t

Can it be used with tables?

I want to use this library to select rows in the table for further actions. I can describe component type for SelectableGroup, for example, tbody. But I can't set component type for SelectableComponent, it's always div. So I have error <tr> cannot appear as a child of <div>. Is there any way to handle it?

Not able to understand how to use and customize

How can I use this, there are no example for this, what goes into SelectableComponent?

And if I want to customize it like I don't want to show the selection box, how can I do that?

Can anyone help me with that?

Single selection click

As can be seen in the demo, selecting a single element doesn't work unless coming in from another window.

Quick question about click position on selection

Is there a way to manipulate the click position getter method? I tried changing the position of SelectableGroup tag to exactly correct place but it didn't help, it still calculates offset values from the left corner of document and drawing the selection using those numbers from the left corner of my div

image

In the above screenshot, my div is separated from the left corner of the document exactly the same amount as in their differences.

Is this a bug or am I looking in the wrong direction?

Ignore dist folder

It is a common pattern to add the dist folder to the .gitignore so it is not tracked by git. This makes diffs much easier to read and shouldn't affect anything.

If doing this it might be good to also add a prepublish script that builds before publish (so this won't be accidentally forgotten when releasing).

persists the event onClick

If I try to catch the event on user click (to handle modifer keys such as CTRL, CMD, ALT) I receive this warning and the event properties are null.

Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property nativeEvent on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.

Ability to specify modifier key to activate select - feature request

I love this component. I have been using it for every list I make.

I needed a way to allow select only when a modifier key is pressed. I am not sure how desirable it might be for everyone but if so, it will be cool to include it as a prop option we can choose to provide.

https://github.com/unclecheese/react-selectable/blob/master/src/selectable-group.js#L155

/*  selectable-group.js */
if (e.metaKey) { 
    window.addEventListener('mousemove', this._openSelector);
}

Pass event object to onSelection

If you pass and event object to onSelection, it would be easier to capture ctrl, or cmd button press, in order to concat results.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.