/**
* 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;
};