Skip to content

Commit

Permalink
fix: settings ux (#3282)
Browse files Browse the repository at this point in the history
* fix: max slippage warning logic

* fix: option border specificity

* fix: dialog resizing through animation

* fix: initial warning states

* fix: hide Modal class
  • Loading branch information
zzmp authored Feb 10, 2022
1 parent f47fcc9 commit b4aac94
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 57 deletions.
5 changes: 2 additions & 3 deletions src/lib/components/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,12 @@ export const Modal = styled.div<{ color: Color }>`
border-radius: ${({ theme }) => theme.borderRadius * 0.75}em;
display: flex;
flex-direction: column;
height: calc(100% - 0.5em);
height: 100%;
left: 0;
margin: 0.25em;
overflow: hidden;
position: absolute;
top: 0;
width: calc(100% - 0.5em);
width: 100%;
z-index: ${Layer.DIALOG};
`

Expand Down
60 changes: 25 additions & 35 deletions src/lib/components/Swap/Settings/MaxSlippageSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Percent } from '@uniswap/sdk-core'
import { useAtom } from 'jotai'
import Popover from 'lib/components/Popover'
import { TooltipHandlers, useTooltip } from 'lib/components/Tooltip'
import { toPercent } from 'lib/hooks/useAllowedSlippage'
import { AlertTriangle, Check, Icon, LargeIcon, XOctagon } from 'lib/icons'
import { autoSlippageAtom, MAX_VALID_SLIPPAGE, maxSlippageAtom, MIN_HIGH_SLIPPAGE } from 'lib/state/settings'
import styled, { Color, ThemedText } from 'lib/theme'
Expand Down Expand Up @@ -58,9 +59,17 @@ function Option({
}

enum WarningState {
NONE,
INVALID_SLIPPAGE = 1,
HIGH_SLIPPAGE,
INVALID_SLIPPAGE,
}

function toWarningState(percent: Percent | undefined): WarningState | undefined {
if (percent?.greaterThan(MAX_VALID_SLIPPAGE)) {
return WarningState.INVALID_SLIPPAGE
} else if (percent?.greaterThan(MIN_HIGH_SLIPPAGE)) {
return WarningState.HIGH_SLIPPAGE
}
return
}

const Warning = memo(function Warning({ state, showTooltip }: { state: WarningState; showTooltip: boolean }) {
Expand All @@ -80,8 +89,6 @@ const Warning = memo(function Warning({ state, showTooltip }: { state: WarningSt
color = 'warning'
content = highSlippage
break
case WarningState.NONE:
return null
}
return (
<Popover
Expand All @@ -104,41 +111,24 @@ export default function MaxSlippageSelect() {
const [autoSlippage, setAutoSlippage] = useAtom(autoSlippageAtom)
const [maxSlippage, setMaxSlippage] = useAtom(maxSlippageAtom)
const maxSlippageInput = useMemo(() => maxSlippage?.toString() || '', [maxSlippage])
const [warning, setWarning] = useState(WarningState.NONE)
const [showTooltip, setShowTooltip, tooltipProps] = useTooltip()
const [warning, setWarning] = useState<WarningState | undefined>(toWarningState(toPercent(maxSlippage)))
const [showTooltip, setShowTooltip, tooltipProps] = useTooltip(/*showOnMount=*/ true)
useEffect(() => setShowTooltip(true), [warning, setShowTooltip]) // enables the tooltip when a warning is set

const processInput = useCallback(
(input: number | undefined) => {
const numerator = input && Math.floor(input * 100)
if (numerator) {
const percent = new Percent(numerator, 10_000)
if (percent.greaterThan(MAX_VALID_SLIPPAGE)) {
setWarning(WarningState.INVALID_SLIPPAGE)
setAutoSlippage(true)
setMaxSlippage(input)
} else if (percent.greaterThan(MIN_HIGH_SLIPPAGE)) {
setWarning(WarningState.HIGH_SLIPPAGE)
setAutoSlippage(false)
setMaxSlippage(input)
} else {
setWarning(WarningState.NONE)
setAutoSlippage(false)
setMaxSlippage(input)
}
} else {
setAutoSlippage(true)
setMaxSlippage(undefined)
}
const processValue = useCallback(
(value: number | undefined) => {
const percent = toPercent(value)
const warning = toWarningState(percent)
setWarning(warning)
setMaxSlippage(value)
setAutoSlippage(!percent || warning === WarningState.INVALID_SLIPPAGE)
},
[setAutoSlippage, setMaxSlippage]
)
const onInputSelect = useCallback(() => {
focus()
processInput(maxSlippage)
}, [focus, maxSlippage, processInput])

useEffect(() => processInput(maxSlippage), [maxSlippage, processInput]) // processes any warnings on mount
useEffect(() => setShowTooltip(true), [warning, setShowTooltip]) // enables the tooltip if a warning is set
processValue(maxSlippage)
}, [focus, maxSlippage, processValue])

return (
<Column gap={0.75}>
Expand All @@ -153,14 +143,14 @@ export default function MaxSlippageSelect() {
wrapper={Custom}
selected={!autoSlippage}
onSelect={onInputSelect}
icon={<Warning state={warning} showTooltip={showTooltip} />}
icon={warning && <Warning state={warning} showTooltip={showTooltip} />}
{...tooltipProps}
>
<Row color={warning === WarningState.INVALID_SLIPPAGE ? 'error' : undefined}>
<DecimalInput
size={Math.max(maxSlippageInput.length, 3)}
value={maxSlippageInput}
onChange={(input) => processInput(+input)}
onChange={(input) => processValue(+input)}
placeholder={placeholder}
ref={input}
/>
Expand Down
4 changes: 4 additions & 0 deletions src/lib/components/Swap/Settings/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export const optionCss = (selected: boolean) => css`
grid-gap: 0.25em;
padding: calc(0.75em - 1px) 0.625em;
:enabled {
border: 1px solid ${({ theme }) => (selected ? theme.active : theme.outline)};
}
:enabled:hover {
border-color: ${({ theme }) => theme.onHover(selected ? theme.active : theme.outline)};
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export interface TooltipHandlers {
onBlur: () => void
}

export function useTooltip(): [boolean, (show: boolean) => void, TooltipHandlers] {
const [show, setShow] = useState(false)
export function useTooltip(showOnMount = false): [boolean, (show: boolean) => void, TooltipHandlers] {
const [show, setShow] = useState(showOnMount)
const enable = useCallback(() => setShow(true), [])
const disable = useCallback(() => setShow(false), [])
return [show, setShow, { onMouseEnter: enable, onMouseLeave: disable, onFocus: enable, onBlur: disable }]
Expand Down
47 changes: 30 additions & 17 deletions src/lib/components/Widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,6 @@ import ErrorBoundary, { ErrorHandler } from './Error/ErrorBoundary'
import WidgetPropValidator from './Error/WidgetsPropsValidator'
import Web3Provider from './Web3Provider'

const slideDown = keyframes`
to {
height: 0;
top: calc(100% - 0.25em);
}
`
const slideUp = keyframes`
from {
height: 0;
top: calc(100% - 0.25em);
}
`

const WidgetWrapper = styled.div<{ width?: number | string }>`
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
Expand Down Expand Up @@ -56,6 +43,31 @@ const WidgetWrapper = styled.div<{ width?: number | string }>`
font-family: ${({ theme }) => theme.fontFamilyVariable};
}
}
`

const slideDown = keyframes`
to {
transform: translateY(calc(100% - 0.25em));
}
`
const slideUp = keyframes`
from {
transform: translateY(calc(100% - 0.25em));
}
`

const DialogWrapper = styled.div`
height: calc(100% - 0.5em);
left: 0;
margin: 0.25em;
overflow: hidden;
position: absolute;
top: 0;
width: calc(100% - 0.5em);
@supports (overflow: clip) {
overflow: clip;
}
${Modal} {
animation: ${slideUp} 0.25s ease-in-out;
Expand Down Expand Up @@ -95,18 +107,19 @@ export default function Widget(props: PropsWithChildren<WidgetProps>) {
provider,
jsonRpcEndpoint,
width = 360,
dialog,
dialog: userDialog,
className,
onError,
} = props

const [wrapper, setWrapper] = useState<HTMLDivElement | null>(null)
const [dialog, setDialog] = useState<HTMLDivElement | null>(null)
return (
<StrictMode>
<I18nProvider locale={locale}>
<ThemeProvider theme={theme}>
<WidgetWrapper width={width} className={className} ref={setWrapper}>
<DialogProvider value={dialog || wrapper}>
<WidgetWrapper width={width} className={className}>
<DialogWrapper ref={setDialog} />
<DialogProvider value={userDialog || dialog}>
<ErrorBoundary onError={onError}>
<WidgetPropValidator {...props}>
<ReduxProvider store={multicallStore}>
Expand Down

0 comments on commit b4aac94

Please sign in to comment.