Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add drag and drop support for Marker #576

Merged
merged 3 commits into from
Aug 13, 2018
Merged

Add drag and drop support for Marker #576

merged 3 commits into from
Aug 13, 2018

Conversation

schnerd
Copy link
Contributor

@schnerd schnerd commented Aug 11, 2018

Resolves issue #483

This PR adds support for drag and drop events to the <Marker> component.

kapture 2018-08-11 at 9 44 37

Simply add a draggable prop to your Marker, and subscribe to whatever events you need:

<Marker 
  longitude={marker.longitude}
  latitude={marker.latitude}
  draggable
  onDragStart={this._onMarkerDragStart}
  onDrag={this._onMarkerDrag}
  onDragEnd={this._onMarkerDragEnd}
>
  <Pin size={20} />
</Marker>

This API design is intended to be similar to Mapbox's draggable markers.

"webpack": "^2.4.0",
"webpack-dev-server": "^2.4.0"
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should eventually look into not having all this boilerplate for each example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should eventually look into not having all this boilerplate for each example.

It is our goal that each example folder can be independently copied out of this repo and work stand-alone, so we do want a minimal set of "boilerplate".

That said, we really want that boilerplate/configuration to be as minimal as possible.

Unfortunately the current fashion in javascript bundlers and compilers is to over-engineer for modularity and they do not seem to offer umbrella modules (not a single unneeded development plugin must installed, even if that requires the user to add 20 lines to package.json and has no effect the final bundle size :).

Two options here are probably

  • move to babel-preset-env which should remove two lines
  • explore create-react-app, which now seems to be supported by mapbox-gl

if (eventManager && this._events) {
eventManager.off(this._events);
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Pessimistress Seemed like it made sense to remove events if the control is unmounted – let me know if I'm missing something.

pancancel: this._onDragCancel.bind(this)
};
eventManager.on(this._dragEvents);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These events need to be bound to the map itself (instead of the marker), otherwise you get behavior like this when the mouse moves outside the pin:

draggable-panmove

And it makes sense to attach these events after panstart, otherwise with 1000 markers you'd have 1000 onDrag event handlers being invoked after each panmove.

result.unmount();

t.end();
});
Copy link
Contributor Author

@schnerd schnerd Aug 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was going to write more tests for draggable functionality specifically, but it seems like react test renderer doesn't really do refs, making it difficult to test the desired behavior.

@@ -245,9 +245,6 @@ hr.short {
bottom: 24px;
color: $white-40;
}
.overlays {
cursor: crosshair;
}
Copy link
Contributor Author

@schnerd schnerd Aug 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having crosshair as the cursor across the examples & website seemed like a mistake. It overrides the default cursor behavior of the library (and doesn't look great IMO)

@@ -31,7 +31,12 @@ const propTypes = Object.assign({}, BaseControl.propTypes, {
// Offset from the left
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not in love with how much code ended up being required in here, but I still think it's a manageable size and broken down into small methods.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not in love with how much code ended up being required in here, but I still think it's a manageable size and broken down into small methods.

How generic is this code? If another component wanted to also implement dragging would it be highly reusable. Could it make sense to organize it as

Marker > DraggableControl > BaseControl

It could look more appealing to have these methods in a separate class that is focused on dragging, rather than mixed with the Marker specific functionality.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this idea, let me try restructuring it that way.

- `event` - The pointer event.
+ `event.lngLat` - The geo coordinates of the drag event, as `[lng, lat]`.

##### `onDragEnd` {Function}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a concept of DragCancel? (ESCAPE key etc)

Copy link
Contributor Author

@schnerd schnerd Aug 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So technically there is a pancancel event in hammer which could theoretically warrant an onDragCancel call, but I couldn't figure out how to trigger it (escape, dragging outside viewport, etc didn't do anything).

We could add support for escape key, though that would require another explicit keyup handler. If we're mostly trying to stay aligned with mapbox draggable markers, they currently don't have a cancel event so it might be fine to omit for now.

"webpack": "^2.4.0",
"webpack-dev-server": "^2.4.0"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should eventually look into not having all this boilerplate for each example.

It is our goal that each example folder can be independently copied out of this repo and work stand-alone, so we do want a minimal set of "boilerplate".

That said, we really want that boilerplate/configuration to be as minimal as possible.

Unfortunately the current fashion in javascript bundlers and compilers is to over-engineer for modularity and they do not seem to offer umbrella modules (not a single unneeded development plugin must installed, even if that requires the user to add 20 lines to package.json and has no effect the final bundle size :).

Two options here are probably

  • move to babel-preset-env which should remove two lines
  • explore create-react-app, which now seems to be supported by mapbox-gl

}]
},

resolve: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this resolve is no longer needed and could be removed from examples

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -31,7 +31,12 @@ const propTypes = Object.assign({}, BaseControl.propTypes, {
// Offset from the left
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not in love with how much code ended up being required in here, but I still think it's a manageable size and broken down into small methods.

How generic is this code? If another component wanted to also implement dragging would it be highly reusable. Could it make sense to organize it as

Marker > DraggableControl > BaseControl

It could look more appealing to have these methods in a separate class that is focused on dragging, rather than mixed with the Marker specific functionality.

@schnerd schnerd merged commit 9c302ae into master Aug 13, 2018
@Pessimistress Pessimistress deleted the draggable-markers branch October 27, 2018 05:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants