Skip to main content
Elastic UI
Elastic UI
ComponentsPatternsContentData visualization
EUI ChangelogGitHubFigma
  • Guidelines
    • Getting started
    • Accessibility
    • Writing
    • Testing
  • Theming
    • Theme provider
    • Color mode
    • High contrast mode
    • Borders
    • Breakpoints
    • Colors
    • Sizing
    • Typography
  • Templates
    • Page template
    • Sitewide search
  • Layout
    • Accordion
    • Bottom bar
    • Flex
    • Flyout
    • Header
    • Horizontal rule
    • Modal
    • Page components
    • Page header
    • Panel
    • Popover
    • Resizable container
    • Spacer
  • Navigation
    • Breadcrumbs
    • Buttons
    • Collapsible nav
    • Context menu
    • Facet
    • Key pad menu
    • Link
    • Pagination
    • Side nav
    • Steps
    • Tabs
    • Tree view
  • Display
    • Aspect ratio
    • Avatar
    • Badge
    • Callout
    • Card
    • Comment list
    • Description list
    • Drag and drop
    • Empty prompt
    • Health
    • Icons
    • Image
    • List group
    • Loading
    • Progress
    • Skeleton
    • Stat
    • Text
    • Timeline
    • Title
    • Toast
    • Tooltip
    • Tour
  • Forms
    • Form controls
    • Form layouts
    • Form validation
    • Text controls
    • Numeric controls
    • Selection controls
    • Search and filter controls
    • Date and time controls
    • Other controls
  • Tabular content
    • Tables
    • Data grid
  • Editors & Syntax
    • Code
    • Markdown
  • Utilities
    • Accessibility
    • Auto sizer
    • Beacon
    • Color palettes
    • Copy
    • CSS utility classes
    • Delay
    • Error boundary
    • Focus trap
    • Highlight and mark
    • HTML ID generator
    • I18n
    • Inner text
    • Mutation observer
    • Outside click detector
    • Overlay mask
    • Portal
    • Pretty duration
    • Provider
    • Resize observer
    • Scroll
    • Text diff
    • Text truncation
    • Window events
  • EUI
  • Display
  • Drag and drop

Drag and drop

An extension of

@hello-pangea/dnd (which is an actively maintained fork of react-beautiful-dnd) with a compatible API and built-in style opinions. Functionality results from 3 components working together:

  • <EuiDragDropContext />: Section of your application containing the draggable elements and the drop targets.
  • <EuiDroppable />: Area into which items can be dropped. Contains one or more <EuiDraggable />.
  • <EuiDraggable />: Items that can be dragged. Must be part of an <EuiDroppable />

Consider your users and use case

Drag and drop interfaces are not well-adapted to many cases, and may be less suitable than other form types for data operations. For instance, drag and drop interaction relies heavily on spatial orientation that may not be entirely valid to all users (e.g., screen readers as the sole source of information). Similarly, users navigating by keyboard may not be afforded nuanced, dual-axis drag item manipulation.

EUI (largely due to the great work already in @hello-pangea/dnd) has and will continue to ensure accessibility where possible. With that in mind, keep your users' working context in mind.

Just the facts

EuiDraggable makes very few assumptions about what content it contains. To give affordance to draggable elements and to ensure a consistent experience, child elements must be able to accept a border and drop shadow (automatically applied via CSS). No other style opinions are applied, however.

Similarly, EuiDroppable must accept a background color overlay (automatically applied via CSS), but has no other restrictions.

All EuiDragDropContext elements are discrete and isolated; EuiDroppables and EuiDraggables cannot be shared/transferred between instances. Also, EuiDragDropContexts cannot be nested. It is recommended that a single, high-level EuiDragDropContext is used and EuiDroppables account for categorical and functional separation (see later examples).

EuiDragDropContext handles all events but makes no assumptions about the result of a drop event. As such, the following event handlers are available:

  • onBeforeDragStart
  • onDragStart
  • onDragUpdate
  • onDragEnd (required)

EUI also provides methods for helping to deal to common action types:

  • reorder: change an item's location in a droppable area
  • copy: create a duplicate of an item in a different droppable area
  • move: move an item to a different droppable area
Loading...

