Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP > feat: twap form styling WIP #2785

Merged
merged 15 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/common/pure/ExecutionPrice/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,28 @@ export interface ExecutionPriceProps {
executionPrice: Price<Currency, Currency>
isInverted: boolean
showBaseCurrency?: boolean
hideSeparator?: boolean
separatorSymbol?: string
hideFiat?: boolean
}

export function ExecutionPrice({
executionPrice,
isInverted,
showBaseCurrency,
separatorSymbol = '≈',
hideSeparator,
hideFiat,
}: ExecutionPriceProps) {
const executionPriceFiat = useExecutionPriceFiat(executionPrice, isInverted)
const executionPriceFiat = useExecutionPriceFiat(hideFiat ? null : executionPrice, isInverted)
const quoteCurrency = isInverted ? executionPrice?.baseCurrency : executionPrice?.quoteCurrency
const baseCurrency = isInverted ? executionPrice?.quoteCurrency : executionPrice?.baseCurrency
const oneBaseCurrency = tryParseCurrencyAmount('1', baseCurrency)

return (
<span>
{showBaseCurrency && <TokenAmount amount={oneBaseCurrency} tokenSymbol={baseCurrency} />}
{` ${separatorSymbol} `}
{!hideSeparator && ` ${separatorSymbol} `}
<TokenAmount amount={isInverted ? executionPrice.invert() : executionPrice} tokenSymbol={quoteCurrency} />
{executionPriceFiat && (
<i>
Expand Down
2 changes: 1 addition & 1 deletion src/common/pure/RateInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface RateInfoParams {

export interface RateInfoProps {
className?: string
label?: string
label?: React.ReactNode
stylized?: boolean
noLabel?: boolean
prependSymbol?: boolean
Expand Down
1 change: 1 addition & 0 deletions src/legacy/assets/cow-swap/protection.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function AdvancedOrdersWidget({ children }: { children: JSX.Element }) {

const params = {
recipient,
compactView: false,
compactView: true,
showRecipient: false,
isTradePriceUpdating,
priceImpact,
Expand Down
31 changes: 22 additions & 9 deletions src/modules/trade/pure/TradeNumberInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,20 @@ export interface TradeNumberInputProps extends TradeWidgetFieldProps {
min?: number
max?: number
placeholder?: string
prefixComponent?: React.ReactElement
}

export function TradeNumberInput(props: TradeNumberInputProps) {
const { value, suffix, onUserInput, placeholder = '0', decimalsPlaces = 0, min, max = 100_000 } = props
const {
value,
suffix,
onUserInput,
placeholder = '0',
decimalsPlaces = 0,
min,
max = 100_000,
Copy link
Contributor

Choose a reason for hiding this comment

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

why max is 100K?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

a bit arbitrary, but ooook

Copy link
Collaborator

Choose a reason for hiding this comment

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

100% arbitrary yes!

Open to suggestions

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there any reason why we would ever want to have an order with more than 100k parts?

prefixComponent,
} = props

const [displayedValue, setDisplayedValue] = useState(value === null ? '' : value.toString())

Expand Down Expand Up @@ -55,15 +65,18 @@ export function TradeNumberInput(props: TradeNumberInputProps) {
}, [])

return (
<TradeWidgetField {...props}>
<TradeWidgetField {...props} hasPrefix={!!prefixComponent}>
<>
<NumericalInput
placeholder={placeholder}
value={displayedValue}
onBlur={(e) => validateInput(e.target.value)}
onUserInput={(value) => setDisplayedValue(value)}
/>
{suffix && <Suffix>{suffix}</Suffix>}
{prefixComponent}
<span>
<NumericalInput
placeholder={placeholder}
value={displayedValue}
onBlur={(e) => validateInput(e.target.value)}
onUserInput={(value) => setDisplayedValue(value)}
/>
{suffix && <Suffix>{suffix}</Suffix>}
</span>
</>
</TradeWidgetField>
)
Expand Down
4 changes: 3 additions & 1 deletion src/modules/trade/pure/TradeNumberInput/styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import styled from 'styled-components/macro'
import Input from 'legacy/components/NumericalInput'

export const Suffix = styled.span`
margin-left: 5px;
margin: 0 0 0 3px;
opacity: 0.7;
font-weight: 600;
`
export const NumericalInput = styled(Input)<{ color?: string }>`
color: ${({ theme, color }) => {
Expand Down
7 changes: 4 additions & 3 deletions src/modules/trade/pure/TradeWidgetField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Trans } from '@lingui/macro'
import QuestionHelper from 'legacy/components/QuestionHelper'
import { renderTooltip } from 'legacy/components/Tooltip'

import { TradeWidgetFieldBox, TradeWidgetFieldLabel, Content, ErrorText } from './styled'
import { Content, ErrorText, TradeWidgetFieldBox, TradeWidgetFieldLabel } from './styled'

export type TradeWidgetFieldError = { type: 'error' | 'warning'; text: string | null } | null

Expand All @@ -15,14 +15,15 @@ export interface TradeWidgetFieldProps {
tooltip?: React.ReactNode | ((params: any) => React.ReactNode)
error?: TradeWidgetFieldError
className?: string
hasPrefix?: boolean
}

export function TradeWidgetField(props: TradeWidgetFieldProps) {
const { className, children, label, tooltip, error } = props
const { className, children, label, tooltip, error, hasPrefix } = props
const tooltipElement = renderTooltip(tooltip, props)

return (
<TradeWidgetFieldBox className={className}>
<TradeWidgetFieldBox className={className} hasPrefix={hasPrefix}>
<TradeWidgetFieldLabel>
<Trans>{label}</Trans>
{tooltip && <QuestionHelper text={tooltipElement} />}
Expand Down
79 changes: 65 additions & 14 deletions src/modules/trade/pure/TradeWidgetField/styled.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import { transparentize } from 'polished'
import styled from 'styled-components/macro'
import styled, { css } from 'styled-components/macro'

export const TradeWidgetFieldBox = styled.div`
background: ${({ theme }) => theme.grey1};
border-radius: 16px;
min-height: 58px;
font-size: 18px;
padding: 16px;
display: flex;
justify-content: space-between;
align-items: center;
flex-flow: row wrap;
flex: 1;
gap: 3px;
`
import { QuestionWrapper } from 'legacy/components/QuestionHelper'

import { NumericalInput } from '../TradeNumberInput/styled'

export const TradeWidgetFieldLabel = styled.span`
color: ${({ theme }) => transparentize(0.3, theme.text1)};
display: flex;
align-items: center;
font-size: 13px;
font-weight: 500;
padding: 0;

${QuestionWrapper} {
opacity: 0.5;
transition: opacity 0.2s ease-in-out;

&:hover {
opacity: 1;
}
}
`

export const Content = styled.div`
display: flex;
align-items: center;
font-weight: 500;
position: relative;
`

export const ErrorText = styled.div<{ type?: 'error' | 'warning' }>`
Expand All @@ -38,3 +39,53 @@ export const ErrorText = styled.div<{ type?: 'error' | 'warning' }>`
font-size: 12px;
margin-top: 5px;
`

export const TradeWidgetFieldBox = styled.div<{ hasPrefix?: boolean }>`
background: ${({ theme, hasPrefix }) => (hasPrefix ? 'transparent' : theme.grey1)};
border: 1px solid ${({ theme, hasPrefix }) => (hasPrefix ? theme.grey1 : 0)};
border-radius: 16px;
min-height: 45px;
font-size: 18px;
padding: 10px 16px;
padding: ${({ hasPrefix }) => (hasPrefix ? '0' : '10px 16px')};
display: flex;
justify-content: space-between;
align-items: center;
flex-flow: row wrap;
flex: 1;
gap: 3px;

${TradeWidgetFieldLabel} {
padding: ${({ hasPrefix }) => (hasPrefix ? '10px 16px' : 'initial')};
}

${Content} {
padding: ${({ hasPrefix }) => (hasPrefix ? '10px 88px 10px 16px' : 'initial')};

> em {
font-style: normal;
}

> span {
display: flex;
align-items: center;
justify-content: flex-end;
background: ${({ theme, hasPrefix }) => (hasPrefix ? theme.grey1 : 'transparent')};

${({ hasPrefix }) =>
hasPrefix &&
css`
position: absolute;
top: -1px;
right: 0;
height: calc(100% + 2px);
width: 76px;
border-radius: 0 15px 15px 0;
padding: 0 16px 0 0;

> ${NumericalInput} {
font-size: 20px;
}
`}
}
`
53 changes: 37 additions & 16 deletions src/modules/twap/containers/TwapFormWidget/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useAtomValue } from 'jotai'
import { useUpdateAtom } from 'jotai/utils'
import { useEffect } from 'react'
import { useEffect, useState } from 'react'

import {
openAdvancedOrdersTabAnalytics,
Expand All @@ -20,7 +20,9 @@ import { TwapFormState } from 'modules/twap/pure/PrimaryActionButton/getTwapForm
import { QuoteObserverUpdater } from 'modules/twap/updaters/QuoteObserverUpdater'
import { useIsSafeApp, useWalletInfo } from 'modules/wallet'

import { usePrice } from 'common/hooks/usePrice'
import { useRateInfoParams } from 'common/hooks/useRateInfoParams'
import { ExecutionPrice } from 'common/pure/ExecutionPrice'

import * as styledEl from './styled'
import { AMOUNT_PARTS_LABELS, LABELS_TOOLTIPS } from './tooltips'
Expand All @@ -35,7 +37,7 @@ import { useTwapFormState } from '../../hooks/useTwapFormState'
import { AmountParts } from '../../pure/AmountParts'
import { DeadlineSelector } from '../../pure/DeadlineSelector'
import { partsStateAtom } from '../../state/partsStateAtom'
import { twapTimeIntervalAtom } from '../../state/twapOrderAtom'
import { twapSlippageAdjustedBuyAmount, twapTimeIntervalAtom } from '../../state/twapOrderAtom'
import {
twapOrderSlippageAtom,
twapOrdersSettingsAtom,
Expand All @@ -57,6 +59,7 @@ export function TwapFormWidget() {

const { numberOfPartsValue, slippageValue, deadline, customDeadline, isCustomDeadline } =
useAtomValue(twapOrdersSettingsAtom)
const buyAmount = useAtomValue(twapSlippageAdjustedBuyAmount)

const { inputCurrencyAmount, outputCurrencyAmount } = useAdvancedOrdersDerivedState()
const { inputCurrencyAmount: rawInputCurrencyAmount } = useAdvancedOrdersRawState()
Expand All @@ -78,6 +81,8 @@ export function TwapFormWidget() {

const rateInfoParams = useRateInfoParams(inputCurrencyAmount, outputCurrencyAmount)

const limitPrice = usePrice(inputCurrencyAmount, buyAmount)

const deadlineState = {
deadline,
customDeadline,
Expand Down Expand Up @@ -110,6 +115,9 @@ export function TwapFormWidget() {
}
}, [account, isFallbackHandlerRequired, isFallbackHandlerCompatible, localFormValidation, verification])

const isInvertedState = useState(false)
const [isInverted] = isInvertedState

return (
<>
<AppDataUpdater orderClass="twap" slippage={twapOrderSlippage} />
Expand All @@ -123,34 +131,45 @@ export function TwapFormWidget() {

{!isWrapOrUnwrap && (
<styledEl.Row>
<styledEl.StyledRateInfo label={LABELS_TOOLTIPS.price.label} rateInfoParams={rateInfoParams} />
<styledEl.StyledRateInfo
label={LABELS_TOOLTIPS.price.label}
rateInfoParams={rateInfoParams}
isInvertedState={isInvertedState}
/>
</styledEl.Row>
)}

<TradeNumberInput
value={slippageValue}
onUserInput={(value: number | null) => updateSettingsState({ slippageValue: value })}
decimalsPlaces={2}
placeholder={DEFAULT_TWAP_SLIPPAGE.toFixed(1)}
max={50}
label={LABELS_TOOLTIPS.slippage.label}
tooltip={renderTooltip(LABELS_TOOLTIPS.slippage.tooltip)}
prefixComponent={
<em>
{limitPrice ? (
<ExecutionPrice executionPrice={limitPrice} isInverted={isInverted} hideFiat hideSeparator />
) : (
'0'
)}
</em>
}
suffix="%"
/>
<styledEl.Row>
<TradeNumberInput
value={numberOfPartsValue}
onUserInput={(value: number | null) =>
updateSettingsState({ numberOfPartsValue: value || DEFAULT_NUM_OF_PARTS })
}
min={DEFAULT_NUM_OF_PARTS}
max={100}
fairlighteth marked this conversation as resolved.
Show resolved Hide resolved
label={LABELS_TOOLTIPS.numberOfParts.label}
tooltip={renderTooltip(LABELS_TOOLTIPS.numberOfParts.tooltip)}
/>
<TradeNumberInput
value={slippageValue}
onUserInput={(value: number | null) => updateSettingsState({ slippageValue: value })}
decimalsPlaces={2}
placeholder={DEFAULT_TWAP_SLIPPAGE.toFixed(1)}
max={50}
label={LABELS_TOOLTIPS.slippage.label}
tooltip={renderTooltip(LABELS_TOOLTIPS.slippage.tooltip)}
suffix="%"
/>
</styledEl.Row>

<AmountParts partsState={partsState} labels={AMOUNT_PARTS_LABELS} />

<styledEl.Row>
<DeadlineSelector
deadline={deadlineState}
Expand All @@ -168,6 +187,8 @@ export function TwapFormWidget() {
</TradeTextBox>
</styledEl.Row>

<AmountParts partsState={partsState} labels={AMOUNT_PARTS_LABELS} />

<TwapFormWarnings localFormValidation={localFormValidation} />
<ActionButtons
fallbackHandlerIsNotSet={isFallbackHandlerRequired}
Expand Down
7 changes: 7 additions & 0 deletions src/modules/twap/containers/TwapFormWidget/styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ export const StyledRateInfo = styled(RateInfo)`
display: grid;
grid-template-columns: max-content auto;
`

export const StyledPriceProtection = styled.div`
display: flex;
flex-flow: row wrap;
align-items: center;
width: 100%;
`
Loading