UNPKG

react-beautiful-dnd

Version:

Beautiful, accessible drag and drop for lists with React.js

154 lines (131 loc) 4.99 kB
// @flow import type { PropType, HasDefaultProp } from 'babel-plugin-react-flow-props-to-prop-types'; import type { DraggableId, DraggableDimension, Position, TypeId, Direction, ZIndex, HTMLElement, ReactElement, } from '../../types'; import { lift, move, moveByWindowScroll, moveForward, moveBackward, crossAxisMoveForward, crossAxisMoveBackward, drop, cancel, dropAnimationFinished, } from '../../state/action-creators'; import type { Provided as DragHandleProvided, } from '../drag-handle/drag-handle-types'; // These styles are applied by default to allow for a // better touch device drag and drop experience. // Users can opt out of these styles or change them if // they really need too for their specific use case. export type BaseStyle = { // A long press on anchors usually pops a content menu that has options for // the link such as 'Open in new tab'. Because long press is used to start // a drag we need to opt out of this behavior WebkitTouchCallout: 'none', // Webkit based browsers add a grey overlay to anchors when they are active. // We remove this tap overlay as it is confusing for users // https://css-tricks.com/snippets/css/remove-gray-highlight-when-tapping-links-in-mobile-safari/ WebkitTapHighlightColor: 'rgba(0,0,0,0)', // Added to avoid the *pull to refresh action* and *anchor focus* on Android Chrome touchAction: 'none', } export type DraggingStyle = BaseStyle & { // Allow scrolling of the element behind the dragging element pointerEvents: 'none', // `position: fixed` is used to ensure that the element is always positioned // in the correct position and ignores the surrounding position:relative parents position: 'fixed', // When we do `position: fixed` the element looses its normal dimensions, // especially if using flexbox. We set the width and height manually to // ensure the element has the same dimensions as before it started dragging width: number, height: number, // When we set the width and height they include the padding on the element. // We use box-sizing: border-box to ensure that the width and height are inclusive of the padding boxSizing: 'border-box', // We initially position the element in the same visual spot as when it started. // To do this we give the element the top / left position with the margins considered top: number, left: number, // We clear any top or left margins on the element to ensure it does not push // the element positioned with the top/left position. // We also clear the margin right / bottom. This has no positioning impact, // but it is cleanest to just remove all the margins rather than only the top and left. margin: 0, // Move the element in response to a user dragging transform: ?string, // When dragging or dropping we control the z-index to ensure that // the layering is correct zIndex: ZIndex, } export type NotDraggingStyle = BaseStyle & { transition: ?string, transform: ?string, pointerEvents: 'none' | 'auto', } export type DraggableStyle = DraggingStyle | NotDraggingStyle; export type ZIndexOptions = {| dragging: number, dropAnimating: number, |} export type Provided = {| innerRef: (?HTMLElement) => void, draggableStyle: ?DraggableStyle, dragHandleProps: ?DragHandleProvided, placeholder: ?ReactElement, |} export type StateSnapshot = {| isDragging: boolean, |} // Using PropType<*,*> to allow strict typing within code and looser typing // for React PropTypes // https://github.com/thejameskyle/babel-plugin-react-flow-props-to-prop-types#override-type-used-in-proptypes export type DispatchProps = { lift: PropType<typeof lift, Function>, move: PropType<typeof move, Function>, moveByWindowScroll: PropType<typeof moveByWindowScroll, Function>, moveForward: PropType<typeof moveForward, Function>, moveBackward: PropType<typeof moveBackward, Function>, crossAxisMoveForward: PropType<typeof crossAxisMoveForward, Function>, crossAxisMoveBackward: PropType<typeof crossAxisMoveBackward, Function>, drop: PropType<typeof drop, Function>, cancel: PropType<typeof cancel, Function>, dropAnimationFinished: PropType<typeof dropAnimationFinished, Function>, } export type MapProps = {| isDragging: boolean, // only provided when dragging // can be null if not over a droppable direction: ?Direction, isDropAnimating: boolean, canLift: boolean, canAnimate: boolean, offset: Position, dimension: ?DraggableDimension, |} export type OwnProps = {| draggableId: DraggableId, children: (Provided, StateSnapshot) => ?ReactElement, type: HasDefaultProp<TypeId>, isDragDisabled: HasDefaultProp<boolean>, |} export type DefaultProps = {| type: TypeId, isDragDisabled: boolean, |} export type Props = MapProps & DispatchProps & OwnProps; // Having issues getting the correct reselect type // export type Selector = OutputSelector<State, OwnProps, MapProps>; export type Selector = Function;