[canvas] Replace react-beautiful-dnd with EuiDrapDrop (#102688)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Clint Andrew Hall 2021-06-30 20:28:21 -04:00 committed by GitHub
parent 81b9e73fed
commit fcd16dd87b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 88 deletions

View file

@ -9,15 +9,22 @@ import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { debounce } from 'lodash';
interface Props {
interface HeightProps {
elementId: string;
height: number;
width?: never;
}
interface WidthProps {
elementId: string;
width: number;
height?: never;
}
export class DomPreview extends PureComponent<Props> {
export class DomPreview extends PureComponent<HeightProps | WidthProps> {
static propTypes = {
elementId: PropTypes.string.isRequired,
height: PropTypes.number.isRequired,
height: PropTypes.number,
width: PropTypes.number,
};
_container: HTMLDivElement | null = null;
@ -78,9 +85,19 @@ export class DomPreview extends PureComponent<Props> {
const originalWidth = parseInt(originalStyle.getPropertyValue('width'), 10);
const originalHeight = parseInt(originalStyle.getPropertyValue('height'), 10);
const thumbHeight = this.props.height;
const scale = thumbHeight / originalHeight;
const thumbWidth = originalWidth * scale;
let thumbHeight = 0;
let thumbWidth = 0;
let scale = 1;
if (this.props.height) {
thumbHeight = this.props.height;
scale = thumbHeight / originalHeight;
thumbWidth = originalWidth * scale;
} else if (this.props.width) {
thumbWidth = this.props.width;
scale = thumbWidth / originalWidth;
thumbHeight = originalHeight * scale;
}
if (this._content.firstChild) {
this._content.removeChild(this._content.firstChild);

View file

@ -7,9 +7,18 @@
import React, { Fragment, Component } from 'react';
import PropTypes from 'prop-types';
import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui';
import {
EuiIcon,
EuiFlexGroup,
EuiFlexItem,
EuiText,
EuiToolTip,
EuiDragDropContext,
EuiDraggable,
EuiDroppable,
DragDropContextProps,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { DragDropContext, Droppable, Draggable, DragDropContextProps } from 'react-beautiful-dnd';
// @ts-expect-error untyped dependency
import Style from 'style-it';
@ -173,46 +182,37 @@ export class PageManager extends Component<Props, State> {
const pageNumber = i + 1;
return (
<Draggable key={page.id} draggableId={page.id} index={i} isDragDisabled={!isWriteable}>
{(provided) => (
<div
key={page.id}
className={`canvasPageManager__page ${
page.id === selectedPage ? 'canvasPageManager__page-isActive' : ''
}`}
ref={(el) => {
if (page.id === selectedPage) {
this._activePageRef = el;
}
provided.innerRef(el);
}}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<EuiFlexGroup gutterSize="s">
<EuiFlexItem grow={false}>
<EuiText size="xs" className="canvasPageManager__pageNumber">
{pageNumber}
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<WorkpadRoutingContext.Consumer>
{({ getUrl }) => (
<RoutingLink to={getUrl(pageNumber)}>
{Style.it(
workpadCSS,
<div>
<PagePreview height={100} page={page} onRemove={this.onConfirmRemove} />
</div>
)}
</RoutingLink>
<EuiDraggable
key={page.id}
draggableId={page.id}
index={i}
isDragDisabled={!isWriteable}
className={`canvasPageManager__page ${
page.id === selectedPage ? 'canvasPageManager__page-isActive' : ''
}`}
>
<EuiFlexGroup gutterSize="s">
<EuiFlexItem grow={false}>
<EuiText size="xs" className="canvasPageManager__pageNumber">
{pageNumber}
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<WorkpadRoutingContext.Consumer>
{({ getUrl }) => (
<RoutingLink to={getUrl(pageNumber)}>
{Style.it(
workpadCSS,
<div>
<PagePreview height={100} page={page} onRemove={this.onConfirmRemove} />
</div>
)}
</WorkpadRoutingContext.Consumer>
</EuiFlexItem>
</EuiFlexGroup>
</div>
)}
</Draggable>
</RoutingLink>
)}
</WorkpadRoutingContext.Consumer>
</EuiFlexItem>
</EuiFlexGroup>
</EuiDraggable>
);
};
@ -224,25 +224,17 @@ export class PageManager extends Component<Props, State> {
<Fragment>
<EuiFlexGroup gutterSize="none" className="canvasPageManager">
<EuiFlexItem className="canvasPageManager__pages">
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="droppable-page-manager" direction="horizontal">
{(provided) => (
<div
className={`canvasPageManager__pageList ${
showTrayPop ? 'canvasPageManager--trayPop' : ''
}`}
ref={(el) => {
this._pageListRef = el;
provided.innerRef(el);
}}
{...provided.droppableProps}
>
{pages.map(this.renderPage)}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
<EuiDragDropContext onDragEnd={this.onDragEnd}>
<EuiDroppable droppableId="droppable-page-manager" grow={true} direction="horizontal">
<div
className={`canvasPageManager__pageList ${
showTrayPop ? 'canvasPageManager--trayPop' : ''
}`}
>
{pages.map(this.renderPage)}
</div>
</EuiDroppable>
</EuiDragDropContext>
</EuiFlexItem>
{isWriteable && (
<EuiFlexItem grow={false}>

View file

@ -7,26 +7,28 @@
import { storiesOf } from '@storybook/react';
import React from 'react';
import { Toolbar } from '../toolbar.component';
// @ts-expect-error untyped local
import { getDefaultElement } from '../../../state/defaults';
// @ts-expect-error
import { getDefaultPage } from '../../../state/defaults';
import { reduxDecorator } from '../../../../storybook';
import { Toolbar } from '../toolbar';
const pages = [...new Array(10)].map(() => getDefaultPage());
const Pages = ({ story }: { story: Function }) => (
<div>
{story()}
<div style={{ visibility: 'hidden', position: 'absolute' }}>
{pages.map((page, index) => (
<div style={{ height: 66, width: 100, textAlign: 'center' }} id={page.id}>
<h1 style={{ paddingTop: 22 }}>Page {index}</h1>
</div>
))}
</div>
</div>
);
storiesOf('components/Toolbar', module)
.add('no element selected', () => (
<Toolbar
isWriteable={true}
selectedPageNumber={1}
totalPages={1}
workpadName={'My Canvas Workpad'}
/>
))
.add('element selected', () => (
<Toolbar
isWriteable={true}
selectedElement={getDefaultElement()}
selectedPageNumber={1}
totalPages={1}
workpadName={'My Canvas Workpad'}
/>
));
.addDecorator((story) => <Pages story={story} />)
.addDecorator(reduxDecorator({ pages }))
.add('redux', () => <Toolbar />);

View file

@ -15,7 +15,7 @@ import { set } from '@elastic/safer-lodash-set';
// @ts-expect-error Untyped local
import { getDefaultWorkpad } from '../../public/state/defaults';
import { CanvasWorkpad, CanvasElement, CanvasAsset } from '../../types';
import { CanvasWorkpad, CanvasElement, CanvasAsset, CanvasPage } from '../../types';
// @ts-expect-error untyped local
import { elementsRegistry } from '../../public/lib/elements_registry';
@ -27,18 +27,23 @@ export { ADDON_ID, ACTIONS_PANEL_ID } from '../addon/src/constants';
export interface Params {
workpad?: CanvasWorkpad;
pages?: CanvasPage[];
elements?: CanvasElement[];
assets?: CanvasAsset[];
}
export const reduxDecorator = (params: Params = {}) => {
const state = cloneDeep(getInitialState());
const { workpad, elements, assets } = params;
const { workpad, elements, assets, pages } = params;
if (workpad) {
set(state, 'persistent.workpad', workpad);
}
if (pages) {
set(state, 'persistent.workpad.pages', pages);
}
if (elements) {
set(state, 'persistent.workpad.pages.0.elements', elements);
}