-
+ <>
{filteredColumns.map((id, index) => (
{(provided, state) => (
))}
-
+ >
diff --git a/src/components/datagrid/controls/column_sorting_draggable.tsx b/src/components/datagrid/controls/column_sorting_draggable.tsx
index a26b08b00c0..2fa7f1264b3 100644
--- a/src/components/datagrid/controls/column_sorting_draggable.tsx
+++ b/src/components/datagrid/controls/column_sorting_draggable.tsx
@@ -7,6 +7,8 @@
*/
import React, { FunctionComponent } from 'react';
+import classNames from 'classnames';
+
import { EuiScreenReaderOnly } from '../../accessibility';
import { EuiButtonGroup, EuiButtonIcon } from '../../button';
import { EuiDraggable } from '../../drag_and_drop';
@@ -78,9 +80,9 @@ export const EuiDataGridColumnSortingDraggable: FunctionComponent<
>
{(provided, state) => (
diff --git a/src/components/datagrid/data_grid.test.tsx b/src/components/datagrid/data_grid.test.tsx
index 6310d80483c..c6c48e0fa77 100644
--- a/src/components/datagrid/data_grid.test.tsx
+++ b/src/components/datagrid/data_grid.test.tsx
@@ -1813,7 +1813,7 @@ describe('EuiDataGrid', () => {
let popover = openColumnSelector(component);
expect(
popover
- .find('.euiDataGridColumnSelector__item')
+ .find('div.euiDataGridColumnSelector__item')
.map((item) => item.text())
).toEqual(['A', 'B']);
closeColumnSelector(component);
@@ -1831,7 +1831,7 @@ describe('EuiDataGrid', () => {
popover = openColumnSelector(component);
expect(
popover
- .find('.euiDataGridColumnSelector__item')
+ .find('div.euiDataGridColumnSelector__item')
.map((item) => item.text())
).toEqual(['A', 'C']);
closeColumnSelector(component);
diff --git a/src/components/drag_and_drop/__snapshots__/drag_drop_context.test.tsx.snap b/src/components/drag_and_drop/__snapshots__/drag_drop_context.test.tsx.snap
index 0cebb4a6dc4..1514a4db265 100644
--- a/src/components/drag_and_drop/__snapshots__/drag_drop_context.test.tsx.snap
+++ b/src/components/drag_and_drop/__snapshots__/drag_drop_context.test.tsx.snap
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`EuiDragDropContext is rendered 1`] = `
`;
+exports[`EuiDragDropContext renders 1`] = ``;
diff --git a/src/components/drag_and_drop/__snapshots__/draggable.test.tsx.snap b/src/components/drag_and_drop/__snapshots__/draggable.test.tsx.snap
index 5057e393180..9784c6be25d 100644
--- a/src/components/drag_and_drop/__snapshots__/draggable.test.tsx.snap
+++ b/src/components/drag_and_drop/__snapshots__/draggable.test.tsx.snap
@@ -2,25 +2,25 @@
exports[`[React 17] EuiDraggable renders 1`] = `
Hello
@@ -33,25 +33,25 @@ exports[`[React 17] EuiDraggable renders 1`] = `
exports[`[React 18] EuiDraggable renders 1`] = `
Hello
diff --git a/src/components/drag_and_drop/__snapshots__/droppable.test.tsx.snap b/src/components/drag_and_drop/__snapshots__/droppable.test.tsx.snap
index ca502ceeded..5fec44c8567 100644
--- a/src/components/drag_and_drop/__snapshots__/droppable.test.tsx.snap
+++ b/src/components/drag_and_drop/__snapshots__/droppable.test.tsx.snap
@@ -1,89 +1,93 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`[React 17] EuiDroppable can be given ReactElement children 1`] = `
-
-
+exports[`[React 17] EuiDroppable renders 1`] = `
+
-
-`;
-
-exports[`[React 17] EuiDroppable can be given multiple ReactElement children 1`] = `
-
-`;
-
-exports[`[React 17] EuiDroppable is rendered 1`] = `
-
+
+
+ Press space bar to start a drag.
+ When dragging you can use the arrow keys to move the item around and escape to cancel.
+ Some screen readers may require you to be in focus mode or to use your pass through key
+
+
+
`;
-exports[`[React 18] EuiDroppable can be given ReactElement children 1`] = `
-
-
+exports[`[React 18] EuiDroppable renders 1`] = `
+
-
-`;
-
-exports[`[React 18] EuiDroppable can be given multiple ReactElement children 1`] = `
-
-`;
-
-exports[`[React 18] EuiDroppable is rendered 1`] = `
-
+
+
+ Press space bar to start a drag.
+ When dragging you can use the arrow keys to move the item around and escape to cancel.
+ Some screen readers may require you to be in focus mode or to use your pass through key
+
+
+
`;
diff --git a/src/components/drag_and_drop/_draggable.scss b/src/components/drag_and_drop/_draggable.scss
deleted file mode 100644
index b631df02198..00000000000
--- a/src/components/drag_and_drop/_draggable.scss
+++ /dev/null
@@ -1,41 +0,0 @@
-.euiDraggable {
- &.euiDraggable--isDragging {
- // Overriding inline styles on JS-inserted HTML elements
- z-index: $euiZLevel9 !important; // stylelint-disable-line declaration-no-important
- }
-
- &.euiDraggable--hasClone:not(.euiDraggable--isDragging) {
- // Overriding inline styles on JS-inserted HTML elements
- transform: none !important; // stylelint-disable-line declaration-no-important
- }
-
- &.euiDraggable--withoutDropAnimation {
- // Overriding inline styles on JS-inserted HTML elements
- transition-duration: .001s !important; // stylelint-disable-line declaration-no-important
- }
-
- &:focus > .euiDraggable__item,
- &.euiDraggable--hasCustomDragHandle > .euiDraggable__item [data-react-beautiful-dnd-drag-handle]:focus {
- @include euiFocusRing;
- }
-
- .euiDraggable__item {
- &.euiDraggable__item--isDisabled {
- cursor: not-allowed;
- }
-
- &.euiDraggable__item--isDragging {
- // TODO: Resolve below
- // Commenting this out for now,
- // I'm thinking about adding an optional prop to auto-add these styles versus always having them
- // @include euiBottomShadow;
- // @include euiFocusRing;
- }
- }
-}
-
-@each $size, $spacing in $euiDragAndDropSpacing {
- .euiDraggable--#{$size} {
- padding: $spacing;
- }
-}
diff --git a/src/components/drag_and_drop/_droppable.scss b/src/components/drag_and_drop/_droppable.scss
deleted file mode 100644
index de9e73c002d..00000000000
--- a/src/components/drag_and_drop/_droppable.scss
+++ /dev/null
@@ -1,40 +0,0 @@
-.euiDroppable {
- $euiDroppableColor: $euiColorSuccess;
- transition: background-color $euiAnimSpeedExtraSlow ease;
-
- &.euiDroppable--isDraggingType:not(.euiDroppable--isDisabled) {
- background-color: transparentize($euiDroppableColor, .9);
-
- &.euiDroppable--isDraggingOver {
- background-color: transparentize($euiDroppableColor, .75);
- }
- }
-
- .euiDroppable__placeholder {
- &.euiDroppable__placeholder--isHidden {
- // Overriding inline styles on JS-inserted HTML elements
- display: none !important; // stylelint-disable-line declaration-no-important
- }
- }
-}
-
-@include euiPanel($selector: '.euiDroppable--withPanel');
-
-.euiDroppable--withPanel {
- @include euiBottomShadowMedium;
- border-radius: $euiBorderRadius;
-}
-
-.euiDroppable--noGrow {
- flex-grow: 0;
-}
-
-.euiDroppable--grow {
- flex-grow: 1;
-}
-
-@each $size, $spacing in $euiDragAndDropSpacing {
- .euiDroppable--#{$size} {
- padding: $spacing;
- }
-}
diff --git a/src/components/drag_and_drop/_index.scss b/src/components/drag_and_drop/_index.scss
deleted file mode 100644
index e3ae587b279..00000000000
--- a/src/components/drag_and_drop/_index.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-@import 'variables';
-@import 'draggable';
-@import 'droppable';
diff --git a/src/components/drag_and_drop/_variables.scss b/src/components/drag_and_drop/_variables.scss
deleted file mode 100644
index 65dc0d6a8b0..00000000000
--- a/src/components/drag_and_drop/_variables.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-$euiDragAndDropSpacing: (
- s: ($euiSizeXS / 2),
- m: ($euiSizeS / 2),
- l: ($euiSize / 2),
-);
diff --git a/src/components/drag_and_drop/drag_drop_context.test.tsx b/src/components/drag_and_drop/drag_drop_context.test.tsx
index 6768442df9f..5e800d8f726 100644
--- a/src/components/drag_and_drop/drag_drop_context.test.tsx
+++ b/src/components/drag_and_drop/drag_drop_context.test.tsx
@@ -7,59 +7,40 @@
*/
import React from 'react';
-import { mount, ReactWrapper } from 'enzyme';
-
-import { findTestSubject } from '../../test';
+import { render } from '../../test/rtl';
import { requiredProps } from '../../test/required_props';
-import { EuiDragDropContext } from './';
-import { EuiDragDropContextContext } from './drag_drop_context';
-
-function snapshotDragDropContext(component: ReactWrapper) {
- // Get the Portal's sibling and return its html
- const renderedHtml = component.html();
- const container = document.createElement('div');
- container.innerHTML = renderedHtml;
- return container.firstChild;
-}
+import {
+ EuiDragDropContext,
+ EuiDragDropContextContext,
+} from './drag_drop_context';
describe('EuiDragDropContext', () => {
- test('is rendered', () => {
- const handler = jest.fn();
- const component = mount(
-
+ it('renders', () => {
+ const { container } = render(
+ {}} {...requiredProps}>
);
- expect(snapshotDragDropContext(component)).toMatchSnapshot();
+ expect(container.firstChild).toMatchSnapshot();
});
- describe('custom behavior', () => {
- describe('isDraggingType', () => {
- test('is set on proprietary context', () => {
- jest.mock('react', () => {
- const react = jest.requireActual('react');
- return {
- ...react,
- useLayoutEffect: react.useEffect,
- };
- });
- const handler = jest.fn();
- const component = mount(
-
-
- {(value) => (
-
- {value.hasOwnProperty('isDraggingType') ? 'true' : 'false'}
-
- )}
-
-
- );
-
- expect(findTestSubject(component, 'child').text()).toBe('true');
- });
+ describe('isDraggingType', () => {
+ test('is set on proprietary context', () => {
+ const { getByTestSubject } = render(
+ {}}>
+
+ {(value) => (
+
+ {value.hasOwnProperty('isDraggingType') ? 'true' : 'false'}
+
+ )}
+
+
+ );
+
+ expect(getByTestSubject('child')).toHaveTextContent('true');
});
});
});
diff --git a/src/components/drag_and_drop/draggable.styles.ts b/src/components/drag_and_drop/draggable.styles.ts
new file mode 100644
index 00000000000..553147a1327
--- /dev/null
+++ b/src/components/drag_and_drop/draggable.styles.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { css } from '@emotion/react';
+
+import { UseEuiTheme } from '../../services';
+import { sharedSpacingPadding } from './droppable.styles';
+
+export const euiDraggableStyles = (euiThemeContext: UseEuiTheme) => {
+ const { euiTheme } = euiThemeContext;
+
+ return {
+ euiDraggable: css`
+ &:focus {
+ outline: none;
+
+ & > .euiDraggable__item {
+ outline: auto;
+ }
+ }
+
+ /* !importants in this file override inline styles on JS-inserted HTML elements */
+ /* stylelint-disable declaration-no-important */
+ `,
+ isDragging: css`
+ z-index: ${euiTheme.levels.toast} !important;
+ `,
+ hasClone: css`
+ transform: none !important;
+ `,
+ isRemovable: css`
+ /* Removes the drop animation */
+ transition-duration: 0.001s !important;
+ `,
+ spacing: sharedSpacingPadding(euiThemeContext),
+ };
+};
+
+export const euiDraggableItemStyles = {
+ euiDraggable__item: css``,
+ disabled: css`
+ cursor: not-allowed;
+ `,
+};
diff --git a/src/components/drag_and_drop/draggable.test.tsx b/src/components/drag_and_drop/draggable.test.tsx
index 3b7d4dd43f2..8de9ca0c5dd 100644
--- a/src/components/drag_and_drop/draggable.test.tsx
+++ b/src/components/drag_and_drop/draggable.test.tsx
@@ -7,84 +7,90 @@
*/
import React from 'react';
-import { render, screen } from '../../test/rtl';
+import { render } from '../../test/rtl';
import { requiredProps } from '../../test';
-import { describeByReactVersion } from '../../test/internal';
-import { EuiDragDropContext, EuiDraggable, EuiDroppable } from './';
+import {
+ shouldRenderCustomStyles,
+ describeByReactVersion,
+} from '../../test/internal';
+
+import { EuiDragDropContext, EuiDroppable } from './';
+import { EuiDraggable } from './draggable';
describeByReactVersion('EuiDraggable', () => {
- it('renders', () => {
- const handler = jest.fn();
+ const TestContextWrapper = ({ children }: { children: any }) => (
+ {}}>
+ {children}
+
+ );
+
+ shouldRenderCustomStyles(
+
+ {() => Hello
}
+ ,
+ { wrapper: TestContextWrapper }
+ );
+ it('renders', () => {
const { container } = render(
-
-
-
- {() => Hello
}
-
-
-
+
+
+ {() => Hello
}
+
+
);
- expect(screen.getByTestSubject('draggable')).toBeVisible();
expect(container.firstChild).toMatchSnapshot();
});
it('renders with render prop children', () => {
- const handler = jest.fn();
-
- render(
-
-
-
- {() => Hello
}
-
-
-
+ const { getByTestSubject } = render(
+
+
+ {() => Hello
}
+
+
);
- expect(screen.getByText('Hello')).toBeVisible();
+ expect(getByTestSubject('draggable')).toHaveTextContent('Hello');
});
it('renders with react element children', () => {
- const handler = jest.fn();
-
- render(
-
-
-
- Hello
-
-
-
+ const { getByTestSubject } = render(
+
+
+ Hello
+
+
);
- expect(screen.getByText('Hello')).toBeVisible();
+ expect(getByTestSubject('draggable')).toHaveTextContent('Hello');
});
it('should render with role="group" and no tabIndex when hasInteractiveChildren is true', () => {
- const handler = jest.fn();
-
- const doRender = (hasInteractiveChildren: boolean) =>
- render(
-
-
-
- Hello
-
-
-
- );
+ const Test = ({
+ hasInteractiveChildren,
+ }: {
+ hasInteractiveChildren: boolean;
+ }) => (
+
+
+ Hello
+
+
+ );
- doRender(false);
- expect(screen.queryByRole('group')).toBeNull();
+ const { queryByRole, rerender } = render(
+
+ );
+ expect(queryByRole('group')).toBeNull();
- doRender(true);
- expect(screen.getByRole('group')).toBeVisible();
- expect(screen.getByRole('group')).not.toHaveAttribute('tabindex', 0);
+ rerender();
+ expect(queryByRole('group')).toBeVisible();
+ expect(queryByRole('group')).not.toHaveAttribute('tabindex', 0);
});
});
diff --git a/src/components/drag_and_drop/draggable.tsx b/src/components/drag_and_drop/draggable.tsx
index 0d343deacab..a9fb66dacc5 100644
--- a/src/components/drag_and_drop/draggable.tsx
+++ b/src/components/drag_and_drop/draggable.tsx
@@ -8,25 +8,18 @@
import React, {
CSSProperties,
- Fragment,
FunctionComponent,
ReactElement,
- cloneElement,
useContext,
} from 'react';
import { Draggable, DraggableProps } from '@hello-pangea/dnd';
import classNames from 'classnames';
-import { CommonProps } from '../common';
-import { EuiDroppableContext } from './droppable';
-const spacingToClassNameMap = {
- none: null,
- s: 'euiDraggable--s',
- m: 'euiDraggable--m',
- l: 'euiDraggable--l',
-};
+import { useEuiTheme, cloneElementWithCss } from '../../services';
+import { CommonProps } from '../common';
-export type EuiDraggableSpacing = keyof typeof spacingToClassNameMap;
+import { EuiDroppableContext, SPACINGS } from './droppable';
+import { euiDraggableStyles, euiDraggableItemStyles } from './draggable.styles';
export interface EuiDraggableProps
extends CommonProps,
@@ -52,7 +45,7 @@ export interface EuiDraggableProps
/**
* Adds padding to the draggable item
*/
- spacing?: EuiDraggableSpacing;
+ spacing?: (typeof SPACINGS)[number];
style?: CSSProperties;
}
@@ -72,6 +65,9 @@ export const EuiDraggable: FunctionComponent = ({
}) => {
const { cloneItems } = useContext(EuiDroppableContext);
+ const euiTheme = useEuiTheme();
+ const styles = euiDraggableStyles(euiTheme);
+
return (
= ({
{...rest}
>
{(provided, snapshot, rubric) => {
- const classes = classNames(
- 'euiDraggable',
- {
- 'euiDraggable--hasClone': cloneItems,
- 'euiDraggable--hasCustomDragHandle': customDragHandle,
- 'euiDraggable--isDragging': snapshot.isDragging,
- 'euiDraggable--withoutDropAnimation': isRemovable,
- },
- spacingToClassNameMap[spacing],
- className
- );
+ const { isDragging } = snapshot;
+
+ const cssStyles = [
+ styles.euiDraggable,
+ cloneItems && !isDragging && styles.hasClone,
+ isDragging && styles.isDragging,
+ isRemovable && styles.isRemovable,
+ styles.spacing[spacing],
+ ];
+
+ const classes = classNames('euiDraggable', className);
const childClasses = classNames('euiDraggable__item', {
- 'euiDraggable__item--hasCustomDragHandle': customDragHandle,
- 'euiDraggable__item--isDisabled': isDragDisabled,
- 'euiDraggable__item--isDragging': snapshot.isDragging,
- 'euiDraggable__item--isDropAnimating': snapshot.isDropAnimating,
+ 'euiDraggable__item-isDisabled': isDragDisabled,
});
const DraggableElement: ReactElement =
typeof children === 'function'
? (children(provided, snapshot, rubric) as ReactElement)
: children;
return (
-
+ <>
= ({
: provided.dragHandleProps?.tabIndex
}
>
- {cloneElement(DraggableElement, {
+ {cloneElementWithCss(DraggableElement, {
className: classNames(
DraggableElement.props.className,
childClasses
),
+ css: [
+ euiDraggableItemStyles.euiDraggable__item,
+ isDragDisabled && euiDraggableItemStyles.disabled,
+ ],
})}
- {cloneItems && snapshot.isDragging && (
-
+ {cloneItems && isDragging && (
+
{DraggableElement}
)}
-
+ >
);
}}
diff --git a/src/components/drag_and_drop/droppable.styles.ts b/src/components/drag_and_drop/droppable.styles.ts
new file mode 100644
index 00000000000..dd4bf3726d2
--- /dev/null
+++ b/src/components/drag_and_drop/droppable.styles.ts
@@ -0,0 +1,53 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { css } from '@emotion/react';
+
+import { UseEuiTheme, transparentize } from '../../services';
+import { euiCanAnimate } from '../../global_styling';
+
+export const euiDroppableStyles = (euiThemeContext: UseEuiTheme) => {
+ const { euiTheme } = euiThemeContext;
+
+ const droppableColor = euiTheme.colors.success;
+
+ return {
+ euiDroppable: css`
+ ${euiCanAnimate} {
+ transition: background-color ${euiTheme.animation.slow} ease;
+ }
+ `,
+ isDragging: css`
+ background-color: ${transparentize(droppableColor, 0.1)};
+ `,
+ isDraggingOver: css`
+ background-color: ${transparentize(droppableColor, 0.25)};
+ `,
+ grow: css`
+ flex-grow: 1;
+ `,
+ noGrow: css`
+ flex-grow: 0;
+ `,
+ spacing: sharedSpacingPadding(euiThemeContext),
+ };
+};
+
+// Droppable and draggable components both have the same shared spacing/padding values
+export const sharedSpacingPadding = ({ euiTheme }: UseEuiTheme) => ({
+ none: null,
+ s: css`
+ padding: ${euiTheme.size.xxs};
+ `,
+ m: css`
+ padding: ${euiTheme.size.xs};
+ `,
+ l: css`
+ padding: ${euiTheme.size.s};
+ `,
+});
diff --git a/src/components/drag_and_drop/droppable.test.tsx b/src/components/drag_and_drop/droppable.test.tsx
index 6fee1e123b7..71fabfa6056 100644
--- a/src/components/drag_and_drop/droppable.test.tsx
+++ b/src/components/drag_and_drop/droppable.test.tsx
@@ -7,140 +7,91 @@
*/
import React from 'react';
-import { mount, ReactWrapper } from 'enzyme';
import { resetServerContext } from '@hello-pangea/dnd';
-
-import { findTestSubject, requiredProps } from '../../test';
+import { render } from '../../test/rtl';
+import { requiredProps } from '../../test';
import {
+ shouldRenderCustomStyles,
invokeOnReactVersion,
describeByReactVersion,
} from '../../test/internal';
-import { EuiDragDropContext, EuiDroppable } from './';
-import { EuiDroppableContext } from './droppable';
-
-function snapshotDragDropContext(component: ReactWrapper) {
- // Get the Portal's sibling and return its html
- const renderedHtml = component.html();
- const container = document.createElement('div');
- container.innerHTML = renderedHtml;
- return container.firstChild;
-}
+import { EuiDragDropContext } from './drag_drop_context';
+import { EuiDroppable, EuiDroppableContext } from './droppable';
describeByReactVersion('EuiDroppable', () => {
+ const requiredContextProps = { onDragEnd: () => {} };
+
afterEach(() => {
// Resetting DND server context is only required in older versions of React
invokeOnReactVersion(['16', '17'], resetServerContext);
});
- test('is rendered', () => {
- const handler = jest.fn();
- jest.mock('react', () => {
- const react = jest.requireActual('react');
- return {
- ...react,
- useLayoutEffect: react.useEffect,
- };
- });
- const component = mount(
-
- {() => }
+ shouldRenderCustomStyles(
+ {() => },
+ { wrapper: EuiDragDropContext }
+ );
+
+ it('renders', () => {
+ const { baseElement } = render(
+
+
+ {() => }
+
);
- expect(snapshotDragDropContext(component)).toMatchSnapshot();
+ expect(baseElement).toMatchSnapshot();
});
- test('can be given ReactElement children', () => {
- const handler = jest.fn();
- jest.mock('react', () => {
- const react = jest.requireActual('react');
- return {
- ...react,
- useLayoutEffect: react.useEffect,
- };
- });
- const component = mount(
-
+ it('can be given ReactElement children', () => {
+ const { getByTestSubject } = render(
+
-
+
);
- expect(snapshotDragDropContext(component)).toMatchSnapshot();
+ expect(getByTestSubject('reactChildren')).toBeInTheDocument();
});
- test('can be given multiple ReactElement children', () => {
- const handler = jest.fn();
- jest.mock('react', () => {
- const react = jest.requireActual('react');
- return {
- ...react,
- useLayoutEffect: react.useEffect,
- };
- });
-
- const component = mount(
-
+ it('can be given multiple ReactElement children', () => {
+ const { getByTestSubject } = render(
+
-
-
-
+
+
+
);
- expect(snapshotDragDropContext(component)).toMatchSnapshot();
+ expect(getByTestSubject('A')).toBeInTheDocument();
+ expect(getByTestSubject('B')).toBeInTheDocument();
+ expect(getByTestSubject('C')).toBeInTheDocument();
});
- describe('custom behavior', () => {
- describe('cloneDraggables', () => {
- jest.mock('react', () => {
- const react = jest.requireActual('react');
- return {
- ...react,
- useLayoutEffect: react.useEffect,
- };
- });
-
- test('sets `cloneItems` on proprietary context', () => {
- const handler = jest.fn();
- const component = mount(
-
-
-
- {({ cloneItems }) => (
-
- {cloneItems ? 'true' : 'false'}
-
- )}
-
-
-
- );
-
- expect(findTestSubject(component, 'child').text()).toBe('true');
- });
-
- test('sets `isDropDisabled`', () => {
- const handler = jest.fn();
- const component = mount(
-
-
-
- {({ cloneItems }) => (
-
- {cloneItems ? 'true' : 'false'}
-
- )}
-
-
-
- );
-
- expect(component.find('.euiDroppable--isDisabled').length).toBe(1);
- });
+ describe('cloneDraggables', () => {
+ it('sets `cloneItems` and `isDropDisabled` on proprietary context', () => {
+ const { container, getByTestSubject } = render(
+
+
+
+ {({ cloneItems }) => (
+
+ {cloneItems ? 'true' : 'false'}
+
+ )}
+
+
+
+ );
+
+ expect(getByTestSubject('child')).toHaveTextContent('true');
+ expect(
+ container.querySelector('.euiDroppable-isDisabled')
+ ).toBeInTheDocument();
});
});
});
diff --git a/src/components/drag_and_drop/droppable.tsx b/src/components/drag_and_drop/droppable.tsx
index 735dc01f26b..a836cd05e47 100644
--- a/src/components/drag_and_drop/droppable.tsx
+++ b/src/components/drag_and_drop/droppable.tsx
@@ -14,17 +14,15 @@ import React, {
} from 'react';
import { Droppable, DroppableProps } from '@hello-pangea/dnd';
import classNames from 'classnames';
+
+import { useEuiTheme } from '../../services';
import { CommonProps } from '../common';
-import { EuiDragDropContextContext } from './drag_drop_context';
+import { EuiPanel } from '../panel';
-const spacingToClassNameMap = {
- none: null,
- s: 'euiDroppable--s',
- m: 'euiDroppable--m',
- l: 'euiDroppable--l',
-};
+import { EuiDragDropContextContext } from './drag_drop_context';
+import { euiDroppableStyles } from './droppable.styles';
-export type EuiDroppableSpacing = keyof typeof spacingToClassNameMap;
+export const SPACINGS = ['none', 's', 'm', 'l'] as const;
export interface EuiDroppableProps
extends CommonProps,
@@ -42,7 +40,7 @@ export interface EuiDroppableProps
/**
* Adds padding to the droppable area
*/
- spacing?: EuiDroppableSpacing;
+ spacing?: (typeof SPACINGS)[number];
/**
* Adds an EuiPanel style to the droppable area
*/
@@ -74,6 +72,10 @@ export const EuiDroppable: FunctionComponent = ({
}) => {
const { isDraggingType } = useContext(EuiDragDropContextContext);
const dropIsDisabled: boolean = cloneDraggables ? true : isDropDisabled;
+
+ const euiTheme = useEuiTheme();
+ const styles = euiDroppableStyles(euiTheme);
+
return (
= ({
{...rest}
>
{(provided, snapshot) => {
+ const { isDraggingOver } = snapshot;
+
+ const PanelOrDiv = withPanel ? EuiPanel : 'div';
+ const panelOrDivProps = withPanel
+ ? {
+ panelRef: provided.innerRef,
+ hasShadow: true,
+ paddingSize: 'none' as const,
+ }
+ : { ref: provided.innerRef };
+
+ const cssStyles = [
+ styles.euiDroppable,
+ isDraggingType === type && !dropIsDisabled && styles.isDragging,
+ isDraggingOver && styles.isDraggingOver,
+ grow ? styles.grow : styles.noGrow,
+ styles.spacing[spacing],
+ ];
+
const classes = classNames(
'euiDroppable',
- {
- 'euiDroppable--isDisabled': dropIsDisabled,
- 'euiDroppable--isDraggingOver': snapshot.isDraggingOver,
- 'euiDroppable--isDraggingType': isDraggingType === type,
- 'euiDroppable--withPanel': withPanel,
- 'euiDroppable--grow': grow,
- 'euiDroppable--noGrow': !grow,
- },
- spacingToClassNameMap[spacing],
+ { 'euiDroppable-isDisabled': dropIsDisabled },
className
);
- const placeholderClasses = classNames('euiDroppable__placeholder', {
- 'euiDroppable__placeholder--isHidden': cloneDraggables,
- });
+
const DroppableElement =
typeof children === 'function'
? children(provided, snapshot)
: children;
+
return (
-
= ({
>
{DroppableElement}
-
{provided.placeholder}
-
+
+ {provided.placeholder}
+
+
);
}}
diff --git a/src/components/index.scss b/src/components/index.scss
index a381f8cdea8..e916bfccef7 100644
--- a/src/components/index.scss
+++ b/src/components/index.scss
@@ -6,7 +6,6 @@
@import 'control_bar/index';
@import 'date_picker/index';
@import 'datagrid/index';
-@import 'drag_and_drop/index';
@import 'empty_prompt/index';
@import 'form/index';
@import 'markdown_editor/index';
diff --git a/upcoming_changelogs/7187.md b/upcoming_changelogs/7187.md
new file mode 100644
index 00000000000..369e9205a09
--- /dev/null
+++ b/upcoming_changelogs/7187.md
@@ -0,0 +1,3 @@
+**CSS-in-JS conversions**
+
+- Converted `EuiDroppable` and `EuiDraggable` to Emotion; Removed `$euiDragAndDropSpacing` Sass variables