Skip to content
This repository has been archived by the owner on Feb 2, 2024. It is now read-only.

Commit

Permalink
Adding surplus column on tx table (#99)
Browse files Browse the repository at this point in the history
* Adding surplus column on tx table

* Use popper tooltip with click instead hover

* Fixing onClick on tooltip

* Creating BaseIconTooltip

* Avoid use tooltip on mobile view

* Fix mobile view wrap surplus

* Use OrderSurplusTooltipDisplay on OrderUserTable

* Hover instead Click, no cast return, amount of smart formatting

* Fix row spacing, improve type naming
  • Loading branch information
henrypalacios authored May 31, 2022
1 parent 183ee90 commit 9c60af0
Show file tree
Hide file tree
Showing 9 changed files with 299 additions and 138 deletions.
96 changes: 69 additions & 27 deletions src/components/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Portal from 'components/Portal'
// hooks
import { usePopperOnClick, usePopperDefault, TOOLTIP_OFFSET } from 'hooks/usePopper'

const QuestionIcon = styled(SVG)`
const CustomSvgIcon = styled(SVG)`
width: 1.4rem;
height: 1.4rem;
fill: ${({ theme }): string => theme.grey};
Expand Down Expand Up @@ -200,31 +200,29 @@ export const LongTooltipContainer = styled.div`
line-height: 1.4;
`

interface HelpTooltipProps {
tooltip: ReactNode
placement?: Placement
offset?: number
}

const HelperSpan = styled.span`
cursor: pointer;
transition: color 0.1s;
display: flex;
padding: 0 0.6rem 0 0;
:hover {
color: #748a47;
}
`

export const HelpTooltipContainer = styled(LongTooltipContainer)`
font-size: 1.6rem;
font-family: monospace;
padding: 1em;
color: black;
`

export const HelpTooltip: React.FC<HelpTooltipProps> = ({ tooltip, placement = 'top', offset }) => {
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &
{
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>
}[Keys]

type BaseTooltipsProps = RequireAtLeastOne<
{
tooltip: ReactNode
placement?: Placement
offset?: number
sourceIconSvg?: string
targetContent?: ReactNode
},
'sourceIconSvg' | 'targetContent'
>

export const BaseIconTooltipOnClick: React.FC<BaseTooltipsProps> = ({
tooltip,
placement = 'top',
offset,
sourceIconSvg,
targetContent,
}) => {
const {
targetProps: { ref, onClick },
tooltipProps,
Expand All @@ -241,9 +239,53 @@ export const HelpTooltip: React.FC<HelpTooltipProps> = ({ tooltip, placement = '
return (
<>
<HelperSpan ref={ref} onClick={handleClick}>
<QuestionIcon src={questionImg} />
{sourceIconSvg ? <CustomSvgIcon src={sourceIconSvg} /> : targetContent}
</HelperSpan>
<Tooltip {...tooltipProps}>{tooltip}</Tooltip>
</>
)
}

export const BaseIconTooltipOnHover: React.FC<BaseTooltipsProps> = ({
tooltip,
placement = 'top',
offset,
sourceIconSvg,
targetContent,
}) => {
const { tooltipProps, targetProps } = usePopperDefault<HTMLSpanElement>(placement, offset)

return (
<>
<HelperSpan {...targetProps}>{sourceIconSvg ? <CustomSvgIcon src={sourceIconSvg} /> : targetContent}</HelperSpan>
<Tooltip {...tooltipProps}>{tooltip}</Tooltip>
</>
)
}

type HelpTooltipProps = Omit<BaseTooltipsProps, 'sourceIconSvg' | 'targetContent'>

const HelperSpan = styled.span`
cursor: pointer;
transition: color 0.1s;
display: flex;
padding: 0 0.6rem 0 0;
.default-icon-tooltip {
color: ${({ theme }): string => theme.grey};
:hover {
color: ${({ theme }): string => theme.white};
}
}
`

export const HelpTooltipContainer = styled(LongTooltipContainer)`
font-size: 1.6rem;
font-family: monospace;
padding: 1em;
color: black;
`

export const HelpTooltip: React.FC<HelpTooltipProps> = ({ tooltip, placement = 'top', offset }) => {
return <BaseIconTooltipOnClick sourceIconSvg={questionImg} tooltip={tooltip} placement={placement} offset={offset} />
}
80 changes: 67 additions & 13 deletions src/components/orders/OrderSurplusDisplay/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import React from 'react'
import styled from 'styled-components'
import styled, { useTheme } from 'styled-components'

import { Order } from 'api/operator'

import { formatSmart, formatSmartMaxPrecision, safeTokenName } from 'utils'
import {
formatSmart,
formatSmartMaxPrecision,
safeTokenName,
formattingAmountPrecision,
FormatAmountPrecision,
} from 'utils'

import { LOW_PRECISION_DECIMALS, PERCENTAGE_PRECISION } from 'apps/explorer/const'
import { BaseIconTooltipOnHover } from 'components/Tooltip'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faArrowAltCircleUp as faIcon } from '@fortawesome/free-regular-svg-icons'

const Wrapper = styled.div`
display: flex;
& > * {
margin-right: 0.25rem;
}
Expand All @@ -26,12 +36,11 @@ const Surplus = styled.span`
// opacity: 0.5;
// `

export type Props = { order: Order }
export type Props = { order: Order; amountSmartFormatting?: boolean } & React.HTMLAttributes<HTMLDivElement>
type SurplusText = { amount: string; percentage: string; formattedSmartAmount: string }

export function OrderSurplusDisplay(props: Props): JSX.Element | null {
const {
order: { kind, buyToken, sellToken, surplusAmount, surplusPercentage },
} = props
function useGetSurplus(order: Order): SurplusText | null {
const { kind, buyToken, sellToken, surplusAmount, surplusPercentage } = order

const surplusToken = kind === 'buy' ? sellToken : buyToken

Expand All @@ -47,21 +56,66 @@ export function OrderSurplusDisplay(props: Props): JSX.Element | null {
precision: PERCENTAGE_PRECISION,
decimals: LOW_PRECISION_DECIMALS,
})
const formattedSurplusAmount = formatSmartMaxPrecision(surplusAmount, surplusToken)
const formattedSurplusAmountMaxPrecision = formatSmartMaxPrecision(surplusAmount, surplusToken)
const formattedSurplusAmount = formattingAmountPrecision(
surplusAmount,
surplusToken,
FormatAmountPrecision.highPrecision,
)

const tokenSymbol = safeTokenName(surplusToken)
// const formattedUsdAmount = formatSmart({
// amount: usdAmount,
// precision: NO_ADJUSTMENT_NEEDED_PRECISION,
// decimals: LOW_PRECISION_DECIMALS,
// })

return {
amount: `${formattedSurplusAmountMaxPrecision} ${tokenSymbol}`,
formattedSmartAmount: `${formattedSurplusAmount} ${tokenSymbol}`,
percentage: `+${formattedSurplusPercentage}%`,
}
}

export function OrderSurplusDisplay(props: Props): JSX.Element | null {
const surplus = useGetSurplus(props.order)

if (!surplus) return null

return (
<Wrapper>
<Surplus>+{formattedSurplusPercentage}%</Surplus>
<span>
{formattedSurplusAmount} {tokenSymbol}
</span>
<Wrapper className={props.className}>
<Surplus>{surplus.percentage}</Surplus>
<span>{props.amountSmartFormatting ? surplus.formattedSmartAmount : surplus.amount}</span>
{/* <UsdAmount>(~${formattedUsdAmount})</UsdAmount> */}
</Wrapper>
)
}

const IconWrapper = styled(FontAwesomeIcon)`
padding: 0.6rem;
margin: -0.6rem 0 -0.6rem -0.6rem;
box-sizing: content-box;
:hover {
cursor: pointer;
}
`

export function OrderSurplusTooltipDisplay({ order }: Props): JSX.Element | null {
const surplus = useGetSurplus(order)
const theme = useTheme()

if (!surplus) return null

return (
<BaseIconTooltipOnHover
tooltip={surplus.amount}
targetContent={
<span>
<IconWrapper icon={faIcon} color={theme.green} />
<Surplus>{surplus.percentage}</Surplus>
</span>
}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import styled from 'styled-components'

import { media } from 'theme/styles/media'
import { Order } from 'api/operator'
import { useMediaBreakpoint } from 'hooks/useMediaBreakPoint'
import { OrderSurplusTooltipDisplay, OrderSurplusDisplay } from '../OrderSurplusDisplay'

export const OrderSurplusDisplayStyled = styled(OrderSurplusDisplay)`
${media.mobile} {
flex-direction: column;
}
`
/**
* Displays surplus amount inside tooltip when display mode has little space to display
*/
export function OrderSurplusDisplayStyledByRow({ order }: { order: Order }): JSX.Element {
const isDesktop = useMediaBreakpoint(['xl', 'lg'])

if (isDesktop) {
return <OrderSurplusTooltipDisplay order={order} />
}

return <OrderSurplusDisplayStyled order={order} amountSmartFormatting />
}
10 changes: 9 additions & 1 deletion src/components/orders/OrdersUserDetailsTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import TradeOrderType from 'components/common/TradeOrderType'
import { LinkWithPrefixNetwork } from 'components/common/LinkWithPrefixNetwork'
import { TextWithTooltip } from 'apps/explorer/components/common/TextWithTooltip'
import Spinner from 'components/common/Spinner'
import { OrderSurplusDisplayStyledByRow } from './OrderSurplusTooltipStyledByRow'

const Wrapper = styled(StyledUserDetailsTable)`
> thead > tr,
> tbody > tr {
grid-template-columns: 12rem 7rem repeat(2, minmax(16rem, 1.5fr)) repeat(2, minmax(18rem, 2fr)) 1fr;
grid-template-columns: 12rem 5.5rem repeat(2, minmax(16rem, 1.5fr)) minmax(18rem, 2fr) 9rem minmax(21.6rem, 2fr) 1.18fr;
}
tr > td {
span.span-inside-tooltip {
Expand Down Expand Up @@ -210,6 +211,12 @@ const RowOrder: React.FC<RowProps> = ({ order, isPriceInverted }) => {
</HeaderTitle>
<HeaderValue>{renderSpinnerWhenNoValue(limitPriceSettled) || limitPriceSettled}</HeaderValue>
</td>
<td>
<HeaderTitle>Surplus</HeaderTitle>
<HeaderValue>
<OrderSurplusDisplayStyledByRow order={order} />
</HeaderValue>
</td>
<td>
<HeaderTitle>Created</HeaderTitle>
<HeaderValue>
Expand Down Expand Up @@ -267,6 +274,7 @@ const OrdersUserDetailsTable: React.FC<Props> = (props) => {
<th>
Limit price <Icon icon={faExchangeAlt} onClick={invertLimitPrice} />
</th>
<th>Surplus</th>
<th>Created</th>
<th>Status</th>
</tr>
Expand Down
Loading

0 comments on commit 9c60af0

Please sign in to comment.