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

README for new UI library #1411

Merged
merged 8 commits into from
Jul 8, 2024
Merged

README for new UI library #1411

merged 8 commits into from
Jul 8, 2024

Conversation

jessepinho
Copy link
Contributor

@jessepinho jessepinho commented Jul 3, 2024

This sets out some coding standards for the new UI library to ensure file structure, naming, etc. are consistent.

Only requesting a review from Gabe, but others should feel free to review as well.

Closes prax-wallet/prax#82

Copy link

changeset-bot bot commented Jul 3, 2024

⚠️ No Changeset found

Latest commit: 6bffda8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@jessepinho jessepinho force-pushed the jessepinho/ui-readme-web-82 branch from 192433b to 45c35fd Compare July 3, 2024 22:54
@jessepinho jessepinho force-pushed the jessepinho/ui-readme-web-82 branch from 45c35fd to c85755f Compare July 3, 2024 22:56
packages/ui/package.json Outdated Show resolved Hide resolved
@jessepinho jessepinho changed the title WIP: README for new UI library README for new UI library Jul 3, 2024
@jessepinho jessepinho marked this pull request as ready for review July 3, 2024 23:19
@jessepinho jessepinho requested a review from grod220 July 3, 2024 23:19
packages/ui/package.json Outdated Show resolved Hide resolved
packages/ui/package.json Outdated Show resolved Hide resolved
packages/ui/readme.md Outdated Show resolved Hide resolved

This ensures that each component is internally responsible for its own styling.

Any variations of the component's appearance must be controlled via props like `variant`, `state`, etc. — not by kitchen-sink props like `className` and `style`, which allow arbitrary changes to be made that could interfere with the internal structure of the component and cause visual inconsistencies between instances of Penumbra UI components.
Copy link
Contributor

Choose a reason for hiding this comment

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

question: even though I agree on this idea, there are cases where className existence is important. For example, take a look at the AssetsTable Row implementation in minifront. When the TableRow with class 'group' is hovered, the inner Link changes its opacity. How can we handle such case?

Copy link
Contributor Author

@jessepinho jessepinho Jul 5, 2024

Choose a reason for hiding this comment

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

Oh man, good find of an edge case... Hm.

Went down a rabbit hole trying to solve this problem, and here's what I came up with:

            <TableBody>
              {account.balances.map((assetBalance, index) => (
                <TableRow key={index}>
                  <TableCell>
                    <ValueViewComponent view={assetBalance.balanceView} />
                  </TableCell>
                  <TableCell>
                    <EquivalentValues valueView={assetBalance.balanceView} />
                  </TableCell>
                  <TableCell>
                    <Link
                      className='transition md:opacity-0 [tr:hover>td>&]:opacity-100'
                      to={getTradeLink(assetBalance)}
                    >
                      <Button variant='secondary' size='md'>
                        Trade
                      </Button>
                    </Link>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>

I've removed group entirely, and used nesting selectors to get the same effect. (I tried using group in combination with & (docs) to get the same effect, but it didn't work. I suspect I'm doing something wrong, and could fix this with a bit more work, but it didn't seem worth the time right now.)

This isn't a great solution (since it requires a very specific DOM structure), so I'll keep playing with it once I cross this particular bridge. But for now, I think we can still avoid className/style props.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wow, didn't know it's possible with Tailwind! Thanks for showing this. It probably worth being documented

Copy link
Contributor

@grod220 grod220 left a comment

Choose a reason for hiding this comment

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

Some thoughts, but definitely think this is on the right track!


This ensures that the Penumbra UI `package.json` `exports` field works as intended, so that components can be imported via `@penumbra-zone/ui/<ComponentName>`.

Note that `<ComponentName>` should be replaced with the `UpperCamelCase` component name — e.g., `./components/v2/LoadingIndicator/index.tsx`.
Copy link
Contributor

Choose a reason for hiding this comment

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

In the past i've run into issues with using capitalization in file names as different operating systems handle case sensitivity in different ways. But maybe not a big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As long as people import it using the same capitalization at the file name, it should work across all systems, right? (I wanted to do this change both A) to make imports a little less annoying to type, and B) because it seems to be the norm across other libraries like MUI — example.)

Comment on lines 81 to 83
### Components must be the default export of the component file.

This allows them to be imported as the default, rather than destructuring an object. It also encourages UI library maintainers to only export one component per file.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this represents the most current thinking on exporting. Last year there was a flurry of articles written around the same time (e.g. https://dev.to/phuocng/avoid-using-default-exports-a1c) and lots of discussion on twitter on how default exports are kinda bad. I find their reasoning compelling.

Copy link
Contributor Author

@jessepinho jessepinho Jul 5, 2024

Choose a reason for hiding this comment

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

Hm, a few thoughts:

  • I don't have a strong opinion about this one way or the other, so I'm happy to change it.

  • It seems that a lot of the discussions of this issue are claiming to be about named vs. default exports, when they should be about named vs. unnamed exports. See Addy Osmani's tweet here, which encourages people to name their exports (whether they are default exports or not).

    A named default export (OK to use, in my opinion):

    export default function MyComponent() {}

    An unnamed default export (bad to use, in my opinion):

    export default () => {}
  • I haven't had the experience that others are describing, where IDEs don't work well with default exports. In my experience with VSCode, if I want to import a default-exported MyComponent, I type <MyComponent in my JSX markup, and it automatically knows to import it. If I later rename MyComponent, it also updates everywhere in the codebase that imports MyComponent, even though it's the default export (since, after all, it is still a named function). It could just be that VSCode is especially smart about this, but I doubt it — I think it's a language-level thing, since MyComponent is actually a named function that happens to be exported as the default.

If you feel strongly about this, though, I can definitely remove this guideline.

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've pushed f01b893 to address this; but pending your response to my comment above, I can revert it back to my original guideline.

}
```

### Components should include Storybook stories.
Copy link
Contributor

Choose a reason for hiding this comment

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

Storybook comes with a testing framework right? or snapshotting?

Should we require test coverage for these new components?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, let me write something up about testing.

Storybook does have integrations with screenshot (not snapshot) testing, but the only one I know of is Chromatic, which is a bit pricey. We could consider that in the future, but for now, I should at least include a point about unit tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done: 6bffda8

Copy link
Contributor

@VanishMax VanishMax left a comment

Choose a reason for hiding this comment

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

This version is well-polished! Approving since all my concerns are noted but it's probably worth to wait for @grod220 to approve too

@jessepinho
Copy link
Contributor Author

Thanks @VanishMax ! @grod220 please weigh in when you have a chance

Copy link
Contributor

@grod220 grod220 left a comment

Choose a reason for hiding this comment

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

Ship it 🚢

@jessepinho jessepinho merged commit 11893fc into main Jul 8, 2024
6 checks passed
@jessepinho jessepinho deleted the jessepinho/ui-readme-web-82 branch July 8, 2024 22:52
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.

Write README describing best practices/etc. for engineers building components
3 participants