Merge branch 'main' of https://github.com/openedx/frontend-lib-content-components into mashal-m/react-upgrade-to-v17

This commit is contained in:
mashal-m
2023-06-21 14:10:01 +05:00
18 changed files with 403 additions and 129 deletions

View File

@@ -0,0 +1,73 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
DndContext,
closestCenter,
KeyboardSensor,
PointerSensor,
useSensor,
useSensors,
} from '@dnd-kit/core';
import {
arrayMove,
SortableContext,
sortableKeyboardCoordinates,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
const DraggableList = ({
itemList,
setState,
updateOrder,
children,
}) => {
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
}),
);
const handleDragEnd = (event) => {
const { active, over } = event;
if (active.id !== over.id) {
let updatedArray;
setState(() => {
const [activeElement] = itemList.filter(item => item.id === active.id);
const [overElement] = itemList.filter(item => item.id === over.id);
const oldIndex = itemList.indexOf(activeElement);
const newIndex = itemList.indexOf(overElement);
updatedArray = arrayMove(itemList, oldIndex, newIndex);
return updatedArray;
});
updateOrder()(updatedArray);
}
};
return (
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
<SortableContext
items={itemList}
strategy={verticalListSortingStrategy}
>
{children}
</SortableContext>
</DndContext>
);
};
DraggableList.propTypes = {
itemList: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
})).isRequired,
setState: PropTypes.func.isRequired,
updateOrder: PropTypes.func.isRequired,
children: PropTypes.node.isRequired,
};
export default DraggableList;

View File

@@ -0,0 +1,63 @@
import React from 'react';
import PropTypes from 'prop-types';
import { intlShape, injectIntl } from '@edx/frontend-platform/i18n';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Icon, IconButtonWithTooltip, Row } from '@edx/paragon';
import { DragIndicator } from '@edx/paragon/icons';
import messages from './messages';
const SortableItem = ({
id,
componentStyle,
children,
// injected
intl,
}) => {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
} = useSortable({ id });
const style = {
transform: CSS.Transform.toString(transform),
transition,
...componentStyle,
};
return (
<Row
ref={setNodeRef}
style={style}
className="mx-0"
>
{children}
<IconButtonWithTooltip
key="drag-to-reorder-icon"
tooltipPlacement="top"
tooltipContent={intl.formatMessage(messages.tooltipContent)}
src={DragIndicator}
iconAs={Icon}
variant="secondary"
alt={intl.formatMessage(messages.tooltipContent)}
{...attributes}
{...listeners}
/>
</Row>
);
};
SortableItem.defaultProps = {
componentStyle: null,
};
SortableItem.propTypes = {
id: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
componentStyle: PropTypes.shape({}),
// injected
intl: intlShape.isRequired,
};
export default injectIntl(SortableItem);

View File

@@ -0,0 +1,5 @@
import DraggableList from './DraggableList';
import SortableItem from './SortableItem';
export { SortableItem };
export default DraggableList;

View File

@@ -0,0 +1,11 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
tooltipContent: {
id: 'authoring.draggableList.tooltip.content',
defaultMessage: 'Drag to reorder',
description: 'Tooltip content for drag indicator icon',
},
});
export default messages;