Skip to content

Commit

Permalink
Finish token type picker
Browse files Browse the repository at this point in the history
Fix tailwind color issue
  • Loading branch information
jmrossy committed Dec 6, 2024
1 parent cdd1609 commit cd5f640
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/components/buttons/BackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function BackButton({ page, ...rest }: ComponentProps<typeof Button> & {

return (
<Button onClick={() => setPage(page)} {...rest} className="flex items-center gap-0.5">
<ArrowIcon direction="w" width={30} height={20} color={Color.accent} />
<ArrowIcon direction="w" width={30} height={20} color={Color.accent['500']} />
<span className="text-md text-accent-500">Back</span>
</Button>
);
Expand Down
4 changes: 2 additions & 2 deletions src/consts/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export const APP_NAME = 'Hyperlane Deploy';
export const APP_DESCRIPTION =
'A DApp to deploy Hyperlane contracts and applications, such as Warp Routes.';
export const APP_URL = 'TODO';
export const BRAND_COLOR = Color.primary;
export const BACKGROUND_COLOR = Color.primary;
export const BRAND_COLOR = Color.primary['500'];
export const BACKGROUND_COLOR = Color.primary['500'];
export const BACKGROUND_IMAGE = 'url(/backgrounds/main.svg)';
10 changes: 5 additions & 5 deletions src/features/chains/ChainSelectField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ export function ChainSelectField({ value, onChange }: Props) {
const { isOpen, close, open } = useModal();

return (
<div>
<FormButton onClick={open}>
<div className="flex-1 grow">
<FormButton onClick={open} className="w-full gap-2 bg-white">
<div className="flex items-center gap-3">
<div className="max-w-[1.4rem] sm:max-w-fit">
<ChainLogo chainName={value} size={32} />
<ChainLogo chainName={value} size={30} />
</div>
<div className="gap- flex flex-col items-start">
<label className="text-xs text-gray-600">Chain</label>
<label className="cursor-pointer text-xs text-gray-600">Chain</label>
{displayName}
</div>
</div>
<ChevronIcon width={12} height={8} direction="s" />
<ChevronIcon width={11} height={8} direction="s" />
</FormButton>
<ChainSelectListModal isOpen={isOpen} close={close} onSelect={onChange} />
</div>
Expand Down
101 changes: 83 additions & 18 deletions src/features/deployment/warp/TokenTypeSelectField.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,88 @@
import { TokenType } from '@hyperlane-xyz/sdk';
import { toTitleCase } from '@hyperlane-xyz/utils';
import { Button, Modal, useModal } from '@hyperlane-xyz/widgets';
import { Button, ChevronIcon, Modal, useModal } from '@hyperlane-xyz/widgets';
import { FormButton } from '../../../components/buttons/FormButton';

const TokenTypes = Object.values(TokenType);
const TokenTypes = Object.values(TokenType).sort();
const TokenTypeDescriptions: Record<TokenType, { label: string; description: string }> = {
[TokenType.collateral]: {
label: 'Collateral',
description: 'A lock-and-mint wrapper for ERC20 tokens.',
},
[TokenType.collateralFiat]: {
label: 'Collateral Fiat',
description: 'A lock-and-mint wrapper for the FiatToken standard by Circle.',
},
[TokenType.collateralUri]: {
label: 'Collateral NFT',
description: 'A lock-and-mint wrapper for ERC721 tokens.',
},
[TokenType.collateralVault]: {
label: 'Collateral Vault',
description:
'A lock-and-mint wrapper for ERC4626 vaults. Yields are manually claimed by owner.',
},
[TokenType.collateralVaultRebase]: {
label: 'Collateral Rebased Vault',
description: 'A lock-and-mint wrapper for ERC4626 vaults. Rebases yields to token holders.',
},
[TokenType.fastCollateral]: {
label: 'Fast Collateral',
description: 'A collateralized wrapper but with support for LP-provided faster transfers.',
},
[TokenType.fastSynthetic]: {
label: 'Fast Synthetic',
description: 'A synthetic HypErc20 token to pair with a Fast Collateral token.',
},
[TokenType.native]: {
label: 'Native',
description: 'A lock-and-mint wrapper for native currencies such as Ether (ETH).',
},
[TokenType.nativeScaled]: {
label: 'Fast Collateral',
description: 'A native type but with support for token decimal scaling.',
},
[TokenType.synthetic]: {
label: 'Synthetic',
description: 'A synthetic HypErc20 token to pair with any collateralized type.',
},
[TokenType.syntheticRebase]: {
label: 'Synthetic Rebased',
description: 'A synthetic HypErc20 token to pair with a Collateral Rebased Vault.',
},
[TokenType.syntheticUri]: {
label: 'Synthetic NFT',
description: 'A synthetic HypErc721 token to pair with a Collateral NFT.',
},
[TokenType.XERC20]: {
label: 'xERC20',
description: 'A lock-and-mint wrapper for xERC20 tokens.',
},
[TokenType.XERC20Lockbox]: {
label: 'xERC20 Lockbox',
description: 'A lock-and-mint wrapper for xERC20 Lockbox tokens.',
},
};

export function TokenTypeSelectField({
value,
onChange,
}: {
value: TokenType;
onChange: (t: TokenType) => void;
}) {
const { isOpen, close, open } = useModal();

const onClick = (t: TokenType) => {
onChange(t);
close();
};

return (
<div>
<div className="flex-1 grow">
<TokenTypeButton value={value} onClick={open} />
<Modal isOpen={isOpen} close={close} panelClassname="p-4 md:p-5 max-w-sm">
<Modal isOpen={isOpen} close={close} panelClassname="px-2 py-3 max-w-sm divide-y">
{TokenTypes.map((t, i) => (
<TokenTypeOption type={t} close={close} key={i} />
<TokenTypeOption type={t} onClick={onClick} key={i} />
))}
</Modal>
</div>
Expand All @@ -27,23 +91,24 @@ export function TokenTypeSelectField({

function TokenTypeButton({ value, onClick }: { value: TokenType; onClick: () => void }) {
return (
<FormButton onClick={onClick} className="flex-col">
<label htmlFor="tokenIndex" className="text-xs text-gray-600">
Token Type
</label>
<div>{toTitleCase(value)}</div>
<FormButton onClick={onClick} className="w-full gap-2 bg-white hover:bg-gray-100">
<div className="flex flex-col items-start">
<label className="cursor-pointer text-xs text-gray-600">Token Type</label>
<span>{TokenTypeDescriptions[value].label}</span>
</div>
<ChevronIcon width={11} height={8} direction="s" />
</FormButton>
);
}

function TokenTypeOption({ type, close }: { type: TokenType; close: () => void }) {
const onClick = () => {
close();
};

function TokenTypeOption({ type, onClick }: { type: TokenType; onClick: (t: TokenType) => void }) {
return (
<Button onClick={onClick} className="flex items-center gap-2 px-4 py-2">
{type}
<Button
onClick={() => onClick(type)}
className="flex w-full flex-col items-start gap-px rounded px-3 py-2 text-left hover:bg-gray-100 hover:opacity-100"
>
<h3 className="text-sm font-medium text-blue-500">{TokenTypeDescriptions[type].label}</h3>
<p className="text-xs text-gray-800">{TokenTypeDescriptions[type].description}</p>
</Button>
);
}
50 changes: 34 additions & 16 deletions src/features/deployment/warp/WarpDeploymentForm.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { arbitrum, ethereum } from '@hyperlane-xyz/registry';
import { TokenType } from '@hyperlane-xyz/sdk';
import { ProtocolType, errorToString } from '@hyperlane-xyz/utils';
import { AccountInfo, useAccounts } from '@hyperlane-xyz/widgets';
import { errorToString, ProtocolType } from '@hyperlane-xyz/utils';
import { AccountInfo, IconButton, useAccounts, XIcon } from '@hyperlane-xyz/widgets';
import { Form, Formik, useFormikContext } from 'formik';
import { BackButton } from '../../../components/buttons/BackButton';
import { ConnectAwareSubmitButton } from '../../../components/buttons/ConnectAwareSubmitButton';
import { H1 } from '../../../components/text/H1';
import { config } from '../../../consts/config';
import { CardPage } from '../../../flows/CardPage';
import { Stepper } from '../../../flows/Stepper';
import { Color } from '../../../styles/Color';
import { logger } from '../../../utils/logger';
import { ChainConnectionWarning } from '../../chains/ChainConnectionWarning';
import { ChainSelectField } from '../../chains/ChainSelectField';
Expand Down Expand Up @@ -77,7 +78,7 @@ function ConfigListSection() {
const { values } = useFormikContext<WarpDeploymentFormValues>();

return (
<div className="">
<div className="space-y-4">
{values.configs.map((config, index) => (
<ChainTokenConfig key={index} index={index} config={config} />
))}
Expand All @@ -95,20 +96,37 @@ function ChainTokenConfig({ config, index }: { config: WarpDeploymentConfigEntry
setValues({ configs: allConfigs });
};

const isRemoveDisabled = values.configs.length <= 2;

const onRemove = () => {
if (isRemoveDisabled) return;
const allConfigs = [...values.configs];
allConfigs.splice(index, 1);
setValues({ configs: allConfigs });
};

return (
<div className="mt-2 flex items-center justify-between gap-4">
<ChainSelectField
value={config.chainName}
onChange={(v) => {
onChange({ chainName: v });
}}
/>
<TokenTypeSelectField
value={config.tokenType}
onChange={(v) => {
onChange({ tokenType: v });
}}
/>
<div className="space-y-1.5 rounded-lg bg-blue-500/5 px-3 pb-3 pt-2">
<div className="flex justify-between">
<h3 className="pl-1 text-xs text-gray-700">{`Chain ${index + 1}`}</h3>
<IconButton title="Remove" onClick={onRemove} disabled={isRemoveDisabled}>
<XIcon width={8} height={8} color={Color.gray['500']} />
</IconButton>
</div>
<div className="flex items-center justify-stretch gap-6">
<ChainSelectField
value={config.chainName}
onChange={(v) => {
onChange({ chainName: v });
}}
/>
<TokenTypeSelectField
value={config.tokenType}
onChange={(v) => {
onChange({ tokenType: v });
}}
/>
</div>
</div>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/features/wallet/WalletFloatingButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ export function WalletFloatingButtons() {
title="History"
onClick={() => setIsSideBarOpen(!isSideBarOpen)}
>
<HistoryIcon color={Color.primary} height={20} width={20} />
<HistoryIcon color={Color.primary['500']} height={20} width={20} />
</IconButton>
<Link
href={links.warpDocs}
target="_blank"
className={`p-0.5 ${styles.roundedCircle} ${styles.link}`}
>
<DocsIcon color={Color.primary} height={19} width={19} className="p-px" />
<DocsIcon color={Color.primary['500']} height={19} width={19} className="p-px" />
</Link>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/features/wallet/context/EvmWalletContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function EvmWalletContext({ children }: PropsWithChildren<unknown>) {
<WagmiProvider config={wagmiConfig}>
<RainbowKitProvider
theme={lightTheme({
accentColor: Color.primary,
accentColor: Color.primary['500'],
borderRadius: 'small',
fontStack: 'system',
})}
Expand Down
9 changes: 4 additions & 5 deletions src/styles/Color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ const themeColors = theme.extend.colors as unknown as Record<string, string>;
export const Color = {
black: themeColors.black,
white: themeColors.white,
gray: themeColors.gray[500],
lightGray: themeColors.gray[200],
primary: themeColors.primary[500],
accent: themeColors.accent[500],
red: themeColors.red[500],
gray: themeColors.gray,
primary: themeColors.primary,
accent: themeColors.accent,
red: themeColors.red,
} as const;
3 changes: 2 additions & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** @type {import('tailwindcss').Config} */

const defaultTheme = require('tailwindcss/defaultTheme');
const defaultColors = require('tailwindcss/colors');

module.exports = {
content: ['./src/**/*.{js,ts,jsx,tsx}'],
Expand All @@ -19,7 +20,7 @@ module.exports = {
colors: {
black: '#010101',
white: '#ffffff',
gray: { ...defaultTheme.colors.gray, 150: '#EBEDF0', 250: '#404040', 350: '#6B6B6B' },
gray: { ...defaultColors.gray, '150': '#EBEDF0', '250': '#404040', '350': '#6B6B6B' },
primary: {
50: '#E6EDF9',
100: '#CDDCF4',
Expand Down

0 comments on commit cd5f640

Please sign in to comment.