/** * WordPress dependencies */ import { useSelect, useDispatch } from '@safe-wordpress/data'; import { createInterpolateElement, useEffect, useState, } from '@safe-wordpress/element'; import { Button, Dashicon } from '@safe-wordpress/components'; import { _x, sprintf } from '@safe-wordpress/i18n'; /** * External dependencies */ import { difference } from 'lodash'; import { AnimatedList } from '@nab/components'; import { createAlternative } from '@nab/utils'; import type { AlternativeId } from '@nab/types'; /** * Internal dependencies */ import './style.scss'; import { AiAlternativeAttributesModal } from '../ai-alternative-attributes-modal'; import { AlternativeContainer } from './alternative-container'; import { AlternativePreviewer } from '../alternative-previewer'; import { useCanAddAlternatives } from '../hooks'; import { store as NAB_EDITOR } from '../../store'; export const AlternativeSection = (): JSX.Element => { const [ control, ...alternativeIds ] = useAlternativeIds(); const addAlternative = useAddAlternative(); const isTestedElementInvalid = useIsTestedElementInvalid(); const isReplacingAlternatives = useIsReplacingAlternatives(); const canAddAlternatives = useCanAddAlternatives(); return (

{ createInterpolateElement( sprintf( /* translators: %s: Dashicon. */ _x( '%s Control Version and Variants', 'text', 'nelio-ab-testing' ), '' ), { icon: ( ), } ) }

{ !! control && ( ) } { alternativeIds.map( ( alternativeId, index ) => ( ) ) }
{ canAddAlternatives && ( ) }
); }; // ===== // HOOKS // ===== const useAlternativeIds = () => useSelect( ( select ) => select( NAB_EDITOR ).getAlternativeIds(), [] ); const useAddAlternative = () => { const { addAlternatives } = useDispatch( NAB_EDITOR ); return () => addAlternatives( createAlternative() ); }; const useIsTestedElementInvalid = () => useSelect( ( select ) => select( NAB_EDITOR ).isTestedElementInvalid(), [] ); const useIsReplacingAlternatives = () => { const altIds = useAlternativeIds(); const [ prevAltIds, setPrevAltIds ] = useState< ReadonlyArray< AlternativeId > >( altIds ); // Keep track of the previous alt IDs. useEffect( () => { if ( altIds !== prevAltIds ) { setPrevAltIds( altIds ); } }, [ altIds, prevAltIds ] ); // Disable animations if several changes at once. if ( altIds === prevAltIds ) { return false; } // This works under the assumption that, usually, there’s only one change // at a time (i.e. adding or removing a single alternative). const d1 = difference( altIds, prevAltIds ); const d2 = difference( prevAltIds, altIds ); return !! d1.length && !! d2.length; };