Skip to content

Commit e3b9098

Browse files
committed
fix: simplify address dropdown
1 parent 3eff40b commit e3b9098

File tree

2 files changed

+73
-163
lines changed

2 files changed

+73
-163
lines changed

apps/namadillo/src/App/Transfer/AddressDropdown.tsx

Lines changed: 73 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { KeplrWalletManager } from "integrations/Keplr";
1111
import { getChainFromAddress } from "integrations/utils";
1212
import { useAtom, useAtomValue } from "jotai";
1313
import { useEffect, useState } from "react";
14-
import { GoChevronDown } from "react-icons/go";
1514
import { useLocation } from "react-router-dom";
1615
import { twMerge } from "tailwind-merge";
1716
import namadaShieldedIcon from "./assets/namada-shielded.svg";
@@ -27,12 +26,10 @@ type AddressOption = {
2726
iconUrl: string;
2827
};
2928

30-
type AddressDropdownProps = {
29+
type AddressListProps = {
3130
selectedAddress?: string;
3231
destinationAddress?: string;
3332
className?: string;
34-
showAddress?: boolean;
35-
onClick?: () => void;
3633
onSelectAddress?: (address: string) => void;
3734
};
3835

@@ -42,11 +39,8 @@ export const AddressDropdown = ({
4239
selectedAddress,
4340
destinationAddress,
4441
className = "",
45-
showAddress = false,
46-
onClick,
4742
onSelectAddress,
48-
}: AddressDropdownProps): JSX.Element => {
49-
const [isOpen, setIsOpen] = useState(false);
43+
}: AddressListProps): JSX.Element => {
5044
const [keplrAddress, setKeplrAddress] = useState<string | null>(null);
5145
const [isConnectingKeplr, setIsConnectingKeplr] = useState(false);
5246
const { data: accounts } = useAtomValue(allDefaultAccountsAtom);
@@ -147,21 +141,7 @@ export const AddressDropdown = ({
147141
});
148142
}
149143

150-
// Find the selected option
151-
const selectedOption = addressOptions.find(
152-
(option) => option.address === selectedAddress
153-
);
154-
155-
const handleToggle = (): void => {
156-
if (onClick) {
157-
onClick();
158-
} else if (addressOptions.length > 1 || !connectedWallets.keplr) {
159-
setIsOpen(!isOpen);
160-
}
161-
};
162-
163144
const handleSelectOption = (option: AddressOption): void => {
164-
setIsOpen(false);
165145
if (onSelectAddress) {
166146
onSelectAddress(option.address);
167147
}
@@ -203,159 +183,90 @@ export const AddressDropdown = ({
203183
} catch (error) {
204184
console.error("Failed to fetch Keplr address after connection:", error);
205185
}
206-
207-
setIsOpen(false);
208186
} catch (error) {
209187
console.error("Failed to connect to Keplr:", error);
210188
} finally {
211189
setIsConnectingKeplr(false);
212190
}
213191
};
214192

215-
// Close dropdown when clicking outside
216-
useEffect(() => {
217-
const handleClickOutside = (event: MouseEvent): void => {
218-
const target = event.target as Element;
219-
if (!target.closest("[data-dropdown-container]")) {
220-
setIsOpen(false);
221-
}
222-
};
223-
224-
if (isOpen) {
225-
document.addEventListener("mousedown", handleClickOutside);
226-
}
227-
228-
return () => {
229-
document.removeEventListener("mousedown", handleClickOutside);
230-
};
231-
}, [isOpen]);
232-
233-
if (!selectedAddress || addressOptions.length === 0) return <></>;
234-
235-
const shouldShowDropdown =
236-
addressOptions.length > 1 || !connectedWallets.keplr;
193+
if (addressOptions.length === 0 && connectedWallets.keplr) return <></>;
237194

