5

I am rewriting a complex Visualforce component into LWC. It's an activity timeline / Gantt chart that's part of a managed package.

The old version let the end users override the bar colo(u)rs with a hierarchy custom setting. Org / Profile / User level was perfect for the job.

In the VF component I simply had a bunch of these

<style>
.fn-gantt .Reservation-Account {
    background-color: {!BLANKVALUE($Setup.Calendar__c.Reservation_Account_background_color__c, '#36C')};
}
.fn-gantt .Reservation-Contact {
    background-color: {!BLANKVALUE($Setup.Calendar__c.Reservation_Contact_background_color__c, '#B82E2E')};
}
</style>

I am wondering what is the best way to give similar power over the LWC version of the component to the end users' admins.

  • There's no nice access to custom settings, fine, I can fetch it with Apex
  • but I can't put <style> tags in the LWC's component (html) file
  • chart bars will be rendered with some iteration or even using lwc:dom="manual" so a dynamic getter trick won't work
  • CSS file can't have variables. No references to custom setting or custom labels
  • clients of managed packages can't reuse the installed components in their own. So normal parent-child mechanisms like @api, using slots to pass markup or even using a Static Resource with CSS overrides won't work.
  • Same with styling hooks I think. I won't be using standard components like lightning-pill for bars so the styling hooks don't help? I know hooks for custom components are coming in Summer'21 but still - if end user can't reuse my component in their own, how would they apply the overrides.
  • I can loadStyle my own static resource but I think it's checked at compile time, no way to load it dynamic. And if there's some hack - might break in future

So far I can think of three things, they all feel bit "meh".

  1. Wrap it in Aura with access="global", end user should be then able to reuse the Aura component.
  2. Create Style__c Text(255) on every sObject used as bar. Not Class__c because how would they pass me the class definitions.
  3. Publish the source code (IP problems, competition advantages, upgrade problems, yadda yadda... and what about orgs on Group Edition that have no custom coding capabilities)

Any clever ideas?

6
  • No answer right now, but the most recent partner AppExchange tech talk covered upcoming changes that allow embedding managed package LWCs in custom LWC templates. May help. Of course, not right now. – Phil W Apr 24 at 18:18
  • @PhilW What makes you say that? – sfdcfox Apr 24 at 18:53
  • It means you can expose API properties into a wrapper LWC outside the managed package for one thing, and these could be used to set CSS variables used in your managed LWCs. My understanding (not tried it myself yet) is that CSS variables are now available in LWC context. Take a look at this blog post... – Phil W Apr 24 at 19:53
  • As noted in this question, you should be able to pass values into a CSS var. – sfdcfox Apr 25 at 0:22
  • Hi @PhilW, an you provide a link to that partner AppExchange tech talk? – Keith C Apr 25 at 11:48
0

Thx for all the great comments and especially @sfdcfox for linking me to How can i use var() in css in LWC?, it was the hint I needed.

2 weeks and dozen distractions later... something like this if you want to keep the default values in CSS.

Apex

@AuraEnabled(cacheable=true)
public static Calendar__c getSetting(){
    return Calendar__c.getInstance();
}

JS

@wire(getSetting) wiredSetting({ error, data }) {
    if (data && data.Id) {
        let style = document.documentElement.style;
        style.setProperty('--loan-account', data.Loan_Account_background_color__c);
        style.setProperty('--loan-contact', data.Loan_Contact_background_color__c);
        // etc etc
    }
}

CSS

.vis-item.Loan-Account {
    background-color: var(--loan-account, #0099C6);
}
.vis-item.Loan-Contact {
    background-color: var(--loan-contact, #DC3912);
}

If you'd rather keep them in apex - remove the "if" in JavaScript. Check server-side whether the custom setting was retrieved from database or SF gave you the empty shell. But you'll most likely have to improve the empty shell, SF will give you empty setting with only SetupOwnerId field set. You'll need a lot of

s.Loan_Contact_background_color__c = Calendar__c.Loan_Contact_background_color__c.getDescribe().getDefaultValueFormula());
return s;

to get it to useable state.

P.S. I wasted few h thinking default values don't work. Don't be me, don't wrap them in apostrophes. var(--loan-account, '#0099C6'); is wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.