kibana/packages/kbn-dom-drag-drop
Julia Rechkunova 6cb937a37a
[Discover] Redesign for the grid, panels and sidebar v1 (#165866)
## Summary

### Part 1

- Resolves https://github.com/elastic/kibana/issues/164287
- Closes https://github.com/elastic/kibana/issues/146339
- Previously separate PR https://github.com/elastic/kibana/pull/164187

Changes:
- ~~swaps checkbox and row selection~~
- removes vertical borders
- adds rows highlight
- increases cell padding
- adds row stripes
- updates header background
- removes grey background from field name and makes it bolder (part of
https://github.com/elastic/kibana/issues/164634)
- updates Surrounding Documents side paddings

### Part 2

- Resolves https://github.com/elastic/kibana/issues/164661
- Previously separate PR https://github.com/elastic/kibana/pull/165687

Changes:
- removes background from panels, tabs and sidebar
- updates "Add a field" button style
- removes shadow from field list items
- makes field search compact

### Part 3

- Resolves https://github.com/elastic/kibana/issues/164662

Changes:
- wraps "Add a field" button in its own container with a top border
- ~~adds a drag handle to sidebar items~~
- ~~adds new Show/Hide buttons to toggle sidebar~~ moves sidebar toggle
button from discover plugin to unified field list
- reduces spaces between sidebar items from 4px to 2px
- reduces padding on Single Document page
- removes border above grid tabs

<img width="600" alt="Screenshot 2023-09-07 at 14 39 48"
src="976db247-fd70-4c9b-8634-552ece45b522">


Please note that "auto" row height is in a separate PR which is also
ready for review https://github.com/elastic/kibana/pull/164218

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Davis McPhee <davismcphee@hotmail.com>
Co-authored-by: Davis McPhee <davis.mcphee@elastic.co>
2023-09-12 08:51:34 +02:00
..
src [Discover] Redesign for the grid, panels and sidebar v1 (#165866) 2023-09-12 08:51:34 +02:00
index.ts [Lens] Refactor drag and drop (#161257) 2023-07-11 13:05:03 +02:00
jest.config.js Migrate drag and drop logic from Lens plugin to its own package (#151836) 2023-03-23 11:09:17 +01:00
kibana.jsonc [UnifiedFieldList][Discover] Create a high level unified field list building block (#160397) 2023-07-10 12:18:40 +02:00
package.json Migrate drag and drop logic from Lens plugin to its own package (#151836) 2023-03-23 11:09:17 +01:00
README.md [Lens] Refactor drag and drop (#161257) 2023-07-11 13:05:03 +02:00
tsconfig.json Migrate drag and drop logic from Lens plugin to its own package (#151836) 2023-03-23 11:09:17 +01:00

DOM Drag & Drop

This is a simple drag / drop mechanism that plays nice with React.

We aren't using EUI or another library, due to the fact that Lens visualizations and datasources may or may not be written in React. Even visualizations which are written in React will end up having their own ReactDOM.render call, and in that sense will be a standalone React application. We want to enable drag / drop across React and native DOM boundaries.

Getting started

First, place a RootDragDropProvider at the root of your application.

<RootDragDropProvider customMiddleware={...}>
  ... your app here ...
</RootDragDropProvider>

If you have a child React application (e.g. a visualization), you will need to pass the drag / drop context down into it. This can be obtained like so:

const context = useDragDropContext();

In your child application, place a ChildDragDropProvider at the root of that, and assign the context into it:

<ChildDragDropProvider value={context}>... your child app here ...</ChildDragDropProvider>

This enables your child application to share the same drag / drop context as the root application.

DragDropIdentifier

An item can be both draggable and droppable at the same time, but for simplicity's sake, we'll treat these two cases separately.

To enable dragging an item, use DragDrop with both a draggable and a value attribute. Property value has to be of a type object with a unique id property.

<div className="field-list">
  {fields.map((f) => (
    <DragDrop key={f.id} className="field-list-item" value={f} draggable>
      {f.name}
    </DragDrop>
  ))}
</div>

Dropping

To enable dropping, use DragDrop with both a dropTypes attribute that should be an array with at least one value and an onDrop handler attribute. dropType should only be truthy if is an item being dragged, and if a drop of the dragged item is supported.

const [ dndState ] = useDragDropContext()

return (
  <DragDrop
    className="axis"
    dropTypes=['truthyValue']
    onDrop={(item) => onChange([...items, item])}
  >
    {items.map((x) => (
      <div>{x.name}</div>
    ))}
  </DragDrop>
);

Reordering

To create a reordering group, surround the elements from the same group with a ReorderProvider:

<ReorderProvider>... elements from one group here ...</ReorderProvider>

The children DragDrop components must have props defined as in the example:

<ReorderProvider>
  <div className="field-list">
    {fields.map((f) => (
      <DragDrop
        key={f.id}
        draggable
        dragType="move"
        dropTypes={["reorder"]} // generally shouldn't be set until a drag operation has started
        reorderableGroup={fields} // consists all reorderable elements in the group, eg. [{id:'3'}, {id:'5'}, {id:'1'}]
        value={{
          id: f.id,
          humanData: {
            label: 'Label'
          }
        }}
        onDrop={/*handler*/}
      >
        {f.name}
      </DragDrop>
    ))}
  </div>
</ReorderProvider>