From 1666b2aee0c54eb5f399cded12b9419457b18cab Mon Sep 17 00:00:00 2001 From: Josh Leonard <30185185+josheleonard@users.noreply.github.com> Date: Mon, 30 Jan 2023 13:29:08 -0700 Subject: [PATCH] Fix allow gas price value below current base fee (#16810) * chore: rename edit-gas component files; re-export * fix: allow gas value below base fee --- .../browser/brave_wallet_constants.h | 2 + .../svg-icons/warning-triangle-filled.svg | 5 + .../brave_wallet_ui/common/async/handlers.ts | 4 +- .../confirm-transaction-panel/common/gas.tsx | 15 +- .../edit-gas/{style.ts => edit-gas.styles.ts} | 23 +- .../edit-gas/{index.tsx => edit-gas.tsx} | 292 +++++++++++------- .../components/extension/index.ts | 2 +- .../extension/shared-panel-styles.ts | 12 +- .../components/extension/sign-panel/index.tsx | 6 +- .../sign-panel/sign-transaction-panel.tsx | 6 +- .../components/extension/sign-panel/style.ts | 8 +- .../leo/alert-inline/alert-inline.stories.tsx | 19 ++ .../leo/alert-inline/alert-inline.style.ts | 43 +++ .../leo/alert-inline/alert-inline.tsx | 62 ++++ .../components/leo/alert-inline/leo-colors.ts | 18 ++ .../components/shared/style.tsx | 46 +++ components/brave_wallet_ui/constants/types.ts | 2 + components/brave_wallet_ui/stories/locale.ts | 3 + components/resources/wallet_strings.grdp | 1 + 19 files changed, 424 insertions(+), 145 deletions(-) create mode 100644 components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg rename components/brave_wallet_ui/components/extension/edit-gas/{style.ts => edit-gas.styles.ts} (90%) rename components/brave_wallet_ui/components/extension/edit-gas/{index.tsx => edit-gas.tsx} (68%) create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/alert-inline.stories.tsx create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx create mode 100644 components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts diff --git a/components/brave_wallet/browser/brave_wallet_constants.h b/components/brave_wallet/browser/brave_wallet_constants.h index bc5ebfade623..be34fdc503c1 100644 --- a/components/brave_wallet/browser/brave_wallet_constants.h +++ b/components/brave_wallet/browser/brave_wallet_constants.h @@ -42,6 +42,8 @@ constexpr char kTransakURL[] = "https://global.transak.com/"; constexpr char kTransakApiKey[] = "985d14f0-4cf5-4a4c-8917-78107620d3b7"; constexpr webui::LocalizedString kLocalizedStrings[] = { + {"braveWalletGasFeeLimitLowerThanBaseFeeWarning", + IDS_BRAVE_WALLET_GAS_FEE_LIMIT_LOWER_THAN_BASE_FEE_WARNING}, {"braveWalletTokenMintAddress", IDS_BRAVE_WALLET_TOKEN_MINT_ADDRESS}, {"braveWalletActivity", IDS_BRAVE_WALLET_ACTIVITY}, {"braveWalletTokenDecimalsIsRequiredError", diff --git a/components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg b/components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg new file mode 100644 index 000000000000..fc1bb1f46096 --- /dev/null +++ b/components/brave_wallet_ui/assets/svg-icons/warning-triangle-filled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/components/brave_wallet_ui/common/async/handlers.ts b/components/brave_wallet_ui/common/async/handlers.ts index 6e120414c780..2c3c7a06fe3e 100644 --- a/components/brave_wallet_ui/common/async/handlers.ts +++ b/components/brave_wallet_ui/common/async/handlers.ts @@ -553,8 +553,8 @@ handler.on(WalletActions.updateUnapprovedTransactionGasFields.type, async (store if (isEIP1559) { const result = await apiProxy.ethTxManagerProxy.setGasFeeAndLimitForUnapprovedTransaction( payload.txMetaId, - payload.maxPriorityFeePerGas || '', - payload.maxFeePerGas || '', + payload.maxPriorityFeePerGas || '0x0', + payload.maxFeePerGas || '0x0', payload.gasLimit ) diff --git a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx index da1407f86d1b..763de4e722bd 100644 --- a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx +++ b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx @@ -4,11 +4,16 @@ // you can obtain one at https://mozilla.org/MPL/2.0/. import * as React from 'react' +import { useSelector } from 'react-redux' -import EditGas, { MaxPriorityPanels } from '../../edit-gas' +// hooks import { usePendingTransactions } from '../../../../common/hooks/use-pending-transaction' -import { useSelector } from 'react-redux' -import { WalletState } from '../../../../constants/types' + +// components +import EditGas, { MaxPriorityPanels } from '../../edit-gas/edit-gas' + +// selectors +import { WalletSelectors } from '../../../../common/selectors' interface Props { onCancel: () => void @@ -18,8 +23,8 @@ export function EditPendingTransactionGas (props: Props) { const { onCancel } = props // redux - const { selectedPendingTransaction: transactionInfo } = useSelector( - ({ wallet }: { wallet: WalletState }) => wallet + const transactionInfo = useSelector( + WalletSelectors.selectedPendingTransaction ) const [suggestedSliderStep, setSuggestedSliderStep] = React.useState('1') diff --git a/components/brave_wallet_ui/components/extension/edit-gas/style.ts b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.styles.ts similarity index 90% rename from components/brave_wallet_ui/components/extension/edit-gas/style.ts rename to components/brave_wallet_ui/components/extension/edit-gas/edit-gas.styles.ts index 5f7c6d3a4b41..bb233e4fc7f4 100644 --- a/components/brave_wallet_ui/components/extension/edit-gas/style.ts +++ b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.styles.ts @@ -1,8 +1,10 @@ // Copyright (c) 2021 The Brave Authors. All rights reserved. // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, -// you can obtain one at https://mozilla.org/MPL/2.0/. +// You can obtain one at https://mozilla.org/MPL/2.0/. + import styled from 'styled-components' +import { LeoColors } from '../../leo/alert-inline/leo-colors' export const StyledWrapper = styled.div` display: flex; @@ -12,6 +14,7 @@ export const StyledWrapper = styled.div` width: 100%; height: 100%; padding: 5px 15px 15px 15px; + overflow-y: auto; ` export const FormColumn = styled.div` @@ -41,7 +44,12 @@ export const Input = styled.input<{ background-image: none; background-color: ${(p) => p.theme.color.background02}; box-shadow: none; - border: ${(p) => `1px solid ${p.theme.color.interactive08}`}; + border-style: solid; + border-width: 1px; + border-color: ${(p) => + p.hasError + ? LeoColors['light.system.feedback.error.icon'] + : p.theme.color.interactive08}; border-radius: 4px; font-family: Poppins; font-style: normal; @@ -50,9 +58,7 @@ export const Input = styled.input<{ letter-spacing: 0.01em; padding: 10px; margin-bottom: 8px; - color: ${(p) => p.hasError - ? p.theme.color.errorText - : p.theme.color.text01}; + color: ${(p) => p.theme.color.text01}; ::placeholder { font-family: Poppins; font-style: normal; @@ -72,6 +78,12 @@ export const Input = styled.input<{ -webkit-appearance: none; margin: 0; } + @media (prefers-color-scheme: dark) { + border-color: ${(p) => + p.hasError + ? LeoColors['light.system.feedback.error.icon'] + : p.theme.color.interactive08}; + } ` export const ButtonRow = styled.div` @@ -125,7 +137,6 @@ export const MaximumFeeRow = styled.div` justify-content: space-between; flex-direction: row; width: 100%; - margin-bottom: 8px; ` export const SliderWrapper = styled.div` diff --git a/components/brave_wallet_ui/components/extension/edit-gas/index.tsx b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx similarity index 68% rename from components/brave_wallet_ui/components/extension/edit-gas/index.tsx rename to components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx index 8121abb619ae..4bd9b6b15d07 100644 --- a/components/brave_wallet_ui/components/extension/edit-gas/index.tsx +++ b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx @@ -8,15 +8,15 @@ import { getLocale } from '../../../../common/locale' import { BraveWallet, SerializableTransactionInfo } from '../../../constants/types' import { UpdateUnapprovedTransactionGasFieldsType } from '../../../common/constants/action_types' -import { NavButton, Panel } from '../' +import { NavButton, Panel } from '..' // Utils import Amount from '../../../utils/amount' // Hooks import { useTransactionFeesParser } from '../../../common/hooks' - // Styled Components +import { ErrorText, Row } from '../../shared/style' import { StyledWrapper, FormColumn, @@ -34,15 +34,15 @@ import { SliderWrapper, SliderValue, WarningText -} from './style' -import { ErrorText } from '../../shared/style' +} from './edit-gas.styles' +import AlertInline from '../../leo/alert-inline/alert-inline' export enum MaxPriorityPanels { setSuggested = 0, setCustom = 1 } -export interface Props { +interface Props { onCancel: () => void networkSpotPrice: string transactionInfo: SerializableTransactionInfo @@ -56,24 +56,24 @@ export interface Props { setMaxPriorityPanel: (value: MaxPriorityPanels) => void } -const EditGas = (props: Props) => { - const { - onCancel, - networkSpotPrice, - selectedNetwork, - transactionInfo, - baseFeePerGas, - suggestedMaxPriorityFeeChoices, - suggestedSliderStep, - maxPriorityPanel, - updateUnapprovedTransactionGasFields, - setSuggestedSliderStep, - setMaxPriorityPanel - } = props +export const EditGas = ({ + onCancel, + networkSpotPrice, + selectedNetwork, + transactionInfo, + baseFeePerGas, + suggestedMaxPriorityFeeChoices, + suggestedSliderStep, + maxPriorityPanel, + updateUnapprovedTransactionGasFields, + setSuggestedSliderStep, + setMaxPriorityPanel +}: Props) => { const parseTransactionFees = useTransactionFeesParser(selectedNetwork, networkSpotPrice) const transactionFees = parseTransactionFees(transactionInfo) const { isEIP1559Transaction } = transactionFees + // state const [suggestedMaxPriorityFee, setSuggestedMaxPriorityFee] = React.useState(suggestedMaxPriorityFeeChoices[1]) const [gasLimit, setGasLimit] = React.useState(transactionFees.gasLimit) const [gasPrice, setGasPrice] = React.useState( @@ -92,21 +92,7 @@ const EditGas = (props: Props) => { .format() ) - React.useEffect( - () => { - const maxPriorityFeePerGasWei = new Amount(maxPriorityFeePerGas) - .multiplyByDecimals(9) // GWei-per-gas → Wei conversion - - const maxFeePerGasWeiValue = new Amount(baseFeePerGas) - .plus(maxPriorityFeePerGasWei) - - setMaxFeePerGas(maxFeePerGasWeiValue - .divideByDecimals(9) // Wei-per-gas → GWei-per-gas conversion - .format()) - }, - [baseFeePerGas] - ) - + // methods const handleGasPriceInputChanged = (event: React.ChangeEvent) => { setGasPrice(event.target.value) } @@ -168,46 +154,6 @@ const EditGas = (props: Props) => { setMaxFeePerGas(computedMaxFeePerGasGWei) } - const showSuggestedMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setSuggested - const showCustomMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setCustom - const suggestedEIP1559GasFee = showSuggestedMaxPriorityPanel - ? new Amount(baseFeePerGas) - .plus(suggestedMaxPriorityFee) - .times(gasLimit) // Wei-per-gas → Wei conversion - .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion - .format(6) - : undefined - - const suggestedEIP1559FiatGasFee = suggestedEIP1559GasFee && new Amount(suggestedEIP1559GasFee) - .times(networkSpotPrice) - .formatAsFiat() - - const customEIP1559GasFee = showCustomMaxPriorityPanel - ? new Amount(maxFeePerGas) - .multiplyByDecimals(9) // GWei-per-gas → Wei-per-gas conversion - .times(gasLimit) // Wei-per-gas → Wei - .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion - .format(6) - : undefined - const customEIP1559FiatGasFee = customEIP1559GasFee && new Amount(customEIP1559GasFee) - .times(networkSpotPrice) - .formatAsFiat() - - const gasLimitComponent = ( - <> - {getLocale('braveWalletEditGasLimit')} - - {gasLimit === '0' && {getLocale('braveWalletEditGasLimitError')}} - - ) - const onSave = () => { if (!isEIP1559Transaction) { updateUnapprovedTransactionGasFields({ @@ -250,6 +196,52 @@ const EditGas = (props: Props) => { onCancel() } + // computed & memos + const showSuggestedMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setSuggested + const showCustomMaxPriorityPanel = isEIP1559Transaction && maxPriorityPanel === MaxPriorityPanels.setCustom + const suggestedEIP1559GasFee = showSuggestedMaxPriorityPanel + ? new Amount(baseFeePerGas) + .plus(suggestedMaxPriorityFee) + .times(gasLimit) // Wei-per-gas → Wei conversion + .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion + .format(6) + : undefined + + const suggestedEIP1559FiatGasFee = suggestedEIP1559GasFee && new Amount(suggestedEIP1559GasFee) + .times(networkSpotPrice) + .formatAsFiat() + + const customEIP1559GasFee = showCustomMaxPriorityPanel + ? new Amount(maxFeePerGas) + .multiplyByDecimals(9) // GWei-per-gas → Wei-per-gas conversion + .times(gasLimit) // Wei-per-gas → Wei + .divideByDecimals(selectedNetwork.decimals) // Wei → ETH conversion + .format(6) + : undefined + const customEIP1559FiatGasFee = customEIP1559GasFee && new Amount(customEIP1559GasFee) + .times(networkSpotPrice) + .formatAsFiat() + + const gasLimitComponent = React.useMemo( + () => ( + <> + {getLocale('braveWalletEditGasLimit')} + + {gasLimit === '0' && ( + {getLocale('braveWalletEditGasLimitError')} + )} + + ), + [gasLimit, handleGasLimitInputChanged] + ) + const isZeroGasPrice = React.useMemo(() => { return ( !isEIP1559Transaction && @@ -273,8 +265,10 @@ const EditGas = (props: Props) => { return true } - if (!isEIP1559Transaction && - new Amount(gasPrice).multiplyByDecimals(9).isNegative()) { + if ( + !isEIP1559Transaction && + new Amount(gasPrice).multiplyByDecimals(9).isNegative() + ) { return true } @@ -282,71 +276,127 @@ const EditGas = (props: Props) => { return true } - if (isEIP1559Transaction && - new Amount(maxFeePerGas).multiplyByDecimals(9).lte(baseFeePerGas) - ) { - return true - } - - return isEIP1559Transaction && + return ( + isEIP1559Transaction && new Amount(maxPriorityFeePerGas).multiplyByDecimals(9).isNegative() - }, [gasLimit, gasPrice, maxPriorityFeePerGas, maxFeePerGas]) + ) + }, [ + gasLimit, + isEIP1559Transaction, + gasPrice, + maxFeePerGas, + baseFeePerGas, + maxPriorityFeePerGas + ]) + + const isCustomGasBelowBaseFee = React.useMemo( + () => + isEIP1559Transaction && + new Amount(maxFeePerGas).multiplyByDecimals(9).lt(baseFeePerGas), + [isEIP1559Transaction, maxFeePerGas, baseFeePerGas] + ) + + // effects + React.useEffect(() => { + const maxPriorityFeePerGasWei = new Amount( + maxPriorityFeePerGas + ).multiplyByDecimals(9) // GWei-per-gas → Wei conversion + const maxFeePerGasWeiValue = new Amount(baseFeePerGas).plus( + maxPriorityFeePerGasWei + ) + + setMaxFeePerGas( + maxFeePerGasWeiValue + .divideByDecimals(9) // Wei-per-gas → GWei-per-gas conversion + .format() + ) + }, [maxPriorityFeePerGas, baseFeePerGas]) + + // render return ( - {isEIP1559Transaction && - {getLocale('braveWalletEditGasDescription')} - } - {showCustomMaxPriorityPanel && + {isEIP1559Transaction && ( + + {getLocale('braveWalletEditGasDescription')} + + )} + {showCustomMaxPriorityPanel && ( - {getLocale('braveWalletEditGasBaseFee')} - { - `${new Amount(baseFeePerGas).divideByDecimals(9).format()} - ${getLocale('braveWalletEditGasGwei')}` - } + {getLocale('braveWalletEditGasBaseFee')} + + + {`${new Amount(baseFeePerGas).divideByDecimals(9).format()} + ${getLocale('braveWalletEditGasGwei')}`} {gasLimitComponent} - {getLocale('braveWalletEditGasPerTipLimit')} + + {getLocale('braveWalletEditGasPerTipLimit')} + - {getLocale('braveWalletEditGasPerPriceLimit')} + {/* Gas-Per-Price Limit */} + + {getLocale('braveWalletEditGasPerPriceLimit')} + - {getLocale('braveWalletEditGasMaximumFee')} - ~${customEIP1559FiatGasFee} USD (${customEIP1559GasFee} {selectedNetwork.symbol}) + {getLocale('braveWalletEditGasMaximumFee')} + + + ~${customEIP1559FiatGasFee} USD (${customEIP1559GasFee}{' '} + {selectedNetwork.symbol}) + {isCustomGasBelowBaseFee && ( + + + + )} - } + )} - {showSuggestedMaxPriorityPanel && + {showSuggestedMaxPriorityPanel && ( {getLocale('braveWalletEditGasMaxFee')}: - ~${suggestedEIP1559FiatGasFee} - {' '}USD ({suggestedEIP1559GasFee} - {' '}{selectedNetwork.symbol}) + ~${suggestedEIP1559FiatGasFee} USD ({suggestedEIP1559GasFee}{' '} + {selectedNetwork.symbol}) + { /> {getLocale('braveWalletEditGasLow')} - {getLocale('braveWalletEditGasOptimal')} + + {getLocale('braveWalletEditGasOptimal')} + {getLocale('braveWalletEditGasHigh')} - } + )} - {!isEIP1559Transaction && + {!isEIP1559Transaction && ( {gasLimitComponent} - {getLocale('braveWalletEditGasPerGasPrice')} + + {getLocale('braveWalletEditGasPerGasPrice')} + { /> {isZeroGasPrice && ( - {getLocale('braveWalletEditGasZeroGasPriceWarning')} + + {getLocale('braveWalletEditGasZeroGasPriceWarning')} + )} - } + )} + { + return +} + +_AlertInline.story = { + name: 'Inline Alert' +} + +export default _AlertInline diff --git a/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts new file mode 100644 index 000000000000..59b2314a7d93 --- /dev/null +++ b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.style.ts @@ -0,0 +1,43 @@ +// Copyright (c) 2023 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +import styled from 'styled-components' +import { AlertType } from '../../../constants/types' + +import { LeoColors } from './leo-colors' + +export const InlineAlertContainer = styled.div<{ + alertType: AlertType +}>` + display: flex; + flex-direction: row; + align-items: center; + gap: 16px; + + margin-top: 16px; + margin-bottom: 16px; + padding: 16px; + width: 100%; + min-height: 56px; + + border-radius: 8px; + + color: ${LeoColors['light.text.primary']}; + background-color: ${({ alertType }) => + alertType === 'danger' + ? LeoColors['light.system.feedback.error.background'] + : alertType === 'warning' + ? LeoColors['light.system.feedback.warning.background'] + : 'unset'}; + @media (prefers-color-scheme: dark) { + color: ${LeoColors['dark.text.primary']}; + background-color: ${({ alertType }) => + alertType === 'danger' + ? LeoColors['dark.system.feedback.error.background'] + : alertType === 'warning' + ? LeoColors['dark.system.feedback.warning.background'] + : 'unset'}; + } +` diff --git a/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx new file mode 100644 index 000000000000..3dedc4073da5 --- /dev/null +++ b/components/brave_wallet_ui/components/leo/alert-inline/alert-inline.tsx @@ -0,0 +1,62 @@ +// Copyright (c) 2023 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +import * as React from 'react' + +// types +import { AlertType } from '../../../constants/types' + +// style +import { + Column, + Text, + WarningCircleFilledIcon, + WarningTriangleFilledIcon +} from '../../shared/style' +import { InlineAlertContainer } from './alert-inline.style' + +interface Props { + alertType: AlertType + message: string + onDismiss?: () => void + onPrimaryClick?: () => void + onSecondaryClick?: () => void + primaryButtonText?: string + secondaryButtonText?: string + title?: string +} + +const ICON_SIZE = { width: 16, height: 16 } + +export const AlertInline: React.FC = ({ + alertType, + message, + onDismiss, + onPrimaryClick, + onSecondaryClick, + primaryButtonText, + secondaryButtonText, + title +}) => { + return ( + + + {alertType === 'danger' && ( + + )} + {alertType === 'warning' && ( + + )} + + + + {message} + + + + ) +} + +export default AlertInline diff --git a/components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts b/components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts new file mode 100644 index 000000000000..907c86c8ea6e --- /dev/null +++ b/components/brave_wallet_ui/components/leo/alert-inline/leo-colors.ts @@ -0,0 +1,18 @@ +// Copyright (c) 2023 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +export const LeoColors = { + 'dark.system.feedback.error.background': '#410912', + 'dark.system.feedback.error.icon': '#EB637A', + 'dark.system.feedback.warning.background': '#281D00', + 'dark.system.feedback.warning.icon': '#BB8800', + 'dark.text.primary': '#ECEFF2', + + 'light.system.feedback.error.background': '#FDF3F5', + 'light.system.feedback.error.icon': '#DC1D3C', + 'light.system.feedback.warning.background': '##FFF4D8', + 'light.system.feedback.warning.icon': '#E2A500', + 'light.text.primary': '#1D1F25' +} diff --git a/components/brave_wallet_ui/components/shared/style.tsx b/components/brave_wallet_ui/components/shared/style.tsx index cf32249ec81c..cd2bb6e9f0c9 100644 --- a/components/brave_wallet_ui/components/shared/style.tsx +++ b/components/brave_wallet_ui/components/shared/style.tsx @@ -11,6 +11,9 @@ import { Link } from 'react-router-dom' import { BraveWallet, StringWithAutocomplete } from '../../constants/types' import IThemeProps from 'brave-ui/src/theme/theme-interface' +// colors +import { LeoColors } from '../leo/alert-inline/leo-colors' + // utils import { stripERC20TokenImageURL } from '../../utils/string-utils' @@ -27,6 +30,8 @@ import ClipboardSvg from '../../assets/svg-icons/copy-to-clipboard-icon.svg' import DownloadSvg from '../../assets/svg-icons/download-icon.svg' import CheckIconSvg from '../../assets/svg-icons/checkbox-check.svg' import SwitchDown from '../../assets/svg-icons/switch-icon.svg' +import WarningCircleFilled from '../../assets/svg-icons/warning-circle-icon.svg' +import WarningTriangleFilled from '../../assets/svg-icons/warning-triangle-filled.svg' export type ThemeColor = StringWithAutocomplete @@ -296,6 +301,47 @@ export const GreenCheckmark = styled.div` vertical-align: middle; ` +export const WarningTriangleFilledIcon = styled.div<{ + color?: keyof IThemeProps['color'] +}>` + mask-size: 100%; + background-color: ${(p) => p?.color + ? p.theme.color[p.color] + : LeoColors['light.system.feedback.warning.icon'] + }; + -webkit-mask-image: url(${WarningTriangleFilled}); + mask-repeat: no-repeat; + mask-image: url(${WarningTriangleFilled}); + @media (prefers-color-scheme: dark) { + color: ${(p) => p.theme.palette.blurple300}; + background-color: ${(p) => p?.color + ? p.theme.color[p.color] + : LeoColors['dark.system.feedback.warning.icon'] + }; + } +` + +export const WarningCircleFilledIcon = styled.div<{ + color?: keyof IThemeProps['color'] +}>` + opacity: 50%; + mask-size: contain; + mask-position: center; + mask-repeat: no-repeat; + background-color: ${(p) => p?.color + ? p.theme.color[p.color] + : LeoColors['light.system.feedback.error.icon'] + }; + -webkit-mask-image: url(${WarningCircleFilled}); + mask-image: url(${WarningCircleFilled}); + @media (prefers-color-scheme: dark) { + background-color: ${(p) => p?.color + ? p.theme.color[p.color] + : LeoColors['dark.system.feedback.error.icon'] + }; + } +` + export const CloseIcon = styled.div` width: 20px; height: 20px; diff --git a/components/brave_wallet_ui/constants/types.ts b/components/brave_wallet_ui/constants/types.ts index 2653c521b7f4..fd521e7011b3 100644 --- a/components/brave_wallet_ui/constants/types.ts +++ b/components/brave_wallet_ui/constants/types.ts @@ -995,3 +995,5 @@ export type AddressMessageInfo = { description?: string url?: string } + +export type AlertType = 'danger' | 'warning' | 'info' | 'success' diff --git a/components/brave_wallet_ui/stories/locale.ts b/components/brave_wallet_ui/stories/locale.ts index df3be717df9c..63694283470d 100644 --- a/components/brave_wallet_ui/stories/locale.ts +++ b/components/brave_wallet_ui/stories/locale.ts @@ -594,6 +594,9 @@ provideStrings({ braveWalletEditGasSetSuggested: 'Set suggested', braveWalletEditGasZeroGasPriceWarning: 'Transaction may not be propagated in the network.', braveWalletEditGasLimitError: 'Gas limit must be an integer greater than 0', + braveWalletGasFeeLimitLowerThanBaseFeeWarning: + 'Fee limit is set lower than the base fee. ' + + 'Your transaction may take a long time or fail.', // Advanced transaction settings braveWalletAdvancedTransactionSettings: 'Advanced settings', diff --git a/components/resources/wallet_strings.grdp b/components/resources/wallet_strings.grdp index 48fcf418e59e..376330b05144 100644 --- a/components/resources/wallet_strings.grdp +++ b/components/resources/wallet_strings.grdp @@ -817,4 +817,5 @@ Token symbol is required Token decimals of precision value is required Mint address + Fee limit is set lower than the base fee. Your transaction may take a long time or fail.