How can we expose inherited properties from a super component’s class in a lightning Web Components through targetConfigs (design attributes)

Is there currently a way of exposing properties inherited from super classes in Lightning Web Components, as design attributes (targetConfigs), or is this a gap? I’m inheriting base classes which themselves ultimately inherit from LightningElement but those which I’ve configured to display as design time attributes in the sub most class aren’t showing up in the editors.

Answer

tl;dr:
Currently, this is a gap.

From the pure perspective of accessibility, @api enabled properties of a LWC are inherited from parent to child. This is standard JS prototype inheritance at work.

You’ve probably found this. But when setting the config for design attribute in the metadata file to be connected to an inherited property, you get the following error:

The ‘propName’ property doesn’t exist on the component.

Here’s a test case to try:

A parent LWC module, and for sake of simplicity, an empty template/markup file.

//parentInheritance.js
import { LightningElement, api } from 'lwc';

export default class ParentInheritance extends LightningElement {

  @api parentProp; 

}

A child LWC extending the parent component with a template referencing both its own prop, and the child.

//childInheritance.js
import { api } from 'lwc';
import ParentInheritance from 'c/parentInheritance';

export default class ChildInheritance extends ParentInheritance {

  @api childProp; 

}

//childInheritance.html
<template>
  <lightning-card>
    <p>{childProp}</p>
    <p>{parentProp}</p>
  </lightning-card>
</template>

Then we compose some UI on another component by sticking c/childInheritance component there, it works fine:

<template>
  <c-child-inheritance 
    child-prop="Child Value 1" 
    parent-prop="Parent Value 2">
  </c-child-inheritance>
</template> 

But when I attempt to add it to the app builder config section of my metadata file, I get the “property does not exist” error above. Here’s what that would look like.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="childInheritance">
    <apiVersion>45.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__AppPage">
            <property name="parentProp" type="String"/>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

As a workaround, you could create a kind of proxy @api exposed property that you map to the meta config file.

export default class ChildInheritance extends ParentInheritance {

  @api childProp; 
  @api parentProxyProp;

  connectedCallback(){
    if (!this.parentProp) {
        this.parentProp = this.parentProxyProp;
    }
  }

}

Then you reference parentProxyProp in metadata.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="childInheritance">
    <apiVersion>45.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__AppPage">
            <property name="parentProxyProp" type="String"/>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

This has a side-effect, though: you now have a new property that’s only meant as a pass-through to connect up the child to the parent prop. Someone could attempt to use it, so not perfect, and you’d need to plan for that accordingly.

This gap is known by the LWC team, but roadmap for when it will be addressed has not been announced.

Attribution
Source : Link , Question Author : Dafydd Johns , Answer Author : pchittum

Leave a Comment