-
Notifications
You must be signed in to change notification settings - Fork 14
Sammajayi/connect a wallet fixes #135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: plan/connect-a-wallet-widget
Are you sure you want to change the base?
Changes from all commits
ed45fce
464ae2a
fed0846
a7b6276
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,11 @@ | ||
| import React from 'react' | ||
| import { AddressDisplay, Badge, BadgeText, ButtonText, ChainBadge, Spinner } from '@goodwidget/ui' | ||
| import React, { useState } from 'react' | ||
| import { ButtonText, Icon, Spinner, Stack, Text, XStack, YStack } from '@goodwidget/ui' | ||
| import type { ConnectAWalletChainLinkState } from '../widgetRuntimeContract' | ||
| import { chainLinkRowPresentation } from './format' | ||
| import { ActionButton, ChainRowCard } from './shared' | ||
| import { ActionButton } from './shared' | ||
|
|
||
| interface ChainLinkRowProps { | ||
| row: ConnectAWalletChainLinkState | ||
| address: `0x${string}` | ||
| onConnect: () => void | ||
| onDisconnect: () => void | ||
| } | ||
|
|
@@ -16,24 +15,111 @@ interface ChainLinkRowProps { | |
| * Disconnect (never hidden) with a Spinner while a status is in flight, per | ||
| * Bounty Lead sign-off on the human-reviewer checklist. | ||
| */ | ||
| export function ChainLinkRow({ row, address, onConnect, onDisconnect }: ChainLinkRowProps) { | ||
| export function ChainLinkRow({ row, onConnect, onDisconnect }: ChainLinkRowProps) { | ||
| const { actionLabel, isBusy, isDisabled } = chainLinkRowPresentation(row.status) | ||
| const handlePress = actionLabel === 'Connect' ? onConnect : onDisconnect | ||
| const [disconnectHovered, setDisconnectHovered] = useState(false) | ||
|
|
||
| // Map status to dot color and display text | ||
| let dotColor = '$placeholderColor' | ||
| let statusText = 'Not Connected' | ||
|
|
||
| if (row.status === 'connected') { | ||
| dotColor = '$success' | ||
| statusText = 'Connected' | ||
| } else if (row.status === 'connecting') { | ||
| statusText = 'Connecting...' | ||
| } else if (row.status === 'disconnecting') { | ||
| statusText = 'Disconnecting...' | ||
| } else if (row.status === 'checking') { | ||
| statusText = 'Checking...' | ||
| } | ||
|
|
||
| const isDisconnect = actionLabel === 'Disconnect' | ||
|
|
||
| return ( | ||
| <ChainRowCard> | ||
| <ChainBadge chainId={row.chainId} name={row.chainName} /> | ||
| <AddressDisplay address={address} size="sm" /> | ||
| <Badge type={row.status === 'connected' ? 'success' : 'info'}> | ||
| <BadgeText>{row.status === 'checking' ? 'checking…' : row.status.replace('_', ' ')}</BadgeText> | ||
| </Badge> | ||
| <ActionButton | ||
| onPress={handlePress} | ||
| disabled={isDisabled} | ||
| variant={actionLabel === 'Disconnect' ? 'outline' : 'primary'} | ||
| > | ||
| {isBusy ? <Spinner size="sm" /> : <ButtonText>{actionLabel}</ButtonText>} | ||
| </ActionButton> | ||
| </ChainRowCard> | ||
| <XStack | ||
| padding="$4" | ||
| alignItems="center" | ||
| justifyContent="space-between" | ||
| gap="$3" | ||
| borderBottomWidth={1} | ||
| borderBottomColor="$borderColor" | ||
| flexWrap="wrap" | ||
| > | ||
| <XStack alignItems="center" gap="$2" flex={1} minWidth={0}> | ||
| <Stack | ||
| width={32} | ||
| height={32} | ||
| borderRadius="$full" | ||
| backgroundColor="$backgroundPress" | ||
| alignItems="center" | ||
| justifyContent="center" | ||
| flexShrink={0} | ||
| > | ||
| <Text fontWeight="700" fontSize="$1" color="$color"> | ||
| {row.chainName.charAt(0)} | ||
| </Text> | ||
| </Stack> | ||
|
|
||
| <YStack gap="$0.5" flex={1} minWidth={0}> | ||
| <Text fontWeight="700" fontSize="$1" color="$color" numberOfLines={1}> | ||
| {row.chainName} | ||
| </Text> | ||
| <XStack alignItems="center" gap="$1"> | ||
| <Stack width={5} height={5} borderRadius={3} backgroundColor={dotColor} flexShrink={0} /> | ||
| <Text fontSize="$1" fontWeight="600" color="$placeholderColor"> | ||
| {statusText} | ||
| </Text> | ||
| </XStack> | ||
| </YStack> | ||
| </XStack> | ||
|
|
||
| {isBusy ? ( | ||
| <ActionButton | ||
| disabled | ||
| variant={isDisconnect ? 'outline' : 'primary'} | ||
| borderColor={isDisconnect ? '$error' : undefined} | ||
| paddingHorizontal="$3.5" | ||
| flexShrink={0} | ||
| > | ||
| <Spinner size="sm" /> | ||
| </ActionButton> | ||
| ) : isDisconnect ? ( | ||
| <ActionButton | ||
| onPress={handlePress} | ||
| disabled={isDisabled} | ||
| variant="outline" | ||
| borderColor="$error" | ||
| hoverStyle={{ backgroundColor: '$error' }} | ||
| onHoverIn={() => setDisconnectHovered(true)} | ||
| onHoverOut={() => setDisconnectHovered(false)} | ||
| paddingHorizontal="$2.5" | ||
| paddingVertical="$1.5" | ||
| flexShrink={0} | ||
| > | ||
|
Comment on lines
+79
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call switching to hoverStyle for the background — that's the right cross-platform pattern. But the icon and label are still hardcoded to color="error" / color="$error", and previously the manual disconnectHovered state also flipped these to white on hover so the text stayed readable against the now-red background. With that state removed, hovering this button now renders red text/icon on a red background — effectively invisible. hoverStyle on the parent ActionButton won't cascade to the Icon/ButtonText children's color props on its own. A couple of ways to fix: If the design system supports Tamagui's group-hover pattern (wrap in a group, use $group-hover theme tokens on the children), that'd keep this fully declarative. (onHoverIn/onHoverOut are Tamagui's cross-platform hover events, so this keeps the RN Web compatibility win from this commit while restoring contrast.) |
||
| <XStack alignItems="center" gap="$1"> | ||
| <Icon name="unlink" size="xs" color={disconnectHovered ? 'white' : 'error'} /> | ||
| <ButtonText fontSize="$1" color={disconnectHovered ? '$white' : '$error'}> | ||
| Disconnect | ||
| </ButtonText> | ||
| </XStack> | ||
| </ActionButton> | ||
| ) : ( | ||
| <ActionButton | ||
| onPress={handlePress} | ||
| disabled={isDisabled} | ||
| variant="primary" | ||
| paddingHorizontal="$2.5" | ||
| paddingVertical="$1.5" | ||
| flexShrink={0} | ||
| > | ||
| <XStack alignItems="center" gap="$1"> | ||
| <Icon name="link" size="xs" color="white" /> | ||
| <ButtonText fontSize="$1" color="$white">Connect</ButtonText> | ||
| </XStack> | ||
| </ActionButton> | ||
| )} | ||
| </XStack> | ||
| ) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this widget runs on RN Web too, so onMouseEnter/onMouseLeave won't fire on touch. The copy button in PrimaryIdentityCard (and Copilot's earlier suggestion) uses hoverStyle instead — could we do the same here and drop the extra useState?
hoverStyle={{ backgroundColor: '$error' }}