Simple item reorder

The simplest case, demonstrating a single EuiDroppable with reorder behavior.

Notice the ability to change rendered content based on dragging state. EuiDraggable children is a render prop that mush return a ReactElement. The snapshot parameter on that function has state data that can be used to alter appearance or behavior (e.g., isDragging).

Loading...

Custom drag handle

By default the entire element surface can initiate a drag. To specify an element within as the handle and create a containing group, set customDragHandle=true and hasInteractiveChildren=true on the EuiDraggable.

The provided parameter on the EuiDraggable children render prop has all data required for functionality. Along with the customDragHandle flag,provided.dragHandleProps needs to be added to the intended handle element.

Accessibility requirement

Icon-only custom drag handles require an accessible label. Add an aria-label="Drag handle" attribute to your React component or HTML element that receivesprovided.dragHandleProps.

Loading...

Interactive elements

EuiDraggable can contain interactive elements such as buttons and form fields. Interactive elements require customDragHandle=true and hasInteractiveChildren=true on the EuiDraggable. These props will maintain drag functionality and accessibility, while enabling click, keypress, etc., events on the interactive child elements.

Loading...

Move between lists

By default, all EuiDroppable elements are of the same type and will accept EuiDraggable elements from others in the same EuiDragDropContext.

The EUI move method is demonstrated in this example.

Loading...

Distinguish droppable areas by type

Setting the type prop on an EuiDroppable element will ensure that it will only accept EuiDraggable elements from the same type of EuiDroppable.

Notice that the enabled, compatible EuiDroppable elements have a visual change that indicates they can accept the actively moving/focused EuiDraggable element.

Loading...

Copyable items

For cases where collections of EuiDraggable elements are static or can be used in multiple places set cloneDraggables=true on the parent EuiDroppable. The EuiDroppable becomes disabled (does not accept new EuiDraggable elements) in this scenario to avoid mixed content intentions.

The EUI copy method is available and demonstrated in the example below. Note that the data point used asdraggableId in EuiDraggable must change to allow for real duplication.

isRemovable is used in the example for cloned items. This API is likely to change, but currently provides the visual changes with drop-to-remove interactions.

Loading...

Portalled items

EuiDraggables use fixed positioning to render and animate the item being dragged. This positioning logic does not work as expected when used inside of containers that have their own stacking context.

To ensure dragging works as expected inside e.g. EuiFlyout, EuiModal or EuiPopover, use the prop usePortal on EuiDraggable components. This will render the currently dragged element inside a portal appended to the document body (or wherever EuiPortal is configured to insert to by default).

Style inheritance

If the styling of the draggable content is scoped to a parent component, the styling won't be applied while dragging it when using usePortal. This is due to the portalled position in the DOM, which changes previous hierarchical relations to other ancestor elements. To prevent this from happening, we recommend applying styling from within the EuiDraggable scope without any parent selectors.

Loading...

Kitchen sink

EuiDraggables in EuiDroppables, EuiDroppables in EuiDraggables, custom drag handles, horizontal movement, vertical movement, flexbox, panel inception, you name it.

Loading...

Props

EuiDragDropContext

𐘂𐘂
✄𐘗✄𐘗
Prop
↦
Description and type
↦
Default value
↵
Prop
dragHandleUsageInstructions#
↦
Description and type
Type: string
↦
Default value
↵
Prop
enableDefaultSensors#
↦
Description and type
Type: boolean
↦
Default value
↵
Prop
nonce#
↦
Description and type
Type: string
↦
Default value
↵
Prop
sensors#
↦
Description and type
Type: Sensor[]
↦
Default value
↵
Prop
autoScrollerOptions#
↦
Description and type

Customize auto scroller

Type: RecursivePartial<AutoScrollerOptions>
↦
Default value
↵
𐘂𐘂

EuiDraggable

𐘂𐘂
✄𐘗✄𐘗
Prop
↦
Description and type
↦
Default value
↵
Prop
children#
↦
Description and type

ReactNode to render as this component's content

