| 1 |
/** |
| 2 |
* WordPress dependencies |
| 3 |
*/ |
| 4 |
import { |
| 5 |
__experimentalInputControlSuffixWrapper as InputControlSuffixWrapper, |
| 6 |
__experimentalNumberControl as NumberControl, |
| 7 |
RangeControl, |
| 8 |
} from '@wordpress/components'; |
| 9 |
import { useInstanceId } from '@wordpress/compose'; |
| 10 |
|
| 11 |
/** |
| 12 |
* Defines the props structure for InputRange. |
| 13 |
* |
| 14 |
* @since 3.14.0 |
| 15 |
*/ |
| 16 |
type InputRangeProps = { |
| 17 |
value: number; |
| 18 |
onChange: ( value: number | undefined ) => void; |
| 19 |
max: number; |
| 20 |
min: number; |
| 21 |
suffix: string; |
| 22 |
label: string; |
| 23 |
initialPosition: number; |
| 24 |
disabled: boolean; |
| 25 |
className?: string; |
| 26 |
size?: 'small' | 'default' | 'compact' | '__unstable-large', |
| 27 |
}; |
| 28 |
|
| 29 |
/** |
| 30 |
* Component that renders a hybrid input range control. |
| 31 |
* On one side you have the number control and on the other side the range control. |
| 32 |
* |
| 33 |
* @since 3.14.0 |
| 34 |
* |
| 35 |
* @param {InputRangeProps} props The component's props. |
| 36 |
*/ |
| 37 |
export const InputRange = ( { |
| 38 |
value, |
| 39 |
onChange, |
| 40 |
max, |
| 41 |
min, |
| 42 |
suffix, |
| 43 |
size, |
| 44 |
label, |
| 45 |
initialPosition, |
| 46 |
disabled, |
| 47 |
className, |
| 48 |
}: Readonly<InputRangeProps> ): React.JSX.Element => { |
| 49 |
const numberControlId = `parsely-inputrange-control-${ useInstanceId( InputRange ) }`; |
| 50 |
|
| 51 |
return ( |
| 52 |
<div className={ `parsely-inputrange-control ${ className ? className : '' }` }> |
| 53 |
<label htmlFor={ numberControlId } className={ 'wp-parsely-editor-sidebar-label' }> |
| 54 |
{ label } |
| 55 |
</label> |
| 56 |
<div className={ 'parsely-inputrange-control__controls' }> |
| 57 |
<NumberControl |
| 58 |
id={ numberControlId } |
| 59 |
disabled={ disabled } |
| 60 |
value={ value } |
| 61 |
suffix={ <InputControlSuffixWrapper>{ suffix }</InputControlSuffixWrapper> } |
| 62 |
size={ size ?? '__unstable-large' } |
| 63 |
min={ min } |
| 64 |
max={ max } |
| 65 |
onChange={ ( newValue ) => { |
| 66 |
const numericValue = parseInt( newValue as string, 10 ); |
| 67 |
if ( isNaN( numericValue ) ) { |
| 68 |
return; |
| 69 |
} |
| 70 |
onChange( numericValue ); |
| 71 |
} } |
| 72 |
/> |
| 73 |
<RangeControl |
| 74 |
disabled={ disabled } |
| 75 |
value={ value } |
| 76 |
showTooltip={ false } |
| 77 |
initialPosition={ initialPosition } |
| 78 |
onChange={ ( newValue ) => { |
| 79 |
onChange( newValue ); |
| 80 |
} } |
| 81 |
withInputField={ false } |
| 82 |
min={ min } |
| 83 |
max={ max } |
| 84 |
/> |
| 85 |
</div> |
| 86 |
</div> |
| 87 |
); |
| 88 |
}; |
| 89 |
|