UiZoo.js — A Dynamic React Components Library

Repository link: https://github.com/myheritage/uizoo.js

How many times have you created a new component just to find out later that someone else has already done the exact same thing? How many times have you discovered that the “generic” component you wanted to use was actually tightly-coupled to the environment it was developed for? Well, no more! Introducing — UiZoo.js.

An example of how a component looks in UiZoo.js

UiZoo.js showcases your components, letting you develop in a sterile environment and browse what you already have and can use, to make better use of your components. And all this with almost no effort!

This tool can be used for development, for product managers to know what is possible, and for UX to see what we have so far. It can also be a playground for cooperation between all of the above.

Background

UiZoo.js started as an internal tool at MyHeritage for developing React components and to improve coordination between departments.

It became a necessity for us so rapidly that we felt we had to share it. It just makes component-creating life so much easier!

Currently, every React component in the MyHeritage website is developed using UiZoo.js.

The following GIF demonstrates how easily a component can be created in UiZoo.js — how changes in the tool reflect your component, and vice versa:

Trying out a component called RaisedButton, first loading an example and then executing an onClick function

How it works

You provide the documentation of your components and the components to UiZoo.js, which in turn creates a page for each component, as well as a sidebar to search and filter the available components.

We use JSDoc parsing from your component’s documentation to show details on the component page, including description, possible props and full JSX examples. We used a well known JSDoc parser called Doctrine and then created a standalone version that we can use in a browser. In this way, we support each and every JSDoc tag imaginable.

For example

To support examples, we first get all of the needed details from the example JSDoc tags, which contains a JSX as a string. In order to use them dynamically in UiZoo.js, we need to compile them to be React elements. Therefore, we use Babel Standalone, a variation of Babel that can run in a browser, and compile JSX to javascript. Using an iframe, we can execute the code with a context to have all the needed components available in a closure.

In the following code snippet, you can see how UiZoo.js compiles and executes examples dynamically:

Factory to create a function with context to receive JSX string as input and returns a React element

Once we have a React element, we can use the power of JSX to choose a type at runtime and render the example, as seen in this code snippet:

ComponentNode is decided at runtime and rendered with chosen props

Props selectors

If the JSDoc holds information on props, we render selectors according to their types. This allows the user to play with the component and try different props combinations.

In the following code snippet, you can see we choose the selector based on the prop type:

Deciding on the best selector for the job

In this GIF, you can see a component called RaisedButton and what happens when the JSDoc of a prop contains literal values, like “pink” and ”purple.”

Changing types in a prop to get a custom selector (ParamSelectorVariant)

JSDoc Block Tags and their meanings

@name (synonyms: @class, @type)

The component name — it becomes the title of the component page.

@module (synonyms: @namespace, @memberOf)

The section of the component — it appears inside this section on the SideBar.

@description (synonyms: @summary, @desc, @classdesc)

The component description — it is shown below the title.

@example

A JSX example, this tag can be used multiple times for more examples. The 1st example is loaded automatically when you browse through to reach to a component page. You can add // comments to explain what a given example contains.

@prop (synonyms: @property, @arg, @argument, @param, @member)

A possible prop for the component, use JSDoc optional syntax to indicate a prop as optional. For some prop types, like function, we have a special input selector.

What’s the difference between UiZoo.js and Storybook?

You may have already heard about a similar solution called Storybook. We actually began our journey to UiZoo.js by using Storybook ourselves, and it is an absolutely great tool. You create a “story” for each variant of a React component and showcase all of your “stories” on the tool UI.

We created UiZoo.js, however, because we already had good JSDoc documentation on all of our components and wanted to use it to create the “stories” for us. Also, we maintain JSDoc anyway, so using UiZoo.js ensures that we maintain the most updated components version and variations automatically.

Contributing

We have a roadmap of features that we would like to add: URL sharing of a specific props combination, better error messages, and even live JSX coding for children props and other react’s node types.

Contributions and feedback are very welcome! Please check our guidelines if you want to contribute.

In Conclusion

Using UiZoo.js has made our everyday practice of developing React components so much easier. It has even improved our coordination with our product managers and designers.

More than that, it enables us to see what we have without having to go through thousands of lines of code only to figure out that the component you have been working on is too tightly coupled to the environment it was developed on for your current functionality.

Try our live example here.