Type: ReactElement<any, string | JSXElementConstructor<any>> | DraggableChildrenFn
↦
Default value
Required
↵
Prop
index#
↦
Description and type
Type: number
↦
Default value
Required
↵
Prop
draggableId#
↦
Description and type
Type: string
↦
Default value
Required
↵
Prop
className#
↦
Description and type
Type: string
↦
Default value
↵
Prop
customDragHandle#
↦
Description and type

Whether the children will provide and set up its own drag handle.
The custom value additionally removes the role from the draggable container.
Use this if the children element is focusable and should keep its
semantic role for accessibility purposes.

Type: boolean | "custom"
↦
Default value
false
↵
Prop
hasInteractiveChildren#
↦
Description and type

Whether the container has interactive children and should have role="group" instead of "button".
Setting this flag ensures your drag & drop container is keyboard and screen reader accessible.

Type: boolean
↦
Default value
false
↵
Prop
isRemovable#
↦
Description and type

Whether the item is currently in a position to be removed

Type: boolean
↦
Default value
false
↵
Prop
usePortal#
↦
Description and type

Whether the currently dragged item is cloned into a portal in the body. This settings will
ensure that drag & drop still works as expected within stacking contexts (e.g. within EuiFlyout,
EuiModal and EuiPopover).

Make sure to apply styles directly to the Draggable content as relative styling from an outside
scope might not be applied when the content is placed in a portal as the DOM structure changes.

Type: boolean
↦
Default value
false
↵
Prop
spacing#
↦
Description and type

Adds padding to the draggable item

Type: "s" | "m" | "l" | "none"
↦
Default value
none
↵
Prop
style#
↦
Description and type
Type: CSSProperties
↦
Default value
↵
Prop
aria-label#
↦
Description and type
Type: string
↦
Default value
↵
Prop
data-test-subj#
↦
Description and type
Type: string
↦
Default value
↵
Prop
css#
↦
Description and type
Type: Interpolation<Theme>
↦
Default value
↵
Prop
isDragDisabled#
↦
Description and type
Type: boolean
↦
Default value
false
↵
Prop
disableInteractiveElementBlocking#
↦
Description and type
Type: boolean
↦
Default value
↵
Prop
shouldRespectForcePress#
↦
Description and type
Type: boolean
↦
Default value
↵
𐘂𐘂

EuiDroppable

𐘂𐘂
✄𐘗✄𐘗
Prop
↦
Description and type
↦
Default value
↵
Prop
children#
↦
Description and type

ReactNode to render as this component's content

Type: ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<any, string | JSXElementConstructor<any>>[] | ((provided: DroppableProvided, snapshot: DroppableStateSnapshot) => ReactNode)
↦
Default value
Required
↵
Prop
droppableId#
↦
Description and type
Type: string
↦
Default value
Required
↵
Prop
className#
↦
Description and type
Type: string
↦
Default value
↵
Prop
cloneDraggables#
↦
Description and type

Makes its items immutable. Dragging creates cloned items that can be dropped elsewhere.

Type: boolean
↦
Default value
false
↵
Prop
style#
↦
Description and type
Type: CSSProperties
↦
Default value
↵
Prop
spacing#
↦
Description and type

Adds padding to the droppable area

Type: "s" | "m" | "l" | "none"
↦
Default value
none
↵
Prop
withPanel#
↦
Description and type

Adds an EuiPanel style to the droppable area

Type: boolean
↦
Default value
false
↵
Prop
grow#
↦
Description and type

Allow the panel to flex-grow?

Type: boolean
↦
Default value
false
↵
Prop
aria-label#
↦
Description and type
Type: string
↦
Default value
↵
Prop
data-test-subj#
↦
Description and type
Type: string
↦
Default value
↵
Prop
css#
↦
Description and type
Type: Interpolation<Theme>
↦
Default value
↵
Prop
renderClone#
↦
Description and type
Type: DraggableChildrenFn
↦
Default value
↵
𐘂𐘂
Edit this page

Previous
Description list
Next
Empty prompt
  • Just the facts
  • Simple item reorder
  • Custom drag handle
  • Interactive elements
  • Move between lists
  • Distinguish droppable areas by type
  • Copyable items
  • Portalled items
  • Kitchen sink
  • Props
EUI is dual-licensed under Elastic License 2.0 and Server Side Public License, v 1 | Crafted with ❤ by Elastic