1
0
Fork 0
blog/src/features/Web3/components/TokenSelect/TokenSelect.tsx

80 lines
2.5 KiB
TypeScript
Raw Normal View History

2023-10-26 21:32:57 +02:00
import * as Select from '@radix-ui/react-select'
2023-10-28 13:55:30 +02:00
import './TokenSelect.css'
import { Token } from './Token'
import { Icon as ChevronDown } from '@images/components/react/ChevronDown'
import { Icon as ChevronsDown } from '@images/components/react/ChevronsDown'
import { Icon as ChevronsUp } from '@images/components/react/ChevronsUp'
import { useFetchTokens } from '@features/Web3/hooks/useFetchTokens'
2023-11-01 16:31:29 +01:00
import { useStore } from '@nanostores/react'
2024-03-12 20:51:45 +01:00
import { $selectedToken } from '@features/Web3/stores'
2023-11-03 00:33:06 +01:00
import { Loader } from '@components/Loader'
2023-11-03 21:56:08 +01:00
import { useAccount } from 'wagmi'
import { useEffect } from 'react'
2023-10-26 21:32:57 +02:00
2023-10-29 23:51:31 +01:00
export function TokenSelect() {
2023-11-05 11:23:06 +01:00
const { address } = useAccount()
2023-11-05 16:31:09 +01:00
const { data: tokens, isLoading } = useFetchTokens()
2023-11-01 16:31:29 +01:00
const selectedToken = useStore($selectedToken)
2023-10-30 20:37:33 +01:00
2023-10-28 13:55:30 +02:00
const items = tokens?.map((token) => (
2024-03-14 14:18:21 +01:00
<Token key={`${token.address}-${token.chainId}`} token={token} />
2023-10-28 13:55:30 +02:00
))
2023-10-28 23:34:58 +02:00
function handleValueChange(value: `0x${string}`) {
const token = tokens?.find((token) => token.address === value)
if (!token) return
2023-11-05 19:57:53 +01:00
2024-03-12 20:51:45 +01:00
$selectedToken.set(token)
2023-10-28 23:34:58 +02:00
}
2023-11-04 01:36:16 +01:00
// Auto-select native token
2023-11-05 16:31:09 +01:00
// when no selection was made yet
2023-11-04 01:36:16 +01:00
useEffect(() => {
2023-11-05 16:31:09 +01:00
if (selectedToken?.address || !tokens || !tokens?.length) return
2023-11-05 11:23:06 +01:00
2024-03-14 14:18:21 +01:00
// select ETH mainnet token
handleValueChange('0x0-1')
2023-11-05 11:23:06 +01:00
}, [tokens, selectedToken])
2023-11-04 01:36:16 +01:00
2023-11-05 16:31:09 +01:00
return tokens && address ? (
2023-10-28 13:55:30 +02:00
<Select.Root
2023-11-05 16:31:09 +01:00
value={selectedToken?.address}
2023-10-28 23:34:58 +02:00
onValueChange={(value: `0x${string}`) => handleValueChange(value)}
disabled={isLoading}
2024-03-12 22:20:40 +01:00
name="selectedToken"
2023-10-28 13:55:30 +02:00
>
2023-10-28 19:01:36 +02:00
<Select.Trigger
className="SelectTrigger"
disabled={isLoading}
2023-10-28 19:01:36 +02:00
aria-label="Token"
>
2023-11-05 11:23:06 +01:00
<Select.Value placeholder="..." />
2023-10-26 21:32:57 +02:00
<Select.Icon>
<ChevronDown />
</Select.Icon>
</Select.Trigger>
2024-03-12 22:20:40 +01:00
<Select.Content className="SelectContent">
<Select.ScrollUpButton className="SelectScrollButton">
<ChevronsUp />
</Select.ScrollUpButton>
<Select.Viewport className="SelectViewport">
<Select.Group>
<Select.Label className="SelectLabel">In Your Wallet</Select.Label>
{items}
</Select.Group>
</Select.Viewport>
<Select.ScrollDownButton className="SelectScrollButton">
<ChevronsDown />
</Select.ScrollDownButton>
</Select.Content>
2023-10-26 21:32:57 +02:00
</Select.Root>
) : isLoading ? (
2023-11-03 00:33:06 +01:00
<div className="Token">
<div className="TokenLogo TokenLoading">
<Loader />
</div>
2023-11-03 00:33:06 +01:00
</div>
) : null
2023-10-26 21:32:57 +02:00
}