Skip to content

Commit

Permalink
[WALL] Lubega / WALL-3544 / Wallets carousel vertical and horizontal …
Browse files Browse the repository at this point in the history
…animation (deriv-com#14080)

* feat: wallets carousel vertical and horizontal animation

* fix: applied comments

* fix: applied comments

* fix: applied comments

* fix: failed component test

* fix: applied comments

* fix: applied comments

* fix: applied comments
  • Loading branch information
lubega-deriv authored Mar 12, 2024
1 parent c9390eb commit 4262722
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ test.describe('Wallets - Mobile carousel', () => {

expect(progressBarItemClass2).toContain('wallets-progress-bar-active');

// timeout to wait for previous swiping animation
await mobilePage.waitForTimeout(1000);

await swipeLeft(mobilePage);

const activeProgressBarItem3 = mobilePage.locator('.wallets-progress-bar div:nth-child(3)');
Expand Down
50 changes: 28 additions & 22 deletions packages/wallets/src/components/WalletCard/WalletCard.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
@import '../../components/SkeletonLoader/SkeletonLoader.scss';

.wallets-card {
display: flex;
flex-direction: column;
align-items: center;
&__carousel-content {
background-color: transparent;
margin: 0 -0.8rem;

&:first-child {
margin-left: 0;
}

&-details {
padding: 1.6rem;
width: 28.8rem;
height: 17.6rem;

&-top {
justify-content: flex-start;
width: unset;
}
}
}

&__container {
display: flex;
flex-direction: column;
align-items: center;
}

&__balance-loader {
padding: 0.7rem;
Expand All @@ -21,37 +43,21 @@
align-items: flex-start;
aspect-ratio: 1.667;

&__carousel-content {
padding: 1.6rem;
width: 24rem;
height: 14.6rem;

&--active {
width: 28.8rem;
height: 17.6rem;
}
}

&__top {
&-top {
display: flex;
flex-direction: row;
width: 100%;
justify-content: space-between;

&__carousel-content {
justify-content: flex-start;
width: unset;
}
}

&__bottom {
&-bottom {
display: flex;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
}

&-landing_company {
&-landing-company {
display: flex;
justify-content: flex-end;
align-items: flex-start;
Expand Down
91 changes: 45 additions & 46 deletions packages/wallets/src/components/WalletCard/WalletCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type TProps = {
balance: string;
currency: string;
iconSize?: React.ComponentProps<typeof WalletCardIcon>['size'];
isActive?: boolean;
isCarouselContent?: boolean;
isDemo?: boolean;
landingCompanyName?: string;
Expand All @@ -21,64 +20,64 @@ const WalletCard: React.FC<TProps> = ({
balance,
currency,
iconSize = 'lg',
isActive = false,
isCarouselContent = false,
isDemo,
landingCompanyName,
}) => {
const { isLoading } = useBalance();

return (
<div className='wallets-card'>
<WalletGradientBackground
currency={isDemo ? 'Demo' : currency}
device='mobile'
hasShine
isDemo={isDemo}
type='card'
>
<div
className={classNames('wallets-card__details', {
'wallets-card__details__carousel-content': isCarouselContent,
'wallets-card__details__carousel-content--active': isCarouselContent && isActive,
})}
data-testid='dt_wallet_card_details'
<div className={classNames('wallets-card', { 'wallets-card__carousel-content': isCarouselContent })}>
<div className='wallets-card__container'>
<WalletGradientBackground
currency={isDemo ? 'Demo' : currency}
device='mobile'
hasShine
isDemo={isDemo}
type='card'
>
<div
className={classNames('wallets-card__details__top', {
'wallets-card__details__top__carousel-content': isCarouselContent,
className={classNames('wallets-card__details', {
'wallets-card__carousel-content-details': isCarouselContent,
})}
data-testid='dt_wallet_card_details'
>
<WalletCardIcon size={iconSize} type={isDemo ? 'Demo' : currency} />
{!isCarouselContent && (
<div className='wallets-card__details-landing_company'>
{landingCompanyName && (
<WalletListCardBadge isDemo={isDemo} label={landingCompanyName} />
)}
</div>
)}
</div>
<div className='wallets-card__details__bottom'>
<WalletText color={isDemo ? 'white' : 'general'} size={isCarouselContent ? 'md' : '2xs'}>
{currency} Wallet
</WalletText>
{isLoading ? (
<div
className='wallets-skeleton wallets-card__balance-loader'
data-testid='dt_wallet_card_balance_loader'
/>
) : (
<WalletText
color={isDemo ? 'white' : 'general'}
size={isCarouselContent ? 'xl' : 'sm'}
weight='bold'
>
{balance}
<div
className={classNames('wallets-card__details-top', {
'wallets-card__carousel-content-details-top': isCarouselContent,
})}
>
<WalletCardIcon size={iconSize} type={isDemo ? 'Demo' : currency} />
{!isCarouselContent && (
<div className='wallets-card__details-landing-company'>
{landingCompanyName && (
<WalletListCardBadge isDemo={isDemo} label={landingCompanyName} />
)}
</div>
)}
</div>
<div className='wallets-card__details-bottom'>
<WalletText color={isDemo ? 'white' : 'general'} size={isCarouselContent ? 'md' : '2xs'}>
{currency} Wallet
</WalletText>
)}
{isLoading ? (
<div
className='wallets-skeleton wallets-card__balance-loader'
data-testid='dt_wallet_card_balance_loader'
/>
) : (
<WalletText
color={isDemo ? 'white' : 'general'}
size={isCarouselContent ? 'xl' : 'sm'}
weight='bold'
>
{balance}
</WalletText>
)}
</div>
</div>
</div>
</WalletGradientBackground>
</WalletGradientBackground>
</div>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ describe('WalletCard', () => {
mockProps = {
balance: '100 BTC',
currency: 'BTC',
isActive: true,
isCarouselContent: true,
landingCompanyName: 'Deriv',
};
Expand All @@ -82,7 +81,7 @@ describe('WalletCard', () => {
const gradient = screen.getByTestId('dt_wallet_gradient_background');
expect(gradient).toHaveClass('wallets-gradient--BTC-mobile-card-light');
const details = screen.getByTestId('dt_wallet_card_details');
expect(details).toHaveClass('wallets-card__details__carousel-content--active');
expect(details).toHaveClass('wallets-card__details wallets-card__carousel-content-details');
});

it('should render the correct wallet card and gradient background for demo wallet', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.wallets-carousel {
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,59 @@
import React, { useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useEventListener } from 'usehooks-ts';
import { useActiveWalletAccount } from '@deriv/api-v2';
import { AccountsList } from '../AccountsList';
import { WalletsCarouselContent } from '../WalletsCarouselContent';
import { WalletsCarouselHeader } from '../WalletsCarouselHeader';
import './WalletsCarousel.scss';

const WalletsCarousel: React.FC = () => {
const [isWalletSettled, setIsWalletSettled] = useState(true);
const [showWalletsCarouselHeader, setShowWalletsCarouselHeader] = useState(false);
const [heightFromTop, setHeightFromTop] = useState(0);
const { data: activeWallet, isLoading: isActiveWalletLoading } = useActiveWalletAccount();

const containerRef = useRef<HTMLDivElement>(null);

// function to handle scrolling event for hiding/displaying WalletsCarouselHeader
// walletsCarouselHeader will be displayed when height from top of screen is more than 100px
const handleScroll = useCallback(() => {
if (containerRef.current) {
const newHeightFromTop = containerRef.current.getBoundingClientRect().top;
setHeightFromTop(newHeightFromTop);
heightFromTop && setShowWalletsCarouselHeader(heightFromTop < -100);
}
}, [heightFromTop]);

//this handle scroll function listens to the scroll as well as touchmove events to handle drag scrolling on mobile
useEventListener('touchmove', handleScroll, containerRef);
useEventListener('scroll', handleScroll, containerRef);

useEffect(() => {
let isMounted = true;

if (isMounted) {
handleScroll();
}

return () => {
isMounted = false;
};
}, [handleScroll, heightFromTop]);

return (
<React.Fragment>
{!isActiveWalletLoading && (
<WalletsCarouselHeader
balance={activeWallet?.display_balance}
currency={activeWallet?.currency || 'USD'}
hidden={!showWalletsCarouselHeader}
isDemo={activeWallet?.is_virtual}
/>
)}
<WalletsCarouselContent onWalletSettled={setIsWalletSettled} />
<AccountsList isWalletSettled={isWalletSettled} />
<div className='wallets-carousel' ref={containerRef}>
<WalletsCarouselContent onWalletSettled={setIsWalletSettled} />
<AccountsList isWalletSettled={isWalletSettled} />
</div>
</React.Fragment>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
width: 100vw;
padding: 2rem;
overflow: hidden;
gap: 1.6rem;

&__container {
height: 17.6rem;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 1.6rem;

& > .wallets-card__details {
width: 45vw;
Expand Down
Loading

0 comments on commit 4262722

Please sign in to comment.