diff --git a/package-lock.json b/package-lock.json index d76261d1..af2356e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28272,6 +28272,7 @@ "@chakra-ui/icons": "2.0.17", "@chakra-ui/react": "2.4.9", "@chakra-ui/theme-tools": "2.0.17", + "@chakra-ui/utils": "2.0.15", "@ckb-lumos/base": "0.20.0-alpha.2", "@ckb-lumos/bi": "0.20.0-alpha.2", "@ckb-lumos/codec": "0.20.0-alpha.2", diff --git a/packages/extension-chrome/package.json b/packages/extension-chrome/package.json index 060aaf28..1edc1123 100644 --- a/packages/extension-chrome/package.json +++ b/packages/extension-chrome/package.json @@ -34,6 +34,7 @@ "@chakra-ui/icons": "2.0.17", "@chakra-ui/react": "2.4.9", "@chakra-ui/theme-tools": "2.0.17", + "@chakra-ui/utils": "2.0.15", "@ckb-lumos/base": "0.20.0-alpha.2", "@ckb-lumos/bi": "0.20.0-alpha.2", "@ckb-lumos/codec": "0.20.0-alpha.2", diff --git a/packages/extension-chrome/src/pages/Components/CircleMarker.tsx b/packages/extension-chrome/src/pages/Components/CircleMarker.tsx new file mode 100644 index 00000000..f5efa31a --- /dev/null +++ b/packages/extension-chrome/src/pages/Components/CircleMarker.tsx @@ -0,0 +1,6 @@ +import { Box, BoxProps } from '@chakra-ui/react'; +import React, { FC } from 'react'; + +export const CircleMarker: FC = (props) => ( + +); diff --git a/packages/extension-chrome/src/pages/Components/DialogFrame.tsx b/packages/extension-chrome/src/pages/Components/DialogFrame.tsx index be08e97b..044508a1 100644 --- a/packages/extension-chrome/src/pages/Components/DialogFrame.tsx +++ b/packages/extension-chrome/src/pages/Components/DialogFrame.tsx @@ -28,13 +28,13 @@ export const DialogFrame: FC = ({ meta }) => { }; return ( - + = ({ total, current, ...rest }) => { + const getIndicatorColor = (index: number) => { + if (index < current) { + return 'primary.lighter'; + } else if (index > current) { + return 'gray.300'; + } + return 'primary'; + }; + return ( + + {range(0, total).map((index) => ( + + ))} + + ); +}; diff --git a/packages/extension-chrome/src/pages/Components/ProgressSteps.tsx b/packages/extension-chrome/src/pages/Components/ProgressSteps.tsx new file mode 100644 index 00000000..5ecc03c3 --- /dev/null +++ b/packages/extension-chrome/src/pages/Components/ProgressSteps.tsx @@ -0,0 +1,61 @@ +import { CheckCircleIcon } from '@chakra-ui/icons'; +import { Box, BoxProps, Grid, Icon, Text } from '@chakra-ui/react'; +import Steps from 'rc-steps'; +import { StepsProps } from 'rc-steps/lib/Steps'; +import React, { FC } from 'react'; +import StepProcessingIcon from './icons/StepProcessing.svg'; +import StepWaitingIcon from './icons/StepWaiting.svg'; + +export type ProgressStepsProps = Pick & BoxProps; +const renderSingleStep: StepsProps['itemRender'] = ({ title, description, status }) => { + const icon = { + wait: , + process: , + finish: , + error: <>, + }[status ?? 'wait']; + return ( + + + {icon} + + + {title} + + + + {description} + + + ); +}; + +export const ProgressSteps: FC = (props) => { + return ; +}; diff --git a/packages/extension-chrome/src/pages/Components/SearchBar.tsx b/packages/extension-chrome/src/pages/Components/SearchBar.tsx new file mode 100644 index 00000000..b1a5cce9 --- /dev/null +++ b/packages/extension-chrome/src/pages/Components/SearchBar.tsx @@ -0,0 +1,35 @@ +import { SearchIcon } from '@chakra-ui/icons'; +import { Center, Input, InputGroup, InputGroupProps, InputLeftElement, InputProps } from '@chakra-ui/react'; +import React, { FC } from 'react'; + +type InputPickedFields = 'onChange' | 'onBlur' | 'onFocus' | 'value' | 'defaultValue'; + +type SearchBarProps = Omit & Pick; + +export const SearchBar: FC = ({ onChange, onBlur, onFocus, value, defaultValue, ...rest }) => ( + + +
+ +
+
+ +
+); diff --git a/packages/extension-chrome/src/pages/Components/WhiteAlphaBox.tsx b/packages/extension-chrome/src/pages/Components/WhiteAlphaBox.tsx index 770fae12..52bedc9f 100644 --- a/packages/extension-chrome/src/pages/Components/WhiteAlphaBox.tsx +++ b/packages/extension-chrome/src/pages/Components/WhiteAlphaBox.tsx @@ -5,7 +5,7 @@ import { Flex, FlexProps } from '@chakra-ui/react'; export const WhiteAlphaBox: FC = ({ children, sx, ...props }) => { return ( { maxW="100%" overflow="hidden" whiteSpace="nowrap" - color="yellow.200" + color="accent" as={RouteLink} to="/sign-transaction/view-data" cursor="pointer" diff --git a/packages/extension-chrome/src/pages/Notification/containers/SignTransaction.tsx b/packages/extension-chrome/src/pages/Notification/containers/SignTransaction.tsx index 59cb581e..c9af4567 100644 --- a/packages/extension-chrome/src/pages/Notification/containers/SignTransaction.tsx +++ b/packages/extension-chrome/src/pages/Notification/containers/SignTransaction.tsx @@ -47,7 +47,7 @@ const CellCapacity: FC<{ capacity: string }> = ({ capacity }) => { return ( <> {decimalPart ? ( - + ≈{integerPart} {' CKB'} @@ -124,7 +124,7 @@ const TransactionIOList: FC = ({ type, networkName, tx, #{index + 1} - + {addr.slice(0, 5)}...{addr.slice(-4)} @@ -199,6 +199,7 @@ export const SignTransaction: FC = () => { mx="-4px" px="4px" overflow="auto" + maxH="420px" > diff --git a/packages/extension-chrome/src/pages/Notification/index.tsx b/packages/extension-chrome/src/pages/Notification/index.tsx index 261ab4eb..3683f25d 100644 --- a/packages/extension-chrome/src/pages/Notification/index.tsx +++ b/packages/extension-chrome/src/pages/Notification/index.tsx @@ -62,7 +62,6 @@ const router = createHashRouter(routes); const App = () => { return ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment diff --git a/packages/extension-chrome/src/pages/Popup/containers/Home.tsx b/packages/extension-chrome/src/pages/Popup/containers/Home.tsx index 7db3c864..a93551b0 100644 --- a/packages/extension-chrome/src/pages/Popup/containers/Home.tsx +++ b/packages/extension-chrome/src/pages/Popup/containers/Home.tsx @@ -67,10 +67,15 @@ export const Home: FC = () => { - + {entries.map(({ title, icon, onClick, testId }) => ( { onClick={onClick} type="button" > -
+
{icon}
diff --git a/packages/extension-chrome/src/pages/Popup/containers/Network/EditNetwork.tsx b/packages/extension-chrome/src/pages/Popup/containers/Network/EditNetwork.tsx index 79eadab4..750fe47a 100644 --- a/packages/extension-chrome/src/pages/Popup/containers/Network/EditNetwork.tsx +++ b/packages/extension-chrome/src/pages/Popup/containers/Network/EditNetwork.tsx @@ -95,7 +95,7 @@ export const EditNetwork: FC = ({ mode }) => { return ( - + Name diff --git a/packages/extension-chrome/src/pages/Popup/containers/Network/NetworkConfig.tsx b/packages/extension-chrome/src/pages/Popup/containers/Network/NetworkConfig.tsx index 13e7786d..d969d685 100644 --- a/packages/extension-chrome/src/pages/Popup/containers/Network/NetworkConfig.tsx +++ b/packages/extension-chrome/src/pages/Popup/containers/Network/NetworkConfig.tsx @@ -1,5 +1,5 @@ import React, { FC } from 'react'; -import { Flex, Spacer, Button, Radio, RadioGroup, Skeleton, Icon, useToast, VStack } from '@chakra-ui/react'; +import { Flex, Spacer, Button, Radio, RadioGroup, Skeleton, Icon, useToast } from '@chakra-ui/react'; import { AddIcon, DeleteIcon } from '@chakra-ui/icons'; import EditIcon from '../../../Components/icons/Edit.svg'; import { useNavigate } from 'react-router-dom'; @@ -58,57 +58,63 @@ export const NetworkConfig: FC = () => { return ( - - - - {networks?.map((network, index) => ( - - - {network.displayName} - - - {!PERSIST_IDS.has(network.id) && ( - - - { - await removeNetworkMutation.mutateAsync(network.id); - await configQuery.invalidate(); - }} - w="20px" - h="20px" - color="white" - /> - - )} + + {networks?.map((network, index) => ( + + + {network.displayName} + + {!PERSIST_IDS.has(network.id) && ( + + + { + await removeNetworkMutation.mutateAsync(network.id); + await configQuery.invalidate(); + }} + w="20px" + h="20px" + color="white" + /> - ))} - - - + )} + + ))} + - +
+ +
+
); }; diff --git a/packages/extension-chrome/src/pages/WalletManager/containers/ConfirmMnemonic.tsx b/packages/extension-chrome/src/pages/WalletManager/containers/ConfirmMnemonic.tsx index b2ff3527..61403839 100644 --- a/packages/extension-chrome/src/pages/WalletManager/containers/ConfirmMnemonic.tsx +++ b/packages/extension-chrome/src/pages/WalletManager/containers/ConfirmMnemonic.tsx @@ -1,4 +1,4 @@ -import { Badge, Box, Button, Heading, SimpleGrid, Textarea } from '@chakra-ui/react'; +import { Box, Button, Center, Heading, SimpleGrid, Textarea } from '@chakra-ui/react'; import React, { FC, ReactElement, useEffect, useMemo } from 'react'; import { useList } from 'react-use'; import shuffle from 'lodash.shuffle'; @@ -6,6 +6,7 @@ import zip from 'lodash.zip'; import { useWalletCreationStore } from '../store'; import range from 'lodash.range'; import { useOutletContext } from './CreateProcessFrame'; +import { CircleMarker } from '../../Components/CircleMarker'; export const ConfirmMnemonic: FC = () => { const { initWallet, seed } = useWalletCreationStore(); @@ -40,8 +41,15 @@ export const ConfirmMnemonic: FC = () => { isAllCorrect = false; } wordElements.push( - - {chosenWord}{' '} + + {chosenWord} , ); }); @@ -57,42 +65,46 @@ export const ConfirmMnemonic: FC = () => { }, [isAllCorrect, setNextAvailable]); return ( - <> + Confirm your Seed - + Please select words in correct order to form your seed. - - + {word4Choose.map((word, index) => { const chosenOrder = chosenIndex.findIndex((i) => i === index); const hasChosen = chosenOrder !== -1; + const isCorrect = seed[chosenOrder] === word; return ( {hasChosen && ( - {chosenOrder + 1} - + )} - + ); diff --git a/packages/extension-chrome/src/pages/WalletManager/containers/NewMnemonic.tsx b/packages/extension-chrome/src/pages/WalletManager/containers/NewMnemonic.tsx index 7c28c5c3..4bc6a231 100644 --- a/packages/extension-chrome/src/pages/WalletManager/containers/NewMnemonic.tsx +++ b/packages/extension-chrome/src/pages/WalletManager/containers/NewMnemonic.tsx @@ -11,9 +11,13 @@ import { Flex, Text, useToast, + List, + ListItem, + ListIcon, } from '@chakra-ui/react'; import React, { useEffect, useState, FC } from 'react'; import { hd } from '@ckb-lumos/lumos'; +import { CircleMarker } from '../../Components/CircleMarker'; import FileCopyIcon from '../../Components/icons/FileCopy.svg'; import { useWalletCreationStore } from '../store'; @@ -41,11 +45,11 @@ export const CreateMnemonic: FC = () => { }, [mnemonic, clipboard, setWalletStore]); return ( - <> + Generate Wallet Seed - + Warning @@ -74,16 +78,18 @@ export const CreateMnemonic: FC = () => { - - - - Store this Seed in a password manager like 1Password. -
-
- Please write this Seed on a piece of paper and store in a secure location. If you want even stronger security, - write it down on multiple pieces of paper and store them in at least 2-3 different locations. -
-
- + + + + + Store this Seed in a password manager like 1Password. + + Please write this Seed on a piece of paper and store in a secure location. If you want even stronger + security, write it down on multiple pieces of paper and store them in at least 2-3 different locations. + + + + +
); }; diff --git a/packages/extension-chrome/src/pages/WalletManager/containers/Password.tsx b/packages/extension-chrome/src/pages/WalletManager/containers/Password.tsx index bc956037..fd78f7b3 100644 --- a/packages/extension-chrome/src/pages/WalletManager/containers/Password.tsx +++ b/packages/extension-chrome/src/pages/WalletManager/containers/Password.tsx @@ -42,7 +42,7 @@ export const SetPassword: FC = ({ isImportSeed }) => { }, [setNextAvailable, formState]); return ( - <> + Create password @@ -121,6 +121,6 @@ export const SetPassword: FC = ({ isImportSeed }) => { */} - + ); }; diff --git a/packages/extension-chrome/src/pages/WalletManager/containers/RecoveryWallet.tsx b/packages/extension-chrome/src/pages/WalletManager/containers/RecoveryWallet.tsx index 734fefa5..3ea2a1ff 100644 --- a/packages/extension-chrome/src/pages/WalletManager/containers/RecoveryWallet.tsx +++ b/packages/extension-chrome/src/pages/WalletManager/containers/RecoveryWallet.tsx @@ -140,16 +140,16 @@ export const RecoveryWallet: FC = () => { }); return ( - <> + Access Wallet With Your Seed - + Nexus cannot recover your password. We will use your Seed to validate your ownership, restore your wallet and set up a new password. First, enter the Seed that you were given when you created your wallet. - + Type your Seed here @@ -157,7 +157,7 @@ export const RecoveryWallet: FC = () => { You can paste your entire Seed into any field - + {inputs} @@ -173,17 +173,13 @@ export const RecoveryWallet: FC = () => { ); return ( - <> - {hasInvalidWord && ( - - - Please check your Seed - - )} - + + + Please check your seed phrase + ); }} /> - + ); }; diff --git a/packages/extension-chrome/src/pages/WalletManager/index.tsx b/packages/extension-chrome/src/pages/WalletManager/index.tsx index 7a6411f1..3b067c77 100644 --- a/packages/extension-chrome/src/pages/WalletManager/index.tsx +++ b/packages/extension-chrome/src/pages/WalletManager/index.tsx @@ -44,12 +44,17 @@ const routeConfig: RouteObject[] = [ { path: 'account', title: 'Create a Username', description: 'Create a username' }, { path: 'password', title: 'Create Password', description: 'Choose a secure one' }, { path: 'seed', title: 'Generate Wallet Seed', description: 'Remember it!', displayOnly: true }, - { path: 'confirm', title: 'Confirm Seed', description: 'Confirm your seed' }, + { + path: 'confirm', + title: 'Confirm Seed', + description: 'Confirm your seed', + nextButtonText: 'Confirm', + disableBack: true, + }, ], entry: '/', exit: '/success', disableBackOnExit: true, - exitButtonText: 'Confirm', } as CreateFlowConfig; }, children: [ @@ -81,8 +86,13 @@ const routeConfig: RouteObject[] = [ path: 'seed', title: 'Confirm Seed', description: 'Confirm your wallet seed', + nextButtonText: 'Confirm', + }, + { + path: 'password', + title: 'Create Password', + description: 'Create a secure password', }, - { path: 'password', title: 'Create Password', description: 'Create a secure password' }, { path: 'account', title: 'Create Username', description: 'Create a username' }, ], entry: '/', diff --git a/packages/extension-chrome/src/pages/WalletManager/types.ts b/packages/extension-chrome/src/pages/WalletManager/types.ts index b2589b7e..e0af295f 100644 --- a/packages/extension-chrome/src/pages/WalletManager/types.ts +++ b/packages/extension-chrome/src/pages/WalletManager/types.ts @@ -2,6 +2,8 @@ export type StepConfig = { path: string; title: string; description?: string; + nextButtonText?: string; + disableBack?: boolean; /** * if true, the next page will only trigger the `onNext` callback, and outlet will not call `onNext` @@ -13,6 +15,4 @@ export type CreateFlowConfig = { steps: StepConfig[]; entry: string; exit: string; - disableBackOnExit?: boolean; - exitButtonText?: string; }; diff --git a/packages/extension-chrome/src/pages/theme/Alert.ts b/packages/extension-chrome/src/pages/theme/Alert.ts new file mode 100644 index 00000000..5d4ee7a6 --- /dev/null +++ b/packages/extension-chrome/src/pages/theme/Alert.ts @@ -0,0 +1,32 @@ +import { alertAnatomy } from '@chakra-ui/anatomy'; +import { createMultiStyleConfigHelpers, AlertProps } from '@chakra-ui/react'; + +const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(alertAnatomy.keys); + +const baseStyle = definePartsStyle(({ status }) => { + const color = { + error: 'error', + warning: 'warning', + info: 'info', + success: 'success', + loading: 'info', + }[status as NonNullable]; + return { + container: { + bg: `${color}.bg`, + }, + icon: { + color: `${color}.darker`, + }, + title: { + color: 'gray.900', + }, + description: { + color: 'gray.900', + }, + }; +}); + +export const Alert = defineMultiStyleConfig({ + baseStyle, +}); diff --git a/packages/extension-chrome/src/pages/theme/Button.ts b/packages/extension-chrome/src/pages/theme/Button.ts index e460a6db..8a82a016 100644 --- a/packages/extension-chrome/src/pages/theme/Button.ts +++ b/packages/extension-chrome/src/pages/theme/Button.ts @@ -39,6 +39,10 @@ const outline = defineStyle(({ colorScheme, theme }) => { bg: transparentize(colorScheme, 0.24)(theme), _disabled: { bg: 'transparent' }, }, + _selected: { + bg: transparentize(colorScheme, 0.24)(theme), + _disabled: { bg: 'transparent' }, + }, }; }); diff --git a/packages/extension-chrome/src/pages/theme/Input.ts b/packages/extension-chrome/src/pages/theme/Input.ts index 0a4cd795..c42297e7 100644 --- a/packages/extension-chrome/src/pages/theme/Input.ts +++ b/packages/extension-chrome/src/pages/theme/Input.ts @@ -1,28 +1,26 @@ import { inputAnatomy } from '@chakra-ui/anatomy'; import { createMultiStyleConfigHelpers } from '@chakra-ui/react'; -import { getColor } from '@chakra-ui/theme-tools'; +import { getColor } from './utils'; const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(inputAnatomy.keys); const primary = definePartsStyle(({ theme }) => ({ field: { color: 'black', - borderWidth: '2px', + borderWidth: '1px', + borderColor: 'gray.100', + + _hover: { + borderColor: 'gray.300', + }, + _invalid: { - borderColor: 'error.darker', + borderWidth: '2px', + borderColor: `${getColor(theme, 'error.darker')} !important`, }, _focusVisible: { borderWidth: '2px', borderColor: 'primary', - boxShadow: `0 0 0 1px ${getColor(theme, 'primary')}`, - _invalid: { - borderColor: 'error.darker', - }, - }, - }, - element: { - _invalid: { - color: 'error.darker', }, }, })); @@ -30,21 +28,18 @@ const primary = definePartsStyle(({ theme }) => ({ const accent = definePartsStyle(({ theme }) => ({ field: { color: 'black', - borderWidth: '2px', + borderWidth: '1px', + borderColor: 'white.300', + _hover: { + borderColor: 'white.700', + }, _invalid: { - borderColor: 'error.lighter', - _focus: { - borderColor: 'error.lighter', - }, + borderWidth: '2px', + borderColor: `${getColor(theme, 'error.lighter')} !important`, }, _focusVisible: { borderWidth: '2px', borderColor: 'accent', - boxShadow: `0 0 0 1px ${getColor(theme, 'accent')}`, - - _invalid: { - borderColor: 'error.lighter', - }, }, }, element: { @@ -55,5 +50,13 @@ const accent = definePartsStyle(({ theme }) => ({ })); export const Input = defineMultiStyleConfig({ + baseStyle: { + field: { + _placeholder: { + color: 'gray.400', + }, + color: 'gray.900', + }, + }, variants: { primary, accent }, }); diff --git a/packages/extension-chrome/src/pages/theme/Radio.ts b/packages/extension-chrome/src/pages/theme/Radio.ts index 5095a6ff..4ea1b5bb 100644 --- a/packages/extension-chrome/src/pages/theme/Radio.ts +++ b/packages/extension-chrome/src/pages/theme/Radio.ts @@ -8,8 +8,9 @@ export const Radio = defineMultiStyleConfig({ return { control: { color: colorScheme, - transition: 'border var(--chakra-transition-duration-normal)', - boxShadow: 'none !important', + transitionProperty: 'border', + transitionDuration: 'normal', + _checked: { borderColor: colorScheme, borderWidth, @@ -29,6 +30,11 @@ export const Radio = defineMultiStyleConfig({ }, }, }, + container: { + _disabled: { + opacity: 0.5, + }, + }, }; }), }); diff --git a/packages/extension-chrome/src/pages/theme/index.ts b/packages/extension-chrome/src/pages/theme/index.ts index a480c25d..0035956e 100644 --- a/packages/extension-chrome/src/pages/theme/index.ts +++ b/packages/extension-chrome/src/pages/theme/index.ts @@ -1,4 +1,5 @@ import { extendTheme, withDefaultColorScheme, withDefaultVariant } from '@chakra-ui/react'; +import { Alert } from './Alert'; import { Button } from './Button'; import { FormLabel } from './FormLabel'; import { Input } from './Input'; @@ -20,7 +21,7 @@ export const theme = extendTheme( 'primary.lighter': '#B794F4', 'primary.darker': '#553C9A', - 'info.darker': '#718096', + 'info.darker': '#3182CE', 'info.lighter': '#63B3ED', 'info.bg': '#BEE3F8', @@ -35,6 +36,28 @@ export const theme = extendTheme( 'success.darker': '#38A169', 'success.lighter': '#68D391', 'success.bg': '#C6F6D5', + + white: 'rgba(255, 255, 255, 1)', + 'white.900': 'rgba(255, 255, 255, 0.92)', + 'white.800': 'rgba(255, 255, 255, 0.80)', + 'white.700': 'rgba(255, 255, 255, 0.64)', + 'white.600': 'rgba(255, 255, 255, 0.48)', + 'white.500': 'rgba(255, 255, 255, 0.36)', + 'white.400': 'rgba(255, 255, 255, 0.24)', + 'white.300': 'rgba(255, 255, 255, 0.16)', + 'white.200': 'rgba(255, 255, 255, 0.08)', + 'white.100': 'rgba(255, 255, 255, 0.06)', + + 'gray.900': '#171923', + 'gray.800': '#1A202C', + 'gray.700': '#2D3748', + 'gray.600': '#4A5568', + 'gray.500': '#718096', + 'gray.400': '#A0AEC0', + 'gray.300': '#CBD5E0', + 'gray.200': '#E2E8F0', + 'gray.100': '#EDF2F7', + 'gray.50': '#F7FAFC', }, }, { @@ -43,6 +66,7 @@ export const theme = extendTheme( Radio: Radio, FormLabel: FormLabel, Input: Input, + Alert: Alert, }, }, withDefaultColorScheme({ diff --git a/packages/extension-chrome/src/pages/theme/utils.ts b/packages/extension-chrome/src/pages/theme/utils.ts new file mode 100644 index 00000000..b2ddc5b5 --- /dev/null +++ b/packages/extension-chrome/src/pages/theme/utils.ts @@ -0,0 +1,6 @@ +import { Dict } from '@chakra-ui/utils'; + +export function getColor(theme: Dict, color: string, defaultValue = '#000000'): string { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + return theme.colors[color] || defaultValue; +}