0

I am using slds path in my component to show the different stages in different colors. Instead of using multiple div tags I opted for single div tag with aura iteration. But my output is not coming as I expected[path colors are overlapping]. Can someone help me in this? Expected Ouput design:enter image description here

Obtained output : enter image description here My Component code :

<aura:attribute name="groceries" type="List"
                default="[ 'Eggs', 'Bacon', 'Bread' ]"/>
<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">
                        <aura:iteration items="{!v.groceries}" var="item">
                           <li class="{! 'slds-path__item slds-is-current ' + (item== 'Bacon' ? 'slds-is-won' : 'slds-is-incomplete')}" role="presentation">
                                <a aria-selected="true" class="slds-path__link" href="javascript:void(0);" id="path-1" role="option" tabindex="0">
                                    <p> {!item}</p>
                                </a>
                            </li>
                        </aura:iteration>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

1

You must render your path as "slds-complete" > "slds-current" > "slds-is-incomplete", or it won't appear correctly. You could hack CSS if you really wanted to, but that can have future incompatibilities. Here's an implementation I wrote that does this:

path.cmp

<aura:component >
    <aura:attribute name="currentStep" type="String" />
    <aura:attribute name="steps" type="String[]" />

    <aura:attribute name="renderInfo" access="private" type="Object[]" />

    <aura:registerEvent name="onselect" type="c:valueSelected" />

    <aura:handler name="init" value="{!this}" action="{!c.update}" />
    <aura:handler name="change" value="{!v.steps}" action="{!c.update}" />
    <aura:handler name="change" value="{!v.currentStep}" action="{!c.update}" />

    <div class="slds-path-coach">
        <div class="slds-grid">
            <div class="slds-tabs_path" role="application">
                <ul class="slds-tabs_path__nav" role="listbox" aria-orientation="horizontal">
                    <aura:iteration items="{!v.renderInfo}" var="item" indexVar="index">
                        <li class="{!'slds-tabs_path__item '+item.state}" role="presentation">
                            <a onclick="{!c.click}" aria-selected="{!item.selected}" 
                                class="slds-tabs_path__link" title="{!item.label}"
                                role="option" tabindex="-1" data-index="{!index}">
                                <span class="slds-tabs_path__stage">
                                    <lightning:icon size="x-small" iconName="utility:check" />
                                    <span class="slds-assistive-text">
                                        {!item.label}
                                    </span>
                                </span>
                                <span class="slds-tabs_path__title">
                                    {!item.label}
                                </span>
                            </a>
                        </li>
                    </aura:iteration>
                </ul>
            </div>
        </div>
    </div>
</aura:component>

pathController.js

({
    click: function(component, event, helper) {
        var index = parseInt(event.target.closest("[data-index]").dataset.index), 
            value, onselect, steps = component.get("v.steps");
        if(index !== undefined) {
            event.preventDefault();
            value = steps[index];
            component.set("v.currentStep", value);
            onselect = component.getEvent("onselect");
            onselect.setParams({ value: value });
            onselect.fire();
            helper.renderState(component);
        }
    },
    update: function(component, event, helper) {
        helper.renderState(component);
    }
})

pathHelper.js

({
    renderState: function(component) {
        var currentStep = component.get("v.currentStep"),
            allSteps = component.get("v.steps"),
            render = [],
            state = "slds-is-complete";
        allSteps.forEach(function(step){
            if(currentStep === step) {
                state = "slds-is-current";
            } else if(state === "slds-is-current") {
                state = "slds-is-incomplete";
            }
            render.push({ label: step, selected: state === "slds-is-current", state: state });
        });
        component.set("v.renderInfo", render);
    }
})

valueSelected.evt

<aura:event access="global" type="COMPONENT" description="Event fired when a value is selected">
    <aura:attribute name="value" type="Object" access="global" />
</aura:event>

Always make sure some valid option is chosen.

  • what if we want to use 'slds-is-lost' or 'slds-is-won' stages?. We can't rely on only 3 stages. – Aruna Aug 31 '18 at 10:39
  • @Aruna This is the basic path implementation. If you're interested in expanding it, be my guest; I didn't have a use for it because it wasn't in my design goals. – sfdcfox Aug 31 '18 at 10:44
0

In response to the comment:

I saw your CSS but I am not able to figure out how to use it in component. Can you please give your component code along with CSS code.

the approach I used was to have a component per path item so I could toggle the complete and current booleans and get the right style applied:

<aura:component extends="c:wizBase">

    <aura:attribute name="stage" type="Object" required="true"/>
    <aura:attribute name="complete" type="Boolean" default="false"/>
    <aura:attribute name="current" type="Boolean" default="false"/>
    <aura:attribute name="minWidth" type="String" default="10rem"/>

    <li style="{! 'min-width: ' + v.minWidth }" class="{! 'slds-path__item ' + (v.current ? 'slds-is-current ' : (v.complete ? 'slds-is-complete' : 'slds-is-incomplete ')) }" role="presentation">
        <a class="slds-path__link" onclick="{! c.onclick }">
            <span class="slds-path__title">{! v.stage.label }</span>
        </a>
    </li>

</aura:component>

and then added these are added to the body of my path component by its controller based on the configured items.

(This is an example that just as in programming adding new classes often helps, in Lightning Components don't be afraid to add building block components.)

  • Hi Keith, thank you for giving me the component code. I will test this and reply you. – Aruna Aug 31 '18 at 13:04
  • I tried your code, Since the attributes 'complete' and 'current' obtain values from Init handler, they are giving same color for all states. I don't want to have same color for all the stages. I want different colors of slds path. – Aruna Aug 31 '18 at 13:15
0

In Winter's 19 release CSS classes for Path are updated. you need to apply some custom CSS like:

.THIS .incomplete_isActive, .THIS .incomplete_isActive::before, .THIS .incomplete_isActive::after{ background-color: rgb(195, 195, 195); background-image: none; }

  • With the Winter 19 release the problem has been fixed completely and there is no need of custom css. – Aruna Sep 25 '18 at 11:09
0

With the Winter 19 release, the slds path has been fixed by Salesforce. In case if CSS hacking has been done before for slds path, then it will make the slds path worse. Removing the CSS will make slds path look good.

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.