Umbraco

Umbraco UI Library release

Umbraco UI components built on web standards

Julia Gruszczynska
Written by Julia Gruszczynska

The Umbraco UI Library (UUI) is stage one of Future-proofing the backoffice - a project aiming to modernize the Umbraco backoffice from a technological standpoint. The components from the UI Library will be the building blocks of the next generation Umbraco backoffice.

The role of the UI Library is to separate the user interface from Umbraco’s business logic and create a unified user experience, with coherent styling and naming, across all Umbraco platforms and projects, also the ones developed by you - the community. With the UI Library, we want to make working with Umbraco easier and more friendly for everyone. 

With the Umbraco UI Library, you get a collection of visual building blocks that hold all the pieces to build any UI In Umbraco. Each component is a building block with a single responsibility - updating its display according to the data passed to the component.

Illustration showing Umbraco UI components in a book situated on a table. Surrounded by a coffe mug with the Umbraco logo, a pencil and a chair. background is dark with a window and a plant.

Web components

The UI Library is based on web standards. We build it using Web Components which work in all modern browsers. In short, Web Components allow you to create custom, reusable HTML elements, with tag names specified by you, that you later drop into your markup as you do with all the native divs, spans, inputs, or buttons.

One of the great things about Web Components is the possibility to encapsulate both logic and styles thanks to the use of Shadow DOM. Component styles do not pollute the global styling and vice versa, and each component has a friendly interface that you can use to configure it. Under the hood 

On top of that, UI Library components are framework agnostic - you can use them with good old backoffice, you can put them in your web project and they will just work, no matter if you’re using Angular, Vue, vanilla javascript, or React (with a tiny bit of extra effort). You can even develop an entire application that looks and feels like Umbraco if that is your need, without much hassle. 

Modern frontend

Under the hood, UI Library components are built with Lit, a lightweight base class that provides reactivity and declarative templating, besides being approachable and giving a good developer experience. They are all written in Typescript, but you don’t need to use Typescript to use the components. They will work perfectly in your Javascript app. 

Each component is an ES module, distributed via npm as a separate, independently versioned package. If you add that to the fact that the UI Library is based on web standards and not a particular framework of choice, you get a truly future-proof UI that will work in any browser many years from now. 

Why will it make you happy?

Let's take a closer look at the components. Each of them has a custom tag name that consists of the “uui” prefix, a hyphen, and the name of the component. For example, the button component from Umbraco UI Library will have a tag name of uui-button. But before you can use it in your markup, it has to be registered, so the browser knows what the <uui-button> is when it’s parsing your HTML file. 

A custom element, and therefore our UI components, have to be registered. This is done by calling the following method on the cutomElements object. The object is a property of the global window object and in the example below, we can see that this method has two parameters. The first one is the tag we want to use for the component, the second one is the class that contains all the component’s logic and styles. After the method is executed, the browser will know how to interpret the <uui-button>.

customElements.define('uui-button', UUIButtonElement);

It is worth noting that all the custom elements are registered globally, on the window object. What that means is that the tag names have to be unique and each element can be registered only once. Otherwise, we will get a nasty error. 

An easier life for Umbraco developers

Today, to use a button that suits the style of Umbraco’s backoffice you would need the AngularJS umb-button component, that only works inside the backoffice:

The implementation of the new uui-button, as seen in the example below, looks very similar to what we use today.

With the uui-avatar component, the new implementation is almost the same.

Smooth migration

So what’s the catch and why would I even bother? - one may ask. The thing is that the new uui-button is a standalone component, not coupled with any framework like the old one is with AngularJS. It will work just as well outside the backoffice, wherever you install it. On top of that, it will also work in the new backoffice from the day it is released. So the UI of whatever you develop today, with the new UI Library components, will be future-proof to a large extent.

Semantic versioning

All the releases of components from the UI Library will follow a semantic versioning specification. That means that breaking changes will only be introduced in major versions, new features that are a part of the component’s public API and are backwards compatible will be released as minor versions. New versions of the individual packages will be published as soon as they are ready. Apart from the individual packages, a bundle containing all the components will also be available, first on npm, then it will find its way to Umbraco 9, so you can start using it in your packages and extensions.

Documentation as a first-class citizen

With the UI Library, we want to make sure that all the components are well documented. Good documentation is something we all love - it can save a ton of time and nerves wasted on trying to figure something out on your own. 

Introducing Storybook

The starting point for working with Umbraco UI Library is its Storybook. It is an application that gathers all the components together, holds their documentation, and showcases different use scenarios. 

