Skip to content

Commit

Permalink
feat: pre release UI updates (#290)
Browse files Browse the repository at this point in the history
* refactor: rename password lock to credential lock

* refactor: decrease size of network badges

* refactor: add border radius to network select container

* refactor: reposition account page header and fix broken scroll in tab containers

* feat: add tab bar control component and use in asset and activity tabs

* chore: squash

* refactor: replace edit name with edit account and a new edit account modal

* refactor: update select modal styles

* chore: squash

* refactor: remove pills from network select and use concise select

* chore: squash

* refactor: update inputs to have full border radius

* chore: squash

* refactor: use new password hook and update new password component to be more dumb

* refactor: add amount input and address input hooks and update send asset modal
  • Loading branch information
kieranroneill authored Aug 27, 2024
1 parent 734c89e commit 65ca387
Show file tree
Hide file tree
Showing 194 changed files with 2,595 additions and 1,823 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import {
} from '@chakra-ui/react';
import React, { FC, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { IoDownloadOutline } from 'react-icons/io5';
import { useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';

// components
import AccountItem from '@extension/components/AccountItem';
import Button from '@extension/components/Button';
import EmptyState from '@extension/components/EmptyState';

// constants
import {
Expand Down Expand Up @@ -73,7 +75,6 @@ import type {
import convertPublicKeyToAVMAddress from '@extension/utils/convertPublicKeyToAVMAddress';
import ellipseAddress from '@extension/utils/ellipseAddress';
import flattenAccountImportSchemaToNewAccounts from '@extension/utils/flattenAccountImportSchemaToNewAccounts';
import EmptyState from '@extension/components/EmptyState';

const ARC0300AccountImportModalContent: FC<
IARC0300ModalContentProps<IARC0300AccountImportSchema[]>
Expand Down Expand Up @@ -310,6 +311,7 @@ const ARC0300AccountImportModalContent: FC<
<Button
isLoading={saving}
onClick={handleImportClick}
rightIcon={<IoDownloadOutline />}
size="lg"
variant="solid"
w="full"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import BigNumber from 'bignumber.js';
import React, { FC, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { IoAddOutline } from 'react-icons/io5';
import { useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';

Expand Down Expand Up @@ -90,6 +91,7 @@ import isAssetInAccountHoldings from '@extension/utils/isAssetInAccountHoldings'
const ARC0300AssetAddModalContent: FC<
IARC0300ModalContentProps<IARC0300AssetAddSchema>
> = ({
_context,
cancelButtonIcon,
cancelButtonLabel,
onComplete,
Expand Down Expand Up @@ -261,6 +263,7 @@ const ARC0300AssetAddModalContent: FC<
<ModalSubHeading text={t<string>('headings.selectAccount')} />

<AccountSelect
_context={_context}
accounts={accounts}
allowWatchAccounts={true}
disabled={loading || saving}
Expand Down Expand Up @@ -341,7 +344,7 @@ const ARC0300AssetAddModalContent: FC<
{/*type*/}
<ModalItem
label={`${t<string>('labels.chain')}:`}
value={<NetworkBadge network={network} />}
value={<NetworkBadge network={network} size="xs" />}
/>

{/*type*/}
Expand Down Expand Up @@ -409,6 +412,7 @@ const ARC0300AssetAddModalContent: FC<
<Button
isLoading={loading || saving}
onClick={handleAddClick}
rightIcon={<IoAddOutline />}
size="lg"
variant="solid"
w="full"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@stablelib/base64';
import type { Transaction } from 'algosdk';
import React, { type FC, useEffect, useState } from 'react';
import { IoArrowUpOutline } from 'react-icons/io5';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';

Expand Down Expand Up @@ -411,6 +412,7 @@ const ARC0300KeyRegistrationTransactionSendModalContent: FC<
<Button
isLoading={sending}
onClick={handleSendClick}
rightIcon={<IoArrowUpOutline />}
size="lg"
variant="solid"
w="full"
Expand Down
1 change: 1 addition & 0 deletions src/extension/components/AccountItem/AccountItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const AccountItem: FC<IProps> = ({
>
{name}
</Text>

<Text
color={subTextColor || defaultSubTextColor}
fontSize="xs"
Expand Down
101 changes: 66 additions & 35 deletions src/extension/components/AccountSelect/AccountSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,97 +1,128 @@
import {
HStack,
Button as ChakraButton,
Icon,
Stack,
Tooltip,
useDisclosure,
VStack,
} from '@chakra-ui/react';
import React, { FC } from 'react';
import React, { type FC } from 'react';
import { useTranslation } from 'react-i18next';
import { GoSingleSelect } from 'react-icons/go';
import { IoChevronDownOutline } from 'react-icons/io5';

// components
import AccountItem from '@extension/components/AccountItem';
import IconButton from '@extension/components/IconButton';
import Label from '@extension/components/Label';

// constants
import { DEFAULT_GAP, INPUT_HEIGHT } from '@extension/constants';

// hooks
import useBorderColor from '@extension/hooks/useBorderColor';
import useButtonHoverBackgroundColor from '@extension/hooks/useButtonHoverBackgroundColor';
import useColorModeValue from '@extension/hooks/useColorModeValue';
import usePrimaryColor from '@extension/hooks/usePrimaryColor';
import useSubTextColor from '@extension/hooks/useSubTextColor';

// modals
import AccountSelectModal from '@extension/modals/AccountSelectModal';
import AccountSelectModal from './AccountSelectModal';

// theme
import { theme } from '@extension/theme';

// types
import type { IAccountWithExtendedProps } from '@extension/types';
import type { IProps } from './types';

// utils
import calculateIconSize from '@extension/utils/calculateIconSize';
import convertPublicKeyToAVMAddress from '@extension/utils/convertPublicKeyToAVMAddress';

const AccountSelect: FC<IProps> = ({
_context,
accounts,
allowWatchAccounts,
disabled = false,
label,
onSelect,
required = false,
selectModalTitle,
value,
}) => {
const { t } = useTranslation();
// hooks
const borderColor = useBorderColor();
const buttonHoverBackgroundColor = useButtonHoverBackgroundColor();
const primaryColorCode = useColorModeValue(
theme.colors.primaryLight['500'],
theme.colors.primaryDark['500']
);
const primaryColor = usePrimaryColor();
const subTextColor = useSubTextColor();
const {
isOpen: isAccountSelectModalOpen,
onClose: onAccountSelectClose,
onOpen: onAccountSelectModalOpen,
} = useDisclosure();
// handlers
const handleAccountClick = () => onAccountSelectModalOpen();
const handleOnAccountSelect = (_value: IAccountWithExtendedProps[]) =>
const handleOnClick = () => onAccountSelectModalOpen();
const handleOnSelect = (_value: IAccountWithExtendedProps[]) =>
onSelect(_value[0]);

return (
<>
{/*account select modal*/}
<AccountSelectModal
_context={_context}
accounts={accounts}
allowWatchAccounts={allowWatchAccounts}
isOpen={isAccountSelectModalOpen}
multiple={false}
onClose={onAccountSelectClose}
onSelect={handleOnAccountSelect}
onSelect={handleOnSelect}
title={selectModalTitle}
/>

<VStack alignItems="flex-start" spacing={DEFAULT_GAP / 3} w="full">
{/*label*/}
{label && <Label label={label} required={required} />}
{label && (
<Label label={label} px={DEFAULT_GAP - 2} required={required} />
)}

<HStack justifyContent="center" spacing={DEFAULT_GAP / 3} w="full">
{/*account view*/}
<Stack
borderRadius="md"
borderWidth={1}
flexGrow={1}
height={INPUT_HEIGHT}
justifyContent="center"
px={DEFAULT_GAP - 2}
w="full"
>
<ChakraButton
_focus={{
borderColor: primaryColor,
boxShadow: `0 0 0 1px ${primaryColorCode}`,
}}
_hover={{
bg: buttonHoverBackgroundColor,
borderColor: borderColor,
}}
aria-label={t<string>('labels.selectAccount')}
alignItems="center"
borderStyle="solid"
borderWidth="1px"
borderRadius="full"
h={INPUT_HEIGHT}
justifyContent="space-between"
onClick={handleOnClick}
px={DEFAULT_GAP - 2}
py={0}
rightIcon={
<Icon
as={IoChevronDownOutline}
boxSize={calculateIconSize()}
color={subTextColor}
/>
}
variant="ghost"
w="full"
>
<Stack flexGrow={1} justifyContent="center" w="full">
<AccountItem
address={convertPublicKeyToAVMAddress(value.publicKey)}
{...(value.name && { name: value.name })}
/>
</Stack>

{/*open account select modal button*/}
<Tooltip label={t<string>('labels.selectAccount')}>
<IconButton
aria-label="Select an account from the list of available accounts"
disabled={disabled}
icon={GoSingleSelect}
onClick={handleAccountClick}
size="lg"
variant="ghost"
/>
</Tooltip>
</HStack>
</ChakraButton>
</VStack>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import {
Tooltip,
VStack,
} from '@chakra-ui/react';
import React, { FC, useState } from 'react';
import React, { type FC, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { IoChevronForward } from 'react-icons/io5';
import { IoCheckmarkOutline, IoChevronForward } from 'react-icons/io5';

// components
import AccountAvatarWithBadges from '@extension/components/AccountAvatarWithBadges';
Expand Down Expand Up @@ -49,21 +49,23 @@ import { theme } from '@extension/theme';

// types
import type { IAccountWithExtendedProps } from '@extension/types';
import type { IProps } from './types';
import type { TAccountSelectModalProps } from './types';

// utils
import calculateIconSize from '@extension/utils/calculateIconSize';
import convertPublicKeyToAVMAddress from '@extension/utils/convertPublicKeyToAVMAddress';
import ellipseAddress from '@extension/utils/ellipseAddress';
import upsertItemsById from '@extension/utils/upsertItemsById';

const AccountSelectModal: FC<IProps> = ({
const AccountSelectModal: FC<TAccountSelectModalProps> = ({
_context,
accounts,
allowWatchAccounts = true,
isOpen,
multiple,
onClose,
onSelect,
title,
}) => {
const { t } = useTranslation();
// selectors
Expand Down Expand Up @@ -143,12 +145,12 @@ const AccountSelectModal: FC<IProps> = ({
_hover={{
bg: BODY_BACKGROUND_COLOR,
}}
borderRadius={0}
borderRadius="full"
cursor="not-allowed"
fontSize="md"
h={TAB_ITEM_HEIGHT}
justifyContent="start"
key={`account-select-modal-item-${index}`}
key={`${_context}-account-select-modal-item-${index}`}
px={DEFAULT_GAP / 2}
py={0}
sx={{
Expand Down Expand Up @@ -270,9 +272,12 @@ const AccountSelectModal: FC<IProps> = ({
textAlign="center"
w="full"
>
{t<string>(
multiple ? 'headings.selectAccounts' : 'headings.selectAccount'
)}
{title ||
t<string>(
multiple
? 'headings.selectAccounts'
: 'headings.selectAccount'
)}
</Heading>

{/*select all accounts*/}
Expand Down Expand Up @@ -302,8 +307,12 @@ const AccountSelectModal: FC<IProps> = ({
</VStack>
</ModalHeader>

{/*content*/}
<ModalBody px={DEFAULT_GAP}>{renderContent()}</ModalBody>
{/*body*/}
<ModalBody px={DEFAULT_GAP}>
<VStack spacing={1} w="full">
{renderContent()}
</VStack>
</ModalBody>

{/*footer*/}
<ModalFooter p={DEFAULT_GAP}>
Expand All @@ -320,6 +329,7 @@ const AccountSelectModal: FC<IProps> = ({
{multiple && (
<Button
onClick={handleConfirmClick}
rightIcon={<IoCheckmarkOutline />}
size="lg"
variant="solid"
w="full"
Expand Down
2 changes: 2 additions & 0 deletions src/extension/components/AccountSelect/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export { default } from './AccountSelect';
export { default as AccountSelectModal } from './AccountSelectModal';
export * from './types';
8 changes: 6 additions & 2 deletions src/extension/components/AccountSelect/types/IProps.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// types
import type { IAccountWithExtendedProps } from '@extension/types';
import type {
IAccountWithExtendedProps,
IPropsWithContext,
} from '@extension/types';

interface IProps {
interface IProps extends IPropsWithContext {
accounts: IAccountWithExtendedProps[];
allowWatchAccounts?: boolean;
disabled?: boolean;
label?: string;
onSelect: (account: IAccountWithExtendedProps) => void;
required?: boolean;
selectModalTitle?: string;
value: IAccountWithExtendedProps;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// types
import type {
IAccountWithExtendedProps,
IModalProps,
IPropsWithContext,
} from '@extension/types';

interface IAccountSelectModalProps {
accounts: IAccountWithExtendedProps[];
allowWatchAccounts?: boolean;
isOpen: boolean;
multiple?: boolean;
onSelect: (accounts: IAccountWithExtendedProps[]) => void;
title?: string;
}

type TAccountSelectModalProps = IAccountSelectModalProps &
IModalProps &
IPropsWithContext;

export default TAccountSelectModalProps;
Loading

0 comments on commit 65ca387

Please sign in to comment.