mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
refactor wallet popup into generic tooltip component
This commit is contained in:
parent
a3d98477ee
commit
a021fb3f13
@ -1,4 +1,4 @@
|
||||
import React from 'react'
|
||||
import React, { ReactElement, ReactNode } from 'react'
|
||||
import styles from './Label.module.css'
|
||||
|
||||
const Label = ({
|
||||
@ -7,9 +7,9 @@ const Label = ({
|
||||
...props
|
||||
}: {
|
||||
required?: boolean
|
||||
children: string
|
||||
children: ReactNode
|
||||
htmlFor: string
|
||||
}) => (
|
||||
}): ReactElement => (
|
||||
<label
|
||||
className={`${styles.label} ${required && styles.required}`}
|
||||
title={required ? 'Required' : ''}
|
||||
|
@ -0,0 +1,41 @@
|
||||
.tooltip {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.content {
|
||||
composes: box from './Box.module.css';
|
||||
padding: calc(var(--spacer) / 4);
|
||||
min-width: 20rem;
|
||||
max-width: 25rem;
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.arrow,
|
||||
.arrow::before {
|
||||
position: absolute;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.arrow::before {
|
||||
content: '';
|
||||
transform: rotate(45deg);
|
||||
background: var(--brand-grey-lighter);
|
||||
}
|
||||
|
||||
.content[data-placement*='top'] > .arrow {
|
||||
bottom: -4px;
|
||||
}
|
||||
|
||||
.content[data-placement*='bottom'] > .arrow {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.content[data-placement*='left'] > .arrow {
|
||||
right: -4px;
|
||||
}
|
||||
|
||||
.content[data-placement*='right'] > .arrow {
|
||||
left: -4px;
|
||||
}
|
@ -1,24 +1,77 @@
|
||||
import React, { ReactElement, forwardRef } from 'react'
|
||||
import Tippy from '@tippyjs/react'
|
||||
import React, { ReactElement, ReactNode } from 'react'
|
||||
import loadable from '@loadable/component'
|
||||
import { useSpring, animated } from 'react-spring'
|
||||
import styles from './Tooltip.module.css'
|
||||
|
||||
export default function Tooltip({
|
||||
content,
|
||||
children
|
||||
}: {
|
||||
content: string
|
||||
children: ReactElement
|
||||
}) {
|
||||
return (
|
||||
<Tippy content={content}>
|
||||
<CustomWrapper>{children}</CustomWrapper>
|
||||
</Tippy>
|
||||
)
|
||||
const Tippy = loadable(() => import('@tippyjs/react/headless'))
|
||||
|
||||
const animation = {
|
||||
config: { tension: 400, friction: 20 },
|
||||
from: { transform: 'scale(0.5) translateY(-3rem)' },
|
||||
to: { transform: 'scale(1) translateY(0)' }
|
||||
}
|
||||
|
||||
// Forward ref for Tippy.js
|
||||
// eslint-disable-next-line
|
||||
const CustomWrapper = forwardRef(
|
||||
({ children }: { children: ReactElement }, ref: any) => {
|
||||
return <div ref={ref}>{children}</div>
|
||||
const DefaultTrigger = React.forwardRef((props, ref: any) => {
|
||||
return <i ref={ref}>Info</i>
|
||||
})
|
||||
|
||||
export default function Tooltip({
|
||||
content,
|
||||
children,
|
||||
trigger,
|
||||
disabled
|
||||
}: {
|
||||
content: ReactNode
|
||||
children?: ReactNode
|
||||
trigger?: string
|
||||
disabled?: boolean
|
||||
}): ReactElement {
|
||||
const [props, setSpring] = useSpring(() => animation.from)
|
||||
|
||||
function onMount() {
|
||||
setSpring({
|
||||
transform: 'scale(1) translateY(0)',
|
||||
onRest: (): void => null,
|
||||
config: animation.config
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
function onHide({ unmount }: { unmount: any }) {
|
||||
setSpring({
|
||||
...animation.from,
|
||||
onRest: unmount,
|
||||
config: { ...animation.config, clamp: true }
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
interactive
|
||||
interactiveBorder={30}
|
||||
zIndex={1}
|
||||
trigger={trigger || 'mouseenter focus'}
|
||||
disabled={disabled || null}
|
||||
render={(attrs: any) => (
|
||||
<animated.div style={props}>
|
||||
<div className={styles.content} {...attrs}>
|
||||
{content}
|
||||
<div className={styles.arrow} data-popper-arrow />
|
||||
</div>
|
||||
</animated.div>
|
||||
)}
|
||||
appendTo={
|
||||
typeof document !== 'undefined' && document.querySelector('body')
|
||||
}
|
||||
animation
|
||||
onMount={onMount}
|
||||
onHide={onHide}
|
||||
fallback={
|
||||
<div className={styles.tooltip}>{children || <DefaultTrigger />}</div>
|
||||
}
|
||||
>
|
||||
<div className={styles.tooltip}>{children || <DefaultTrigger />}</div>
|
||||
</Tippy>
|
||||
)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import { isCorrectNetwork } from '../../../../utils/wallet'
|
||||
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
||||
import InputElement from '../../../atoms/Input/InputElement'
|
||||
import Label from '../../../atoms/Input/Label'
|
||||
import Tooltip from '../../../atoms/Tooltip'
|
||||
|
||||
export default function Advanced({
|
||||
ocean,
|
||||
@ -95,7 +96,9 @@ export default function Advanced({
|
||||
</div>
|
||||
|
||||
<footer className={styles.summary}>
|
||||
<Label htmlFor="liquidityProviderFee">Liquidity Provider Fee</Label>
|
||||
<Label htmlFor="liquidityProviderFee">
|
||||
Liquidity Provider Fee <Tooltip content="Help Me" />
|
||||
</Label>
|
||||
<InputElement
|
||||
value={liquidityProviderFee}
|
||||
name="liquidityProviderFee"
|
||||
|
@ -1,8 +1,5 @@
|
||||
.details {
|
||||
composes: box from '../../atoms/Box.module.css';
|
||||
padding: calc(var(--spacer) / 2) !important;
|
||||
min-width: 20rem;
|
||||
max-width: 25rem;
|
||||
padding: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.balance {
|
||||
@ -31,33 +28,3 @@
|
||||
font-size: var(--font-size-small);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.arrow,
|
||||
.arrow::before {
|
||||
position: absolute;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.arrow::before {
|
||||
content: '';
|
||||
transform: rotate(45deg);
|
||||
background: var(--brand-grey-lighter);
|
||||
}
|
||||
|
||||
.details[data-placement*='top'] > .arrow {
|
||||
bottom: -4px;
|
||||
}
|
||||
|
||||
.details[data-placement*='bottom'] > .arrow {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.details[data-placement*='left'] > .arrow {
|
||||
right: -4px;
|
||||
}
|
||||
|
||||
.details[data-placement*='right'] > .arrow {
|
||||
left: -4px;
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ import { getInjectedProviderName } from 'web3modal'
|
||||
import Conversion from '../../atoms/Price/Conversion'
|
||||
import { formatCurrency } from '@coingecko/cryptoformat'
|
||||
|
||||
export default function Details({ attrs }: { attrs: any }): ReactElement {
|
||||
export default function Details(): ReactElement {
|
||||
const { balance, connect, logout, chainId } = useOcean()
|
||||
|
||||
return (
|
||||
<div className={styles.details} {...attrs}>
|
||||
<div className={styles.details}>
|
||||
<ul>
|
||||
{Object.entries(balance).map(([key, value]) => (
|
||||
<li className={styles.balance} key={key}>
|
||||
@ -41,7 +41,6 @@ export default function Details({ attrs }: { attrs: any }): ReactElement {
|
||||
</li>
|
||||
</ul>
|
||||
<Web3Feedback />
|
||||
<div className={styles.arrow} data-popper-arrow />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,62 +1,15 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import loadable from '@loadable/component'
|
||||
import { useSpring, animated } from 'react-spring'
|
||||
import Account from './Account'
|
||||
import Details from './Details'
|
||||
import Tooltip from '../../atoms/Tooltip'
|
||||
import { useOcean } from '@oceanprotocol/react'
|
||||
|
||||
const Tippy = loadable(() => import('@tippyjs/react/headless'))
|
||||
|
||||
const animation = {
|
||||
config: { tension: 400, friction: 20 },
|
||||
from: { transform: 'scale(0.5) translateY(-3rem)' },
|
||||
to: { transform: 'scale(1) translateY(0)' }
|
||||
}
|
||||
|
||||
export default function Wallet(): ReactElement {
|
||||
const { accountId, refreshBalance } = useOcean()
|
||||
const [props, setSpring] = useSpring(() => animation.from)
|
||||
|
||||
// always refetch balance when popover is opened
|
||||
function onMount() {
|
||||
accountId && refreshBalance()
|
||||
|
||||
setSpring({
|
||||
transform: 'scale(1) translateY(0)',
|
||||
onRest: (): void => null,
|
||||
config: animation.config
|
||||
})
|
||||
}
|
||||
|
||||
function onHide({ unmount }: { unmount: any }) {
|
||||
setSpring({
|
||||
...animation.from,
|
||||
onRest: unmount,
|
||||
config: { ...animation.config, clamp: true }
|
||||
})
|
||||
}
|
||||
const { accountId } = useOcean()
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
interactive
|
||||
interactiveBorder={30}
|
||||
trigger="click focus"
|
||||
zIndex={1}
|
||||
render={(attrs: any) => (
|
||||
<animated.div style={props}>
|
||||
<Details attrs={attrs} />
|
||||
</animated.div>
|
||||
)}
|
||||
appendTo={
|
||||
typeof document !== 'undefined' && document.querySelector('body')
|
||||
}
|
||||
animation
|
||||
onMount={onMount}
|
||||
onHide={onHide}
|
||||
disabled={!accountId}
|
||||
fallback={<Account />}
|
||||
>
|
||||
<Tooltip content={<Details />} trigger="click focus" disabled={!accountId}>
|
||||
<Account />
|
||||
</Tippy>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user