My solution is using all of the available SLDS and plus javascript and available Aura Javascript to emulate the behaviour of a select list.
I took the example from the SLDS documentation and added aura:id
tags to it. SLDS base picklist open
component:
<aura:component >
<aura:attribute name="currentCheckedPicklistIds" type="String[]" />
<div aura:id="dropdown" class="slds-picklist slds-dropdown-trigger slds-dropdown-trigger--click">
<div class="slds-form-element">
<label class="slds-form-element__label" for="text-input-01">Categories</label>
<div class="slds-form-element__control slds-input-has-icon slds-input-has-icon--right slds-picklist__input">
<input aura:id="selectedOption" type="search" id="text-input-01" class="slds-lookup__search-input slds-input" placeholder="Select an Option" aria-owns="option-list-01" role="combobox" aria-activedescendant="" aria-expanded="true" readonly="" />
<lightning:buttonIcon class="slds-button slds-input__icon slds-text-color--default" iconName="utility:down" onclick="{!c.openDropdown}" alternativeText="Open or close dropdown."/>
</div>
</div>
<div class="slds-dropdown slds-dropdown--left slds-dropdown--length-5" role="listbox">
<ul aura:id="checklist" id="option-list-01" class="slds-dropdown__list" role="presentation">
<li aura:id="option1" role="presentation" onclick="{!c.checkOption1}">
<span class="slds-lookup__item-action slds-lookup__item-action--label" role="option" tabindex="0" id="listbox-option-2279">
<lightning:icon aura:id="optionIcon1" class="slds-hide slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" iconName="utility:check" size="xx-small" />
<div aura:id="padding1" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" />
<span aura:id="content1" class="slds-truncate">Option A</span>
</span>
</li>
<li aura:id="option2" role="presentation" onclick="{!c.checkOption2}">
<span class="slds-lookup__item-action slds-lookup__item-action--label" role="option" tabindex="-1" id="listbox-option-2280">
<lightning:icon aura:id="optionIcon2" class="slds-hide slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" iconName="utility:check" size="xx-small" />
<!-- fake the padding because nothing lines up... -->
<div aura:id="padding2" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" />
<span aura:id="content2" class="slds-truncate">Option B</span>
</span>
</li>
<li aura:id="option3" role="presentation" onclick="{!c.checkOption3}">
<span class="slds-lookup__item-action slds-lookup__item-action--label" role="option" tabindex="-1" id="listbox-option-2281">
<lightning:icon aura:id="optionIcon3" class="slds-hide slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" iconName="utility:check" size="xx-small" />
<!-- fake the padding because nothing lines up... -->
<div aura:id="padding3" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" />
<span aura:id="content3" class="slds-truncate">Option C</span>
</span>
</li>
<li aura:id="option4" role="presentation" onclick="{!c.checkOption4}">
<span class="slds-lookup__item-action slds-lookup__item-action--label" role="option" tabindex="-1" id="listbox-option-2282">
<lightning:icon aura:id="optionIcon4" class="slds-hide slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" iconName="utility:check" size="xx-small" />
<!-- fake the padding because nothing lines up... -->
<div aura:id="padding4" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" />
<span aura:id="content4" class="slds-truncate">Option D</span>
</span>
</li>
<li aura:id="option5" role="presentation" onclick="{!c.checkOption5}">
<span class="slds-lookup__item-action slds-lookup__item-action--label" role="option" tabindex="-1" id="listbox-option-2283">
<lightning:icon aura:id="optionIcon5" class="slds-hide slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" iconName="utility:check" size="xx-small" />
<!-- fake the padding because nothing lines up... -->
<div aura:id="padding5" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" />
<span aura:id="content5" class="slds-truncate">Option E</span>
</span>
</li>
<li aura:id="option6" role="presentation" onclick="{!c.checkOption6}">
<span class="slds-lookup__item-action slds-lookup__item-action--label" role="option" tabindex="-1" id="listbox-option-2284">
<lightning:icon aura:id="optionIcon6" class="slds-hide slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" iconName="utility:check" size="xx-small" />
<!-- fake the padding because nothing lines up... -->
<div aura:id="padding6" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small slds-shrink-none" />
<span aura:id="content6" class="slds-truncate" title="Option FGHIJKLMNOPQRSTUVWXYZ">Option FGHIJKLMNOPQRSTUVWXYZ</span>
</span>
</li>
</ul>
</div>
</div>
</aura:component>
controller:
({
openDropdown: function(component, event, helper) {
var dropdown = component.find("dropdown");
if($A.util.hasClass(dropdown, "slds-is-open")) {
$A.util.removeClass(dropdown, "slds-is-open");
} else {
$A.util.addClass(dropdown, "slds-is-open");
}
},
checkOption1: function(component, event, helper) {
helper.performCheckActions(component, "option1", "optionIcon1", "padding1", "content1");
},
checkOption2: function(component, event, helper) {
helper.performCheckActions(component, "option2", "optionIcon2", "padding2", "content2");
},
checkOption3: function(component, event, helper) {
helper.performCheckActions(component, "option3", "optionIcon3", "padding3", "content3");
},
checkOption4: function(component, event, helper) {
helper.performCheckActions(component, "option4", "optionIcon4", "padding4", "content4");
},
checkOption5: function(component, event, helper) {
helper.performCheckActions(component, "option5", "optionIcon5", "padding5", "content5");
},
checkOption6: function(component, event, helper) {
helper.performCheckActions(component, "option6", "optionIcon6", "padding6", "content6");
}
})
helper:
({
performCheckActions : function(component, optionId, optionIconId, paddingId, contentId) {
this.resetPreviousCheckedOption(component);
this.storeAsCurrentlyCheckedValue(component, optionId, optionIconId, paddingId);
this.checkOption(component, optionId);
this.showOptionIcon(component, optionIconId, paddingId);
this.setInputBar(component, contentId);
},
showOptionIcon : function(component, iconName, paddingName) {
if( !iconName || !paddingName ) {
return;
}
var option = component.find(iconName);
var padding = component.find(paddingName);
if($A.util.hasClass(option, "slds-hide")) {
$A.util.removeClass(option, "slds-hide");
//hide the padding
var padding = component.find(paddingName);
$A.util.addClass(padding, "slds-hide")
} else {
$A.util.addClass(option, "slds-hide");
$A.util.removeClass(padding, "slds-hide");
}
},
checkOption : function(component, componentName) {
if( !componentName ) {
return;
}
var option = component.find(componentName);
if($A.util.hasClass(option, "slds-is-selected")) {
$A.util.removeClass(option, "slds-is-selected");
} else {
$A.util.addClass(option, "slds-is-selected");
}
},
setInputBar : function(component, content) {
var selectedText = component.find(content).getElement().textContent;
var selectedBox = component.find("selectedOption").getElement();
selectedBox.value = selectedText;
},
storeAsCurrentlyCheckedValue : function(component, currentOptionId, currentOptionIconId, currentPaddingId) {
var currentIdStorage = [currentOptionId, currentOptionIconId, currentPaddingId];
component.set("v.currentCheckedPicklistIds", currentIdStorage);
},
resetPreviousCheckedOption : function(component) {
var optionIds = component.get("v.currentCheckedPicklistIds");
this.checkOption(component, optionIds[0]);
this.showOptionIcon(component, optionIds[1], optionIds[2]);
}
})
A screenshot of what it looks like:
The reason I had to add all that Javascript was because the SLDS documentation does not show how to transition between states. The Javascript supplements that.
Note: at the moment, once you click an option, you cannot leave the picklist blank, that is, it won't go back to the initial state. My solution may not be the most scalable... You can divide, if it's possible, each of the options in the picklist to be a separate component, and create events to callout to the <aura:attribute>
.