5

Let's say that I have a component library with buttons, input fields and more complex components as well, that I want to distribute via npm so that I can use it in a lot of different "Parent Projects" in order to get the same look and feel throughout all of my different applications.

Let's say that the component library and all of the "Parent Projects" are built in React. They might as well be built in Vue or Angular or something else but let's go with react

Let's also say that I am a big fan of the look and feel in material-design so in my component library I want to use material-ui in some of my components but not all of them. I still want to wrap material-ui components to make sure that all of my parent projects uses them in the same way and they might be customised and so on.

Let's also say that I want the user to be able to change the theme in som of the parent projects to dark mode or maybe something that affects the typography or whatever. So the components are dependent on the selected theme for their styling and so might the parent projects be.

Let's also say that since I like material design so much I might want to use it directly in the parent projects as well. But just in some of the projects.

Now my question is how to technically organize the different projects.

  1. Is it possible to get rid of the material-ui dependency completely in the parent projects. That is, not demand from the parent projects to supply a version and not ship one with the npm package?
  2. If that's not possible. What are the pros and cons with require a peerDependency from the parent vs supplying one from the component lib?
  3. How can I handle the theme and still have the components well encapsulated? Who is responsible for setting the theme? When will the theme styling be set in the parent project? Should I send the selected theme to the component? Do I have to replicate the theme styling in order to make the components encapsulated?

TLDR; I want a component library that's depending on another third part library and want to keep my components as encapsulated as possible. What could be a good structure for this?

Mike
  • 443
  • 9
  • 26

1 Answers1

1

Create your own components folder which contains your components like Button, and encapsulate around the material-ui button/ any third party component which you choose. That way, the component library which you are creating can be testable, reusable as a npm module & also follows a pattern, and used in Container components as project components. This mainly minimizes the overhead of creating the initial components which are already available in a third party library. Also material-ui supports theming, and with variables, so you can always create some variables for colors, font size etc, and use those variable values inside your components.

themes
     -> blue.theme.js
             $primaryColor:'blue'
     -> white.theme.js
             $primaryColor:'white'
     -> dark.theme.js
             $primaryColor:'deepBlue'

components
     -> Button.js
            <MuiButton.js />
        Button.scss
             color: $primaryColor;    
Vijay122
  • 884
  • 8
  • 12
  • Yeah, but if I just create a npm package of my component library, the whole material-ui will be shipped with it and might risk to clash with the version of material-ui in the "parent project" right? And, if I do it like this and add material-ui as a peer dependency, the "parent project" has to include material-ui to even use the component library, which will require the parent project to use material-ui with a certain version and so on – Mike Jun 16 '20 at 09:20
  • Got it. Dependency management and software upgradation is always a tech debt, in open-source projects. Where in, you could also look into [link](https://materializecss.com/) which can be bundled with your other css and remains as your local css. The parent project which uses your npm, need not depend on any packages. However, the new supports like aria, accessibility which are coming up newly, needs to be supported from your npm package. – Vijay122 Jun 18 '20 at 13:41