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: extend ShadCN initialization #13347

Conversation

TylerAPfledderer
Copy link
Contributor

@TylerAPfledderer TylerAPfledderer commented Jul 7, 2024

Description

Extends #13343 in initializing the setup of Radix/Tailwind (ShadCN)

  • Add the tailwind prettier plugin
  • Adds a set of locally structured primitive components from Radix (generated via ShadCN cli)
  • Adds all foundational tokens and global styles to tailwind config
    • Prefers CSS vars to be able to cleanly create semantic tokens for color mode
  • Updates Storybook config with a reusable provider decorator containing the Chakra and next-themes providers
    • This decorator is also used in prod to improve sync with storybook
  • Contains a tailwind folder holding an accordion and stack components.
    • Currently used for example with migration, but are not currently active in prod (full migration to be done in a separate PR)

Cc @pettinarip

@github-actions github-actions bot added config ⚙️ Changes to configuration files dependencies 📦 Changes related to project dependencies tooling 🔧 Changes related to tooling of the project labels Jul 7, 2024

export default meta

export const Basic: StoryObj = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Found complication here.

Passing the type of Accordion (which is actually Accordion.Root from Radix) to the meta object ends up with the args option being given the type never, though it should be required in this setup.

Seems like the type of this component is pretty complex and StoryObj might not be acknowledging it and assuming it's not a component type.

