Skip to content

Sammajayi/connect a wallet fixes - #135

Open
sammajayi wants to merge 4 commits into
GoodDollar:plan/connect-a-wallet-widgetfrom
sammajayi:sammajayi/connect-a-wallet-fixes
Open

Sammajayi/connect a wallet fixes#135
sammajayi wants to merge 4 commits into
GoodDollar:plan/connect-a-wallet-widgetfrom
sammajayi:sammajayi/connect-a-wallet-fixes

Conversation

@sammajayi

Copy link
Copy Markdown

Description

Redesigned the connect-wallet widget UI following the design reference in #113 in reference to the main pr in #116, executed following the plan in #114 . Fixed crash on error/unsupported states, addressed overflow on small viewports, and updated component styling to match the design system.

PR about #116

How Has This Been Tested?

  • Ran pnpm test: demo tests/widgets/connect-a-wallet-widget - all 8 Playwright state tests pass
  • Manual testing in Storybook for visual verification
  • Verified build and lint pass

Checklist:

  • PR title matches follow: (Feature|Bug|Chore) Task Name
  • My code follows the style guidelines of this project
  • I have followed all the instructions described in the initial task (check Definitions of Done)
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have added reference to a related issue in the repository
  • I have added a detailed description of the changes proposed in the pull request. I am as descriptive as possible, assisting reviewers as much as possible.
  • I have added screenshots related to my pull request (for frontend tasks)
  • I have pasted a gif showing the feature.
  • @mentions of the person or team responsible for reviewing proposed changes

- Fix missing Alert import crash on error/unsupported states
- Remove unused address prop from ChainLinkRow (lint fix)
- Restructure PrimaryIdentityCard layout (shield/text/copy)
- Reduce GlowCard shadow opacity and radius
- Update unlink SVG path to match lucide icon
- Add flexWrap to ChainLinkRow for 320px viewport support
- Reduce input/button sizes for small viewports
- Center address in verified identity box with wide gap
- Adjust heading spacing and checkmark position
- Update Playwright test screenshots
@sammajayi
sammajayi force-pushed the sammajayi/connect-a-wallet-fixes branch from bbfde2f to ed45fce Compare July 30, 2026 11:24
@sirpy
sirpy requested a lite review from Copilot August 11, 2026 12:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines the Connect-a-wallet widget by aligning its UI more closely with the design reference, improving responsiveness on small viewports, and hardening edge/error states. It also updates supporting UI primitives and Playwright state tests to match the new copy and layout.

Changes:

  • Updated Connect-a-wallet widget view/layout (header, info callout, responsive chain rows, revised copy) and improved small-viewport behavior.
  • Added link / unlink icons and tuned GlowCard shadow styling to better match the design system.
  • Hardened Playwright state tests with a more reliable “wait until rendered” helper and added mobile/desktop layout screenshots.

Reviewed changes

Copilot reviewed 8 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/widgets/connect-a-wallet-widget/states.spec.ts Improves test stability via waitForText and adds mobile/desktop layout coverage.
packages/ui/src/components/Icon.tsx Adds link / unlink SVG paths for the redesigned connect/disconnect buttons.
packages/ui/src/components/GlowCard.ts Adjusts glow shadow intensity/radius to better fit updated visual style.
packages/connect-a-wallet-widget/src/components/shared.tsx Allows chain row card wrapping and simplifies ActionButton sizing for responsiveness.
packages/connect-a-wallet-widget/src/components/PrimaryIdentityCard.tsx Redesigns the primary identity card and adds copy-to-clipboard affordance.
packages/connect-a-wallet-widget/src/components/ConnectAWalletWidgetView.tsx Restructures the widget layout (header/callout/footer) and changes form/ready-state rendering.
packages/connect-a-wallet-widget/src/components/ChainLinkRow.tsx Redesigns per-chain rows with status indicator + icon buttons and wrapping layout.
packages/connect-a-wallet-widget/src/components/AddressLinkForm.tsx Updates form copy/typography and input/button sizing.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

)
}

const showForm = state.status !== 'error' && !(state.status === 'ready' && state.secondaryAddress)
width={40}
height={40}
borderRadius="$2"
backgroundColor="rgba(0, 174, 255, 0.15)"
Comment on lines +59 to +67
<YStack
onPress={handleCopy}
cursor="pointer"
padding="$1"
hoverStyle={{ opacity: 0.7 }}
flexShrink={0}
>
<Icon name={copied ? 'check' : 'copy'} size="md" color={copied ? 'success' : 'muted'} />
</YStack>
Adds a changeSecondaryAddress adapter action and "Change address" button
so users can check a different address without reloading, replaces a
hardcoded RGBA background with the $infoMuted token, and swaps the
copy-address control for an accessible, focusable Button.
@L03TJ3
L03TJ3 requested review from a team and pheobeayo and removed request for a team August 17, 2026 11:52
Comment on lines 19 to 26
alignItems: 'center' as const,
justifyContent: 'space-between' as const,
flexWrap: 'wrap' as const,
gap: '$2',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChainRowCard looks unused now — ChainLinkRow.tsx builds its row layout inline with raw XStack/YStack instead of this. Since the commit is titled "lint fixes," might as well drop this export too, or it'll get flagged by an unused-export rule later.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<Heading level={6} fontSize="$1">Connect or Disconnect Address</Heading>
This is the exact same string as the heading in AddressLinkForm.tsx, but it's showing at a different point in the flow (after the address has already been checked, next to "Change address"). Two headings with identical text at different steps could be confusing when navigating by heading (e.g. screen readers), and it reads oddly sitting above rows that are already linked/checked. Could we give this one distinct copy, e.g. "Linked address" or "Manage connections"?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const [disconnectHovered, setDisconnectHovered] = useState(false)
...
onMouseEnter={() => setDisconnectHovered(true)}
onMouseLeave={() => setDisconnectHovered(false)}

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' }}

