UNPKG

@gravityforms/components

Version:

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

47 lines (35 loc) 1.61 kB
import { React } from '@gravityforms/libraries'; import { sprintf } from '@gravityforms/utils'; const { useState, useCallback } = React; const deepClone = ( obj ) => JSON.parse( JSON.stringify( obj ) ); const resolvePath = ( path, base = window ) => { return path.split( '.' ).reduce( ( acc, part ) => acc && acc[ part ], base ); }; const useRepeaterState = ( initialStateOrPath, syncWithWindow = false, titleKey = '', repeaterType = 'inline', titlePrefix = '' ) => { const isPath = typeof initialStateOrPath === 'string'; const initialState = isPath ? deepClone( resolvePath( initialStateOrPath ) || [] ) : deepClone( initialStateOrPath ); const [ items, setItems ] = useState( initialState ); const updateExternalState = ( updatedItems ) => { if ( isPath && syncWithWindow ) { const target = resolvePath( initialStateOrPath ); if ( target ) { target.length = 0; target.push( ...updatedItems ); } } }; const handleChange = useCallback( ( updatedItems ) => { setItems( updatedItems ); updateExternalState( updatedItems ); }, [ isPath, initialStateOrPath, syncWithWindow ] ); const onChange = useCallback( ( key, index ) => ( value ) => { const updatedItems = [ ...items ]; updatedItems[ index ][ key ] = value; if ( titleKey && repeaterType === 'block' && key === titleKey ) { updatedItems[ index ].repeater_item_block_content_title = titlePrefix ? sprintf( titlePrefix, value ) : value; } handleChange( updatedItems ); }, [ items, handleChange, repeaterType, titleKey ] ); return { items, handleChange, onChange }; }; export default useRepeaterState;