Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
alexreardon authored Mar 21, 2019
2 parents 8386259 + 66d3fff commit 855e274
Show file tree
Hide file tree
Showing 24 changed files with 591 additions and 578 deletions.
22 changes: 11 additions & 11 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
{
"dist/react-beautiful-dnd.js": {
"bundled": 355996,
"minified": 138322,
"gzipped": 40545
"bundled": 357308,
"minified": 138768,
"gzipped": 40712
},
"dist/react-beautiful-dnd.min.js": {
"bundled": 302438,
"minified": 113232,
"gzipped": 32713
"bundled": 303784,
"minified": 113686,
"gzipped": 32910
},
"dist/react-beautiful-dnd.esm.js": {
"bundled": 236773,
"minified": 125151,
"gzipped": 31183,
"bundled": 237952,
"minified": 125718,
"gzipped": 31356,
"treeshaked": {
"rollup": {
"code": 85436,
"code": 85891,
"import_statements": 832
},
"webpack": {
"code": 88124
"code": 88596
}
}
}
Expand Down
55 changes: 8 additions & 47 deletions src/view/drag-drop-context/drag-drop-context.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ import {
updateDroppableIsCombineEnabled,
collectionStarting,
} from '../../state/action-creators';
import { getFormattedMessage } from '../../dev-warning';
import { peerDependencies } from '../../../package.json';
import checkReactVersion from './check-react-version';
import checkDoctype from './check-doctype';
import isMovementAllowed from '../../state/is-movement-allowed';
import ErrorBoundary from '../error-boundary';

type Props = {|
...Responders,
Expand All @@ -58,25 +58,6 @@ export const resetServerContext = () => {
resetStyleContext();
};

const printFatalDevError = (error: Error) => {
if (process.env.NODE_ENV === 'production') {
return;
}
// eslint-disable-next-line no-console
console.error(
...getFormattedMessage(
`
An error has occurred while a drag is occurring.
Any existing drag will be cancelled.
> ${error.message}
`,
),
);
// eslint-disable-next-line no-console
console.error('raw', error);
};

export default class DragDropContext extends React.Component<Props> {
/* eslint-disable react/sort-comp */
store: Store;
Expand Down Expand Up @@ -175,7 +156,6 @@ export default class DragDropContext extends React.Component<Props> {
getIsMovementAllowed = () => isMovementAllowed(this.store.getState());

componentDidMount() {
window.addEventListener('error', this.onWindowError);
this.styleMarshal.mount();
this.announcer.mount();

Expand All @@ -185,43 +165,24 @@ export default class DragDropContext extends React.Component<Props> {
}
}

componentDidCatch(error: Error) {
this.onFatalError(error);

// If the failure was due to an invariant failure - then we handle the error
if (error.message.indexOf('Invariant failed') !== -1) {
this.setState({});
return;
}

// Error is more serious and we throw it
throw error;
}

componentWillUnmount() {
window.removeEventListener('error', this.onWindowError);

const state: State = this.store.getState();
if (state.phase !== 'IDLE') {
this.store.dispatch(clean());
}

this.tryResetStore();
this.styleMarshal.unmount();
this.announcer.unmount();
}

onFatalError = (error: Error) => {
printFatalDevError(error);

tryResetStore = () => {
const state: State = this.store.getState();
if (state.phase !== 'IDLE') {
this.store.dispatch(clean());
}
};

onWindowError = (error: Error) => this.onFatalError(error);

render() {
return this.props.children;
return (
<ErrorBoundary onError={this.tryResetStore}>
{this.props.children}
</ErrorBoundary>
);
}
}
143 changes: 100 additions & 43 deletions src/view/draggable/connected-draggable.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,54 +32,83 @@ import type {
DragImpact,
DisplacementMap,
MovementMode,
DropResult,
} from '../../types';
import type {
MapProps,
OwnProps,
DefaultProps,
DispatchProps,
Selector,
StateSnapshot,
DropAnimation,
} from './draggable-types';
import whatIsDraggedOver from '../../state/droppable/what-is-dragged-over';

const getCombineWith = (impact: DragImpact): ?DraggableId => {
if (!impact.merge) {
return null;
const getDraggingOverFromResult = (result: DropResult): ?DraggableId => {
if (result.destination) {
return result.destination.droppableId;
}
if (result.combine) {
return result.combine.droppableId;
}
return impact.merge.combine.draggableId;
return null;
};

const defaultMapProps: MapProps = {
secondary: {
offset: origin,
combineTargetFor: null,
shouldAnimateDisplacement: true,
},
dragging: null,
const getCombineWithFromResult = (result: DropResult): ?DraggableId => {
return result.combine ? result.combine.draggableId : null;
};

const getCombineWithFromImpact = (impact: DragImpact): ?DraggableId => {
return impact.merge ? impact.merge.combine.draggableId : null;
};

// Returning a function to ensure each
// Draggable gets its own selector
export const makeMapStateToProps = (): Selector => {
const memoizedOffset = memoizeOne(
(x: number, y: number): Position => ({ x, y }),
const getDraggingSnapshot = memoizeOne(
(
mode: MovementMode,
draggingOver: ?DroppableId,
combineWith: ?DraggableId,
dropping: ?DropAnimation,
): StateSnapshot => ({
isDragging: true,
isDropAnimating: Boolean(dropping),
dropAnimation: dropping,
mode,
draggingOver,
combineWith,
combineTargetFor: null,
}),
);

const getSecondaryProps = memoizeOne(
(
offset: Position,
combineTargetFor: ?DraggableId = null,
shouldAnimateDisplacement: boolean,
): MapProps => ({
secondary: {
offset,
combineTargetFor,
shouldAnimateDisplacement,
},
dragging: null,
const getSecondarySnapshot = memoizeOne(
(combineTargetFor: ?DraggableId): StateSnapshot => ({
isDragging: false,
isDropAnimating: false,
dropAnimation: null,
mode: null,
draggingOver: null,
combineTargetFor,
combineWith: null,
}),
);

const defaultMapProps: MapProps = {
mapped: {
type: 'SECONDARY',
offset: origin,
combineTargetFor: null,
shouldAnimateDisplacement: true,
snapshot: getSecondarySnapshot(null),
},
};

const memoizedOffset = memoizeOne(
(x: number, y: number): Position => ({ x, y }),
);

const getDraggingProps = memoizeOne(
(
offset: Position,
Expand All @@ -91,16 +120,33 @@ export const makeMapStateToProps = (): Selector => {
combineWith: ?DraggableId,
forceShouldAnimate: ?boolean,
): MapProps => ({
dragging: {
mode,
mapped: {
type: 'DRAGGING',
dropping: null,
offset,
dimension,
draggingOver,
combineWith,
mode,
offset,
dimension,
forceShouldAnimate,
snapshot: getDraggingSnapshot(mode, draggingOver, combineWith, null),
},
}),
);

const getSecondaryProps = memoizeOne(
(
offset: Position,
combineTargetFor: ?DraggableId = null,
shouldAnimateDisplacement: boolean,
): MapProps => ({
mapped: {
type: 'SECONDARY',
offset,
combineTargetFor,
shouldAnimateDisplacement,
snapshot: getSecondarySnapshot(combineTargetFor),
},
secondary: null,
}),
);

Expand Down Expand Up @@ -156,7 +202,7 @@ export const makeMapStateToProps = (): Selector => {
// const shouldAnimateDragMovement: boolean = state.shouldAnimate;
const mode: MovementMode = state.movementMode;
const draggingOver: ?DroppableId = whatIsDraggedOver(state.impact);
const combineWith: ?DraggableId = getCombineWith(state.impact);
const combineWith: ?DraggableId = getCombineWithFromImpact(state.impact);
const forceShouldAnimate: ?boolean = state.forceShouldAnimate;

return getDraggingProps(
Expand All @@ -178,29 +224,40 @@ export const makeMapStateToProps = (): Selector => {

const dimension: DraggableDimension =
state.dimensions.draggables[ownProps.draggableId];
const draggingOver: ?DroppableId = whatIsDraggedOver(completed.impact);
const combineWith: ?DraggableId = getCombineWith(completed.impact);

const result: DropResult = completed.result;
const mode: MovementMode = result.mode;
// these need to be pulled from the result as they can be different to the final impact
const draggingOver: ?DroppableId = getDraggingOverFromResult(result);
const combineWith: ?DraggableId = getCombineWithFromResult(result);
const duration: number = state.dropDuration;
const mode: MovementMode = completed.result.mode;

// not memoized as it is the only execution
const dropping: DropAnimation = {
duration,
curve: curves.drop,
moveTo: state.newHomeClientOffset,
opacity: combineWith ? combine.opacity.drop : null,
scale: combineWith ? combine.scale.drop : null,
};

return {
dragging: {
mapped: {
type: 'DRAGGING',
offset: state.newHomeClientOffset,
dimension,
dropping,
draggingOver,
combineWith,
mode,
forceShouldAnimate: null,
dropping: {
duration,
curve: curves.drop,
moveTo: state.newHomeClientOffset,
opacity: combineWith ? combine.opacity.drop : null,
scale: combineWith ? combine.scale.drop : null,
},
snapshot: getDraggingSnapshot(
mode,
draggingOver,
combineWith,
dropping,
),
},
secondary: null,
};
}

Expand Down
15 changes: 11 additions & 4 deletions src/view/draggable/draggable-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,33 @@ export type DispatchProps = {|
|};

export type DraggingMapProps = {|
type: 'DRAGGING',
offset: Position,
mode: MovementMode,
dropping: ?DropAnimation,
dimension: DraggableDimension,
draggingOver: ?DroppableId,
draggingOver: ?DraggableId,
combineWith: ?DraggableId,
dimension: DraggableDimension,
forceShouldAnimate: ?boolean,
snapshot: StateSnapshot,
|};

export type SecondaryMapProps = {|
type: 'SECONDARY',
offset: Position,
combineTargetFor: ?DraggableId,
shouldAnimateDisplacement: boolean,
snapshot: StateSnapshot,
|};

export type MappedProps = DraggingMapProps | SecondaryMapProps;

export type MapProps = {|
// when an item is being displaced by a dragging item,
// we need to know if that movement should be animated
dragging: ?DraggingMapProps,
secondary: ?SecondaryMapProps,
mapped: MappedProps,
// dragging: ?DraggingMapProps,
// secondary: ?SecondaryMapProps,
|};

export type ChildrenFn = (Provided, StateSnapshot) => Node | null;
Expand Down
Loading

0 comments on commit 855e274

Please sign in to comment.