updated patternfly

This commit is contained in:
Alex Corey
2021-12-06 10:11:09 -05:00
parent a259e48377
commit 4c2fd056ef
4 changed files with 119 additions and 201 deletions

View File

@@ -6,10 +6,10 @@
"": { "": {
"dependencies": { "dependencies": {
"@lingui/react": "3.9.0", "@lingui/react": "3.9.0",
"@patternfly/patternfly": "4.102.1", "@patternfly/patternfly": "4.159.1",
"@patternfly/react-core": "4.121.1", "@patternfly/react-core": "4.175.4",
"@patternfly/react-icons": "4.7.22", "@patternfly/react-icons": "4.26.4",
"@patternfly/react-table": "4.26.7", "@patternfly/react-table": "4.44.4",
"ace-builds": "^1.4.12", "ace-builds": "^1.4.12",
"ansi-to-html": "0.7.2", "ansi-to-html": "0.7.2",
"axios": "0.22.0", "axios": "0.22.0",
@@ -2614,22 +2614,22 @@
"dev": true "dev": true
}, },
"node_modules/@patternfly/patternfly": { "node_modules/@patternfly/patternfly": {
"version": "4.102.1", "version": "4.159.1",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.102.1.tgz", "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.159.1.tgz",
"integrity": "sha512-YQSJH4EirnFdwJ3eN7BUgGj/Q3bg/Lmc+8vU/bhIDnRuk5KqGZ7xbVCPrWwrV0oYrfIUAWgbrbJjpP03VjrJLw==" "integrity": "sha512-CPLE7yAmtETH8TAdQhHkyFmyvjGwsv/7PeR4k57DY9X4IHpx41m4SXrv9cBCr/+Uy8o2SjvE8dtlZb+h0rLByQ=="
}, },
"node_modules/@patternfly/react-core": { "node_modules/@patternfly/react-core": {
"version": "4.121.1", "version": "4.175.4",
"resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.121.1.tgz", "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.175.4.tgz",
"integrity": "sha512-WIlh7Wd4o4r0PA2+9/fPcOxMAnc2H/InPx8rulJzD9a8KdUevl7+XDtKok6p6grKRUriV5wKPQyfZrxcb5VVHw==", "integrity": "sha512-bnQhvXKbprni5WhlbMI+nbYxwMR03bFZtUk+F7JiLM96uk/yCrPjUes6u8Pbgkh/HhsRYx8K1kx84WmC+MyD5w==",
"dependencies": { "dependencies": {
"@patternfly/react-icons": "^4.10.7", "@patternfly/react-icons": "^4.26.4",
"@patternfly/react-styles": "^4.10.7", "@patternfly/react-styles": "^4.25.4",
"@patternfly/react-tokens": "^4.11.8", "@patternfly/react-tokens": "^4.27.4",
"focus-trap": "6.2.2", "focus-trap": "6.2.2",
"react-dropzone": "9.0.0", "react-dropzone": "9.0.0",
"tippy.js": "5.1.2", "tippy.js": "5.1.2",
"tslib": "1.13.0" "tslib": "^2.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^16.8.0 || ^17.0.0", "react": "^16.8.0 || ^17.0.0",
@@ -2646,12 +2646,12 @@
} }
}, },
"node_modules/@patternfly/react-icons": { "node_modules/@patternfly/react-icons": {
"version": "4.7.22", "version": "4.26.4",
"resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.7.22.tgz", "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.26.4.tgz",
"integrity": "sha512-JDsnebr9CNIyrv9yjaGFQ56OChbV6KcxMYBIpNc8/sZdU4TXHWNC7P7rlUM/BuGpbWvyaOJtscRuf5uteIKX3A==", "integrity": "sha512-h1NJixtNVK+nYxLON3HOO0xguA9qXQ5rkGUo4TZJ/kRehFCJMH8PPeebdOAKgAo38NjS2/06+atNKjDRl6zYcA==",
"peerDependencies": { "peerDependencies": {
"react": "^16.8.0", "react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0" "react-dom": "^16.8.0 || ^17.0.0"
} }
}, },
"node_modules/@patternfly/react-styles": { "node_modules/@patternfly/react-styles": {
@@ -2660,14 +2660,14 @@
"integrity": "sha512-GHFLzsvyimymkGTTyTW8HZDlhYbGpCqw/69Se1EHCaZnbTYluiJMRI6YfNTRC5ZvYF+x4GMAG5AjwQ5LfbZ/xg==" "integrity": "sha512-GHFLzsvyimymkGTTyTW8HZDlhYbGpCqw/69Se1EHCaZnbTYluiJMRI6YfNTRC5ZvYF+x4GMAG5AjwQ5LfbZ/xg=="
}, },
"node_modules/@patternfly/react-table": { "node_modules/@patternfly/react-table": {
"version": "4.26.7", "version": "4.44.4",
"resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.26.7.tgz", "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.44.4.tgz",
"integrity": "sha512-rG6ZrkOf9sDGoKFP5VuntmB2DiOr2CyStZ4TKSFpH55ZIIIQB9FtuaDmX58cTE0xDpP4YW/NPEKkWHDVo7t76Q==", "integrity": "sha512-UV2kq4OV1v6Hv2TXvvsEApPwbAyD6zvurvl0/BZoqqEHTWVQedG0m1jUN9jFMTJiD4GTESvg6TAcSowGkJlTug==",
"dependencies": { "dependencies": {
"@patternfly/react-core": "^4.115.2", "@patternfly/react-core": "^4.175.4",
"@patternfly/react-icons": "^4.10.2", "@patternfly/react-icons": "^4.26.4",
"@patternfly/react-styles": "^4.10.2", "@patternfly/react-styles": "^4.25.4",
"@patternfly/react-tokens": "^4.11.3", "@patternfly/react-tokens": "^4.27.4",
"lodash": "^4.17.19", "lodash": "^4.17.19",
"tslib": "1.13.0" "tslib": "1.13.0"
}, },
@@ -28535,22 +28535,22 @@
"dev": true "dev": true
}, },
"@patternfly/patternfly": { "@patternfly/patternfly": {
"version": "4.102.1", "version": "4.159.1",
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.102.1.tgz", "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.159.1.tgz",
"integrity": "sha512-YQSJH4EirnFdwJ3eN7BUgGj/Q3bg/Lmc+8vU/bhIDnRuk5KqGZ7xbVCPrWwrV0oYrfIUAWgbrbJjpP03VjrJLw==" "integrity": "sha512-CPLE7yAmtETH8TAdQhHkyFmyvjGwsv/7PeR4k57DY9X4IHpx41m4SXrv9cBCr/+Uy8o2SjvE8dtlZb+h0rLByQ=="
}, },
"@patternfly/react-core": { "@patternfly/react-core": {
"version": "4.121.1", "version": "4.175.4",
"resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.121.1.tgz", "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.175.4.tgz",
"integrity": "sha512-WIlh7Wd4o4r0PA2+9/fPcOxMAnc2H/InPx8rulJzD9a8KdUevl7+XDtKok6p6grKRUriV5wKPQyfZrxcb5VVHw==", "integrity": "sha512-bnQhvXKbprni5WhlbMI+nbYxwMR03bFZtUk+F7JiLM96uk/yCrPjUes6u8Pbgkh/HhsRYx8K1kx84WmC+MyD5w==",
"requires": { "requires": {
"@patternfly/react-icons": "^4.10.7", "@patternfly/react-icons": "^4.26.4",
"@patternfly/react-styles": "^4.10.7", "@patternfly/react-styles": "^4.25.4",
"@patternfly/react-tokens": "^4.11.8", "@patternfly/react-tokens": "^4.27.4",
"focus-trap": "6.2.2", "focus-trap": "6.2.2",
"react-dropzone": "9.0.0", "react-dropzone": "9.0.0",
"tippy.js": "5.1.2", "tippy.js": "5.1.2",
"tslib": "1.13.0" "tslib": "^2.0.0"
}, },
"dependencies": { "dependencies": {
"@patternfly/react-icons": { "@patternfly/react-icons": {
@@ -28562,9 +28562,9 @@
} }
}, },
"@patternfly/react-icons": { "@patternfly/react-icons": {
"version": "4.7.22", "version": "4.26.4",
"resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.7.22.tgz", "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.26.4.tgz",
"integrity": "sha512-JDsnebr9CNIyrv9yjaGFQ56OChbV6KcxMYBIpNc8/sZdU4TXHWNC7P7rlUM/BuGpbWvyaOJtscRuf5uteIKX3A==", "integrity": "sha512-h1NJixtNVK+nYxLON3HOO0xguA9qXQ5rkGUo4TZJ/kRehFCJMH8PPeebdOAKgAo38NjS2/06+atNKjDRl6zYcA==",
"requires": {} "requires": {}
}, },
"@patternfly/react-styles": { "@patternfly/react-styles": {
@@ -28573,14 +28573,14 @@
"integrity": "sha512-GHFLzsvyimymkGTTyTW8HZDlhYbGpCqw/69Se1EHCaZnbTYluiJMRI6YfNTRC5ZvYF+x4GMAG5AjwQ5LfbZ/xg==" "integrity": "sha512-GHFLzsvyimymkGTTyTW8HZDlhYbGpCqw/69Se1EHCaZnbTYluiJMRI6YfNTRC5ZvYF+x4GMAG5AjwQ5LfbZ/xg=="
}, },
"@patternfly/react-table": { "@patternfly/react-table": {
"version": "4.26.7", "version": "4.44.4",
"resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.26.7.tgz", "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.44.4.tgz",
"integrity": "sha512-rG6ZrkOf9sDGoKFP5VuntmB2DiOr2CyStZ4TKSFpH55ZIIIQB9FtuaDmX58cTE0xDpP4YW/NPEKkWHDVo7t76Q==", "integrity": "sha512-UV2kq4OV1v6Hv2TXvvsEApPwbAyD6zvurvl0/BZoqqEHTWVQedG0m1jUN9jFMTJiD4GTESvg6TAcSowGkJlTug==",
"requires": { "requires": {
"@patternfly/react-core": "^4.115.2", "@patternfly/react-core": "^4.175.4",
"@patternfly/react-icons": "^4.10.2", "@patternfly/react-icons": "^4.26.4",
"@patternfly/react-styles": "^4.10.2", "@patternfly/react-styles": "^4.25.4",
"@patternfly/react-tokens": "^4.11.3", "@patternfly/react-tokens": "^4.27.4",
"lodash": "^4.17.19", "lodash": "^4.17.19",
"tslib": "1.13.0" "tslib": "1.13.0"
}, },

View File

@@ -6,10 +6,10 @@
}, },
"dependencies": { "dependencies": {
"@lingui/react": "3.9.0", "@lingui/react": "3.9.0",
"@patternfly/patternfly": "4.102.1", "@patternfly/patternfly": "4.159.1",
"@patternfly/react-core": "4.121.1", "@patternfly/react-core": "4.175.4",
"@patternfly/react-icons": "4.7.22", "@patternfly/react-icons": "4.26.4",
"@patternfly/react-table": "4.26.7", "@patternfly/react-table": "4.44.4",
"ace-builds": "^1.4.12", "ace-builds": "^1.4.12",
"ansi-to-html": "0.7.2", "ansi-to-html": "0.7.2",
"axios": "0.22.0", "axios": "0.22.0",

View File

@@ -1,15 +1,18 @@
import React, { useState } from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
Button, Button,
DataList,
DataListAction, DataListAction,
DragDrop,
Droppable,
Draggable,
DataListItemRow,
DataListItemCells,
DataList,
DataListItem, DataListItem,
DataListCell, DataListCell,
DataListItemRow,
DataListControl, DataListControl,
DataListDragButton, DataListDragButton,
DataListItemCells,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { TimesIcon } from '@patternfly/react-icons'; import { TimesIcon } from '@patternfly/react-icons';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -23,112 +26,82 @@ const RemoveActionSection = styled(DataListAction)`
`; `;
function DraggableSelectedList({ selected, onRemove, onRowDrag }) { function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
const [liveText, setLiveText] = useState('');
const [id, setId] = useState('');
const [isDragging, setIsDragging] = useState(false);
const onDragStart = (newId) => {
setId(newId);
setLiveText(t`Dragging started for item id: ${newId}.`);
setIsDragging(true);
};
const onDragMove = (oldIndex, newIndex) => {
setLiveText(
t`Dragging item ${id}. Item with index ${oldIndex} in now ${newIndex}.`
);
};
const onDragCancel = () => {
setLiveText(t`Dragging cancelled. List is unchanged.`);
setIsDragging(false);
};
const onDragFinish = (newItemOrder) => {
const selectedItems = newItemOrder.map((item) =>
selected.find((i) => i.name === item)
);
onRowDrag(selectedItems);
setIsDragging(false);
};
const removeItem = (item) => { const removeItem = (item) => {
onRemove(selected.find((i) => i.name === item)); onRemove(selected.find((i) => i.name === item));
}; };
function reorder(list, startIndex, endIndex) {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
}
function dragItem(item, dest) {
if (!dest || item.index === dest.index) {
return false;
}
const newItems = reorder(selected, item.index, dest.index);
onRowDrag(newItems);
return true;
}
if (selected.length <= 0) { if (selected.length <= 0) {
return null; return null;
} }
const orderedList = selected.map((item) => item?.name);
return ( return (
<> <DragDrop onDrop={dragItem}>
<DataList <Droppable>
aria-label={t`Draggable list to reorder and remove selected items.`} <DataList>
data-cy="draggable-list" {selected.map(({ name: label, id }, index) => {
itemOrder={orderedList} const rowPosition = index + 1;
onDragCancel={onDragCancel} return (
onDragFinish={onDragFinish} <Draggable value={id} key={rowPosition}>
onDragMove={onDragMove} <DataListItem>
onDragStart={onDragStart} <DataListItemRow>
> <DataListControl>
{orderedList.map((label, index) => { <DataListDragButton isDisabled={selected.length < 2} />
const rowPosition = index + 1; </DataListControl>
return ( <DataListItemCells
<DataListItem id={label} key={rowPosition}> dataListCells={[
<DataListItemRow> <DataListCell key={label}>
<DataListControl> <span
<DataListDragButton id={rowPosition}
aria-label={t`Reorder`} >{`${rowPosition}. ${label}`}</span>
aria-labelledby={rowPosition} </DataListCell>,
aria-describedby={t`Press space or enter to begin dragging, ]}
and use the arrow keys to navigate up or down. />
Press enter to confirm the drag, or any other key to <RemoveActionSection>
cancel the drag operation.`} <Button
aria-pressed="false" onClick={() => removeItem(label)}
data-cy={`reorder-${label}`} variant="plain"
isDisabled={selected.length === 1} aria-label={t`Remove`}
/> ouiaId={`draggable-list-remove-${label}`}
</DataListControl> >
<DataListItemCells <TimesIcon />
dataListCells={[ </Button>
<DataListCell key={label}> </RemoveActionSection>
<span id={rowPosition}>{`${rowPosition}. ${label}`}</span> </DataListItemRow>
</DataListCell>, </DataListItem>
]} </Draggable>
/> );
<RemoveActionSection aria-label={t`Actions`} id={rowPosition}> })}
<Button </DataList>
onClick={() => removeItem(label)} </Droppable>
variant="plain" </DragDrop>
aria-label={t`Remove`}
ouiaId={`draggable-list-remove-${label}`}
isDisabled={isDragging}
>
<TimesIcon />
</Button>
</RemoveActionSection>
</DataListItemRow>
</DataListItem>
);
})}
</DataList>
<div className="pf-screen-reader" aria-live="assertive">
{liveText}
</div>
</>
); );
} }
const ListItem = PropTypes.shape({ const SelectedListItem = PropTypes.shape({
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
}); });
DraggableSelectedList.propTypes = { DraggableSelectedList.propTypes = {
onRemove: PropTypes.func, onRemove: PropTypes.func,
onRowDrag: PropTypes.func, onRowDrag: PropTypes.func,
selected: PropTypes.arrayOf(ListItem), selected: PropTypes.arrayOf(SelectedListItem),
}; };
DraggableSelectedList.defaultProps = { DraggableSelectedList.defaultProps = {
onRemove: () => null, onRemove: () => null,

View File

@@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import DraggableSelectedList from './DraggableSelectedList'; import DraggableSelectedList from './DraggableSelectedList';
@@ -28,16 +27,16 @@ describe('<DraggableSelectedList />', () => {
/> />
); );
expect(wrapper.find('DraggableSelectedList').length).toBe(1); expect(wrapper.find('DraggableSelectedList').length).toBe(1);
expect(wrapper.find('DataListItem').length).toBe(2); expect(wrapper.find('Draggable').length).toBe(2);
expect( expect(
wrapper wrapper
.find('DataListItem DataListCell') .find('Draggable')
.first() .first()
.containsMatchingElement(<span>1. foo</span>) .containsMatchingElement(<span>1. foo</span>)
).toEqual(true); ).toEqual(true);
expect( expect(
wrapper wrapper
.find('DataListItem DataListCell') .find('Draggable')
.last() .last()
.containsMatchingElement(<span>2. bar</span>) .containsMatchingElement(<span>2. bar</span>)
).toEqual(true); ).toEqual(true);
@@ -65,64 +64,10 @@ describe('<DraggableSelectedList />', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<DraggableSelectedList selected={mockSelected} onRemove={onRemove} /> <DraggableSelectedList selected={mockSelected} onRemove={onRemove} />
); );
expect( wrapper.find('Button[aria-label="Remove"]').simulate('click');
wrapper
.find('DataListDragButton[aria-label="Reorder"]')
.prop('isDisabled')
).toBe(true);
wrapper
.find('DataListItem[id="foo"] Button[aria-label="Remove"]')
.simulate('click');
expect(onRemove).toBeCalledWith({ expect(onRemove).toBeCalledWith({
id: 1, id: 1,
name: 'foo', name: 'foo',
}); });
}); });
test('should disable remove button when dragging item', () => {
const mockSelected = [
{
id: 1,
name: 'foo',
},
{
id: 2,
name: 'bar',
},
];
wrapper = mountWithContexts(
<DraggableSelectedList
selected={mockSelected}
onRemove={() => {}}
onRowDrag={() => {}}
/>
);
expect(
wrapper.find('Button[aria-label="Remove"]').at(0).prop('isDisabled')
).toBe(false);
expect(
wrapper.find('Button[aria-label="Remove"]').at(1).prop('isDisabled')
).toBe(false);
act(() => {
wrapper.find('DataList').prop('onDragStart')();
});
wrapper.update();
expect(
wrapper.find('Button[aria-label="Remove"]').at(0).prop('isDisabled')
).toBe(true);
expect(
wrapper.find('Button[aria-label="Remove"]').at(1).prop('isDisabled')
).toBe(true);
act(() => {
wrapper.find('DataList').prop('onDragCancel')();
});
wrapper.update();
expect(
wrapper.find('Button[aria-label="Remove"]').at(0).prop('isDisabled')
).toBe(false);
expect(
wrapper.find('Button[aria-label="Remove"]').at(1).prop('isDisabled')
).toBe(false);
});
}); });