Skip to content

Commit

Permalink
refactor: convert widget into compound components
Browse files Browse the repository at this point in the history
  • Loading branch information
tigranpetrossian committed Nov 18, 2024
1 parent 088249e commit 4d77d8c
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 97 deletions.
84 changes: 47 additions & 37 deletions apps/mobile/src/components/widgets/accounts/accounts-widget.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useRef } from 'react';
import { ScrollView } from 'react-native-gesture-handler';

import { AddWalletSheet } from '@/components/add-wallet/';
import { AccountSelectorSheet } from '@/features/account-selector-sheet';
Expand All @@ -7,69 +8,78 @@ import { AppRoutes } from '@/routes';
import { useAccounts } from '@/store/accounts/accounts.read';
import { useWallets } from '@/store/wallets/wallets.read';
import { t } from '@lingui/macro';
import { useTheme } from '@shopify/restyle';
import { useRouter } from 'expo-router';

import { Box, SheetRef } from '@leather.io/ui/native';
import { Box, SheetRef, Theme } from '@leather.io/ui/native';

import { Balance } from '../../balance/balance';
import { Widget, WidgetHeader } from '../components/widget';
import { Widget } from '../components/widget';
import { AccountCard } from './components/cards/account-card';
import { AddAccountCard } from './components/cards/add-account-card';
import { CreateWalletCard } from './components/cards/create-wallet-card';
import { AddAccountSheet } from './sheets/add-account-sheet';

