UNPKG

@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-migration

Version:

An optional Pragmatic drag and drop package that enables rapid migration from react-beautiful-dnd to Pragmatic drag and drop

227 lines (217 loc) 8.38 kB
import _extends from "@babel/runtime/helpers/extends"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; /** * @jsxRuntime classic * @jsx jsx */ import { useCallback, useLayoutEffect, useRef, useState } from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 import { css, jsx } from '@emotion/react'; // eslint-disable-next-line import/no-extraneous-dependencies import { isSameLocation } from '../../drag-drop-context/draggable-location'; import { getActualDestination } from '../../drag-drop-context/get-destination'; import { useDragDropContext } from '../../drag-drop-context/internal-context'; import { useMonitorForLifecycle } from '../../drag-drop-context/lifecycle-context'; import { rbdInvariant } from '../../drag-drop-context/rbd-invariant'; import { customAttributes } from '../../utils/attributes'; import { directionMapping, lineOffset, lineThickness } from './constants'; import { getIndicatorSizeAndOffset } from './get-dimensions'; var scrollMarginTop = lineThickness + 2 * lineOffset; var baseStyles = css({ background: "var(--ds-border-brand, #0C66E4)", /** * Ensures that when the indicator is scrolled into view there is visual * space around it. * * Otherwise it will hug the edge of the container and be hard to see. */ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766 scrollMarginTop: scrollMarginTop, /** * The bottom margin needs to be slightly bigger for the gap to look * the same visually. * * It's unclear why, this was found through testing. */ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 scrollMarginBottom: scrollMarginTop + lineOffset }); /** * For virtual lists, the indicator might not be a sibling of the contents. * This can lead to issues like wrapping. * * This style 'resets' it so that there is a consistent initial position. */ var virtualStyles = css({ position: 'absolute', top: 0, left: 0 }); /** * When targeting the source location, we hide the drop indicator. * But it should still be scrolled to, so we only want to hide it visually, * instead of not rendering it. */ var visuallyHiddenStyles = css({ opacity: 0 }); var directionStyles = { horizontal: css({ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766 width: lineThickness, height: '100%', // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 marginLeft: -lineThickness }), vertical: css({ width: '100%', // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766 height: lineThickness, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 marginTop: -lineThickness }) }; function getDynamicStyles(_ref) { var direction = _ref.direction, dimensions = _ref.dimensions, indicatorOffset = _ref.indicatorOffset; if (dimensions === null) { /** * We hide the indicator initially until dimensions can be taken. */ return { opacity: 0 }; } var _directionMapping$dir = directionMapping[direction], mainAxis = _directionMapping$dir.mainAxis, crossAxis = _directionMapping$dir.crossAxis; return _defineProperty(_defineProperty({ transform: "".concat(mainAxis.style.transform, "(").concat(dimensions.mainAxis.offset - indicatorOffset, "px)") }, crossAxis.style.length, dimensions.crossAxis.length), crossAxis.style.offset, dimensions.crossAxis.offset); } var dropIndicatorData = _defineProperty({}, customAttributes.dropIndicator, ''); export var DropIndicator = function DropIndicator(_ref3) { var direction = _ref3.direction, mode = _ref3.mode; var _useDragDropContext = useDragDropContext(), contextId = _useDragDropContext.contextId, getDragState = _useDragDropContext.getDragState; var ref = useRef(null); var _useState = useState(null), _useState2 = _slicedToArray(_useState, 2), dimensions = _useState2[0], setDimensions = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), isHidden = _useState4[0], setIsHidden = _useState4[1]; var monitorForLifecycle = useMonitorForLifecycle(); var updateIndicator = useCallback(function (_ref4) { var targetLocation = _ref4.targetLocation, source = _ref4.source, destination = _ref4.destination; if (!targetLocation) { return setDimensions(null); } var isInHomeLocation = isSameLocation(source, destination); /** * Determines if the drop indicator should be hidden. * * This is desired when the current drop target would not change the position * of the draggable. */ setIsHidden(isInHomeLocation); return setDimensions(getIndicatorSizeAndOffset({ targetLocation: targetLocation, isInHomeLocation: isInHomeLocation, direction: direction, mode: mode, contextId: contextId })); }, [contextId, direction, mode]); /** * This is in a `useLayoutEffect` for immediacy. * * When mounting (cross-axis movement) the indicator should update into * its correct position right away, so that the drag preview can be placed * correctly. */ useLayoutEffect(function () { var dragState = getDragState(); if (!dragState.isDragging) { return; } /** * If the indicator is only just mounting then it needs an immediate * update to have it appear in the correct position. */ var targetLocation = dragState.targetLocation, sourceLocation = dragState.sourceLocation; var destination = getActualDestination({ start: sourceLocation, target: targetLocation }); updateIndicator({ targetLocation: targetLocation, destination: destination, source: sourceLocation }); return monitorForLifecycle({ onPrePendingDragUpdate: function onPrePendingDragUpdate(_ref5) { var update = _ref5.update, targetLocation = _ref5.targetLocation; var _update$destination = update.destination, destination = _update$destination === void 0 ? null : _update$destination, source = update.source; updateIndicator({ targetLocation: targetLocation, source: source, destination: destination }); } }); }, [contextId, direction, getDragState, mode, monitorForLifecycle, updateIndicator]); /** * Scroll the indicator into view. * * This is in a `useLayoutEffect` for immediacy. * Otherwise the keyboard drag preview can appear in the wrong (old) location. */ useLayoutEffect(function () { if (dimensions === null) { return; } /** * If we are doing a mouse drag, * then we don't want to scroll to the indicator. * * Otherwise, it will conflict with the auto-scroll addon. */ var dragState = getDragState(); if (!dragState.isDragging || dragState.mode !== 'SNAP') { return; } var element = ref.current; rbdInvariant(element instanceof HTMLElement); element.scrollIntoView({ block: 'nearest' }); }, [dimensions, getDragState]); var mainAxis = directionMapping[direction].mainAxis; var indicatorOffset = ref.current ? ref.current[mainAxis.offset] : 0; var dynamicStyles = getDynamicStyles({ direction: direction, dimensions: dimensions, indicatorOffset: indicatorOffset }); var isVirtual = mode === 'virtual'; return jsx("div", _extends({ ref: ref, css: [baseStyles, directionStyles[direction], isVirtual && virtualStyles, isHidden && visuallyHiddenStyles] // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 , style: dynamicStyles }, dropIndicatorData)); };