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 6 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
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 | string
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
11 changes: 8 additions & 3 deletions src/modules/trade/pure/TradeNumberInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ export interface TradeNumberInputProps extends TradeWidgetFieldProps {
min?: number
max?: number
placeholder?: string
inputType?: string
limitPrice?: string
}

export function TradeNumberInput(props: TradeNumberInputProps) {
const { value, suffix, onUserInput, placeholder, decimalsPlaces = 0, min, max = 0 } = props
const { value, suffix, onUserInput, placeholder, decimalsPlaces = 0, min, max = 0, inputType, limitPrice } = props

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

Expand Down Expand Up @@ -57,8 +59,11 @@ export function TradeNumberInput(props: TradeNumberInputProps) {
return (
<TradeWidgetField {...props}>
<>
<NumericalInput placeholder={placeholder} value={displayedValue} onUserInput={onChange} />
{suffix && <Suffix>{suffix}</Suffix>}
<em>{inputType === 'priceProtection' && limitPrice && <>{limitPrice}</>}</em>
<span>
<NumericalInput placeholder={placeholder} value={displayedValue} onUserInput={onChange} />
{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
5 changes: 3 additions & 2 deletions src/modules/trade/pure/TradeWidgetField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ export interface TradeWidgetFieldProps {
tooltip?: React.ReactNode | ((params: any) => React.ReactNode)
error?: TradeWidgetFieldError
className?: string
inputType?: string
}

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

return (
<TradeWidgetFieldBox className={className}>
<TradeWidgetFieldBox className={className} inputType={inputType}>
<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<{ inputType?: string }>`
background: ${({ theme, inputType }) => (inputType === 'priceProtection' ? 'transparent' : theme.grey1)};
border: 1px solid ${({ theme, inputType }) => (inputType === 'priceProtection' ? theme.grey1 : 0)};
border-radius: 16px;
min-height: 45px;
font-size: 18px;
padding: 10px 16px;
padding: ${({ inputType }) => (inputType === 'priceProtection' ? '0' : '10px 16px')};
display: flex;
justify-content: space-between;
align-items: center;
flex-flow: row wrap;
flex: 1;
gap: 3px;

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

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

> em {
font-style: normal;
}

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

${({ inputType }) =>
inputType === 'priceProtection' &&
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;
}
`}
}
`
27 changes: 14 additions & 13 deletions src/modules/twap/containers/TwapFormWidget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,18 @@ export function TwapFormWidget() {
<styledEl.StyledRateInfo label={LABELS_TOOLTIPS.price.label} rateInfoParams={rateInfoParams} />
</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)}
inputType="priceProtection"
limitPrice={'1484.45 USDC'} // TODO: add real dynamic limit price
suffix="%"
/>
<styledEl.Row>
<TradeNumberInput
value={numberOfPartsValue}
Expand All @@ -104,20 +115,8 @@ export function TwapFormWidget() {
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 @@ -135,6 +134,8 @@ export function TwapFormWidget() {
</TradeTextBox>
</styledEl.Row>

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

<TwapFormWarnings localFormValidation={localFormValidation} />
<ActionButtons localFormValidation={localFormValidation} primaryFormValidation={primaryFormValidation} />
</>
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%;
`
36 changes: 28 additions & 8 deletions src/modules/twap/containers/TwapFormWidget/tooltips.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import SVG from 'react-inlinesvg'
import styled from 'styled-components/macro'

import ShieldImage from 'legacy/assets/cow-swap/protection.svg'

import { deadlinePartsDisplay } from 'modules/twap/utils/deadlinePartsDisplay'

const IconImage = styled.div`
display: flex;
align-items: center;
justify-content: center;

> svg {
opacity: 0.5;
fill: ${({ theme }) => theme.text1};
margin: 0 3px 0 0;
}
`

export interface LabelTooltip {
label: string
label: React.ReactNode | string
tooltip?: React.ReactNode | ((params: any) => React.ReactNode)
}

Expand Down Expand Up @@ -42,19 +59,22 @@ export const LABELS_TOOLTIPS: LabelTooltipItems = {
),
},
slippage: {
label: 'Slippage',
label: (
<>
<IconImage>
<SVG src={ShieldImage} width="16" height="16" title="Price protection" />
</IconImage>{' '}
Price protection
</>
),
tooltip: (
<>
This slippage will apply to each part of your order. Since a TWAP order executes over a longer period of time,
your slippage should take into account possible price fluctuations over that time.
<br />
<br />
If your slippage is too low, you risk some parts of your order failing to execute.
Your TWAP order won't execute and is protected if the market price dips more than your set slippage tolerance.
</>
),
},
price: {
label: 'Current market price',
label: 'Price',
tooltip: 'This is the current market price',
},
sellAmount: {
Expand Down