You can explore all the components through stories that reflect their use cases. Each story has interactive controls that let you change the state of the component in real-time. Every publicly available property is editable in Storybook, so you test out various configurations and use-cases. You can also change the value of CSS custom properties, to see What the component will look like. On top of that, almost every story has a code example that you can copy and paste into your project, making it super easy to implement the components in your own packages and extensions. 

Click for full-screen video.

Codebase as a source of truth

A big part of the UI Library documentation is generated automatically from the codebase itself. That guarantees that nothing important is missing from the docs and they are always up to date. If the component has a public property it will end up displayed in the storybook along with its type and it will get updated with every release. 


Properties are not the only thing that is documented. From the docs tab in Umbraco Storybook you can also learn what events a component emits, and how many slot elements it has. Apart from the default slot, a web component can have named slots, allowing a more complex composition of the components. For example, the uui-box component has a header slot. Whatever you place there will show up in the top part of the box, even if it is after other elements in the markup.

IntelliSense

All UI Library components are shipped with type declarations. Thanks to that, when developing interfaces with UI Library components, you can enjoy code autocompletion and discovery in your IDE. Besides type declarations, each component package also contains a custom element manifest JSON file. This file can be read by various tools, like browser extensions and IDEs. For example, based on it, VS CODE can give you autocompletion in HTML files. 

Built-in accessibility

The web should be available for everyone. As a CMS - essentially a tool that gives people the ability to create and manage web content - it is crucial for the backoffice to be accessible. For everyone. With components’ responsibility reduced to the presentation layer, it is easier to focus on fulfilling accessibility requirements for each of them. 

During development, we test components for accessibility twice. Once with an automated test that is a part of the code base, and for the second time in Storybook. There the story is tested again and you can see the result in real-time. For example, you can check on the fly if the colors you picked fulfill contrast requirements.

Click for full-screen video.

By making sure that each tiny building block of the UI is accessible we allow creating more complex interfaces that stay accessible. If you need some custom component, you can extend the existing elements from the library and therefore make sure your component stays accessible. On top of that, we provide helpful hints in the console, when it’s your responsibility to set an accessibility-related property, like the label for example.

Now - how to get started

The best place to start working with Umbraco UI Library is the storybook. In its main window there are two tabs: Canvas and Docs. The Canvas tab is where you can use interactive controls. Under the Docs tab, you can find code examples for all the stories and copy-paste them to your markup. You can look it up by tag name or head to the project repository, where, in the packages folder, you will find all the component packages with all the necessary scripts and examples in the readme files. You can install a component through npm or you can link the script from CDN. 

Installation

The easiest way to play and test all the components is to grab the bundled package. If you are installing a component via npm, there are always two ways you can import it, depending on how you want to use it. One: you can import the component and register it at the same time.

import '@umbraco-ui/uui-button/lib';

Doing it this way calls the customElements.define() method mentioned earlier and the component will be ready to use in your markup. 

If you want to build on top of components functionality, You can extend its class. To do so import it like in the example below.

import { UUIButtonElement } from 
'@umbraco-ui/uui-button/lib/uui-button.element';

This way you will not register the uui-button element, but you will get access to its class. 

Extending the elements

To make use of the UUIButtonElement class you need to declare your class and use it to register the new custom element. In the example below, you can see how you can build some logic on top of the button from the UUI library and then use your new element with <extended-button> tag.

State of the UI Library

The Umbraco UI Library currently includes 19 components and a base package that they all depend on. There are more to come soon. We have more than 30 additional components in the works and they will be added gradually to the library and published as they are finished. 

All of the components that are published today are still no higher version than 0.x.x. This means that for now, we can introduce a breaking change in any update. We also want to give you some time to get familiar with the components and their interface. This is the best time to suggest naming, features, or anything that you wish to be a part of the components or UI Library in general.

At some point all the components will be shipped to the backoffice with Umbraco 9. They will be available out of the box to use in your extensions and packages. They will not be used to build the backoffice interface just yet. Once they make it to the backoffice, components will be in version 1.0.0. Then you can start future-proofing your packages and extensions with certainty that we will carefully consider what is and what isn’t a breaking change every time we plan a new release, and no breaking changes will only be introduced before backoffice gets a new major version. 

Does that mean you shouldn’t use the components yet? On the contrary. We would love it if you help us battle-test the components and send feedback our way on the Umbraco.UI repository - hack the heck out of them, spot all the bugs and help make them better, friendlier, faster, stronger 🚀