Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(DragDrop): introduce new package and deprecate old implementation #8620

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -84,16 +83,6 @@ import global_BorderWidth_sm from '@patternfly/react-tokens/dist/esm/global_Bord

```

### 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 @@ -2,7 +2,7 @@
id: Drag and drop
section: components
propComponents: [DragDrop, Draggable, Droppable, DraggableItemPosition]
beta: true
title: React - next
---

You can use the `DragDrop` component to move items in or between lists. The `DragDrop` component should contain `Droppable` components which contain `Draggable` components.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -11,6 +11,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 +40,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 +89,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
1 change: 1 addition & 0 deletions packages/react-core/src/components/DragDrop/index.ts
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';
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
2 changes: 2 additions & 0 deletions packages/react-core/src/components/DualListSelector/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export * from './DualListSelector';
export * from './DualListSelectorContext';
export * from './DualListSelectorControl';
export * from './DualListSelectorControlsWrapper';
export * from './DualListSelectorPane';
export * from './DualListSelectorList';
export * from './DualListSelectorListItem';
export * from './DualListSelectorTree';
export * from './DualListSelectorContext';
2 changes: 1 addition & 1 deletion packages/react-core/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from './DataList';
export * from './DatePicker';
export * from './DescriptionList';
export * from './Divider';
export * from './DragDrop';
export * from './Drawer';
export * from './Dropdown';
export * from './DualListSelector';
Expand Down Expand Up @@ -76,7 +77,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';
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.4",
"@patternfly/react-code-editor": "^5.2.0-prerelease.10",
"@patternfly/react-core": "^5.2.0-prerelease.10",
"@patternfly/react-drag-drop": "^5.2.0-prelease.0",
"@patternfly/react-icons": "^5.2.0-prerelease.3",
"@patternfly/react-styles": "^5.2.0-prerelease.2",
"@patternfly/react-table": "^5.2.0-prerelease.10",
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-next');

// OUIA MD
sourceMD(path.join(reactCorePath, 'helpers/OUIA/OUIA.md'), 'react');
};
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": "5.2.0-prelease.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"
},
"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.2.0-prerelease.2",
"@patternfly/react-icons": "^5.2.0-prerelease.1",
"@patternfly/react-styles": "^5.2.0-prerelease.1",
"memoize-one": "^5.1.0",
"resize-observer-polyfill": "^1.5.1"
},
"peerDependencies": {
"react": "^17 || ^18",
"react-dom": "^17 || ^18"
},
"devDependencies": {
"rimraf": "^2.6.2",
"typescript": "^4.7.4"
}
}
23 changes: 23 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,23 @@
import * as React from 'react';
import { css } from '@patternfly/react-styles';
import dragButtonStyles from '@patternfly/react-styles/css/components/DataList/data-list';
import buttonStyles from '@patternfly/react-styles/css/components/Button/button';
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, buttonStyles.button, buttonStyles.modifiers.plain)} aria-label="Drag button" {...props}>

Check failure on line 17 in packages/react-drag-drop/src/components/DragDrop/DragButton.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `·className={css(className,·buttonStyles.button,·buttonStyles.modifiers.plain)}·aria-label="Drag·button"·{...props}` with `⏎····className={css(className,·buttonStyles.button,·buttonStyles.modifiers.plain)}⏎····aria-label="Drag·button"⏎····{...props}⏎··`
<span className={css(dragButtonStyles.dataListItemDraggableIcon)}>
<GripVerticalIcon />
</span>
</button>
);
DragButton.displayName = 'DragButton';
Loading
Loading