react-box-o-buttons
v0.0.16
Published
BoxOButtons
Downloads
19
Readme
BoxOButtons
Drag and drop things into this box and they display as buttons.
Box highlights when you drag compatible items over it (Use dataKey property to tell it what drag items are compatible).
Drag and drop buttons within the box to re-order them.
Click the 'X' on a button to delete it.
Click a button to select it (for editing details or whatever).
Designed to work with react-drag-drop-container component (though it would be pretty easy to adapt to straight HTML 5 d-n-d if you had to).
Callbacks for buttonAdded, buttonDeleted, buttonsReordered, and buttonSelected enable the parent component to approve or refuse any action -- the updated buttons are passed in the callback, and the parent can apply them or not.
Demo & Examples
Live demo: peterh32.github.io/react-box-o-buttons
To build the examples locally, run:
npm install
npm start
Then open localhost:8000
in a browser.
Installation
npm install react-box-o-buttons --save
Usage
Create a parent component and have it render BoxOButtons:
var BoxOButtons = require('react-box-o-buttons');
class DummyParent extends React.Component {
constructor(props) {
super(props);
// add some buttons
this.state = {
buttons: ['frog', 'bug', 'newt'].map(
(label, i)=>{return {'label': label, 'id': i}}
),
selectedButtonIndex: null
};
}
render() {
return (
<BoxOButtons
buttons={this.state.buttons}
selectedButton={this.state.selectedButtonIndex}
dataKey="foo"
/>
);
}
}
export default DummyParent
The dataKey field is how your BoxOButtons will recognize compatible drop objects.
Stick the parent element in a page and you should see three buttons:frog, bug, and newt.
<DummyParent />
In the parent, add methods to handle the four callbacks from BoxOButtons: buttonAdded, buttonDeleted, buttonsReordered, and buttonSelected.
handleButtonAdded(updatedButtons, newButton) {
//... test if newButton is acceptable and then ...
this.setState({buttons: updatedButtons});
return true;
}
handleButtonDeleted(updatedButtons, deletedButton, newSelectedButton, force) {
//... test if it's ok to delete deletedButton, or if 'force' is true, then ...
this.setState({buttons: updatedButtons, selectedButtonIndex: newSelectedButton});
return true;
}
handleButtonsReordered(updatedButtons, newSelectedButton) {
//... if this is ok then ...
this.setState({buttons: updatedButtons, selectedButtonIndex: newSelectedButton});
return true;
}
handleButtonSelected(n) {
//... test if n is ok to highlight then ...
this.setState({selectedButtonIndex: n});
return true;
}
Wire them up in your render method:
render() {
return (
<BoxOButtons
buttons={this.state.buttons}
dataKey="foo"
buttonAdded={this.handleButtonAdded}
buttonDeleted={this.handleButtonDeleted}
buttonsReordered={this.handleButtonsReordered}
buttonSelected={this.handleButtonSelected}
/>
);
}
Remember to bind them in your constructor:
this.handleButtonAdded = this.handleButtonAdded.bind(this);
this.handleButtonDeleted = this.handleButtonDeleted.bind(this);
this.handleButtonsReordered = this.handleButtonsReordered.bind(this);
this.handleButtonSelected = this.handleButtonSelected.bind(this);
Now go back to your page. Click an 'x' on one of the buttons and it should disappear. You can also drag and drop buttons to reorder them.
In your page, add some items you can drag into the box, using DragDropContainer (DragDropContainer is a required dependency):
var DragDropContainer = require('react-drag-drop-container');
...
<DragDropContainer dataKey="foo" dragData={{label: 'alligator'}}>
Gator
</DragDropContainer>
<DragDropContainer dataKey="foo" dragData={{label: 'fish'}}>
Fish
</DragDropContainer>
<DragDropContainer dataKey="foo" dragData={{label: 'mosquito'}}>
Mosquito
</DragDropContainer>
In your page, drag and drop these into the BoxOButtons and they should display as buttons.
If you have multiple compatible boxes (compatible => matching dataKey properties) then you can also drag elements between them.
Properties
Callbacks (all required)
BoxOButtons uses callbacks to tell the parent component about changes such as deletions, additions, and reordering.
The callbacks then must
- decide whether to accept the change.
- make changes in the buttons and selectedButton properties if the change is accepted.
- return true if the change was accepted, false otherwise.
buttonAdded
Callback when item is dropped. Args: updatedButtons (array) and newButton (object).
buttonDeleted
Callback when button is deleted. Args: updatedButtons (array), deletedButton (object), newSelectedButton (since deleting a button can change this), and force (boolean, set true if you want to skip any confirmations etc.).
buttonsReordered
Callback when buttons are re-ordered. Args: updatedButtons (array) and newSelectedButton (object) (since rearranging the buttons can change the selection)
buttonSelected
Callback when a button is selected (highlighted). Arg: button index (int) or null if nothing is selected.
Other Properties
placeholderText
Optional text to display when the box is empty.
dataKey
The key to use for retrieving drag data from a dragged element. This also determines which dragged elements are considered 'compatible' with this box and cause it to highlight when dragged over. Defaults to 'data'.
labelField
The field to use as the button label; defaults to 'label'.
buttons
Array representing the current set of buttons.
selectedButton
0-based index of selected button, or null if no button is selected.
Notes
CSS
CSS will be inserted in the <head>
section of your document in a <style>
element with
id="react-box-o-buttons". It should be fairly easy to overwrite styles if you want the buttons
or the box to look different. (I suppose we could also add properties to let you set the
classnames to something else.)
Development (src
, lib
and the build process)
NOTE: The source code for the component is in src
. A transpiled CommonJS version (generated with Babel) is available in lib
for use with node.js, browserify and webpack. A UMD bundle is also built to dist
, which can be included without the need for any build system.
To build, watch and serve the examples (which will also watch the component source), run npm start
. If you just want to watch changes to src
and rebuild lib
, run npm run watch
(this is useful if you are working with npm link
).
License
Proprietary, not licensed for re-use.
Copyright (c) 2017 Medidata.