Lightning Components Facets

Today I want to talk a bit about Lightning Component Facets. What is a Facet? A facet is an attribute that we can define and place in a subcomponent, in order that another container component, which references the subcomponent, can fill up the facet space with some html code. Note that the subcomponent and container component are simply components, but I will call them in this way in order their relationship is easier to understand .

A facet attribute is similar to any other component attributes, but instead of having a primitive, collection, sObject or custom class type, it has an “Aura.Component[]” type. And instead of holding those kind of data, it will hold HTML markups or even another component.

For learning how this works, nothing better than an example. I have created a subcomponent (MySubcomponent.cmp) that has some facets defined. Forget by now about the {!v.body} expression:

<aura:component >
    <aura:attribute name="topArea" type="Aura.Component[]"/>
    <aura:attribute name="leftArea" type="Aura.Component[]"/>
    <aura:attribute name="rightArea" type="Aura.Component[]"/>
    <aura:attribute name="bottomArea" type="Aura.Component[]"/>
    
    <div class="topArea">
        {!v.topArea}    
    </div>
    <div class="middleArea">
        <div class="leftArea">
            {!v.leftArea}   
        </div>
        <div class="rightArea">
            {!v.rightArea}   
        </div>
    </div>
    <div class="bottomArea">
        {!v.bottomArea}
    </div>
    <div>
        I'am the body!: {!v.body}
    </div>
</aura:component>

I have defined the css of this subcomponent in order each of the areas are styled according to a two column grid I have imagined. Note that I have used basic css, but I could have taken advantage of Lightning Design System for configuring my grid. I leave that for a future post 🙂

Then, I have defined another component (MyContainer.cmp), which is going to be the container component. This means in the container component we are going to call the subcomponent, setting the facets values, in order each of the areas of my subcomponent are dynamically filled up by the container.

<aura:component implements="force:appHostable">
    <c:MySubcomponent>
        <aura:set attribute="topArea">
            <h1>I'm a Super Component</h1>
            <p>I like very much communicating with other components</p>
        <aura:set>
        <aura:set attribute="leftArea">
            <ul>
                <li>I can be embedded in a standalone app</li>
                <li>I can be used in SF1 navigation menu</li>
                <li>I can be used in Lightning App Builder</li>
            </ul>
        </aura:set>
        <aura:set attribute="rightArea">
            <p>My implementation details can be encapsulated when sharing myself to other people!</p>
        </aura:set>
        <aura:set attribute="bottomArea">
            <c:MyBottomAreaComponent/>
        </aura:set>
        <h2>I haven't been set in any attribute. Where should I go?h2>
    </c:MySubcomponent> 
</aura:component>

Notice that I have set several HTML markups in topArea, leftArea and rightArea facets, as well as a call to another component (MyBottomAreaComponent.cmp) in the bottomArea facet, whose code is the following:

<aura:component >
    <p>You can do great things with me</p>
</aura:component>

For visualising my container component in the navigation menu of Salesforce1, I have created a Lightning Tab that holds the component. And the result is the next one:

Screen Shot 2016-05-01 at 09.50.14

As you can see, the subcomponent has dynamically filled the areas in which the facets had been defined to be, and the html code rendered there has adopted the styles I have defined in the subcomponent css. Here is the css, if you want to take a look at it:

.THIS h1
{
    font-weight: bold;
}

.THIS p
{
    font-style: italic;
}

.THIS.topArea
{
    color: red;
    font-size: 14px;
    text-align: center;
}

.THIS.middleArea
{
    display: inline-block;
    width: 100%;
}

.THIS .leftArea
{
    color: green;
    font-size: 10px;
    width: 50%;
    float: left;
}

.THIS .rightArea
{
    color: blue;
    font-size: 10px;
    width: 50%;
    float: right;
}

.THIS.bottomArea
{
    color: gray;
    font-size: 14px;
    text-align: right;
}

To finish, I would like to talk about a facet that is implicitly defined in each component, the body facet. When we reference a subcomponent writing some HTML markups between the tags that include the component into the container, we are implicitly setting the body facet.

This is, the h3 tag that was defined in the container is rendered where the {!v.body} has been placed in the subcomponent. So, the result is exactly the same as if we had set this h3 to the body facet attribute in the next way:

<aura:set attribute="body">
   <h3>I haven't been set in any attribute. Where should I go?</h3>
</aura:set>

But we don’t have to do this because Salesforce is smart enough to deduce it.

The code of the example can be downloaded from my git repository.

2 thoughts on “Lightning Components Facets

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s