@gravityforms/components
Version:
UI components for use in Gravity Forms development. Both React and vanilla js flavors.
108 lines (97 loc) • 3.15 kB
JavaScript
import { React, PropTypes, classnames } from '@gravityforms/libraries';
import { useIdContext, useStoreContext } from '@gravityforms/react-utils';
import {
getId,
getSearchItem,
} from './utils';
import Input from '../../elements/Input';
const { forwardRef } = React;
/**
* @module DropdownSearch
* @description The search component for the dropdown.
*
* @since 4.5.0
*
* @param {object} props The component props.
* @param {boolean} props.ajaxSearch Whether to use ajax search for the dropdown.
* @param {boolean} props.hasSearch Whether the dropdown has a search component.
* @param {Function} props.onSearch Callback for when the search value changes.
* @param {object} props.searchAttributes The search component attributes.
* @param {string|Array|object} props.searchClasses The search component classes.
* @param {object} ref The ref object.
*
* @return {JSX.Element} The dropdown search component.
*/
const DropdownSearch = forwardRef( ( {
ajaxSearch = false,
hasSearch = false,
onSearch = () => {},
searchAttributes = {},
searchClasses = [],
}, ref ) => {
const id = useIdContext();
const dropdownOpen = useStoreContext( ( state ) => state.dropdownOpen );
const activeItem = useStoreContext( ( state ) => state.activeItem );
const searchValue = useStoreContext( ( state ) => state.searchValue );
const setActiveItem = useStoreContext( ( state ) => state.setActiveItem );
const setSearchValue = useStoreContext( ( state ) => state.setSearchValue );
if ( ! hasSearch ) {
return null;
}
const listId = getId( id, 'list' );
const searchId = getId( id, 'search' );
const {
customAttributes: searchCustomAttributes = {},
wrapperClasses: searchWrapperClasses = [],
...restSearchAttributes
} = searchAttributes;
const searchProps = {
customClasses: classnames( [
'gform-dropdown__search',
], searchClasses ),
...restSearchAttributes,
controlled: true,
customAttributes: {
...searchCustomAttributes,
autoComplete: 'off',
role: 'combobox',
'aria-autocomplete': 'list',
'aria-haspopup': 'listbox',
'aria-controls': listId,
'aria-expanded': dropdownOpen ? 'true' : 'false',
onMouseMove: () => {
setActiveItem( getSearchItem( id ) );
},
ref,
},
id: searchId,
wrapperClasses: classnames( [
'gform-dropdown__search-wrapper',
], searchWrapperClasses ),
onChange: ( value ) => {
setSearchValue( value );
if ( ajaxSearch ) {
onSearch?.( value );
}
},
value: searchValue,
};
if ( activeItem.type === 'search' ) {
searchProps.customAttributes[ 'data-active-item' ] = 'true';
} else {
searchProps.customAttributes[ 'aria-activedescendant' ] = activeItem.id;
}
return <Input { ...searchProps } />;
} );
DropdownSearch.propTypes = {
ajaxSearch: PropTypes.bool,
hasSearch: PropTypes.bool,
onSearch: PropTypes.func,
searchAttributes: PropTypes.object,
searchClasses: PropTypes.oneOfType( [
PropTypes.array,
PropTypes.object,
PropTypes.string,
] ),
};
export default DropdownSearch;