@gravityforms/components
Version:
UI components for use in Gravity Forms development. Both React and vanilla js flavors.
151 lines (143 loc) • 3.61 kB
JavaScript
/**
* @function useDropdownControl
* @description Adds the control handlers to props.
*
* @since 4.5.0
*
* @param {object} props The props to add handlers to.
* @param {Function} useStore The useStore hook.
*
* @return {object} The modified props.
*/
const useDropdownControl = ( props = {}, useStore = () => {} ) => {
const {
multi = false,
onClose = () => {},
onAfterClose = () => {},
onOpen = () => {},
onAfterOpen = () => {},
} = props;
const listItems = useStore( ( state ) => state.listItems );
const selectedItem = useStore( ( state ) => state.selectedItem );
const setActiveItem = useStore( ( state ) => state.setActiveItem );
const setSelectedItem = useStore( ( state ) => state.setSelectedItem );
const setSearchValue = useStore( ( state ) => state.setSearchValue );
const setOpen = useStore( ( state ) => state.setOpen );
const setHide = useStore( ( state ) => state.setHide );
const setReveal = useStore( ( state ) => state.setReveal );
const triggerRef = useStore( ( state ) => state.triggerRef );
/**
* @function close
* @description Closes the dropdown.
*
* @since 4.5.0
*
* @param {Event} event The event object.
*/
const close = ( event ) => {
onClose?.( event );
setOpen( false );
setHide( true );
setTimeout( () => {
setHide( false );
setSearchValue( '' );
onAfterClose?.( event );
}, 150 );
};
/**
* @function open
* @description Opens the dropdown.
*
* @since 4.5.0
*
* @param {Event} event The event object.
*/
const open = ( event ) => {
onOpen?.( event );
setReveal( true );
requestAnimationFrame( () => {
setOpen( true );
setTimeout( () => {
setReveal( false );
onAfterOpen?.( event );
}, 150 );
} );
};
/**
* @function resetAndClose
* @description Resets and closes the dropdown.
*
* @since 4.5.0
*
* @param {Event} event The event object.
*/
const resetAndClose = ( event ) => {
setTimeout( () => {
if ( multi ) {
setActiveItem( listItems.items[ 0 ] );
} else {
setActiveItem( selectedItem );
}
}, 150 );
close( event );
};
/**
* @function selectItem
* @description Selects an item in the list.
*
* @since 4.5.0
*
* @param {object} item The item to select.
*
* @return {Function} The event handler.
*/
const selectItem = ( item ) => ( event ) => {
if ( multi ) {
const selected = selectedItem.some( ( selItem ) => selItem.value === item.value );
// Handle multi case.
if ( selected ) {
// If already selected, remove it.
setSelectedItem( selectedItem.filter( ( selItem ) => selItem.value !== item.value ) );
} else {
// Otherwise add it to the selected items.
setSelectedItem( [ ...selectedItem, item ] );
}
return;
}
// Not multi, set selected item.
setSelectedItem( item );
requestAnimationFrame( () => {
close( event );
triggerRef?.current?.focus();
} );
};
/**
* @function selectMultipleItems
* @description Selects multiple items.
*
* @since 4.5.0
*
* @param {Array} items The items to select.
*/
const selectMultipleItems = ( items = [] ) => {
const newSelectedItems = items.reduce( ( carry, item ) => {
// Check if item is already selected.
if ( selectedItem.some( ( selItem ) => selItem.value === item.value ) ) {
return carry;
}
// Add item to selected items.
carry.push( item );
return carry;
}, [ ...selectedItem ] );
setSelectedItem( newSelectedItems );
};
return {
...props,
close,
open,
resetAndClose,
selectItem,
selectMultipleItems,
};
};
export default useDropdownControl;