UNPKG

@awsui/components-react

Version:

On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en

104 lines 6.09 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import React, { useEffect, useRef } from 'react'; import { DndContext, DragOverlay } from '@dnd-kit/core'; import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import clsx from 'clsx'; import Portal from '../../components/portal'; import { fireNonCancelableEvent } from '../../events'; import { joinStrings } from '../../utils/strings'; import useDragAndDropReorder from './use-drag-and-drop-reorder'; import useLiveAnnouncements from './use-live-announcements'; import styles from './styles.css.js'; export default function SortableArea({ items, itemDefinition, renderItem, onItemsChange, disableReorder, i18nStrings, }) { var _a; const { activeItemId, setActiveItemId, collisionDetection, handleKeyDown, sensors } = useDragAndDropReorder({ items, itemDefinition, }); const activeItem = activeItemId ? items.find(item => itemDefinition.id(item) === activeItemId) : null; const isDragging = activeItemId !== null; const announcements = useLiveAnnouncements(Object.assign({ items, itemDefinition, isDragging }, i18nStrings)); const portalContainer = usePortalContainer(); return (React.createElement(DndContext, { sensors: sensors, collisionDetection: collisionDetection, accessibility: { announcements, restoreFocus: false, screenReaderInstructions: (i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.dragHandleAriaDescription) ? { draggable: i18nStrings.dragHandleAriaDescription } : undefined, container: portalContainer !== null && portalContainer !== void 0 ? portalContainer : undefined, }, onDragStart: ({ active }) => setActiveItemId(active.id), onDragEnd: event => { setActiveItemId(null); const { active, over } = event; if (over && active.id !== over.id) { const movedItem = items.find(item => itemDefinition.id(item) === active.id); const oldIndex = items.findIndex(item => itemDefinition.id(item) === active.id); const newIndex = items.findIndex(item => itemDefinition.id(item) === over.id); fireNonCancelableEvent(onItemsChange, { items: arrayMove([...items], oldIndex, newIndex), movedItem }); } }, onDragCancel: () => setActiveItemId(null) }, React.createElement(SortableContext, { disabled: disableReorder, items: items.map(item => itemDefinition.id(item)), strategy: verticalListSortingStrategy }, items.map(item => (React.createElement(DraggableItem, { key: itemDefinition.id(item), item: item, itemDefinition: itemDefinition, renderItem: renderItem, onKeyDown: handleKeyDown, dragHandleAriaLabel: i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.dragHandleAriaLabel })))), React.createElement(Portal, { container: portalContainer }, React.createElement(DragOverlay, { className: clsx(styles['drag-overlay'], styles[`drag-overlay-${getBorderRadiusVariant(itemDefinition)}`]), dropAnimation: null, style: { zIndex: 5000 } }, activeItem && renderItem({ item: activeItem, style: {}, className: styles.active, isDropPlaceholder: true, isSortingActive: false, isDragGhost: true, dragHandleProps: { ariaLabel: (_a = joinStrings(i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.dragHandleAriaLabel, itemDefinition.label(activeItem))) !== null && _a !== void 0 ? _a : '', onKeyDown: handleKeyDown, }, }))))); } function usePortalContainer() { const portalContainerRef = useRef(typeof document !== 'undefined' ? document.createElement('div') : null); useEffect(() => { const container = portalContainerRef.current; if (container && !container.isConnected) { document.body.appendChild(container); } return () => { if (container && container.isConnected) { document.body.removeChild(container); } }; }, []); return portalContainerRef.current; } function DraggableItem({ item, itemDefinition, dragHandleAriaLabel, onKeyDown, renderItem, }) { var _a; const { isDragging, isSorting, listeners, setNodeRef, transform, attributes } = useSortable({ id: itemDefinition.id(item), }); const style = { transform: CSS.Translate.toString(transform) }; const dragHandleListeners = attributes['aria-disabled'] ? {} : Object.assign(Object.assign({}, listeners), { onKeyDown: (event) => { if (onKeyDown) { onKeyDown(event); } if (listeners === null || listeners === void 0 ? void 0 : listeners.onKeyDown) { listeners.onKeyDown(event); } } }); const className = clsx(isDragging && clsx(styles.placeholder, styles[`placeholder-${getBorderRadiusVariant(itemDefinition)}`]), isSorting && styles.sorting); return (React.createElement(React.Fragment, null, renderItem({ item, ref: setNodeRef, style, className, isDropPlaceholder: isDragging, isSortingActive: isSorting, isDragGhost: false, dragHandleProps: Object.assign(Object.assign({}, dragHandleListeners), { ariaLabel: (_a = joinStrings(dragHandleAriaLabel, itemDefinition.label(item))) !== null && _a !== void 0 ? _a : '', ariaDescribedby: attributes['aria-describedby'], disabled: attributes['aria-disabled'] }), }))); } export function getBorderRadiusVariant(itemDefinition) { var _a; return (_a = itemDefinition.borderRadius) !== null && _a !== void 0 ? _a : 'item'; } //# sourceMappingURL=index.js.map