Skip to content

Commit 7713101

Browse files
fix: fix modal positioning for multiple toggle buttons
1 parent 628de53 commit 7713101

File tree

5 files changed

+75
-39
lines changed

5 files changed

+75
-39
lines changed

packages/ui-kit/src/lib/components/LoginModal/index.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ type LoginModalProps = {
2727
isWalletMinimised: boolean;
2828
setMinimiseWallet: (isWalletMinimised: boolean) => void;
2929
handleUserLogOutEvent: () => void;
30-
toggleButtonRef: React.RefObject<HTMLDivElement>;
3130
sendMessageToPushWallet: (message: any) => void;
3231
isReadOnly: boolean;
32+
toggleButtonRefs: React.MutableRefObject<Record<string, HTMLDivElement | null>>;
33+
activeTriggerId: string | undefined;
3334
};
3435

3536
const LoginModal: FC<LoginModalProps> = ({
@@ -45,20 +46,22 @@ const LoginModal: FC<LoginModalProps> = ({
4546
setMinimiseWallet,
4647
handleUserLogOutEvent,
4748
config,
48-
toggleButtonRef,
4949
sendMessageToPushWallet,
50-
isReadOnly
50+
isReadOnly,
51+
toggleButtonRefs,
52+
activeTriggerId,
5153
}) => {
5254
const [version, setVersion] = React.useState<number>(5);
5355

5456
const { modal } = config;
5557
const { pushChainClient } = usePushChainClient(config?.uid || 'default');
5658

5759
const { top, left } = useSmartModalPosition(
58-
toggleButtonRef,
60+
activeTriggerId || null,
61+
toggleButtonRefs,
5962
450,
6063
675,
61-
config.uid
64+
config.uid,
6265
);
6366

6467
const handleSendTransaction = async (data: ExecuteParams) => {
@@ -278,10 +281,12 @@ const FrameContainer = styled.div<{
278281
$style?: Record<'top' | 'left', number>;
279282
}>`
280283
position: fixed;
281-
top: ${({ $universalAccount, $accountMenuVariant }) =>
284+
top: ${({ $universalAccount, $accountMenuVariant, $style }) =>
282285
$universalAccount
283286
? $accountMenuVariant === PushUI.CONSTANTS.CONNECTED.LAYOUT.FULL
284287
? '0'
288+
: $style?.top != null
289+
? `${$style.top}px`
285290
: '50px'
286291
: '0'};
287292
left: ${({ $style }) => ($style?.left != null ? `${$style.left}px` : 'auto')};

packages/ui-kit/src/lib/components/LoginModal/useSmartModalPosition.ts

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { PushUI } from '../../constants';
55
type Position = { top: number; left: number };
66

77
export function useSmartModalPosition(
8-
triggerRef: React.RefObject<HTMLElement>,
8+
triggerId: string | null,
9+
triggerRefs: React.MutableRefObject<Record<string, HTMLDivElement | null>>,
910
modalWidth = 450,
1011
modalHeight = 675,
1112
uid?: string,
@@ -16,35 +17,43 @@ export function useSmartModalPosition(
1617

1718
useEffect(() => {
1819
const calculatePosition = () => {
19-
if (!triggerRef.current) return;
20+
if (!triggerId || !triggerRefs.current[triggerId]) return;
21+
22+
const triggerRef = triggerRefs.current[triggerId];
2023

2124
if (config.modal?.connectedLayout === PushUI.CONSTANTS.CONNECTED.LAYOUT.FULL) {
2225
setPosition({ top: 0, left: 0 });
2326
return;
2427
}
2528

26-
const triggerRect = triggerRef.current.getBoundingClientRect();
29+
const triggerRect = triggerRef.getBoundingClientRect();
2730
const viewportHeight = window.innerHeight;
2831
const viewportWidth = window.innerWidth;
2932

3033
const spaceBelow = viewportHeight - triggerRect.bottom;
3134
const spaceAbove = triggerRect.top;
32-
const spaceRight = viewportWidth - triggerRect.left;
33-
const spaceLeft = triggerRect.right;
34-
35-
const top =
36-
spaceBelow >= modalHeight
37-
? triggerRect.bottom - 16
38-
: spaceAbove >= modalHeight
39-
? triggerRect.top - modalHeight + 16
40-
: Math.max(viewportHeight - modalHeight, 0);
41-
42-
const left =
43-
spaceRight >= modalWidth
44-
? triggerRect.left - 35
45-
: spaceLeft >= modalWidth
46-
? triggerRect.right - modalWidth + 35
47-
: Math.max(viewportWidth - modalWidth, 0);
35+
const spaceRight = viewportWidth - triggerRect.right;
36+
const spaceLeft = triggerRect.left;
37+
38+
let top;
39+
let left;
40+
41+
if (spaceBelow >= modalHeight) {
42+
top = triggerRect.bottom;
43+
} else if (spaceAbove >= modalHeight) {
44+
top = triggerRect.top - modalHeight;
45+
} else {
46+
top = Math.max(viewportHeight - modalHeight, 0) / 2;
47+
}
48+
49+
// Horizontal
50+
if ((spaceRight + triggerRect.width) >= modalWidth) {
51+
left = triggerRect.left - 35;
52+
} else if (spaceLeft >= modalWidth) {
53+
left = triggerRect.right - modalWidth + 35;
54+
} else {
55+
left = Math.max(viewportWidth - modalWidth, 0) / 2;
56+
}
4857

4958
setPosition({ top, left });
5059
};
@@ -61,7 +70,7 @@ export function useSmartModalPosition(
6170
window.removeEventListener('resize', calculatePosition);
6271
document.body.style.overflow = '';
6372
};
64-
}, [triggerRef, modalWidth, modalHeight, isWalletMinimised, config]);
73+
}, [triggerId, triggerRefs, modalWidth, modalHeight, isWalletMinimised, config, uid]);
6574

6675
useEffect(() => {
6776
if (!universalAccount) {

packages/ui-kit/src/lib/components/PushUniversalAccountButton/TogglePushWalletButton.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { CHAIN } from '@pushchain/core/src/lib/constants/enums';
33
import { usePushWalletContext } from '../../hooks/usePushWallet';
44
import { UniversalAccount } from '../../types';
5-
import { Button, PushLogo, PushMonotone } from '../common';
5+
import { Button, PushMonotone } from '../common';
66
import { centerMaskString, getChainId } from '../../helpers';
77
import { CHAIN_LOGO } from '../../constants';
88
import styled from 'styled-components';
@@ -14,14 +14,15 @@ export type TogglePushWalletButtonProps = {
1414
customComponent?: React.ReactNode;
1515
className?: string;
1616
};
17+
1718
const TogglePushWalletButton: React.FC<TogglePushWalletButtonProps> = ({
1819
uid,
1920
universalAccount,
2021
customComponent,
21-
className,
22+
className = 'default',
2223
style,
2324
}) => {
24-
const { setMinimiseWallet, isWalletMinimised, toggleButtonRef } =
25+
const { setMinimiseWallet, isWalletMinimised, toggleButtonRefs , setActiveTriggerId } =
2526
usePushWalletContext(uid);
2627
const { chain, address } = universalAccount;
2728

@@ -40,10 +41,26 @@ const TogglePushWalletButton: React.FC<TogglePushWalletButtonProps> = ({
4041

4142
const maskedAddress = centerMaskString(address);
4243

44+
const handleClick = () => {
45+
setActiveTriggerId(className);
46+
setMinimiseWallet(!isWalletMinimised);
47+
};
48+
49+
const setTriggerRef = React.useCallback(
50+
(node: HTMLDivElement | null) => {
51+
if (node) {
52+
toggleButtonRefs.current[className] = node;
53+
} else {
54+
delete toggleButtonRefs.current[className];
55+
}
56+
},
57+
[className]
58+
);
59+
4360
return (
4461
<ButtonContainer
45-
onClick={() => setMinimiseWallet(!isWalletMinimised)}
46-
ref={toggleButtonRef}
62+
onClick={handleClick}
63+
ref={setTriggerRef}
4764
>
4865
{customComponent ? customComponent : (
4966
<Button

packages/ui-kit/src/lib/components/PushUniversalAccountButton/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { usePushWalletContext } from '../../hooks/usePushWallet';
44
import { ConnectPushWalletButtonProps, ConnectWalletButton } from './ConnectWalletButton';
55
import { TogglePushWalletButton, TogglePushWalletButtonProps } from './TogglePushWalletButton';
66
import {
7-
createGlobalStyle,
87
DefaultTheme,
98
ThemeProvider,
109
} from 'styled-components';

packages/ui-kit/src/lib/context/WalletContext.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import React, {
22
createContext,
33
FC,
4-
useCallback,
54
useEffect,
65
useRef,
76
useState,
87
} from 'react';
98
import { PushChain } from '@pushchain/core';
109
import {
11-
PROGRESS_HOOK,
1210
ProgressEvent,
1311
} from '@pushchain/core/src/lib/progress-hook/progress-hook.types';
1412
import {
@@ -65,14 +63,16 @@ export type WalletContextType = {
6563
themeMode: ThemeMode;
6664
themeOverrides: ThemeOverrides;
6765

68-
toggleButtonRef: React.RefObject<HTMLDivElement>;
69-
7066
progress: ProgressEvent | null;
7167
setProgress: React.Dispatch<React.SetStateAction<ProgressEvent | null>>;
7268

7369
isReadOnly: boolean;
7470
setIsReadOnly: React.Dispatch<React.SetStateAction<boolean>>;
7571
requestPushWalletConnection: () => Promise<{ chain: ChainType; provider: IWalletProvider["name"] }>;
72+
73+
activeTriggerId: string | undefined;
74+
setActiveTriggerId: React.Dispatch<React.SetStateAction<string | undefined>>;
75+
toggleButtonRefs: React.MutableRefObject<Record<string, HTMLDivElement | null>>;
7676
};
7777

7878
export const WalletContext = createContext<WalletContextType | null>(null);
@@ -131,7 +131,10 @@ export const WalletContextProvider: FC<PushWalletProviderProps> = ({
131131
: undefined
132132
);
133133

134-
const toggleButtonRef = useRef<HTMLDivElement>(null);
134+
const [activeTriggerId, setActiveTriggerId] = useState<string>();
135+
136+
const toggleButtonRefs = React.useRef<Record<string, HTMLDivElement | null>>({});
137+
135138

136139
const updateModalAppData = (newData: Partial<ModalAppDetails>) => {
137140
setModalAppData((prevData) => ({
@@ -663,13 +666,15 @@ export const WalletContextProvider: FC<PushWalletProviderProps> = ({
663666
handleSignMessage,
664667
handleSignAndSendTransaction,
665668
handleSignTypedData,
666-
toggleButtonRef,
667669
progress,
668670
setProgress,
669671
isReadOnly,
670672
setIsReadOnly,
671673
handleExternalWalletConnection,
672674
requestPushWalletConnection,
675+
activeTriggerId,
676+
setActiveTriggerId,
677+
toggleButtonRefs,
673678
}}
674679
>
675680
<LoginModal
@@ -685,9 +690,10 @@ export const WalletContextProvider: FC<PushWalletProviderProps> = ({
685690
isWalletMinimised={isWalletMinimised}
686691
setMinimiseWallet={setMinimiseWallet}
687692
handleUserLogOutEvent={handleUserLogOutEvent}
688-
toggleButtonRef={toggleButtonRef}
689693
sendMessageToPushWallet={sendMessageToPushWallet}
690694
isReadOnly={isReadOnly}
695+
toggleButtonRefs={toggleButtonRefs}
696+
activeTriggerId={activeTriggerId}
691697
/>
692698
{progress && (
693699
<PushWalletToast progress={progress} setProgress={setProgress} />

0 commit comments

Comments
 (0)