2022-02-17 19:32:48 -08:00
|
|
|
import { Fragment, useCallback, useMemo, useRef, useState } from 'react'
|
2022-02-07 02:28:36 -08:00
|
|
|
import useMangoGroupConfig from '../hooks/useMangoGroupConfig'
|
|
|
|
import { Popover, Transition } from '@headlessui/react'
|
2022-02-19 01:11:29 -08:00
|
|
|
import { SearchIcon } from '@heroicons/react/outline'
|
|
|
|
import { ChevronDownIcon } from '@heroicons/react/solid'
|
2022-02-07 02:28:36 -08:00
|
|
|
import Input from './Input'
|
|
|
|
import { useTranslation } from 'next-i18next'
|
2022-02-09 02:55:54 -08:00
|
|
|
import MarketNavItem from './MarketNavItem'
|
2022-02-18 14:24:06 -08:00
|
|
|
import useMangoStore from '../stores/useMangoStore'
|
2022-02-07 02:28:36 -08:00
|
|
|
|
|
|
|
const SwitchMarketDropdown = () => {
|
|
|
|
const groupConfig = useMangoGroupConfig()
|
2022-02-18 14:24:06 -08:00
|
|
|
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
|
|
|
const baseSymbol = marketConfig.baseSymbol
|
|
|
|
const isPerpMarket = marketConfig.kind === 'perp'
|
|
|
|
|
2022-02-17 19:32:48 -08:00
|
|
|
const markets = useMemo(
|
|
|
|
() => [...groupConfig.spotMarkets, ...groupConfig.perpMarkets],
|
|
|
|
[groupConfig]
|
2022-02-09 02:55:54 -08:00
|
|
|
)
|
2022-02-17 19:32:48 -08:00
|
|
|
const spotMarkets = useMemo(
|
|
|
|
() =>
|
|
|
|
[...groupConfig.spotMarkets].sort((a, b) => a.name.localeCompare(b.name)),
|
|
|
|
[groupConfig]
|
|
|
|
)
|
|
|
|
const perpMarkets = useMemo(
|
|
|
|
() =>
|
|
|
|
[...groupConfig.perpMarkets].sort((a, b) => a.name.localeCompare(b.name)),
|
|
|
|
[groupConfig]
|
2022-02-09 02:55:54 -08:00
|
|
|
)
|
2022-02-17 19:32:48 -08:00
|
|
|
|
2022-02-07 02:28:36 -08:00
|
|
|
const [suggestions, setSuggestions] = useState([])
|
|
|
|
const [searchString, setSearchString] = useState('')
|
|
|
|
const buttonRef = useRef(null)
|
|
|
|
const { t } = useTranslation('common')
|
|
|
|
const filteredMarkets = markets
|
|
|
|
.filter((m) => m.name.toLowerCase().includes(searchString.toLowerCase()))
|
|
|
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
|
|
|
|
|
|
const onSearch = (searchString) => {
|
|
|
|
if (searchString.length > 0) {
|
|
|
|
const newSuggestions = suggestions.filter((v) =>
|
|
|
|
v.name.toLowerCase().includes(searchString.toLowerCase())
|
|
|
|
)
|
|
|
|
setSuggestions(newSuggestions)
|
|
|
|
}
|
|
|
|
setSearchString(searchString)
|
|
|
|
}
|
|
|
|
|
|
|
|
const callbackRef = useCallback((inputElement) => {
|
|
|
|
if (inputElement) {
|
|
|
|
const timer = setTimeout(() => inputElement.focus(), 200)
|
|
|
|
return () => clearTimeout(timer)
|
|
|
|
}
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Popover>
|
|
|
|
{({ open }) => (
|
2022-02-18 14:24:06 -08:00
|
|
|
<div className="flex flex-col relative">
|
2022-02-07 02:28:36 -08:00
|
|
|
<Popover.Button
|
2022-02-21 16:16:20 -08:00
|
|
|
className={`border border-th-bkg-4 p-0.5 hover:border-th-fgd-4 focus:outline-none focus:border-th-fgd-4 ${
|
|
|
|
open && 'border-th-fgd-4'
|
2022-02-07 02:28:36 -08:00
|
|
|
}`}
|
|
|
|
ref={buttonRef}
|
|
|
|
>
|
2022-02-19 01:11:29 -08:00
|
|
|
<div className="flex items-center pl-2">
|
2022-02-18 14:24:06 -08:00
|
|
|
<img
|
|
|
|
alt=""
|
|
|
|
width="24"
|
|
|
|
height="24"
|
|
|
|
src={`/assets/icons/${baseSymbol.toLowerCase()}.svg`}
|
|
|
|
className={`mr-2.5`}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<div className="font-semibold pr-0.5 text-xl">{baseSymbol}</div>
|
|
|
|
<span className="text-th-fgd-4 text-xl">
|
|
|
|
{isPerpMarket ? '-' : '/'}
|
|
|
|
</span>
|
|
|
|
<div className="font-semibold pl-0.5 text-xl">
|
|
|
|
{isPerpMarket ? 'PERP' : groupConfig.quoteSymbol}
|
|
|
|
</div>
|
|
|
|
<div
|
2022-02-19 01:11:29 -08:00
|
|
|
className={`flex h-10 items-center justify-center rounded-none w-8`}
|
2022-02-18 14:24:06 -08:00
|
|
|
>
|
2022-02-19 01:11:29 -08:00
|
|
|
<ChevronDownIcon
|
|
|
|
className={`default-transition h-6 w-6 ${
|
|
|
|
open ? 'transform rotate-180' : 'transform rotate-360'
|
|
|
|
}`}
|
|
|
|
/>
|
2022-02-18 14:24:06 -08:00
|
|
|
</div>
|
2022-02-07 02:28:36 -08:00
|
|
|
</div>
|
|
|
|
</Popover.Button>
|
|
|
|
<Transition
|
|
|
|
appear={true}
|
|
|
|
show={open}
|
|
|
|
as={Fragment}
|
|
|
|
enter="transition-all ease-in duration-200"
|
|
|
|
enterFrom="opacity-0 transform scale-75"
|
|
|
|
enterTo="opacity-100 transform scale-100"
|
|
|
|
leave="transition ease-out duration-200"
|
|
|
|
leaveFrom="opacity-100"
|
|
|
|
leaveTo="opacity-0"
|
|
|
|
>
|
|
|
|
<Popover.Panel
|
2022-02-19 01:11:29 -08:00
|
|
|
className="absolute bg-th-bkg-3 max-h-96 overflow-y-auto p-4 left-0 transform rounded-b-md rounded-tl-md thin-scroll top-14 w-72 z-10"
|
2022-02-07 02:28:36 -08:00
|
|
|
static
|
|
|
|
>
|
|
|
|
<div className="pb-2.5">
|
|
|
|
<Input
|
|
|
|
onChange={(e) => onSearch(e.target.value)}
|
|
|
|
prefix={<SearchIcon className="h-4 text-th-fgd-3 w-4" />}
|
|
|
|
ref={callbackRef}
|
|
|
|
type="text"
|
|
|
|
value={searchString}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
{searchString.length > 0 ? (
|
2022-02-18 14:24:06 -08:00
|
|
|
<div className="pt-1.5">
|
2022-02-07 02:57:30 -08:00
|
|
|
{filteredMarkets.length > 0 ? (
|
|
|
|
filteredMarkets.map((mkt) => (
|
2022-02-09 02:55:54 -08:00
|
|
|
<MarketNavItem
|
|
|
|
buttonRef={buttonRef}
|
2022-02-17 19:32:48 -08:00
|
|
|
onClick={() => setSearchString('')}
|
2022-02-09 02:55:54 -08:00
|
|
|
market={mkt}
|
|
|
|
key={mkt.name}
|
|
|
|
/>
|
2022-02-07 02:57:30 -08:00
|
|
|
))
|
|
|
|
) : (
|
|
|
|
<p className="mb-0 text-center">{t('no-markets')}</p>
|
|
|
|
)}
|
2022-02-07 02:28:36 -08:00
|
|
|
</div>
|
|
|
|
) : (
|
2022-02-18 14:24:06 -08:00
|
|
|
<div className="">
|
|
|
|
<div className="flex justify-between py-1.5">
|
|
|
|
<h4 className="text-xs">{t('perp')}</h4>
|
2022-02-09 02:55:54 -08:00
|
|
|
<p className="mb-0 text-th-fgd-4 text-xs">
|
2022-02-19 13:47:39 -08:00
|
|
|
{/* {t('rolling-change')} */}
|
2022-02-09 02:55:54 -08:00
|
|
|
</p>
|
|
|
|
</div>
|
2022-02-18 14:24:06 -08:00
|
|
|
{perpMarkets.map((mkt) => (
|
2022-02-09 02:55:54 -08:00
|
|
|
<MarketNavItem
|
|
|
|
buttonRef={buttonRef}
|
2022-02-17 19:32:48 -08:00
|
|
|
onClick={() => setSearchString('')}
|
2022-02-09 02:55:54 -08:00
|
|
|
market={mkt}
|
|
|
|
key={mkt.name}
|
|
|
|
/>
|
|
|
|
))}
|
2022-02-18 14:24:06 -08:00
|
|
|
<div className="flex justify-between py-1.5">
|
|
|
|
<h4 className="text-xs">{t('spot')}</h4>
|
2022-02-09 02:55:54 -08:00
|
|
|
<p className="mb-0 text-th-fgd-4 text-xs">
|
2022-02-19 13:47:39 -08:00
|
|
|
{/* {t('rolling-change')} */}
|
2022-02-09 02:55:54 -08:00
|
|
|
</p>
|
|
|
|
</div>
|
2022-02-18 14:24:06 -08:00
|
|
|
{spotMarkets.map((mkt) => (
|
2022-02-09 02:55:54 -08:00
|
|
|
<MarketNavItem
|
|
|
|
buttonRef={buttonRef}
|
2022-02-17 19:32:48 -08:00
|
|
|
onClick={() => setSearchString('')}
|
2022-02-09 02:55:54 -08:00
|
|
|
market={mkt}
|
|
|
|
key={mkt.name}
|
|
|
|
/>
|
|
|
|
))}
|
2022-02-07 02:28:36 -08:00
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</Popover.Panel>
|
|
|
|
</Transition>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</Popover>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default SwitchMarketDropdown
|