-
Notifications
You must be signed in to change notification settings - Fork 381
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4ee8a5e
commit 3b165c4
Showing
11 changed files
with
482 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import styled from 'styled-components'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { forwardRef, useCallback } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import DropZone from '../dropzone'; | ||
import { useStory } from '../../app/story'; | ||
|
||
const Page = styled.button` | ||
padding: 0; | ||
margin: 0; | ||
border: none; | ||
outline: 2px solid ${ ( { isActive, theme } ) => isActive ? theme.colors.selection : theme.colors.bg.v1 }; | ||
&:focus, &:hover { | ||
outline: 2px solid ${ ( { theme } ) => theme.colors.selection }; | ||
} | ||
height: ${ ( { height } ) => height }px; | ||
width: ${ ( { width } ) => width }px; | ||
background-color: ${ ( { theme } ) => theme.colors.mg.v1 }; | ||
flex: none; | ||
transition: width .2s ease, height .2s ease; | ||
`; | ||
|
||
// Disable reason: forwardRef render functions do not support propTypes | ||
//eslint-disable-next-line react/prop-types | ||
function DraggablePageWithRef( { pageIndex, onClick, isActive, ariaLabel, width, height, dragIndicatorOffset }, ref ) { | ||
const { state: { pages }, actions: { setCurrentPage, arrangePage } } = useStory(); | ||
|
||
const getArrangeIndex = ( sourceIndex, dstIndex, position ) => { | ||
// If the dropped element is before the dropzone index then we have to deduct | ||
// that from the index to make up for the "lost" element in the row. | ||
const indexAdjustment = sourceIndex < dstIndex ? -1 : 0; | ||
if ( 'left' === position.x ) { | ||
return dstIndex + indexAdjustment; | ||
} | ||
return dstIndex + 1 + indexAdjustment; | ||
}; | ||
|
||
const onDragStart = useCallback( ( evt ) => { | ||
const pageData = { | ||
type: 'page', | ||
index: pageIndex, | ||
}; | ||
evt.dataTransfer.setData( 'text', JSON.stringify( pageData ) ); | ||
}, [ pageIndex ] ); | ||
|
||
const onDrop = ( evt, { position } ) => { | ||
const droppedEl = JSON.parse( evt.dataTransfer.getData( 'text' ) ); | ||
if ( ! droppedEl || 'page' !== droppedEl.type ) { | ||
return; | ||
} | ||
const arrangedIndex = getArrangeIndex( droppedEl.index, pageIndex, position ); | ||
// Do nothing if the index didn't change. | ||
if ( droppedEl.index !== arrangedIndex ) { | ||
const pageId = pages[ droppedEl.index ].id; | ||
arrangePage( { pageId, position: arrangedIndex } ); | ||
setCurrentPage( { pageId } ); | ||
} | ||
}; | ||
|
||
return ( | ||
<DropZone onDrop={ onDrop } pageIndex={ pageIndex } dragIndicatorOffset={ dragIndicatorOffset }> | ||
<Page | ||
draggable="true" | ||
onClick={ onClick } | ||
onDragStart={ onDragStart } | ||
isActive={ isActive } | ||
aria-label={ ariaLabel } | ||
width={ width } | ||
height={ height } | ||
ref={ ref } | ||
/> | ||
</DropZone> | ||
); | ||
} | ||
|
||
const DraggablePage = forwardRef( DraggablePageWithRef ); | ||
|
||
export default DraggablePage; |
Oops, something went wrong.