Skip to content

Commit

Permalink
feat(DragDrop): introduce new package and deprecate old implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolethoen committed Oct 9, 2023
1 parent 8c784c2 commit e4e413a
Show file tree
Hide file tree
Showing 41 changed files with 907 additions and 148 deletions.
13 changes: 1 addition & 12 deletions packages/react-core/src/components/DataList/examples/DataList.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ propComponents:
'DataListItemRow',
'DataListToggle',
'DataListContent',
'DataListDragButton',
'DataListControl'
'DataListControl',
]
---

Expand Down Expand Up @@ -80,16 +79,6 @@ import { css } from '@patternfly/react-styles';

```

### 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.

Original file line number Diff line number Diff line change
Expand Up @@ -85,26 +85,6 @@ The dual list selector can also be built in a composable manner to make customiz

```

### 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 @@ -76,7 +76,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
Expand Up @@ -2,14 +2,15 @@
id: Drag and drop
section: components
propComponents: [DragDrop, Draggable, Droppable, DraggableItemPosition]
beta: true
---

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

import { DragDrop, Draggable, Droppable, DraggableItemPosition } from '@patternfly/react-core/deprecated';

```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,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,14 +20,14 @@ 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) {
Expand All @@ -42,8 +42,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
@@ -1,3 +1,4 @@
export * from './DragDrop';
export * from './Draggable';
export * from './Droppable';
export * from './DroppableContext';
1 change: 1 addition & 0 deletions packages/react-core/src/deprecated/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './ApplicationLauncher';
export * from './ContextSelector';
export * from './DragDrop';
export * from './Dropdown';
export * from './OptionsMenu';
export * from './PageHeader';
Expand Down
1 change: 1 addition & 0 deletions packages/react-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@patternfly/react-charts": "^7.2.0-prerelease.2",
"@patternfly/react-code-editor": "^5.2.0-prerelease.2",
"@patternfly/react-core": "^5.2.0-prerelease.2",
"@patternfly/react-drag-drop": "^5.0.0-alpha.0",
"@patternfly/react-icons": "^5.2.0-prerelease.1",
"@patternfly/react-styles": "^5.2.0-prerelease.1",
"@patternfly/react-table": "^5.2.0-prerelease.2",
Expand Down
5 changes: 5 additions & 0 deletions packages/react-docs/patternfly-docs/patternfly-docs.source.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ module.exports = (baseSourceMD, sourceProps) => {
const reactCodeEditorPath = require
.resolve('@patternfly/react-code-editor/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);
sourceProps(path.join(reactTablePath, '/**/*.tsx'), reactPropsIgnore);
sourceProps(path.join(reactChartsPath, '/**/*.tsx'), reactPropsIgnore);
sourceProps(path.join(reactCodeEditorPath, '/**/*.tsx'), reactPropsIgnore);
sourceProps(path.join(reactDragDropPath, '/**/*.tsx'), reactPropsIgnore);

// React MD
sourceMD(path.join(reactCorePath, '/components/**/examples/*.md'), 'react');
Expand All @@ -41,6 +43,9 @@ module.exports = (baseSourceMD, sourceProps) => {
// Code Editor MD
sourceMD(path.join(reactCodeEditorPath, '/**/examples/*.md'), 'react');

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

// OUIA MD
sourceMD(path.join(reactCorePath, 'helpers/OUIA/OUIA.md'), 'react');
};
50 changes: 50 additions & 0 deletions packages/react-drag-drop/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "@patternfly/react-drag-drop",
"version": "5.0.0-alpha.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": "alpha"
},
"patternfly:src": "src/",
"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": "^6.0.8",
"@dnd-kit/modifiers": "^6.0.1",
"@dnd-kit/sortable": "^7.0.2",
"@patternfly/react-core": "^5.0.0-alpha.33",
"@patternfly/react-icons": "^5.0.0-alpha.4",
"@patternfly/react-styles": "^5.0.0-alpha.4",
"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"
}
}
22 changes: 22 additions & 0 deletions packages/react-drag-drop/src/components/DragDrop/DragButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import { css } from '@patternfly/react-styles';
import dragButtonStyles from '@patternfly/react-styles/css/components/DataList/data-list';
import GripVerticalIcon from '@patternfly/react-icons/dist/esm/icons/grip-vertical-icon';

export interface DragButtonProps extends React.HTMLProps<HTMLButtonElement> {
/** Additional classes added to the drag button */
className?: string;
/** Sets button type */
type?: 'button' | 'submit' | 'reset';
/** Flag indicating if drag is disabled for the item */
isDisabled?: boolean;
}

export const DragButton: React.FunctionComponent<DragButtonProps> = ({ className, ...props }: DragButtonProps) => (
<button className={css(className, 'pf-c-button', 'pf-m-plain')} aria-label="Drag button" {...props}>
<span className={css(dragButtonStyles.dataListItemDraggableIcon)}>
<GripVerticalIcon />
</span>
</button>
);
DragButton.displayName = 'DragButton';
Loading

0 comments on commit e4e413a

Please sign in to comment.