Skip to content

Commit 668201f

Browse files
committed
Dynamic height change for modal
1 parent f086b0a commit 668201f

File tree

7 files changed

+197
-147
lines changed

7 files changed

+197
-147
lines changed

packages/modal-ui/src/components/Body/Body.tsx

Lines changed: 142 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { type SafeEventEmitter } from "@web3auth/auth";
22
import { ChainNamespaceType, log, WALLET_ADAPTERS, WalletRegistry, WalletRegistryItem } from "@web3auth/base/src";
33
import Bowser from "bowser";
4-
import { createMemo, Match, Show, Suspense, Switch, useContext } from "solid-js";
4+
import { createMemo, createSignal, Match, Show, Suspense, Switch, useContext } from "solid-js";
55
import { createStore } from "solid-js/store";
66

77
import { PAGES } from "../../constants";
@@ -53,16 +53,6 @@ export interface BodyProps {
5353
handleBackClick: () => void;
5454
}
5555

56-
// interface BodyContextType {
57-
// bodyState: {
58-
// showWalletDetails: boolean;
59-
// walletDetails: ExternalButton;
60-
// };
61-
// setBodyState: (state: { showWalletDetails: boolean; walletDetails: ExternalButton }) => void;
62-
// }
63-
64-
// export const BodyContext = createContext<BodyContextType>({} as BodyContextType);
65-
6656
const Body = (props: BodyProps) => {
6757
const { isDark } = useContext(ThemedContext);
6858

@@ -74,6 +64,9 @@ const Body = (props: BodyProps) => {
7464
walletDetails: null,
7565
});
7666

