Skip to content

Commit 659b91e

Browse files
committed
pr feedback
1 parent 1fa349a commit 659b91e

File tree

8 files changed

+147
-5
lines changed

8 files changed

+147
-5
lines changed

packages/react-core/src/components/DataList/examples/DataList.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ propComponents:
1313
'DataListItemRow',
1414
'DataListToggle',
1515
'DataListContent',
16+
'DataListDragButton',
1617
'DataListControl',
1718
]
1819
---
@@ -83,6 +84,17 @@ import global_BorderWidth_sm from '@patternfly/react-tokens/dist/esm/global_Bord
8384

8485
```
8586

87+
### Draggable
88+
89+
Note: There is a new recommended drag and drop implementation that has full keyboard functionality. Examples and details may be located [here](/components/drag-and-drop/react-next).
90+
91+
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. Keyboard accessibility and screen reader accessibility for the `DragDrop` component are still in development.
92+
93+
```ts isBeta file="./DataListDraggable.tsx"
94+
95+
```
96+
97+
8698
### Small grid breakpoint
8799

88100
```ts file="./DataListSmGridBreakpoint.tsx"
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import React from 'react';
2+
import {
3+
DataList,
4+
DataListItem,
5+
DataListCell,
6+
DataListItemRow,
7+
DataListCheck,
8+
DataListControl,
9+
DataListDragButton,
10+
DataListItemCells,
11+
DragDrop,
12+
Draggable,
13+
Droppable,
14+
getUniqueId
15+
} from '@patternfly/react-core';
16+
17+
interface ItemType {
18+
id: string;
19+
content: string;
20+
}
21+
22+
const getItems = (count: number) =>
23+
Array.from({ length: count }, (_, idx) => idx).map((idx) => ({
24+
id: `draggable-item-${idx}`,
25+
content: `item ${idx} `.repeat(idx === 4 ? 20 : 1)
26+
}));
27+
28+
const reorder = (list: ItemType[], startIndex: number, endIndex: number) => {
29+
const result = list;
30+
const [removed] = result.splice(startIndex, 1);
31+
result.splice(endIndex, 0, removed);
32+
return result;
33+
};
34+
35+
export const DataListDraggable: React.FunctionComponent = () => {
36+
const [items, setItems] = React.useState(getItems(10));
37+
const [liveText, setLiveText] = React.useState('');
38+
39+
function onDrag(source) {
40+
setLiveText(`Started dragging ${items[source.index].content}`);
41+
// Return true to allow drag
42+
return true;
43+
}
44+
45+
function onDragMove(source, dest) {
46+
const newText = dest ? `Move ${items[source.index].content} to ${items[dest.index].content}` : 'Invalid drop zone';
47+
if (newText !== liveText) {
48+
setLiveText(newText);
49+
}
50+
}
51+
52+
function onDrop(source, dest) {
53+
if (dest) {
54+
const newItems = reorder(items, source.index, dest.index);
55+
setItems(newItems);
56+
57+
setLiveText('Dragging finished.');
58+
return true; // Signal that this is a valid drop and not to animate the item returning home.
59+
} else {
60+
setLiveText('Dragging cancelled. List unchanged.');
61+
}
62+
}
63+
64+
const uniqueId = getUniqueId();
65+
66+
return (
67+
<DragDrop onDrag={onDrag} onDragMove={onDragMove} onDrop={onDrop}>
68+
<Droppable hasNoWrapper>
69+
<DataList aria-label="draggable data list example" isCompact>
70+
{items.map(({ id, content }) => (
71+
<Draggable key={id} hasNoWrapper>
72+
<DataListItem aria-labelledby={`draggable-${id}`} ref={React.createRef()}>
73+
<DataListItemRow>
74+
<DataListControl>
75+
<DataListDragButton
76+
aria-label="Reorder"
77+
aria-labelledby={`draggable-${id}`}
78+
aria-describedby={`description-${uniqueId}`}
79+
aria-pressed="false"
80+
/>
81+
<DataListCheck aria-labelledby={`draggable-${id}`} name={id} otherControls />
82+
</DataListControl>
83+
<DataListItemCells
84+
dataListCells={[
85+
<DataListCell key={id}>
86+
<span id={`draggable-${id}`}>{content}</span>
87+
</DataListCell>
88+
]}
89+
/>
90+
</DataListItemRow>
91+
</DataListItem>
92+
</Draggable>
93+
))}
94+
</DataList>
95+
</Droppable>
96+
<div className="pf-v5-screen-reader" aria-live="assertive">
97+
{liveText}
98+
</div>
99+
<div className="pf-v5-screen-reader" id={`description-${uniqueId}`}>
100+
Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm
101+
the drag, or any other key to cancel the drag operation.
102+
</div>
103+
</DragDrop>
104+
);
105+
};

