Check with your designers to help you design this section
Check with your designers to help you design this section
Custom elements are a new way to implement the RAUL shell and in-page components. Custom elements simplify markup and provide a way to bind with various frameworks within the RealPage technology ecosystem.
RAUL's main mission is to help get all of our products onto a unified look. This is in order to help our customers feel like they are using one product. In the past we were able to provide the styles via CSS and functionality via JavaScript. However HTML layout, structure, the correct classes, and properties was always the responsibility of the team implementing the library.
This has many disadvantageous limitiations. The most prevelant being change management. Every time we need to make a change to the HTML to fix something or improve it, our teams have to go through documentation all over again and try to understand the changes, and then restructure the HTML on their side.
With the use of Autonomous Custom Elements (and some custom bindings) we are able to encapsulate the HTML structures on the library side. This abstracts the HTML implementation for the user and creates a custom interface for our teams.
Below is some information and background on Custom Elements, followed by implementation examples. If you are familiar with custom elements, please feel free to skip past the introduction section.
One of the key features of the Web Components standard is the ability to create Custom Elements that encapsulate your functionality on an HTML page, rather than having to make do with a long, nested batch of elements that together provide a custom page feature.- MDN Documentation
Custom Elements are generally utilized when creating Web Components in order to create a tightly encapsulated abstraction of HTML structures. RAUL provides the benefits of using Custom Elements and the abstraction of Web Components, without the encapsulation caveats.
- webcomponents.orgWeb components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. Custom components and widgets build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML.
Web components are based on existing web standards. Features to support web components are currently being added to the HTML and DOM specs, letting web developers easily extend HTML with new elements with encapsulated styling and custom behavior.
One of the most common questions asked is why are we not using Web Components. And on the surface this makes a lot of sense. Custom Elements together with Web Components can provide a nice wrapper for HTML structures. But as we explored that route, we have learned that Web Components are not ready or just simply not right for what we are trying to accomplish.
As far as browser compatability, Web Components can be implemented using polyfills. There is a performance cost in browsers with non-native implementation, especially in IE11. While this is not the end of the world, it is not ideal either.
The real problem happens to be with the Shadow DOM and its implementation. The Shadow DOM is tightly encapsulated with it's own root, and it functions autonomously within a its host. This means that very few things can cross the Shadow DOM boundry. Something as simple as common shared CSS helper classes do not cross the bounds and must be re-included in each component. This is okay when creating completely autonomous components for distribution on the web, but becomes problematic when you are creating a helper library.
Another problem with the Shadow DOM is that simple form elements such inputs, and selects, do not cross the shadow boundry either. As an example imagine we need to create a login wrapper containing username and password input fields. When implemented as a Web Component and included inside of a form on a page, the inputs' values are not visible. Meaning that when the form submits, it does not pick up the necessary values.
These are just some of the reasons why we are currently not fully investing into Web Components. However, we are simulating the abstarction, and some of the encapsulation, by wrapping our implementation using Vue, Custom Element extension for Vue, and custom RAUL bindings. This is completely encapsulated from the user, and allows us to mimic Web Components, without the negative caveats.
The first major use of Custom Elements inside RAUL is the UI shell. The UI shell consists of the main header at the top of each page, the left navigation, the page header (bread crumbs area), and a wrapper for the main content.
A note on alpha: since this is still new and we are working the kinks out as we go, the APIs are subject to change as needed. While we do not forsee any APIs changing, there is a chance they still might to simplify usage or to better help users. The first real beta is scheduled in the pre-release versions of RAUL v3. A beta version will have the APIs solidified and will further focus on improvements and fixes. At this time all legacy APIs and code will be marked deprecated and scheduled for removal in RAUL v3. The finalized API is expected to be included in the release of RAUL v3 and all deprecated APIs / code will be removed.
The header is one of the major pieces that unifies all of our products together. The most obvious way is with the style, but also with integration across all of our products via our Unity APIs as they become more available. The left nav is contextual to the product. The page header (breadcrumbs) describes the current product contextual page the user is on. And finally the main content wrapper is simply a shallow wrap around the page content presented by each product.
One of the biggest benefits of using the new RAUL shell implementation is actually under the hood. Each of the Shell sections are able to access a common data store, which allows us to better communicate between the various shell components.
Another big benefit is that it works across various tech stacks and front-end frameworks. We also support Modern browsers and IE11. Note: as a company we do not support IE10 and below due to security reasons.
Below is an example of the UI Shell and various attributes you can set. The attributes will create properties on the element in the DOM. This tag will generate all the necessary html based on the options specified via the property list.
<ui-shell
product-name="RAUL UI Library"
company-name="Styleguide"
property-name="v2"
user-name="Logged In User"
user-title="Logged In User Role"
help-link="#help"
home-link="#home"
logout-link="#logout"
settings-link="#settings"
user-settings-link="#user-settings"
notifications-link=""
notifications-count="5"
shopping-link=""
shopping-cart-count="5"
show-app-switcher
show-help-link
show-home-link
show-notifications
show-settings-link
show-shopping
show-search
domain="Styleguide"
page="Shell"
subpage="Custom Elements"
page-content-id="custom-elements-page"
></ui-shell>
The ui-shell tag is just a wrapper around various Shell components. There are cases where teams need to implement different sections in different files. To do this, you can just use the custom shell tags seperately, shown belown.
<ui-header
product-name="RAUL UI Library"
company-name="Styleguide"
property-name="v2"
user-name="Logged In User"
user-title="Logged In User Role"
help-link="#help"
home-link="#home"
logout-link="#logout"
settings-link="#settings"
user-settings-link="#user-settings"
notifications-link=""
notifications-count="5"
shopping-link=""
shopping-cart-count="5"
show-app-switcher
show-help-link
show-home-link
show-notifications
show-settings-link
show-shopping
show-search
></ui-header>
<ui-left-nav></ui-left-nav>
<ui-page-header domain="Styleguide" page="Shell" subpage="Custom Elements"></ui-page-header>
<ui-main-content></ui-main-content>
It is possible that your team might want to utilize a RAUL layout without a side navigation in
certain situations. This can possibly be a one off generated internal form or some other context.
Whenever your team needs this capability, they can add the hide-left-nav
property on
the ui-shell
tag or ui-header
tag, depending on which is used.
<ui-shell
...
hide-left-nav
...
></ui-shell>
Below are the attributes you can set per shell component. When using ui-shell
tag,
you can combine the attributes onto it from the various components.
Tag: <ui-header>
Attribute | Type | Default Value | Description |
---|---|---|---|
Product Details | |||
product-name |
String | Empty string |
Sets the product name. This attribute is required and will show |
company-name |
String | Empty string |
Sets the company name or other contexts, depending on the team implementing the header. This attribute can be omitted and will remove the section gracefully. |
property-name |
String | Empty string |
Sets the property name or other contexts, depending on the team implementing the header. This attribute can be omitted and will remove the section gracefully. |
User Details | |||
user-name |
String | Empty String |
Sets the user name of the current logged in user. If attribute is omitted the entire user information section is removed. |
user-title |
String | Empty String |
Sets the user title or role for the currently logged in user. This attribute can be omitted and will gracefully remove itself from the UI. |
user-settings-class |
String | "log-out" |
Sets the class name for the user settings link that is added under the user context dropdown. |
user-settings-link |
String | Empty String |
Sets the link for the user settings link that is added under the user context dropdown. This is currently required, and if omitted will have a null as the link pointer. Post Alpha Plan: removing the attribute should remove link from UI. |
logout-class |
String | "log-out" |
Sets the class name for the log out link that is added under the user context dropdown. |
logout-link |
String | Empty String |
Sets the link for the log out link that is added under the user context dropdown. This is currently required, and if omitted will have a null as the link pointer. Post Alpha Plan: removing the attribute should remove link from UI. Post Alpha Plan 2: add an API to allow javascript to allow a javascript hook when link is clicked. |
Unified Navbar Section | |||
help-link |
String | Empty String |
Sets the link help icon in the unified navbar section of the header. This is currently required, and if omitted will have a null as the link pointer.
To show the link in the UI you must use the boolean attribute Post Alpha Plan: removing the attribute should remove link from UI. Remove the additional boolean. Post Alpha Plan 2: add an API to allow javascript to allow a javascript hook when link is clicked. |
home-link |
String | Empty String |
Sets the link help icon in the unified navbar section of the header. This is currently required, and if omitted will have a null as the link pointer.
To show the link in the UI you must use the boolean attribute Post Alpha Plan: removing the attribute should remove link from UI. Remove the additional boolean. Post Alpha Plan 2: add an API to allow javascript to allow a javascript hook when link is clicked. |
settings-link |
String | Empty String |
Sets the link settings icon in the unified navbar section of the header. This is currently required, and if omitted will have a null as the link pointer.
To show the link in the UI you must use the boolean attribute
Post Alpha Plan: removing the attribute should remove link from UI. Remove the additional boolean. Post Alpha Plan 2: add an API to allow javascript to allow a javascript hook when link is clicked. |
notifications-link |
String | Empty String |
Sets the link notifications icon in the unified navbar section of the header. This is currently required, and if omitted will have a null as the link pointer.
To show the link in the UI you must use the boolean attribute
Post Alpha Plan: removing the attribute should remove link from UI. Remove the additional boolean. Post Alpha Plan 2: add an API to allow javascript to allow a javascript hook when link is clicked. |
shopping-link |
String | Empty String |
Sets the link help icon in the unified navbar section of the header. This is currently required, and if omitted will have a null as the link pointer.
To show the link in the UI you must use the boolean attribute Post Alpha Plan: removing the attribute should remove link from UI. Remove the additional boolean. Post Alpha Plan 2: add an API to allow javascript to allow a javascript hook when link is clicked. |
notifications-count |
Number | 0 |
Sets the badge showing the number of notifications on the notification icon in the unified navbar. If omitted or does not set a value, then the default (0) is used. Post Alpha Plan: removing the attribute should remove the badge from UI. |
shopping-cart-count |
Number | 0 |
Sets the badge showing the number of shopping cart items on the shopping icon in the unified navbar. If omitted or does not set a value, then the default (0) is used. Post Alpha Plan: removing the attribute should remove the badge from UI. |
show-app-switcher |
Boolean | True |
If attribute exists the App Switcher icon will show up in the header. This attribute does not require a value and if is not added will remove the UI for App Switcher |
show-help-link |
Boolean | True |
If attribute exists the help icon in unified navbar will show up in the header. Otherwise help link is hidden in the UI.
Post Alpha Plan: removing the attribute |
show-home-link |
Boolean | True |
If attribute exists the home icon in unified navbar will show up in the header. Otherwise home link is hidden in the UI.
Post Alpha Plan: removing the attribute |
show-notifications |
Boolean | True |
If attribute exists the notifications icon in unified navbar will show up in the header. Otherwise notifications link is hidden in the UI.
Post Alpha Plan: removing the attribute |
show-settings-link |
Boolean | True |
If attribute exists the settings icon in unified navbar will show up in the header. Otherwise settings link is hidden in the UI.
Post Alpha Plan: removing the attribute |
show-shopping |
Boolean | True |
If attribute exists the shopping icon in unified navbar will show up in the header. Otherwise shopping link is hidden in the UI.
Post Alpha Plan: removing the attribute |
Search | |||
show-search |
Boolean | True |
If attribute exists the search bar will be shown. Otherwise search will be removed from the UI. |
Left Nav | |||
hide-left-nav |
Boolean | False |
If attribute exists the left-nav related items will be hidden. Otherwise left-nav items will exist in the UI. |
Tag: <ui-left-nav>
Attribute | Type | Default Value | Description |
---|---|---|---|
Thre are currently no attributes to be added on this tag |
Tag: <ui-page-header>
Attribute | Type | Default Value | Description |
---|---|---|---|
domain |
String | Empty String |
Sets the domain context of the page. This could be an specific section within a product, such as "Users" as an example. |
Page |
String | Empty String |
Sets the page context for page. Uner the example of "Users" as domain, the page could be "User". |
Subpage |
String | Empty String |
Sets the subpage context for page. Uner the example of "Users" as domain, and "User" as page, the subpage could be "Edit". |
Tag: <ui-main-content>
Attribute | Type | Default Value | Description |
---|---|---|---|
page-content-id |
String | Empty String |
Sets the custom id attribute for main content wrapper. |
no-content-padding |
Boolean | False |
If attribute exists, there is no space between the page header and
|
The API is attached directly to the custom element. You can use it by accessing the DOM element and using the api property to call methods. The following is a quick example of how to do this:
var header = document.querySelector('ui-header');
header.api.onLogOut = function() {
// do something when log out button is clicked
};
Methods | Description |
---|---|
Header | |
header.api.onLogOut |
Gets the function attached to the click event on log out button. Default value is an empty function. |
header.api.onLogOut = function() { // do something when log out button is clicked }
|
Sets the function attached to the click event on log out button. |
header.api.onUserSettings |
Gets the function attached to the click event on user settings button. Default value is an empty function. |
header.api.onUserSettings = function() { // do something when user settings button is clicked }
|
Sets the function attached to the click event on user settings button. |
When you need to provide custom content, you can use templates and slots. Slots are are assigned internally as placeholders for content. You can designate which slot gets which content in two ways. The first is by simply adding your content inside the component tag. This will delegate the content to the default slot. Otherise, you can target named slots using template tag syntax.
The template tag syntax requires an attribute named slot
and an id
attribute with the name of the slot. When the content is delegated the template will be removed.
Adding the v-cloak
attribute will prevent the content from being visible before
the section is fully loaded and ready.
<!-- Example of targeting default slots -->
<ui-main-content>
<h2>My Page Title</h2>
<p>My custom content</p>
</ui-main-content>
<!-- Example of targeting named slots using templates -->
<ui-shell
...attributes
>
<template slot id="left-nav" v-cloak>
<ul>
...
</ul>
</template>
<template slot id="content" v-cloak>
<h2>My Page Title</h2>
<p>My custom content</p>
</template>
</ui-shell>
There is a caveat and a change of API when using slots in Angular 6. The component tag needs to
have the slots
attribute set. The value should be the name of the names of all slots
used, seperated by a comma (slots="left-nav,content"
). The default slot will always
be added as long as the attribute is added and the value is at least empty
(slots=""
). Internally custom placeholders named slot-template
are used
in order to acheive the desired outcome. For the most part these are cleaned up, but if any
artifacts remain, they are harmless, yet worthwhile to know what they are.
The API for the template tag changes as well. Instead of splitting attributes into
slot
and id
, you should just set the named value onto the slot
attribute (slot="left-nav"
).
<!-- Example of targeting default slots -->
<ui-main-content slots="">
<h2>My Page Title</h2>
<p>My custom content</p>
</ui-main-content>
<!-- Example of targeting named slots using templates -->
<ui-shell
...attributes
slots="content,left-nav"
>
<template slot="left-nav" v-cloak>
<ul>
...
</ul>
</template>
<template slot="content" v-cloak>
<h2>My Page Title</h2>
<p>My custom content</p>
</template>
</ui-shell>