67+
const [isSocialLoginsExpanded, setIsSocialLoginsExpanded] = createSignal(false);
68+
const [isWalletDetailsExpanded, setIsWalletDetailsExpanded] = createSignal(false);
69+
7770
const handleExternalWalletBtnClick = (flag: boolean) => {
7871
props.setModalState({
7972
...props.modalState,
@@ -288,110 +281,148 @@ const Body = (props: BodyProps) => {
288281
return allButtons().length + customAdapterButtons().length;
289282
});
290283

284+
const handleSocialLoginHeight = () => {
285+
setIsSocialLoginsExpanded((prev) => !prev);
286+
};
287+
288+
const handleWalletDetailsHeight = () => {
289+
setIsWalletDetailsExpanded((prev) => !prev);
290+
};
291+
292+
const containerMaxHeight = createMemo(() => {
293+
if (isWalletDetailsExpanded()) {
294+
return "588px";
295+
}
296+
if (props.modalState.currentPage === PAGES.CONNECT_WALLET || isSocialLoginsExpanded()) {
297+
return "642px";
298+
}
299+
return "539px";
300+
});
301+
291302
return (
292-
<div class="w3a--h-auto w3a--p-6 w3a--flex w3a--flex-col w3a--flex-1 w3a--relative">
293-
{/* Content */}
294-
<Show
295-
when={props.modalState.status !== MODAL_STATUS.INITIALIZED}
296-
fallback={
297-
<Suspense>
298-
<Switch>
299-
<Match
300-
when={
301-
props.modalState.currentPage === PAGES.LOGIN && props.showExternalWalletPage && props.modalState.status === MODAL_STATUS.INITIALIZED
302-
}
303-
>
304-
<Login
305-
{...props}
306-
isDark={isDark}
307-
showPasswordLessInput={props.showPasswordLessInput}
308-
showExternalWalletButton={props.showExternalWalletButton}
309-
handleSocialLoginClick={props.handleSocialLoginClick}
310-
socialLoginsConfig={props.socialLoginsConfig}
311-
areSocialLoginsVisible={props.areSocialLoginsVisible}
312-
isEmailPrimary={props.isEmailPrimary}
313-
isExternalPrimary={props.isExternalPrimary}
314-
handleExternalWalletBtnClick={handleExternalWalletBtnClick}
315-
isEmailPasswordLessLoginVisible={props.isEmailPasswordLessLoginVisible}
316-
isSmsPasswordLessLoginVisible={props.isSmsPasswordLessLoginVisible}
317-
totalExternalWallets={totalExternalWalletsLength()}
318-
/>
319-
</Match>
320-
<Match
321-
when={
322-
props.modalState.currentPage === PAGES.CONNECT_WALLET &&
323-
!props.showExternalWalletPage &&
324-
props.modalState.status === MODAL_STATUS.INITIALIZED
325-
}
326-
>
327-
<ConnectWallet
328-
isDark={isDark}
329-
onBackClick={handleBackClick}
330-
modalStatus={props.modalState.status}
331-
showBackButton={props.areSocialLoginsVisible || props.showPasswordLessInput}
332-
handleExternalWalletClick={props.preHandleExternalWalletClick}
333-
chainNamespace={props.chainNamespace}
334-
walletConnectUri={props.modalState.walletConnectUri}
335-
config={props.modalState.externalWalletsConfig}
336-
walletRegistry={props.walletRegistry}
337-
appLogo={props.appLogo}
338-
totalExternalWallets={totalExternalWalletsLength()}
339-
allExternalButtons={allButtons()}
340-
adapterVisibilityMap={adapterVisibility()}
341-
customAdapterButtons={customAdapterButtons()}
342-
deviceDetails={deviceDetailsWallets()}
343-
bodyState={bodyState}
344-
setBodyState={setBodyState}
345-
/>
346-
</Match>
347-
</Switch>
348-
</Suspense>
349-
}
303+
<div class="w3a--flex w3a--flex-col">
304+
<div
305+
class="h-screen w3a--transition-all w3a--overflow-hidden w3a--duration-[400ms] w3a--ease-in-out w3a--relative"
306+
style={{
307+
"max-height": containerMaxHeight(),
308+
}}
350309
>
351-
<Loader
352-
adapter={props.modalState.detailedLoaderAdapter}
353-
adapterName={props.modalState.detailedLoaderAdapter}
354-
modalStatus={props.modalState.status}
355-
onClose={props.onCloseLoader}
356-
appLogo={props.appLogo}
357-
/>
358-
</Show>
359-
360-
{/* Footer */}
361-
<Footer />
362-
363-
{/* Wallet Details */}
364-
<Show when={bodyState.showWalletDetails}>
365-
<div
366-
class="w3a--absolute w3a--h-full w3a--w-full w3a--top-0 w3a--left-0 w3a--bottom-sheet-bg w3a--rounded-3xl"
367-
onClick={() => setBodyState({ showWalletDetails: false })}
368-
/>
369-
<div
370-
class="w3a--absolute w3a--bottom w3a--left-0 w3a--bg-app-light-surface-main dark:w3a--bg-app-dark-surface-main w3a--rounded-3xl w3a--p-4 w3a--bottom-sheet-width w3a--flex w3a--flex-col
371-
w3a--gap-y-2 w3a--shadow-sm w3a--border w3a--border-app-gray-100 dark:w3a--border-app-gray-600"
372-
>
373-
<div
374-
class="w3a--h-1 w3a--w-16 w3a--bg-app-gray-200 dark:w3a--bg-app-gray-700 w3a--mx-auto w3a--rounded-full w3a--cursor-pointer"
375-
onClick={() => setBodyState({ showWalletDetails: false })}
376-
aria-hidden="true"
377-
role="button"
378-
/>
379-
<div class="w3a--flex w3a--justify-center w3a--my-4">
380-
<Image
381-
imageId={`login-${bodyState.walletDetails.name}`}
382-
hoverImageId={`login-${bodyState.walletDetails.name}`}
383-
fallbackImageId="wallet"
384-
height="80"
385-
width="80"
386-
isButton
387-
extension={bodyState.walletDetails.imgExtension}
310+
<div class="w3a--modal-curtain" />
311+
<div class="w3a--h-full w3a--p-6 w3a--flex w3a--flex-col w3a--flex-1 w3a--relative">
312+
{/* Content */}
313+
<Show
314+
when={props.modalState.status !== MODAL_STATUS.INITIALIZED}
315+
fallback={
316+
<Suspense>
317+
<Switch>
318+
<Match
319+
when={
320+
props.modalState.currentPage === PAGES.LOGIN &&
321+
props.showExternalWalletPage &&
322+
props.modalState.status === MODAL_STATUS.INITIALIZED
323+
}
324+
>
325+
<Login
326+
{...props}
327+
isDark={isDark}
328+
showPasswordLessInput={props.showPasswordLessInput}
329+
showExternalWalletButton={props.showExternalWalletButton}
330+
handleSocialLoginClick={props.handleSocialLoginClick}
331+
socialLoginsConfig={props.socialLoginsConfig}
332+
areSocialLoginsVisible={props.areSocialLoginsVisible}
333+
isEmailPrimary={props.isEmailPrimary}
334+
isExternalPrimary={props.isExternalPrimary}
335+
handleExternalWalletBtnClick={handleExternalWalletBtnClick}
336+
isEmailPasswordLessLoginVisible={props.isEmailPasswordLessLoginVisible}
337+
isSmsPasswordLessLoginVisible={props.isSmsPasswordLessLoginVisible}
338+
totalExternalWallets={totalExternalWalletsLength()}
339+
handleSocialLoginHeight={handleSocialLoginHeight}
340+
/>
341+
</Match>
342+
<Match
343+
when={
344+
props.modalState.currentPage === PAGES.CONNECT_WALLET &&
345+
!props.showExternalWalletPage &&
346+
props.modalState.status === MODAL_STATUS.INITIALIZED
347+
}
348+
>
349+
<ConnectWallet
350+
isDark={isDark}
351+
onBackClick={handleBackClick}
352+
modalStatus={props.modalState.status}
353+
showBackButton={props.areSocialLoginsVisible || props.showPasswordLessInput}
354+
handleExternalWalletClick={props.preHandleExternalWalletClick}
355+
chainNamespace={props.chainNamespace}
356+
walletConnectUri={props.modalState.walletConnectUri}
357+
config={props.modalState.externalWalletsConfig}
358+
walletRegistry={props.walletRegistry}
359+
appLogo={props.appLogo}
360+
totalExternalWallets={totalExternalWalletsLength()}
361+
allExternalButtons={allButtons()}
362+
adapterVisibilityMap={adapterVisibility()}
363+
customAdapterButtons={customAdapterButtons()}
364+
deviceDetails={deviceDetailsWallets()}
365+
bodyState={bodyState}
366+
setBodyState={setBodyState}
367+
handleWalletDetailsHeight={handleWalletDetailsHeight}
368+
/>
369+
</Match>
370+
</Switch>
371+
</Suspense>
372+
}
373+
>
374+
<Loader
375+
adapter={props.modalState.detailedLoaderAdapter}
376+
adapterName={props.modalState.detailedLoaderAdapter}
377+
modalStatus={props.modalState.status}
378+
onClose={props.onCloseLoader}
379+
appLogo={props.appLogo}
380+
/>
381+
</Show>
382+
383+
{/* Footer */}
384+
<Footer />
385+
386+
{/* Wallet Details */}
387+
<Show when={bodyState.showWalletDetails}>
388+
{/* Backdrop */}
389+
<div
390+
class="w3a--fixed w3a--top-0 w3a--left-0 w3a--w-full w3a--h-full w3a--bottom-sheet-bg w3a--transition-opacity w3a--duration-300"
391+
onClick={() => setBodyState({ showWalletDetails: false })}
388392
/>
389-
</div>
390-
<ul class="w3a--flex w3a--flex-col w3a--gap-y-2">
391-
{deviceDetails().platform === "desktop" ? desktopInstallLinks() : mobileInstallLinks()}
392-
</ul>
393+
{/* Bottom Sheet */}
394+
<div
395+
class={`w3a--fixed w3a--left-0 w3a--bottom-0 w3a--w-full w3a--bg-app-light-surface-main dark:w3a--bg-app-dark-surface-main
396+
w3a--rounded-t-3xl w3a--p-4 w3a--flex w3a--flex-col w3a--gap-y-2 w3a--shadow-lg w3a--border w3a--border-app-gray-100
397+
dark:w3a--border-app-gray-600 w3a--transition-transform w3a--duration-500 w3a--ease-out
398+
${bodyState.showWalletDetails ? "w3a--translate-y-0 w3a--delay-700" : "w3a--translate-y-full"}`}
399+
>
400+
{/* Drag Handle */}
401+
<div
402+
class="w3a--h-1 w3a--w-16 w3a--bg-app-gray-200 dark:w3a--bg-app-gray-700 w3a--mx-auto w3a--rounded-full
403+
w3a--cursor-pointer"
404+
onClick={() => setBodyState({ showWalletDetails: false })}
405+
aria-hidden="true"
406+
role="button"
407+
/>
408+
<div class="w3a--flex w3a--justify-center w3a--my-4">
409+
<Image
410+
imageId={`login-${bodyState.walletDetails.name}`}
411+
hoverImageId={`login-${bodyState.walletDetails.name}`}
412+
fallbackImageId="wallet"
413+
height="80"
414+
width="80"
415+
isButton
416+
extension={bodyState.walletDetails.imgExtension}
417+
/>
418+
</div>
419+
<ul class="w3a--flex w3a--flex-col w3a--gap-y-2">
420+
{deviceDetails().platform === "desktop" ? desktopInstallLinks() : mobileInstallLinks()}
421+
</ul>
422+
</div>
423+
</Show>
393424
</div>
394-
</Show>
425+
</div>
395426
</div>
396427
);
397428
};

packages/modal-ui/src/components/Body/ConnectWallet.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export interface ConnectWalletProps {
3030
walletDetails: ExternalButton;
3131
};
3232
setBodyState: (state: { showWalletDetails: boolean; walletDetails: ExternalButton }) => void;
33+
handleWalletDetailsHeight: () => void;
3334
}
3435

