Motivation - acl-services/paprika GitHub Wiki

Brief History

Prior to Paprika UI library, we had created another UI library called ACL UI. ACL was our company previous name before we rebranded to Galvanize in early 2019.

The original goal of ACL UI was to easily distribute UI components, HTML, CSS and JS. Version 3 was the last iteration of ACL UI. It was our company's first large-scale approach to reusable component using React. It was very successful at helping developers speed up the delivery of features. It improves UI's consistency. At present, a relatively large number of components are still in a number of applications, in production.

See how ACL UI and Paprika have been growing and evolving by visiting the Sonar Project.
Note: you must be connected to the Galvanize network locally or via VPN to view this site.

Pain Points

While ACL UI was the pioneer, it also suffered from a number of issues. It was difficult to scale up for a larger, more globally distributed development team. Ultimately, it led us to the development of Paprika UI library, the same concept, but in a brand new, spicier library.

Distribution and Versioning

ACL UI used GitHub as a release mechanism. A CI process built and bundled our code into a new repository, where it would typically be consumed as an npm package in our applications. The drawback to this approach was that components were not versioned individually – the entire repository was included in each new version. This created a significant barrier to iterating on components and created a lot of headaches in consuming apps when ACL UI was updated – getting the latest version for one specific component with a required update meant accepting a lot of breaking changes to other components in active development.

API Inconsistency

Especially in the early days of ACL UI 3, many components were originally developed in a specific app, in the coding style preferred by the team developing that app, and then migrated to ACL UI when it was recognized another team could benefit from the same component. This meant that the conventions, techniques, and API design could vary greatly between components. This made it more difficult to learn how to use each component, since there were very few consistent patterns – each component was it's own special snowflake with it's own set of unique props and design patterns (even if the visual design was fairly consistent).

Controlled Components

ACL UI adopted a very rigid philosophy of providing only controlled components. For simple components, this was fine, but for more complex components, like the <Multiselect>, this required a lot of controlling logic to be provided by the application. While this was sometimes necessary, in many situations it was just inconvenient and cumbersome.

Accessibility as an Afterthought

Some accessibility features were added on to our components in ACL UI as WCAG compliance became a higher priority for ACL/Galvanize, however many deficiencies remained due to the cost of refactoring existing code when accessibility is not considered from the beginning. Level AA compliance is now essential for new features, and some of our components required a complete overhaul – patching the code was not going to be effective.

CSS Pollution

In many real world legacy apps, CSS frameworks like Bootstrap and/or Foundation are still in use, are very difficult to remove, and result in a lot of styling conflicts and headaches. ACL UI contributed to this problem by applying styling to native HTML elements like <button>, <table>, etc. Additionally, the composition of features from different repos within an application can result in multiple versions of the same ACL UI component in the same view – with CSS conflicts that are difficult and messy to fix.

Solutions

To address the above pain point in Paprika, we decided to apply the following strategies.

Lerna + Semver

To solve the versioning and distribution issues, we have chosen to use Lerna. This allows us to host many individually versioned packages (components) in a single repository (monorepo). With this approach, consuming developers can import only the specific components they need, and if an update to one is required, other components will not be affected.

As more complex components are composed of simpler ones, this means it's possible for an application to have multiple different versions of Paprika components in their app, even in the same view.

Lerna will help us manage the dependencies among our components and publish updates to npm's registry.

By adhering to the rules of semantic versioning (Semver breaking changes can be identified easily, and non-breaking updates can be applied safely and predictably.

Styled Components

Our goal is to prevent polluting the global CSS scope with our components' styling and at the same time make them as resilient to global CSS as possible. However, we also want to be flexible enough to allow developers of consuming apps to override the styling of our components in a safe, convenient, and predictable way.

To achieve this we have chosen to implement our components with the styled-component library. This will safely encapsulate the styling for each component, prevent conflicts between multiple versions of the same component that are rendered in the same view, and give us the additional benefit of eliminating the dependency of Sass (or any CSS pre-processor) from our library (we ship purely Javascript).

We still want to provide some CSS resources to app developers for styling their own applications in accordance with our design system, so we have included some packages that can be consumed as either JS or Sass. Our design tokens are important for maintaining visual consistency, and there are several mixins and functions that make building CSS layouts more convenient, and can replace existing utilities that were provided by ACL UI without contributing global CSS pollution, or bloating application bundles.

Design Consistency + Documentation

We decided that with Paprika, we will make full use of important React 16 features like the new context API and hooks. This requires a peer dependency of React 16.8+, and forced many of our applications to upgrade from React 15. While that was a significant cost, it has also pushed forward the state of our frontend technology and provided the same beneficial features to our application developers.

We have also shifted our design philosophy with a greater focus on providing a delightful developer experience (DX). When possible we will absorb complexity in our components to provide a cleaner, simpler API for consumers. For example, we will rethink on a case-by-case basis whether it is more appropriate to build components are controlled, uncontrolled, or can behave in both ways, as hybrid components.

We have also committed to using Storybook and taking advantage of the latest features, some which are still to-be-released, like Docs, MDX and CSF (compact story format). Our Storybook is deployed publicly at paprika.highbond.com. (Temporarily the most up-to-date version is only available internally).

Solving these issues cannot be accomplished by libraries alone however, and a commitment to coding conventions and thorough documentation takes ongoing discipline and prioritization.

Comprehensive Testing

For testing we have settled on a stack of frameworks for full coverage so consumers can trust that the components will be well-tested, and contributors can easily find common patterns and best practices in our repo. That stack includes: ESLint, React Testing Library, Cypress, and Screener.

First Class Accessibility

It is a priority for Galvanize to build software that is accessible to all users and meets WCAG 2.0 Level AA compliance. Our components must adhere to this standard and the core development team of Paprika is committed to helping contributors meet those requirements.

Open Source

We believe Paprika is a world-class UI library, and we are happy to show it off! We hope that allows other developers from around the globe to benefit from our work or contribute to our efforts. It will also allow us to use npm's registry for version control and distribution as well as many other third party tools available only to open source projects.

⚠️ **GitHub.com Fallback** ⚠️