return null
}

const handleCopy = async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const handleCopy = async () => {
  const success = await copyTextToClipboard(walletAddress)
  if (success) {
    setCopied(true)
    setTimeout(() => setCopied(false), 2000)
  }
}

Small robustness thing: if the widget unmounts within the 2s window, this'll call setCopied on an unmounted component. Worth clearing the timeout on unmount, e.g.:

const timeoutRef = useRef<ReturnType<typeof setTimeout>>()
useEffect(() => () => clearTimeout(timeoutRef.current), [])
const handleCopy = async () => {
  const success = await copyTextToClipboard(walletAddress)
  if (success) {
    setCopied(true)
    timeoutRef.current = setTimeout(() => setCopied(false), 2000)
  }
}

@sammajayi

Copy link
Copy Markdown
Author

@pheobeayo, thanks for your review, will check it out right away.

Remove unused ChainRowCard export, disambiguate the duplicate "Connect
or Disconnect Address" heading, swap hover-tracked useState for
hoverStyle on the disconnect button (RN Web/touch compatible), and
clear the copy-feedback timeout on unmount.
@sammajayi

Copy link
Copy Markdown
Author

@pheobeayo, I have addressed all the reviews. Kindly check it out

@sammajayi
sammajayi force-pushed the sammajayi/connect-a-wallet-fixes branch from 919cb1f to fed0846 Compare August 18, 2026 01:58

@pheobeayo pheobeayo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good — this round addresses three of the four items I flagged, but introduces one new visual bug in the process. Here's the follow-up review.

✅ Resolved cleanly:

  • ChainRowCard dead code — removed from shared.tsx.
  • Duplicate "Connect or Disconnect Address" heading — now reads "Linked address" in the ready-state section, distinct from the form heading.
  • Copy-confirmation timeout — now tracked in a timeoutRef and cleared on unmount via useEffect. Clean fix, hooks are still called unconditionally before the !walletAddress early return, so no Rules of Hooks issue.

Comment on lines +78 to +97
<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' }}
paddingHorizontal="$2.5"
paddingVertical="$1.5"
flexShrink={0}
>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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.
Otherwise, the simplest fix is reintroducing a small bit of hover state just for the text/icon color (keeping hoverStyle for the background, since that part works fine as-is):
const [hovered, setHovered] = useState(false)

...
<ActionButton
  ...
  hoverStyle={{ backgroundColor: '$error' }}
  onHoverIn={() => setHovered(true)}
  onHoverOut={() => setHovered(false)}
>
  <Icon name="unlink" size="xs" color={hovered ? 'white' : 'error'} />
  <ButtonText fontSize="$1" color={hovered ? '$white' : '$error'}>Disconnect</ButtonText>
</ActionButton>

(onHoverIn/onHoverOut are Tamagui's cross-platform hover events, so this keeps the RN Web compatibility win from this commit while restoring contrast.)

hoverStyle only flips the background to red; icon/label were still
hardcoded to error color, making them invisible on hover. Reintroduce
a small hover flag via onHoverIn/onHoverOut to swap text/icon to
white on hover, per pheobeayo's review.
@sammajayi

Copy link
Copy Markdown
Author

@pheobeayo I have fixed as requested

@pheobeayo pheobeayo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work — all the review findings are addressed now. Confirmed:

ChainRowCard dead code removed from shared.tsx
Heading copy disambiguated ("Linked address" vs. the form's "Connect or Disconnect Address")
Copy-confirmation timeout cleaned up on unmount in PrimaryIdentityCard
Disconnect button hover fixed — onHoverIn/onHoverOut now flip the icon/text to white so they stay readable against the hoverStyle red background, and it stays RN Web-compatible

Tested against the Playwright state stories and the state machine, empty/error states, and the "always show exactly one of Connect/Disconnect" invariant all hold up. changeSecondaryAddress is a solid addition too — good catch fixing the dead-end flow.

Approving 🚀

@pheobeayo

Copy link
Copy Markdown

@L03TJ3 Kindly check through and review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants