At the beginning of a new project, a frequent question is whether one should abstract away or wrap the UI Component library. Often this decision is made based on the wrong reasons. The following article is a summary of the different aspects to consider for making the correct decision for your project.

This article is part of a series about Advanced Angular Patterns which focuses on patterns and questions relevant to large enterprise applications written in Angular.

UI Component Libraries

For a large web project choosing the right UI component library is one of the most important decisions. Needing to implement missing functionality or having to change the design of your component library is a source of bugs and a huge time sink.

There are a lot of different component libraries to consider. But before starting a new big Angular project the 3 libraries which need to be part of your evaluation are Angular Material, Kendo UI for Angular and PrimeNg. Angular Material provides a really great design but is a bit lacking in functionality, both Kendo UI for Angular and PrimeNg are great functionality wise but lacking on the design front.

Arguments for wrapping the UI Component Library

Reducing API surface:

The wrapper will only expose the functionality which you want to be used in your application. This enforces a consistent behavior and reduces the complexity when adding new features. In other words, if it is possible to use the component library in any way, every developer on your team will use it slightly differently. Limiting the ways the components can be used will reduce the complexity and thus bugs on all screens and increase maintainability.

Applying application wide changes:

Having wrapped the UI component library, a change in all instances of a specific component will become easy. In many cases, it would still be possible via Angular directives or a similar mechanism in your web framework of choice. But having a wrapper makes it much easier.

Being able to replace your component library if needed.

If you have wrapped your component library you could, in theory, replace it with another component library and thus you would not be dependent on the future development of the library. I said in theory because replacing the UI component library is always a very costly endeavor, even if the components are wrapped. Your manager will most likely not approve replacing the library mid-project.

Arguments against wrapping the UI Component Library

Small Project

If your project is small the investment of wrapping the components will most likely not pay off. Also if only one developer is working on the project the component usage should hopefully be already quite consistent, the benefit of reducing API surface is thus reduced.

The usage of your component is always different.

If you need to use the UI components of your library in every possible way your wrapper will just become a copy of the component and thus not be helpful at all. Be careful in such a situation as this it is an indicator of missing consistency. Actions to take in such a case:

Talk about the component usage with your Business Analyst. Is he just writing down customer requests without doing his job? Creating a consistent UI is one of the most important tasks of a BA.

Warn your project manager of a possible maintainability risk

Do you have a dedicated UX designer? If yes, great! Delegate to him. A usability guide which describes all allowed usages of every component could help a lot. Discussions about the needed features of each component can then happen between BA and UX without slowing down the development team.

Summary

For most big projects it probably makes sense to wrap the UI Component library. The main reason for this is not the often stated argument that one should abstract away all external dependencies, like the UI component library. Instead, the main benefit comes from the reduced complexity and the gained consistency of reducing the used API surface of the external library.

How to wrap your UI Component Library

Did you come to the conclusion that you need to wrap your UI component library in your next project? Yes, then the next question is in which sprint to schedule the actual task of wrapping the components. The first idea is probably to do it in the very beginning of the project, but that would probably be a mistake. Instead, I suggest to use the UI component library directly at the beginning of the project and wait with implementing a wrapper for a component until it is used at least10 times. After 10 usages you will have a good idea of how the application will utilize the component. Discuss the future usage with UX and the Business Analysts and then it will be easy to define a simple to use API for your wrapper.

If you create the wrapper at the beginning the risk is that you will not yet know what the consistent, application wide behavior, of your component will be. Each developer in your team will just add the missing functionality for his user story to the minimalistic initial wrapper. This is a recipe for a horrible wrapper API which will grow over time. Instead of reducing complexity this will add unnecessary complexity on top and be bad for maintainability. Another good way to fight this tendency, besides the 10 usages rule, is to not allow Pull Requests which contain changes at business logic and at the wrapper implementation at the same time. Instead, if a wrapper change is needed, discuss it with UX first and then create a separate user story with a clear goal.

Implementing the wrapper

Generally, the wrapper will just be a thin layer around the component which maps from your API to the library API. It is fine to copy part of the library API, this can potentially save time on documentation, but in the end, the API needs to be consistent.

It is of paramount importance to document the wrapper API thoroughly. Without documentation, other developers will either not use the wrapper or try to work around the wrapper, both defies the purpose. It often helps to create some kind of playground area in your application where the wrapped components can be tested in isolation. The playground will also act as a living documentation where one can get a good example of how to use the wrapper.

Implementing the wrapper in Angular

Implementing a wrapper around a UI component in Angular is mostly straightforward. If the wrapper contains not only simple mappings from one API to the other but also more complicated logic I would suggest to extract this into its own directive. Give the directive the same selector as the component. This pattern helps to achieve separation of concerns and thus increase readability and maintainability. My next article in the Advanced Angular Patterns series will be about this pattern and discuss how and when to use it.

NgModel and the ControlValueAccessor interface

One possible pitfall when writing a wrapper in Angular is the two way binding with NgModel. In this case, the wrapper needs to implement the ControlValueAccessor interface and register a new value accessor provider.

The following Stackblitz example showcases the wrapping of the NgModel binding on an input component from Kendo UI for Angular.