-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update packages/compose/src/hooks/use-dragging/README.md
Co-Authored-By: Enrique Piqueras <[email protected]> (+13 squashed commits) Squashed commits: [35d3443b82] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [0666388f69] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [7291bd40d4] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [e4cc24e24c] Update packages/compose/src/hooks/use-dragging/index.js Co-Authored-By: Enrique Piqueras <[email protected]> [10e835bdbc] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [72607b4dc0] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [e7a80b3b13] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [75fa7962d2] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [945b498921] Update packages/compose/src/hooks/use-dragging/README.md Co-Authored-By: Enrique Piqueras <[email protected]> [f103de2ea7] Update packages/components/src/angle-picker/stories/index.js Co-Authored-By: Enrique Piqueras <[email protected]> [e572887] Update snapshot [0f502ac] Add documentation to the useDragging hook [97455c2] Add AnglePicker Component; Add useDragging hook
- Loading branch information
1 parent
dcb08f3
commit ed3f482
Showing
9 changed files
with
372 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useRef } from '@wordpress/element'; | ||
import { useInstanceId, __experimentalUseDragging as useDragging } from '@wordpress/compose'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import BaseControl from '../base-control'; | ||
|
||
function getAngle( centerX, centerY, pointX, pointY ) { | ||
const y = pointY - centerY; | ||
const x = pointX - centerX; | ||
|
||
const angleInRadians = Math.atan2( y, x ); | ||
const angleInDeg = Math.round( angleInRadians * ( 180 / Math.PI ) ) + 90; | ||
if ( angleInDeg < 0 ) { | ||
return 360 + angleInDeg; | ||
} | ||
return angleInDeg; | ||
} | ||
|
||
const AngleCircle = ( { value, onChange, ...props } ) => { | ||
const angleCircleRef = useRef(); | ||
const angleCircleCenter = useRef(); | ||
|
||
const setAngleCircleCenter = () => { | ||
const rect = angleCircleRef.current.getBoundingClientRect(); | ||
angleCircleCenter.current = { | ||
x: rect.x + ( rect.width / 2 ), | ||
y: rect.y + ( rect.height / 2 ), | ||
}; | ||
}; | ||
|
||
const changeAngleToPosition = ( event ) => { | ||
const { x: centerX, y: centerY } = angleCircleCenter.current; | ||
onChange( getAngle( centerX, centerY, event.clientX, event.clientY ) ); | ||
}; | ||
|
||
const { startDrag, isDragging } = useDragging( { | ||
onDragStart: ( event ) => { | ||
setAngleCircleCenter(); | ||
changeAngleToPosition( event ); | ||
}, | ||
onDragMove: changeAngleToPosition, | ||
onDragEnd: changeAngleToPosition, | ||
} ); | ||
return ( | ||
/* eslint-disable jsx-a11y/no-static-element-interactions */ | ||
<div | ||
ref={ angleCircleRef } | ||
onMouseDown={ startDrag } | ||
className="components-angle-picker__angle-circle" | ||
style={ isDragging ? { cursor: 'grabbing' } : undefined } | ||
{ ...props } | ||
> | ||
<div | ||
style={ value ? { transform: `rotate(${ value }deg)` } : undefined } | ||
className="components-angle-picker__angle-circle-indicator-wrapper" | ||
> | ||
<span className="components-angle-picker__angle-circle-indicator" /> | ||
</div> | ||
</div> | ||
/* eslint-enable jsx-a11y/no-static-element-interactions */ | ||
); | ||
}; | ||
|
||
export default function AnglePicker( { value, onChange, label = __( 'Angle' ) } ) { | ||
const instanceId = useInstanceId( AnglePicker ); | ||
const inputId = `components-angle-picker__input-${ instanceId }`; | ||
return ( | ||
<BaseControl | ||
label={ label } | ||
id={ inputId } | ||
className="components-angle-picker" | ||
> | ||
<AngleCircle | ||
value={ value } | ||
onChange={ onChange } | ||
aria-hidden="true" | ||
/> | ||
<input | ||
className="components-angle-picker__input-field" | ||
type="number" | ||
id={ inputId } | ||
onChange={ ( event ) => { | ||
const unprocessedValue = event.target.value; | ||
const inputValue = unprocessedValue !== '' ? | ||
parseInt( event.target.value, 10 ) : | ||
0; | ||
onChange( inputValue ); | ||
} } | ||
value={ value } | ||
min={ 0 } | ||
max={ 360 } | ||
step="1" | ||
/> | ||
</BaseControl> | ||
); | ||
} | ||
|
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,23 @@ | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useState } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import AnglePicker from '../'; | ||
|
||
export default { title: 'Components|AnglePicker', component: AnglePicker }; | ||
|
||
const AnglePickerWithState = () => { | ||
const [ angle, setAngle ] = useState(); | ||
return ( | ||
<AnglePicker value={ angle } onChange={ setAngle } /> | ||
); | ||
}; | ||
|
||
export const _default = () => { | ||
return <AnglePickerWithState />; | ||
}; |
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,42 @@ | ||
.components-angle-picker { | ||
width: 50%; | ||
&.components-base-control .components-base-control__label { | ||
display: block; | ||
} | ||
} | ||
|
||
.components-angle-picker__input-field { | ||
width: calc(100% - #{$icon-button-size}); | ||
max-width: 100px; | ||
} | ||
|
||
.components-angle-picker__angle-circle { | ||
width: $icon-button-size - ( 2 * $grid-size-small ); | ||
height: $icon-button-size - ( 2 * $grid-size-small ); | ||
border: 2px solid $dark-gray-500; | ||
border-radius: 50%; | ||
float: left; | ||
margin-right: $grid-size-small; | ||
cursor: grab; | ||
} | ||
|
||
.components-angle-picker__angle-circle-indicator-wrapper { | ||
position: relative; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
|
||
.components-angle-picker__angle-circle-indicator { | ||
width: 1px; | ||
height: 1px; | ||
border-radius: 50%; | ||
border: 3px solid $dark-gray-500; | ||
display: block; | ||
position: absolute; | ||
top: -($icon-button-size - (2 * $grid-size-small)) / 2; | ||
bottom: 0; | ||
left: 0; | ||
right: 0; | ||
margin: auto; | ||
background: $dark-gray-500; | ||
} |
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,88 @@ | ||
`useDragging` | ||
============== | ||
|
||
In some situations, we want to have simple drag & drop behaviors. | ||
Typically drag & drop behaviors follow a common pattern: We have an element that we want to drag or where we want dragging to start; the dragging starts when the `onMouseDown` event happens on the target element. When the dragging starts, global event listeners for mouse movement (`mousemove`) and the mouse up event (`mouseup`) are added. When the global mouse movement event triggers, the dragging behavior happens (e.g., a position is updated), when the mouse up event triggers, dragging stops, and both global event listeners are removed. | ||
`useDragging` makes the implementation of the described common pattern simpler because it handles the addition and removal of global events. | ||
|
||
## Input Object Properties | ||
|
||
### `onDragStart` | ||
|
||
- Type: `Function` | ||
|
||
The hook calls `onDragStart` when the dragging starts. The function receives as parameters the same parameters passed to `startDrag` whose documentation is available below. | ||
If `startDrag` is passed directly as an `onMouseDown` event handler, `onDragStart` will receive the `onMouseDown` event. | ||
|
||
### `onDragMove` | ||
|
||
- Type: `Function` | ||
|
||
The hook calls `onDragMove ` after the dragging starts and when a mouse movement happens. | ||
It receives the `mousemove` event. | ||
|
||
### `onDragEnd` | ||
|
||
- Type: `Function` | ||
|
||
The hook calls `onDragEnd` when the dragging ends. When dragging is explicitly stopped, the function receives as parameters, the same parameters passed to `endDrag` whose documentation is available below. | ||
When dragging stops because the user releases the mouse, the function receives the `mouseup` event. | ||
|
||
## Return Object Properties | ||
|
||
### `startDrag` | ||
|
||
- Type: `Function` | ||
|
||
A function that, when called, starts the dragging behavior. Parameters passed to this function will be passed to `onDragStart` when the dragging starts. | ||
It is possible to directly pass `startDrag` as the `onMouseDown` event handler of some element. | ||
|
||
### `endDrag` | ||
|
||
- Type: `Function` | ||
|
||
A function that, when called, stops the dragging behavior. Parameters passed to this function will be passed to `onDragEnd` when the dragging ends. | ||
In most cases, there is no need to call this function directly. Dragging behavior automatically stops when the mouse is released. | ||
|
||
### `isDragging` | ||
|
||
- Type: `Boolean` | ||
|
||
A boolean value, when true it means dragging is currently taking place; when false, it means dragging is not taking place. | ||
|
||
## Usage | ||
The following example allows us to drag & drop a red square around the entire viewport. | ||
|
||
```jsx | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useState, useCallback } from '@wordpress/element'; | ||
import { __experimentalUseDragging as useDragging } from '@wordpress/compose'; | ||
|
||
|
||
const UseDraggingExample = () => { | ||
const [ position, setPosition ] = useState( null ); | ||
const changePosition = useCallback( | ||
( event ) => { | ||
setPosition( { x: event.clientX, y: event.clientY } ); | ||
} | ||
); | ||
const { startDrag } = useDragging( { | ||
onDragMove: changePosition, | ||
} ); | ||
return ( | ||
// eslint-disable-next-line jsx-a11y/no-static-element-interactions | ||
<div | ||
onMouseDown={ startDrag } | ||
style={ { | ||
position: 'fixed', | ||
width: 10, | ||
height: 10, | ||
backgroundColor: 'red', | ||
...( position ? { top: position.y, left: position.x } : {} ), | ||
} } | ||
/> | ||
); | ||
}; | ||
``` |
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,74 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
useCallback, | ||
useEffect, | ||
useLayoutEffect, | ||
useRef, | ||
useState, | ||
} from '@wordpress/element'; | ||
|
||
const useIsomorphicLayoutEffect = | ||
typeof window !== 'undefined' ? useLayoutEffect : useEffect; | ||
|
||
export default function useDragging( { onDragStart, onDragMove, onDragEnd } ) { | ||
const [ isDragging, setIsDragging ] = useState( false ); | ||
|
||
const eventsRef = useRef( { | ||
onDragStart, | ||
onDragMove, | ||
onDragEnd, | ||
} ); | ||
useIsomorphicLayoutEffect( | ||
() => { | ||
eventsRef.current.onDragStart = onDragStart; | ||
eventsRef.current.onDragMove = onDragMove; | ||
eventsRef.current.onDragEnd = onDragEnd; | ||
}, | ||
[ onDragStart, onDragMove, onDragEnd ] | ||
); | ||
|
||
const onMouseMove = useCallback( | ||
( ...args ) => ( eventsRef.current.onDragMove && eventsRef.current.onDragMove( ...args ) ), | ||
[] | ||
); | ||
const endDrag = useCallback( | ||
( ...args ) => { | ||
if ( eventsRef.current.onDragEnd ) { | ||
eventsRef.current.onDragEnd( ...args ); | ||
} | ||
document.removeEventListener( 'mousemove', onMouseMove ); | ||
document.removeEventListener( 'mouseup', endDrag ); | ||
setIsDragging( false ); | ||
}, | ||
[] | ||
); | ||
const startDrag = useCallback( | ||
( ...args ) => { | ||
if ( eventsRef.current.onDragStart ) { | ||
eventsRef.current.onDragStart( ...args ); | ||
} | ||
document.addEventListener( 'mousemove', onMouseMove ); | ||
document.addEventListener( 'mouseup', endDrag ); | ||
setIsDragging( true ); | ||
}, | ||
[] | ||
); | ||
|
||
// Remove the global events when unmounting if needed. | ||
useEffect( () => { | ||
return () => { | ||
if ( isDragging ) { | ||
document.removeEventListener( 'mousemove', onMouseMove ); | ||
document.removeEventListener( 'mouseup', endDrag ); | ||
} | ||
}; | ||
}, [ isDragging ] ); | ||
|
||
return { | ||
startDrag, | ||
endDrag, | ||
isDragging, | ||
}; | ||
} |
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
Oops, something went wrong.