Skip to content

Commit

Permalink
feat: add carousel for trade type selection modal
Browse files Browse the repository at this point in the history
  • Loading branch information
kate-deriv committed Nov 13, 2024
1 parent d4166f9 commit 84d8660
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 180 deletions.
37 changes: 23 additions & 14 deletions packages/trader/src/AppV2/Components/Carousel/carousel-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@ import React from 'react';
import { ActionSheet } from '@deriv-com/quill-ui';
import { LabelPairedArrowLeftMdRegularIcon, LabelPairedCircleInfoMdRegularIcon } from '@deriv/quill-icons';

export type TQuillIcon = typeof LabelPairedArrowLeftMdRegularIcon;
type TCarouselHeaderProps = {
current_index: number;
onNextClick: () => void;
onPrevClick: () => void;
previous_icon?: TQuillIcon;
next_icon?: TQuillIcon;
title?: React.ReactNode;
};

const CarouselHeader = ({ current_index, onNextClick, onPrevClick, title }: TCarouselHeaderProps) => (
<ActionSheet.Header
className='carousel-controls'
title={title}
icon={
current_index ? (
<LabelPairedArrowLeftMdRegularIcon onClick={onPrevClick} />
) : (
<LabelPairedCircleInfoMdRegularIcon onClick={onNextClick} />
)
}
iconPosition={current_index ? 'left' : 'right'}
/>
);
const CarouselHeader = ({
current_index,
onNextClick,
onPrevClick,
previous_icon,
next_icon,
title,
}: TCarouselHeaderProps) => {
const NextIcon = next_icon ?? LabelPairedCircleInfoMdRegularIcon;
const PreviousIcon = previous_icon ?? LabelPairedArrowLeftMdRegularIcon;

return (
<ActionSheet.Header
className='carousel-controls'
title={title}
icon={current_index ? <PreviousIcon onClick={onPrevClick} /> : <NextIcon onClick={onNextClick} />}
iconPosition={current_index ? 'left' : 'right'}
/>
);
};

export default CarouselHeader;
8 changes: 7 additions & 1 deletion packages/trader/src/AppV2/Components/Carousel/carousel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import CarouselHeader from './carousel-header';
import CarouselHeader, { TQuillIcon } from './carousel-header';
import { useSwipeable } from 'react-swipeable';
import clsx from 'clsx';

Expand All @@ -11,6 +11,8 @@ type TCarousel = {
is_infinite_loop?: boolean;
pages: { id: number; component: JSX.Element }[];
title?: React.ReactNode;
previous_icon?: TQuillIcon;
next_icon?: TQuillIcon;
setCurrentIndex?: (arg: number) => void;
};

