import React, { useMemo, useState } from 'react'; import { observer } from 'mobx-react-lite'; import { FiltersMap } from '@wix/bex-core'; import { Box, Loader, Text, TextButton } from '@wix/design-system'; import { PickerListItemProps } from '../PickerListItemProps'; import { PickerContentBaseWrapped, PickerContentBaseWrappedProps, } from './PickerContentBaseWrapped'; import { AdditionalStepState, PickerContentState } from '../../state'; import { ChevronLeft } from '@wix/wix-ui-icons-common'; import { st, classes } from './PickerContentAdditionalStep.st.css.js'; export interface PickerContentAdditionalStepProps extends Partial { /** When true, the picker will start directly on the additional step, skipping the first selection step. The back button will also be hidden. */ autoAdditionalStepOnInitialSelect?: boolean; /** The additional step title */ additionalStepTitle?: string; /** The additional step subtitle */ additionalStepSubtitle?: string; /** Defines a function that returns a component to render in the additional step content area, if `hasAdditionalStep` returns `false` this prop is ignored. */ renderAdditionalStepContent?: (props: { item: T }) => JSX.Element; /** Indicates if selected item has additional step or not */ hasAdditionalStep?: (props: { item: T }) => boolean; /** Defines a callback function just before primaryButtonOnClick callback, returned value will be added as `additionalStepData` in onSelect payload */ onBeforeSelectAdditionalStep?: () => Promise; /** Defines a callback function after user clicks on the continue button to additional step content */ continueButtonOnClick?: (props: { item: T }) => void; /** Defines a callback function after user clicks on the back button in the additional step content */ backButtonOnClick?: (props: { item: T }) => void; /** Additional steps modal content overrides */ additionalStepOverrides?: { extraNode?: React.ReactNode; extraText?: string; subtitle?: string; image?: React.ReactNode; enablePrimaryButton?: boolean; }; } interface PickerContentAdditionalStepStateProps { pickerContentState: PickerContentState; renderItem: (item: T, index: number) => Partial; onBackButtonClick: () => void; } export type PickerContentAdditionalStepFullProps< T, F extends FiltersMap = FiltersMap, > = PickerContentAdditionalStepProps & PickerContentAdditionalStepStateProps; const AdditionalStepContentRenderer = ({ renderAdditionalStepContent, item, }: { renderAdditionalStepContent?: (props: { item: T }) => JSX.Element; item: T; }) => renderAdditionalStepContent?.({ item }) ?? null; function _PickerContentAdditionalStep( props: PickerContentAdditionalStepFullProps, ) { const { pickerContentState, renderItem, renderAdditionalStepContent, additionalStepTitle, additionalStepSubtitle, primaryButtonOnClick, secondaryButtonOnClick, onCloseButtonClick, onBeforeSelectAdditionalStep, onBackButtonClick, additionalStepOverrides = {}, primaryButtonText, autoAdditionalStepOnInitialSelect, height, // extract from rest to disable overrides ...rest } = props; const [state] = useState( () => (pickerContentState.additionalStep = new AdditionalStepState({ collection: pickerContentState.picker.collection, })), ); const selectedKeyedItem = state.selectedKeyedItem; const renderedItemProps = useMemo(() => { if (!selectedKeyedItem) { return { title: '', subtitle: '', }; } const { item, index } = selectedKeyedItem; const renderProps = renderItem(item, index); return { title: state.collection.itemName(item), ...renderProps, }; }, [selectedKeyedItem]); const { collection: { translate: t }, } = state; const suffixNode = useMemo(() => { return [ additionalStepOverrides.extraNode, additionalStepOverrides.extraText, renderedItemProps.extraNode, renderedItemProps.extraText, ].find((node) => node !== undefined); }, [ renderedItemProps, additionalStepOverrides.extraNode, additionalStepOverrides.extraText, ]); renderedItemProps.image = additionalStepOverrides?.image || renderedItemProps.image; renderedItemProps.subtitle = additionalStepOverrides?.subtitle || renderedItemProps.subtitle; const enablePrimaryButton = additionalStepOverrides?.enablePrimaryButton || false; return ( { state.isLoading = true; if (onBeforeSelectAdditionalStep) { try { state.isLoading = true; state.additionalData = await onBeforeSelectAdditionalStep?.(); primaryButtonOnClick?.(); } catch (err) { console.error(err); state.isLoading = false; } } else { primaryButtonOnClick?.(); } }} secondaryButtonOnClick={secondaryButtonOnClick} onCloseButtonClick={onCloseButtonClick} title={additionalStepTitle} subtitle={additionalStepSubtitle} primaryButtonText={ state.isLoading ? : primaryButtonText } secondaryButtonText={t('cairo.cancel.button')} primaryButtonProps={{ disabled: state.isLoading || !enablePrimaryButton, }} sideActions={ autoAdditionalStepOnInitialSelect ? undefined : ( } dataHook="back-button" onClick={() => onBackButtonClick()} > {t('cairo.pickerModal.back.button')} ) } > {renderedItemProps.image}
{renderedItemProps.title} {renderedItemProps.subtitle}
{suffixNode !== undefined && (
{typeof suffixNode === 'string' ? ( {suffixNode} ) : ( {suffixNode} )}
)}
{selectedKeyedItem && ( )}
); } export const PickerContentAdditionalStep = observer( _PickerContentAdditionalStep, );