From ed2b4d6bc682962bd24e2fc1a64d28d133f13290 Mon Sep 17 00:00:00 2001 From: Stanley Yuen <102275989+stanleyyconsensys@users.noreply.github.com> Date: Tue, 25 Feb 2025 20:49:43 +0800 Subject: [PATCH] feat: add account drawer UI for account switch (#516) * chore: fix ui redux state over subscribe * fix: lint * feat: add account drawer modal * feat: add account drawer modal * chore: refinement * chore: refine sidebar * fix: undefined account chain id from ui * chore: remove account switch pull down * chore: refine * chore: lint * chore: rename file * chore: update path * chore: remove space * chore: disable click for selected account * chore: fix account click event * chore: add missing redux state separation * chore: add no hidden account text * chore(wallet-ui): update flex style --------- Co-authored-by: khanti42 --- packages/wallet-ui/src/assets/locales/en.json | 12 +- packages/wallet-ui/src/assets/locales/fr.json | 12 +- .../ui/atom/Scrollable/Scrollable.style.ts | 5 + .../ui/atom/Scrollable/Scrollable.view.tsx | 25 +++ .../components/ui/atom/Scrollable/index.ts | 1 + .../AccountDrawer/AccountDrawer.style.ts | 26 +++ .../AccountDrawer/AccountDrawer.view.tsx | 42 +++++ .../ui/organism/AccountDrawer/index.ts | 1 + .../AccountListModal/AccountItem.style.ts | 31 ++++ .../AccountListModal/AccountItem.view.tsx | 69 ++++++++ .../AccountListModal/AccountList.style.ts | 59 +++++++ .../AccountListModal/AccountList.view.tsx | 155 ++++++++++++++++++ .../ui/organism/AccountListModal/index.ts | 1 + .../AccountSwitchModal.stories.tsx | 33 ---- .../AccountSwitchModal.style.ts | 61 ------- .../AccountSwitchModal.view.tsx | 135 --------------- .../AccountsHeader/AccountsHeader.stories.tsx | 26 --- .../AccountsHeader/AccountsHeader.view.tsx | 49 ------ .../AccountsHeader/index.ts | 1 - .../HiddenAccountsList.story.tsx | 24 --- .../HiddenAccountsList.view.tsx | 48 ------ .../HiddenAccountsList/index.ts | 1 - .../VisibleAccountsList.story.tsx | 26 --- .../VisibleAccountsList.view.tsx | 81 --------- .../VisibleAccountsList/index.ts | 1 - .../ui/organism/AccountSwitchModal/index.ts | 1 - .../AddAccountModal/AddAccountModal.style.ts | 17 +- .../AddAccountModal/AddAccountModal.view.tsx | 29 ++-- .../AddAccountModal/index.ts | 0 .../ui/organism/SideBar/SideBar.view.tsx | 30 ++-- packages/wallet-ui/src/hooks/index.ts | 4 + .../wallet-ui/src/hooks/useCurrentAccount.ts | 12 ++ .../wallet-ui/src/hooks/useCurrentNetwork.ts | 13 ++ packages/wallet-ui/src/hooks/useScrollTo.ts | 36 ++++ packages/wallet-ui/src/utils/utils.ts | 12 +- 35 files changed, 545 insertions(+), 534 deletions(-) create mode 100644 packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.style.ts create mode 100644 packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.view.tsx create mode 100644 packages/wallet-ui/src/components/ui/atom/Scrollable/index.ts create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.style.ts create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.view.tsx create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountDrawer/index.ts create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.style.ts create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.view.tsx create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.style.ts create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.view.tsx create mode 100644 packages/wallet-ui/src/components/ui/organism/AccountListModal/index.ts delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.stories.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.style.ts delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.view.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.stories.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.view.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/index.ts delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.story.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.view.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/index.ts delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.story.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.view.tsx delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/index.ts delete mode 100644 packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/index.ts rename packages/wallet-ui/src/components/ui/organism/{AccountSwitchModal => }/AddAccountModal/AddAccountModal.style.ts (76%) rename packages/wallet-ui/src/components/ui/organism/{AccountSwitchModal => }/AddAccountModal/AddAccountModal.view.tsx (81%) rename packages/wallet-ui/src/components/ui/organism/{AccountSwitchModal => }/AddAccountModal/index.ts (100%) create mode 100644 packages/wallet-ui/src/hooks/index.ts create mode 100644 packages/wallet-ui/src/hooks/useCurrentAccount.ts create mode 100644 packages/wallet-ui/src/hooks/useCurrentNetwork.ts create mode 100644 packages/wallet-ui/src/hooks/useScrollTo.ts diff --git a/packages/wallet-ui/src/assets/locales/en.json b/packages/wallet-ui/src/assets/locales/en.json index c5c078bb..03ec6402 100644 --- a/packages/wallet-ui/src/assets/locales/en.json +++ b/packages/wallet-ui/src/assets/locales/en.json @@ -10,9 +10,6 @@ "accountName": { "message": "Account name" }, - "accounts": { - "message": "Accounts" - }, "accountDeployedSuccessfully": { "message": "Account deployed successfully." }, @@ -148,6 +145,9 @@ "gotIt": { "message": "GOT IT!" }, + "hiddenAccounts": { + "message": "Hidden accounts" + }, "inputAmountExceedsBalance": { "message": "Input amount exceeds user balance" }, @@ -214,6 +214,9 @@ "nonZeroBalanceOnCairo0": { "message": "You have a non-zero balance on a Cairo 0 non-deployed address" }, + "noHiddenAccount": { + "message": "No hidden accounts" + }, "openBetaVersion": { "message": "This is the Open Beta version of the dapp, updates are made regularly" }, @@ -244,6 +247,9 @@ "selectTokenForTransactionFees": { "message": "Select Token for Transaction Fees" }, + "selectAnAccount": { + "message": "Select an account" + }, "send": { "message": "Send" }, diff --git a/packages/wallet-ui/src/assets/locales/fr.json b/packages/wallet-ui/src/assets/locales/fr.json index b88ef335..970cdbdd 100644 --- a/packages/wallet-ui/src/assets/locales/fr.json +++ b/packages/wallet-ui/src/assets/locales/fr.json @@ -10,9 +10,6 @@ "accountName": { "message": "Nom du compte" }, - "accounts": { - "message": "Comptes" - }, "accountDeployedSuccessfully": { "message": "Compte déployé avec succès." }, @@ -142,6 +139,9 @@ "gotIt": { "message": "COMPRIS !" }, + "hiddenAccounts": { + "message": "Comptes cachés" + }, "inputAmountExceedsBalance": { "message": "Le montant entré dépasse le solde de l'utilisateur" }, @@ -208,6 +208,9 @@ "nonZeroBalanceOnCairo0": { "message": "Vous avez un solde non nul sur une adresse Cairo 0 non déployée" }, + "noHiddenAccount": { + "message": "Pas de comptes cachés" + }, "openBetaVersion": { "message": "Il s'agit de la version Open Beta de la dApp, des mises à jour sont effectuées régulièrement" }, @@ -238,6 +241,9 @@ "selectTokenForTransactionFees": { "message": "Sélectionner un jeton pour les frais de transaction" }, + "selectAnAccount": { + "message": "Sélectionnez un compte" + }, "send": { "message": "Envoie" }, diff --git a/packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.style.ts b/packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.style.ts new file mode 100644 index 00000000..52464752 --- /dev/null +++ b/packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.style.ts @@ -0,0 +1,5 @@ +import styled from 'styled-components'; + +export const ScrollableWrapper = styled.div` + overflow-y: scroll; +`; diff --git a/packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.view.tsx b/packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.view.tsx new file mode 100644 index 00000000..c81d5c33 --- /dev/null +++ b/packages/wallet-ui/src/components/ui/atom/Scrollable/Scrollable.view.tsx @@ -0,0 +1,25 @@ +import { useScrollTo } from 'hooks'; +import { RefObject } from 'react'; + +import { ScrollableWrapper } from './Scrollable.style'; + +export interface Props { + height: number; + child: (scrollTo: RefObject) => React.ReactNode; +} + +export const ScrollableView = ({ + child, + height, +}: Props) => { + const { scrollTo } = useScrollTo(); + return ( + + {child(scrollTo)} + + ); +}; diff --git a/packages/wallet-ui/src/components/ui/atom/Scrollable/index.ts b/packages/wallet-ui/src/components/ui/atom/Scrollable/index.ts new file mode 100644 index 00000000..32285cb2 --- /dev/null +++ b/packages/wallet-ui/src/components/ui/atom/Scrollable/index.ts @@ -0,0 +1 @@ +export { ScrollableView as Scrollable } from './Scrollable.view'; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.style.ts b/packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.style.ts new file mode 100644 index 00000000..1011edfa --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.style.ts @@ -0,0 +1,26 @@ +import { Button } from 'components/ui/atom/Button'; +import styled from 'styled-components'; + +export const Drawer = styled(Button).attrs((props) => ({ + fontSize: props.theme.typography.c1.fontSize, + upperCaseOnly: false, + textStyle: { + fontWeight: props.theme.typography.p1.fontWeight, + fontFamily: props.theme.typography.p1.fontFamily, + }, + iconStyle: { + fontSize: props.theme.typography.i1.fontSize, + color: props.theme.palette.grey.grey1, + }, +}))` + padding: ${(props) => props.theme.spacing.tiny2}; + height: ${(props) => props.theme.spacing.base}; + color: ${(props) => props.theme.palette.grey.black}; + border-radius: ${(props) => props.theme.corner.medium}; + border: 1px solid ${(props) => props.theme.palette.grey.grey3}; + + :hover { + background-color: ${(props) => props.theme.palette.grey.grey4}; + border: none; + } +`; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.view.tsx b/packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.view.tsx new file mode 100644 index 00000000..9a574629 --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountDrawer/AccountDrawer.view.tsx @@ -0,0 +1,42 @@ +import { useState } from 'react'; + +import { PopIn } from 'components/ui/molecule/PopIn'; +import { formatAddress } from 'utils/utils'; +import { useCurrentAccount } from 'hooks'; +import { AccountListModal } from '../AccountListModal'; +import { AddAccountModal } from '../AddAccountModal'; +import { Drawer } from './AccountDrawer.style'; + +export interface Props { + starkName?: string; +} + +export const AccountDrawerView = ({ starkName }: Props) => { + const [accountListModalOpen, setAccountListModalOpen] = useState(false); + const [accountAddModalOpen, setAccountAddModalOpen] = useState(false); + const { address } = useCurrentAccount(); + + return ( + <> + + setAccountListModalOpen(false)} + onAddAccountClick={() => { + setAccountListModalOpen(false); + setAccountAddModalOpen(true); + }} + /> + + + setAccountAddModalOpen(false)} /> + + setAccountListModalOpen(true)} + > + {formatAddress(address, starkName)} + + + ); +}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountDrawer/index.ts b/packages/wallet-ui/src/components/ui/organism/AccountDrawer/index.ts new file mode 100644 index 00000000..d6be4665 --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountDrawer/index.ts @@ -0,0 +1 @@ +export { AccountDrawerView as AccountDrawer } from './AccountDrawer.view'; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.style.ts b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.style.ts new file mode 100644 index 00000000..e2b850ee --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.style.ts @@ -0,0 +1,31 @@ +import styled from 'styled-components'; +import { AccountImage } from 'components/ui/atom/AccountImage'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +export const Wrapper = styled.div<{ selected: boolean; visible: boolean }>` + display: flex; + align-items: center; + justify-content: space-between; + opacity: ${(props) => (props.visible ? 1 : 0.5)}; + background-color: ${(props) => + props.selected ? props.theme.palette.grey.grey4 : 'transparent'}; + border-left: ${(props) => + props.selected + ? `${props.theme.spacing.tiny} solid ${props.theme.palette.secondary.main}` + : `${props.theme.spacing.tiny} solid ${props.theme.palette.secondary.contrastText}`}; + padding: ${(props) => props.theme.spacing.small}; + cursor: pointer; +`; + +export const AccountInfoWrapper = styled.div` + display: flex; + align-items: center; +`; + +export const AccountImageStyled = styled(AccountImage)` + cursor: pointer; +`; + +export const VisibilityIcon = styled(FontAwesomeIcon)` + color: ${(props) => props.theme.palette.grey.grey1}; +`; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.view.tsx b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.view.tsx new file mode 100644 index 00000000..58725ec6 --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountItem.view.tsx @@ -0,0 +1,69 @@ +import { IconButton } from '@mui/material'; + +import { Account } from 'types'; +import { formatAddress } from 'utils/utils'; +import { + AccountInfoWrapper, + AccountImageStyled, + VisibilityIcon, + Wrapper, +} from './AccountItem.style'; + +export interface Props { + account: Account; + selected?: boolean; + visible: boolean; + scrollToRef?: React.RefObject | null; + onItemClick?: (account: Account) => Promise; + onIconButtonClick: (account: Account) => Promise; +} + +export const AccountItem = ({ + selected = false, + account, + visible, + scrollToRef, + onItemClick, + onIconButtonClick, +}: Props) => { + const { address, accountName } = account; + + const preventDefaultMouseEvent = (event: React.MouseEvent) => { + // Prevent triggering the native behaviour + event.preventDefault(); + // Prevent triggering the parent onClick event + event.stopPropagation(); + }; + + const onIconBtnClick = async (event: React.MouseEvent) => { + preventDefaultMouseEvent(event); + await onIconButtonClick(account); + }; + + const onClick = async (event: React.MouseEvent) => { + preventDefaultMouseEvent(event); + if (typeof onItemClick === 'function') { + await onItemClick(account); + } + }; + + return ( + + + +
+
{accountName}
+
{formatAddress(address)}
+
+
+ + + +
+ ); +}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.style.ts b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.style.ts new file mode 100644 index 00000000..c78f5cae --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.style.ts @@ -0,0 +1,59 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import styled from 'styled-components'; + +export const Wrapper = styled.div` + width: ${(props) => props.theme.modal.base}; + padding: ${(props) => props.theme.spacing.base}; + background-color: ${(props) => props.theme.palette.grey.white}; + border-radius: ${(props) => props.theme.corner.small}; +`; + +export const ButtonWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + padding: ${(props) => props.theme.spacing.base}; + padding-top: 0; +`; + +export const Title = styled.div` + text-align: center; + font-style: normal; + font-weight: ${(props) => props.theme.typography.h3.fontWeight}; + font-size: ${(props) => props.theme.typography.h3.fontSize}; + font-family: ${(props) => props.theme.typography.h3.fontFamily}; + line-height: ${(props) => props.theme.typography.h3.lineHeight}; + color: ${(props) => props.theme.palette.primary.main}; + margin-bottom: ${(props) => props.theme.spacing.base}; +`; + +export const HiddenAccountBar = styled.div` + display: flex; + justify-content: space-between; + padding: ${(props) => props.theme.spacing.base}; + padding-bottom: 0; + cursor: pointer; +`; + +export const HiddenAccountBarLeftIcon = styled(FontAwesomeIcon)` + color: ${(props) => props.theme.palette.grey.grey1}; + margin-right: ${(props) => props.theme.spacing.tiny2}; +`; + +export const HiddenAccountBarRightIcon = styled(FontAwesomeIcon)` + color: ${(props) => props.theme.palette.grey.grey1}; + margin-left: ${(props) => props.theme.spacing.tiny2}; +`; + +export const NoHiddenAccountText = styled.span` + color: ${(props) => props.theme.palette.grey.grey1}; +`; + +export const VerticalAlignBox = styled.div` + height: 100%; + display: flex; + align-item: center; + justify-content: center; + flex-direction: column; + text-align: center; +`; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.view.tsx b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.view.tsx new file mode 100644 index 00000000..dada767c --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountListModal/AccountList.view.tsx @@ -0,0 +1,155 @@ +import React, { useMemo, useState } from 'react'; +import Toastr from 'toastr2'; + +import { useMultiLanguage, useStarkNetSnap } from 'services'; +import { useCurrentNetwork, useCurrentAccount, useAppSelector } from 'hooks'; +import { Account } from 'types'; +import { Button } from 'components/ui/atom/Button'; +import { Scrollable } from 'components/ui/atom/Scrollable'; +import { + Wrapper, + ButtonWrapper, + Title, + HiddenAccountBar, + HiddenAccountBarLeftIcon, + HiddenAccountBarRightIcon, + NoHiddenAccountText, + VerticalAlignBox, +} from './AccountList.style'; +import { AccountItem } from './AccountItem.view'; + +export const AccountListModalView = ({ + onClose, + onAddAccountClick, +}: { + onClose: () => void; + onAddAccountClick: () => void; +}) => { + const toastr = new Toastr(); + const { + switchAccount: switchSnapAccount, + hideAccount: hideSnapAccount, + unHideAccount: showSnapAccount, + } = useStarkNetSnap(); + const { translate } = useMultiLanguage(); + const currentNework = useCurrentNetwork(); + const { address: currentAddress } = useCurrentAccount(); + const accounts = useAppSelector((state) => state.wallet.accounts); + const [visibility, setVisibility] = useState(true); + // Use useMemo to avoid re-rendering the component when the state changes + const [visibleAccounts, hiddenAccounts] = useMemo(() => { + const visibleAccounts: Account[] = []; + const hiddenAccounts: Account[] = []; + for (const account of accounts) { + // account.visibility = `undefined` refer to the case when previous account state doesnt include this field + // hence we consider it is `visible` + if (account.visibility === undefined || account.visibility === true) { + visibleAccounts.push(account); + } else { + hiddenAccounts.push(account); + } + } + return [visibleAccounts, hiddenAccounts]; + }, [accounts]); + const chainId = currentNework?.chainId; + + const switchAccount = async (account: Account) => { + onClose(); + await switchSnapAccount(chainId, account.address); + }; + + const hideAccount = async (account: Account) => { + if (visibleAccounts.length < 2) { + toastr.error(translate('youCannotHideLastAccount')); + } else { + await hideSnapAccount({ + chainId, + address: account.address, + currentAddress, + }); + } + }; + + const showAccount = async (account: Account) => { + await showSnapAccount({ + chainId, + address: account.address, + }); + }; + + return ( + <> + + {translate('selectAnAccount')} + {visibility && ( + + height={365} + child={(scrollTo) => ( + <> + {visibleAccounts.map((account) => { + const selected = currentAddress === account.address; + return ( + + ); + })} + + )} + /> + )} + {!visibility && ( + + height={365} + child={() => ( + <> + {hiddenAccounts.length === 0 ? ( + + + {translate('noHiddenAccount')} + + + ) : ( + hiddenAccounts.map((account) => ( + + )) + )} + + )} + /> + )} + setVisibility(!visibility)}> +
+ + {translate('hiddenAccounts')} +
+
+ {hiddenAccounts.length} + +
+
+
+ + + + + ); +}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountListModal/index.ts b/packages/wallet-ui/src/components/ui/organism/AccountListModal/index.ts new file mode 100644 index 00000000..bf4e83e1 --- /dev/null +++ b/packages/wallet-ui/src/components/ui/organism/AccountListModal/index.ts @@ -0,0 +1 @@ +export { AccountListModalView as AccountListModal } from './AccountList.view'; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.stories.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.stories.tsx deleted file mode 100644 index 11be92a8..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.stories.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Meta } from '@storybook/react'; -import { AccountSwitchModalView } from './AccountSwitchModal.view'; - -export default { - title: 'Molecule/AccountAddress', - component: AccountSwitchModalView, -} as Meta; - -const wrapperStyle = { - backgroundColor: 'white', - height: '300px', - alignItems: 'center', - display: 'flex', - justifyContent: 'center', -}; - -export const Default = () => ( -
- -
-); - -export const Full = () => ( -
- -
-); - -export const DarkerBackground = () => ( -
- -
-); diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.style.ts b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.style.ts deleted file mode 100644 index fec71cad..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.style.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { AccountImage } from 'components/ui/atom/AccountImage'; -import { Button } from 'components/ui/atom/Button'; -import styled from 'styled-components'; - -export const MenuSection = styled.div` - padding: 0px 10px; - display: flex; - flex-direction: column; - height: 202; - overflow-y: auto; -`; - -export const Wrapper = styled(Button).attrs((props) => ({ - fontSize: props.theme.typography.c1.fontSize, - upperCaseOnly: false, - textStyle: { - fontWeight: props.theme.typography.p1.fontWeight, - fontFamily: props.theme.typography.p1.fontFamily, - }, - iconStyle: { - fontSize: props.theme.typography.i1.fontSize, - color: props.theme.palette.grey.grey1, - }, -}))` - padding: 4px 5px; - height: 25px; - color: ${(props) => props.theme.palette.grey.black}; - border-radius: 24px; - border: 1px solid ${(props) => props.theme.palette.grey.grey3}; - - :hover { - background-color: ${(props) => props.theme.palette.grey.grey4}; - border: none; - } -`; - -export const Normal = styled.div` - font-size: ${(props) => props.theme.typography.p1.fontSize}; -`; - -export const AccountSwitchMenuItem = styled.div` - cursor: pointer; - display: flex; - align-items: center; - padding: 14px; - justify-content: space-between; -`; - -export const AccountImageStyled = styled(AccountImage)` - margin-left: ${(props) => props.theme.spacing.small}; - cursor: pointer; -`; - -export const Container = styled.div` - display: flex; - alignitems: center; -`; - -export const MenuItemText = styled.span` - ${(props) => props.theme.typography.p2}; -`; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.view.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.view.tsx deleted file mode 100644 index f01559cc..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountSwitchModal.view.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import { useState } from 'react'; -import { shortenAddress, shortenDomain } from 'utils/utils'; -import { Menu } from '@headlessui/react'; -import { useAppSelector } from 'hooks/redux'; -import { useMultiLanguage, useStarkNetSnap } from 'services'; -import { - AccountSwitchMenuItem, - MenuSection, - Wrapper, -} from './AccountSwitchModal.style'; -import { MenuItems, MenuDivider } from 'components/ui/organism/Menu/Menu.style'; -import { theme } from 'theme/default'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { AccountsHeader } from './AccountsHeader'; -import { VisibleAccountsList } from './VisibleAccountsList'; -import { HiddenAccountsList } from './HiddenAccountsList'; -import { Account } from 'types'; -import Toastr from 'toastr2'; -import { PopIn } from 'components/ui/molecule/PopIn'; -import { AddAccountModal } from './AddAccountModal'; - -interface Props { - full?: boolean; - starkName?: string; -} - -export const AccountSwitchModalView = ({ full, starkName }: Props) => { - const networks = useAppSelector((state) => state.networks); - const currentAccount = useAppSelector((state) => state.wallet.currentAccount); - const accounts = useAppSelector((state) => state.wallet.accounts); - const { switchAccount, hideAccount, unHideAccount } = useStarkNetSnap(); - const { translate } = useMultiLanguage(); - const chainId = networks?.items[networks.activeNetwork]?.chainId; - - const [showHiddenAccounts, setShowHiddenAccounts] = useState(false); - const [addAccountOpen, setAddAccountOpen] = useState(false); - - const onAccountVisibleClick = (account: Account) => { - setShowHiddenAccounts(false); - unHideAccount({ chainId, address: account.address }); - }; - - const onAccountHiddenClick = (account: Account) => { - if (accounts.filter((account) => account.visibility).length < 2) { - const toastr = new Toastr(); - toastr.error(translate('youCannotHideLastAccount')); - } else { - hideAccount({ - chainId, - address: account.address, - currentAddress, - }); - } - }; - - const onAccountSwitchClick = (account: Account) => { - switchAccount(chainId, account.address); - }; - - const visibleAccounts: Account[] = []; - const hiddenAccounts: Account[] = []; - for (const account of accounts) { - // account.visibility = `undefined` refer to the case when previous account state doesnt include this field - // hence we consider it is `visible` - if (account.visibility === undefined || account.visibility === true) { - visibleAccounts.push(account); - } else { - hiddenAccounts.push(account); - } - } - const currentAddress = currentAccount.address; - const displayName = full - ? starkName ?? currentAddress - : starkName - ? shortenDomain(starkName) - : shortenAddress(currentAddress); - - return ( - - - - {displayName} - - - - - {/* Accounts Header */} - - - - {/* Account Lists */} - {showHiddenAccounts ? ( - - ) : ( - - )} - - - - - setAddAccountOpen(true)} - style={{ - justifyContent: 'center', - padding: '8px 0', - textAlign: 'center', - }} - > - - - - - - - setAddAccountOpen(false)} /> - - - ); -}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.stories.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.stories.tsx deleted file mode 100644 index 2d24b8f2..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.stories.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Meta } from '@storybook/react'; -import { AccountsHeaderView } from './AccountsHeader.view'; -import { useState } from 'react'; -import { Account } from 'types'; - -export default { - title: 'Molecule/AccountsHeader', - component: AccountsHeaderView, -} as Meta; - -const accounts = [ - { address: '0x123', addressIndex: 0, visibility: false }, - { address: '0x456', addressIndex: 1, visibility: false }, -]; - -export const Default = () => { - const [showHiddenAccounts, setShowHiddenAccounts] = useState(false); - - return ( - - ); -}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.view.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.view.tsx deleted file mode 100644 index 4d373848..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/AccountsHeader.view.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { Account } from 'types'; -import { - AccountSwitchMenuItem, - Container, - MenuSection, - Normal, -} from '../AccountSwitchModal.style'; -import { Menu } from '@headlessui/react'; -import { IconButton } from '@mui/material'; -import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; -import VisibilityIcon from '@mui/icons-material/Visibility'; -import { useMultiLanguage } from 'services'; - -interface Props { - showHiddenAccounts: boolean; - setShowHiddenAccounts: (value: boolean) => void; - hiddenAccounts: Account[]; -} - -export const AccountsHeaderView = ({ - showHiddenAccounts, - setShowHiddenAccounts, - hiddenAccounts, -}: Props) => { - const { translate } = useMultiLanguage(); - return ( - - - - - {translate('accounts')} - - {hiddenAccounts.length > 0 && ( - setShowHiddenAccounts(!showHiddenAccounts)} - size="small" - > - {showHiddenAccounts ? ( - - ) : ( - - )} - - )} - - - - ); -}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/index.ts b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/index.ts deleted file mode 100644 index 2f1db978..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AccountsHeader/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AccountsHeaderView as AccountsHeader } from './AccountsHeader.view'; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.story.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.story.tsx deleted file mode 100644 index 8f0a7ace..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.story.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Meta } from '@storybook/react'; -import { HiddenAccountsListView } from './HiddenAccountsList.view'; -import { Account } from 'types'; - -export default { - title: 'Molecule/HiddenAccountsList', - component: HiddenAccountsListView, -} as Meta; - -const accounts = [ - { address: '0x123', addressIndex: 0, visibility: false }, - { address: '0x456', addressIndex: 1, visibility: false }, -]; - -export const Default = () => { - return ( - - console.log(`Show account ${account.address}`) - } - /> - ); -}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.view.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.view.tsx deleted file mode 100644 index 7ce2d8b0..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/HiddenAccountsList.view.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Account } from 'types'; -import { - AccountImageStyled, - AccountSwitchMenuItem, - MenuSection, - MenuItemText, -} from '../AccountSwitchModal.style'; -import { Menu } from '@headlessui/react'; -import { Box, IconButton } from '@mui/material'; -import VisibilityIcon from '@mui/icons-material/Visibility'; -import { shortenAddress } from 'utils/utils'; - -interface Props { - accounts: Account[]; - onAccountVisibleClick: (account: Account) => void; -} - -export const HiddenAccountsListView = ({ - accounts, - onAccountVisibleClick, -}: Props) => { - return ( - - {accounts.map((account) => ( - - { - e.preventDefault(); - onAccountVisibleClick(account); - }} - > - - - -
{account.accountName}
-
{shortenAddress(account.address)}
-
-
- - - -
-
- ))} -
- ); -}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/index.ts b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/index.ts deleted file mode 100644 index afa817e1..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/HiddenAccountsList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { HiddenAccountsListView as HiddenAccountsList } from './HiddenAccountsList.view'; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.story.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.story.tsx deleted file mode 100644 index 7030a1b7..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.story.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Meta } from '@storybook/react'; -import { VisibleAccountsListView } from './VisibleAccountsList.view'; -import { Account } from 'types'; - -export default { - title: 'Molecule/VisibleAccountsList', - component: VisibleAccountsListView, -} as Meta; - -const accounts = [ - { address: '0xabc', addressIndex: 1, visibility: true }, - { address: '0xdef', addressIndex: 2, visibility: true }, -]; - -export const Default = () => ( - - console.log(`Switch to ${account.address}`) - } - onAccountHiddenClick={(account: Account) => - console.log(`Hide account ${account.address}`) - } - /> -); diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.view.tsx b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.view.tsx deleted file mode 100644 index 53c0a6da..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/VisibleAccountsList.view.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { Account } from 'types'; -import { - AccountImageStyled, - AccountSwitchMenuItem, - MenuSection, - MenuItemText, -} from '../AccountSwitchModal.style'; -import { Menu } from '@headlessui/react'; -import { Box, IconButton } from '@mui/material'; -import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; -import { theme } from 'theme/default'; -import { shortenAddress } from 'utils/utils'; - -interface Props { - accounts: Account[]; - currentAddress: string; - onAccountSwitchClick: (account: Account) => void; - onAccountHiddenClick: (account: Account) => void; -} - -export const VisibleAccountsListView = ({ - accounts, - currentAddress, - onAccountSwitchClick, - onAccountHiddenClick, -}: Props) => { - return ( - - {accounts.map((account) => { - const isSelected = account.address === currentAddress; - return ( - - - onAccountSwitchClick(account) : undefined - } - > - - - -
{account.accountName}
-
{shortenAddress(account.address)}
-
-
-
- { - // Hiding accounts does not close the switch dropdown if there are still hidden accounts left. - // This allows to hide several accounts more effectively. - if (accounts.length > 2) { - e.preventDefault(); - } - onAccountHiddenClick(account); - }} - size="small" - > - - -
-
- ); - })} -
- ); -}; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/index.ts b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/index.ts deleted file mode 100644 index 7652ed7d..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/VisibleAccountsList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { VisibleAccountsListView as VisibleAccountsList } from './VisibleAccountsList.view'; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/index.ts b/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/index.ts deleted file mode 100644 index f510464a..00000000 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AccountSwitchModalView as AccountSwitchModal } from './AccountSwitchModal.view'; diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/AddAccountModal.style.ts b/packages/wallet-ui/src/components/ui/organism/AddAccountModal/AddAccountModal.style.ts similarity index 76% rename from packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/AddAccountModal.style.ts rename to packages/wallet-ui/src/components/ui/organism/AddAccountModal/AddAccountModal.style.ts index fc387d16..1bbacfb8 100644 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/AddAccountModal.style.ts +++ b/packages/wallet-ui/src/components/ui/organism/AddAccountModal/AddAccountModal.style.ts @@ -7,8 +7,9 @@ export const Wrapper = styled.div` width: ${(props) => props.theme.modal.base}; padding: ${(props) => props.theme.spacing.base}; background-color: ${(props) => props.theme.palette.grey.white}; - border-radius: 8px 8px 0px 0px; + border-radius: ${(props) => props.theme.corner.small}; `; + export const Title = styled.div` text-align: center; font-style: normal; @@ -17,14 +18,11 @@ export const Title = styled.div` font-family: ${(props) => props.theme.typography.h3.fontFamily}; line-height: ${(props) => props.theme.typography.h3.lineHeight}; color: ${(props) => props.theme.palette.primary.main}; - margin-bottom: 24px; + margin-bottom: ${(props) => props.theme.spacing.base}; `; export const FormGroup = styled.div` - margin: 8px 0; -`; -export const Space = styled.div` - margin-top: 1.1rem; + margin: ${(props) => props.theme.spacing.tiny2} 0; `; export const ButtonStyled = styled(Button)` @@ -32,15 +30,10 @@ export const ButtonStyled = styled(Button)` `; export const ButtonsWrapper = styled.div` - background-color: ${(props) => props.theme.palette.grey.white}; padding: ${(props) => props.theme.spacing.base}; + gap: ${(props) => props.theme.spacing.base}; display: flex; flex-direction: row; - justify-content: space-between; - align-items: center; - box-shadow: inset 0px 1px 0px rgba(212, 212, 225, 0.4); - border-radius: 0px 0px 8px 8px; - width: ${(props) => props.theme.modal.base}; `; export const ErrorMsg = styled.div` diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/AddAccountModal.view.tsx b/packages/wallet-ui/src/components/ui/organism/AddAccountModal/AddAccountModal.view.tsx similarity index 81% rename from packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/AddAccountModal.view.tsx rename to packages/wallet-ui/src/components/ui/organism/AddAccountModal/AddAccountModal.view.tsx index 5ddc283d..b068015c 100644 --- a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/AddAccountModal.view.tsx +++ b/packages/wallet-ui/src/components/ui/organism/AddAccountModal/AddAccountModal.view.tsx @@ -1,32 +1,32 @@ import { useState, useEffect, ChangeEvent } from 'react'; -import { useAppSelector } from 'hooks/redux'; + +import { useAppSelector, useCurrentNetwork } from 'hooks'; import { useMultiLanguage, useStarkNetSnap } from 'services'; +import { getDefaultAccountName } from 'utils/utils'; +import { ACCOUNT_NAME_LENGTH } from 'utils/constants'; import { InputWithLabel } from 'components/ui/molecule/InputWithLabel'; import { ButtonStyled, ButtonsWrapper, ErrorMsg, FormGroup, - Space, Title, Wrapper, } from './AddAccountModal.style'; -import { getDefaultAccountName } from 'utils/utils'; -import { ACCOUNT_NAME_LENGTH } from 'utils/constants'; interface Props { - closeModal: () => void; + onClose: () => void; } -export const AddAccountModalView = ({ closeModal }: Props) => { +export const AddAccountModalView = ({ onClose }: Props) => { const [minLength, maxLength] = ACCOUNT_NAME_LENGTH; const { addNewAccount } = useStarkNetSnap(); const { translate } = useMultiLanguage(); - const networks = useAppSelector((state) => state.networks); + const currentNework = useCurrentNetwork(); const accounts = useAppSelector((state) => state.wallet.accounts); const [enabled, setEnabled] = useState(true); const [accountName, setAccountName] = useState(''); - const chainId = networks?.items[networks.activeNetwork].chainId; + const chainId = currentNework?.chainId; useEffect(() => { const trimedAccountName = accountName.trim(); @@ -42,6 +42,9 @@ export const AddAccountModalView = ({ closeModal }: Props) => { }; const onAddAccount = async () => { + // The UX is better if we close the modal before adding the account + onClose(); + const trimedAccountName = accountName.trim(); // Reset account name to undefined if it is empty, // so that the default account name is used in Snap @@ -49,14 +52,12 @@ export const AddAccountModalView = ({ closeModal }: Props) => { chainId, trimedAccountName === '' ? undefined : trimedAccountName, ); - closeModal(); }; return ( <> {translate('addAccount')} - { - + onClose()} + backgroundTransparent + borderVisible + > {translate('cancel')} - + onAddAccount()}> {translate('add')} diff --git a/packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/index.ts b/packages/wallet-ui/src/components/ui/organism/AddAccountModal/index.ts similarity index 100% rename from packages/wallet-ui/src/components/ui/organism/AccountSwitchModal/AddAccountModal/index.ts rename to packages/wallet-ui/src/components/ui/organism/AddAccountModal/index.ts diff --git a/packages/wallet-ui/src/components/ui/organism/SideBar/SideBar.view.tsx b/packages/wallet-ui/src/components/ui/organism/SideBar/SideBar.view.tsx index caad0fb9..3a4d5686 100644 --- a/packages/wallet-ui/src/components/ui/organism/SideBar/SideBar.view.tsx +++ b/packages/wallet-ui/src/components/ui/organism/SideBar/SideBar.view.tsx @@ -1,9 +1,16 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { useEffect, useRef, useState } from 'react'; + +import { useAppSelector, useCurrentAccount, useCurrentNetwork } from 'hooks'; +import { useMultiLanguage, useStarkNetSnap } from 'services'; import { RoundedIcon } from 'components/ui/atom/RoundedIcon'; -import { AccountSwitchModal } from 'components/ui/organism/AccountSwitchModal'; import { AssetsList } from 'components/ui/molecule/AssetsList'; import { PopIn } from 'components/ui/molecule/PopIn'; +import { PopperTooltip } from 'components/ui/molecule/PopperTooltip'; +import { openExplorerTab } from 'utils/utils'; +import { defaultAccount } from 'utils/constants'; +import { AccountDrawer } from '../AccountDrawer'; +import { AddTokenModal } from '../AddTokenModal'; import { AccountDetailsModal } from '../AccountDetailsModal'; import { ConnectInfoModal } from '../ConnectInfoModal'; import { @@ -20,30 +27,23 @@ import { RowDiv, Wrapper, } from './SideBar.style'; -import { openExplorerTab } from 'utils/utils'; -import { useAppSelector } from 'hooks/redux'; -import { AddTokenModal } from '../AddTokenModal'; -import { useMultiLanguage, useStarkNetSnap } from 'services'; -import { defaultAccount } from 'utils/constants'; -import { PopperTooltip } from 'components/ui/molecule/PopperTooltip'; export const SideBarView = () => { - const networks = useAppSelector((state) => state.networks); - const currentAccount = useAppSelector((state) => state.wallet.currentAccount); + const { getStarkName } = useStarkNetSnap(); + const { translate } = useMultiLanguage(); + const currentNework = useCurrentNetwork(); + const { address, accountName } = useCurrentAccount(); const erc20TokenBalances = useAppSelector( (state) => state.wallet.erc20TokenBalances, ); const connected = useAppSelector((state) => state.wallet.connected); - const chainId = networks?.items[networks.activeNetwork]?.chainId; const [listOverflow, setListOverflow] = useState(false); const [infoModalOpen, setInfoModalOpen] = useState(false); const [accountDetailsOpen, setAccountDetailsOpen] = useState(false); const [addTokenOpen, setAddTokenOpen] = useState(false); - const { getStarkName } = useStarkNetSnap(); - const { translate } = useMultiLanguage(); const [starkName, setStarkName] = useState(undefined); - const address = currentAccount.address; const ref = useRef(); + const chainId = currentNework?.chainId; useEffect(() => { if (ref.current) { @@ -113,10 +113,10 @@ export const SideBarView = () => { - {currentAccount.accountName} + {accountName} setInfoModalOpen(true)}>i - + navigator.clipboard.writeText(address)} diff --git a/packages/wallet-ui/src/hooks/index.ts b/packages/wallet-ui/src/hooks/index.ts new file mode 100644 index 00000000..e2780cdf --- /dev/null +++ b/packages/wallet-ui/src/hooks/index.ts @@ -0,0 +1,4 @@ +export * from './redux'; +export * from './useCurrentNetwork'; +export * from './useCurrentAccount'; +export * from './useScrollTo'; diff --git a/packages/wallet-ui/src/hooks/useCurrentAccount.ts b/packages/wallet-ui/src/hooks/useCurrentAccount.ts new file mode 100644 index 00000000..246769c7 --- /dev/null +++ b/packages/wallet-ui/src/hooks/useCurrentAccount.ts @@ -0,0 +1,12 @@ +import { Account } from 'types'; +import { useAppSelector } from './redux'; + +/** + * A hook to get the current account + * + * @returns the current account + */ +export const useCurrentAccount = (): Account => { + const currentAccount = useAppSelector((state) => state.wallet.currentAccount); + return currentAccount; +}; diff --git a/packages/wallet-ui/src/hooks/useCurrentNetwork.ts b/packages/wallet-ui/src/hooks/useCurrentNetwork.ts new file mode 100644 index 00000000..5b375c84 --- /dev/null +++ b/packages/wallet-ui/src/hooks/useCurrentNetwork.ts @@ -0,0 +1,13 @@ +import { Network } from 'types'; +import { useAppSelector } from './redux'; + +/** + * A hook to get the current network + * + * @returns the current network + */ +export const useCurrentNetwork = (): Network => { + const networks = useAppSelector((state) => state.networks); + const currentNetwork = networks?.items?.[networks?.activeNetwork]; + return currentNetwork; +}; diff --git a/packages/wallet-ui/src/hooks/useScrollTo.ts b/packages/wallet-ui/src/hooks/useScrollTo.ts new file mode 100644 index 00000000..8e438aab --- /dev/null +++ b/packages/wallet-ui/src/hooks/useScrollTo.ts @@ -0,0 +1,36 @@ +import { useEffect, useRef } from 'react'; + +/** + * A hook for scroll to the ref element + * @param behavior - scrollIntoView options [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollIntoView) + * + * @returns scrollTo - ref object to scroll to + * @returns scrollToView - function to scroll to the ref element + */ +export const useScrollTo = ( + behavior: ScrollIntoViewOptions = { + behavior: 'smooth', + block: 'start', + }, +): { + scrollTo: React.RefObject; + scrollToView: () => void; +} => { + const scrollTo = useRef(null); + + const scrollToView = () => { + if (scrollTo && scrollTo.current) { + scrollTo.current.scrollIntoView(behavior); + } + }; + + useEffect(() => { + scrollToView(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [scrollTo]); + + return { + scrollToView, + scrollTo, + }; +}; diff --git a/packages/wallet-ui/src/utils/utils.ts b/packages/wallet-ui/src/utils/utils.ts index dc7cc8ec..02d8cd0a 100644 --- a/packages/wallet-ui/src/utils/utils.ts +++ b/packages/wallet-ui/src/utils/utils.ts @@ -257,16 +257,24 @@ export const isUserDenyError = (error: any): Boolean => { return false; }; -export const getDefaultAccountName = (hdIndex = 0) => { +export const getDefaultAccountName = (hdIndex = 0): string => { if (hdIndex < 0) { throw new Error('hdIndex cannot be negative.'); } return `Account ${hdIndex + 1}`; }; -export const removeUndefined = (obj: Record) => { +export const removeUndefined = ( + obj: Record, +): Record => { // eslint-disable-next-line @typescript-eslint/no-unused-vars return Object.fromEntries( Object.entries(obj).filter(([_, val]) => val !== undefined), ); }; + +export const formatAddress = (address: string, starkName?: string): string => { + return starkName + ? shortenDomain(starkName) + : (shortenAddress(address) as string); +};