Skip to content

Commit

Permalink
feat(DragDrop): new drag and drop solution for reordering lists
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolethoen committed Jan 23, 2023
1 parent b914e49 commit 790e962
Show file tree
Hide file tree
Showing 42 changed files with 918 additions and 189 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,6 @@ import { css } from '@patternfly/react-styles';
```ts file="./DataListControllingText.tsx"
```

### Draggable

Draggable data lists used to have their own HTML5-based API for drag and drop, which wasn't able to fulfill requirements such as custom styling on items being dragged. So we wrote generic `DragDrop`, `Draggable`, and `Droppable` components for this purpose. Use those new components instead of the deprecated (and buggy!) HTML5-based API.

Note: Keyboard accessibility and screen reader accessibility for the `DragDrop` component are still in development.

```ts isBeta file="./DataListDraggable.tsx"
```

### Small grid breakpoint

```ts file="./DataListSmGridBreakpoint.tsx"
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -78,25 +78,6 @@ The dual list selector can also be built in a composable manner to make customiz
```ts file="./DualListSelectorComposable.tsx"
```

### Composable with drag and drop

This example only allows reordering the contents of the "chosen" pane with drag and drop. To make a pane able to be reordered:

- wrap the `DualListSelectorPane` in a `DragDrop` component
- wrap the `DualListSelectorList` in a `Droppable` component
- wrap the `DualListSelectorListItem` components in a `Draggable` component
- define an `onDrop` callback which reorders the sortable options.
- The `onDrop` function provides the starting location and destination location for a dragged item. It should return
true to enable the 'drop' animation in the new location and false to enable the 'drop' animation back to the item's
old position.
- define an `onDrag` callback which ensures that the drag event will not cross hairs with the `onOptionSelect` click
event set on the option. Note: the `ignoreNextOptionSelect` state value is used to prevent selection while dragging.

Note: Keyboard accessibility and screen reader accessibility for the `DragDrop` component are still in development.

```ts file="DualListSelectorComposableDragDrop.tsx"
```

### Composable with tree

```ts file="DualListSelectorComposableTree.tsx"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './DualListSelectorPane';
export * from './DualListSelectorList';
export * from './DualListSelectorListItem';
export * from './DualListSelectorTree';
export * from './DualListSelectorContext';
1 change: 0 additions & 1 deletion packages/react-core/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ export * from './Tooltip';
export * from './NumberInput';
export * from './TreeView';
export * from './Wizard';
export * from './DragDrop';
export * from './TextInputGroup';
export * from './Panel';
export * from './Truncate';
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { DragDrop, Draggable, Droppable } from '@patternfly/react-core';
import { DragDrop, Draggable, Droppable } from '@patternfly/react-core/deprecated';

interface ItemType {
id: string;
Expand All @@ -20,20 +20,19 @@ const getItems = (count: number) =>
}));

const reorder = (list: ItemType[], startIndex: number, endIndex: number) => {
const result = list;
const result = [...list];
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};

export const DragDropBasic: React.FunctionComponent = () => {
const [items, setItems] = React.useState(getItems(10));
const [items, setItems] = React.useState<ItemType[]>(getItems(10));

function onDrop(source: SourceType, dest: DestinationType) {
if (dest) {
const newItems = reorder(items, source.index, dest.index);
setItems(newItems);

return true;
}
return false;
Expand All @@ -42,8 +41,8 @@ export const DragDropBasic: React.FunctionComponent = () => {
return (
<DragDrop onDrop={onDrop}>
<Droppable>
{items.map(({ content }, i) => (
<Draggable key={i} style={{ padding: '8px' }}>
{items.map(({ id, content }) => (
<Draggable key={id} style={{ padding: '8px' }}>
{content}
</Draggable>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { DragDrop, Draggable, Droppable, Split, SplitItem } from '@patternfly/react-core';
import { DragDrop, Draggable, Droppable } from '@patternfly/react-core/deprecated';
import { Split, SplitItem } from '@patternfly/react-core';

interface ItemType {
id: string;
Expand All @@ -11,6 +12,11 @@ interface SourceType {
index: number;
}

interface MultipleListState {
items1: ItemType[];
items2: ItemType[];
}

interface DestinationType extends SourceType {}

const getItems = (count: number, startIndex: number) =>
Expand All @@ -35,7 +41,7 @@ const move = (source: ItemType[], destination: ItemType[], sourceIndex: number,
};

export const DragDropMultipleLists: React.FunctionComponent = () => {
const [items, setItems] = React.useState({
const [items, setItems] = React.useState<MultipleListState>({
items1: getItems(10, 0),
items2: getItems(5, 10)
});
Expand Down Expand Up @@ -84,7 +90,7 @@ export const DragDropMultipleLists: React.FunctionComponent = () => {
{Object.entries(items).map(([key, subitems]) => (
<SplitItem key={key} style={{ flex: 1 }}>
<Droppable zone="multizone" droppableId={key}>
{subitems.map(({ id, content }) => (
{(subitems as ItemType[]).map(({ id, content }) => (
<Draggable key={id} style={{ padding: '8px' }}>
{content}
</Draggable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ section: components
propComponents: [DragDrop, Draggable, Droppable, DraggableItemPosition]
beta: true
---
import { DragDrop, Draggable, Droppable } from '@patternfly/react-core/deprecated';

You can use the `DragDrop` component to move items in or between lists. The `DragDrop` component should contain `Droppable` components which contain `Draggable` components.

```ts noLive
import React from 'react';
import { DragDrop, Draggable, Droppable } from '@patternfly/react-core';
import { DragDrop, Draggable, Droppable } from '@patternfly/react-core/deprecated';

const DragDropCodeSample: React.FunctionComponent = () => (
<DragDrop>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './DragDrop';
export * from './Draggable';
export * from './Droppable';
export * from './DroppableContext';
2 changes: 1 addition & 1 deletion packages/react-core/src/deprecated/components/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './';
export * from './DragDrop';
1 change: 1 addition & 0 deletions packages/react-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@patternfly/react-charts": "^6.94.18",
"@patternfly/react-code-editor": "^4.82.111",
"@patternfly/react-core": "^4.276.4",
"@patternfly/react-drag-drop": "^4.0.0",
"@patternfly/react-icons": "^4.93.6",
"@patternfly/react-inline-edit-extension": "^4.86.116",
"@patternfly/react-styles": "^4.92.6",
Expand Down
6 changes: 6 additions & 0 deletions packages/react-docs/patternfly-docs/patternfly-docs.source.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = (baseSourceMD, sourceProps) => {
.resolve('@patternfly/react-virtualized-extension/package.json')
.replace('package.json', 'src');
const reactTopologyPath = require.resolve('@patternfly/react-topology/package.json').replace('package.json', 'src');
const reactDragDropPath = require.resolve('@patternfly/react-drag-drop/package.json').replace('package.json', 'src');
const reactPropsIgnore = '**/*.test.tsx';

sourceProps(path.join(reactCorePath, '/**/*.tsx'), reactPropsIgnore);
Expand All @@ -32,12 +33,14 @@ module.exports = (baseSourceMD, sourceProps) => {
sourceProps(path.join(reactCatalogViewPath, '/**/*.tsx'), reactPropsIgnore);
sourceProps(path.join(reactVirtualizedPath, '/**/*.tsx'), reactPropsIgnore);
sourceProps(path.join(reactTopologyPath, '/**/*.tsx'), reactPropsIgnore);
sourceProps(path.join(reactDragDropPath, '/**/*.tsx'), reactPropsIgnore);

// React MD
sourceMD(path.join(reactCorePath, '/components/**/examples/*.md'), 'react');
sourceMD(path.join(reactCorePath, '/layouts/**/examples/*.md'), 'react');
sourceMD(path.join(reactCorePath, '/next/components/**/examples/*.md'), 'react-next');
sourceMD(path.join(reactCorePath, '/**/demos/**/*.md'), 'react-demos');
sourceMD(path.join(reactCorePath, '/deprecated/components/**/examples/*.md'), 'react-tech-review');

// React-table MD
sourceMD(path.join(reactTablePath, '/**/TableComposable/examples/*.md'), 'react');
Expand All @@ -61,6 +64,9 @@ module.exports = (baseSourceMD, sourceProps) => {

// Topology MD
sourceMD(path.join(reactTopologyPath, '/**/examples/*.md'), 'react');

// Drag drop MD
sourceMD(path.join(reactDragDropPath, '/**/examples/*.md'), 'react');

// Release notes
sourceMD(require.resolve('@patternfly/react-docs/RELEASE-NOTES.md'), 'react');
Expand Down
49 changes: 49 additions & 0 deletions packages/react-drag-drop/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@patternfly/react-drag-drop",
"version": "4.0.0",
"description": "PatternFly drag and drop solution",
"main": "dist/js/index.js",
"module": "dist/esm/index.js",
"types": "dist/esm/index.d.ts",
"sideEffects": false,
"publishConfig": {
"access": "public",
"tag": "prerelease"
},
"repository": {
"type": "git",
"url": "https://github.com/patternfly/patternfly-react.git"
},
"keywords": [
"react",
"patternfly",
"drag-drop"
],
"author": "Red Hat",
"license": "MIT",
"bugs": {
"url": "https://github.com/patternfly/patternfly-react/issues"
},
"homepage": "https://github.com/patternfly/patternfly-react/tree/main/packages/react-drag-drop#readme",
"scripts": {
"clean": "rimraf dist"
},
"dependencies": {
"@dnd-kit/core": "^5.0.3",
"@dnd-kit/modifiers": "^5.0.0",
"@dnd-kit/sortable": "^6.0.1",
"@patternfly/react-core": "^4.237.3",
"@patternfly/react-icons": "^4.88.3",
"@patternfly/react-styles": "^4.87.3",
"memoize-one": "^5.1.0",
"resize-observer-polyfill": "^1.5.1"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
"devDependencies": {
"rimraf": "^2.6.2",
"typescript": "^4.7.4"
}
}
Loading

0 comments on commit 790e962

Please sign in to comment.