1

I am trying to create a lightning path in LWC, for which I used two components with SLDS Path.

But the view is not as expected to Chevron.

Parent Component: customPathLwc

<template>
    <lightning-card>
        <div class="slds-path">
            <div class="slds-grid slds-path__track">
                <div class="slds-grid slds-path__scroller-container">
                    <div class="slds-path__scroller" role="application">
                        <div class="slds-path__scroller_inner">
                            <ul class="slds-path__nav" role="listbox" aria-orientation="horizontal">
                                <template if:true={picklistFieldValues.data}>
                                    <template for:each={picklistFieldValues.data.values} for:item="item">
                                        <c-custom-path-ui-lwc key={item.value} label={item.label} value={item.value} selected-value={selectedValue}></c-custom-path-ui-lwc>
                                    </template>
                                </template>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </lightning-card>
</template>

Child Component: customPathUiLwc

<template>
    <li key={value} class={classList} role="presentation"></li>
        <a aria-selected="true" class="slds-path__link" href="javascript:void(0);" id={value} role="option"
            tabindex="0">
            <span class="slds-path__stage">
                <svg class="slds-icon slds-icon_x-small" aria-hidden="true">
                    <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#check">
                    </use>
                </svg>
                <span class="slds-assistive-text">Current Stage:</span>
            </span>
            <span class="slds-path__title">{label}</span>
        </a>
    </li>
</template>

Expected look and feel:

enter image description here

Actual look:

enter image description here

I am setting class for li based on selected value

import { LightningElement, api } from 'lwc';

    export default class CustomPathUILwc extends LightningElement {
        @api selectedValue;
        @api value
        @api label
        get classList() {
            return this.value === this.selectedValue ? 'slds-path__item slds-is-current slds-is-active' : 'slds-path__item ';
        }
    }

Can someone tell what is going wrong here?

  • When you inspect the html rendered, does the classList variable value is right? Is the class slds-path__item added to your li element? – Martin Lezer May 23 at 9:37
  • Although it is your choice but why you are not using lightning-progress-indicator and lightning-progress-step. It is very easy to implement in LWC. – Dhanik Lal Sahni May 23 at 9:47
  • @MartinLezer Yes is showing up. – rahul gawale May 23 at 10:33
  • @DhanikLalSahni That is something interesting I will look into that, thanks for the info. – rahul gawale May 23 at 10:34
  • @DhanikLalSahni I checked that, but that is not something I am looking for, the design is completely different. – rahul gawale May 23 at 10:38
1

The problem comes from the combination of LWC, how you use it and the Lightning Desin System itself.

Indeed, here's the HTML generetad by your code when you add the list item inside another component:

<ul role="listbox" aria-orientation="horizontal" class="slds-path__nav">
     <c-custom-path-ui-lwc>
          <li role="presentation" class="slds-path__item slds-is-incomplete"><a aria-selected="true" href="javascript:void(0);" id="Contacted-120" role="option" tabindex="0" class="slds-path__link">

As you can see, the name of the child component is added as an html element before adding the li element.

Unfortunately, the style applied by Lighting Desin System for the path component can't work with a block between the ul parent and the li element.

The only way I see would be to not use a child component and directly apply your html code inside the same component.

  • I used child component because I was not able to use the expression to set the class. can you help with that? according to the selected value, I need to set the class to the <li> – rahul gawale May 23 at 13:03
0

Finally, I used it in the same component, instead of going with the child component. As we could not use expressions directly in HTML markup of Lwc's, so I created one additional custom property as classlist which I generated conditionally in Js controller itself.

here is the code for js controller method. See how I generated classList based on condition.

get picklistValues() {
    let itemsList = [];
    console.log(JSON.stringify(this.record));
    if (this.record.data) {
        if (!this.selectedValue && this.record.data.fields.Status.value) {
            this.selectedValue = this.record.data.fields.Status.value + '';
        }
        if (this.picklistFieldValues && this.picklistFieldValues.data && this.picklistFieldValues.data.values) {
            console.log('got picklist field data');
            let selectedUpTo = 0;
            for (let item in this.picklistFieldValues.data.values) {

                if (Object.prototype.hasOwnProperty.call(this.picklistFieldValues.data.values, item)) {
                    let classList;
                    if (this.picklistFieldValues.data.values[item].value === this.selectedValue) {
                        classList = 'slds-path__item slds-is-current slds-is-active';
                        selectedUpTo++;
                    } else {
                        classList = 'slds-path__item slds-is-incomplete';
                    }

                    console.log(classList);

                    itemsList.push({
                        pItem: this.picklistFieldValues.data.values[item],
                        classList: classList
                    })
                }
            }

            if (selectedUpTo > 0) {
                for (let item = 0; item < selectedUpTo; item++) {
                    itemsList[item].classList = 'slds-path__item slds-is-complete';
                }
            }
            console.log('im here = ' + this.selectedValue);
            return itemsList;
        }
    }
    return null;
}

then I just referenced the same property in HTML markup of the component as below. Please see it used classList as class={item.classList} in below code.

<ul class="slds-path__nav" role="listbox" aria-orientation="horizontal">
    <template if:true={picklistValues}>
        <template for:each={picklistValues} for:item="item">

            <li data-value={item.pItem.value} onclick={handleSelect} key={item} class={item.classList} role="presentation">
                <a data-value={item.pItem.value} onclick={handleSelect} aria-selected="true" class="slds-path__link" href="javascript:void(0);" id={item.pItem.value} role="option"
                    tabindex="0">
                    <span class="slds-path__stage">
                        <lightning-icon icon-name="utility:check" alternative-text="Warning!" variant="inverse" size="x-small"></lightning-icon>
                        <span class="slds-assistive-text">Current Stage:</span>
                    </span>
                    <span class="slds-path__title">{item.pItem.label}</span>
                </a>
            </li>

        </template>
    </template>
</ul>

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.