refactor: consolidate price delta components (#7268)
* refactor: move delta component out of price chart file * refactor: remove PortfolioArrow * refactor: search row arrow cell * fix: svg prop + snapshots failing unit tests * refactor: css nit
This commit is contained in:
parent
f69226c1d1
commit
bb28235bee
@ -5,13 +5,11 @@ import { useWeb3React } from '@web3-react/core'
|
||||
import { sendAnalyticsEvent, TraceEvent } from 'analytics'
|
||||
import { ButtonEmphasis, ButtonSize, LoadingButtonSpinner, ThemeButton } from 'components/Button'
|
||||
import Column from 'components/Column'
|
||||
import { ArrowChangeDown } from 'components/Icons/ArrowChangeDown'
|
||||
import { ArrowChangeUp } from 'components/Icons/ArrowChangeUp'
|
||||
import { Power } from 'components/Icons/Power'
|
||||
import { Settings } from 'components/Icons/Settings'
|
||||
import { AutoRow } from 'components/Row'
|
||||
import { LoadingBubble } from 'components/Tokens/loading'
|
||||
import { formatDelta } from 'components/Tokens/TokenDetails/PriceChart'
|
||||
import { DeltaArrow, formatDelta } from 'components/Tokens/TokenDetails/Delta'
|
||||
import Tooltip from 'components/Tooltip'
|
||||
import { getConnection } from 'connection'
|
||||
import { useDisableNFTRoutes } from 'hooks/useDisableNFTRoutes'
|
||||
@ -20,11 +18,11 @@ import { useProfilePageState, useSellAsset, useWalletCollections } from 'nft/hoo
|
||||
import { useIsNftClaimAvailable } from 'nft/hooks/useIsNftClaimAvailable'
|
||||
import { ProfilePageStateType } from 'nft/types'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { CreditCard, IconProps, Info } from 'react-feather'
|
||||
import { CreditCard, Info } from 'react-feather'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useAppDispatch } from 'state/hooks'
|
||||
import { updateSelectedWallet } from 'state/user/reducer'
|
||||
import styled, { useTheme } from 'styled-components'
|
||||
import styled from 'styled-components'
|
||||
import { CopyHelper, ExternalLink, ThemedText } from 'theme'
|
||||
import { shortenAddress } from 'utils'
|
||||
import { formatNumber, NumberType } from 'utils/formatNumbers'
|
||||
@ -151,15 +149,6 @@ const PortfolioDrawerContainer = styled(Column)`
|
||||
flex: 1;
|
||||
`
|
||||
|
||||
export function PortfolioArrow({ change, ...rest }: { change: number } & IconProps) {
|
||||
const theme = useTheme()
|
||||
return change < 0 ? (
|
||||
<ArrowChangeDown color={theme.critical} width={16} {...rest} />
|
||||
) : (
|
||||
<ArrowChangeUp color={theme.success} width={16} {...rest} />
|
||||
)
|
||||
}
|
||||
|
||||
export default function AuthenticatedHeader({ account, openSettings }: { account: string; openSettings: () => void }) {
|
||||
const { connector } = useWeb3React()
|
||||
const { ENSName } = useENSName(account)
|
||||
@ -287,7 +276,7 @@ export default function AuthenticatedHeader({ account, openSettings }: { account
|
||||
<AutoRow marginBottom="20px">
|
||||
{absoluteChange !== 0 && percentChange && (
|
||||
<>
|
||||
<PortfolioArrow change={absoluteChange as number} />
|
||||
<DeltaArrow delta={absoluteChange} />
|
||||
<ThemedText.BodySecondary>
|
||||
{`${formatNumber({
|
||||
input: Math.abs(absoluteChange as number),
|
||||
|
@ -2,7 +2,7 @@ import { BrowserEvent, InterfaceElementName, SharedEventName } from '@uniswap/an
|
||||
import { TraceEvent } from 'analytics'
|
||||
import { useCachedPortfolioBalancesQuery } from 'components/AccountDrawer/PrefetchBalancesWrapper'
|
||||
import Row from 'components/Row'
|
||||
import { formatDelta } from 'components/Tokens/TokenDetails/PriceChart'
|
||||
import { DeltaArrow, formatDelta } from 'components/Tokens/TokenDetails/Delta'
|
||||
import { TokenBalance } from 'graphql/data/__generated__/types-and-hooks'
|
||||
import { getTokenDetailsURL, gqlToCurrency, logSentryErrorForUnsupportedChain } from 'graphql/data/util'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
@ -15,7 +15,6 @@ import { formatNumber, NumberType } from 'utils/formatNumbers'
|
||||
import { splitHiddenTokens } from 'utils/splitHiddenTokens'
|
||||
|
||||
import { useToggleAccountDrawer } from '../..'
|
||||
import { PortfolioArrow } from '../../AuthenticatedHeader'
|
||||
import { hideSmallBalancesAtom } from '../../SmallBalanceToggle'
|
||||
import { ExpandoRow } from '../ExpandoRow'
|
||||
import { PortfolioLogo } from '../PortfolioLogo'
|
||||
@ -115,7 +114,7 @@ function TokenRow({ token, quantity, denominatedValue, tokenProjectMarket }: Tok
|
||||
})}
|
||||
</ThemedText.SubHeader>
|
||||
<Row justify="flex-end">
|
||||
<PortfolioArrow change={percentChange} size={20} strokeWidth={1.75} />
|
||||
<DeltaArrow delta={percentChange} />
|
||||
<ThemedText.BodySecondary>{formatDelta(percentChange)}</ThemedText.BodySecondary>
|
||||
</Row>
|
||||
</>
|
||||
|
@ -20,18 +20,15 @@ import styled from 'styled-components'
|
||||
import { ThemedText } from 'theme'
|
||||
import { formatUSDPrice } from 'utils/formatNumbers'
|
||||
|
||||
import { DeltaText, getDeltaArrow } from '../Tokens/TokenDetails/PriceChart'
|
||||
import { DeltaArrow, DeltaText } from '../Tokens/TokenDetails/Delta'
|
||||
import { useAddRecentlySearchedAsset } from './RecentlySearchedAssets'
|
||||
import * as styles from './SearchBar.css'
|
||||
|
||||
const PriceChangeContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`
|
||||
|
||||
const ArrowCell = styled.span`
|
||||
padding-top: 4px;
|
||||
padding-right: 2px;
|
||||
gap: 2px;
|
||||
`
|
||||
|
||||
interface CollectionRowProps {
|
||||
@ -156,8 +153,6 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index,
|
||||
}
|
||||
}, [toggleOpen, isHovered, token, navigate, handleClick, tokenDetailsPath])
|
||||
|
||||
const arrow = getDeltaArrow(token.market?.pricePercentChange?.value, 16)
|
||||
|
||||
return (
|
||||
<Link
|
||||
data-testid={`searchbar-token-row-${token.chain}-${token.address ?? 'NATIVE'}`}
|
||||
@ -192,7 +187,7 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index,
|
||||
<Box className={styles.primaryText}>{formatUSDPrice(token.market.price.value)}</Box>
|
||||
</Row>
|
||||
<PriceChangeContainer>
|
||||
<ArrowCell>{arrow}</ArrowCell>
|
||||
<DeltaArrow delta={token.market?.pricePercentChange?.value} />
|
||||
<ThemedText.BodySmall>
|
||||
<DeltaText delta={token.market?.pricePercentChange?.value}>
|
||||
{Math.abs(token.market?.pricePercentChange?.value ?? 0).toFixed(2)}%
|
||||
|
47
src/components/Tokens/TokenDetails/Delta.tsx
Normal file
47
src/components/Tokens/TokenDetails/Delta.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import { ArrowChangeDown } from 'components/Icons/ArrowChangeDown'
|
||||
import { ArrowChangeUp } from 'components/Icons/ArrowChangeUp'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const StyledUpArrow = styled(ArrowChangeUp)<{ $noColor?: boolean }>`
|
||||
color: ${({ theme, $noColor }) => ($noColor ? theme.neutral2 : theme.success)};
|
||||
`
|
||||
const StyledDownArrow = styled(ArrowChangeDown)<{ $noColor?: boolean }>`
|
||||
color: ${({ theme, $noColor }) => ($noColor ? theme.neutral2 : theme.critical)};
|
||||
`
|
||||
|
||||
export function calculateDelta(start: number, current: number) {
|
||||
return (current / start - 1) * 100
|
||||
}
|
||||
|
||||
function isValidDelta(delta: number | null | undefined): delta is number {
|
||||
// Null-check not including zero
|
||||
return delta !== null && delta !== undefined && delta !== Infinity && !isNaN(delta)
|
||||
}
|
||||
|
||||
interface DeltaArrowProps {
|
||||
delta?: number | null
|
||||
noColor?: boolean
|
||||
size?: number
|
||||
}
|
||||
|
||||
export function formatDelta(delta: number | null | undefined) {
|
||||
if (!isValidDelta(delta)) return '-'
|
||||
|
||||
const formattedDelta = Math.abs(delta).toFixed(2) + '%'
|
||||
return formattedDelta
|
||||
}
|
||||
|
||||
export function DeltaArrow({ delta, noColor = false, size = 16 }: DeltaArrowProps) {
|
||||
if (!isValidDelta(delta)) return null
|
||||
|
||||
return Math.sign(delta) < 0 ? (
|
||||
<StyledDownArrow width={size} height={size} key="arrow-down" aria-label="down" $noColor={noColor} />
|
||||
) : (
|
||||
<StyledUpArrow width={size} height={size} key="arrow-up" aria-label="up" $noColor={noColor} />
|
||||
)
|
||||
}
|
||||
|
||||
export const DeltaText = styled.span<{ delta?: number }>`
|
||||
color: ${({ theme, delta }) =>
|
||||
delta !== undefined ? (Math.sign(delta) < 0 ? theme.critical : theme.success) : theme.neutral1};
|
||||
`
|
@ -6,14 +6,12 @@ import { GlyphCircle } from '@visx/glyph'
|
||||
import { Line } from '@visx/shape'
|
||||
import AnimatedInLineChart from 'components/Charts/AnimatedInLineChart'
|
||||
import FadedInLineChart from 'components/Charts/FadeInLineChart'
|
||||
import { ArrowChangeDown } from 'components/Icons/ArrowChangeDown'
|
||||
import { ArrowChangeUp } from 'components/Icons/ArrowChangeUp'
|
||||
import { MouseoverTooltip } from 'components/Tooltip'
|
||||
import { bisect, curveCardinal, NumberValue, scaleLinear, timeDay, timeHour, timeMinute, timeMonth } from 'd3'
|
||||
import { PricePoint, TimePeriod } from 'graphql/data/util'
|
||||
import { useActiveLocale } from 'hooks/useActiveLocale'
|
||||
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { ArrowDownRight, ArrowUpRight, Info, TrendingUp } from 'react-feather'
|
||||
import { Info, TrendingUp } from 'react-feather'
|
||||
import styled, { useTheme } from 'styled-components'
|
||||
import { ThemedText } from 'theme'
|
||||
import { textFadeIn } from 'theme/styles'
|
||||
@ -27,6 +25,8 @@ import {
|
||||
} from 'utils/formatChartTimes'
|
||||
import { formatUSDPrice } from 'utils/formatNumbers'
|
||||
|
||||
import { calculateDelta, DeltaArrow, formatDelta } from './Delta'
|
||||
|
||||
const DATA_EMPTY = { value: 0, timestamp: 0 }
|
||||
|
||||
export function getPriceBounds(pricePoints: PricePoint[]): [number, number] {
|
||||
@ -36,56 +36,6 @@ export function getPriceBounds(pricePoints: PricePoint[]): [number, number] {
|
||||
return [min, max]
|
||||
}
|
||||
|
||||
const StyledUpArrow = styled(ArrowChangeUp)`
|
||||
color: ${({ theme }) => theme.success};
|
||||
`
|
||||
const StyledDownArrow = styled(ArrowChangeDown)`
|
||||
color: ${({ theme }) => theme.critical};
|
||||
`
|
||||
|
||||
const DefaultUpArrow = styled(ArrowUpRight)`
|
||||
color: ${({ theme }) => theme.neutral3};
|
||||
`
|
||||
const DefaultDownArrow = styled(ArrowDownRight)`
|
||||
color: ${({ theme }) => theme.neutral3};
|
||||
`
|
||||
|
||||
function calculateDelta(start: number, current: number) {
|
||||
return (current / start - 1) * 100
|
||||
}
|
||||
|
||||
export function getDeltaArrow(delta: number | null | undefined, iconSize = 16, styled = true) {
|
||||
// Null-check not including zero
|
||||
if (delta === null || delta === undefined) {
|
||||
return null
|
||||
} else if (Math.sign(delta) < 0) {
|
||||
return styled ? (
|
||||
<StyledDownArrow width={iconSize} height={iconSize} key="arrow-down" aria-label="down" />
|
||||
) : (
|
||||
<DefaultDownArrow size={iconSize} key="arrow-down" aria-label="down" />
|
||||
)
|
||||
}
|
||||
return styled ? (
|
||||
<StyledUpArrow width={iconSize} height={iconSize} key="arrow-up" aria-label="up" />
|
||||
) : (
|
||||
<DefaultUpArrow size={iconSize} key="arrow-up" aria-label="up" />
|
||||
)
|
||||
}
|
||||
|
||||
export function formatDelta(delta: number | null | undefined) {
|
||||
// Null-check not including zero
|
||||
if (delta === null || delta === undefined || delta === Infinity || isNaN(delta)) {
|
||||
return '-'
|
||||
}
|
||||
const formattedDelta = Math.abs(delta).toFixed(2) + '%'
|
||||
return formattedDelta
|
||||
}
|
||||
|
||||
export const DeltaText = styled.span<{ delta?: number }>`
|
||||
color: ${({ theme, delta }) =>
|
||||
delta !== undefined ? (Math.sign(delta) < 0 ? theme.critical : theme.success) : theme.neutral1};
|
||||
`
|
||||
|
||||
const ChartHeader = styled.div`
|
||||
position: absolute;
|
||||
${textFadeIn};
|
||||
@ -113,10 +63,6 @@ const DeltaContainer = styled.div`
|
||||
margin-top: 4px;
|
||||
color: ${({ theme }) => theme.neutral2};
|
||||
`
|
||||
export const ArrowCell = styled.div`
|
||||
padding-right: 3px;
|
||||
display: flex;
|
||||
`
|
||||
|
||||
const OutdatedPriceContainer = styled.div`
|
||||
display: flex;
|
||||
@ -151,6 +97,22 @@ function fixChart(prices: PricePoint[] | undefined | null) {
|
||||
const margin = { top: 100, bottom: 48, crosshair: 72 }
|
||||
const timeOptionsHeight = 44
|
||||
|
||||
interface ChartDeltaProps {
|
||||
startingPrice: PricePoint
|
||||
endingPrice: PricePoint
|
||||
noColor?: boolean
|
||||
}
|
||||
|
||||
function ChartDelta({ startingPrice, endingPrice, noColor }: ChartDeltaProps) {
|
||||
const delta = calculateDelta(startingPrice.value, endingPrice.value)
|
||||
return (
|
||||
<DeltaContainer>
|
||||
{formatDelta(delta)}
|
||||
<DeltaArrow delta={delta} noColor={noColor} />
|
||||
</DeltaContainer>
|
||||
)
|
||||
}
|
||||
|
||||
interface PriceChartProps {
|
||||
width: number
|
||||
height: number
|
||||
@ -202,10 +164,6 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
|
||||
return DATA_EMPTY
|
||||
}, [prices])
|
||||
|
||||
const totalDelta = calculateDelta(firstPrice.value, lastPrice.value)
|
||||
const formattedTotalDelta = formatDelta(totalDelta)
|
||||
const defaultArrow = getDeltaArrow(totalDelta, 20, false)
|
||||
|
||||
// first price point on the x-axis of the current time period's chart
|
||||
const startingPrice = originalPrices?.[0] ?? DATA_EMPTY
|
||||
// last price point on the x-axis of the current time period's chart
|
||||
@ -334,9 +292,6 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
|
||||
}
|
||||
|
||||
const updatedTicks = maxTicks > 0 ? (ticks.length > maxTicks ? calculateTicks(ticks) : ticks) : []
|
||||
const delta = calculateDelta(startingPrice.value, displayPrice.value)
|
||||
const formattedDelta = formatDelta(delta)
|
||||
const arrow = getDeltaArrow(delta)
|
||||
const crosshairEdgeMax = width * 0.85
|
||||
const crosshairAtEdge = !!crosshair && crosshair > crosshairEdgeMax
|
||||
|
||||
@ -355,10 +310,7 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
|
||||
{displayPrice.value ? (
|
||||
<>
|
||||
<TokenPrice>{formatUSDPrice(displayPrice.value)}</TokenPrice>
|
||||
<DeltaContainer>
|
||||
{formattedDelta}
|
||||
<ArrowCell>{arrow}</ArrowCell>
|
||||
</DeltaContainer>
|
||||
<ChartDelta startingPrice={startingPrice} endingPrice={displayPrice} />
|
||||
</>
|
||||
) : lastPrice.value ? (
|
||||
<OutdatedContainer>
|
||||
@ -368,10 +320,7 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
|
||||
<Info size={16} />
|
||||
</MouseoverTooltip>
|
||||
</OutdatedPriceContainer>
|
||||
<DeltaContainer>
|
||||
{formattedTotalDelta}
|
||||
<ArrowCell>{defaultArrow}</ArrowCell>
|
||||
</DeltaContainer>
|
||||
<ChartDelta startingPrice={firstPrice} endingPrice={lastPrice} noColor />
|
||||
</OutdatedContainer>
|
||||
) : (
|
||||
<>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
exports[`PriceChart renders correctly with all prices filled 1`] = `
|
||||
<DocumentFragment>
|
||||
.c4 {
|
||||
.c3 {
|
||||
color: #40B66B;
|
||||
}
|
||||
|
||||
@ -34,14 +34,6 @@ exports[`PriceChart renders correctly with all prices filled 1`] = `
|
||||
color: #7D7D7D;
|
||||
}
|
||||
|
||||
.c3 {
|
||||
padding-right: 3px;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
<div
|
||||
class="c0"
|
||||
data-cy="chart-header"
|
||||
@ -55,12 +47,9 @@ exports[`PriceChart renders correctly with all prices filled 1`] = `
|
||||
class="c2"
|
||||
>
|
||||
0.00%
|
||||
<div
|
||||
class="c3"
|
||||
>
|
||||
<svg
|
||||
aria-label="up"
|
||||
class="c4"
|
||||
class="c3"
|
||||
fill="none"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
@ -74,7 +63,6 @@ exports[`PriceChart renders correctly with all prices filled 1`] = `
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
data-cy="price-chart"
|
||||
height="392"
|
||||
@ -426,8 +414,8 @@ exports[`PriceChart renders correctly with some prices filled 1`] = `
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.c7 {
|
||||
color: #CECECE;
|
||||
.c6 {
|
||||
color: #7D7D7D;
|
||||
}
|
||||
|
||||
.c0 {
|
||||
@ -462,14 +450,6 @@ exports[`PriceChart renders correctly with some prices filled 1`] = `
|
||||
color: #7D7D7D;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
padding-right: 3px;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c2 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
@ -535,36 +515,23 @@ exports[`PriceChart renders correctly with some prices filled 1`] = `
|
||||
class="c5"
|
||||
>
|
||||
0.00%
|
||||
<div
|
||||
class="c6"
|
||||
>
|
||||
<svg
|
||||
aria-label="up"
|
||||
class="c7"
|
||||
class="c6"
|
||||
fill="none"
|
||||
height="20"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
width="16"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<line
|
||||
x1="7"
|
||||
x2="17"
|
||||
y1="17"
|
||||
y2="7"
|
||||
/>
|
||||
<polyline
|
||||
points="7 7 17 7 17 17"
|
||||
<path
|
||||
d="M13.3021 7.7547L17.6821 14.2475C18.4182 15.3388 17.7942 17 16.6482 17L7.3518 17C6.2058 17 5.5818 15.3376 6.3179 14.2475L10.6979 7.7547C11.377 6.7484 12.623 6.7484 13.3021 7.7547Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
data-cy="price-chart"
|
||||
height="392"
|
||||
|
@ -33,7 +33,7 @@ import {
|
||||
TokenSortMethod,
|
||||
useSetSortMethod,
|
||||
} from '../state'
|
||||
import { ArrowCell, DeltaText, formatDelta, getDeltaArrow } from '../TokenDetails/PriceChart'
|
||||
import { DeltaArrow, DeltaText, formatDelta } from '../TokenDetails/Delta'
|
||||
|
||||
const Cell = styled.div`
|
||||
display: flex;
|
||||
@ -103,8 +103,9 @@ const StyledTokenRow = styled.div<{
|
||||
}
|
||||
`
|
||||
|
||||
const ClickableContent = styled.div`
|
||||
const ClickableContent = styled.div<{ gap?: number }>`
|
||||
display: flex;
|
||||
${({ gap }) => gap && `gap: ${gap}px`};
|
||||
text-decoration: none;
|
||||
color: ${({ theme }) => theme.neutral1};
|
||||
align-items: center;
|
||||
@ -184,6 +185,7 @@ const PercentChangeInfoCell = styled(Cell)`
|
||||
|
||||
@media only screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) {
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
justify-content: flex-end;
|
||||
color: ${({ theme }) => theme.neutral2};
|
||||
font-size: 12px;
|
||||
@ -445,8 +447,6 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
|
||||
const chainId = supportedChainIdFromGQLChain(filterNetwork)
|
||||
const timePeriod = useAtomValue(filterTimeAtom)
|
||||
const delta = token.market?.pricePercentChange?.value
|
||||
const arrow = getDeltaArrow(delta)
|
||||
const smallArrow = getDeltaArrow(delta, 14)
|
||||
const formattedDelta = formatDelta(delta)
|
||||
|
||||
const exploreTokenSelectedEventProperties = {
|
||||
@ -489,15 +489,15 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
|
||||
<PriceInfoCell>
|
||||
{price}
|
||||
<PercentChangeInfoCell>
|
||||
<ArrowCell>{smallArrow}</ArrowCell>
|
||||
<DeltaArrow delta={delta} size={14} />
|
||||
<DeltaText delta={delta}>{formattedDelta}</DeltaText>
|
||||
</PercentChangeInfoCell>
|
||||
</PriceInfoCell>
|
||||
</ClickableContent>
|
||||
}
|
||||
percentChange={
|
||||
<ClickableContent>
|
||||
<ArrowCell>{arrow}</ArrowCell>
|
||||
<ClickableContent gap={3}>
|
||||
<DeltaArrow delta={delta} />
|
||||
<DeltaText delta={delta}>{formattedDelta}</DeltaText>
|
||||
</ClickableContent>
|
||||
}
|
||||
|
@ -2,22 +2,14 @@
|
||||
|
||||
exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
<DocumentFragment>
|
||||
.c18 {
|
||||
color: #40B66B;
|
||||
}
|
||||
|
||||
.c19 {
|
||||
color: #40B66B;
|
||||
}
|
||||
|
||||
.c20 {
|
||||
color: #40B66B;
|
||||
}
|
||||
|
||||
.c18 {
|
||||
padding-right: 3px;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c9 {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 250ms ease-in;
|
||||
@ -113,6 +105,22 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.c21 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
color: #222222;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
gap: 8px;
|
||||
max-width: 100%;
|
||||
@ -156,7 +164,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.c21 {
|
||||
.c20 {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
@ -264,7 +272,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
}
|
||||
|
||||
@media only screen and (max-width:540px) {
|
||||
.c21 {
|
||||
.c20 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@ -275,6 +283,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
-webkit-box-pack: end;
|
||||
-webkit-justify-content: flex-end;
|
||||
-ms-flex-pack: end;
|
||||
@ -407,13 +416,10 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
$1.00
|
||||
<div
|
||||
class="c2 c17"
|
||||
>
|
||||
<div
|
||||
class="c18"
|
||||
>
|
||||
<svg
|
||||
aria-label="up"
|
||||
class="c19"
|
||||
class="c18"
|
||||
fill="none"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
@ -425,9 +431,8 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
class="c20"
|
||||
class="c19"
|
||||
>
|
||||
0.00%
|
||||
</span>
|
||||
@ -436,18 +441,15 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c2 c14 c21"
|
||||
class="c2 c14 c20"
|
||||
data-testid="percent-change-cell"
|
||||
>
|
||||
<div
|
||||
class="c5"
|
||||
>
|
||||
<div
|
||||
class="c18"
|
||||
class="c21"
|
||||
>
|
||||
<svg
|
||||
aria-label="up"
|
||||
class="c19"
|
||||
class="c18"
|
||||
fill="none"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
@ -459,9 +461,8 @@ exports[`LoadedRow.tsx renders a row 1`] = `
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
class="c20"
|
||||
class="c19"
|
||||
>
|
||||
0.00%
|
||||
</span>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getDeltaArrow } from 'components/Tokens/TokenDetails/PriceChart'
|
||||
import { DeltaArrow } from 'components/Tokens/TokenDetails/Delta'
|
||||
import { useScreenSize } from 'hooks/useScreenSize'
|
||||
import { Box, BoxProps } from 'nft/components/Box'
|
||||
import { Column, Row } from 'nft/components/Flex'
|
||||
@ -352,7 +352,6 @@ const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMob
|
||||
const floorPriceStr = floorFormatter(stats.stats?.floor_price ?? 0)
|
||||
// graphQL formatted %age values out of 100, whereas v3 endpoint did a decimal between 0 & 1
|
||||
const floorChangeStr = Math.round(Math.abs(stats?.stats?.one_day_floor_change ?? 0))
|
||||
const arrow = stats?.stats?.one_day_floor_change ? getDeltaArrow(stats.stats.one_day_floor_change) : undefined
|
||||
|
||||
const isBagExpanded = useBag((state) => state.bagExpanded)
|
||||
const isScreenSize = useScreenSize()
|
||||
@ -372,7 +371,7 @@ const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMob
|
||||
{stats.stats?.one_day_floor_change !== undefined ? (
|
||||
<StatsItem label="Floor 24H" shouldHide={false}>
|
||||
<PercentChange isNegative={stats.stats.one_day_floor_change < 0}>
|
||||
{arrow}
|
||||
<DeltaArrow delta={stats?.stats?.one_day_floor_change} />
|
||||
{floorChangeStr}%
|
||||
</PercentChange>
|
||||
</StatsItem>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { formatEther } from '@ethersproject/units'
|
||||
import { ArrowChangeDown } from 'components/Icons/ArrowChangeDown'
|
||||
import { ArrowChangeUp } from 'components/Icons/ArrowChangeUp'
|
||||
import { DeltaArrow } from 'components/Tokens/TokenDetails/Delta'
|
||||
import { VerifiedIcon } from 'nft/components/icons'
|
||||
import { useIsMobile } from 'nft/hooks'
|
||||
import { Denomination } from 'nft/types'
|
||||
@ -162,11 +161,7 @@ export const ChangeCell = ({ change, children }: { children?: ReactNode; change?
|
||||
const TextComponent = isMobile ? ThemedText.BodySmall : ThemedText.BodyPrimary
|
||||
return (
|
||||
<ChangeCellContainer change={change ?? 0}>
|
||||
{!change || change > 0 ? (
|
||||
<ArrowChangeUp width="16px" height="16px" />
|
||||
) : (
|
||||
<ArrowChangeDown width="16px" height="16px" />
|
||||
)}
|
||||
<DeltaArrow delta={change} />
|
||||
<TextComponent color="currentColor">{children || `${change ? Math.abs(Math.round(change)) : 0}%`}</TextComponent>
|
||||
</ChangeCellContainer>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user