Merge pull request #104 from blockworks-foundation/focus-states

add focus states and improve keyboard navigation
This commit is contained in:
saml33 2023-04-18 09:33:17 +10:00 committed by GitHub
commit 489a057acb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 545 additions and 600 deletions

View File

@ -25,7 +25,7 @@ const AccountsButton = () => {
return (
<>
<button
className="hidden h-16 border-l border-th-bkg-3 px-4 md:block"
className="hidden h-16 border-l border-th-bkg-3 px-4 focus:bg-th-bkg-3 md:block"
id="account-step-two"
onClick={handleShowAccounts}
>

View File

@ -3,13 +3,11 @@ import {
ArrowLeftIcon,
ArrowUpLeftIcon,
ArrowUpTrayIcon,
ChevronDownIcon,
ExclamationCircleIcon,
LinkIcon,
} from '@heroicons/react/20/solid'
import Decimal from 'decimal.js'
import { useTranslation } from 'next-i18next'
import Image from 'next/legacy/image'
import React, { useCallback, useMemo, useState } from 'react'
import NumberFormat, {
NumberFormatValues,
@ -44,12 +42,16 @@ import { floorToDecimal } from 'utils/numbers'
import BankAmountWithValue from './shared/BankAmountWithValue'
import useBanksWithBalances from 'hooks/useBanksWithBalances'
import { isMangoError } from 'types'
import TokenListButton from './shared/TokenListButton'
interface BorrowFormProps {
onSuccess: () => void
token?: string
}
export const ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES =
'default-transition w-full rounded-lg rounded-l-none border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-xl text-th-fgd-1 focus:border-th-fgd-4 focus:outline-none md:hover:border-th-input-border-hover md:hover:focus:border-th-fgd-4'
function BorrowForm({ onSuccess, token }: BorrowFormProps) {
const { t } = useTranslation('common')
const { group } = useMangoGroup()
@ -181,12 +183,7 @@ function BorrowForm({ onSuccess, token }: BorrowFormProps) {
className="absolute bottom-0 left-0 z-20 h-full w-full overflow-auto rounded-lg bg-th-bkg-1 p-6"
show={showTokenList}
>
<button
onClick={() => setShowTokenList(false)}
className={`absolute left-4 top-4 z-40 w-6 text-th-fgd-4 focus:outline-none md:right-2 md:top-2 md:hover:text-th-active`}
>
<ArrowLeftIcon className={`h-6 w-6`} />
</button>
<BackButton onClick={() => setShowTokenList(false)} />
<h2 className="mb-4 text-center text-lg">{t('select-borrow-token')}</h2>
<div className="flex items-center px-4 pb-2">
<div className="w-1/4">
@ -234,26 +231,12 @@ function BorrowForm({ onSuccess, token }: BorrowFormProps) {
/>
) : null}
</div>
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-input-border bg-th-input-bkg">
<button
onClick={() => setShowTokenList(true)}
className="default-transition flex h-full w-full items-center rounded-lg rounded-r-none py-2 px-3 text-th-fgd-2 hover:cursor-pointer hover:bg-th-bkg-2 hover:text-th-fgd-1"
>
<div className="mr-2.5 flex min-w-[24px] items-center">
<Image
alt=""
width="24"
height="24"
src={
logoUri || `/icons/${selectedToken.toLowerCase()}.svg`
}
/>
</div>
<div className="flex w-full items-center justify-between">
<div className="text-xl font-bold">{selectedToken}</div>
<ChevronDownIcon className="h-6 w-6" />
</div>
</button>
<div className="col-span-1">
<TokenListButton
token={selectedToken}
logoUri={logoUri}
setShowList={setShowTokenList}
/>
</div>
<div className="col-span-1">
<NumberFormat
@ -264,7 +247,7 @@ function BorrowForm({ onSuccess, token }: BorrowFormProps) {
allowNegative={false}
isNumericString={true}
decimalScale={bank?.mintDecimals || 6}
className="w-full rounded-lg rounded-l-none border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-xl text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover"
className={ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES}
placeholder="0.00"
value={inputAmount}
onValueChange={handleInputChange}
@ -395,3 +378,14 @@ function BorrowForm({ onSuccess, token }: BorrowFormProps) {
}
export default BorrowForm
export const BackButton = ({ onClick }: { onClick: (x: boolean) => void }) => {
return (
<button
onClick={() => onClick(false)}
className="absolute left-4 top-4 z-40 w-6 text-th-fgd-4 focus:text-th-active focus:outline-none md:right-2 md:top-2 md:hover:text-th-active"
>
<ArrowLeftIcon className={`h-6 w-6`} />
</button>
)
}

View File

@ -1,13 +1,10 @@
import {
ArrowDownTrayIcon,
ArrowLeftIcon,
ChevronDownIcon,
ExclamationCircleIcon,
LinkIcon,
} from '@heroicons/react/20/solid'
import { useWallet } from '@solana/wallet-adapter-react'
import { useTranslation } from 'next-i18next'
import Image from 'next/legacy/image'
import React, { useCallback, useMemo, useState } from 'react'
import NumberFormat, { NumberFormatValues } from 'react-number-format'
import mangoStore from '@store/mangoStore'
@ -37,6 +34,8 @@ import { floorToDecimal } from 'utils/numbers'
import BankAmountWithValue from './shared/BankAmountWithValue'
import useBanksWithBalances from 'hooks/useBanksWithBalances'
import { isMangoError } from 'types'
import TokenListButton from './shared/TokenListButton'
import { ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES, BackButton } from './BorrowForm'
interface DepositFormProps {
onSuccess: () => void
@ -172,12 +171,7 @@ function DepositForm({ onSuccess, token }: DepositFormProps) {
className="absolute bottom-0 left-0 z-20 h-full w-full overflow-auto rounded-lg bg-th-bkg-1 p-6"
show={showTokenList}
>
<button
onClick={() => setShowTokenList(false)}
className={`absolute left-4 top-4 z-40 w-6 text-th-fgd-4 focus:outline-none md:right-2 md:top-2 md:hover:text-th-active`}
>
<ArrowLeftIcon className={`h-6 w-6`} />
</button>
<BackButton onClick={() => setShowTokenList(false)} />
<h2 className="mb-4 text-center text-lg">
{t('select-deposit-token')}
</h2>
@ -222,26 +216,12 @@ function DepositForm({ onSuccess, token }: DepositFormProps) {
value={tokenMax.maxAmount}
/>
</div>
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-input-border bg-th-input-bkg">
<button
onClick={() => setShowTokenList(true)}
className="default-transition flex h-full w-full items-center rounded-lg rounded-r-none py-2 px-3 text-th-fgd-2 hover:cursor-pointer hover:bg-th-bkg-2 hover:text-th-fgd-1"
>
<div className="mr-2.5 flex min-w-[24px] items-center">
<Image
alt=""
width="24"
height="24"
src={
logoUri || `/icons/${selectedToken.toLowerCase()}.svg`
}
/>
</div>
<div className="flex w-full items-center justify-between">
<div className="text-xl font-bold">{selectedToken}</div>
<ChevronDownIcon className="h-6 w-6" />
</div>
</button>
<div className="col-span-1">
<TokenListButton
token={selectedToken}
logoUri={logoUri}
setShowList={setShowTokenList}
/>
</div>
<div className="col-span-1">
<NumberFormat
@ -252,7 +232,7 @@ function DepositForm({ onSuccess, token }: DepositFormProps) {
allowNegative={false}
isNumericString={true}
decimalScale={bank?.mintDecimals || 6}
className="w-full rounded-lg rounded-l-none border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-xl text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover"
className={ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES}
placeholder="0.00"
value={inputAmount}
onValueChange={(e: NumberFormatValues) => {

View File

@ -90,7 +90,7 @@ const Layout = ({ children }: { children: ReactNode }) => {
<div className="fixed z-20 hidden h-screen md:block">
<button
className="default-transition absolute right-0 top-1/2 z-20 hidden h-8 w-3 -translate-y-1/2 rounded-none rounded-l bg-th-bkg-4 hover:bg-th-bkg-4 focus:outline-none lg:block"
className="default-transition absolute right-0 top-1/2 z-20 hidden h-8 w-3 -translate-y-1/2 rounded-none rounded-l bg-th-bkg-3 hover:bg-th-bkg-4 focus:bg-th-bkg-4 focus:outline-none lg:block"
onClick={handleToggleSidebar}
>
<ChevronRightIcon

View File

@ -1,14 +1,10 @@
import {
ArrowDownRightIcon,
ArrowLeftIcon,
ChevronDownIcon,
ExclamationCircleIcon,
QuestionMarkCircleIcon,
} from '@heroicons/react/20/solid'
import { useWallet } from '@solana/wallet-adapter-react'
import Decimal from 'decimal.js'
import { useTranslation } from 'next-i18next'
import Image from 'next/legacy/image'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import NumberFormat, { NumberFormatValues } from 'react-number-format'
import mangoStore from '@store/mangoStore'
@ -35,6 +31,8 @@ import ConnectEmptyState from './shared/ConnectEmptyState'
import BankAmountWithValue from './shared/BankAmountWithValue'
import useBanksWithBalances from 'hooks/useBanksWithBalances'
import { isMangoError } from 'types'
import TokenListButton from './shared/TokenListButton'
import { ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES, BackButton } from './BorrowForm'
interface RepayFormProps {
onSuccess: () => void
@ -187,12 +185,7 @@ function RepayForm({ onSuccess, token }: RepayFormProps) {
className="absolute bottom-0 left-0 z-20 h-full w-full overflow-auto rounded-lg bg-th-bkg-1 p-6"
show={showTokenList}
>
<button
onClick={() => setShowTokenList(false)}
className={`absolute left-4 top-4 z-40 w-6 text-th-fgd-4 focus:outline-none md:right-2 md:top-2 md:hover:text-th-active`}
>
<ArrowLeftIcon className={`h-6 w-6`} />
</button>
<BackButton onClick={() => setShowTokenList(false)} />
<h2 className="mb-4 text-center text-lg">{t('select-repay-token')}</h2>
<div className="flex items-center px-4 pb-2">
<div className="w-1/2 text-left">
@ -233,23 +226,12 @@ function RepayForm({ onSuccess, token }: RepayFormProps) {
/>
) : null}
</div>
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-input-border bg-th-input-bkg">
<button
onClick={() => setShowTokenList(true)}
className="default-transition flex h-full w-full items-center rounded-lg rounded-r-none py-2 px-3 text-th-fgd-2 hover:cursor-pointer hover:bg-th-bkg-2 hover:text-th-fgd-1"
>
<div className="mr-2.5 flex min-w-[24px] items-center">
{logoUri ? (
<Image alt="" width="24" height="24" src={logoUri} />
) : (
<QuestionMarkCircleIcon className="h-6 w-6 text-th-fgd-3" />
)}
</div>
<div className="flex w-full items-center justify-between">
<div className="text-xl font-bold">{selectedToken}</div>
<ChevronDownIcon className="h-6 w-6" />
</div>
</button>
<div className="col-span-1">
<TokenListButton
token={selectedToken}
logoUri={logoUri}
setShowList={setShowTokenList}
/>
</div>
<div className="col-span-1">
<NumberFormat
@ -260,7 +242,7 @@ function RepayForm({ onSuccess, token }: RepayFormProps) {
allowNegative={false}
isNumericString={true}
decimalScale={bank?.mintDecimals || 6}
className="w-full rounded-lg rounded-l-none border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-xl text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover"
className={ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES}
placeholder="0.00"
value={inputAmount}
onValueChange={(e: NumberFormatValues) => {

View File

@ -10,7 +10,6 @@ import {
Cog8ToothIcon,
ArrowsRightLeftIcon,
ArrowTrendingUpIcon,
XMarkIcon,
MagnifyingGlassIcon,
BanknotesIcon,
NewspaperIcon,
@ -19,7 +18,7 @@ import {
} from '@heroicons/react/20/solid'
import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
import { Fragment, ReactNode, useState } from 'react'
import { Fragment, ReactNode } from 'react'
import { Disclosure, Popover, Transition } from '@headlessui/react'
import MangoAccountSummary from './account/MangoAccountSummary'
import Tooltip from './shared/Tooltip'
@ -29,7 +28,6 @@ import mangoStore from '@store/mangoStore'
import HealthHeart from './account/HealthHeart'
import useMangoAccount from 'hooks/useMangoAccount'
import { useTheme } from 'next-themes'
import { IconButton } from './shared/Button'
import LeaderboardIcon from './icons/LeaderboardIcon'
const SideNav = ({ collapsed }: { collapsed: boolean }) => {
@ -204,7 +202,6 @@ const SideNav = ({ collapsed }: { collapsed: boolean }) => {
size={32}
/>
}
isOpen
panelTitle={mangoAccount?.name ? mangoAccount.name : t('account')}
title={
<div className="w-24 text-left">
@ -222,7 +219,6 @@ const SideNav = ({ collapsed }: { collapsed: boolean }) => {
}
alignBottom
hideIconBg
showClose
>
<div className="px-4 py-2">
<MangoAccountSummary />
@ -315,8 +311,6 @@ export const ExpandableMenuItem = ({
hideIconBg,
icon,
panelTitle,
isOpen,
showClose,
title,
}: {
alignBottom?: boolean
@ -325,134 +319,112 @@ export const ExpandableMenuItem = ({
hideIconBg?: boolean
icon: ReactNode
panelTitle?: string
isOpen?: boolean
showClose?: boolean
title: string | ReactNode
}) => {
const [showMenu, setShowMenu] = useState(isOpen || false)
const { theme } = useTheme()
const toggleMenu = () => {
setShowMenu(!showMenu)
}
return collapsed ? (
<Popover>
<div
className={`relative z-30 ${alignBottom ? '' : 'py-2 pl-4'}`}
role="button"
<Popover className={`relative z-30 ${alignBottom ? '' : 'py-2 pl-4'}`}>
<Popover.Button
className={`${theme === 'Light' ? 'text-th-fgd-3' : 'text-th-fgd-2'} ${
alignBottom ? 'focus:bg-th-bkg-3' : 'focus:text-th-active'
} md:hover:text-th-active`}
>
<Popover.Button
className={`${
theme === 'Light' ? 'text-th-fgd-3' : 'text-th-fgd-2'
} md:hover:text-th-active`}
onClick={() => toggleMenu()}
<div
className={` ${
hideIconBg
? ''
: `flex h-8 w-8 items-center justify-center rounded-full ${
theme === 'Light' ? 'bg-th-bkg-2' : 'bg-th-bkg-3'
}`
} ${
alignBottom
? 'default-transition flex h-[64px] w-[64px] items-center justify-center hover:bg-th-bkg-2'
: ''
}`}
>
<div
className={` ${
hideIconBg
? ''
: `flex h-8 w-8 items-center justify-center rounded-full ${
theme === 'Light' ? 'bg-th-bkg-2' : 'bg-th-bkg-3'
}`
} ${
alignBottom
? 'default-transition flex h-[64px] w-[64px] items-center justify-center hover:bg-th-bkg-2'
: ''
}`}
>
{icon}
{icon}
</div>
</Popover.Button>
<Popover.Panel
className={`absolute left-[64px] z-20 w-56 rounded-md rounded-l-none bg-th-bkg-1 focus:outline-none ${
alignBottom
? 'bottom-0 rounded-b-none border-b-0 p-0'
: 'top-1/2 -translate-y-1/2'
}`}
>
<div
className={`rounded-md rounded-l-none bg-th-bkg-2 ${
alignBottom ? 'pt-4 pb-2' : 'py-2'
}`}
>
<div className="flex items-center justify-between pl-4 pr-2">
{panelTitle ? (
<h3 className="text-sm font-bold">{panelTitle}</h3>
) : null}
</div>
</Popover.Button>
{showMenu ? (
<Popover.Panel
static
className={`absolute z-20 w-56 rounded-md rounded-l-none bg-th-bkg-1 ${
alignBottom
? 'bottom-0 left-[63px] rounded-b-none border-b-0 p-0'
: 'top-1/2 left-[63px] -translate-y-1/2'
}`}
>
<div className="rounded-md rounded-l-none bg-th-bkg-2 py-2">
<div className="flex items-center justify-between pl-4 pr-2">
{panelTitle ? (
<h3 className="text-sm font-bold">{panelTitle}</h3>
) : null}
{showClose ? (
<IconButton
onClick={() => setShowMenu(false)}
hideBg
size="small"
>
<XMarkIcon className="h-5 w-5" />
</IconButton>
) : null}
</div>
{children}
</div>
</Popover.Panel>
) : null}
</div>
{children}
</div>
</Popover.Panel>
</Popover>
) : (
<Disclosure>
<div
onClick={() => setShowMenu(!showMenu)}
role="button"
className={`w-full px-4 py-2 ${
alignBottom ? 'h-[64px] hover:bg-th-bkg-2' : ''
}`}
>
<Disclosure.Button
className={`flex h-full w-full items-center justify-between rounded-none md:hover:text-th-active`}
>
<div className="flex items-center">
<div
className={
hideIconBg
? ''
: 'flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-3'
}
>
{icon}
{({ open }) => (
<>
<Disclosure.Button
className={`default-transition flex h-full w-full items-center justify-between rounded-none px-4 py-2 focus:text-th-active md:hover:text-th-active ${
alignBottom
? 'h-[64px] focus:bg-th-bkg-3 md:hover:bg-th-bkg-2'
: ''
}`}
>
<div className="flex items-center">
<div
className={
hideIconBg
? ''
: 'flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-3'
}
>
{icon}
</div>
<Transition
appear={true}
show={!collapsed}
as={Fragment}
enter="transition ease-in duration-300"
enterFrom="opacity-50"
enterTo="opacity-100"
leave="transition ease-out duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<span className="ml-3 truncate xl:text-base">{title}</span>
</Transition>
</div>
<Transition
appear={true}
show={!collapsed}
as={Fragment}
enter="transition ease-in duration-300"
enterFrom="opacity-50"
enterTo="opacity-100"
leave="transition ease-out duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<span className="ml-3 truncate xl:text-base">{title}</span>
</Transition>
</div>
<ChevronDownIcon
className={`${
showMenu ? 'rotate-180' : 'rotate-360'
} h-5 w-5 flex-shrink-0`}
/>
</Disclosure.Button>
</div>
<Transition
appear={true}
show={showMenu}
as={Fragment}
enter="transition-all ease-in duration-300"
enterFrom="opacity-100 max-h-0"
enterTo="opacity-100 max-h-80"
leave="transition-all ease-out duration-300"
leaveFrom="opacity-100 max-h-80"
leaveTo="opacity-0 max-h-0"
>
<Disclosure.Panel className="w-full overflow-hidden">
<div className={`${!alignBottom ? 'ml-1.5' : ''}`}>{children}</div>
</Disclosure.Panel>
</Transition>
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-360'
} h-5 w-5 flex-shrink-0`}
/>
</Disclosure.Button>
<Transition
as={Fragment}
enter="transition-all ease-in duration-300"
enterFrom="opacity-100 max-h-0"
enterTo="opacity-100 max-h-80"
leave="transition-all ease-out duration-300"
leaveFrom="opacity-100 max-h-80"
leaveTo="opacity-0 max-h-0"
>
<Disclosure.Panel className="w-full overflow-hidden">
<div className={`${!alignBottom ? 'ml-1.5' : ''}`}>
{children}
</div>
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
)
}

View File

@ -1,14 +1,11 @@
import { HealthType } from '@blockworks-foundation/mango-v4'
import {
ArrowLeftIcon,
ArrowUpTrayIcon,
ChevronDownIcon,
ExclamationCircleIcon,
LinkIcon,
} from '@heroicons/react/20/solid'
import Decimal from 'decimal.js'
import { useTranslation } from 'next-i18next'
import Image from 'next/legacy/image'
import { useCallback, useMemo, useState } from 'react'
import NumberFormat, { NumberFormatValues } from 'react-number-format'
@ -39,6 +36,8 @@ import { floorToDecimal } from 'utils/numbers'
import BankAmountWithValue from './shared/BankAmountWithValue'
import useBanksWithBalances from 'hooks/useBanksWithBalances'
import { isMangoError } from 'types'
import TokenListButton from './shared/TokenListButton'
import { ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES, BackButton } from './BorrowForm'
interface WithdrawFormProps {
onSuccess: () => void
@ -160,12 +159,7 @@ function WithdrawForm({ onSuccess, token }: WithdrawFormProps) {
className="absolute bottom-0 left-0 z-20 h-full w-full overflow-auto rounded-lg bg-th-bkg-1 p-6"
show={showTokenList}
>
<button
onClick={() => setShowTokenList(false)}
className={`absolute left-4 top-4 z-40 w-6 text-th-fgd-4 focus:outline-none md:right-2 md:top-2 md:hover:text-th-active`}
>
<ArrowLeftIcon className={`h-6 w-6`} />
</button>
<BackButton onClick={() => setShowTokenList(false)} />
<h2 className="mb-4 text-center text-lg">
{t('select-withdraw-token')}
</h2>
@ -211,26 +205,12 @@ function WithdrawForm({ onSuccess, token }: WithdrawFormProps) {
/>
) : null}
</div>
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-input-border bg-th-input-bkg">
<button
onClick={() => setShowTokenList(true)}
className="default-transition flex h-full w-full items-center rounded-lg rounded-r-none py-2 px-3 text-th-fgd-2 hover:cursor-pointer hover:bg-th-bkg-2 hover:text-th-fgd-1"
>
<div className="mr-2.5 flex min-w-[24px] items-center">
<Image
alt=""
width="24"
height="24"
src={
logoUri || `/icons/${selectedToken.toLowerCase()}.svg`
}
/>
</div>
<div className="flex w-full items-center justify-between">
<div className="text-xl font-bold">{selectedToken}</div>
<ChevronDownIcon className="h-6 w-6" />
</div>
</button>
<div className="col-span-1">
<TokenListButton
token={selectedToken}
logoUri={logoUri}
setShowList={setShowTokenList}
/>
</div>
<div className="col-span-1">
<NumberFormat
@ -241,7 +221,7 @@ function WithdrawForm({ onSuccess, token }: WithdrawFormProps) {
allowNegative={false}
isNumericString={true}
decimalScale={bank?.mintDecimals || 6}
className="w-full rounded-lg rounded-l-none border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-xl text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover"
className={ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES}
placeholder="0.00"
value={inputAmount}
onValueChange={(e: NumberFormatValues) =>

View File

@ -296,10 +296,10 @@ const AccountPage = () => {
<div className="hide-scroll flex justify-center space-x-2 md:justify-start">
{TABS.map((tab) => (
<button
className={`default-transition rounded-md py-1.5 px-2.5 text-sm font-medium md:hover:text-th-fgd-2 ${
className={`default-transition rounded-md py-1.5 px-2.5 text-sm font-medium focus:bg-th-bkg-3 md:hover:text-th-fgd-2 ${
activeTab === tab
? 'bg-th-bkg-3 text-th-active'
: 'text-th-fgd-3'
? 'bg-th-bkg-3 text-th-active focus:text-th-active'
: 'text-th-fgd-3 focus:text-th-fgd-1'
}`}
onClick={() => setActiveTab(tab)}
key={tab}

View File

@ -32,7 +32,7 @@ const ActionTokenItem = ({
return (
<button
className="default-transition flex w-full items-center rounded-md border border-th-bkg-4 bg-th-bkg-1 px-4 py-3 disabled:cursor-not-allowed disabled:opacity-30 md:hover:border-th-fgd-4 md:disabled:hover:border-th-bkg-4"
className="default-transition flex w-full items-center rounded-md border border-th-bkg-4 bg-th-bkg-1 px-4 py-3 focus:border-th-fgd-4 disabled:cursor-not-allowed disabled:opacity-30 md:hover:border-th-fgd-4 md:disabled:hover:border-th-bkg-4"
onClick={() => onSelect(name)}
disabled={customValue <= 0}
>

View File

@ -140,12 +140,14 @@ const ActivityFilters = () => {
</IconButton>
</Tooltip>
) : null}
<div
<button
onClick={() => setShowFilters(!showFilters)}
role="button"
className={`default-transition mr-4 ml-3 rounded-md border border-th-button px-2 py-1.5 md:mr-6 md:hover:border-th-button-hover`}
className={`default-transition mr-4 ml-3 rounded-md border border-th-button px-2 py-1.5 focus:border-th-fgd-4 md:mr-6 md:hover:border-th-button-hover`}
>
<Disclosure.Button className="flex h-full w-full items-center justify-between">
<Disclosure.Button
as="div"
className="flex h-full w-full items-center justify-between"
>
<div className="flex items-center space-x-2">
<AdjustmentsVerticalIcon className="hidden h-5 w-5 text-th-fgd-4 sm:block" />
<span className="text-sm font-medium text-th-fgd-1">
@ -158,7 +160,7 @@ const ActivityFilters = () => {
} ml-1.5 h-5 w-5 flex-shrink-0`}
/>
</Disclosure.Button>
</div>
</button>
</div>
{showFilters ? (
<Disclosure.Panel

View File

@ -27,10 +27,10 @@ const HistoryTabs = () => {
<div className="hide-scroll flex space-x-2 pl-4 md:pl-6">
{TABS.map((tab) => (
<button
className={`default-transition rounded-md py-1.5 px-2.5 text-sm font-medium md:hover:bg-th-bkg-4 ${
className={`default-transition rounded-md py-1.5 px-2.5 text-sm font-medium focus:bg-th-bkg-4 md:hover:bg-th-bkg-4 ${
activeTab === tab
? 'bg-th-bkg-4 text-th-active'
: 'bg-th-bkg-3 text-th-fgd-3'
? 'bg-th-bkg-4 text-th-active focus:text-th-active'
: 'text-th-fgd-3 focus:text-th-fgd-1'
}`}
onClick={() => setActiveTab(tab)}
key={tab}

View File

@ -37,13 +37,13 @@ const ButtonGroup = <T extends Values>({
) : null}
{values.map((v, i) => (
<button
className={`${className} default-transition relative w-1/2 cursor-pointer rounded-md px-3 text-center disabled:cursor-not-allowed ${
className={`${className} default-transition relative w-1/2 cursor-pointer rounded-md px-3 text-center focus:bg-th-bkg-3 disabled:cursor-not-allowed ${
large ? 'h-12 text-sm' : 'h-10 text-xs'
} font-normal
${
v === activeValue
? `text-th-active`
: `text-th-fgd-2 md:hover:text-th-active`
? `text-th-active focus:text-th-active`
: `text-th-fgd-2 focus:text-th-fgd-1 md:hover:text-th-fgd-1`
}
`}
disabled={disabled}

View File

@ -34,7 +34,7 @@ const MangoDateRangePicker = ({
<div className="w-full">
<Label text={t('date-from')} />
<input
className="default-transition h-12 w-full rounded-md border border-th-input-border bg-th-input-bkg px-3 text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover"
className="default-transition h-12 w-full rounded-md border border-th-input-border bg-th-input-bkg px-3 text-th-fgd-1 focus:border-th-fgd-4 focus:outline-none md:hover:border-th-input-border-hover"
{...startDateInputProps}
placeholder="Start Date"
/>
@ -45,7 +45,7 @@ const MangoDateRangePicker = ({
<div className="w-full">
<Label text={t('date-to')} />
<input
className="default-transition h-12 w-full rounded-md border border-th-input-border bg-th-input-bkg px-3 text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover"
className="default-transition h-12 w-full rounded-md border border-th-input-border bg-th-input-bkg px-3 text-th-fgd-1 focus:border-th-fgd-4 focus:outline-none md:hover:border-th-input-border-hover"
{...endDateInputProps}
placeholder="End Date"
/>

View File

@ -21,7 +21,7 @@ const MultiSelectDropdown = ({
{({ open }) => (
<div className="flex flex-col">
<Popover.Button
className={`default-transition h-12 rounded-md bg-th-input-bkg px-3 text-th-fgd-1 ring-1 ring-inset ring-th-input-border md:hover:ring-th-input-border-hover ${
className={`default-transition h-12 rounded-md bg-th-input-bkg px-3 text-th-fgd-1 ring-1 ring-inset ring-th-input-border focus:ring-th-fgd-4 md:hover:ring-th-input-border-hover ${
open ? 'ring-th-input-border-hover' : 'ring-th-input-border'
}`}
>
@ -47,8 +47,6 @@ const MultiSelectDropdown = ({
</div>
</Popover.Button>
<Transition
appear={true}
show={open}
as={Fragment}
enter="transition-all ease-in duration-200"
enterFrom="opacity-0 transform scale-75"

View File

@ -27,7 +27,7 @@ const Select = ({
{({ open }) => (
<>
<Listbox.Button
className={`default-transition h-full w-full rounded-md bg-th-input-bkg py-2.5 font-normal ring-1 ring-inset ring-th-input-border focus:border-th-input-border-hover focus:outline-none md:hover:ring-th-input-border-hover`}
className={`default-transition h-full w-full rounded-md bg-th-input-bkg py-2.5 font-normal ring-1 ring-inset ring-th-input-border focus:outline-none focus:ring-th-fgd-4 md:hover:ring-th-input-border-hover`}
>
<div
className={`flex items-center justify-between space-x-2 px-3 text-th-fgd-1`}
@ -38,20 +38,17 @@ const Select = ({
<span className="text-th-fgd-3">{placeholder}</span>
)}
<ChevronDownIcon
className={`default-transition h-5 w-5 flex-shrink-0 text-th-fgd-1 ${
className={`default-transition h-5 w-5 flex-shrink-0 text-th-fgd-3 ${
open ? 'rotate-180' : 'rotate-360'
}`}
/>
</div>
</Listbox.Button>
{open ? (
<Listbox.Options
static
className={`thin-scroll absolute left-0 z-20 mt-1 max-h-60 w-full origin-top-left space-y-2 overflow-auto rounded-md bg-th-bkg-2 p-4 text-th-fgd-1 outline-none ${dropdownPanelClassName}`}
>
{children}
</Listbox.Options>
) : null}
<Listbox.Options
className={`thin-scroll absolute left-0 z-20 mt-1 max-h-60 w-full origin-top-left space-y-2 overflow-auto rounded-md bg-th-bkg-2 p-4 outline-none ${dropdownPanelClassName}`}
>
{children}
</Listbox.Options>
</>
)}
</Listbox>
@ -67,13 +64,12 @@ interface OptionProps {
const Option = ({ value, children, className }: OptionProps) => {
return (
<Listbox.Option className="mb-0" value={value}>
<Listbox.Option
className="default-transition mb-0 text-th-fgd-2 hover:cursor-pointer focus:text-th-active md:hover:text-th-fgd-1"
value={value}
>
{({ selected }) => (
<div
className={`default-transition rounded text-th-fgd-2 hover:cursor-pointer md:hover:text-th-fgd-1 ${
selected ? 'text-th-active' : ''
} ${className}`}
>
<div className={` ${selected ? 'text-th-active' : ''} ${className}`}>
{children}
</div>
)}

View File

@ -27,8 +27,9 @@ const Switch: FunctionComponent<SwitchProps> = ({
className={`${
checked ? 'bg-th-success' : 'bg-th-bkg-4'
} relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer rounded-full
border-2 border-transparent transition-colors duration-200 ease-in-out
focus:outline-none ${disabled ? 'opacity-60' : ''}`}
border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-1 focus:outline-offset-2 focus:outline-th-fgd-4 ${
disabled ? 'opacity-60' : ''
}`}
role="switch"
aria-checked={checked}
onClick={handleClick}

View File

@ -128,7 +128,7 @@ const MangoAccountsListModal = ({
>
<button
onClick={() => handleSelectMangoAccount(acc)}
className="default-transition flex h-full w-full items-center justify-between rounded-md rounded-r-none bg-th-bkg-2 px-4 text-th-fgd-1 hover:bg-th-bkg-3"
className="default-transition flex h-full w-full items-center justify-between rounded-md rounded-r-none border border-th-bkg-4 px-4 text-th-fgd-1 focus:border-th-fgd-4 md:hover:border-th-fgd-4"
>
<div className="flex w-full items-center justify-between">
<div className="flex items-center space-x-2.5">
@ -190,7 +190,7 @@ const MangoAccountsListModal = ({
</div>
</div>
</button>
<div className="flex h-full items-center justify-center rounded-md rounded-l-none bg-th-bkg-3">
<div className="flex h-full items-center justify-center rounded-md rounded-l-none border border-l-0 border-th-bkg-4">
<Tooltip
className="hidden md:block"
content={t('copy-address')}

View File

@ -20,7 +20,7 @@ const volumeAlertSound = new Howl({
export const DEFAULT_VOLUME_ALERT_SETTINGS = { seconds: 30, value: 10000 }
const INPUT_CLASSES =
'h-12 w-full rounded-md border border-th-input-border bg-th-input-bkg px-3 font-mono text-base text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover'
'h-12 w-full rounded-md border border-th-input-border bg-th-input-bkg px-3 font-mono text-base text-th-fgd-1 focus:border-th-fgd-4 focus:outline-none md:hover:border-th-input-border-hover'
const TradeVolumeAlertModal = ({ isOpen, onClose }: ModalProps) => {
const { t } = useTranslation(['common', 'trade'])

View File

@ -45,6 +45,7 @@ import { isMangoError } from 'types'
import ColorBlur from '@components/ColorBlur'
import useLocalStorageState from 'hooks/useLocalStorageState'
import { ACCEPT_TERMS_KEY } from 'utils/constants'
import { ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES } from '@components/BorrowForm'
const UserSetupModal = ({
isOpen,
@ -429,7 +430,7 @@ const UserSetupModal = ({
allowNegative={false}
isNumericString={true}
decimalScale={tokenMax.decimals || 6}
className="w-full rounded-lg rounded-l-none border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-xl text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover"
className={ACCOUNT_ACTIONS_NUMBER_FORMAT_CLASSES}
placeholder="0.00"
value={depositAmount}
onValueChange={(e: NumberFormatValues) => {

View File

@ -5,6 +5,11 @@ import ChartMiddleOBRight from '@components/icons/ChartMiddleOBRight'
import ChartOnLeft from '@components/icons/ChartOnLeft'
import ChartOnRight from '@components/icons/ChartOnRight'
import Tooltip from '@components/shared/Tooltip'
import { TradeLayout } from '@components/trade/TradeAdvancedPage'
// import dayjs from 'dayjs'
import { ReactNode } from 'react'
// import { useRouter } from 'next/router'
// import { useCallback } from 'react'
import dayjs from 'dayjs'
import useLocalStorageState from 'hooks/useLocalStorageState'
import { useTranslation } from 'next-i18next'
@ -74,10 +79,7 @@ const DisplaySettings = () => {
TRADE_CHART_UI_KEY,
'trading-view'
)
const [tradeLayout, setTradeLayout] = useLocalStorageState(
TRADE_LAYOUT_KEY,
'chartLeft'
)
const [, setTradeLayout] = useLocalStorageState(TRADE_LAYOUT_KEY, 'chartLeft')
const handleLangChange = useCallback(
(l: string) => {
@ -101,9 +103,7 @@ const DisplaySettings = () => {
>
{THEMES.map((theme) => (
<Select.Option key={theme} value={t(`settings:${theme}`)}>
<div className="flex w-full items-center justify-between">
{t(`settings:${theme}`)}
</div>
{t(`settings:${theme}`)}
</Select.Option>
))}
</Select>
@ -111,7 +111,7 @@ const DisplaySettings = () => {
</div>
<div className="flex flex-col border-t border-th-bkg-3 py-4 md:flex-row md:items-center md:justify-between md:px-4">
<p className="mb-2 md:mb-0">{t('settings:language')}</p>
<div className="w-full min-w-[330px] md:w-[480px] md:pl-4">
<div className="w-full min-w-[220px] md:w-auto md:pl-4">
<ButtonGroup
activeValue={savedLanguage}
onChange={(l) => handleLangChange(l)}
@ -130,9 +130,7 @@ const DisplaySettings = () => {
>
{NOTIFICATION_POSITIONS.map((val) => (
<Select.Option key={val} value={t(`settings:${val}`)}>
<div className="flex w-full items-center justify-between">
{t(`settings:${val}`)}
</div>
{t(`settings:${val}`)}
</Select.Option>
))}
</Select>
@ -142,52 +140,32 @@ const DisplaySettings = () => {
<p className="mb-2 md:mb-0">{t('settings:trade-layout')}</p>
<div className="flex space-x-3">
<Tooltip content={t('settings:chart-left')}>
<button
className={`flex h-max items-center justify-center rounded border ${
tradeLayout === 'chartLeft'
? 'border-th-active'
: 'border-th-bkg-4 md:hover:border-th-fgd-4'
} p-0.5 `}
<ChartLayoutButton
icon={<ChartOnLeft className="h-auto w-32" />}
position="chartLeft"
onClick={() => setTradeLayout('chartLeft')}
>
<ChartOnLeft className="h-auto w-32" />
</button>
/>
</Tooltip>
<Tooltip content={t('settings:chart-middle-ob-right')}>
<button
className={`flex h-max items-center justify-center rounded border ${
tradeLayout === 'chartMiddleOBRight'
? 'border-th-active'
: 'border-th-bkg-4 md:hover:border-th-fgd-4'
} p-0.5 `}
<ChartLayoutButton
icon={<ChartMiddleOBRight className="h-auto w-32" />}
position="chartMiddleOBRight"
onClick={() => setTradeLayout('chartMiddleOBRight')}
>
<ChartMiddleOBRight className="h-auto w-32" />
</button>
/>
</Tooltip>
<Tooltip content={t('settings:chart-middle-ob-left')}>
<button
className={`flex h-max items-center justify-center rounded border ${
tradeLayout === 'chartMiddleOBLeft'
? 'border-th-active'
: 'border-th-bkg-4 md:hover:border-th-fgd-4'
} p-0.5 `}
<ChartLayoutButton
icon={<ChartMiddleOBLeft className="h-auto w-32" />}
position="chartMiddleOBLeft"
onClick={() => setTradeLayout('chartMiddleOBLeft')}
>
<ChartMiddleOBLeft className="h-auto w-32" />
</button>
/>
</Tooltip>
<Tooltip content={t('settings:chart-right')}>
<button
className={`flex h-max items-center justify-center rounded border ${
tradeLayout === 'chartRight'
? 'border-th-active'
: 'border-th-bkg-4 md:hover:border-th-fgd-4'
} p-0.5 `}
<ChartLayoutButton
icon={<ChartOnRight className="h-auto w-32" />}
position="chartRight"
onClick={() => setTradeLayout('chartRight')}
>
<ChartOnRight className="h-auto w-32" />
</button>
/>
</Tooltip>
</div>
</div>
@ -218,3 +196,27 @@ const DisplaySettings = () => {
}
export default DisplaySettings
const ChartLayoutButton = ({
onClick,
icon,
position,
}: {
onClick: (l: TradeLayout) => void
icon: ReactNode
position: TradeLayout
}) => {
const [tradeLayout] = useLocalStorageState(TRADE_LAYOUT_KEY, 'chartLeft')
return (
<button
className={`flex h-max items-center justify-center rounded border ${
tradeLayout === position
? 'border-th-active'
: 'border-th-bkg-4 md:hover:border-th-fgd-4'
} p-0.5 focus:border-th-fgd-4`}
onClick={() => onClick(position)}
>
{icon}
</button>
)
}

View File

@ -1,5 +1,5 @@
import { useTheme } from 'next-themes'
import { FunctionComponent, ReactNode } from 'react'
import { forwardRef, FunctionComponent, ReactNode, Ref } from 'react'
interface AllButtonProps {
onClick?: (e?: React.MouseEvent) => void
@ -33,8 +33,8 @@ const Button: FunctionComponent<ButtonCombinedProps> = ({
disabled={disabled}
className={`rounded-md ${
secondary
? 'border border-th-button md:hover:border-th-button-hover'
: 'bg-th-button md:hover:bg-th-button-hover'
? 'border border-th-button focus:border-th-fgd-4 md:hover:border-th-button-hover'
: 'bg-th-button focus:border focus:border-th-fgd-4 md:hover:bg-th-button-hover'
} ${
size === 'medium'
? 'h-10 px-4'
@ -45,7 +45,7 @@ const Button: FunctionComponent<ButtonCombinedProps> = ({
theme === 'High Contrast' && !secondary
? 'text-th-bkg-1'
: 'text-th-fgd-1'
} disabled:cursor-not-allowed disabled:opacity-60 disabled:hover:brightness-100 ${className}`}
} disabled:cursor-not-allowed disabled:opacity-60 ${className}`}
type={type}
{...props}
>
@ -57,19 +57,16 @@ const Button: FunctionComponent<ButtonCombinedProps> = ({
interface IconButtonProps {
hideBg?: boolean
size?: 'small' | 'medium' | 'large'
ref?: Ref<HTMLButtonElement>
}
type IconButtonCombinedProps = AllButtonProps & IconButtonProps
export const IconButton: FunctionComponent<IconButtonCombinedProps> = ({
children,
onClick,
disabled = false,
className,
hideBg,
size,
...props
}) => {
export const IconButton = forwardRef<
HTMLButtonElement,
IconButtonCombinedProps
>((props, ref) => {
const { children, onClick, disabled = false, className, hideBg, size } = props
return (
<button
onClick={onClick}
@ -85,15 +82,17 @@ export const IconButton: FunctionComponent<IconButtonCombinedProps> = ({
} default-transition items-center justify-center rounded-full ${
hideBg
? 'md:hover:text-th-active'
: 'border border-th-button md:hover:border-th-button-hover'
: 'border border-th-button focus:border-th-fgd-3 md:hover:border-th-button-hover'
} text-th-fgd-1 focus:outline-none disabled:cursor-not-allowed disabled:bg-th-bkg-4
disabled:text-th-fgd-4 md:disabled:hover:text-th-fgd-4 ${className}`}
{...props}
disabled:text-th-fgd-4 md:disabled:hover:text-th-fgd-4 ${className} focus:text-th-active`}
ref={ref}
>
{children}
</button>
)
}
})
IconButton.displayName = 'IconButton'
interface LinkButtonProps {
icon?: ReactNode
@ -115,7 +114,7 @@ export const LinkButton: FunctionComponent<LinkButtonCombinedProps> = ({
disabled={disabled}
className={`default-transition flex items-center border-0 font-bold ${
secondary ? 'text-th-active' : 'text-th-fgd-2'
} underline focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:hover:no-underline ${className}`}
} rounded-sm underline focus:text-th-active focus:no-underline disabled:cursor-not-allowed disabled:opacity-50 md:hover:no-underline ${className}`}
{...props}
type="button"
>

View File

@ -19,7 +19,7 @@ const ChartRangeButtons: FunctionComponent<ChartRangeButtonsProps> = ({
<div className="relative flex">
{activeValue && values.includes(activeValue) ? (
<div
className={`default-transition absolute left-0 top-0 h-full transform rounded-md bg-th-bkg-3`}
className="default-transition absolute left-0 top-0 h-full transform rounded-md bg-th-bkg-3"
style={{
transform: `translateX(${
values.findIndex((v) => v === activeValue) * 100
@ -30,7 +30,7 @@ const ChartRangeButtons: FunctionComponent<ChartRangeButtonsProps> = ({
) : null}
{values.map((v, i) => (
<button
className={`${className} default-transition relative h-6 cursor-pointer rounded-md px-3 text-center text-xs
className={`${className} default-transition relative h-6 cursor-pointer rounded-md px-3 text-center text-xs focus:bg-th-bkg-3 focus:text-th-fgd-1
${
v === activeValue
? `text-th-active`

View File

@ -27,14 +27,14 @@ const FavoriteMarketButton = ({
(marketName: string) => marketName === market.name
) ? (
<button
className="default-transition flex items-center justify-center text-th-active md:hover:text-th-fgd-3"
className="default-transition flex items-center justify-center text-th-active focus:text-th-fgd-4 md:hover:text-th-fgd-3"
onClick={() => removeFromFavorites(market.name)}
>
<FilledStarIcon className="h-5 w-5" />
</button>
) : (
<button
className="default-transition flex items-center justify-center text-th-fgd-4 md:hover:text-th-active"
className="default-transition flex items-center justify-center text-th-fgd-4 focus:text-th-active md:hover:text-th-active"
onClick={() => addToFavorites(market.name)}
>
<StarIcon className="h-5 w-5" />

View File

@ -46,7 +46,9 @@ const IconDropMenu = ({
: size === 'medium'
? 'h-10 w-10'
: 'h-8 w-8'
} default-transition items-center justify-center rounded-full border border-th-button text-th-fgd-1 md:hover:border-th-button-hover md:hover:text-th-fgd-1 ${
} default-transition items-center justify-center rounded-full border border-th-button text-th-fgd-1 ${
!open ? 'focus:border-th-fgd-2' : ''
} md:hover:border-th-button-hover md:hover:text-th-fgd-1 ${
disabled ? 'cursor-not-allowed opacity-60' : ''
}`}
disabled={disabled}

View File

@ -57,7 +57,7 @@ const LeverageSlider = ({
min="0"
max={leverageMax}
step={step}
className="w-full"
className="w-full focus:outline-none"
onChange={handleSliderChange}
value={value}
></input>

View File

@ -19,12 +19,12 @@ const MaxAmountButton = ({
}) => {
return (
<LinkButton
className={`font-normal no-underline ${className}`}
className={`font-normal no-underline ${className} md:hover:text-th-fgd-3`}
disabled={disabled}
onClick={onClick}
>
<p className="mr-1 text-th-fgd-4">{label}:</p>
<span className="font-mono text-th-fgd-2 underline">
<span className="font-mono">
<FormatNumericValue value={value} decimals={decimals} />
</span>
</LinkButton>

View File

@ -47,15 +47,15 @@ function Modal({
: 'p-4 pt-6 sm:h-auto sm:max-w-md sm:rounded-lg sm:border sm:border-th-bkg-3 sm:p-6'
} relative `}
>
<div>{children}</div>
{!hideClose ? (
<button
onClick={onClose}
className={`absolute right-4 top-4 z-40 text-th-fgd-4 focus:outline-none sm:right-2 sm:top-2 md:hover:text-th-active`}
className={`absolute right-4 top-4 z-40 text-th-fgd-4 focus:text-th-active focus:outline-none sm:right-2 sm:top-2 md:hover:text-th-active`}
>
<XMarkIcon className={`h-6 w-6`} />
</button>
) : null}
<div>{children}</div>
</Dialog.Panel>
</div>
</Dialog>

View File

@ -25,7 +25,7 @@ const TabButtons = <T extends Values>({
{values.map(([label, count], i) => (
<div className={fillWidth ? 'flex-1' : ''} key={`${label}` + i}>
<button
className={`default-transition flex h-12 w-full items-center justify-center px-4 font-normal md:px-6 ${
className={`default-transition flex h-12 w-full items-center justify-center px-4 font-normal focus:bg-th-bkg-2 md:px-6 ${
rounded ? 'rounded-md' : 'rounded-none'
} ${
showBorders
@ -39,8 +39,8 @@ const TabButtons = <T extends Values>({
? 'bg-th-up-dark font-display text-th-fgd-1'
: label === 'sell'
? 'bg-th-down-dark font-display text-th-fgd-1'
: 'bg-th-bkg-2 text-th-active'
: 'hover:cursor-pointer hover:text-th-fgd-2'
: 'bg-th-bkg-2 text-th-active focus:text-th-active'
: 'hover:cursor-pointer hover:text-th-fgd-2 focus:text-th-fgd-1'
}`}
key={`${label}${i}`}
onClick={() => onChange(label)}

View File

@ -54,11 +54,11 @@ const TabUnderline = <T extends Values>({
${
activeValue === value
? activeValue === 'buy'
? 'text-th-up'
? 'text-th-up focus:text-th-up'
: activeValue === 'sell'
? 'text-th-down'
: 'text-th-active'
: 'text-th-fgd-4 hover:text-th-fgd-3'
? 'text-th-down focus:text-th-down'
: 'text-th-active focus:text-th-active'
: 'text-th-fgd-4 focus:text-th-fgd-1 md:hover:text-th-fgd-3'
}
`}
key={`${value}` + i}

View File

@ -0,0 +1,34 @@
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import Image from 'next/image'
const TokenListButton = ({
logoUri,
token,
setShowList,
}: {
logoUri: string | undefined
token: string
setShowList: (x: boolean) => void
}) => {
return (
<button
onClick={() => setShowList(true)}
className="default-transition flex h-full w-full items-center rounded-lg rounded-r-none border border-th-input-border bg-th-input-bkg py-2 px-3 text-th-fgd-2 hover:cursor-pointer hover:bg-th-bkg-2 hover:text-th-fgd-1 focus:border-th-fgd-4"
>
<div className="mr-2.5 flex min-w-[24px] items-center">
<Image
alt=""
width="24"
height="24"
src={logoUri || `/icons/${token.toLowerCase()}.svg`}
/>
</div>
<div className="flex w-full items-center justify-between">
<div className="text-xl font-bold">{token}</div>
<ChevronDownIcon className="h-6 w-6" />
</div>
</button>
)
}
export default TokenListButton

View File

@ -24,7 +24,6 @@ import Button, { IconButton } from '../shared/Button'
import Loading from '../shared/Loading'
import { EnterBottomExitBottom } from '../shared/Transitions'
import useQuoteRoutes from './useQuoteRoutes'
import SheenLoader from '../shared/SheenLoader'
import { HealthType } from '@blockworks-foundation/mango-v4'
import {
INPUT_TOKEN_DEFAULT,
@ -57,6 +56,9 @@ export const withValueLimit = (values: NumberFormatValues): boolean => {
: true
}
const NUMBER_FORMAT_CLASSNAMES =
'default-transition w-full rounded-lg rounded-l-none border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-xl text-th-fgd-1 focus:border-th-fgd-4 focus:outline-none md:hover:border-th-input-border-hover md:hover:focus:border-th-fgd-4'
const set = mangoStore.getState().set
const SwapForm = () => {
@ -338,7 +340,7 @@ const SwapForm = () => {
) : null}
</div>
<div className="mb-3 grid grid-cols-2" id="swap-step-two">
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-input-border bg-th-input-bkg">
<div className="col-span-1">
<TokenSelect
bank={
inputBank ||
@ -357,7 +359,7 @@ const SwapForm = () => {
decimalScale={inputBank?.mintDecimals || 6}
name="amountIn"
id="amountIn"
className="w-full rounded-l-none rounded-r-lg border border-th-input-border bg-th-input-bkg p-3 text-right font-mono text-base font-bold text-th-fgd-1 focus:outline-none lg:text-lg xl:text-xl"
className={NUMBER_FORMAT_CLASSNAMES}
placeholder="0.00"
value={amountInFormValue}
onValueChange={handleAmountInChange}
@ -367,7 +369,7 @@ const SwapForm = () => {
</div>
<div className="-mb-2 flex justify-center">
<button
className="rounded-full border border-th-bkg-4 p-1.5 text-th-fgd-3 md:hover:text-th-active"
className="rounded-full border border-th-bkg-4 p-1.5 text-th-fgd-3 focus:border-th-fgd-4 md:hover:text-th-active"
onClick={handleSwitchTokens}
>
<ArrowDownIcon
@ -382,7 +384,7 @@ const SwapForm = () => {
</div>
<p className="mb-2 text-th-fgd-2 lg:text-base">{t('swap:receive')}</p>
<div id="swap-step-three" className="mb-3 grid grid-cols-2">
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-input-border bg-th-input-bkg">
<div className="col-span-1">
<TokenSelect
bank={
outputBank ||
@ -392,12 +394,10 @@ const SwapForm = () => {
type="output"
/>
</div>
<div className="flex h-[54px] w-full items-center justify-end rounded-r-lg border border-th-input-border text-right text-lg font-bold text-th-fgd-3 xl:text-xl">
<div className="col-span-1 flex h-[54px]">
{loadingSwapDetails ? (
<div className="w-full">
<SheenLoader className="flex flex-1 rounded-l-none">
<div className="h-[52px] w-full rounded-r-lg bg-th-bkg-4" />
</SheenLoader>
<div className="flex w-full items-center justify-center rounded-l-none rounded-r-lg border border-th-input-border bg-th-bkg-2">
<Loading />
</div>
) : (
<NumberFormat
@ -408,7 +408,7 @@ const SwapForm = () => {
decimalScale={outputBank?.mintDecimals || 6}
name="amountOut"
id="amountOut"
className="w-full rounded-l-none rounded-r-lg bg-th-input-bkg p-3 text-right font-mono text-base font-bold text-th-fgd-1 focus:outline-none lg:text-lg xl:text-xl"
className={NUMBER_FORMAT_CLASSNAMES}
placeholder="0.00"
value={amountOutFormValue}
onValueChange={handleAmountOutChange}

View File

@ -1,4 +1,4 @@
import { memo, useMemo, useEffect } from 'react'
import { memo, useMemo, useEffect, useRef } from 'react'
import { Token } from '../../types/jupiter'
import mangoStore from '@store/mangoStore'
import { IconButton } from '../shared/Button'
@ -133,6 +133,7 @@ const SwapFormTokenList = ({
const outputBank = mangoStore((s) => s.swap.outputBank)
const { group } = useMangoGroup()
const { mangoAccount } = useMangoAccount()
const focusRef = useRef<HTMLButtonElement>(null)
// const popularTokens = useMemo(() => {
// return tokens.filter((token) => {
@ -202,6 +203,12 @@ const SwapFormTokenList = ({
// const sortedTokens = search ? startSearch(tokenInfos, search) : tokenInfos
const sortedTokens = tokenInfos
useEffect(() => {
if (focusRef?.current) {
focusRef.current.focus()
}
}, [focusRef])
return (
<>
<p className="mb-3">
@ -215,6 +222,7 @@ const SwapFormTokenList = ({
className="absolute top-2 right-2 text-th-fgd-3 hover:text-th-fgd-2"
onClick={onClose}
hideBg
ref={focusRef}
>
<XMarkIcon className="h-6 w-6" />
</IconButton>

View File

@ -4,6 +4,7 @@ import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import {
@ -199,6 +200,7 @@ const SwapReviewRouteInfo = ({
SOUND_SETTINGS_KEY,
INITIAL_SOUND_SETTINGS
)
const focusRef = useRef<HTMLButtonElement>(null)
const inputTokenIconUri = useMemo(() => {
return inputTokenInfo ? inputTokenInfo.logoURI : ''
@ -211,6 +213,12 @@ const SwapReviewRouteInfo = ({
)
}, [selectedRoute, outputTokenInfo])
useEffect(() => {
if (focusRef?.current) {
focusRef.current.focus()
}
}, [focusRef])
useEffect(() => {
setCoingeckoPrices(EMPTY_COINGECKO_PRICES)
const fetchTokenPrices = async () => {
@ -354,6 +362,7 @@ const SwapReviewRouteInfo = ({
className="absolute top-4 left-4 mr-3 text-th-fgd-2"
onClick={onClose}
size="small"
ref={focusRef}
>
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
@ -570,7 +579,11 @@ const SwapReviewRouteInfo = ({
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button className="default-transition flex w-full items-center justify-between rounded-md p-3">
<Disclosure.Button
className={`default-transition flex w-full items-center justify-between rounded-md p-3 focus:bg-th-bkg-3 ${
open ? 'mb-2 rounded-b-none' : ''
}`}
>
<p>{open ? t('swap:hide-fees') : t('swap:show-fees')}</p>
<ChevronDownIcon
className={`${

View File

@ -1,6 +1,6 @@
import { XMarkIcon } from '@heroicons/react/20/solid'
import { useTranslation } from 'next-i18next'
import { useEffect, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import mangoStore from '@store/mangoStore'
import ButtonGroup from '../forms/ButtonGroup'
import Input from '../forms/Input'
@ -14,6 +14,7 @@ const SwapSettings = ({ onClose }: { onClose: () => void }) => {
const margin = mangoStore((s) => s.swap.margin)
const slippage = mangoStore((s) => s.swap.slippage)
const set = mangoStore((s) => s.set)
const focusRef = useRef<HTMLButtonElement>(null)
const [showCustomSlippageForm, setShowCustomSlippageForm] = useState(false)
const [inputValue, setInputValue] = useState(slippage.toString())
@ -36,10 +37,21 @@ const SwapSettings = ({ onClose }: { onClose: () => void }) => {
})
}
useEffect(() => {
if (focusRef?.current) {
focusRef.current.focus()
}
}, [focusRef])
return (
<>
<h3 className="mb-3">{t('settings')}</h3>
<IconButton className="absolute top-2 right-2" onClick={onClose} hideBg>
<IconButton
className="absolute top-2 right-2"
onClick={onClose}
hideBg
ref={focusRef}
>
<XMarkIcon className="h-6 w-6" />
</IconButton>

View File

@ -28,10 +28,9 @@ const TokenSelect = ({ bank, showTokenList, type }: TokenSelectProps) => {
}
return (
<div
<button
onClick={() => showTokenList(type)}
className="default-transition flex h-full items-center rounded-lg rounded-r-none p-3 text-th-fgd-2 hover:cursor-pointer hover:bg-th-bkg-2 hover:text-th-fgd-1"
role="button"
className="default-transition flex h-full w-full items-center rounded-lg rounded-r-none border border-th-input-border bg-th-input-bkg py-2 px-3 text-th-fgd-2 hover:cursor-pointer hover:bg-th-bkg-2 hover:text-th-fgd-1 focus:border-th-fgd-4"
>
<div className="mr-2.5 flex min-w-[24px] items-center">
{logoURI ? (
@ -44,7 +43,7 @@ const TokenSelect = ({ bank, showTokenList, type }: TokenSelectProps) => {
<div className="text-xl font-bold text-th-fgd-1">{bank?.name}</div>
<ChevronDownIcon className="h-6 w-6" />
</div>
</div>
</button>
)
}

View File

@ -64,6 +64,12 @@ const successSound = new Howl({
volume: 0.5,
})
const INPUT_SUFFIX_CLASSNAMES =
'absolute right-[1px] top-1/2 flex h-[calc(100%-2px)] -translate-y-1/2 items-center rounded-r-md bg-th-input-bkg px-2 text-xs font-normal text-th-fgd-4'
const INPUT_PREFIX_CLASSNAMES =
'absolute left-2 top-1/2 h-5 w-5 flex-shrink-0 -translate-y-1/2'
const DEFAULT_CHECKBOX_SETTINGS = {
ioc: false,
post: false,
@ -498,9 +504,9 @@ const AdvancedTradeForm = () => {
{t('trade:limit-price')}
</p>
</div>
<div className="default-transition flex items-center rounded-md border border-th-input-border bg-th-input-bkg p-2 text-sm font-bold text-th-fgd-1 md:hover:border-th-input-border-hover lg:text-base">
<div className="relative">
{quoteLogoURI ? (
<div className="h-5 w-5 flex-shrink-0">
<div className={INPUT_PREFIX_CLASSNAMES}>
<Image alt="" width="20" height="20" src={quoteLogoURI} />
</div>
) : (
@ -516,14 +522,12 @@ const AdvancedTradeForm = () => {
decimalScale={tickDecimals}
name="price"
id="price"
className="ml-2 w-full bg-transparent font-mono focus:outline-none"
className="default-transition flex w-full items-center rounded-md border border-th-input-border bg-th-input-bkg p-2 pl-9 font-mono text-sm font-bold text-th-fgd-1 focus:border-th-fgd-4 focus:outline-none md:hover:border-th-input-border-hover md:hover:focus:border-th-fgd-4 lg:text-base"
placeholder="0.00"
value={tradeForm.price}
onValueChange={handlePriceChange}
/>
<div className="text-xs font-normal text-th-fgd-4">
{quoteSymbol}
</div>
<div className={INPUT_SUFFIX_CLASSNAMES}>{quoteSymbol}</div>
</div>
</>
) : null}
@ -533,11 +537,24 @@ const AdvancedTradeForm = () => {
useMargin={savedCheckboxSettings.margin}
/>
<div className="flex flex-col">
<div className="default-transition flex items-center rounded-md rounded-b-none border border-th-input-border bg-th-input-bkg p-2 text-sm font-bold text-th-fgd-1 md:hover:z-10 md:hover:border-th-input-border-hover lg:text-base">
<div className="h-5 w-5 flex-shrink-0">
<div className="relative">
<NumberFormat
inputMode="decimal"
thousandSeparator=","
allowNegative={false}
isNumericString={true}
decimalScale={minOrderDecimals}
name="base"
id="base"
className="default-transition relative flex w-full items-center rounded-md rounded-b-none border border-th-input-border bg-th-input-bkg p-2 pl-9 font-mono text-sm font-bold text-th-fgd-1 focus:z-10 focus:border-th-fgd-4 focus:outline-none md:hover:z-10 md:hover:border-th-input-border-hover md:hover:focus:border-th-fgd-4 lg:text-base"
placeholder="0.00"
value={tradeForm.baseSize}
onValueChange={handleBaseSizeChange}
/>
<div className={`z-10 ${INPUT_PREFIX_CLASSNAMES}`}>
<LogoWithFallback
alt=""
className="z-10 drop-shadow-md"
className="drop-shadow-md"
width={'24'}
height={'24'}
src={baseLogoURI || `/icons/${baseSymbol?.toLowerCase()}.svg`}
@ -548,26 +565,13 @@ const AdvancedTradeForm = () => {
}
/>
</div>
<NumberFormat
inputMode="decimal"
thousandSeparator=","
allowNegative={false}
isNumericString={true}
decimalScale={minOrderDecimals}
name="base"
id="base"
className="ml-2 w-full bg-transparent font-mono focus:outline-none"
placeholder="0.00"
value={tradeForm.baseSize}
onValueChange={handleBaseSizeChange}
/>
<div className="text-xs font-normal text-th-fgd-4">
<div className={`z-10 ${INPUT_SUFFIX_CLASSNAMES}`}>
{baseSymbol}
</div>
</div>
<div className="default-transition -mt-[1px] flex items-center rounded-md rounded-t-none border border-th-input-border bg-th-input-bkg p-2 text-sm font-bold text-th-fgd-1 md:hover:border-th-input-border-hover lg:text-base">
<div className="relative">
{quoteLogoURI ? (
<div className="h-5 w-5 flex-shrink-0">
<div className={INPUT_PREFIX_CLASSNAMES}>
<Image alt="" width="20" height="20" src={quoteLogoURI} />
</div>
) : (
@ -583,14 +587,12 @@ const AdvancedTradeForm = () => {
decimalScale={tickDecimals}
name="quote"
id="quote"
className="ml-2 w-full bg-transparent font-mono focus:outline-none"
className="default-transition -mt-[1px] flex w-full items-center rounded-md rounded-t-none border border-th-input-border bg-th-input-bkg p-2 pl-9 font-mono text-sm font-bold text-th-fgd-1 focus:border-th-fgd-4 focus:outline-none md:hover:border-th-input-border-hover md:hover:focus:border-th-fgd-4 lg:text-base"
placeholder="0.00"
value={tradeForm.quoteSize}
onValueChange={handleQuoteSizeChange}
/>
<div className="text-xs font-normal text-th-fgd-4">
{quoteSymbol}
</div>
<div className={INPUT_SUFFIX_CLASSNAMES}>{quoteSymbol}</div>
</div>
</div>
</div>
@ -704,8 +706,8 @@ const AdvancedTradeForm = () => {
!connected
? ''
: tradeForm.side === 'buy'
? 'bg-th-up-dark text-white md:hover:bg-th-up'
: 'bg-th-down-dark text-white md:hover:bg-th-down'
? 'bg-th-up-dark text-white md:hover:bg-th-up-dark md:hover:brightness-90'
: 'bg-th-down text-white md:hover:bg-th-down md:hover:brightness-90'
}`}
disabled={connected && (!tradeForm.baseSize || !tradeForm.price)}
size="large"

View File

@ -34,17 +34,19 @@ const FavoriteMarketsBar = () => {
market = group?.getSerum3MarketByName(mkt)
}
return (
<Link href={`/trade?name=${mkt}`} key={mkt} shallow={true}>
<div
className={`default-transition flex items-center whitespace-nowrap py-1 text-xs hover:text-th-active hover:opacity-100 ${
selectedMarket && selectedMarket.name === mkt
? 'text-th-active'
: 'text-th-fgd-1 opacity-60'
}`}
>
{market ? <MarketLogos market={market} size="small" /> : null}
<span className="mb-0 mr-1.5 text-xs">{mkt}</span>
{/* {change24h ? (
<Link
className={`default-transition flex items-center whitespace-nowrap py-1 text-xs hover:text-th-active hover:opacity-100 focus:text-th-fgd-1 focus:opacity-100 focus:outline-none ${
selectedMarket && selectedMarket.name === mkt
? 'text-th-active'
: 'text-th-fgd-1 opacity-60'
}`}
href={`/trade?name=${mkt}`}
key={mkt}
shallow={true}
>
{market ? <MarketLogos market={market} size="small" /> : null}
<span className="mb-0 mr-1.5 text-xs">{mkt}</span>
{/* {change24h ? (
<div
className={`text-xs ${
change24h
@ -57,7 +59,6 @@ const FavoriteMarketsBar = () => {
{`${(change24h * 100).toFixed(1)}%`}
</div>
) : null} */}
</div>
</Link>
)
})}

View File

@ -30,7 +30,7 @@ const GroupSize = ({
{({ open }) => (
<>
<Listbox.Button
className={`default-transition flex h-6 items-center rounded bg-th-bkg-1 py-1 font-normal text-th-fgd-2 hover:text-th-active focus:border-th-bkg-4 focus:outline-none`}
className={`default-transition flex h-6 items-center rounded bg-th-bkg-1 py-1 pl-1.5 font-normal text-th-fgd-2 hover:text-th-active focus:border-th-bkg-4 focus:bg-th-bkg-3 focus:outline-none`}
>
<div
className={`flex items-center justify-between font-mono text-xs leading-none`}

View File

@ -55,10 +55,10 @@ const MarketSelectDropdown = () => {
<Popover>
{({ open, close }) => (
<div
className="relative flex flex-col overflow-visible"
className="relative -ml-2 flex flex-col overflow-visible"
id="trade-step-one"
>
<Popover.Button className="default-transition flex h-12 items-center justify-between hover:text-th-active">
<Popover.Button className="default-transition -ml-4 flex h-12 items-center justify-between px-4 hover:text-th-active focus:bg-th-bkg-3">
<div className="flex items-center">
{selectedMarket ? <MarketLogos market={selectedMarket} /> : null}
<div className="whitespace-nowrap text-xl font-bold text-th-fgd-1 md:text-base">
@ -91,24 +91,15 @@ const MarketSelectDropdown = () => {
}}
>
<Link
className="default-transition flex items-center hover:cursor-pointer focus:text-th-active focus:outline-none md:hover:text-th-fgd-3"
href={{
pathname: '/trade',
query: { name: m.name },
}}
shallow={true}
>
<div className="default-transition flex items-center hover:cursor-pointer md:hover:text-th-fgd-3">
<MarketLogos market={m} />
<span
className={
m.name === selectedMarket?.name
? 'text-th-active'
: ''
}
>
{m.name}
</span>
</div>
<MarketLogos market={m} />
<span>{m.name}</span>
</Link>
<div className="flex items-center space-x-3">
{!loadingPerpStats ? (
@ -155,24 +146,15 @@ const MarketSelectDropdown = () => {
}}
>
<Link
className="default-transition flex items-center hover:cursor-pointer focus:text-th-active focus:outline-none md:hover:text-th-fgd-3"
href={{
pathname: '/trade',
query: { name: m.name },
}}
shallow={true}
>
<div className="default-transition flex items-center hover:cursor-pointer md:hover:text-th-fgd-3">
<MarketLogos market={m} />
<span
className={
m.name === selectedMarket?.name
? 'text-th-active'
: ''
}
>
{m.name}
</span>
</div>
<MarketLogos market={m} />
<span>{m.name}</span>
</Link>
<div className="flex items-center space-x-3">
{!loadingPrices ? (

View File

@ -497,7 +497,7 @@ const Orderbook = () => {
<button
className={`rounded ${
showAsks ? 'bg-th-bkg-3' : 'bg-th-bkg-2'
} default-transition flex h-6 w-6 items-center justify-center hover:border-th-fgd-4 focus:outline-none disabled:cursor-not-allowed`}
} default-transition flex h-6 w-6 items-center justify-center hover:border-th-fgd-4 focus:bg-th-bkg-4 focus:outline-none disabled:cursor-not-allowed`}
onClick={() => toggleSides('bids')}
>
<OrderbookIcon className="h-4 w-4" side="buy" />
@ -511,7 +511,7 @@ const Orderbook = () => {
<button
className={`rounded ${
showBids ? 'bg-th-bkg-3' : 'bg-th-bkg-2'
} default-transition flex h-6 w-6 items-center justify-center hover:border-th-fgd-4 focus:outline-none disabled:cursor-not-allowed`}
} default-transition flex h-6 w-6 items-center justify-center hover:border-th-fgd-4 focus:bg-th-bkg-4 focus:outline-none disabled:cursor-not-allowed`}
onClick={() => toggleSides('asks')}
>
<OrderbookIcon className="h-4 w-4" side="sell" />
@ -523,7 +523,7 @@ const Orderbook = () => {
placement="bottom"
>
<button
className="default-transition flex h-6 w-6 items-center justify-center rounded bg-th-bkg-3 hover:border-th-fgd-4 focus:outline-none disabled:cursor-not-allowed"
className="default-transition flex h-6 w-6 items-center justify-center rounded bg-th-bkg-3 hover:border-th-fgd-4 focus:bg-th-bkg-4 focus:outline-none disabled:cursor-not-allowed"
onClick={resetOrderbook}
>
<ArrowPathIcon className="h-4 w-4" />

View File

@ -17,7 +17,7 @@ import FavoriteMarketsBar from './FavoriteMarketsBar'
import useLocalStorageState from 'hooks/useLocalStorageState'
import { TRADE_LAYOUT_KEY } from 'utils/constants'
type TradeLayout =
export type TradeLayout =
| 'chartLeft'
| 'chartMiddleOBRight'
| 'chartMiddleOBLeft'

View File

@ -25,42 +25,40 @@ export const ConnectWalletButton: React.FC = () => {
<button
onClick={handleConnect}
disabled={!groupLoaded}
className={` text-white focus:outline-none disabled:cursor-wait disabled:opacity-25`}
className="relative flex h-16 w-44 bg-th-bkg-3 py-2 text-white before:absolute before:inset-0 before:bg-gradient-to-r before:from-transparent before:via-th-bkg-4 before:to-transparent before:opacity-0 hover:overflow-hidden hover:before:-translate-x-full hover:before:animate-[shimmer_0.75s_normal] hover:before:opacity-100 focus:bg-th-bkg-4 disabled:cursor-wait disabled:opacity-25"
>
<div className="relative flex h-16 w-44 bg-th-bkg-3 py-2 before:absolute before:inset-0 before:bg-gradient-to-r before:from-transparent before:via-th-bkg-4 before:to-transparent before:opacity-0 hover:overflow-hidden hover:before:-translate-x-full hover:before:animate-[shimmer_0.75s_normal] hover:before:opacity-100">
<div className="default-transition relative z-10 flex h-full items-center justify-center space-x-3 px-4">
{connecting ? (
<Loading className="h-[28px] w-[28px]" />
) : (
<div
className={`flex h-[28px] w-[28px] items-center justify-center rounded-full ${
wallet?.adapter.name === 'Solflare' ? 'bg-black' : ''
}`}
>
<img
src={wallet?.adapter.icon || selectedWallet?.adapter.icon}
className={
wallet?.adapter.name === 'Solflare'
? 'h-auto w-[20px]'
: 'h-auto w-[28px]'
}
alt={`${wallet?.adapter.name} icon`}
/>
</div>
)}
<div className="text-left">
<div className="mb-1.5 flex font-display text-base leading-none text-th-fgd-1">
{t('connect')}
</div>
<div className="default-transition relative z-10 flex h-full items-center justify-center space-x-3 px-4">
{connecting ? (
<Loading className="h-[28px] w-[28px]" />
) : (
<div
className={`flex h-[28px] w-[28px] items-center justify-center rounded-full ${
wallet?.adapter.name === 'Solflare' ? 'bg-black' : ''
}`}
>
<img
src={wallet?.adapter.icon || selectedWallet?.adapter.icon}
className={
wallet?.adapter.name === 'Solflare'
? 'h-auto w-[20px]'
: 'h-auto w-[28px]'
}
alt={`${wallet?.adapter.name} icon`}
/>
</div>
)}
<div className="text-left">
<div className="mb-1.5 flex font-display text-base leading-none text-th-fgd-1">
{t('connect')}
</div>
<div className="text-xxs font-normal leading-3 text-th-fgd-3">
{preselectedWalletName}
</div>
<div className="text-xxs font-normal leading-3 text-th-fgd-3">
{preselectedWalletName}
</div>
</div>
</div>
</button>
<div className="absolute top-1/2 right-0 z-20 h-full -translate-y-1/2">
<div className="absolute right-0 top-0 z-20 flex h-full">
<WalletSelect />
</div>
</div>

View File

@ -1,4 +1,4 @@
import { Menu, Transition } from '@headlessui/react'
import { Popover, Transition } from '@headlessui/react'
import {
ArrowRightOnRectangleIcon,
CurrencyDollarIcon,
@ -73,92 +73,82 @@ const ConnectedMenu = () => {
return (
<>
<Menu>
{({ open }) => (
<div className="relative">
<Menu.Button
className={`default-transition h-16 ${
!isMobile ? 'w-48 border-l border-th-bkg-3 px-4' : ''
} hover:bg-th-bkg-2 focus:outline-none`}
>
<div className="flex items-center" id="account-step-one">
<ProfileImage
imageSize="40"
placeholderSize="24"
isOwnerProfile
/>
{!loadProfileDetails && !isMobile ? (
<div className="ml-2.5 overflow-hidden text-left">
<p className="text-xs text-th-fgd-3">
{wallet?.adapter.name}
</p>
<p className="truncate pr-2 text-sm font-bold text-th-fgd-1">
{publicKey ? abbreviateAddress(publicKey) : ''}
</p>
{/* <p className="truncate pr-2 text-sm font-bold capitalize text-th-fgd-1">
<Popover>
<div className="relative">
<Popover.Button
className={`default-transition h-16 ${
!isMobile ? 'w-48 border-l border-th-bkg-3 px-4' : ''
} hover:bg-th-bkg-2 focus:bg-th-bkg-3 focus:outline-none`}
>
<div className="flex items-center" id="account-step-one">
<ProfileImage
imageSize="40"
placeholderSize="24"
isOwnerProfile
/>
{!loadProfileDetails && !isMobile ? (
<div className="ml-2.5 overflow-hidden text-left">
<p className="text-xs text-th-fgd-3">
{wallet?.adapter.name}
</p>
<p className="truncate pr-2 text-sm font-bold text-th-fgd-1">
{publicKey ? abbreviateAddress(publicKey) : ''}
</p>
{/* <p className="truncate pr-2 text-sm font-bold capitalize text-th-fgd-1">
{profileDetails?.profile_name
? profileDetails.profile_name
: 'Profile Unavailabe'}
</p> */}
</div>
) : null}
</div>
</Menu.Button>
<Transition
appear={true}
show={open}
as={Fragment}
enter="transition ease-in duration-200"
enterFrom="opacity-0 scale-75"
enterTo="opacity-100 scale-100"
leave="transition ease-out duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Menu.Items className="absolute right-0 top-[61px] z-20 mt-1 w-48 space-y-1.5 rounded-md rounded-t-none bg-th-bkg-2 px-4 py-2.5 md:rounded-r-none">
<Menu.Item>
<button
className="default-transition flex w-full flex-row items-center rounded-none py-0.5 font-normal focus:outline-none md:hover:cursor-pointer md:hover:text-th-fgd-1"
onClick={() => setShowEditProfileModal(true)}
>
<UserCircleIcon className="h-4 w-4" />
<div className="pl-2 text-left">
{t('profile:edit-profile-pic')}
</div>
) : null}
</div>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-in duration-200"
enterFrom="opacity-0 scale-75"
enterTo="opacity-100 scale-100"
leave="transition ease-out duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Popover.Panel className="absolute right-0 top-[61px] z-20 mt-1 w-48 space-y-1.5 rounded-md rounded-t-none bg-th-bkg-2 px-4 py-2.5 focus:outline-none md:rounded-r-none">
<button
className="default-transition flex w-full flex-row items-center rounded-none py-0.5 font-normal focus:text-th-active focus:outline-none md:hover:cursor-pointer md:hover:text-th-fgd-1"
onClick={() => setShowEditProfileModal(true)}
>
<UserCircleIcon className="h-4 w-4" />
<div className="pl-2 text-left">
{t('profile:edit-profile-pic')}
</div>
</button>
{isMobile ? (
<button
className="default-transition flex w-full flex-row items-center rounded-none py-0.5 font-normal focus:text-th-active focus:outline-none"
onClick={() => setShowMangoAccountsModal(true)}
>
<CurrencyDollarIcon className="h-4 w-4" />
<div className="pl-2 text-left">{t('accounts')}</div>
</button>
) : null}
<button
className="default-transition flex w-full flex-row items-center rounded-none py-0.5 font-normal focus:text-th-active focus:outline-none md:hover:cursor-pointer md:hover:text-th-fgd-1"
onClick={handleDisconnect}
>
<ArrowRightOnRectangleIcon className="h-4 w-4" />
<div className="pl-2 text-left">
<div className="pb-0.5">{t('disconnect')}</div>
{publicKey ? (
<div className="font-mono text-xs text-th-fgd-4">
{abbreviateAddress(publicKey)}
</div>
</button>
</Menu.Item>
{isMobile ? (
<Menu.Item>
<button
className="default-transition flex w-full flex-row items-center rounded-none py-0.5 font-normal focus:outline-none"
onClick={() => setShowMangoAccountsModal(true)}
>
<CurrencyDollarIcon className="h-4 w-4" />
<div className="pl-2 text-left">{t('accounts')}</div>
</button>
</Menu.Item>
) : null}
<Menu.Item>
<button
className="default-transition flex w-full flex-row items-center rounded-none py-0.5 font-normal focus:outline-none md:hover:cursor-pointer md:hover:text-th-fgd-1"
onClick={handleDisconnect}
>
<ArrowRightOnRectangleIcon className="h-4 w-4" />
<div className="pl-2 text-left">
<div className="pb-0.5">{t('disconnect')}</div>
{publicKey ? (
<div className="font-mono text-xs text-th-fgd-4">
{abbreviateAddress(publicKey)}
</div>
) : null}
</div>
</button>
</Menu.Item>
</Menu.Items>
</Transition>
</div>
)}
</Menu>
) : null}
</div>
</button>
</Popover.Panel>
</Transition>
</div>
</Popover>
{showEditProfileModal ? (
<EditProfileModal
isOpen={showEditProfileModal}

View File

@ -1,6 +1,6 @@
import React, { Fragment } from 'react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { Menu, Transition } from '@headlessui/react'
import { Popover, Transition } from '@headlessui/react'
import { useEnhancedWallet } from './EnhancedWalletProvider'
import useMangoGroup from 'hooks/useMangoGroup'
@ -9,11 +9,11 @@ const WalletSelect = () => {
const { group } = useMangoGroup()
return (
<Menu>
<Popover>
{({ open }) => (
<>
<Menu.Button
className={`flex h-full w-12 cursor-pointer items-center justify-center rounded-none bg-transparent text-th-fgd-3 hover:brightness-[1.1] focus:outline-none disabled:opacity-25`}
<Popover.Button
className={`flex h-full w-12 cursor-pointer items-center justify-center rounded-none bg-transparent text-th-fgd-3 hover:brightness-[1.1] focus:text-th-active focus:outline-none disabled:opacity-25`}
disabled={!group}
>
<ChevronDownIcon
@ -21,10 +21,8 @@ const WalletSelect = () => {
open ? 'rotate-180' : 'rotate-360'
}`}
/>
</Menu.Button>
</Popover.Button>
<Transition
appear={true}
show={open}
as={Fragment}
enter="transition ease-in duration-200"
enterFrom="opacity-0 scale-75"
@ -33,31 +31,30 @@ const WalletSelect = () => {
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Menu.Items className="absolute top-16 right-0 z-20 w-44 rounded-md rounded-t-none bg-th-bkg-2 px-4 py-2.5 outline-none">
<Popover.Panel className="absolute top-16 right-0 z-20 w-44 rounded-md rounded-t-none bg-th-bkg-2 px-4 py-2.5 outline-none">
{displayedWallets?.map((wallet, index) => (
<Menu.Item key={index}>
<button
className="flex w-full flex-row items-center justify-between rounded-none py-1.5 font-normal focus:outline-none md:hover:cursor-pointer md:hover:text-th-active"
onClick={() => {
handleSelect(wallet.adapter.name)
}}
>
<div className="flex items-center">
<img
src={wallet.adapter.icon}
className="mr-2 h-5 w-5"
alt={`${wallet.adapter.name} icon`}
/>
{wallet.adapter.name}
</div>
</button>
</Menu.Item>
<button
className="flex w-full flex-row items-center justify-between rounded-none py-1.5 font-normal focus:text-th-active focus:outline-none md:hover:cursor-pointer md:hover:text-th-active"
onClick={() => {
handleSelect(wallet.adapter.name)
}}
key={wallet.adapter.name + index}
>
<div className="flex items-center">
<img
src={wallet.adapter.icon}
className="mr-2 h-5 w-5"
alt={`${wallet.adapter.name} icon`}
/>
{wallet.adapter.name}
</div>
</button>
))}
</Menu.Items>
</Popover.Panel>
</Transition>
</>
)}
</Menu>
</Popover>
)
}

View File

@ -401,7 +401,7 @@ body {
}
button {
@apply default-transition tracking-wider focus:outline-none;
@apply tracking-wider focus:outline-none;
}
svg {
@ -543,7 +543,7 @@ table p {
/* slider */
input[type='range'] {
@apply h-1.5 appearance-none rounded bg-th-bkg-3 bg-gradient-to-r from-th-active to-th-active bg-no-repeat;
@apply default-transition h-1.5 appearance-none rounded bg-th-bkg-3 bg-gradient-to-r from-th-active to-th-active bg-no-repeat focus:bg-th-bkg-4;
}
input[type='range']::-webkit-slider-thumb {