Skip to content

Commit

Permalink
feat: new warning UI in toolbar (#568)
Browse files Browse the repository at this point in the history
* feat: new warning UI in toolbar

* feat: updates w/ input from design

* fix: address comments

* fix: comment and test update
  • Loading branch information
just-toby authored Mar 31, 2023
1 parent c382859 commit c60952f
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 51 deletions.
4 changes: 3 additions & 1 deletion src/components/Swap/PriceImpactRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ export function PriceImpactRow({ impact, reverse, tooltipText }: PriceImpactProp
return (
<Row gap={0.25} flex align="center" flow={reverse ? 'row-reverse' : 'row wrap'}>
<ThemedText.Body2 userSelect={false} color={impact.warning ?? 'hint'}>
<TooltipText text={`(${formatPriceImpact(impact?.percent)})`}>{tooltipText}</TooltipText>
<TooltipText text={`(${formatPriceImpact(impact?.percent)})`}>
<ThemedText.Caption>{tooltipText}</ThemedText.Caption>
</TooltipText>
</ThemedText.Body2>
{impact?.warning && (
<Tooltip icon={AlertTriangle} iconProps={{ color: impact.warning }} data-testid="alert-tooltip">
Expand Down
3 changes: 2 additions & 1 deletion src/components/Swap/Settings/TransactionTtlInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import { Expando as ExpandoIcon } from 'icons'
import { useRef, useState } from 'react'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'
import { WIDGET_BREAKPOINTS } from 'theme/breakpoints'

import { Label } from './components'

const Input = styled(Row)`
${inputCss};
background-color: transparent;
max-width: 360px;
max-width: ${WIDGET_BREAKPOINTS.EXTRA_SMALL}px;
input {
text-align: right;
Expand Down
89 changes: 47 additions & 42 deletions src/components/Swap/Toolbar/Caption.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { Trans } from '@lingui/macro'
import { Placement } from '@popperjs/core'
import { formatPriceImpact } from '@uniswap/conedison/format'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import Row from 'components/Row'
import Tooltip from 'components/Tooltip'
import { loadingCss } from 'css/loading'
import { PriceImpact as PriceImpactType } from 'hooks/usePriceImpact'
import { useIsWideWidget } from 'hooks/useWidgetWidth'
import { useIsWideWidget, useWidgetWidth } from 'hooks/useWidgetWidth'
import { AlertTriangle, ChevronDown, Icon, Info, LargeIcon, Spinner } from 'icons'
import { ReactNode, useCallback } from 'react'
import { InterfaceTrade } from 'state/routing/types'
import styled from 'styled-components/macro'
import styled, { css } from 'styled-components/macro'
import { AnimationSpeed, Color, ThemedText } from 'theme'
import { WIDGET_BREAKPOINTS } from 'theme/breakpoints'

import Price from '../Price'
import { GasEstimateTooltip, TradeTooltip } from './GasEstimateTooltip'
Expand Down Expand Up @@ -139,10 +138,36 @@ export interface TradeProps {

interface ExpandProps {
expanded: boolean
}
warning?: 'warning' | 'error'
}

const ExpanderRow = styled(Row)<{ $expanded: boolean; warning?: 'warning' | 'error' }>`
${({ warning, $expanded }) => {
if (!warning) return undefined
return css`
background-color: ${({ theme }) =>
$expanded ? 'transparent' : warning === 'error' ? theme.criticalSoft : theme.warningSoft};
border-radius: ${({ theme }) => theme.borderRadius.xsmall}rem;
padding: 0.375rem 0.5rem 0.375rem 0.375rem;
transition: background-color ${AnimationSpeed.Medium} linear, padding ${AnimationSpeed.Medium} linear,
width ${AnimationSpeed.Medium} linear;
`
}}
`

function Expander({ expanded }: ExpandProps) {
return <ExpandIcon $expanded={expanded} />
function Expander({ expanded, warning }: ExpandProps) {
return (
<ExpanderRow $expanded={expanded} warning={warning} gap={0.5}>
{warning && !expanded && (
<Tooltip icon={AlertTriangle} iconProps={{ color: warning }} placement="auto">
<ThemedText.Caption>
<Trans>Your trade will have a high impact on the market price of this pool.</Trans>
</ThemedText.Caption>
</Tooltip>
)}
<ExpandIcon $expanded={expanded} color={expanded ? undefined : warning} />
</ExpanderRow>
)
}

export function Trade({
Expand All @@ -151,59 +176,39 @@ export function Trade({
gasUseEstimateUSD,
expanded,
loading,
warning,
}: TradeProps & TradeTooltip & ExpandProps) {
const widgetWidth = useWidgetWidth()
// The USD value doesn't fit in the widget at small sizes when we show the warning UI.
const shouldHideUSD = widgetWidth < WIDGET_BREAKPOINTS.EXTRA_SMALL && warning && !expanded
return (
<>
<Caption
caption={
<ThemedText.Body2 opacity={loading ? 0.4 : 1}>
<Price trade={trade} outputUSDC={outputUSDC} />
<Price trade={trade} outputUSDC={shouldHideUSD ? undefined : outputUSDC} />
</ThemedText.Body2>
}
icon={loading ? Spinner : null}
/>
<CaptionRow gap={0.75}>
{!expanded && (
<CaptionRow gap={0.25}>
<GasEstimateTooltip gasUseEstimateUSD={gasUseEstimateUSD} trade={trade} />
</CaptionRow>
)}
<Expander expanded={expanded} />
</CaptionRow>
{!loading && (
<CaptionRow gap={0.75}>
{!expanded && (
<CaptionRow gap={0.25}>
<GasEstimateTooltip gasUseEstimateUSD={gasUseEstimateUSD} trade={trade} />
</CaptionRow>
)}
<Expander expanded={expanded} warning={warning} />
</CaptionRow>
)}
</>
)
}

interface PriceImpactProps {
impact: PriceImpactType
}

export function PriceImpactWarningTooltipContent() {
return (
<ThemedText.Caption>
There will be a large difference between your input and output values due to current liquidity.
</ThemedText.Caption>
)
}

export function PriceImpact({ impact, expanded }: PriceImpactProps & ExpandProps) {
return (
<>
<Caption
icon={AlertTriangle}
caption="High price impact"
color={impact.warning}
tooltip={{
placement: 'auto',
content: <PriceImpactWarningTooltipContent />,
}}
/>
<CaptionRow gap={0.75}>
<ThemedText.Body2 userSelect={false} color={impact.warning}>
{formatPriceImpact(impact?.percent)}
</ThemedText.Body2>
<Expander expanded={expanded} />
</CaptionRow>
</>
)
}
6 changes: 4 additions & 2 deletions src/components/Swap/Toolbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ function CaptionRow() {
gasUseEstimateUSD={open ? null : gasUseEstimateUSD}
expanded={open}
loading={state === TradeState.LOADING}
warning={impact?.warning}
/>
),
isExpandable: true,
Expand All @@ -95,14 +96,15 @@ function CaptionRow() {
}, [
error,
state,
trade,
inputCurrency,
outputCurrency,
isAmountPopulated,
gasUseEstimateUSD,
isWrap,
trade,
open,
outputUSDC,
open,
impact?.warning,
])

const maybeToggleOpen = useCallback(() => {
Expand Down
5 changes: 3 additions & 2 deletions src/components/WidgetWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { WidgetWidthProvider } from 'hooks/useWidgetWidth'
import { PropsWithChildren, useEffect, useMemo, useRef, useState } from 'react'
import ResizeObserver from 'resize-observer-polyfill'
import styled from 'styled-components/macro'
import { WIDGET_BREAKPOINTS } from 'theme/breakpoints'
import toLength from 'utils/toLength'

const ROOT_CONTAINER_PADDING = 8
Expand Down Expand Up @@ -49,7 +50,7 @@ export default function WidgetWrapper(props: PropsWithChildren<WidgetWrapperProp
return 600
}
}
return props.width ?? 360
return props.width ?? WIDGET_BREAKPOINTS.EXTRA_SMALL
}, [props.width])

/**
Expand All @@ -59,7 +60,7 @@ export default function WidgetWrapper(props: PropsWithChildren<WidgetWrapperProp
const ref = useRef<HTMLDivElement>(null)
const [wrapperWidth, setWidgetWidth] = useState<number>(
toLength(initialWidth) === initialWidth
? 360 // If the initial width is a string, use default width until the ResizeObserver gives us the true width as a number.
? WIDGET_BREAKPOINTS.EXTRA_SMALL // If the initial width is a string, use default width until the ResizeObserver gives us the true width as a number.
: (initialWidth as number)
)
useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/__snapshots__/Header.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ Object {
class="Row-sc-1nzvhrh-0 TransactionTtlInput__InputContainer-sc-1fem02o-1 gQrhhv eMmnPF"
>
<div
class="Row-sc-1nzvhrh-0 TransactionTtlInput__Input-sc-1fem02o-0 fcddMn ehOYyS"
class="Row-sc-1nzvhrh-0 TransactionTtlInput__Input-sc-1fem02o-0 fcddMn itTgvP"
>
<input
autocomplete="off"
Expand Down Expand Up @@ -658,7 +658,7 @@ Object {
class="Row-sc-1nzvhrh-0 TransactionTtlInput__InputContainer-sc-1fem02o-1 gQrhhv eMmnPF"
>
<div
class="Row-sc-1nzvhrh-0 TransactionTtlInput__Input-sc-1fem02o-0 fcddMn ehOYyS"
class="Row-sc-1nzvhrh-0 TransactionTtlInput__Input-sc-1fem02o-0 fcddMn itTgvP"
>
<input
autocomplete="off"
Expand Down
3 changes: 2 additions & 1 deletion src/cosmos/SwapSkeleton.fixture.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { darkTheme, defaultTheme, lightTheme, SwapWidgetSkeleton } from '@uniswap/widgets'
import { useEffect } from 'react'
import { useValue } from 'react-cosmos/fixture'
import { WIDGET_BREAKPOINTS } from 'theme/breakpoints'

function Fixture() {
const [width] = useValue('width', { defaultValue: 360 })
const [width] = useValue('width', { defaultValue: WIDGET_BREAKPOINTS.EXTRA_SMALL })
const [theme, setTheme] = useValue('theme', { defaultValue: defaultTheme })
const [darkMode] = useValue('darkMode', { defaultValue: false })
useEffect(() => setTheme((theme) => ({ ...theme, ...(darkMode ? darkTheme : lightTheme) })), [darkMode, setTheme])
Expand Down
2 changes: 2 additions & 0 deletions src/theme/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const defaultBorderRadius = {
large: 1.5,
medium: 1,
small: 0.75,
xsmall: 0.5,
}

export const defaultTheme = {
Expand Down Expand Up @@ -155,6 +156,7 @@ function toDefaultTheme(theme: Required<Theme>): DefaultTheme {
large: clampNum(value.large),
medium: clampNum(value.medium),
small: clampNum(value.small),
xsmall: clampNum(value.xsmall),
}
}
}
1 change: 1 addition & 0 deletions src/theme/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type ThemeBorderRadius = {
large: number
medium: number
small: number
xsmall: number
}

export type ZIndex = {
Expand Down

1 comment on commit c60952f

@vercel
Copy link

@vercel vercel bot commented on c60952f Mar 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

widgets – ./

widgets-git-main-uniswap.vercel.app
widgets-uniswap.vercel.app
widgets-seven-tau.vercel.app

Please sign in to comment.