-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CustomGradientPicker: Update Type and Angle controls (#23802)
* Refactor AnglePickerControl styles * Update SelectControl. Integrate new SelectControl with AnglePickerControl in GradientPicker * Improve Gradient Select and radio control UI * Update snapshots * Update snapshot * Update snapshot * Add label for gradient picker type * Fixed sizing. * Improve focus. * Harmonize spacing. * Fix so swatches align with the gradient control below. Co-authored-by: jasmussen <[email protected]>
- Loading branch information
Showing
23 changed files
with
666 additions
and
411 deletions.
There are no files selected for viewing
8 changes: 4 additions & 4 deletions
8
packages/block-editor/src/components/colors-gradients/style.scss
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
2 changes: 1 addition & 1 deletion
2
...ges/block-editor/src/components/responsive-block-control/test/__snapshots__/index.js.snap
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 |
---|---|---|
@@ -1,3 +1,3 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Basic rendering should render with required props 1`] = `"<fieldset class=\\"block-editor-responsive-block-control\\"><legend class=\\"block-editor-responsive-block-control__title\\">Padding</legend><div class=\\"block-editor-responsive-block-control__inner\\"><div class=\\"components-base-control components-toggle-control block-editor-responsive-block-control__toggle\\"><div class=\\"components-base-control__field\\"><span class=\\"components-form-toggle is-checked\\"><input class=\\"components-form-toggle__input\\" id=\\"inspector-toggle-control-0\\" type=\\"checkbox\\" aria-describedby=\\"inspector-toggle-control-0__help\\" checked=\\"\\"><span class=\\"components-form-toggle__track\\"></span><span class=\\"components-form-toggle__thumb\\"></span></span><label for=\\"inspector-toggle-control-0\\" class=\\"components-toggle-control__label\\">Use the same padding on all screensizes.</label></div><p id=\\"inspector-toggle-control-0__help\\" class=\\"components-base-control__help\\">Toggle between using the same value for all screen sizes or using a unique value per screen size.</p></div><div class=\\"block-editor-responsive-block-control__group\\"><div class=\\"components-base-control\\"><div class=\\"components-base-control__field\\"><label class=\\"components-base-control__label\\" for=\\"inspector-select-control-0\\"><span aria-describedby=\\"rbc-desc-0\\">All</span><span class=\\"components-visually-hidden\\" id=\\"rbc-desc-0\\">Controls the padding property for All viewports.</span></label><select id=\\"inspector-select-control-0\\" class=\\"components-select-control__input\\"><option value=\\"\\">Please select</option><option value=\\"small\\">Small</option><option value=\\"medium\\">Medium</option><option value=\\"large\\">Large</option></select></div></div><p id=\\"all\\">All is used here for testing purposes to ensure we have access to details about the device.</p></div></div></fieldset>"`; | ||
exports[`Basic rendering should render with required props 1`] = `"<fieldset class=\\"block-editor-responsive-block-control\\"><legend class=\\"block-editor-responsive-block-control__title\\">Padding</legend><div class=\\"block-editor-responsive-block-control__inner\\"><div class=\\"components-base-control components-toggle-control block-editor-responsive-block-control__toggle\\"><div class=\\"components-base-control__field\\"><span class=\\"components-form-toggle is-checked\\"><input class=\\"components-form-toggle__input\\" id=\\"inspector-toggle-control-0\\" type=\\"checkbox\\" aria-describedby=\\"inspector-toggle-control-0__help\\" checked=\\"\\"><span class=\\"components-form-toggle__track\\"></span><span class=\\"components-form-toggle__thumb\\"></span></span><label for=\\"inspector-toggle-control-0\\" class=\\"components-toggle-control__label\\">Use the same padding on all screensizes.</label></div><p id=\\"inspector-toggle-control-0__help\\" class=\\"components-base-control__help\\">Toggle between using the same value for all screen sizes or using a unique value per screen size.</p></div><div class=\\"block-editor-responsive-block-control__group\\"><div class=\\"components-base-control\\"><div class=\\"components-base-control__field\\"><div class=\\"components-flex components-select-control e1cr7zh10 css-sbt0p2-Flex-Root eboqfv50\\"><div class=\\"components-flex__item e1cr7zh14 css-d373l0-Item-LabelWrapper eboqfv51\\"><label for=\\"inspector-select-control-0\\" class=\\"components-input-control__label css-7tv4lf-Text-BaseLabel e1cr7zh13\\"><span aria-describedby=\\"rbc-desc-0\\">All</span><span class=\\"components-visually-hidden\\" id=\\"rbc-desc-0\\">Controls the padding property for All viewports.</span></label></div><div class=\\"components-input-control__container css-99mm9s-Container e1cr7zh11\\"><select class=\\"components-select-control__input css-hwcz8s-Select e12x0a390\\" id=\\"inspector-select-control-0\\"><option value=\\"\\">Please select</option><option value=\\"small\\">Small</option><option value=\\"medium\\">Medium</option><option value=\\"large\\">Large</option></select><span class=\\"components-input-control__suffix css-1lym30p-Suffix e1cr7zh19\\"><div class=\\"css-s55r1c-DownArrowWrapper e12x0a391\\"><svg viewBox=\\"0 0 24 24\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"18\\" height=\\"18\\" role=\\"img\\" aria-hidden=\\"true\\" focusable=\\"false\\"><path d=\\"M17 9.4L12 14 7 9.4l-1 1.2 6 5.4 6-5.4z\\"></path></svg></div></span><fieldset aria-hidden=\\"true\\" class=\\"components-input-control__backdrop css-15qcvxb-Fieldset e1cr7zh15\\"></fieldset></div></div></div></div><p id=\\"all\\">All is used here for testing purposes to ensure we have access to details about the device.</p></div></div></fieldset>"`; |
93 changes: 93 additions & 0 deletions
93
packages/components/src/angle-picker-control/angle-circle.js
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,93 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useEffect, useRef } from '@wordpress/element'; | ||
import { __experimentalUseDragging as useDragging } from '@wordpress/compose'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
CircleRoot, | ||
CircleIndicatorWrapper, | ||
CircleIndicator, | ||
} from './styles/angle-picker-control-styles'; | ||
|
||
function AngleCircle( { value, onChange, ...props } ) { | ||
const angleCircleRef = useRef(); | ||
const angleCircleCenter = useRef(); | ||
const previousCursorValue = 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; | ||
// Prevent (drag) mouse events from selecting and accidentally | ||
// triggering actions from other elements. | ||
event.preventDefault(); | ||
|
||
onChange( getAngle( centerX, centerY, event.clientX, event.clientY ) ); | ||
}; | ||
|
||
const { startDrag, isDragging } = useDragging( { | ||
onDragStart: ( event ) => { | ||
setAngleCircleCenter(); | ||
changeAngleToPosition( event ); | ||
}, | ||
onDragMove: changeAngleToPosition, | ||
onDragEnd: changeAngleToPosition, | ||
} ); | ||
|
||
useEffect( () => { | ||
if ( isDragging ) { | ||
if ( previousCursorValue.current === undefined ) { | ||
previousCursorValue.current = document.body.style.cursor; | ||
} | ||
document.body.style.cursor = 'grabbing'; | ||
} else { | ||
document.body.style.cursor = previousCursorValue.current || null; | ||
previousCursorValue.current = undefined; | ||
} | ||
}, [ isDragging ] ); | ||
|
||
return ( | ||
/* eslint-disable jsx-a11y/no-static-element-interactions */ | ||
<CircleRoot | ||
ref={ angleCircleRef } | ||
onMouseDown={ startDrag } | ||
className="components-angle-picker-control__angle-circle" | ||
style={ isDragging ? { cursor: 'grabbing' } : undefined } | ||
{ ...props } | ||
> | ||
<CircleIndicatorWrapper | ||
style={ | ||
value ? { transform: `rotate(${ value }deg)` } : undefined | ||
} | ||
className="components-angle-picker-control__angle-circle-indicator-wrapper" | ||
> | ||
<CircleIndicator className="components-angle-picker-control__angle-circle-indicator" /> | ||
</CircleIndicatorWrapper> | ||
</CircleRoot> | ||
/* eslint-enable jsx-a11y/no-static-element-interactions */ | ||
); | ||
} | ||
|
||
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; | ||
} | ||
|
||
export default AngleCircle; |
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 |
---|---|---|
@@ -1,116 +1,74 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import classnames from 'classnames'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useRef } from '@wordpress/element'; | ||
import { | ||
useInstanceId, | ||
__experimentalUseDragging as useDragging, | ||
} from '@wordpress/compose'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { useInstanceId } from '@wordpress/compose'; | ||
|
||
/** | ||
* 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; | ||
// Prevent (drag) mouse events from selecting and accidentally | ||
// triggering actions from other elements. | ||
event.preventDefault(); | ||
|
||
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-control__angle-circle" | ||
style={ isDragging ? { cursor: 'grabbing' } : undefined } | ||
{ ...props } | ||
> | ||
<div | ||
style={ | ||
value ? { transform: `rotate(${ value }deg)` } : undefined | ||
} | ||
className="components-angle-picker-control__angle-circle-indicator-wrapper" | ||
> | ||
<span className="components-angle-picker-control__angle-circle-indicator" /> | ||
</div> | ||
</div> | ||
/* eslint-enable jsx-a11y/no-static-element-interactions */ | ||
); | ||
}; | ||
import { FlexBlock } from '../flex'; | ||
import NumberControl from '../number-control'; | ||
import AngleCircle from './angle-circle'; | ||
import { | ||
Root, | ||
NumberControlWrapper, | ||
} from './styles/angle-picker-control-styles'; | ||
|
||
export default function AnglePickerControl( { | ||
className, | ||
id: idProp, | ||
value, | ||
onChange, | ||
label = __( 'Angle' ), | ||
label, | ||
...props | ||
} ) { | ||
const instanceId = useInstanceId( AnglePickerControl ); | ||
const inputId = `components-angle-picker-control__input-${ instanceId }`; | ||
const instanceId = useInstanceId( | ||
AnglePickerControl, | ||
'components-angle-picker-control__input' | ||
); | ||
const id = idProp || instanceId; | ||
|
||
const handleOnNumberChange = ( unprocessedValue ) => { | ||
const inputValue = | ||
unprocessedValue !== '' ? parseInt( unprocessedValue, 10 ) : 0; | ||
onChange( inputValue ); | ||
}; | ||
|
||
const classes = classnames( 'components-angle-picker-control', className ); | ||
|
||
return ( | ||
<BaseControl | ||
className={ classes } | ||
id={ id } | ||
label={ label } | ||
id={ inputId } | ||
className="components-angle-picker-control" | ||
{ ...props } | ||
> | ||
<AngleCircle | ||
value={ value } | ||
onChange={ onChange } | ||
aria-hidden="true" | ||
/> | ||
<input | ||
className="components-angle-picker-control__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" | ||
/> | ||
<Root gap={ 3 }> | ||
<NumberControlWrapper> | ||
<NumberControl | ||
className="components-angle-picker-control__input-field" | ||
id={ id } | ||
max={ 360 } | ||
min={ 0 } | ||
onChange={ handleOnNumberChange } | ||
step="1" | ||
value={ value } | ||
/> | ||
</NumberControlWrapper> | ||
<FlexBlock> | ||
<AngleCircle | ||
aria-hidden="true" | ||
value={ value } | ||
onChange={ onChange } | ||
/> | ||
</FlexBlock> | ||
</Root> | ||
</BaseControl> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.