Custom Brand Your Apps in LWC using Styling Hooks

Intro

Are you planning to build a new App? If yes, then this blog is for you!! There are so many components which has many branding part of the components like Color, Font, Icon and many others. But there is a loop hole here! If you roll-out your app to multiple clients what would you do? Our blog always has your back! I will show how to include a small piece of code where you can customize all your branding components which you can customize in your client org without any code!!!

Let Us Begin

Consider the below example, we want to display this line in Red color for Client A and in Yellow color for Client B. Let us see how!

Here we are using property tag in meta file of our LWC which is connected to an Apex controller which provides multiple values for the color and font style.

In LWC we are using a concept called Styling Hooks where we set CSS Properties from JavaScript. This helps us choose the Branding from App Builder without having to customize the code separately for different customers. In this way we can minimize development efforts. Also can be customized easily by Admins.

brandingDemo.js-meta.xml

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">

<apiVersion>51.0</apiVersion>

<isExposed>true</isExposed>

<masterLabel>Branding Demo</masterLabel>

<targets>

<target>lightning__AppPage</target>

</targets>

<targetConfigs>

<targetConfig targets="lightning__AppPage">

<property label="Color" name="color" type="String" datasource="apex://GenericColorDesignDefinition"/>

<property label="Font" name="font" type="String" datasource="apex://GenericFontDesignDefinition"/>

</targetConfig>

</targetConfigs>

</LightningComponentBundle>


brandingDemo.js

import { LightningElement ,api,track} from 'lwc';


export default class BrandingDemo extends LightningElement {

@api color;

@api font;

@track colorFromParent;

@track fontName;

connectedCallback(){

this.colorFromParent = this.color;

this.fontName = this.font;

document.body.style.setProperty("--mycolor", this.colorFromParent);

document.body.style.setProperty("--myfont", this.fontName);

debugger;

}

}


brandingDemo.css

.style1{

color: var(--mycolor);

}

.fontStyle1{

font-style: var(--myfont);

}

brandingDemo.html

<template>

<div class="slds-box slds-theme_default">

<p class="style1">Hello How are you?</p>

<p class="fontStyle1">Hello How are you?</p>

</div>

</template>

GenericColorDesignDefinition.cls

global class GenericDesignDefinition extends VisualEditor.DynamicPickList{

global override VisualEditor.DataRow getDefaultValue(){

VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('red', 'red');

return defaultValue;

}

global override VisualEditor.DynamicPickListRows getValues() {

VisualEditor.DataRow value1 = new VisualEditor.DataRow('red', 'red');

VisualEditor.DataRow value2 = new VisualEditor.DataRow('yellow', 'yellow');

VisualEditor.DataRow value3 = new VisualEditor.DataRow('green', 'green');

VisualEditor.DataRow value4 = new VisualEditor.DataRow('blue', 'blue');

VisualEditor.DataRow value5 = new VisualEditor.DataRow('purple', 'purple');

VisualEditor.DynamicPickListRows myValues = new VisualEditor.DynamicPickListRows();

myValues.addRow(value1);

myValues.addRow(value2);

myValues.addRow(value3);

myValues.addRow(value4);

myValues.addRow(value5);

return myValues;

}

}

GenericFontDesignDefinition

global class GenericFontDesignDefinition extends VisualEditor.DynamicPickList{

global override VisualEditor.DataRow getDefaultValue(){

VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('normal', 'normal');

return defaultValue;

}

global override VisualEditor.DynamicPickListRows getValues() {

VisualEditor.DataRow value1 = new VisualEditor.DataRow('normal', 'normal');

VisualEditor.DataRow value2 = new VisualEditor.DataRow('italic', 'italic');

VisualEditor.DataRow value3 = new VisualEditor.DataRow('oblique', 'oblique');

VisualEditor.DynamicPickListRows myValues = new VisualEditor.DynamicPickListRows();

myValues.addRow(value1);

myValues.addRow(value2);

myValues.addRow(value3);

return myValues;

}

}