diff --git a/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx b/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx
index 9e78c9b48bf2b..771bc97ceab42 100644
--- a/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx
+++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx
@@ -6,17 +6,30 @@
import React from 'react';
import { render, shallow, mount } from 'enzyme';
-import { DragDrop } from './drag_drop';
-import { ChildDragDropProvider } from './providers';
+import { DragDropInternal } from './drag_drop';
+import { DragContextState } from './providers';
jest.useFakeTimers();
+function mockContext(): DragContextState {
+ return {
+ dragging: undefined,
+ setDragging: jest.fn(),
+ };
+}
+
describe('DragDrop', () => {
test('renders if nothing is being dragged', () => {
const component = render(
-
+
Hello!
-
+
);
expect(component).toMatchSnapshot();
@@ -24,7 +37,11 @@ describe('DragDrop', () => {
test('dragover calls preventDefault if droppable is true', () => {
const preventDefault = jest.fn();
- const component = shallow(Hello!);
+ const component = shallow(
+
+ Hello!
+
+ );
component.find('[data-test-subj="lnsDragDrop"]').simulate('dragover', { preventDefault });
@@ -33,7 +50,11 @@ describe('DragDrop', () => {
test('dragover does not call preventDefault if droppable is false', () => {
const preventDefault = jest.fn();
- const component = shallow(Hello!);
+ const component = shallow(
+
+ Hello!
+
+ );
component.find('[data-test-subj="lnsDragDrop"]').simulate('dragover', { preventDefault });
@@ -41,7 +62,7 @@ describe('DragDrop', () => {
});
test('dragstart sets dragging in the context', async () => {
- const setDragging = jest.fn();
+ const context = mockContext();
const dataTransfer = {
setData: jest.fn(),
getData: jest.fn(),
@@ -49,9 +70,9 @@ describe('DragDrop', () => {
const value = {};
const component = mount(
-
- Hello!
-
+
+ Ahoy!
+
);
component.find('[data-test-subj="lnsDragDrop"]').simulate('dragstart', { dataTransfer });
@@ -59,22 +80,29 @@ describe('DragDrop', () => {
jest.runAllTimers();
expect(dataTransfer.setData).toBeCalledWith('text', 'dragging');
- expect(setDragging).toBeCalledWith(value);
+ expect(context.setDragging).toBeCalledWith(value);
});
test('drop resets all the things', async () => {
+ const context = mockContext();
const preventDefault = jest.fn();
const stopPropagation = jest.fn();
- const setDragging = jest.fn();
const onDrop = jest.fn();
const value = {};
+ context.dragging = 'hola';
+
const component = mount(
-
-
- Hello!
-
-
+
+ Ahoy!
+
);
component
@@ -83,20 +111,23 @@ describe('DragDrop', () => {
expect(preventDefault).toBeCalled();
expect(stopPropagation).toBeCalled();
- expect(setDragging).toBeCalledWith(undefined);
+ expect(context.setDragging).toBeCalledWith(undefined);
expect(onDrop).toBeCalledWith('hola');
});
test('droppable is reflected in the className', () => {
const component = render(
- {
throw x;
}}
droppable
>
Hello!
-
+
);
expect(component).toMatchSnapshot();
diff --git a/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx b/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx
index 35326a46a6820..1ac8c2c7eef40 100644
--- a/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx
+++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx
@@ -6,7 +6,7 @@
import React, { useState, useContext } from 'react';
import classNames from 'classnames';
-import { DragContext } from './providers';
+import { DragContext, DragContextState } from './providers';
type DroppableEvent = React.DragEvent;
@@ -54,6 +54,13 @@ interface Props {
draggable?: boolean;
}
+// For internal usage / test purposes only.
+type InternalProps = Props & {
+ context: DragContextState;
+ isActive: boolean;
+ setIsActive: (isActive: boolean) => void;
+};
+
/**
* A draggable / droppable item. Items can be both draggable and droppable at
* the same time.
@@ -61,14 +68,40 @@ interface Props {
* @param props
*/
export function DragDrop(props: Props) {
- const { dragging, setDragging } = useContext(DragContext);
+ const context = useContext(DragContext);
const [state, setState] = useState({ isActive: false });
- const { className, onDrop, value, children, droppable, draggable } = props;
+
+ return (
+ setState({ isActive })}
+ {...props}
+ />
+ );
+}
+
+/**
+ * For internal usage / test purposes only.
+ */
+export function DragDropInternal(props: InternalProps) {
+ const {
+ className,
+ onDrop,
+ value,
+ children,
+ droppable,
+ draggable,
+ context,
+ isActive,
+ setIsActive,
+ } = props;
+ const { dragging, setDragging } = context;
const isDragging = draggable && value === dragging;
const classes = classNames('lnsDragDrop', className, {
'lnsDragDrop-isDropTarget': droppable,
- 'lnsDragDrop-isActiveDropTarget': droppable && state.isActive,
+ 'lnsDragDrop-isActiveDropTarget': droppable && isActive,
'lnsDragDrop-isDragging': isDragging,
});
@@ -100,20 +133,20 @@ export function DragDrop(props: Props) {
e.preventDefault();
// An optimization to prevent a bunch of React churn.
- if (!state.isActive) {
- setState({ ...state, isActive: true });
+ if (!isActive) {
+ setIsActive(true);
}
};
const dragLeave = () => {
- setState({ ...state, isActive: false });
+ setIsActive(false);
};
const drop = (e: DroppableEvent) => {
e.preventDefault();
e.stopPropagation();
- setState({ ...state, isActive: false });
+ setIsActive(false);
setDragging(undefined);
if (onDrop) {
diff --git a/x-pack/plugins/lens/public/drag_drop/index.ts b/x-pack/plugins/lens/public/drag_drop/index.ts
index e597bb8b6e893..24860e83c0c8b 100644
--- a/x-pack/plugins/lens/public/drag_drop/index.ts
+++ b/x-pack/plugins/lens/public/drag_drop/index.ts
@@ -5,4 +5,4 @@
*/
export * from './providers';
-export * from './drag_drop';
+export { DragDrop } from './drag_drop';