Skip to content

fix: alignment of Snaps icons within ButtonLink/SnapUIButton component #14243

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

Open
wants to merge 30 commits into
base: main
Choose a base branch
from

Conversation

Daniel-Cross
Copy link
Contributor

@Daniel-Cross Daniel-Cross commented Mar 26, 2025

Description

Snaps sometimes passes in Icons as part of a button, such as a close or swap button. They are currently wrapped in multiple <Text/> components which pushes the alignment out. The ways to address this is to remove the text component wrappers but that would also involve making changes to the DS component ButtonLink, which would affect the rest of the app.

ButtonLink wraps any child passed in with a text component if ButtonSize is set to Auto. When set to Sm, Md, or Lg, and the text component wrapper is removed from the SnapUIButton component the Icon is correctly aligned, however paddingHorizonal: 16 is then applied to the Icon which forces the Icon button to take up more space in text inputs and the layout in general.

It currently seems the only way to address this issue is to make changes to the DS component or build a custom button component within SnapUIButton to fit the needs of Snaps specifically.

Related issues

Fixes: MetaMask/snaps#3244

Manual testing steps

  1. Add a Solana account
  2. Press Send
  3. Add a wallet and see the icons appear within the text inputs

Screenshots/Recordings

Before

Screenshot 2025-03-25 at 14 27 14

After

Simulator Screenshot - iPhone 16 Pro - 2025-03-26 at 11 34 15

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

@Daniel-Cross Daniel-Cross added No QA Needed Apply this label when your PR does not need any QA effort. No E2E Smoke Needed If the PR does not need E2E smoke test run team-snaps-platform Snaps Platform team labels Mar 26, 2025
@Daniel-Cross Daniel-Cross self-assigned this Mar 26, 2025
@Daniel-Cross Daniel-Cross requested a review from a team as a code owner March 26, 2025 10:45
@Daniel-Cross Daniel-Cross linked an issue Mar 26, 2025 that may be closed by this pull request
Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-mobile-platform Mobile Platform team label Mar 26, 2025
@Daniel-Cross Daniel-Cross linked an issue Mar 27, 2025 that may be closed by this pull request
);
}

return children;
Copy link
Member

Choose a reason for hiding this comment

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

One of the problems with this is that we don't inherit the text color when complex children are used:
Screenshot 2025-03-27 at 17 06 30

Also for some reason this text is now center aligned?

Can be reproed by rendering

<Box>
  <Button>Foo <Icon name="arrow-right" /> Bar</Button>
</Box>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! Let me take a look and make some changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This seems to be resolved now

const isIcon =
React.isValidElement(children) &&
(children.props?.type === 'Icon' ||
(children.type as React.ComponentType<unknown> & { displayName?: string })
Copy link
Member

Choose a reason for hiding this comment

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

What is going on here? What even is .displayName?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah this has been removed, I was experimenting with something that didn't work.

handleEvent({
event: UserInputEventType.ButtonClickEvent,
name,
});

// Since we don't have onSubmit on mobile, the button submits the form.
Copy link
Member

Choose a reason for hiding this comment

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

Why are we removing this documentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Re-added this comment

Comment on lines 145 to 150
return React.cloneElement(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
children as React.ReactElement<{ sections: any }>,
{
sections: modifiedSections,
},
Copy link
Member

Choose a reason for hiding this comment

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

Seems simpler to try and solve this at the mapper level before we turn it into React components to prevent having to do this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I took a look at moving this over to the button.ts file and it's possible to map the children there correctly instead of in the SnapUIButton.tsx component, however we still have to map the children again in this component to apply the correct colour to the text as we don't have access to the Theme colours, which is a React hook, and not accessible in the button.ts file.

Not really sure how to solve both the alignment issue (multiple Text component wraps) and the text colour inheritance issue at this point if we need this to be in the button.ts mapper component.

I can perhaps create some sort of theme utility that doesn't rely on react, or I can pass them through via params from the utils.ts file via the mapToTemplate function?

Copy link
Member

@FrederikBolding FrederikBolding Mar 31, 2025

Choose a reason for hiding this comment

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

however we still have to map the children again in this component to apply the correct colour to the text as we don't have access to the Theme colours, which is a React hook, and not accessible in the button.ts file.

We already have access to the theme values in the mappers! For reference:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Awesome, this might work then

Copy link

sonarqubecloud bot commented Apr 2, 2025

/**
* Apply styles to a component based on its type
*/
function styleComponent(component: UIComponent): UIComponent {
Copy link
Member

Choose a reason for hiding this comment

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

I think we can avoid all of this with #14355


const color = COLORS[overriddenVariant as keyof typeof COLORS];
Copy link
Member

Choose a reason for hiding this comment

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

We still want to support the colors for the Snap UI button, but we may have to do it at the mapper level once #14355 lands

disabled = false,
loading = false,
textVariant,
style,
onPress,
Copy link
Member

Choose a reason for hiding this comment

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

?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
No E2E Smoke Needed If the PR does not need E2E smoke test run No QA Needed Apply this label when your PR does not need any QA effort. team-mobile-platform Mobile Platform team team-snaps-platform Snaps Platform team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Alignment is off on SnapUILink icons Alignment is off on some SnapUIButtons
3 participants