diff --git a/.changelog/519.feature.md b/.changelog/519.feature.md new file mode 100644 index 00000000..4b2309ae --- /dev/null +++ b/.changelog/519.feature.md @@ -0,0 +1 @@ +Use the newly added Oasis UI Library in wrap diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29e088e8..f40b5d6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -457,6 +457,9 @@ importers: bignumber.js: specifier: ^9.1.2 version: 9.1.2 + lucide-react: + specifier: ^0.513.0 + version: 0.513.0(react@18.3.1) react: specifier: ^18.2.0 version: 18.3.1 diff --git a/ui-library b/ui-library index f283d7a7..85623267 160000 --- a/ui-library +++ b/ui-library @@ -1 +1 @@ -Subproject commit f283d7a7f4ee71153716523ee208a276a91eec4d +Subproject commit 856232676828081ba9a806d9d9646b4f41668112 diff --git a/ui/src/core/components/RainbowKitConnectButton/index.tsx b/ui/src/core/components/RainbowKitConnectButton/index.tsx index 4a6cd20f..03a9856a 100644 --- a/ui/src/core/components/RainbowKitConnectButton/index.tsx +++ b/ui/src/core/components/RainbowKitConnectButton/index.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import { ConnectButton } from '@rainbow-me/rainbowkit' import { ChevronDown, Wallet } from 'lucide-react' -import { Button } from '@oasisprotocol/ui-library/src/components/ui/button' +import { cn, Button } from '@oasisprotocol/ui-library/src' import { DropdownMenu, DropdownMenuContent, @@ -25,15 +25,34 @@ const TruncatedAddress: FC<{ address: string; className?: string }> = ({ address interface Props { onMobileClose?: () => void + className?: string } +export const ConnectWalletButton: FC = ({ onMobileClose, className }) => ( + + {({ openConnectModal }) => ( + + )} + +) + export const RainbowKitConnectButton: FC = ({ onMobileClose }) => { const isMobile = useIsMobile() const { disconnect } = useDisconnect() return ( - {({ account, chain, openAccountModal, openChainModal, openConnectModal, mounted }) => { + {({ account, chain, openAccountModal, openChainModal, mounted }) => { const ready = mounted const connected = ready && account && chain @@ -50,19 +69,7 @@ export const RainbowKitConnectButton: FC = ({ onMobileClose }) => { > {(() => { if (!connected) { - return ( - - ) + return } if (chain.unsupported) { diff --git a/ui/src/wrap/components/Spinner/index.module.css b/ui/src/core/components/Spinner/index.module.css similarity index 100% rename from ui/src/wrap/components/Spinner/index.module.css rename to ui/src/core/components/Spinner/index.module.css diff --git a/ui/src/wrap/components/Spinner/index.tsx b/ui/src/core/components/Spinner/index.tsx similarity index 100% rename from ui/src/wrap/components/Spinner/index.tsx rename to ui/src/core/components/Spinner/index.tsx diff --git a/ui/src/core/components/icons/AppLogo.tsx b/ui/src/core/components/icons/AppLogo.tsx index c0e953e4..f3ce617e 100644 --- a/ui/src/core/components/icons/AppLogo.tsx +++ b/ui/src/core/components/icons/AppLogo.tsx @@ -8,7 +8,7 @@ export const AppLogo = () => { ) @@ -18,7 +18,7 @@ export const AppLogo = () => { ( - - Oasis ROSE app logo - +import { FC } from 'react' + +export const Logo: FC<{ imageOnly?: boolean }> = imageOnly => + imageOnly ? ( + + Oasis ROSE app logo + + + + + + + + + + ) : ( + + Oasis ROSE app logo + + + + + + + + - - - - - - - - - - - - - -) + + + + + + + ) diff --git a/ui/src/core/components/index.ts b/ui/src/core/components/index.ts index 58c34645..c028dbba 100644 --- a/ui/src/core/components/index.ts +++ b/ui/src/core/components/index.ts @@ -5,3 +5,4 @@ export * from './Header' export * from './RainbowKitConnectButton' export * from './NavbarLink' export * from './AppLayout' +export * from './Spinner' diff --git a/ui/src/index.ts b/ui/src/index.ts index a441b952..464549f8 100644 --- a/ui/src/index.ts +++ b/ui/src/index.ts @@ -1,4 +1,3 @@ export * from './stake' export * from './move' export * from './core' -export * from './wrap' diff --git a/ui/src/wrap/components/Alert/index.module.css b/ui/src/wrap/components/Alert/index.module.css deleted file mode 100644 index 3f2fafbe..00000000 --- a/ui/src/wrap/components/Alert/index.module.css +++ /dev/null @@ -1,22 +0,0 @@ -.alert { - padding: 0.5rem 0.25rem; - background-color: white; - font-size: 14px; - line-height: 120%; - border-radius: 10px; - margin-top: 1rem; - text-align: center; - word-wrap: break-word; -} - -.alertDanger { - color: var(--danger); -} - -.alertWarn { - color: var(--warn); -} - -.alertInfo { - color: var(--brand-dark); -} diff --git a/ui/src/wrap/components/Alert/index.tsx b/ui/src/wrap/components/Alert/index.tsx deleted file mode 100644 index cc27c4be..00000000 --- a/ui/src/wrap/components/Alert/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import classes from './index.module.css' -import { FC, PropsWithChildren } from 'react' - -type AlertVariant = 'danger' | 'warn' | 'info' - -interface Props extends PropsWithChildren { - variant?: AlertVariant -} - -const variantMap: Record = { - danger: classes.alertDanger, - warn: classes.alertWarn, - info: classes.alertInfo, -} - -export const Alert: FC = ({ children, variant = 'info' }) => ( -

{children}

-) diff --git a/ui/src/wrap/components/Button/index.module.css b/ui/src/wrap/components/Button/index.module.css deleted file mode 100644 index f8cd3d11..00000000 --- a/ui/src/wrap/components/Button/index.module.css +++ /dev/null @@ -1,58 +0,0 @@ -.button { - width: auto; - border-radius: 46px; - border: 1px solid transparent; - box-shadow: none; - cursor: pointer; - font-family: 'Figtree Variable', 'Helvetica', 'Arial', sans-serif; - font-size: 18px; - font-style: normal; - font-weight: 700; - line-height: 125%; - outline: none; - padding: 1.125rem 1.5rem; - text-decoration: none; - user-select: none; - text-transform: capitalize; - color: var(--white); -} - -.buttonPrimary { - border-color: var(--gray-medium-light); - background-color: var(--brand-medium); -} - -.buttonSecondary { - border-color: var(--gray-medium-light); - background-color: transparent; -} - -.buttonTertiary { - border-width: 2px; - border-color: var(--gray-medium-light); - background-color: transparent; - min-width: 75px; - padding: 0.4rem; - line-height: 120%; - border-radius: 10px; - font-size: 13.5px; -} - -.buttonDisabled { - cursor: not-allowed; - border-color: var(--gray-medium-light); - background-color: var(--gray-wrap-medium-dark); - opacity: 0.5; -} - -.fullWidth { - width: 100%; -} - -@media screen and (min-width: 1000px) { - .buttonTertiary { - min-width: 100px; - padding: 0.58rem 1.5rem; - font-size: 18px; - } -} diff --git a/ui/src/wrap/components/Button/index.tsx b/ui/src/wrap/components/Button/index.tsx deleted file mode 100644 index 95525b15..00000000 --- a/ui/src/wrap/components/Button/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import classes from './index.module.css' -import { FC, MouseEventHandler, PropsWithChildren } from 'react' - -type ButtonVariant = 'primary' | 'secondary' | 'tertiary' - -interface Props extends PropsWithChildren { - disabled?: boolean - variant?: ButtonVariant - fullWidth?: boolean - onClick?: MouseEventHandler - className?: string - type?: 'submit' | 'reset' | 'button' -} - -const variantMap: Record = { - primary: classes.buttonPrimary, - secondary: classes.buttonSecondary, - tertiary: classes.buttonTertiary, -} - -export const Button: FC = ({ - className, - children, - disabled, - variant = 'primary', - fullWidth, - onClick, - type, -}) => ( - -) diff --git a/ui/src/wrap/components/Input/index.module.css b/ui/src/wrap/components/Input/index.module.css deleted file mode 100644 index bd6c7a82..00000000 --- a/ui/src/wrap/components/Input/index.module.css +++ /dev/null @@ -1,66 +0,0 @@ -.inputGroup { - display: flex; - flex-wrap: nowrap; - align-items: center; - justify-content: space-between; - width: 100%; - border-radius: 46px; - padding: 1.125rem 2.8125rem; -} - -.inputGroupDisabled { - cursor: not-allowed; - - * { - cursor: not-allowed; - } -} - -.inputGroup > label { - color: var(--gray-wrap-extra-dark); - font-size: 18px; - font-style: normal; - font-weight: 400; - line-height: 125%; - opacity: 0.7; - flex: 0 1 auto; -} - -.inputGroup > input { - margin: 0; - flex: 1 1 auto; - max-width: 60%; - outline: none; - border: none; - background-image: none; - background-color: transparent; - box-shadow: none; - font-size: 22px; - font-style: normal; - font-weight: 700; - line-height: 125%; - text-align: right; - color: revert; /* Workaround for tailwindcss/preflight */ -} - -.inputGroup > input::placeholder { - opacity: 0.75; -} - -.inputGroupLight { - border: 1px solid var(--white); - background: var(--white); -} - -.inputGroupDark { - border: 2px solid var(--gray-wrap-medium-dark); - background: var(--white); -} - -@media screen and (min-width: 1000px) { - @media screen and (min-width: 1000px) { - .inputGroup > input { - max-width: 75%; - } - } -} diff --git a/ui/src/wrap/components/Input/index.tsx b/ui/src/wrap/components/Input/index.tsx deleted file mode 100644 index d1b822ce..00000000 --- a/ui/src/wrap/components/Input/index.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import classes from './index.module.css' -import { HTMLInputTypeAttribute, PropsWithChildren, useId } from 'react' - -type InputGroupVariant = 'light' | 'dark' - -const inputGroupVariantMap: Record = { - light: classes.inputGroupLight, - dark: classes.inputGroupDark, -} - -interface Props extends PropsWithChildren { - type: HTMLInputTypeAttribute - label: string - variant?: InputGroupVariant - pattern?: string - placeholder?: string - id?: string - disabled?: boolean - inputMode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search' - className?: string - value: T - valueChange?: (value: T) => void -} - -export const Input = ({ - type, - label, - variant = 'light', - pattern, - placeholder, - id, - disabled, - inputMode, - className, - value, - valueChange, -}: Props) => { - const uniqueId = useId() - const inputId = id || uniqueId - - return ( -
- - valueChange?.(value as T)} - /> -
- ) -} diff --git a/ui/src/wrap/components/Layout/index.module.css b/ui/src/wrap/components/Layout/index.module.css deleted file mode 100644 index 23cd5ee5..00000000 --- a/ui/src/wrap/components/Layout/index.module.css +++ /dev/null @@ -1,72 +0,0 @@ -.layout { - min-height: 100dvh; - display: flex; - flex-direction: column; - justify-content: space-between; - - margin: 0; - font-family: 'Figtree Variable', 'Helvetica', 'Arial', sans-serif; - font-size: 16px; - font-style: normal; - font-weight: normal; - line-height: 150%; - color: var(--white); - text-align: left; - background-color: var(--brand-blue); - background-size: contain; - background-position: left bottom; - background-repeat: no-repeat; -} - -.main { - display: flex; - justify-content: center; - flex: 1 0 auto; - margin: 0 auto; - width: 100%; - padding: 6.875rem 1.875rem 1.875rem; -} - -.headerLink { - text-decoration: none; - color: var(--white); - min-height: 70px; - display: flex; - align-items: center; -} - -.footer { - display: flex; - flex-wrap: wrap; - justify-content: start; - align-items: center; - padding: 2.5rem 1rem 0.5rem; - color: var(--white); - font-size: 12px; - font-weight: 400; - line-height: 150%; - margin: 0 auto; - width: 100%; - max-width: 1076px; - gap: 0.5rem; - - a { - color: var(--white); - text-decoration: none; - - &:hover { - text-decoration: underline; - } - } -} - -@media screen and (min-width: 1000px) { - .main { - max-width: 670px; - padding: 1.5rem 0 0; - } - - .footer { - padding: 3rem 2rem 1.25rem; - } -} diff --git a/ui/src/wrap/components/Layout/index.tsx b/ui/src/wrap/components/Layout/index.tsx deleted file mode 100644 index 965bbea9..00000000 --- a/ui/src/wrap/components/Layout/index.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { FC, PropsWithChildren } from 'react' -import { NavLink, Outlet, useMatch } from 'react-router-dom' -import { WrapLogoIcon } from '../icons/WrapLogoIcon' -import { ConnectButton } from '@rainbow-me/rainbowkit' -import { useMediaQuery } from 'react-responsive' -import classes from './index.module.css' -import globalClasses from '../../index.module.css' -import { Header } from '../../../core' - -const dateFormatLong = new Intl.DateTimeFormat('en', { - year: 'numeric', - month: 'numeric', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', - second: 'numeric', -}) - -export const Layout: FC = () => { - const isHomePage = useMatch('/wrap') - const isMobileScreen = useMediaQuery({ query: '(max-width: 1023px)' }) - - return ( -
-
- - - ) - } - > - {isHomePage &&
} - {!isHomePage && !isMobileScreen && } -
-
- -
- -
- ) -} diff --git a/ui/src/wrap/components/Modal/index.module.css b/ui/src/wrap/components/Modal/index.module.css deleted file mode 100644 index bec60f79..00000000 --- a/ui/src/wrap/components/Modal/index.module.css +++ /dev/null @@ -1,44 +0,0 @@ -.modalOverlay { - position: fixed; - display: flex; - justify-content: center; - align-items: center; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(6, 21, 43, 0.9); -} - -.modal { - position: relative; - background: #fff; - padding: 1.25rem; - width: 100%; - max-width: 675px; - border-radius: 20px; -} - -.modalContent { - padding: 3.5rem 3.5rem 0; -} - -.modalCloseButton { - float: right; - border: none; - background: none; - cursor: pointer; -} - -@media screen and (max-width: 1000px) { - .modal { - max-width: none; - width: 100%; - height: 100vh; - padding: 1.75rem; - overflow: auto; - } - .modalContent { - padding: 1rem; - } -} diff --git a/ui/src/wrap/components/Modal/index.tsx b/ui/src/wrap/components/Modal/index.tsx deleted file mode 100644 index 9c6a32c4..00000000 --- a/ui/src/wrap/components/Modal/index.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { FC, PropsWithChildren } from 'react' -import classes from './index.module.css' -import { TimesIcon } from '../icons/TimesIcon' -import { WrapModalProps } from '../../types' - -export const Modal: FC> = ({ - children, - isOpen, - disableBackdropClick, - closeModal, -}) => { - if (!isOpen) { - return null - } - - const handleOverlayClick = () => { - if (!disableBackdropClick) { - closeModal() - } - } - - return ( -
-
- -
{children}
-
-
- ) -} diff --git a/ui/src/wrap/components/ToggleButton/index.module.css b/ui/src/wrap/components/ToggleButton/index.module.css deleted file mode 100644 index 598bdbf9..00000000 --- a/ui/src/wrap/components/ToggleButton/index.module.css +++ /dev/null @@ -1,23 +0,0 @@ -.toggleButton { - display: flex; - justify-content: center; - align-items: center; - width: 38px; - height: 38px; - border-radius: 50%; - border: 1px solid transparent; - box-shadow: none; - cursor: pointer; - outline: none; - text-decoration: none; - user-select: none; - color: var(--white); - background: var(--brand-dark); -} - -@media screen and (min-width: 1000px) { - .toggleButton { - width: 48px; - height: 48px; - } -} diff --git a/ui/src/wrap/components/ToggleButton/index.tsx b/ui/src/wrap/components/ToggleButton/index.tsx deleted file mode 100644 index d5a0bcd7..00000000 --- a/ui/src/wrap/components/ToggleButton/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import classes from './index.module.css' -import { FC, MouseEventHandler } from 'react' -import { CachedIcon } from '../icons/CachedIcon' - -interface Props { - className?: string - disabled?: boolean - onClick?: MouseEventHandler -} - -export const ToggleButton: FC = ({ className, disabled, onClick }) => ( - -) diff --git a/ui/src/wrap/components/icons/CachedIcon.tsx b/ui/src/wrap/components/icons/CachedIcon.tsx deleted file mode 100644 index 85857fbb..00000000 --- a/ui/src/wrap/components/icons/CachedIcon.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright 2024 https://github.com/material-icons/material-icons - * SPDX-License-Identifier: Apache-2.0 - */ -import { FC } from 'react' - -export const CachedIcon: FC = () => ( - - - - - - - - - - -) diff --git a/ui/src/wrap/components/icons/LogoIconRound.tsx b/ui/src/wrap/components/icons/LogoIconRound.tsx deleted file mode 100644 index a4935953..00000000 --- a/ui/src/wrap/components/icons/LogoIconRound.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { FC } from 'react' - -export const LogoIconRound: FC = () => ( - - - - - - -) diff --git a/ui/src/wrap/components/icons/OpenInNewIcon.tsx b/ui/src/wrap/components/icons/OpenInNewIcon.tsx deleted file mode 100644 index c4f87766..00000000 --- a/ui/src/wrap/components/icons/OpenInNewIcon.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright 2024 https://github.com/material-icons/material-icons - * SPDX-License-Identifier: Apache-2.0 - */ -import { FC } from 'react' - -export const OpenInNewIcon: FC = () => ( - - - - - - - - - - -) diff --git a/ui/src/wrap/components/icons/TimesIcon.tsx b/ui/src/wrap/components/icons/TimesIcon.tsx deleted file mode 100644 index cfdbd9f6..00000000 --- a/ui/src/wrap/components/icons/TimesIcon.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright 2024 https://github.com/material-icons/material-icons - * SPDX-License-Identifier: Apache-2.0 - */ -import { FC } from 'react' - -export const TimesIcon: FC = () => ( - - - - - - - - - - -) diff --git a/ui/src/wrap/components/icons/index.ts b/ui/src/wrap/components/icons/index.ts deleted file mode 100644 index f4ca08be..00000000 --- a/ui/src/wrap/components/icons/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './CachedIcon' -export * from './WrapLogoIcon' -export * from './LogoIconRound' -export * from './OpenInNewIcon' -export * from './TimesIcon' diff --git a/ui/src/wrap/components/index.ts b/ui/src/wrap/components/index.ts deleted file mode 100644 index 8c0753d2..00000000 --- a/ui/src/wrap/components/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { Alert as WrapAlert } from './Alert' -export { Button as WrapButton } from './Button' -export * from './icons' -export { Input as WrapInput } from './Input' -export { Layout as WrapLayout } from './Layout' -export { Modal as WrapModal } from './Modal' -export * from './Spinner' -export { ToggleButton as WrapToggleButton } from './ToggleButton' diff --git a/ui/src/wrap/index.module.css b/ui/src/wrap/index.module.css deleted file mode 100644 index 0dc857b6..00000000 --- a/ui/src/wrap/index.module.css +++ /dev/null @@ -1,36 +0,0 @@ -.global { - :global(h1), - :global(h2), - :global(h3), - :global(h4), - :global(h5), - :global(h6), - :global(p) { - margin-top: 0; - margin-bottom: 0.5rem; - } - - :global(h2) { - font-size: 32px; - font-weight: 700; - line-height: 140%; - } - - :global(h3) { - font-size: 24px; - font-weight: 700; - line-height: 140%; - } - - :global(h4) { - font-size: 18px; - font-weight: 700; - line-height: 120%; - } - - :global(p) { - font-size: 16px; - font-weight: 400; - line-height: 150%; - } -} diff --git a/ui/src/wrap/index.ts b/ui/src/wrap/index.ts deleted file mode 100644 index 7e739fe1..00000000 --- a/ui/src/wrap/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './components' -export * from './types' diff --git a/ui/src/wrap/types/ModalProps.ts b/ui/src/wrap/types/ModalProps.ts deleted file mode 100644 index 65e00d20..00000000 --- a/ui/src/wrap/types/ModalProps.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { MouseEvent } from 'react' - -export interface ModalProps { - isOpen: boolean - disableBackdropClick?: boolean - closeModal: (event?: MouseEvent) => void -} diff --git a/ui/src/wrap/types/index.ts b/ui/src/wrap/types/index.ts deleted file mode 100644 index d22dcf67..00000000 --- a/ui/src/wrap/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export type { ModalProps as WrapModalProps } from './ModalProps' diff --git a/wrap/package.json b/wrap/package.json index ec00dafa..2a037591 100644 --- a/wrap/package.json +++ b/wrap/package.json @@ -21,6 +21,7 @@ "@oasisprotocol/ui-library": "file:../ui-library", "@rainbow-me/rainbowkit": "^2.1.2", "bignumber.js": "^9.1.2", + "lucide-react": "^0.513.0", "react": "^18.2.0", "react-responsive": "^9.0.2", "react-router-dom": "^6.22.2", diff --git a/wrap/src/App.tsx b/wrap/src/App.tsx index e93fd0ab..291cea08 100644 --- a/wrap/src/App.tsx +++ b/wrap/src/App.tsx @@ -1,9 +1,11 @@ import { FC } from 'react' -import { WrapLayout } from '@oasisprotocol/rose-app-ui/wrap' +import { Outlet } from 'react-router-dom' import { Web3ContextProvider } from './providers/Web3Provider' export const App: FC = () => ( - +
+ +
) diff --git a/ui/src/wrap/components/icons/WrapLogoIcon.tsx b/wrap/src/components/Logo/WrapLogoIcon.tsx similarity index 100% rename from ui/src/wrap/components/icons/WrapLogoIcon.tsx rename to wrap/src/components/Logo/WrapLogoIcon.tsx diff --git a/wrap/src/components/ToggleButton/index.tsx b/wrap/src/components/ToggleButton/index.tsx new file mode 100644 index 00000000..7e668053 --- /dev/null +++ b/wrap/src/components/ToggleButton/index.tsx @@ -0,0 +1,17 @@ +import { FC, MouseEventHandler } from 'react' +import { ArrowDownUp } from 'lucide-react' + +interface Props { + disabled?: boolean + onClick?: MouseEventHandler +} + +export const ToggleButton: FC = ({ disabled, onClick }) => ( + +) diff --git a/wrap/src/components/WrapFeeWarningModal/index.module.css b/wrap/src/components/WrapFeeWarningModal/index.module.css index ffc18ba5..9be85e32 100644 --- a/wrap/src/components/WrapFeeWarningModal/index.module.css +++ b/wrap/src/components/WrapFeeWarningModal/index.module.css @@ -1,83 +1,4 @@ -.wrapFeeWarningModalContent { - display: flex; - flex-direction: column; - - h4 { - color: var(--gray-wrap-extra-dark); - } - - p { - color: var(--gray-wrap-extra-dark); - - &:first-of-type { - margin-bottom: 1rem; - } - - &:last-of-type { - margin-bottom: 3.125rem; - } - } -} - -.wrapFeeWarningModalLogo { - align-self: center; - margin-bottom: 3.125rem; -} - .wrapFeeWarningModalInput { width: 75%; margin: 0 auto; } - -.wrapFeeWarningModalActions { - display: flex; - flex-direction: column; - gap: 2.125rem; - margin: 2.5rem auto; - text-align: center; -} - -.wrapFeeWarningModalButton { - min-width: 250px; -} - -.wrapFeeWarningModalButtonText { - font-size: 13px; -} - -.wrapFeeWarningModalFullAmount { - background: none; - border: none; - padding: 0; - font: inherit; - outline: inherit; - color: var(--danger); - text-decoration: underline; - cursor: pointer; -} - -@media screen and (max-width: 1000px) { - .wrapFeeWarningModalContent { - p { - &:last-of-type { - margin-bottom: 2.625rem; - } - } - } - - .wrapFeeWarningModalLogo { - margin-bottom: 2rem; - } - - .wrapFeeWarningModalInput { - width: 100%; - } - - .wrapFeeWarningModalActions { - display: flex; - flex-direction: column; - gap: 1.625rem; - margin: 1.25rem auto; - text-align: center; - } -} diff --git a/wrap/src/components/WrapFeeWarningModal/index.tsx b/wrap/src/components/WrapFeeWarningModal/index.tsx index ab9ef94d..6fceb369 100644 --- a/wrap/src/components/WrapFeeWarningModal/index.tsx +++ b/wrap/src/components/WrapFeeWarningModal/index.tsx @@ -1,11 +1,18 @@ import { FC } from 'react' +import { Logo } from '@oasisprotocol/rose-app-ui' import { - WrapModal, - WrapModalProps, - LogoIconRound, - WrapInput, - WrapButton, -} from '@oasisprotocol/rose-app-ui/wrap' + Button, + cn, + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + Input, + Label, +} from '@oasisprotocol/ui-library/src' import classes from './index.module.css' import { useWrapForm } from '../../hooks/useWrapForm' import { WRAP_FEE_DEDUCTION_MULTIPLIER } from '../../constants/config' @@ -13,7 +20,9 @@ import { NumberUtils } from '../../utils/number.utils' import BigNumber from 'bignumber.js' import { formatEther } from 'viem' -interface WrapFeeWarningModalProps extends Pick { +interface WrapFeeWarningModalProps { + isOpen: boolean + closeModal: () => void next: (amount: BigNumber) => void } @@ -27,47 +36,56 @@ export const WrapFeeWarningModal: FC = ({ isOpen, clos const estimatedAmountWithDeductedFees = roseAmount!.minus(estimatedFeeDeduction) return ( - -
-
- -
+ + + +
+ +
-

You have chosen to wrap your entire balance

+ You have chosen to wrap your entire balance -

- It is recommended to keep a small amount in your wallet at all times to cover future transactions. -

-

- Choose if you want to wrap the reduced amount and keep {sum of {WRAP_FEE_DEDUCTION_MULTIPLIER}{' '} - x gas fee - e.g. ‘{formatEther(NumberUtils.BNtoBigInt(estimatedFeeDeduction))} ROSE’} in - your account, or continue with the full amount. -

+ +

+ It is recommended to keep a small amount in your wallet at all times to cover future + transactions. +

+

+ Choose if you want to wrap the reduced amount and keep {sum of{' '} + {WRAP_FEE_DEDUCTION_MULTIPLIER} x gas fee - e.g. ‘ + {formatEther(NumberUtils.BNtoBigInt(estimatedFeeDeduction))} ROSE’} in your account, + or continue with the full amount. +

+
+
- - className={classes.wrapFeeWarningModalInput} - variant="dark" - disabled - type="text" - label="wROSE" - placeholder="0" - inputMode="decimal" - value={formatEther(NumberUtils.BNtoBigInt(estimatedAmountWithDeductedFees))} - /> +
+ + +
-
- next(estimatedAmountWithDeductedFees)} - > - Wrap reduced amount - + + + + - -
-
-
+ + + + + + ) } diff --git a/wrap/src/components/WrapForm/index.module.css b/wrap/src/components/WrapForm/index.module.css deleted file mode 100644 index d64403a2..00000000 --- a/wrap/src/components/WrapForm/index.module.css +++ /dev/null @@ -1,36 +0,0 @@ -.wrapForm { - display: flex; - flex-direction: column; - position: relative; -} - -.wrapFormInputs { - position: relative; - display: flex; - flex-direction: column; - gap: 0.625rem; -} - -.toggleBtn { - position: absolute; - left: 2.8125rem; - top: 50%; - transform: translateY(-50%); -} - -.gasEstimateLabel.gasEstimateLabel { - text-align: center; - margin: 2rem 0 1rem; -} - -@media screen and (min-width: 1000px) { - .toggleBtn { - left: 50%; - top: 50%; - transform: translate3d(-50%, -50%, 0); - } - - .gasEstimateLabel { - margin: 3.875rem 0 1.5rem; - } -} diff --git a/wrap/src/components/WrapForm/index.tsx b/wrap/src/components/WrapForm/index.tsx index 2375dce6..23262b17 100644 --- a/wrap/src/components/WrapForm/index.tsx +++ b/wrap/src/components/WrapForm/index.tsx @@ -1,6 +1,6 @@ -import { FC, FormEvent, MouseEvent, useEffect, useRef, useState } from 'react' -import { WrapInput, WrapButton, WrapAlert, WrapToggleButton } from '@oasisprotocol/rose-app-ui/wrap' -import classes from './index.module.css' +import { ChangeEvent, FC, FormEvent, MouseEvent, useEffect, useRef, useState } from 'react' +import { Button, Alert, AlertTitle, cn, Separator, Input, Label } from '@oasisprotocol/ui-library/src' +import { Typography } from '@oasisprotocol/ui-library/src/components/typography' import { useNavigate } from 'react-router-dom' import { useWrapForm } from '../../hooks/useWrapForm' import { WrapFormType } from '../../utils/types' @@ -9,37 +9,49 @@ import { NumberUtils } from '../../utils/number.utils' import { WrapFeeWarningModal } from '../WrapFeeWarningModal' import { formatEther, parseEther } from 'viem' import BigNumber from 'bignumber.js' +import { ToggleButton } from '../ToggleButton' const AMOUNT_PATTERN = '^[0-9]*[.,]?[0-9]*$' -interface WrapFormLabels { +interface WrapFormData { firstInputLabel: string secondInputLabel: string submitBtnLabel: string -} - -const labelMapByFormType: Record = { - [WrapFormType.WRAP]: { - firstInputLabel: 'ROSE', - secondInputLabel: 'wROSE', - submitBtnLabel: 'Wrap tokens', - }, - [WrapFormType.UNWRAP]: { - firstInputLabel: 'wROSE', - secondInputLabel: 'ROSE', - submitBtnLabel: 'Unwrap tokens', - }, + firstBalance: string + secondBalance: string } export const WrapForm: FC = () => { const navigate = useNavigate() const { - state: { formType, amount, isLoading, balance, estimatedFee }, + state: { formType, amount, isLoading, balance, wRoseBalance, estimatedFee }, toggleFormType, submit, debounceLeadingSetFeeAmount, } = useWrapForm() - const { firstInputLabel, secondInputLabel, submitBtnLabel } = labelMapByFormType[formType] + + const roseBalanceString = `${balance ? formatEther(NumberUtils.BNtoBigInt(balance)) : '0'} ROSE` + const wRoseBalanceString = `${wRoseBalance ? formatEther(NumberUtils.BNtoBigInt(wRoseBalance)) : '0'} wROSE` + + const labelMapByFormType: Record = { + [WrapFormType.WRAP]: { + firstInputLabel: 'ROSE', + secondInputLabel: 'wROSE', + submitBtnLabel: 'Wrap tokens', + firstBalance: roseBalanceString, + secondBalance: wRoseBalanceString, + }, + [WrapFormType.UNWRAP]: { + firstInputLabel: 'wROSE', + secondInputLabel: 'ROSE', + submitBtnLabel: 'Unwrap tokens', + firstBalance: wRoseBalanceString, + secondBalance: roseBalanceString, + }, + } + + const { firstInputLabel, secondInputLabel, submitBtnLabel, firstBalance, secondBalance } = + labelMapByFormType[formType] const [value, setValue] = useState('') const [error, setError] = useState('') const [isWrapFeeModalOpen, setIsWrapFeeModalOpen] = useState(false) @@ -62,8 +74,8 @@ export const WrapForm: FC = () => { setValue(formattedAmount) }, [setValue, amount]) - const handleValueChange = (amount: string) => { - setValue(amount) + const handleValueChange = (event: ChangeEvent) => { + setValue(event.target.value) } const handleToggleFormType = (e: MouseEvent) => { @@ -99,12 +111,12 @@ export const WrapForm: FC = () => { ) { setIsWrapFeeModalOpen(true) } else { - submitTransaction(amount) + void submitTransaction(amount) } } const submitWrapFeeModal = (amount: BigNumber) => { - submitTransaction(amount) + void submitTransaction(amount) setIsWrapFeeModalOpen(false) } @@ -113,41 +125,73 @@ export const WrapForm: FC = () => { return (
-
-
- - disabled={isLoading} - type="text" - label={firstInputLabel} - pattern={AMOUNT_PATTERN} - placeholder="0" - inputMode="decimal" - value={value} - valueChange={handleValueChange} - /> - - disabled={isLoading} - type="text" - label={secondInputLabel} - pattern={AMOUNT_PATTERN} - placeholder="0" - inputMode="decimal" - value={value} - valueChange={handleValueChange} - /> - + +
+
+ +
+ + {firstInputLabel} +
+ + Balance: {firstBalance} + +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ + {secondInputLabel} +
+ + Balance: {secondBalance} + +
-

Estimated fee: {estimatedFeeTruncated}

+
+ Estimated gas fee: + {estimatedFeeTruncated} +
- - {submitBtnLabel} - - {error && {error}} +
+ + {error && ( + + {error} + + )} +
{ return ( -
- + + + WRAP -

- Quickly wrap your ROSE into wROSE and vice versa with the (un)wrap ROSE tool. -
- Please connect your wallet to get started. -

+ + Quickly wrap your ROSE into wROSE and vice versa with the (un)wrap ROSE tool. Please connect your + wallet to get started. + +
- -
+ + + + ) } diff --git a/wrap/src/pages/Transaction/index.tsx b/wrap/src/pages/Transaction/index.tsx index fe7215f2..0ac5e2b0 100644 --- a/wrap/src/pages/Transaction/index.tsx +++ b/wrap/src/pages/Transaction/index.tsx @@ -1,5 +1,7 @@ import { FC, useEffect, useState } from 'react' -import { WrapButton, OpenInNewIcon, Spinner } from '@oasisprotocol/rose-app-ui/wrap' +import { ExternalLink } from 'lucide-react' +import { Spinner } from '@oasisprotocol/rose-app-ui' +import { Button } from '@oasisprotocol/ui-library/src' import { useNavigate, useParams, useSearchParams } from 'react-router-dom' import classes from './index.module.css' import { StringUtils } from '../../utils/string.utils' @@ -89,15 +91,15 @@ const TransactionCmp: FC = () => { {txUrl && ( - + )} - +
)} {status === TransactionStatus.Fail && ( @@ -109,9 +111,9 @@ const TransactionCmp: FC = () => { Please try again. - +
)} diff --git a/wrap/src/pages/Wrapper/index.tsx b/wrap/src/pages/Wrapper/index.tsx index c5f2ce79..80f6b1b2 100644 --- a/wrap/src/pages/Wrapper/index.tsx +++ b/wrap/src/pages/Wrapper/index.tsx @@ -1,46 +1,45 @@ import { FC, useEffect } from 'react' -import classes from './index.module.css' -import { WrapButton } from '@oasisprotocol/rose-app-ui/wrap' -import { NumberUtils } from '../../utils/number.utils' +import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@oasisprotocol/ui-library/src' +// import { NumberUtils } from '../../utils/number.utils' import { WrapForm } from '../../components/WrapForm' -import { useWeb3 } from '../../hooks/useWeb3' +// import { useWeb3 } from '../../hooks/useWeb3' import { useWrapForm } from '../../hooks/useWrapForm' -import { WrapFormType } from '../../utils/types' -import BigNumber from 'bignumber.js' +// import { WrapFormType } from '../../utils/types' +// import BigNumber from 'bignumber.js' import { useAccount } from 'wagmi' import { withDisconnectedWallet } from '../../hoc/withDisconnectedWallet' -interface PercentageEntry { - value: BigNumber - label: string -} +// interface PercentageEntry { +// value: BigNumber +// label: string +// } -const percentageList: PercentageEntry[] = [ - { - label: '10%', - value: BigNumber(10), - }, - { - label: '25%', - value: BigNumber(25), - }, - { - label: '50%', - value: BigNumber(50), - }, - { - label: 'Max', - value: BigNumber(100), - }, -] +// const percentageList: PercentageEntry[] = [ +// { +// label: '10%', +// value: BigNumber(10), +// }, +// { +// label: '25%', +// value: BigNumber(25), +// }, +// { +// label: '50%', +// value: BigNumber(50), +// }, +// { +// label: 'Max', +// value: BigNumber(100), +// }, +// ] const WrapperCmp: FC = () => { const { address } = useAccount() - const { addTokenToWallet } = useWeb3() + // const { addTokenToWallet } = useWeb3() const { - state: { isLoading, balance, wRoseBalance, formType, estimatedFee }, + // state: { isLoading, balance, wRoseBalance, formType, estimatedFee }, init, - setAmount, + // setAmount, } = useWrapForm() useEffect(() => { @@ -48,47 +47,51 @@ const WrapperCmp: FC = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [address]) - const handlePercentageCalc = (percentage: BigNumber) => { - if (formType === WrapFormType.WRAP) { - if (percentage.eq(100)) { - /* In case of 100% WRAP, deduct gas fee */ - const percAmount = NumberUtils.getPercentageAmount(balance, percentage) - setAmount(percAmount.minus(estimatedFee)) - } else { - setAmount(NumberUtils.getPercentageAmount(balance, percentage)) - } - } else if (formType === WrapFormType.UNWRAP) { - setAmount(NumberUtils.getPercentageAmount(wRoseBalance, percentage)) - } else { - throw new Error('[formType] Invalid form type') - } - } + // const handlePercentageCalc = (percentage: BigNumber) => { + // if (formType === WrapFormType.WRAP) { + // if (percentage.eq(100)) { + // /* In case of 100% WRAP, deduct gas fee */ + // const percAmount = NumberUtils.getPercentageAmount(balance, percentage) + // setAmount(percAmount.minus(estimatedFee)) + // } else { + // setAmount(NumberUtils.getPercentageAmount(balance, percentage)) + // } + // } else if (formType === WrapFormType.UNWRAP) { + // setAmount(NumberUtils.getPercentageAmount(wRoseBalance, percentage)) + // } else { + // throw new Error('[formType] Invalid form type') + // } + // } return ( -
-
-

Quickly wrap your ROSE into wROSE and vice versa with the (un)wrap ROSE tool.

- - - Import WROSE to Wallet - -
+ + + WRAP + + Quickly wrap your ROSE into wROSE and vice versa with the (un)wrap ROSE tool. + + -
- {percentageList.map(({ label, value }) => ( - handlePercentageCalc(value)} - key={label} - variant="tertiary" - > - {label} - - ))} -
+ {/**/} - -
+ + {/*
*/} + {/* {percentageList.map(({ label, value }) => (*/} + {/* handlePercentageCalc(value)}*/} + {/* key={label}*/} + {/* variant="outline"*/} + {/* >*/} + {/* {label}*/} + {/* */} + {/* ))}*/} + {/*
*/} + +
+ ) }