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'
|
2023-11-01 22:42:45 +01:00
|
|
|
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'
|
2023-11-01 20:17:24 +01:00
|
|
|
import { useFetchTokens } from '@features/Web3/hooks/useFetchTokens'
|
2023-11-01 16:31:29 +01:00
|
|
|
import { useStore } from '@nanostores/react'
|
2023-11-03 21:56:08 +01:00
|
|
|
import { $setTokens, $tokens } from '@features/Web3/stores'
|
2023-11-01 16:31:29 +01:00
|
|
|
import {
|
|
|
|
$selectedToken,
|
|
|
|
$setSelectedToken
|
|
|
|
} from '@features/Web3/stores/selectedToken'
|
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-03 21:56:08 +01:00
|
|
|
const { address } = useAccount()
|
2023-11-01 20:17:24 +01:00
|
|
|
const { isLoading } = useFetchTokens()
|
|
|
|
const tokens = useStore($tokens)
|
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) => (
|
|
|
|
<Token key={token.address} token={token} />
|
|
|
|
))
|
|
|
|
|
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-01 16:31:29 +01:00
|
|
|
$setSelectedToken(token)
|
2023-10-28 23:34:58 +02:00
|
|
|
}
|
|
|
|
|
2023-11-03 21:56:08 +01:00
|
|
|
// reset when no account connected
|
|
|
|
useEffect(() => {
|
|
|
|
if (!address && tokens?.length) {
|
|
|
|
$setTokens(undefined)
|
|
|
|
}
|
|
|
|
}, [address])
|
|
|
|
|
2023-11-03 00:33:06 +01:00
|
|
|
return tokens && selectedToken ? (
|
2023-10-28 13:55:30 +02:00
|
|
|
<Select.Root
|
2023-10-29 15:36:48 +01:00
|
|
|
defaultValue={selectedToken?.address}
|
2023-10-28 23:34:58 +02:00
|
|
|
onValueChange={(value: `0x${string}`) => handleValueChange(value)}
|
2023-11-01 20:17:24 +01:00
|
|
|
disabled={isLoading}
|
2023-10-28 13:55:30 +02:00
|
|
|
>
|
2023-10-28 19:01:36 +02:00
|
|
|
<Select.Trigger
|
|
|
|
className="SelectTrigger"
|
2023-11-01 20:17:24 +01:00
|
|
|
disabled={isLoading}
|
2023-10-28 19:01:36 +02:00
|
|
|
aria-label="Token"
|
|
|
|
>
|
2023-11-03 00:33:06 +01:00
|
|
|
<Select.Value />
|
2023-10-26 21:32:57 +02:00
|
|
|
<Select.Icon>
|
|
|
|
<ChevronDown />
|
|
|
|
</Select.Icon>
|
|
|
|
</Select.Trigger>
|
|
|
|
|
2023-11-01 23:16:02 +01:00
|
|
|
{/* @ts-expect-error-next-line: style actually is passed through and is needed in our case */}
|
2023-10-26 21:32:57 +02:00
|
|
|
<Select.Portal style={{ zIndex: 10 }}>
|
|
|
|
<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>
|
2023-10-28 13:55:30 +02:00
|
|
|
{items}
|
2023-10-26 21:32:57 +02:00
|
|
|
</Select.Group>
|
|
|
|
</Select.Viewport>
|
|
|
|
<Select.ScrollDownButton className="SelectScrollButton">
|
|
|
|
<ChevronsDown />
|
|
|
|
</Select.ScrollDownButton>
|
|
|
|
</Select.Content>
|
|
|
|
</Select.Portal>
|
|
|
|
</Select.Root>
|
2023-11-01 20:17:24 +01:00
|
|
|
) : isLoading ? (
|
2023-11-03 00:33:06 +01:00
|
|
|
<div className="Token">
|
|
|
|
<div className="TokenLogo TokenLoading">
|
|
|
|
<Loader />
|
2023-11-01 20:17:24 +01:00
|
|
|
</div>
|
2023-11-03 00:33:06 +01:00
|
|
|
</div>
|
2023-11-01 20:17:24 +01:00
|
|
|
) : null
|
2023-10-26 21:32:57 +02:00
|
|
|
}
|