UNPKG

@gravityforms/components

Version:

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

151 lines (143 loc) 3.61 kB
/** * @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;