Expand All @@ -23,6 +25,8 @@ const Carousel = ({
pages,
setCurrentIndex,
title,
previous_icon,
next_icon,
}: TCarousel) => {
const [internalIndex, setInternalIndex] = React.useState(0);

Expand Down Expand Up @@ -55,6 +59,8 @@ const Carousel = ({
current_index={index}
onNextClick={handleNextClick}
onPrevClick={handlePrevClick}
previous_icon={previous_icon}
next_icon={next_icon}
title={title}
/>
)}
Expand Down
102 changes: 60 additions & 42 deletions packages/trader/src/AppV2/Components/Guide/guide-description-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import clsx from 'clsx';
import { ActionSheet, Heading, Chip, Text } from '@deriv-com/quill-ui';
import { VideoPlayer } from '@deriv/components';
import { Localize } from '@deriv/translations';
Expand All @@ -16,6 +17,7 @@ type TGuideDescriptionModal = {
onTermClick: (term: string) => void;
selected_contract_type: string;
show_guide_for_selected_contract?: boolean;
show_description_in_a_modal?: boolean;
};

const GuideDescriptionModal = ({
Expand All @@ -27,6 +29,7 @@ const GuideDescriptionModal = ({
onTermClick,
selected_contract_type,
show_guide_for_selected_contract,
show_description_in_a_modal = true,
}: TGuideDescriptionModal) => {
const [is_video_player_opened, setIsVideoPlayerOpened] = React.useState(false);
const modal_ref = React.useRef<HTMLDialogElement>(null);
Expand All @@ -36,55 +39,70 @@ const GuideDescriptionModal = ({
const toggleVideoPlayer = (e?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => {
clickAndKeyEventHandler(() => setIsVideoPlayerOpened(!is_video_player_opened), e);
};
// TODO: move outside
const GuideContent = (
<React.Fragment>
{!show_guide_for_selected_contract && (
<div className='guide__menu'>
{contract_list.map(({ tradeType, id }: { tradeType: React.ReactNode; id: string }) => (
<Chip.Selectable
key={id}
onChipSelect={() => onChipSelect(id)}
selected={id === selected_contract_type}
>
<Text size='sm'>{tradeType}</Text>
</Chip.Selectable>
))}
</div>
)}
<div
className={clsx('guide__contract-description', {
'guide__contract-description--without-btn': !show_description_in_a_modal,
})}
key={selected_contract_type}
>
<TradeDescription contract_type={selected_contract_type} onTermClick={onTermClick} />
<VideoPreview
contract_type={selected_contract_type}
toggleVideoPlayer={toggleVideoPlayer}
video_src={video_src}
/>
</div>
</React.Fragment>
);

React.useEffect(() => {
if (modal_ref.current) is_video_player_opened ? modal_ref.current.showModal() : modal_ref.current.close();
}, [is_video_player_opened]);

return (
<React.Fragment>
<ActionSheet.Root isOpen={is_open} onClose={onClose} position='left' expandable={false}>
<ActionSheet.Portal shouldCloseOnDrag>
<ActionSheet.Content className='guide__wrapper--content'>
<Heading.H4 className='guide__title'>
{show_guide_for_selected_contract ? (
selected_contract_type
) : (
<Localize i18n_default_text='Trade types' />
)}
</Heading.H4>
{!show_guide_for_selected_contract && (
<div className='guide__menu'>
{contract_list.map(({ tradeType, id }: { tradeType: React.ReactNode; id: string }) => (
<Chip.Selectable
key={id}
onChipSelect={() => onChipSelect(id)}
selected={id === selected_contract_type}
>
<Text size='sm'>{tradeType}</Text>
</Chip.Selectable>
))}
</div>
)}
<div className='guide__contract-description' key={selected_contract_type}>
<TradeDescription contract_type={selected_contract_type} onTermClick={onTermClick} />
<VideoPreview
contract_type={selected_contract_type}
toggleVideoPlayer={toggleVideoPlayer}
video_src={video_src}
/>
</div>
</ActionSheet.Content>
<ActionSheet.Footer
alignment='vertical'
primaryAction={{
content: <Localize i18n_default_text='Got it' />,
onAction: onClose,
}}
className='guide__button'
/>
</ActionSheet.Portal>
</ActionSheet.Root>
{show_description_in_a_modal ? (
<ActionSheet.Root isOpen={is_open} onClose={onClose} position='left' expandable={false}>
<ActionSheet.Portal shouldCloseOnDrag>
<ActionSheet.Content className='guide__wrapper__content'>
<Heading.H4 className='guide__title'>
{show_guide_for_selected_contract ? (
selected_contract_type
) : (
<Localize i18n_default_text='Trade types' />
)}
</Heading.H4>
{GuideContent}
</ActionSheet.Content>
<ActionSheet.Footer
alignment='vertical'
primaryAction={{
content: <Localize i18n_default_text='Got it' />,
onAction: onClose,
}}
className='guide__button'
/>
</ActionSheet.Portal>
</ActionSheet.Root>
) : (
<div className='guide__wrapper__content--separate'>{GuideContent}</div>
)}
{is_video_player_opened && (
<dialog
ref={modal_ref}
Expand Down
11 changes: 10 additions & 1 deletion packages/trader/src/AppV2/Components/Guide/guide.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@
}

&__wrapper {
&--content {
&__content {
padding: var(--component-actionSheet-spacing-padding-lg) var(--component-actionSheet-spacing-padding-lg) 0;
overflow-x: hidden;

&--separate {
padding: 0 var(--component-actionSheet-spacing-padding-lg) 0;
overflow-x: hidden;
}
}
}

Expand All @@ -41,6 +46,10 @@
&::-webkit-scrollbar {
display: none;
}

&--without-btn {
height: calc(90dvh - 17rem);
}
}

&__button {
Expand Down
Loading

0 comments on commit 84d8660

Please sign in to comment.