diff --git a/package.json b/package.json index 6e1036b..72700c7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "sortable", "grid" ], - "version": "1.1.0", + "version": "1.1.1", "description": "A draggable grid for react native", "main": "built/index.js", "types": "src/index.ts", diff --git a/src/draggable-grid.tsx b/src/draggable-grid.tsx index 4b61894..03e1f71 100644 --- a/src/draggable-grid.tsx +++ b/src/draggable-grid.tsx @@ -20,14 +20,15 @@ interface IBaseItemType { key:string; } -export interface IDraggableGridProps{ +export interface IDraggableGridProps { + dragEnabled:boolean; numColumns:number; data:DataType[]; renderItem:(item:DataType, order:number) => React.ReactElement; style?:ViewStyle; itemHeight?:number; dragStartAnimation?:StyleProp; - onItemPress?:(item:DataType) => void; + onItemPress?:(item:DataType, position:Animated.AnimatedValueXY) => void; onDragStart?:(item:DataType) => void; onDragRelease?:(newSortedData:DataType[]) => void; } @@ -61,7 +62,11 @@ export class DraggableGrid extends React.Compone private items: IItem[] = []; private blockPositions:IPositionOffset[] = []; private activeBlockOffset:IPositionOffset = {x:0, y:0}; - + + static defaultProps = { + dragEnabled: true, + }; + public constructor(props:IDraggableGridProps) { super(props); this.panResponderCapture = false; @@ -90,13 +95,13 @@ export class DraggableGrid extends React.Compone }, }; } - + private resetGridHeight = () => { const {props} = this; const rowCount = Math.ceil(props.data.length / props.numColumns); this.state.gridHeight.setValue(rowCount * this.state.blockHeight) } - + public componentWillReceiveProps(nextProps:IDraggableGridProps) { nextProps.data.forEach((item, index) => { if (this.orderMap[item.key]) { @@ -117,11 +122,11 @@ export class DraggableGrid extends React.Compone this.removeItem(item); }); } - + public componentDidUpdate() { this.resetGridHeight(); } - + private addItem = (item:DataType, index:number) => { this.blockPositions.push(this.getBlockPositionByOrder(this.items.length)); this.orderMap[item.key] = { @@ -132,16 +137,16 @@ export class DraggableGrid extends React.Compone itemData:item, currentPosition:new Animated.ValueXY(this.getBlockPositionByOrder(index)), }); - + } - + private removeItem = (item:IItem) => { const itemIndex = findIndex(this.items, (curItem) => curItem.key === item.key); this.items.splice(itemIndex, 1); this.blockPositions.pop(); delete this.orderMap[item.key]; } - + public componentWillMount() { this.items = this.props.data.map((item, index) => { this.orderMap[item.key] = { @@ -154,7 +159,7 @@ export class DraggableGrid extends React.Compone }; }) } - + public render() { return ( extends React.Compone ); } - + private onBlockPress(itemIndex:number) { - this.props.onItemPress && this.props.onItemPress(this.items[itemIndex].itemData); + this.props.onItemPress && this.props.onItemPress(this.items[itemIndex].itemData, this.items[itemIndex].currentPosition); } - + private getBlockStyle = (itemIndex:number) => { return [ { @@ -207,10 +212,14 @@ export class DraggableGrid extends React.Compone left:this.items[itemIndex].currentPosition.getLayout().left, }, ]; - + } - + private setActiveBlock = (itemIndex:number) => { + if (!this.props.dragEnabled) { + return false; + } + this.panResponderCapture = true; this.setState({ activeItemIndex:itemIndex, @@ -218,12 +227,12 @@ export class DraggableGrid extends React.Compone this.startDragStartAnimation(); }); } - + private getDragStartAnimation = (itemIndex:number) => { if (this.state.activeItemIndex != itemIndex) { return; } - + let dragStartAnimation; if (this.props.dragStartAnimation) { dragStartAnimation = this.props.dragStartAnimation; @@ -235,7 +244,7 @@ export class DraggableGrid extends React.Compone ...dragStartAnimation, }; } - + private getDefaultDragStartAnimation = () => { return { transform:[ @@ -252,7 +261,7 @@ export class DraggableGrid extends React.Compone }, }; } - + private startDragStartAnimation = () => { if (!this.props.dragStartAnimation) { this.state.dragStartAnimatedValue.setValue(1); @@ -262,7 +271,7 @@ export class DraggableGrid extends React.Compone }).start(); } } - + private getBlockPositionByOrder = (order:number) => { if (this.blockPositions[order]) { return this.blockPositions[order]; @@ -275,7 +284,7 @@ export class DraggableGrid extends React.Compone x,y } } - + private assessGridSize = (event:IOnLayoutEvent) => { if (!this.state.hadInitBlockSize) { let blockWidth,blockHeight; @@ -291,7 +300,7 @@ export class DraggableGrid extends React.Compone }); } } - + private initBlockPositions = () => { this.items.forEach((item, index) => { this.blockPositions[index] = this.getBlockPositionByOrder(index); @@ -301,18 +310,18 @@ export class DraggableGrid extends React.Compone }) this.setState({hadInitBlockSize:true}); } - + private getActiveItem = () => { if (this.state.activeItemIndex === undefined) return false; return this.items[this.state.activeItemIndex]; } - + private getDistance = (startOffset:IPositionOffset, endOffset:IPositionOffset) => { const xDistance = startOffset.x + this.activeBlockOffset.x - endOffset.x; const yDistance = startOffset.y + this.activeBlockOffset.y - endOffset.y; return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2)); } - + private onStartDrag(nativeEvent:GestureResponderEvent, gestureState:PanResponderGestureState) { const activeItem = this.getActiveItem(); if (!activeItem) return false; @@ -334,15 +343,15 @@ export class DraggableGrid extends React.Compone y:moveY, }) } - + private onHandMove(nativeEvent:GestureResponderEvent, gestureState:PanResponderGestureState) { const activeItem = this.getActiveItem(); if (!activeItem) return false; const {moveX, moveY } = gestureState; - + const xChokeAmount = Math.max(0, (this.activeBlockOffset.x + moveX) - (this.state.gridLayout.width - this.state.blockWidth)); const xMinChokeAmount = Math.min(0, this.activeBlockOffset.x + moveX); - + const dragPosition = { x:moveX - xChokeAmount - xMinChokeAmount, y:moveY, @@ -350,10 +359,10 @@ export class DraggableGrid extends React.Compone const originPosition = this.blockPositions[this.orderMap[activeItem.key].order]; const dragPositionToActivePositionDistance = this.getDistance(dragPosition, originPosition); activeItem.currentPosition.setValue(dragPosition); - + let closetItemIndex = this.state.activeItemIndex as number; let closetDistance = dragPositionToActivePositionDistance; - + this.items.forEach((item, index) => { if ( index != this.state.activeItemIndex @@ -374,7 +383,7 @@ export class DraggableGrid extends React.Compone this.orderMap[activeItem.key].order = closetOrder; } } - + private resetBlockPositionByOrder = (startOrder:number, endOrder:number) => { if (startOrder > endOrder) { for (let i = startOrder - 1; i >= endOrder; i--) { @@ -390,7 +399,7 @@ export class DraggableGrid extends React.Compone } } } - + private moveBlockToBlockOrderPosition = (itemKey:string) => { const itemIndex = findIndex(this.items, (item) => item.key === itemKey); this.items[itemIndex].currentPosition.flattenOffset(); @@ -402,11 +411,11 @@ export class DraggableGrid extends React.Compone } ).start(); } - + private getKeyByOrder = (order:number) => { return findKey(this.orderMap, (item:IOrderMapItem) => item.order === order) as string; } - + private onHandRelease() { const activeItem = this.getActiveItem(); if (!activeItem) return false; @@ -432,4 +441,4 @@ const styles = StyleSheet.create({ flexDirection:'row', flexWrap:'wrap', }, -}); \ No newline at end of file +});