--ring: 0 0% 83.1%;
}
@layer components {
.accordion-trigger {
Copy link
Contributor Author

@TylerAPfledderer TylerAPfledderer Jul 7, 2024

Choose a reason for hiding this comment

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

Either dump all the utility classes used for a primitive part into a single custom class name here, or have the utilities directly declared in the component file.

Though what to do about readability here with components that have variants? See tailwind/ui/button.tsx

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that I removed the button component here, take a look at the source file

Copy link
Member

Choose a reason for hiding this comment

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

@TylerAPfledderer didn't get why we are doing this approach. Could you elaborate more?

Don't understand why we are not using the same form as in Shadcn: just using the utility classes on the component. I think it is much clearer and easier to tweak, right?

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 was just presenting this approach to you for inquiry of opinion.

If we have all the utilities under a class like I have here, then all those utilities will not render separately when viewing dev tools, so the styling is easier to read and digest because all the styling would still be listed under that one class name.

The downside here is that we are separating general styling from the way we would create variants, such as the approach ShadCN would take in the button component.

I don't have a problem either way and can personally manage the readability if all the styling was kept directly at the component. The prettier plugin should also provide the ability to sort the order of the utility classes used.

Copy link
Member

Choose a reason for hiding this comment

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

Oh I see now. Ok, that is interesting to know.

I would say that, at least for this initial stage, lets keep with the "tailwind/shadcn" convention since all the documentation/examples are pointing in that direction (I think it will be clearer for most devs and contributors) and because I see those downsides that you mention as important. IMO the DX having this separated files is going to be worse than using the classes on the component itself where you can easily find and modify them.

The other minor (but important to us at this point) is performance. Defining new classes will increase the size of the generated css as you are not reusing the utility classes on the compiled bundles.

Copy link
Member

Choose a reason for hiding this comment

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

I'll merge this PR as it is and we can tweak these things later.

Copy link
Member

@pettinarip pettinarip left a comment

Choose a reason for hiding this comment

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

Amazing @TylerAPfledderer, thanks!

Couple of questions.

  1. I see that you have created a completely new folder in which you are putting the new stories for the Shadcn components. This basically creates two separate SBs instances. I was thinking earlier about catching regressions with Chromatic while we do the migration, could be really helpful. With this approach, I don't think we'll be able to have that, right? Wouldn't it be possible to use the same SB config and support both? Chakra and Shadcn components? or do you think it is going to be a mess to config and maintain that?
  2. Noticed that you imported a bunch of the Shadcn components right away. I'm not 100% sure if we're going to use all of them at this point. I was thinking that it might be better to install them as we migrate things, so that at the end we only have the necessary components installed. I.e. the pagination component, I doubt we will be using that. I believe that if we leave it in, we are just never going to clean it up.

.prettierignore Outdated
@@ -4,3 +4,4 @@ yarn.lock
package-lock.json
public
build
!tailwind.config.js
Copy link
Member

Choose a reason for hiding this comment

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

why is this needed? (on the other hand, its a .ts, .js)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whoops! Had issues earlier with prettier. This should be removed

}
"trailingComma": "es5",
"plugins": [
"prettier-plugin-tailwindcss"
Copy link
Member

Choose a reason for hiding this comment

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

Nice! very handy

Copy link
Member

Choose a reason for hiding this comment

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

🤔 hmm why this file name/route? don't like it honestly. I think we can make it simpler by just following the conventions we have with the other utils, or am I missing something? are you expecting to add more things in here?

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 understand. I frankly don't really understand how defining the alias in components.json is different than defining it in the tsconfig.

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 am not anticipating other utilities to be created, but since the cn() is in it's own file in a utils folder instead of a utils file, I figured that would be the better approach.

I still go back to my initial comment above though 😅

Copy link
Member

Choose a reason for hiding this comment

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

I still don't get the idea of what this files does haha. Can we remove it since it is currently duplicating the cn function?

Not sure if this is adding a benefit or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you talking about confusion with the components.json file? Used for configuration when adding components via the cli

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you talking about confusion with the components.json file? Used for configuration when adding components via the cli

Copy link
Member

Choose a reason for hiding this comment

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

No, sorry. I'm taking about the filename **/*.ts. On the base branch, I've already created a cn.ts file. Was wondering if we could remove one to avoid the duplication.

I frankly don't really understand how defining the alias in components.json is different than defining it in the tsconfig.

Me neither xD

Copy link
Member

Choose a reason for hiding this comment

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

Do you like the main.css file? was thinking that perhaps we could have one of these two options:

  1. main.css and fonts.css
  2. global.css and fonts.css

main and global at the same time seems very redundant to me.

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 would want to follow the provided convention. global.css and font.css make sense here.

],
"./src/**/*.{ts,tsx}",
// TODO: remove after migration
"./tailwind/**/*.tsx",
Copy link
Member

Choose a reason for hiding this comment

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

Ok, you plan on moving the ui to the components folder once the migration is done?

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 would expect to do this if we are going to follow the suggested convention provided by ShadCN. It makes sense to me for the "Atom" components at least.

Comment on lines 31 to 32
highContrast: "var(--primary-highContrast)",
lowContrast: "var(--primary-lowContrast)",
Copy link
Member

Choose a reason for hiding this comment

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

Not sure about this. Do you know how these are compiled? are they going to be kebab case? or are they going to keep the same?
This: bg-primary-lowContrast vs bg-primary-low-contrast. I would prefer to keep them as kebab now that we are using this convention. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Compiling retains pascalCase. Good with me flipping them to kebab. That feels more natural here.

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 updated the naming here

*/

const config: StorybookConfig = {
// TODO: Post migration - ui directory should be moved under `src/components`
Copy link
Member

Choose a reason for hiding this comment

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

Got it, this answers my previous question about post-migration tasks.

@TylerAPfledderer
Copy link
Contributor Author

Amazing @TylerAPfledderer, thanks!

Couple of questions.

  1. I see that you have created a completely new folder in which you are putting the new stories for the Shadcn components. This basically creates two separate SBs instances. I was thinking earlier about catching regressions with Chromatic while we do the migration, could be really helpful. With this approach, I don't think we'll be able to have that, right? Wouldn't it be possible to use the same SB config and support both? Chakra and Shadcn components? or do you think it is going to be a mess to config and maintain that?
  2. Noticed that you imported a bunch of the Shadcn components right away. I'm not 100% sure if we're going to use all of them at this point. I was thinking that it might be better to install them as we migrate things, so that at the end we only have the necessary components installed. I.e. the pagination component, I doubt we will be using that. I believe that if we leave it in, we are just never going to clean it up.

@pettinarip

  1. I can experiment here. My initial thought was that it would create a mess, but I can take another pass. My intention here was not to ignore Storybook. I had a different approach, but it would've been more steps.

For the sake of this PR, if it's fine to just update the existing config, then I would not want to allow the new accordion file and its stories to get pushed here, which could start adding or making conflicting snapshot. They would need to be reserved for a new PR that does the full migration of this component for Chromatic and prod.

  1. No problem removing them, and just adding when necessary.

@TylerAPfledderer
Copy link
Contributor Author

TylerAPfledderer commented Jul 8, 2024

@pettinarip Was able to sync up the provider changes into the main Storybook config.

Two things:

  1. I removed those Radix components except for Accordion, which I made a story for testing. If you'd like, I can stash what I did to add in a separate PR when properly migrating the component for prod. (Thereby removing the need for that tailwind folder)
  2. View the comment I made in the denied UI test for the StatsBoxGrid, trying to figure out what to do about this regression.


const theme = useMemo(() => merge(customTheme, { direction }), [direction])
return (
<NextThemesProvider
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Having both providers in one reusable component helps with the sync with Storybook and prod.

Also note here that I added the style tag in here with the CSS vars for the fonts for the same reason as above. See that TODO comment also

Copy link
Member

Choose a reason for hiding this comment

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

Looks better 👍🏼

@pettinarip
Copy link
Member

Two things:

  1. I removed those Radix components except for Accordion, which I made a story for testing. If you'd like, I can stash what I did to add in a separate PR when properly migrating the component for prod. (Thereby removing the need for that tailwind folder)

All good with leaving that on the PR. Serves as an example and future implementations.

@TylerAPfledderer
Copy link
Contributor Author

TylerAPfledderer commented Jul 9, 2024

Two things:

  1. I removed those Radix components except for Accordion, which I made a story for testing. If you'd like, I can stash what I did to add in a separate PR when properly migrating the component for prod. (Thereby removing the need for that tailwind folder)

All good with leaving that on the PR. Serves as an example and future implementations.

Ok! I leave it where it is. Storybook config is not looking at the tailwind folder, and will work on full migration of accordion in a separate PR.

@TylerAPfledderer
Copy link
Contributor Author

@pettinarip should be good to go here?

Copy link
Member

@pettinarip pettinarip left a comment

Choose a reason for hiding this comment

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

LGTM @TylerAPfledderer! lfg

@pettinarip pettinarip merged commit 547dffb into ethereum:shadcn-initial-setup Jul 11, 2024
5 of 6 checks passed
@TylerAPfledderer TylerAPfledderer deleted the feat/shadcn-extend-initialization branch July 11, 2024 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
config ⚙️ Changes to configuration files dependencies 📦 Changes related to project dependencies tooling 🔧 Changes related to tooling of the project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants