UNPKG

@gravityforms/components

Version:

UI components for use in Gravity Forms development. Both React and vanilla js flavors.

167 lines (156 loc) 5.09 kB
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;