Skip to content

Commit

Permalink
UI added
Browse files Browse the repository at this point in the history
  • Loading branch information
smgv committed Nov 6, 2024
1 parent 740af55 commit 8ab49d5
Show file tree
Hide file tree
Showing 21 changed files with 387 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
"changeProcessCWD": true
}
],
"cSpell.words": ["JRPC","Solana"]
"cSpell.words": ["clsx", "JRPC", "Ronin", "Solana"]
}
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,8 @@
"packages/plugins/*",
"packages/providers/*",
"packages/ui"
]
],
"dependencies": {
"tailwind-merge": "^2.5.4"
}
}
1 change: 1 addition & 0 deletions packages/modal-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"url": "https://github.com/Web3Auth/Web3Auth/issues"
},
"dependencies": {
"clsx": "^2.1.1",
"solid-js": "^1.8.11"
},
"description": "Ui modal for web3Auth",
Expand Down
24 changes: 11 additions & 13 deletions packages/modal-ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { batch, type Component, createSignal } from "solid-js";
import { createSignal, type Component } from "solid-js";
import { Modal } from "./components/Modal";
import { Body } from "./components/Body";

const App: Component = () => {
const [counter, setCounter] = createSignal(0);

const incrementCounter = () => {
batch(() => {
setCounter((c) => c + 1);
});
};
const [open, setOpen] = createSignal(false);
return (
<>
<p class="text-4xl text-app-white text-center py-20 bg-app-primary-600">Hello tailwind! hello</p>
<br />
<button onClick={incrementCounter}>Click to increment - {counter()}</button>
</>
<div class="w-screen h-screen flex items-center justify-center flex-col gap-4">
<h1 class="text-3xl font-bold text-slate-700">Try out your new modal</h1>
<button onClick={() => setOpen(true)}>Open Modal</button>
<Modal open={open()} onClose={() => setOpen(false)} placement="center" padding={false} showCloseIcon>
<Body />
</Modal>
</div>
);
};

Expand Down
25 changes: 25 additions & 0 deletions packages/modal-ui/src/components/Body/Body.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { createSignal } from "solid-js";
import Footer from "../Footer/Footer";
import ConnectWallet from "./ConnectWallet";
import Login from "./Login";

const PAGES = {
LOGIN: 'login',
CONNECT_WALLET: 'connect_wallet'
}

const Body = () => {

const [currentPage, setCurrentPage] = createSignal(PAGES.LOGIN);


return (
<div class="h-[760px] p-6 flex flex-col flex-1">
{currentPage() === PAGES.LOGIN && <Login onExternalWalletClick={() => setCurrentPage(PAGES.CONNECT_WALLET)} />}
{currentPage() === PAGES.CONNECT_WALLET && <ConnectWallet onBackClick={() => setCurrentPage(PAGES.LOGIN)} />}
<Footer />
</div>
);
};

export default Body
78 changes: 78 additions & 0 deletions packages/modal-ui/src/components/Body/ConnectWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { createSignal, For } from "solid-js"
import { WalletButton } from "../WalletButton"

export interface ConnectWalletProps {
onBackClick?: () => void
};

const WALLET_LIST = ['Metamask', 'Ronin Wallet', 'Phantom', 'Rainbow', 'Trust Wallet', 'Coinbase Wallet', 'Uniswap', 'Metamask', 'Ronin Wallet', 'Phantom', 'Rainbow', 'Trust Wallet', 'Coinbase Wallet', 'Uniswap', 'Metamask', 'Ronin Wallet', 'Phantom', 'Rainbow', 'Trust Wallet', 'Coinbase Wallet', 'Uniswap']


const PAGES = {
CONNECT_WALLET: 'Connect Wallet',
SELECTED_WALLET: "Selected Wallet"
}

const ConnectWallet = ({ onBackClick }: ConnectWalletProps) => {

const [currentPage, setCurrentPage] = createSignal(PAGES.CONNECT_WALLET);
const [selectedWallet, setSelectedWallet] = createSignal(false);

const handleBack = () => {
if (!selectedWallet() && currentPage() === PAGES.CONNECT_WALLET && onBackClick) {
onBackClick()
}

if (selectedWallet) {
setCurrentPage(PAGES.CONNECT_WALLET)
setSelectedWallet(false)
}
}

return (
<div class="flex flex-col gap-y-4 flex-1 relative">
<div class="flex items-center justify-between">
<figure class="w-5 h-5 rounded-full bg-app-gray-200 cursor-pointer" onClick={handleBack}></figure>
<p class="text-base font-medium text-app-gray-900">{currentPage()}</p>
<div class="w-5 h-5" />
</div>

{!selectedWallet() ? <div class="contents">
<input placeholder="Search through wallets..." class="w-full px-4 py-2.5 border border-app-gray-300 bg-app-gray-50 placeholder:text-app-gray-400 placeholder:text-sm placeholder:font-normal rounded-full" />
<ul class="flex flex-col gap-y-2 h-[calc(100dvh_-_240px)] overflow-y-auto">
<For each={WALLET_LIST}>
{(wallet) =>
<WalletButton label={wallet} onClick={() => { setSelectedWallet(true); setCurrentPage(PAGES.SELECTED_WALLET) }} />
}
</For>
</ul>
</div> :
<div class="contents">
<div class="bg-app-gray-200 rounded-lg h-[320px] w-[320px] mx-auto"></div>
<p class="text-center text-sm text-app-gray-500 font-normal">Scan with a WalletConnect-supported wallet or click the QR code to copy to your clipboard.</p>
<div class="flex items-center justify-between w-full mt-auto bg-app-gray-50 rounded-xl p-3">
<p class="text-sm text-app-gray-900">Don't have Trust Wallet?</p>
<button class="appearance-none border border-app-gray-900 text-xs text-app-gray-900 rounded-full px-2 py-2">Get Wallet</button>
</div>
</div>
}

{/* <div class="absolute bottom-0 left-0 bg-app-white rounded-lg p-6 w-full flex flex-col gap-y-2 shadow-sm border border-app-gray-100">
<div class="flex items-center gap-x-2 w-full bg-app-gray-100 px-4 py-2 rounded-full">
<figure class="w-5 h-5 rounded-full bg-app-gray-200 cursor-pointer"></figure>
<p class="text-sm font-medium text-app-gray-900">Install Chrome</p>
</div>
<div class="flex items-center gap-x-2 w-full bg-app-gray-100 px-4 py-2 rounded-full">
<figure class="w-5 h-5 rounded-full bg-app-gray-200 cursor-pointer"></figure>
<p class="text-sm font-medium text-app-gray-900">Install Chrome</p>
</div>
<div class="flex items-center gap-x-2 w-full bg-app-gray-100 px-4 py-2 rounded-full">
<figure class="w-5 h-5 rounded-full bg-app-gray-200 cursor-pointer"></figure>
<p class="text-sm font-medium text-app-gray-900">Install Chrome</p>
</div>
</div> */}
</div>
)
}

export default ConnectWallet
38 changes: 38 additions & 0 deletions packages/modal-ui/src/components/Body/Login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import SocialLoginList from "../SocialLoginList";

export interface LoginProps {
onExternalWalletClick?: () => void;
};

const Login = ({ onExternalWalletClick }: LoginProps) => {

const handleConnectWallet = (e: MouseEvent) => {
e.preventDefault();
if (onExternalWalletClick) onExternalWalletClick()
}
return (
<div class="flex flex-col gap-y-4 h-full">
<div class="flex flex-col items-start gap-y-1">
<p class="text-xl font-bold text-app-gray-900 dark:text-app-white">Sign in</p>
<p class="text-sm font-normal text-app-gray-500 dark:text-app-gray-400">Your Web3Auth wallet with one click</p>
</div>

<SocialLoginList />


<form class="flex flex-col gap-y-4 mt-auto">
<div class="flex flex-col gap-y-2">
<label class="text-sm font-semibold text-app-gray-900 text-start">Email or Phone</label>
<input placeholder="E.g. +00-123455/[email protected]" class="px-4 py-2.5 border border-app-gray-300 bg-app-gray-50 placeholder:text-app-gray-400 placeholder:text-sm placeholder:font-normal rounded-full" />
</div>
<button class="w-full px-5 py-3 rounded-full bg-app-gray-100 disabled:text-app-gray-400 text-app-gray-900 text-sm font-medium">Continue with Email</button>
<div class="flex flex-col gap-y-2">
<label class="text-sm font-semibold text-app-gray-900 text-start">External Wallet</label>
<button class="w-full px-5 py-3 rounded-full bg-app-gray-100 disabled:text-app-gray-400 text-app-gray-900 text-sm font-medium" onClick={handleConnectWallet}>Connect with Wallet</button>
</div>
</form>
</div>
)
}

export default Login;
1 change: 1 addition & 0 deletions packages/modal-ui/src/components/Body/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Body } from "./Body";
21 changes: 21 additions & 0 deletions packages/modal-ui/src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const Footer = () => {
return (
<div class="flex items-center gap-2 justify-center pt-6 mt-auto">
<div class="text-xs text-app-gray-300 dark:text-app-gray-500">{"modal.footer.message-new"}</div>
<img
height="16"
src="https://images.web3auth.io/web3auth-footer-logo-light.svg"
alt="Web3Auth Logo Light"
class="h-4 block dark:hidden"
/>
<img
height="16"
src="https://images.web3auth.io/web3auth-footer-logo-dark.svg"
alt="Web3Auth Logo Dark"
class="h-4 hidden dark:block"
/>
</div>
)
}

export default Footer
Empty file.
78 changes: 78 additions & 0 deletions packages/modal-ui/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Component, JSX, createSignal, createEffect, mergeProps } from "solid-js";
import { cn } from "../../utils/common";

export interface ModalProps {
children: JSX.Element[] | JSX.Element;
open: boolean;
onClose?: () => void;
placement?: 'center' | 'top-center' | 'bottom-center' | 'left' | 'right';
padding?: boolean;
shadow?: boolean;
border?: boolean;
showCloseIcon?: boolean;
}

const Modal: Component<ModalProps> = (props: ModalProps) => {

const mergedProps = mergeProps({ open: false, padding: true, placement: 'center', shadow: true, border: true, showCloseIcon: false }, props as ModalProps);

const [isOpen, setIsOpen] = createSignal<boolean>(false);

createEffect(() => {
if (mergedProps.open) {
document.body.style.overflow = "hidden";
// Give a very small delay for the animation to start from the correct position
setTimeout(() => {
setIsOpen(true);
}, 50);
} else {
setIsOpen(false);
// Remove overflow styling to enable scroll again.
document.body.style.overflow = "";
}
}, false);


const onCloseHandler = () => {
if (mergedProps.onClose) mergedProps.onClose()
};

const positions: Record<string, string> = {
'center': 'top-0 left-0 items-center justify-center',
'top-center': 'top-8 left-0 items-start justify-center',
'bottom-center': 'bottom-8 left-0 items-end justify-center',
'left': 'sm:left-8 flex items-center justify-center sm:justify-start',
'right': 'sm:right-8 flex items-center justify-center sm:justify-end',
};

const placementClass = positions[mergedProps.placement as string]

return (
<div
class={cn('fixed z-50 overflow-hidden flex transition-all', placementClass, {
"w-screen h-screen": isOpen(),
"w-0 h-0 delay-500": !isOpen(),
})}
>
<div
class={cn('bg-app-white rounded-3xl w-full sm:w-[400px] duration-500', {
"translate-y-0 delay-100": isOpen(),
"translate-y-[100vh]": !isOpen(),
"p-4": mergedProps.padding,
"shadow-xl sm:shadow-lg": mergedProps.shadow,
"border border-app-gray-100": mergedProps.border
})}
>
{mergedProps.showCloseIcon && <div class="absolute right-6 top-[30px] cursor-pointer">
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg" onClick={onCloseHandler}>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.292787 1.29299C0.480314 1.10552 0.734622 1.0002 0.999786 1.0002C1.26495 1.0002 1.51926 1.10552 1.70679 1.29299L5.99979 5.58599L10.2928 1.29299C10.385 1.19748 10.4954 1.1213 10.6174 1.06889C10.7394 1.01648 10.8706 0.988893 11.0034 0.987739C11.1362 0.986585 11.2678 1.01189 11.3907 1.06217C11.5136 1.11245 11.6253 1.1867 11.7192 1.28059C11.8131 1.37449 11.8873 1.48614 11.9376 1.60904C11.9879 1.73193 12.0132 1.86361 12.012 1.99639C12.0109 2.12917 11.9833 2.26039 11.9309 2.38239C11.8785 2.5044 11.8023 2.61474 11.7068 2.70699L7.41379 6.99999L11.7068 11.293C11.8889 11.4816 11.9897 11.7342 11.9875 11.9964C11.9852 12.2586 11.88 12.5094 11.6946 12.6948C11.5092 12.8802 11.2584 12.9854 10.9962 12.9877C10.734 12.9899 10.4814 12.8891 10.2928 12.707L5.99979 8.41399L1.70679 12.707C1.51818 12.8891 1.26558 12.9899 1.00339 12.9877C0.741188 12.9854 0.490376 12.8802 0.304968 12.6948C0.11956 12.5094 0.0143906 12.2586 0.0121121 11.9964C0.00983372 11.7342 0.110629 11.4816 0.292787 11.293L4.58579 6.99999L0.292787 2.70699C0.105316 2.51946 0 2.26515 0 1.99999C0 1.73483 0.105316 1.48052 0.292787 1.29299V1.29299Z" fill="#6B7280" />
</svg>
</div>}
{mergedProps.children}
</div>
</div >

);
};

export default Modal;
1 change: 1 addition & 0 deletions packages/modal-ui/src/components/Modal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Modal } from "./Modal";
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface SocialLoginButtonProps {
showIcon?: boolean;
showText?: boolean;
}

const SocialLoginButton = ({ showIcon = true, showText = true }: SocialLoginButtonProps) => {
return (
<button type="button" class="appearance-none w-full border border-app-gray-400 rounded-full px-5 py-2.5 flex items-center justify-center gap-x-2 hover:shadow-md hover:translate-y-[0.5px]">
{showIcon && <figure class="h-5 w-5 rounded-full bg-app-gray-200"></figure>}
{showText && <p class="text-sm font-semibold">Continue with Google</p>}
</button>
);
};

export default SocialLoginButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as SocialLoginButton } from "./SocialLoginButton";
Loading

0 comments on commit 8ab49d5

Please sign in to comment.