21

for the past few hours I have been trying to search for a way to make a react component draggable and resizable. I have found a way to make it draggable with react drag and drop, but I can't find a simple way to make it resizeable :/ Does anyone have any experience on how to make a component draggable and resizable?

Any help or pointers are appreciated!

CWSites
  • 1,428
  • 1
  • 19
  • 34

3 Answers3

14

Using react-grid-layout to solve this problem. Specifically for a scheduling widget where users can scale time blocks and drag and drop them along a horizontal timeline.

react-grid-layout provides a grid with draggable and resizable widgets plus responsive layout, optional auto-packing, among other features.

var ReactGridLayout = require('react-grid-layout');

// React component render function:
render: function() {
  return (
    <ReactGridLayout className="layout" cols={12} rowHeight={30}>
      <div key={1} _grid={{x: 0, y: 0, w: 1, h: 2}}>1</div>
      <div key={2} _grid={{x: 1, y: 0, w: 1, h: 2}}>2</div>
      <div key={3} _grid={{x: 2, y: 0, w: 1, h: 2}}>3</div>
    </ReactGridLayout>
  )
}

The child nodes are draggable and resizable. The layout defined in each child "_grid" prop can alternatively be defined directly on the parent "layout" prop:

// React component render function:
render: function() {
  // layout is an array of objects, see the demo
  var layout = getOrGenerateLayout();
  return (
    <ReactGridLayout className="layout" layout={layout} cols={12} rowHeight={30}>
      <div key={1}>1</div>
      <div key={2}>2</div>
      <div key={3}>3</div>
    </ReactGridLayout>
  )
}

Callback functions can be passed to the components as props. Hooking into these should allow you to define any custom behavior:

// Calls when drag starts.
onDragStart: React.PropTypes.func,
// Calls on each drag movement.
onDrag: React.PropTypes.func,
// Calls when drag is complete.
onDragStop: React.PropTypes.func,
// Calls when resize starts.
onResizeStart: React.PropTypes.func,
// Calls when resize movement happens.
onResize: React.PropTypes.func,
// Calls when resize is complete.
onResizeStop: React.PropTypes.func

Code sample from docs: https://github.com/STRML/react-grid-layout

Demo here: https://strml.github.io/react-grid-layout/examples/0-showcase.html

sebastian the crab
  • 1,331
  • 1
  • 8
  • 7
  • 1
    Note that [link-only answers](http://meta.stackoverflow.com/tags/link-only-answers/info) are discouraged, SO answers should be the end-point of a search for a solution (vs. yet another stopover of references, which tend to get stale over time). Please consider adding a stand-alone synopsis here, keeping the link as a reference – kleopatra Sep 01 '15 at 08:23
  • This does exactly what I need. Also, very clean and can be added in any other UI framework – Krishna Vedula Oct 11 '17 at 06:22
8

I've been using react-rnd and am really happy with it: https://github.com/bokuweb/react-rnd

oldo.nicho
  • 2,149
  • 2
  • 25
  • 39
2

https://github.com/STRML/react-resizable

This answer is only for resizable component. You can find other answer which has both functionalities.

'use strict';
var React = require('react/addons');
typeof window !== "undefined" && (window.React = React); // for devtools
typeof window !== "undefined" && (window.Perf = React.addons.Perf); // for devtools
var _ = require('lodash');
var ResizableBox = require('../lib/ResizableBox.jsx');
var Resizable = require('../lib/Resizable.jsx');
require('style!css!../css/styles.css');

var TestLayout = module.exports = React.createClass({
  displayName: 'TestLayout',

  getInitialState() {
    return {width: 200, height: 200};
  },

  onClick() {
    this.setState({width: 200, height: 200})
  },

  onResize(event, {element, size}) {
    this.setState({width: size.width, height: size.height});
  },

  render() {
    return (
      <div>
        <button onClick={this.onClick} style={{'marginBottom': '10px'}}>Reset first element's width/height</button>
        <Resizable className="box" height={this.state.height} width={this.state.width} onResize={this.onResize}>
          <div className="box" style={{width: this.state.width + 'px', height: this.state.height + 'px'}}>
            <span className="text">{"Raw use of <Resizable> element. 200x200, no constraints."}</span>
          </div>
        </Resizable>
        <ResizableBox className="box" width={200} height={200}>
          <span className="text">{"<ResizableBox>, same as above."}</span>
        </ResizableBox>
        <ResizableBox className="box" width={200} height={200} draggableOpts={{grid: [25, 25]}}>
          <span className="text">Resizable box that snaps to even intervals of 25px.</span>
        </ResizableBox>
        <ResizableBox className="box" width={200} height={200} minConstraints={[150, 150]} maxConstraints={[500, 300]}>
          <span className="text">Resizable box, starting at 200x200. Min size is 150x150, max is 500x300.</span>
        </ResizableBox>
        <ResizableBox className="box box3" width={200} height={200} minConstraints={[150, 150]} maxConstraints={[500, 300]}>
          <span className="text">Resizable box with a handle that only appears on hover.</span>
        </ResizableBox>
        <ResizableBox className="box" width={200} height={200} lockAspectRatio={true}>
          <span className="text">Resizable square with a locked aspect ratio.</span>
        </ResizableBox>
        <ResizableBox className="box" width={200} height={120} lockAspectRatio={true}>
          <span className="text">Resizable rectangle with a locked aspect ratio.</span>
        </ResizableBox>
      </div>
    );
  }
});
Vishnu
  • 11,614
  • 6
  • 51
  • 90
  • 12
    This illustrated how to make the elements resizable, but the question asks how to make an element both resizable and draggable. – nnyby Jun 27 '16 at 18:06
  • I've just gone on this adventure, and what feels best is to combine react-resizable, with react-draggable. The resizable component can be wrapped in a Draggable, achieving both. Draggable is used internally by react-resizable – Muneeb Baderoen Jun 27 '20 at 11:43
  • 2
    React-Draggable and React-Resizable don't work together as of September 2020 according to this Issue and my personal experience: [link](https://github.com/STRML/react-resizable/issues/143) – Mahsan Nourani Jan 06 '21 at 19:26