@gravityforms/components
Version:
UI components for use in Gravity Forms development. Both React and vanilla js flavors.
167 lines (156 loc) • 5.09 kB
JavaScript
import { React, PropTypes, classnames } from '@gravityforms/libraries';
import { useIdContext, useStoreContext } from '@gravityforms/react-utils';
import {
NEEDS_I18N_LABEL,
getId,
getComponent,
} from './utils';
const { forwardRef } = React;
/**
* @module DropdownTrigger
* @description The trigger for the dropdown.
*
* @since 4.5.0
*
* @param {object} props Component props.
* @param {boolean} props.disabled Whether the dropdown is disabled.
* @param {Function} props.handleBlur The blur event handler.
* @param {Function} props.handleEscKeyDown The escape keydown event handler.
* @param {Function} props.handleKeyDownCapture The keydown capture event handler.
* @param {Function} props.handleTriggerKeyDown The trigger keydown event handler.
* @param {object} props.i18n The i18n object.
* @param {string} props.label The label for the dropdown.
* @param {boolean} props.multi Whether the dropdown is multi-select.
* @param {Function} props.open The open function.
* @param {Function} props.resetAndClose The reset and close function.
* @param {object} props.triggerAttributes Custom attributes for the trigger.
* @param {string|Array|object} props.triggerClasses Custom classes for the trigger.
* @param {object} ref Ref to the component.
*
* @return {JSX.Element} The trigger component.
*/
const DropdownTrigger = forwardRef( ( {
disabled = false,
handleBlur = () => {},
handleEscKeyDown = () => {},
handleKeyDownCapture = () => {},
handleTriggerKeyDown = () => {},
i18n = {},
label = '',
multi = false,
open = () => {},
resetAndClose = () => {},
triggerAttributes = {},
triggerClasses = [],
}, ref ) => {
const id = useIdContext();
const dropdownOpen = useStoreContext( ( state ) => state.open );
const selectedItem = useStoreContext( ( state ) => state.selectedItem );
const triggerHeight = useStoreContext( ( state ) => state.triggerHeight );
const popoverId = getId( id, 'popover' );
const labelId = getId( id, 'label' );
const pillsId = getId( id, 'pills' );
const triggerProps = {
className: classnames( [
'gform-dropdown__trigger',
'gform-text',
'gform-text--color-port',
'gform-typography--size-text-sm',
'gform-typography--weight-regular',
], triggerClasses ),
...triggerAttributes,
'aria-autocomplete': 'none',
'aria-controls': popoverId,
'aria-expanded': dropdownOpen ? 'true' : 'false',
'aria-haspopup': 'listbox',
disabled,
onBlur: handleBlur,
onClick: ( event ) => {
const clickHandler = dropdownOpen ? resetAndClose : open;
clickHandler( event );
},
onKeyDown: ( event ) => {
handleEscKeyDown( event );
handleTriggerKeyDown( event );
},
onKeyDownCapture: ( event ) => handleKeyDownCapture( event ),
role: 'combobox',
type: 'button',
};
if ( label ) {
triggerProps[ 'aria-labelledby' ] = labelId;
}
if ( multi ) {
triggerProps[ 'aria-describedby' ] = pillsId;
}
if ( triggerHeight ) {
triggerProps.style = {
height: `${ triggerHeight }px`,
};
}
/**
* @function getSingleTriggerLabel
* @description Get the label for the single dropdown trigger.
*
* @since 4.5.0
*
* @return {JSX.Element} The label for the single dropdown trigger.
*/
const getSingleTriggerLabel = () => (
<>
{ selectedItem.beforeLabel && (
<span className="gform-dropdown__trigger-before-label">
{ getComponent( selectedItem.beforeLabel ) }
</span>
) }
<span className="gform-dropdown__trigger-label">{ selectedItem.label }</span>
{ selectedItem.afterLabel && (
<span className="gform-dropdown__trigger-after-label">
{ getComponent( selectedItem.afterLabel ) }
</span>
) }
</>
);
/**
* @function getMultiTriggerLabel
* @description Get the label for the multi dropdown trigger.
*
* @since 4.5.0
*
* @return {string|JSX.Element} The label for the multi dropdown trigger.
*/
const getMultiTriggerLabel = () => {
if ( selectedItem.length ) {
return (
<span className="gform-visually-hidden">
{ selectedItem.map( ( item ) => item.label ).join( ', ' ) }
</span>
);
}
return i18n.multiTriggerLabel || NEEDS_I18N_LABEL;
};
return (
<button { ...triggerProps } ref={ ref }>
{ multi ? getMultiTriggerLabel() : getSingleTriggerLabel() }
</button>
);
} );
DropdownTrigger.propTypes = {
disabled: PropTypes.bool,
handleBlur: PropTypes.func,
handleEscKeyDown: PropTypes.func,
handleKeyDownCapture: PropTypes.func,
handleTriggerKeyDown: PropTypes.func,
i18n: PropTypes.object,
label: PropTypes.string,
multi: PropTypes.bool,
open: PropTypes.func,
resetAndClose: PropTypes.func,
triggerAttributes: PropTypes.object,
triggerClasses: PropTypes.oneOfType( [
PropTypes.string,
PropTypes.array,
PropTypes.object,
] ),
};
export default DropdownTrigger;