Skip to content
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

feat: new token selection modal #711

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

Conversation

0xAlunara
Copy link
Collaborator

@0xAlunara 0xAlunara commented Feb 26, 2025

Various:

  • Fixes incorrect border colors for clickable chips
  • Implements correct colors for dividers
  • Removes outlines on focused lists (was a black border around the entire list)
  • Fixes card headers being vertically aligned to the bottom

Main:

  • Adds new token select feature
  • Adds stories for the new token select feature
  • Removes old token select code and replaces it with the new one

Highlights:

  • User search is debounced for performance
  • Tried Tanstack Virtual, but had to abandon due to glitchy behaviour and even worse performance than native. The good thing is, the token icons are loaded lazily even in native React, which means they won't be loaded until the users scrolls it into view
  • Adds support for token favorites. A good example use case is when creating a pool and selected a token, two tokens can be considered favorite.
  • Token list is sorted first by user dollar balance, putting anything with a dollar value on top. If one has no usd value, it switches to ordering by token balance. Lastly, if that also doesn't work, it switches to ordering by token symbol
  • I've added the 'hide small pools' settings to the user profile, because it makes sense to me that it's a global setting across different pages.
  • The token selector can be disabled
  • Specific tokens in the list can be disabled (perhaps due to blacklisting because of a hack)
  • You can pass a custom settings component to the selector in case you want to add extra settings between the list and the favorite chips yourself.

I've refrained from refactoring old code as much as possible, which means that the initial fetching of the token list is still slow as hell. I don't want to inflate the PR with even more code changes than it already has.

Copy link

vercel bot commented Feb 26, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
curve-dapp ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 1, 2025 2:46am
curve-dapp-storybook ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 1, 2025 2:46am

OnlyJousting
OnlyJousting previously approved these changes Feb 26, 2025
)}

{error ? (
<Alert variant="filled" severity="error">
Copy link
Contributor

Choose a reason for hiding this comment

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

Adding an invalid token in the pool creation page results in this
image

Tried with 0x1D774ed0A7b897aAaE3526F07e487C5F9540F55D

Copy link
Contributor

Choose a reason for hiding this comment

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

The popup gets stuck afterwards, even closing and reopening the modal doesn't clear the error and adding a good token doesn't work anymore

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've made the error message grow in height as needed. The height is actually fixed to IconSize.sm in defineMuiAlertTitle. I didn't really want to introduce an entire variant for this one off, so I've opted for sx={{ '&': { height: 'auto' } }} for now.

The error will also go away when you close the modal or change the search value.

Not sure what's the best way to tack on a friendly error message. I could change any error to "invalid token" but maybe it's not related to the token but the RPC. Or maybe there's something else, and then you'd want to know the full error. Not sure we can just look at the error message and search for "Multicall3", replace it with "Invalid token" and call it a day

import { FavoriteTokens } from './FavoriteTokens'
import { TokenOption } from './TokenOption'

// Prevent all the token options from re-rendering if only the balance of a single one has changed.
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't be necessary, it should happen automatically 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried with and without and didn't notice / measure any difference, so I've removed it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I really need to give virtualization a second try though, when you first open the modal with all tokens the performance is dogshit imo. Not the case when I limit the list to just 5 items. It's also not the re-renders causing the performance hog, checked it with a console.log(symbol) inside TokenOption.tsx.

}),
}}
>
{/* I'm abusing the symbol here to deliberately show a tooltip for the address instead */}
Copy link
Contributor

Choose a reason for hiding this comment

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

why? 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've experimented with showing the address on hover and keyboard focus at the place where the label would be, but because we're not using labels it causes the token symbol to move up. See video attached, the symbol typography has to move up to make room for the address to show up. When no longer hovering or focusing the item the address would go away and the symbol would move down again.

This looks very jumpy and distracting so I've opted to keep the token on hover for now

Video.mp4

['desc'],
).map(({ address }) => address)
const selectToList = Object.entries(tokensMapper)
.map(([_, v]) => v!)
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks incorrect - if tokensMapper has no null/undefined why is it typed so?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Probably because export type TokensMapper = { [tokenAddress: string]: Token | undefined }

If I remove the exclamation mark I actually get a type error that the address in .map(({ address }) => address) might be undefined as the type is Token | undefined. It's a bit silly because then I don't even know if you can have a key whose value is undefined?

styleOverrides: {
root: {
'&:focus': {
outline: 'none',
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure we want to disable this? It might be useful for accessibility. How about focus-visible?
For buttons and icon buttons I use '&:focus-visible': { borderColor: Focus_Outline } as discussed with UX.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The menu list has an auto-focus so you can use keyboard navigation immediately to navigate the list. However, that means it immediately renders with a damn awful black border. I could change &:focus to &:focus-visible, but showing any kind of outline is not an option, so neither would be using Focus_Outline

image

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