3536
const ConnectWallet = (props: ConnectWalletProps) => {
@@ -55,6 +56,7 @@ const ConnectWallet = (props: ConnectWalletProps) => {
5556
if (selectedWallet()) {
5657
setCurrentPage(CONNECT_WALLET_PAGES.CONNECT_WALLET);
5758
setSelectedWallet(false);
59+
props.handleWalletDetailsHeight();
5860
}
5961
};
6062

@@ -141,6 +143,8 @@ const ConnectWallet = (props: ConnectWalletProps) => {
141143
walletDetails: button,
142144
});
143145
}
146+
147+
props.handleWalletDetailsHeight();
144148
};
145149

146150
const handleMoreWallets = () => {
@@ -211,7 +215,7 @@ const ConnectWallet = (props: ConnectWalletProps) => {
211215
)}
212216
onClick={() => setSelectedChain("ethereum")}
213217
>
214-
<img src={getIcons(props.isDark ? "ethereum-dark" : "ethereum-light")} alt="ethereum" />
218+
<img src={getIcons(props.isDark ? "ethereum-dark" : "ethereum-light")} alt="ethereum" class="w3a--w-5 w3a--h-5" />
215219
</button>
216220
<button
217221
class={cn(
@@ -222,7 +226,7 @@ const ConnectWallet = (props: ConnectWalletProps) => {
222226
)}
223227
onClick={() => setSelectedChain("polygon")}
224228
>
225-
<img src={getIcons(props.isDark ? "polygon-dark" : "polygon-light")} alt="polygon" />
229+
<img src={getIcons(props.isDark ? "polygon-dark" : "polygon-light")} alt="polygon" class="w3a--w-5 w3a--h-5" />
226230
</button>
227231
<button
228232
class={cn(
@@ -233,7 +237,7 @@ const ConnectWallet = (props: ConnectWalletProps) => {
233237
)}
234238
onClick={() => setSelectedChain("solana")}
235239
>
236-
<img src={getIcons(props.isDark ? "solana-dark" : "solana-light")} alt="solana" />
240+
<img src={getIcons(props.isDark ? "solana-dark" : "solana-light")} alt="solana" class="w3a--w-5 w3a--h-5" />
237241
</button>
238242
</div>
239243
</Show>

packages/modal-ui/src/components/Body/Login.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export interface LoginProps {
2424
isEmailPasswordLessLoginVisible: boolean;
2525
isSmsPasswordLessLoginVisible: boolean;
2626
totalExternalWallets: number;
27+
handleSocialLoginHeight: () => void;
2728
}
2829

2930
export type rowType = {
@@ -64,6 +65,7 @@ const Login = (props: LoginProps) => {
6465
const handleExpand = () => {
6566
setExpand((prev) => !prev);
6667
setIsPasswordlessCtaClicked(false);
68+
props.handleSocialLoginHeight();
6769
};
6870

6971
createEffect(() => {

packages/modal-ui/src/components/Modal/Modal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const Modal: Component<ModalProps> = (props: ModalProps) => {
6060
>
6161
<div
6262
class={cn(
63-
"w3a--bg-app-light-surface1 dark:w3a--bg-app-dark-surface-main w3a--rounded-3xl w3a--w-[96%] sm:w3a--w-[393px] w3a--h-[642px] w3a--flex w3a--flex-col w3a--duration-500",
63+
"w3a--bg-app-light-surface1 dark:w3a--bg-app-dark-surface-main w3a--rounded-3xl w3a--w-[96%] sm:w3a--w-[393px] w3a--h-auto w3a--flex w3a--flex-col w3a--duration-500",
6464
{
6565
"w3a--translate-y-0 w3a--delay-100": isOpen(),
6666
"w3a--translate-y-[100vh]": !isOpen(),

0 commit comments

Comments
 (0)