export function AccountsWidget() {
const sheetRef = useRef<SheetRef>(null);
const accountSelectorSheetRef = useRef<SheetRef>(null);
const addAccountSheetRef = useRef<SheetRef>(null);
const addWalletSheetRef = useRef<SheetRef>(null);
const router = useRouter();
const wallets = useWallets();
const accounts = useAccounts();
const theme = useTheme<Theme>();

const { totalBalance } = useTotalBalance();

return (
<>
<Widget
scrollDirection="horizontal"
header={
<Box marginHorizontal="5">
<WidgetHeader
title={t({
id: 'accounts.header_title',
message: 'My accounts',
})}
sheetRef={sheetRef}
sheet={<AccountSelectorSheet sheetRef={sheetRef} />}
/>
{wallets.hasWallets && <Balance balance={totalBalance} variant="heading03" />}
</Box>
}
>
{accounts.list.map(account => (
<AccountCard
account={account}
key={account.id}
onPress={() => {
router.navigate({
pathname: AppRoutes.Account,
params: {
accountId: account.id,
},
});
<Widget>
<Box>
<Widget.Header onPress={() => accountSelectorSheetRef.current?.present()}>
<Widget.Title title={t({ id: 'accounts.header_title', message: 'My accounts' })} />
</Widget.Header>
{wallets.hasWallets && (
<Box px="5">
<Balance balance={totalBalance} variant="heading03" />
</Box>
)}
</Box>
<Widget.Body>
<ScrollView
horizontal
showsHorizontalScrollIndicator
contentContainerStyle={{
gap: theme.spacing['3'],
paddingHorizontal: theme.spacing['5'],
}}
/>
))}
>
{accounts.list.map(account => (
<AccountCard
account={account}
key={account.id}
onPress={() => {
router.navigate({
pathname: AppRoutes.Account,
params: {
accountId: account.id,
},
});
}}
/>
))}

{accounts.hasAccounts ? (
<AddAccountCard onPress={() => addAccountSheetRef.current?.present()} />
) : (
<CreateWalletCard onPress={() => addWalletSheetRef.current?.present()} />
)}
{accounts.hasAccounts ? (
<AddAccountCard onPress={() => addAccountSheetRef.current?.present()} />
) : (
<CreateWalletCard onPress={() => addWalletSheetRef.current?.present()} />
)}
</ScrollView>
</Widget.Body>
</Widget>

<AddAccountSheet addAccountSheetRef={addAccountSheetRef} />
<AddWalletSheet addWalletSheetRef={addWalletSheetRef} />
<AccountSelectorSheet sheetRef={accountSelectorSheetRef} />
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
import React from 'react';
import { ScrollView } from 'react-native-gesture-handler';

import { t } from '@lingui/macro';
import { useTheme } from '@shopify/restyle';

import { Money } from '@leather.io/models';
import { CollectibleCard, CollectibleCardProps } from '@leather.io/ui/native';
import { CollectibleCard, CollectibleCardProps, Theme } from '@leather.io/ui/native';

import { Widget, WidgetHeader } from '../components/widget';
import { Widget } from '../components/widget';

interface CollectiblesWidgetProps {
collectibles: CollectibleCardProps[];
totalBalance: Money;
}

export function CollectiblesWidget({ collectibles, totalBalance }: CollectiblesWidgetProps) {
const theme = useTheme<Theme>();

return (
<Widget
header={
<WidgetHeader
<Widget>
<Widget.Header>
<Widget.Title
title={t({
id: 'collectibles.header_title',
message: 'My collectibles',
})}
totalBalance={totalBalance}
/>
}
scrollDirection="horizontal"
>
{collectibles.map((collectible: CollectibleCardProps, index) => (
<CollectibleCard key={index} {...collectible} />
))}
</Widget.Header>
<Widget.Body>
<ScrollView
horizontal
showsHorizontalScrollIndicator
contentContainerStyle={{
gap: theme.spacing['3'],
paddingHorizontal: theme.spacing['5'],
}}
>
{collectibles.map((collectible: CollectibleCardProps, index) => (
<CollectibleCard key={index} {...collectible} />
))}
</ScrollView>
</Widget.Body>
</Widget>
);
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
import { Money } from '@leather.io/models';
import { Box, SheetRef, TouchableOpacity } from '@leather.io/ui/native';
import { ReactNode } from 'react';

import { WidgetTitle } from './widget-title';
import { Box, TouchableOpacity } from '@leather.io/ui/native';

interface WidgetHeaderProps {
title: string;
sheetRef?: React.RefObject<SheetRef>;
sheet?: React.ReactNode;
totalBalance?: Money;
children: ReactNode;
onPress?(): void;
}

export function WidgetHeader({ title, totalBalance, sheetRef, sheet }: WidgetHeaderProps) {
if (sheet && sheetRef) {
export function WidgetHeader({ children, onPress }: WidgetHeaderProps) {
if (onPress) {
return (
<>
<TouchableOpacity
onPress={() => sheetRef.current?.present()}
flexDirection="row"
gap="1"
alignItems="center"
>
<WidgetTitle title={title} totalBalance={totalBalance} />
</TouchableOpacity>

{sheet}
</>
<TouchableOpacity onPress={onPress}>
<Box flexDirection="row" gap="1" alignItems="center" px="5">
{children}
</Box>
</TouchableOpacity>
);
}

return (
<Box flexDirection="row" gap="1" alignItems="center" marginHorizontal="5">
<WidgetTitle title={title} totalBalance={totalBalance} />
<Box flexDirection="row" gap="1" alignItems="center" px="5">
{children}
</Box>
);
}
30 changes: 9 additions & 21 deletions apps/mobile/src/components/widgets/components/widget/widget.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
import { ScrollView } from 'react-native-gesture-handler';
import { HasChildren } from '@/utils/types';

import { useTheme } from '@shopify/restyle';
import { Box } from '@leather.io/ui/native';

import { Box, Theme } from '@leather.io/ui/native';
import { WidgetHeader } from './widget-header';
import { WidgetTitle } from './widget-title';

interface WidgetProps {
children: React.ReactNode;
header?: React.ReactNode;
scrollDirection?: 'vertical' | 'horizontal';
}

export function Widget({ children, header, scrollDirection = 'vertical' }: WidgetProps) {
const theme = useTheme<Theme>();
export function Widget({ children }: HasChildren) {
return (
<Box paddingVertical="5" flexDirection="column" gap="3">
<Box>{header}</Box>
<ScrollView
horizontal={scrollDirection === 'horizontal'}
showsHorizontalScrollIndicator={scrollDirection === 'horizontal' ? false : undefined}
contentContainerStyle={{ gap: theme.spacing['3'], paddingHorizontal: theme.spacing['5'] }}
>
{children}
</ScrollView>
{children}
</Box>
);
}

// refactor to remove Pressable , fix balance display(reverse for Fiat) + line break
// check if I broke add account
Widget.Header = WidgetHeader;
Widget.Title = WidgetTitle;
Widget.Body = Box;
11 changes: 6 additions & 5 deletions apps/mobile/src/components/widgets/tokens/tokens-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import { AccountId } from '@/models/domain.model';
import { HasChildren } from '@/utils/types';
import { t } from '@lingui/macro';

import { Widget, WidgetHeader } from '../components/widget';
import { Widget } from '../components/widget';

export function TokensWidget({ children }: HasChildren) {
return (
<Widget
header={<WidgetHeader title={t({ id: 'tokens.header_title', message: 'My tokens' })} />}
>
{children}
<Widget>
<Widget.Header>
<Widget.Title title={t({ id: 'tokens.header_title', message: 'My tokens' })} />
</Widget.Header>
<Widget.Body>{children}</Widget.Body>
</Widget>
);
}
Expand Down

0 comments on commit 4d77d8c

Please sign in to comment.