draggable
draggable copied to clipboard
Unable to use this with ReactJS
I've the following html structure:
<div className="items__food">
<div className="food food--apple">
<img src={Apple} alt="Apple" />
</div>
<div className="food food--banana">
<img src={Banana} alt="Banana" />
</div>
<div className="food food--bread">
<img src={Bread} alt="Bread" />
</div>
</div>
And in my componentDidMount
, I'm doing:
new Draggable(document.querySelectorAll('.items__food'))
.on('drag:start', () => console.log('drag:start'))
.on('drag:move', () => console.log('drag:move'))
.on('drag:stop', () => console.log('drag:stop'));
However, I'm unable to drag any .food
items and as a result, nothing is outputted on the console.

Interested to see how to integrate with React - I had some strange behaviour with elements duplicating. :)
I don't think you can do this (well, you can, but you shouldn't), b/c react
is not aware of what draggable
does to your DOM nodes so react
is unable to compute valid DOM representation for the next render.
I will park that idea for now then. =) ref: https://reactjs.org/docs/integrating-with-other-libraries.html
I just encountered the issue with react
not being aware of the DOM manipulation draggable
does. Since draggable
does it on the fly while dragging, there's no way to cancel it (from what I can see) like you can with the alike jQuery UI Sortable and let React do it instead.
I would love to have integration with MVVM-libraries, too.
@ghoshnirmalya should definitely work with React. You would also need to override the componentDidUpdate
to figure out if, e.g. children elements have changed, or you could see if a sortable:sorted
has fired (implementation is up to you). Or you could also just return false
within componentDidUpdate
which tells react to never re-render.
There are plans on releasing a react component as a separate bundle for this repo.
Since draggable does it on the fly while dragging, there's no way to cancel it
@STenorio99 this is true, Sortable
, Swappable
and Droppable
do DOM manipulations as you drag around, as supposed to on drag end. This makes this draggable library different than others, but we could add a traditional sortable module (built on top of Draggable) that performs DOM manipulation on drag end instead.
You can cancel most DOM manipulations via canceling events, e.g.
new Swappable(containers)
.on('swappable:swapped', (event) => event.cancel())
We are missing the cancelable action for sortable:sorted
, but we can easily add it, which is the plan. It would work like swappable https://github.com/shopify/draggable#events-3
I hope that answered a lot of the questions in this issue?
Awesome
We are working on React html editor, making it easy to use this library would make our editor a lot more awesome!
Do you have any, even very basic and simple example of React component using it?
We do not. that was supposed to be a motivational comment to add react support/docs soon
While we're at it, what about other frameworks such as VueJS?
@jefflam https://github.com/Shopify/draggable/issues/18.
There are plans on releasing a react component as a separate bundle for this repo.
React support would be awesome.
Yeah, I would love to see React support! Thanks for the library
I just threw together a very simple example integrating the Sortable portion of this library with React if anyone wants to check it out for reference.
That's great. Thanks Justin!
On Fri, Nov 17, 2017 at 4:50 PM, Justin Mak [email protected] wrote:
I just threw together a very simple example integrating the Sortable portion of this library with React if anyone wants to check it out for reference.
Repo https://github.com/jmakGH/shopify-draggable-react-example Demo https://jmakgh.github.io/shopify-draggable-react-example/
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Shopify/draggable/issues/34#issuecomment-345151868, or mute the thread https://github.com/notifications/unsubscribe-auth/AAH9Yk5k6wKIWeZf32ZmSPIJPW3936Jyks5s3R6LgaJpZM4PpxDd .
wow thanks @jmakGH :+1:
No problem guys, although I should note it's definitely a rough draft. ~~The current setup works outside of the React lifecycle, meaning that sorting the blocks only changes the UI representation but not the actual state.~~
Project is updated and now runs all updates properly through React.
All the hooks are there though to update state accordingly and I'll be getting this more Reactified in the upcoming days as well as getting a few more different examples up.
@jmakGH thank you so much! I couldn't figure it out by myself
@tsov do we want to leave this issue open until we have some official React integration – or would you say its safe to close this?
Let's keep it open until we natively support react or can recommend a 3rd party wrapper library. This is also a good spot for people with the same question
@tsov @beefchimi I'm going to start working on a React wrapper for this! :) I'll keep you guys posted
Update # 1:
Design for Draggable
Supports single containers
DraggableContainer
props:
draggable: string
handle: string
as: string // what to render the container as
className: string // classname for the container
style: {[string]:string} //inline styling
delay: number
classes: {[string]: string} // add classes to elements to indicate state
draggableRef: (Draggable) => void // ref so you can access the Draggable object to override stuff if u want. Like event listeners
// and all the React synthetic event handlers :)
Draggable
context:
draggable: string // classnames for the query selector. Added onto classname
props:
as: string
className: string // classname for the component
style: {[string]:string} //inline style
children: Nodes // what to render inside (even react components)
// and all the React synthetic event handlers :)
Handle
context:
handle: // classnames for the handle. Added onto classname
props:
as: string
className: string // classname for the component
style: {[string]: string}
// and all the React synthetic event handlers :)
Usage would be like:
<DraggableContainer draggable="whatever" handle="whatever2">
<Draggable children={<Handle/>} />
</DraggableContainer>
Using the provider pattern to pass the classnames to the respective children without explicitly passing the props in Draggable and Handle. I should have it implemented soon :)
Update # 2:
95% DONE!!! :)
repo: https://github.com/wuweiweiwu/react-shopify-draggable
I just need to finish some enzyme tests and flesh out the demos and update the README
Will update soon.
ps: react-shopify-draggable
is actually taken on npm already but it just has some boilerplate code that that just create a Draggable instance and nothing else. So I will be publishing it as a scoped module
yarn add @wuweiweiwu/react-shopify-draggable
@tsov @beefchimi
Done and published! :)
Repo: https://github.com/wuweiweiwu/react-shopify-draggable Simple Demo: https://weiweiwu.me/react-shopify-draggable/ NPM: https://www.npmjs.com/package/@wuweiweiwu/react-shopify-draggable
Implementation details: https://github.com/wuweiweiwu/react-shopify-draggable#implementation-details on how I was able to pass options down via context. And update props like id
className
and style
without rerendering
@jmakGH I took your example + some styling to create my simple example. And it is pasted below.
render() {
return (
<div className="App">
<div className="App-body">
<div className="App-body-count">
<h1 className="App-body-count-text">Block count:</h1>
<input
type="number"
className="App-body-count-input"
value={this.state.blockCount}
onChange={this.handleBlockCount}
/>
</div>
<DraggableContainer
as="div"
type="sortable"
className="BlockGenerator"
>
{Array.from(Array(this.state.blockCount).keys()).map(number => (
<DraggableItem
as="div"
className="Block"
style={{ backgroundColor: randomColor() }}
>
{number}
</DraggableItem>
))}
</DraggableContainer>
</div>
</div>
);
}
Also working on some more advanced examples in Storybook
I would love any feedback. Enjoy 💯
Any plans on making sortable:sorted
cancelable?
+1
If for some reason you don't want to use the awesome react-shopify-draggable, I've written a short tutorial (https://afi.io/blog/how-to-use-shopify-draggable-with-react/) that shows how you can make shopify draggable work with react.