238195
return (
239-
<div className="relative" data-dropdown-container>
240-
<div
241-
role="button"
242-
className={twMerge(
243-
clsx(
244-
"flex justify-between items-center gap-2.5 text-sm text-neutral-500",
245-
"font-light text-right transition-colors",
246-
{
247-
"hover:text-neutral-400": Boolean(onClick) || shouldShowDropdown,
248-
"cursor-auto": !onClick && !shouldShowDropdown,
249-
"cursor-pointer": Boolean(onClick) || shouldShowDropdown,
250-
},
251-
className
252-
)
253-
)}
254-
onClick={handleToggle}
255-
>
256-
<div className="flex items-center gap-2.5 mt-2">
257-
<img
258-
src={selectedOption?.iconUrl || namadaTransparentIcon}
259-
alt={(selectedOption?.walletType || "Namada") + " Logo"}
260-
className="w-7 select-none"
261-
/>
262-
{showAddress && selectedOption && (
263-
<div className="text-xs text-neutral-400">
264-
{shortenAddress(selectedOption.address, 10, 10)}
265-
</div>
266-
)}
267-
</div>
268-
{shouldShowDropdown && (
269-
<GoChevronDown
196+
<div className={twMerge("space-y-1", className)}>
197+
{/* Address Options List */}
198+
{addressOptions.map((option) => {
199+
const keplr = option.id === "keplr";
200+
const transparent = option.id === "namada-transparent";
201+
const shielded = option.id === "namada-shielded";
202+
const isShieldedTransfer =
203+
location.pathname !== routes.maspShield &&
204+
isShieldedAddress(destinationAddress ?? "");
205+
const isShieldingTxn = location.pathname === routes.maspShield;
206+
const disabled =
207+
(keplr && isShieldedTransfer) ||
208+
(transparent && isShieldedTransfer) ||
209+
(shielded && isShieldingTxn);
210+
const isSelected = option.address === selectedAddress;
211+
if (disabled) return null;
212+
return (
213+
<button
214+
key={option.id}
215+
type="button"
270216
className={clsx(
271-
"text-xs text-neutral-400 transition-transform ml-1",
272-
isOpen && "rotate-180"
217+
"w-full p-2 text-left flex items-center gap-3",
218+
"transition-all duration-200",
219+
{
220+
"opacity-40 cursor-not-allowed": disabled,
221+
}
273222
)}
223+
onClick={() => handleSelectOption(option)}
224+
>
225+
<div className="flex-shrink-0">
226+
<img
227+
src={option.iconUrl}
228+
alt={option.label}
229+
className="w-6 h-6"
230+
/>
231+
</div>
232+
<div className="flex-1 min-w-0">
233+
<div
234+
className={clsx(
235+
"text-sm truncate",
236+
isSelected ?
237+
"text-yellow-300 font-medium"
238+
: "text-neutral-300"
239+
)}
240+
>
241+
{shortenAddress(option.address, 8, 6)}
242+
</div>
243+
</div>
244+
</button>
245+
);
246+
})}
247+
248+
{/* Connect Wallet button if Keplr is not connected */}
249+
{!connectedWallets.keplr && (
250+
<button
251+
type="button"
252+
className={clsx(
253+
"w-full p-2 text-left flex items-center gap-3",
254+
"transition-all duration-200",
255+
"text-sm font-medium text-neutral-300",
256+
isConnectingKeplr && "opacity-50 cursor-not-allowed"
257+
)}
258+
onClick={handleConnectKeplr}
259+
disabled={isConnectingKeplr}
260+
>
261+
<img
262+
src={wallets.keplr.iconUrl}
263+
alt="Keplr"
264+
className="w-6 h-6 flex-shrink-0 opacity-70"
274265
/>
275-
)}
276-
</div>
277-
278-
{isOpen && shouldShowDropdown && (
279-
<>
280-
<div
281-
className="fixed inset-0 z-10"
282-
onClick={() => setIsOpen(false)}
283-
/>
284-
285-
<div className="absolute right-0 top-full mt-1 z-20 bg-neutral-800 rounded-md border border-neutral-700 shadow-lg min-w-[240px]">
286-
<ul className="py-1">
287-
{addressOptions.map((option) => {
288-
const keplr = option.id === "keplr";
289-
const transparent = option.id === "namada-transparent";
290-
const shielded = option.id === "namada-shielded";
291-
const isShieldedTransfer =
292-
location.pathname !== routes.maspShield &&
293-
isShieldedAddress(destinationAddress ?? "");
294-
const isShieldingTxn = location.pathname === routes.maspShield;
295-
const disabled =
296-
(keplr && isShieldedTransfer) ||
297-
(transparent && isShieldedTransfer) ||
298-
(shielded && isShieldingTxn);
299-
return (
300-
<li key={option.id}>
301-
<button
302-
disabled={disabled}
303-
type="button"
304-
className={clsx(
305-
"w-full px-4 py-3 text-left flex items-center gap-3",
306-
"hover:bg-neutral-700 transition-colors",
307-
"text-sm text-white",
308-
option.address === selectedAddress && "bg-neutral-700",
309-
disabled && "opacity-30 cursor-not-allowed"
310-
)}
311-
onClick={() => handleSelectOption(option)}
312-
>
313-
<img
314-
src={option.iconUrl}
315-
alt={option.label}
316-
className="w-6 h-6 flex-shrink-0"
317-
/>
318-
<div className="flex-1 min-w-0">
319-
<div className="font-medium text-white">
320-
{option.label}
321-
</div>
322-
<div className="text-xs text-neutral-400 truncate">
323-
{shortenAddress(option.address, 10, 10)}
324-
</div>
325-
</div>
326-
</button>
327-
</li>
328-
);
329-
})}
330-
331-
{/* Connect Wallet button if Keplr is not connected */}
332-
{!connectedWallets.keplr && (
333-
<li className="border-t border-neutral-700 mt-1 pt-1">
334-
<button
335-
type="button"
336-
className={clsx(
337-
"w-full px-4 py-3 text-left flex items-center gap-3",
338-
"hover:bg-neutral-700 transition-colors",
339-
"text-sm font-medium",
340-
isConnectingKeplr && "opacity-50 cursor-not-allowed"
341-
)}
342-
onClick={handleConnectKeplr}
343-
disabled={isConnectingKeplr}
344-
>
345-
<img
346-
src={wallets.keplr.iconUrl}
347-
alt="Keplr"
348-
className="w-5 h-5 flex-shrink-0"
349-
/>
350-
<div className="flex-1 ml-1">
351-
{isConnectingKeplr ? "Connecting..." : "Connect Wallet"}
352-
</div>
353-
</button>
354-
</li>
355-
)}
356-
</ul>
266+
<div className="flex-1">
267+
{isConnectingKeplr ? "Connecting..." : "Connect Wallet"}
357268
</div>
358-
</>
269+
</button>
359270
)}
360271
</div>
361272
);

apps/namadillo/src/App/Transfer/SelectToken.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ export const SelectToken = ({
242242
destinationAddress={destinationAddress}
243243
selectedAddress={sourceAddress}
244244
onSelectAddress={handleAddressChange}
245-
showAddress={true}
246245
/>
247246
</div>
248247

0 commit comments

Comments
 (0)