Skip to content

Commit

Permalink
made token selection something pleasant in Swap with Radix
Browse files Browse the repository at this point in the history
  • Loading branch information
dredshep committed Apr 3, 2024
1 parent 96323d1 commit 0d8c114
Show file tree
Hide file tree
Showing 34 changed files with 496 additions and 204 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions components/app/UserWallet.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// UserWallet.tsx
import React from "react";
import { RxCaretDown } from "react-icons/rx";
import PlaceholderFromHexAddress from "@/components/app/molecules/PlaceholderFromHexAddress";
import PlaceholderImageFromSeed from "@/components/app/molecules/PlaceholderImageFromSeed";
import { SecretString } from "@/types";

interface UserWalletProps {
Expand All @@ -27,7 +27,7 @@ const UserWallet: React.FC<UserWalletProps> = ({
{isConnected ? (
<>
<div className="relative">
<PlaceholderFromHexAddress userAddress={userAddress} size={48} />
<PlaceholderImageFromSeed seed={userAddress} size={48} />
</div>
<div>
<div className="hidden md:flex font-medium items-center gap-2">
Expand Down
11 changes: 11 additions & 0 deletions components/app/atoms/Swap/MaxButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const MaxButton = ({ onClick }: { onClick: () => void }) => {
return (
<button
className="bg-adamant-app-input text-sm font-bold text-white px-4"
onClick={onClick}
>
MAX
</button>
);
};
export default MaxButton;
11 changes: 11 additions & 0 deletions components/app/atoms/Swap/TokenInput/InputBalanceAffordance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function InputBalanceAffordance({
balance,
}: {
balance: number;
}) {
return (
<div className="flex items-center px-4 bg-adamant-app-input text-sm font-bold text-gray-500">
{balance.toFixed(2)}
</div>
);
}
16 changes: 16 additions & 0 deletions components/app/atoms/Swap/TokenInputBaseInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export default function TokenInputBaseInput({
amount,
handleChange,
}: {
amount: string;
handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}) {
return (
<input
className="rounded-l-xl text-2xl font-bold py-2 px-[21px] bg-adamant-app-input w-full"
placeholder="0.0"
value={amount}
onChange={handleChange}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
/* <div className="flex justify-between items-center px-6">
<h2 className="text-lg leading-[21px]">Select a token</h2>
<X onClick={onClose} className="cursor-pointer text-gray-400 w-4" />
</div> */
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { FaSearch } from "react-icons/fa";

export default function TokenSelectionSearchBar({
searchTerm,
setSearchTerm,
}: {
searchTerm: string;
setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
}) {
return (
<div className="mt-6 px-6">
<div className="flex items-center bg-adamant-app-input h-12 px-4 rounded-xl">
<FaSearch className="h-[18px] w-[18px] text-white text-opacity-25" />
<input
type="text"
placeholder="Search or paste a token address"
className="bg-transparent p-2 w-full focus:outline-none text-base placeholder-white placeholder-opacity-25"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
</div>
);
}
33 changes: 0 additions & 33 deletions components/app/molecules/PlaceholderFromHexAddress.tsx

This file was deleted.

31 changes: 31 additions & 0 deletions components/app/molecules/PlaceholderImageFromSeed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";
import ImageWithPlaceholder from "@/components/app/ImageWithPlaceholder";
import { SecretString } from "@/types";
import generateHexColorsFromSeed from "@/utils/ImageWithPlaceholder/generateHexColorsFromSeed";

interface PlaceholderImageFromSeedProps {
seed: SecretString;
size?: number;
}

const PlaceholderImageFromSeed: React.FC<PlaceholderImageFromSeedProps> = ({
seed,
size = 48,
}) => {
const [color1, color2, color3] = generateHexColorsFromSeed(seed, 3);
const colorQueryString = `shape1Color=${color1}&shape2Color=${color2}&shape3Color=${color3}`;
const placeholderUrl = `https://api.dicebear.com/6.x/shapes/svg?seed=${seed}&height=${size}&width=${size}&${colorQueryString}`;

return (
<ImageWithPlaceholder
imageUrl={placeholderUrl}
placeholderUrl={placeholderUrl}
index={1}
length={2}
alt="Avatar"
size={size}
/>
);
};

export default PlaceholderImageFromSeed;
100 changes: 0 additions & 100 deletions components/app/molecules/TokenInput.tsx

This file was deleted.

32 changes: 32 additions & 0 deletions components/app/molecules/TokenSelectionItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Token } from "@/types";
import PlaceholderImageFromSeed from "@/components/app/molecules/PlaceholderImageFromSeed";
import * as Dialog from "@radix-ui/react-dialog";

interface TokenSelectionItemProps {
token: Token;
network: string; // Assuming you can provide network information
balance: string; // Assuming you have balance information as a string
handleTokenSelect: (token: Token) => void;
}

const TokenSelectionItem: React.FC<TokenSelectionItemProps> = ({
token,
network,
balance,
handleTokenSelect,
}) => {
return (
<Dialog.Close onClick={() => handleTokenSelect(token)} asChild>
<div className="flex justify-between items-center cursor-pointer hover:bg-adamant-app-boxHighlight py-2 rounded-xl mx-2 px-6">
<PlaceholderImageFromSeed seed={token.address} size={40} />
<div className="flex-grow ml-3 flex flex-col">
<span className="font-bold">{token.symbol}</span>
<span className="text-gray-500 text-xs font-medium">{network}</span>
</div>
<span className="font-medium">{balance}</span>
</div>
</Dialog.Close>
);
};

export default TokenSelectionItem;
2 changes: 1 addition & 1 deletion components/app/organisms/SwapForm/SwapForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import InputLabel from "@/components/app/atoms/InputLabel";
import TokenInput from "@/components/app/molecules/TokenInput";
import TokenInput from "@/components/app/organisms/SwapForm/TokenInput";
import SwapButton from "@/components/app/atoms/SwapButton";
import { useStore } from "@/store/swapStore"; // Ensure this path matches the location of your store
import DynamicField from "@/components/app/molecules/DynamicField";
Expand Down
66 changes: 66 additions & 0 deletions components/app/organisms/SwapForm/TokenInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from "react";
import { useStore } from "@/store/swapStore";
import PlaceholderImageFromSeed from "../../molecules/PlaceholderImageFromSeed";
import { RxCaretDown } from "react-icons/rx";
import { TokenInputs } from "@/types";
import TokenSelectionModal from "./TokenSelectionModalRadix";
import MaxButton from "../../atoms/Swap/MaxButton";
import TokenInputBaseInput from "../../atoms/Swap/TokenInputBaseInput";
import InputBalanceAffordance from "../../atoms/Swap/TokenInput/InputBalanceAffordance";
import * as Dialog from "@radix-ui/react-dialog";

interface TokenInputProps {
inputIdentifier: keyof TokenInputs;
maxable?: boolean;
balance: number;
}

const TokenInput: React.FC<TokenInputProps> = ({
inputIdentifier,
maxable = false,
balance,
}) => {
const { tokenInputs, setTokenInputProperty } = useStore();
const { token, amount } = tokenInputs[inputIdentifier];
const [isModalOpen, setIsModalOpen] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
const numValue = parseFloat(value);

if (!isNaN(numValue) && numValue >= 0 && numValue <= balance) {
setTokenInputProperty(inputIdentifier, "amount", value);
} else if (value === "") {
setTokenInputProperty(inputIdentifier, "amount", "");
}
};

const handleMax = () => {
setTokenInputProperty(inputIdentifier, "amount", balance.toString());
};

return (
<Dialog.Root>
<div className="flex">
<TokenInputBaseInput amount={amount} handleChange={handleChange} />
<InputBalanceAffordance balance={balance} />
{maxable && <MaxButton onClick={handleMax} />}
<Dialog.Trigger asChild>
<div className="flex gap-3 items-center rounded-r-xl text-sm font-bold py-3 px-4 bg-adamant-app-selectTrigger min-w-48 cursor-pointer">
<PlaceholderImageFromSeed seed={token.address} size={24} />
{token.symbol}
<RxCaretDown className="text-white h-5 w-5 ml-auto" />
</div>
</Dialog.Trigger>
</div>
<TokenSelectionModal
inputIdentifier={inputIdentifier}
isOpen={isModalOpen}
onClose={() => {
setIsModalOpen(false);
}}
/>
</Dialog.Root>
);
};

export default TokenInput;
Loading

0 comments on commit 0d8c114

Please sign in to comment.