packages/react-core/src/components/DualListSelector/examples/DualListSelector.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,28 @@ The dual list selector can also be built in a composable manner to make customiz
8585

8686
```
8787

88+
### Composable with drag and drop
89+
90+
Note: There is a new recommended drag and drop implementation that has full keyboard functionality. Examples and details may be located [here](/components/drag-and-drop/react-next).
91+
92+
This example only allows reordering the contents of the "chosen" pane with drag and drop. To make a pane able to be reordered:
93+
94+
- wrap the `DualListSelectorPane` in a `DragDrop` component
95+
- wrap the `DualListSelectorList` in a `Droppable` component
96+
- wrap the `DualListSelectorListItem` components in a `Draggable` component
97+
- define an `onDrop` callback which reorders the sortable options.
98+
- The `onDrop` function provides the starting location and destination location for a dragged item. It should return
99+
true to enable the 'drop' animation in the new location and false to enable the 'drop' animation back to the item's
100+
old position.
101+
- define an `onDrag` callback which ensures that the drag event will not cross hairs with the `onOptionSelect` click
102+
event set on the option. Note: the `ignoreNextOptionSelect` state value is used to prevent selection while dragging.
103+
104+
Keyboard accessibility and screen reader accessibility for the `DragDrop` component are still in development.
105+
106+
```ts file="DualListSelectorComposableDragDrop.tsx"
107+
108+
```
109+
88110
### Composable with tree
89111

90112
```ts file="DualListSelectorComposableTree.tsx"

packages/react-drag-drop/src/components/DragDrop/DragDropSort.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import styles from '@patternfly/react-styles/css/components/DragDrop/drag-drop';
2727
export type DragDropSortDragEndEvent = DragEndEvent;
2828
export type DragDropSortDragStartEvent = DragStartEvent;
2929

30+
/**
31+
* DragDropSortProps extends dnd-kit's props which may be viewed at https://docs.dndkit.com/api-documentation/context-provider#props.
32+
*/
3033
export interface DragDropSortProps extends DndContextProps {
3134
/** Custom defined content wrapper for draggable items. By default, draggable items are wrapped in a styled div.
3235
* Intended to be a 'DataList' or 'DualListSelectorList' without children. */

packages/react-drag-drop/src/components/DragDrop/Draggable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ export interface DraggableProps extends React.HTMLProps<HTMLDivElement> {
1212
hasNoWrapper?: boolean;
1313
/** Class to add to outer div */
1414
className?: string;
15-
/** */
15+
/** @hide Id of the sortable context. */
1616
id?: string;
17-
/** */
17+
/** Flag indicating the draggable element should include a drag button. */
1818
useDragButton?: boolean;
1919
}
2020

packages/react-drag-drop/src/components/DragDrop/DraggableDataListItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface DraggableDataListItemProps extends React.HTMLProps<HTMLLIElemen
1919
hasNoWrapper?: boolean;
2020
/** Class to add to outer div */
2121
className?: string;
22-
/** */
22+
/** @hide Id of the sortable context. */
2323
id?: string;
2424
}
2525

packages/react-drag-drop/src/components/DragDrop/DraggableDualListSelectorListItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export interface DraggableDualListSelectorListItemProps extends React.HTMLProps<
1414
hasNoWrapper?: boolean;
1515
/** Class to add to outer div */
1616
className?: string;
17-
/** */
17+
/** @hide Id of the sortable context */
1818
id?: string;
1919
/** Flag indicating the list item is currently selected. */
2020
isSelected?: boolean;

packages/react-drag-drop/src/components/DragDrop/examples/DragDrop.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ hideNavItem: true
77
beta: true
88
---
99

10-
Note: DragDrop lives in its own package at @patternfly/react-drag-drop!'
10+
Note: This drag and drop implementation lives in its own package at [@patternfly/react-drag-drop](https://www.npmjs.com/package/@patternfly/react-drag-drop)!
1111

1212
import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
1313
import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';

0 commit comments

Comments
 (0)