Skip to content

Latest commit

 

History

History
111 lines (83 loc) · 3.68 KB

dragging-svgs.md

File metadata and controls

111 lines (83 loc) · 3.68 KB

Dragging <svg>s

Summary: @hello-pangea/dnd does not support the usage of <svg> (SVGElement) for a <Draggable /> or it's drag handle. You are still able to drag SVG's around using a number of different strategies listed below

Background: HTMLElement

We require that a <Draggable /> and its drag handle be a HTMLElement. Almost every element that you make in the browser is a HTMLElement. See huge list on MDN. A HTMLElement extends Element

HTMLElement

Focus management

We use and manipulate focus on a drag handle during a drag if it is needed. This is especially true for keyboard dragging that relies on focus management. See our focus guide.

Enter SVGElement 🖼

An SVGElement does not implement HTMLElement, and directly extends Element.

SVGElement

SVGElement has inconsistent, and sometimes, non-existent focus management behavior across browsers. more information. Trying to call svgElement.focus() on IE11 will cause an exception. There are also additional concerns:

  • Applying aria-* to a <svg> has unknown screen reader implications.
  • Inconsistent tabindex behaviour in older browsers

One of the core values of @hello-pangea/dnd is accessibility

Beautiful and accessible drag and drop for lists with React

But I want to drag using a <svg>!

Option 1: Wrap in an HTMLElement

In order to provide the best accessibility and cross browser experience for consumers we enforce that SVGElements need to be wrapped in a HTMLElement such as <span> or <div> if you want to have them as your <Draggable /> or drag handle.

// ❌ not supported
<Draggable draggableId="not-supported" index={0}>
  {provided => (
    <svg
      {...provided.draggableProps}
      {...provided.dragHandleProps}
      ref={provided.innerRef}
      {/* other SVG stuff */}
    />
  )}
</Draggable>
// ✅ supported
<Draggable draggableId="supported" index={0}>
{provided => (
  <span
    {...provided.draggableProps}
    {...provided.dragHandleProps}
    ref={provided.innerRef}
    >
      <svg {/* other SVG stuff */} />
  </span>
)}
</Draggable>

Option 2: use an <img> tag

You can use the src of an <img> tag (which is a HTMLElement) to have a draggable SVG.

// ✅ supported
<Draggable draggableId="supported" index={0}>
  {(provided) => (
    <img
      {...provided.draggableProps}
      {...provided.dragHandleProps}
      ref={provided.innerRef}
      src="my-cool-image.svg"
    />
  )}
</Draggable>

You can read more about this approach on CSS-Tricks

Option 3: use background-image

Alternatively you could also apply the SVG as a background-image to another HTMLElement.

.item {
  background-image: url(my-cool-image.svg);
}
// ✅ supported
<Draggable draggableId="supported" index={0}>
  {(provided) => (
    <div
      {...provided.draggableProps}
      {...provided.dragHandleProps}
      ref={provided.innerRef}
      className="item"
    />
  )}
</Draggable>

You can read more about this approach on CSS-Tricks

← Back to documentation