react-beautiful-dnd
Advanced tools
Comparing version 12.0.0-beta.1 to 12.0.0-beta.2
{ | ||
"name": "react-beautiful-dnd", | ||
"version": "12.0.0-beta.1", | ||
"version": "12.0.0-beta.2", | ||
"description": "Beautiful and accessible drag and drop for lists with React", | ||
@@ -120,2 +120,3 @@ "author": "Alex Reardon <areardon@atlassian.com>", | ||
"react-test-renderer": "^16.9.0", | ||
"react-virtualized": "^9.21.1", | ||
"react-window": "^1.8.5", | ||
@@ -122,0 +123,0 @@ "rimraf": "^3.0.0", |
@@ -51,3 +51,3 @@ <p align="center"> | ||
- Custom drag handles - you can drag a whole item by just a part of it | ||
- Able to drag a [clone](/docs/patterns/using-a-clone.md) or use a [portal](/docs/patterns/using-a-portal.md) | ||
- Able to move the dragging item to another element while dragging (clone, portal) - [Reparenting your `<Draggable />`](/docs/guides/reparenting.md) | ||
- Full [programmatic api 🎮](/docs/sensors/programmatic.md) | ||
@@ -109,2 +109,3 @@ - 🌲 Tree support through the [`@atlaskit/tree`](https://atlaskit.atlassian.com/packages/core/tree) package | ||
- [Rules for `draggableId` and `droppableId`s](/docs/guides/identifiers.md) | ||
- [Focus management](/docs/guides/focus.md) | ||
- [Customising or skipping the drop animation](/docs/guides/drop-animation.md) | ||
@@ -125,3 +126,3 @@ - [Auto scrolling](/docs/guides/auto-scrolling.md) | ||
- [Tables](/docs/patterns/tables.md) | ||
- [Using a portal (`ReactDOM.createPortal`)](/docs/patterns/using-a-portal.md) | ||
- [Reparenting a `<Draggable />`](/docs/guides/reparenting.md) | ||
@@ -128,0 +129,0 @@ ### Support 👩⚕️ |
@@ -53,3 +53,3 @@ // @flow | ||
if (home.descriptor.mode !== 'VIRTUAL') { | ||
if (home.descriptor.mode !== 'virtual') { | ||
warning(` | ||
@@ -59,3 +59,3 @@ You are attempting to add or remove a Draggable [id: ${entry.descriptor.id}] | ||
See https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/virtual-lists.md | ||
See https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/patterns/virtual-lists.md | ||
`); | ||
@@ -62,0 +62,0 @@ return false; |
@@ -25,2 +25,9 @@ // @flow | ||
const axis: Axis = droppable.axis; | ||
// A virtual list will most likely not contain all of the Draggables | ||
// so counting them does not help. | ||
if (droppable.descriptor.mode === 'virtual') { | ||
return patch(axis.line, placeholderSize[axis.line]); | ||
} | ||
// TODO: consider margin collapsing? | ||
@@ -27,0 +34,0 @@ // Using contentBox as that is where the Draggables will sit |
@@ -56,3 +56,3 @@ // @flow | ||
const afterCritical: LiftEffect = { | ||
inVirtualList: home.descriptor.mode === 'VIRTUAL', | ||
inVirtualList: home.descriptor.mode === 'virtual', | ||
displacedBy, | ||
@@ -59,0 +59,0 @@ effected, |
@@ -45,3 +45,4 @@ // @flow | ||
next(action); | ||
autoScroller.scroll(store.getState()); | ||
}; |
@@ -59,2 +59,15 @@ // @flow | ||
function removeScrollJumpRequest(state: State): State { | ||
if (state.isDragging && state.movementMode === 'SNAP') { | ||
return { | ||
// will be overwritten by spread | ||
// needed for flow | ||
phase: 'DRAGGING', | ||
...state, | ||
scrollJumpRequest: null, | ||
}; | ||
} | ||
return state; | ||
} | ||
const idle: IdleState = { phase: 'IDLE', completed: null, shouldFlush: false }; | ||
@@ -202,3 +215,3 @@ | ||
if (state.phase === 'DROP_PENDING') { | ||
return state; | ||
return removeScrollJumpRequest(state); | ||
} | ||
@@ -209,3 +222,3 @@ | ||
if (state.phase === 'COLLECTING') { | ||
return state; | ||
return removeScrollJumpRequest(state); | ||
} | ||
@@ -317,3 +330,3 @@ | ||
if (isEqual(state.viewport.scroll.current, newScroll)) { | ||
return state; | ||
return removeScrollJumpRequest(state); | ||
} | ||
@@ -320,0 +333,0 @@ |
@@ -11,3 +11,3 @@ // @flow | ||
export type DroppableMode = 'STANDARD' | 'VIRTUAL'; | ||
export type DroppableMode = 'standard' | 'virtual'; | ||
export type DroppableDescriptor = {| | ||
@@ -482,2 +482,2 @@ id: DroppableId, | ||
export type ErrorMode = 'RECOVER' | 'ONLY_ABORT'; | ||
export type ErrorMode = 'recover' | 'abort'; |
@@ -44,3 +44,3 @@ // @flow | ||
import useAnnouncer from '../use-announcer'; | ||
import useDragHandleDescription from '../use-lift-instruction'; | ||
import useLiftInstruction from '../use-lift-instruction'; | ||
import AppContext, { type AppContextValue } from '../context/app-context'; | ||
@@ -96,3 +96,3 @@ import useStartupValidation from './use-startup-validation'; | ||
const liftInstructionId: ElementId = useDragHandleDescription( | ||
const liftInstructionId: ElementId = useLiftInstruction( | ||
contextId, | ||
@@ -99,0 +99,0 @@ liftInstruction, |
@@ -31,3 +31,4 @@ // @flow | ||
props.liftInstruction || preset.liftInstruction; | ||
const errorMode: ErrorMode = props.errorMode || 'RECOVER'; | ||
// TODO: no caps | ||
const errorMode: ErrorMode = props.errorMode || 'recover'; | ||
@@ -34,0 +35,0 @@ // We need the error boundary to be on the outside of App |
@@ -57,4 +57,5 @@ // @flow | ||
// used for shared global styles | ||
'data-rbd-draggable-context-id': string, | ||
'data-rbd-draggable-id': string, | ||
'data-rbd-draggable-context-id': ContextId, | ||
// used for lookups | ||
'data-rbd-draggable-id': DraggableId, | ||
// used to know when a transition ends | ||
@@ -61,0 +62,0 @@ onTransitionEnd: ?(event: TransitionEvent) => void, |
@@ -52,2 +52,3 @@ // @flow | ||
draggingFromThisWith: null, | ||
isUsingPlaceholder: false, | ||
}, | ||
@@ -62,70 +63,62 @@ useClone: null, | ||
const getMapProps = memoizeOne( | ||
( | ||
id: DroppableId, | ||
isEnabled: boolean, | ||
isDraggingOver: boolean, | ||
dragging: DraggableDimension, | ||
snapshot: StateSnapshot, | ||
renderClone: ?DraggableChildrenFn, | ||
): MapProps => { | ||
const isHome: boolean = dragging.descriptor.droppableId === id; | ||
const getMapProps = memoizeOne(( | ||
id: DroppableId, | ||
isEnabled: boolean, | ||
isDraggingOverForConsumer: boolean, | ||
isDraggingOverForImpact: boolean, | ||
dragging: DraggableDimension, | ||
// snapshot: StateSnapshot, | ||
renderClone: ?DraggableChildrenFn, | ||
): MapProps => { | ||
const draggableId: DraggableId = dragging.descriptor.id; | ||
const isHome: boolean = dragging.descriptor.droppableId === id; | ||
if (isHome) { | ||
const useClone: ?UseClone = renderClone | ||
? { | ||
render: renderClone, | ||
dragging: dragging.descriptor, | ||
} | ||
: null; | ||
if (isHome) { | ||
const useClone: ?UseClone = renderClone | ||
? { | ||
render: renderClone, | ||
dragging: dragging.descriptor, | ||
} | ||
: null; | ||
return { | ||
placeholder: dragging.placeholder, | ||
shouldAnimatePlaceholder: false, | ||
snapshot, | ||
useClone, | ||
}; | ||
} | ||
const snapshot: StateSnapshot = { | ||
isDraggingOver: isDraggingOverForConsumer, | ||
draggingOverWith: isDraggingOverForConsumer ? draggableId : null, | ||
draggingFromThisWith: draggableId, | ||
isUsingPlaceholder: true, | ||
}; | ||
if (!isEnabled) { | ||
return idleWithoutAnimation; | ||
} | ||
// not over foreign list - return idle | ||
if (!isDraggingOver) { | ||
// TODO: needs to be with animation | ||
return idleWithAnimation; | ||
} | ||
return { | ||
placeholder: dragging.placeholder, | ||
// Animating placeholder in foreign list | ||
shouldAnimatePlaceholder: true, | ||
shouldAnimatePlaceholder: false, | ||
snapshot, | ||
useClone: null, | ||
useClone, | ||
}; | ||
}, | ||
); | ||
} | ||
const getSnapshot = memoizeOne( | ||
( | ||
id: DroppableId, | ||
isDraggingOver: boolean, | ||
dragging: DraggableDimension, | ||
): StateSnapshot => { | ||
const draggableId: DraggableId = dragging.descriptor.id; | ||
const isHome: boolean = dragging.descriptor.droppableId === id; | ||
const draggingOverWith: ?DraggableId = isDraggingOver | ||
? draggableId | ||
: null; | ||
const draggingFromThisWith: ?DraggableId = isHome ? draggableId : null; | ||
if (!isEnabled) { | ||
return idleWithoutAnimation; | ||
} | ||
return { | ||
isDraggingOver, | ||
draggingOverWith, | ||
draggingFromThisWith, | ||
}; | ||
}, | ||
); | ||
// not over foreign list - return idle | ||
if (!isDraggingOverForImpact) { | ||
return idleWithAnimation; | ||
} | ||
const snapshot: StateSnapshot = { | ||
isDraggingOver: isDraggingOverForConsumer, | ||
draggingOverWith: draggableId, | ||
draggingFromThisWith: null, | ||
isUsingPlaceholder: true, | ||
}; | ||
return { | ||
placeholder: dragging.placeholder, | ||
// Animating placeholder in foreign list | ||
shouldAnimatePlaceholder: true, | ||
snapshot, | ||
useClone: null, | ||
}; | ||
}); | ||
const selector = (state: State, ownProps: OwnProps): MapProps => { | ||
@@ -151,4 +144,2 @@ // not checking if item is disabled as we need the home list to display a placeholder | ||
// Snapshot based on current impact | ||
const snapshot: StateSnapshot = getSnapshot(id, isDraggingOver, dragging); | ||
return getMapProps( | ||
@@ -158,4 +149,4 @@ id, | ||
isDraggingOver, | ||
isDraggingOver, | ||
dragging, | ||
snapshot, | ||
renderClone, | ||
@@ -179,14 +170,8 @@ ); | ||
// to move everything back | ||
const snapshot: StateSnapshot = getSnapshot( | ||
id, | ||
whatIsDraggedOverFromResult(completed.result) === id, | ||
dragging, | ||
); | ||
return getMapProps( | ||
id, | ||
isEnabled, | ||
whatIsDraggedOverFromResult(completed.result) === id, | ||
whatIsDraggedOver(completed.impact) === id, | ||
dragging, | ||
snapshot, | ||
renderClone, | ||
@@ -241,3 +226,3 @@ ); | ||
const defaultProps = ({ | ||
mode: 'STANDARD', | ||
mode: 'standard', | ||
type: 'DEFAULT', | ||
@@ -244,0 +229,0 @@ direction: 'vertical', |
@@ -45,2 +45,5 @@ // @flow | ||
draggingFromThisWith: ?DraggableId, | ||
// Whether or not the placeholder is actively being used. | ||
// This is useful information when working with virtual lists | ||
isUsingPlaceholder: boolean, | ||
|}; | ||
@@ -47,0 +50,0 @@ |
@@ -91,7 +91,7 @@ // @flow | ||
if (args.props.mode === 'STANDARD') { | ||
if (args.props.mode === 'standard') { | ||
runChecks(args, standard); | ||
} | ||
if (args.props.mode === 'VIRTUAL') { | ||
if (args.props.mode === 'virtual') { | ||
runChecks(args, virtual); | ||
@@ -98,0 +98,0 @@ } |
@@ -67,3 +67,3 @@ // @flow | ||
// If the failure was due to an invariant failure - then we handle the error | ||
if (this.props.mode === 'RECOVER' && isInvariant(error)) { | ||
if (this.props.mode === 'recover' && isInvariant(error)) { | ||
this.setState({}); | ||
@@ -70,0 +70,0 @@ } |
// @flow | ||
import { useRef, useEffect } from 'react'; | ||
import invariant from 'tiny-invariant'; | ||
import { useEffect } from 'react'; | ||
import { useMemo } from 'use-memo-one'; | ||
@@ -17,10 +16,6 @@ import type { ContextId, ElementId } from '../../types'; | ||
const id: string = useMemo(() => getId(contextId), [contextId]); | ||
const ref = useRef<?HTMLElement>(null); | ||
useEffect( | ||
function mount() { | ||
invariant(!ref.current, 'Description node already mounted'); | ||
const el: HTMLElement = document.createElement('div'); | ||
ref.current = el; | ||
@@ -40,8 +35,4 @@ // identifier | ||
return function unmount() { | ||
const toBeRemoved: ?HTMLElement = ref.current; | ||
invariant(toBeRemoved, 'Cannot unmount description node'); | ||
// Remove from body | ||
getBodyElement().removeChild(toBeRemoved); | ||
ref.current = null; | ||
getBodyElement().removeChild(el); | ||
}; | ||
@@ -48,0 +39,0 @@ }, |
@@ -194,4 +194,4 @@ // @flow | ||
function getShouldRespectForcePress(): boolean { | ||
const item: DraggableEntry = registry.draggable.getById(draggableId); | ||
return item.options.shouldRespectForcePress; | ||
// not looking up the entry as it might have been removed in a virtual list | ||
return entry.options.shouldRespectForcePress; | ||
} | ||
@@ -198,0 +198,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1378562
38262
152
286
74