React-sortable-hoc: Changing cursor to grab/grabbing with dragHandle

Created on 28 Dec 2017  路  10Comments  路  Source: clauderic/react-sortable-hoc

If anyone could provide an example with how I can use a grab and grabbing cursor with a drag handle, that would be great. Right now, no matter what CSS I try to use, the cursor seems to always go to default when dragging is active.

Edit: Closing this, I ended up using a workaround where I just applied a class to the whole document body

Most helpful comment

FYI heres's how i did it:

onSortStart={() => (document.body.style.cursor = 'grabbing')}
onSortEnd={({ newIndex, oldIndex }: any) => {
    document.body.style.cursor = 'default';
...

then on your drag handler make sure to put cursor: grab on it

All 10 comments

for other people who bump in here: https://github.com/clauderic/react-sortable-hoc/issues/253

this issue (and all the links there) can provide you with tips on ways to do this.

FYI heres's how i did it:

onSortStart={() => (document.body.style.cursor = 'grabbing')}
onSortEnd={({ newIndex, oldIndex }: any) => {
    document.body.style.cursor = 'default';
...

then on your drag handler make sure to put cursor: grab on it

Thank you for this @zackify 鈥擨 would never have figured this out :( This should be documented somewhere :/

Completely agree. I searched forever then figured this out 馃槀 I don鈥檛 like having to call document methods inside react. But oh well!

A somewhat improved version of @zackify 's method. I wanted the cursor to change immediately on click for user feedback. Still pretty hacky, and there's a cursor flash if you release the mouse button over the drag handle or happen to pass over any elements that change cursor while you're dragging:

const GroupDragHandle = SortableHandle((): React.ReactElement => {
  return (
    <DragHandleIcon
      onMouseEnter={ (): void => { if (document.body.style.cursor !== 'grabbing') document.body.style.cursor = 'grab' } }
      onMouseLeave={ (): void => { if (document.body.style.cursor === 'grab') document.body.style.cursor = '' } }
      onMouseDown={ (): void => { document.body.style.cursor = 'grabbing' } }
    />
  );
});

...then on the SortableList itself:

onSortEnd={ (): void => { document.body.style.cursor = ''; } }

Thanks @neckro it works the way I need it. Could you tell me please what the void operator does there?

It is possible to do this with only changing one component:

  const SortableList = SortableContainer(({ items }: { items: typeof values }) => (
    <div
      className="sortable_list_container" 
      style={{ cursor: 'grab' }}
      onMouseDown={() => document.querySelectorAll('.sortable_list_container').forEach((el) => ((el as HTMLElement).style.cursor = 'grabbing'))}
      onMouseUp={() => document.querySelectorAll('.sortable_list_container').forEach((el) => ((el as HTMLElement).style.cursor = 'grab'))}
    >
      {items.map((item, index) => (
        <SortableItem key={keys[index]} index={index} item={item} />
      ))}
    </div>
  ));

Where className is used, instead of id, to support more than one "sortable list" per document.

Thanks @neckro it works the way I need it. Could you tell me please what the void operator does there?

Sorry for not checking my notifications. That's Typescript -- you can remove the : void and the : React.ReactElement type hints for plain JS.

FYI heres's how i did it:

onSortStart={() => (document.body.style.cursor = 'grabbing')}
onSortEnd={({ newIndex, oldIndex }: any) => {
    document.body.style.cursor = 'default';
...

then on your drag handler make sure to put cursor: grab on it

Just to add to @zackify 's approach, to make sure that the cursor will not change when you drag over, say a button (it may change to a pointer), you can do this:

onSortStart={() => (document.body.className = 'grabbing')}
onSortEnd={({ newIndex, oldIndex }: any) => {
  document.body.className = '';
...

where grabbing is

grabbing {
  cursor: grabbing;
}
grabbing * {
  cursor: grabbing;
}

@arosisi Your solution works like a charm :+1: It should be in the doc. Team Work power, thx guys ;p

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Miteshdv picture Miteshdv  路  16Comments

edygar picture edygar  路  10Comments

smmoosavi picture smmoosavi  路  9Comments

stahlmanDesign picture stahlmanDesign  路  12Comments

mccambridge picture mccambridge  路  10Comments