| | |
| | | <template> |
| | | <div class={getFormElementClass}> |
| | | <label lwc:if={label} class={getLabelClass} for="combobox"> |
| | | <abbr lwc:if={required} title="required" class="slds-required" |
| | | >*</abbr |
| | | > |
| | | <abbr lwc:if={required} title="required" class="slds-required">*</abbr> |
| | | {label} |
| | | </label> |
| | | <div class="slds-form-element__control"> |
| | | <div class={getContainerClass}> |
| | | <div |
| | | class={getDropdownClass} |
| | | aria-expanded={isListboxOpen} |
| | | aria-haspopup="listbox" |
| | | aria-owns="listbox" |
| | | role="combobox" |
| | | > |
| | | <div class={getDropdownClass} aria-expanded={isListboxOpen} aria-haspopup="listbox" aria-owns="listbox" |
| | | role="combobox"> |
| | | <!-- Search input start --> |
| | | <div class={getComboboxClass} role="none"> |
| | | <template lwc:if={isSingleEntry}> |
| | | <lightning-icon |
| | | icon-name={getSelectIconName} |
| | | size="small" |
| | | alternative-text="Selected item icon" |
| | | class={getSelectIconClass} |
| | | > |
| | | <lightning-icon icon-name={getSelectIconName} size="small" |
| | | alternative-text="Selected item icon" class={getSelectIconClass}> |
| | | </lightning-icon> |
| | | </template> |
| | | |
| | | <!-- Text input --> |
| | | <input |
| | | type="text" |
| | | class={getInputClass} |
| | | aria-autocomplete="list" |
| | | aria-controls="listbox" |
| | | aria-activedescendant={_focusedResultIndex} |
| | | autocomplete="off" |
| | | role="textbox" |
| | | id="combobox" |
| | | placeholder={placeholder} |
| | | value={getInputValue} |
| | | title={getInputTitle} |
| | | readonly={isInputReadonly} |
| | | disabled={disabled} |
| | | onfocus={handleFocus} |
| | | onblur={handleBlur} |
| | | oninput={handleInput} |
| | | onkeydown={handleKeyDown} |
| | | /> |
| | | <input type="text" class={getInputClass} aria-autocomplete="list" aria-controls="listbox" |
| | | aria-activedescendant={_focusedResultIndex} autocomplete="off" role="textbox" id="combobox" |
| | | placeholder={placeholder} value={getInputValue} title={getInputTitle} |
| | | readonly={isInputReadonly} disabled={disabled} onfocus={handleFocus} onblur={handleBlur} |
| | | oninput={handleInput} onkeydown={handleKeyDown} /> |
| | | |
| | | <!-- Search icon --> |
| | | <lightning-icon |
| | | icon-name="utility:search" |
| | | size="x-small" |
| | | alternative-text="Search icon" |
| | | class={getSearchIconClass} |
| | | ></lightning-icon> |
| | | <lightning-icon icon-name="utility:search" size="x-small" alternative-text="Search icon" |
| | | class={getSearchIconClass}></lightning-icon> |
| | | |
| | | <!-- Clear selection button icon for single entry lookups --> |
| | | <template lwc:if={isSingleEntry}> |
| | | <button |
| | | title="Remove selected option" |
| | | type="button" |
| | | onclick={handleClearSelection} |
| | | class={getClearSelectionButtonClass} |
| | | disabled={disabled} |
| | | > |
| | | <lightning-icon |
| | | icon-name="utility:close" |
| | | size="x-small" |
| | | <button title="Remove selected option" type="button" onclick={handleClearSelection} |
| | | class={getClearSelectionButtonClass} disabled={disabled}> |
| | | <lightning-icon icon-name="utility:close" size="x-small" |
| | | alternative-text="Remove selected option" |
| | | class="slds-button__icon" |
| | | ></lightning-icon> |
| | | class="slds-button__icon"></lightning-icon> |
| | | </button> |
| | | </template> |
| | | </div> |
| | | <!-- Search input end --> |
| | | |
| | | <!-- Result list box start --> |
| | | <div |
| | | id="listbox" |
| | | role="listbox" |
| | | aria-label={label} |
| | | onmousedown={handleComboboxMouseDown} |
| | | onmouseup={handleComboboxMouseUp} |
| | | class={getListboxClass} |
| | | > |
| | | <ul |
| | | class="slds-listbox slds-listbox_vertical" |
| | | role="presentation" |
| | | > |
| | | <div id="listbox" role="listbox" aria-label={label} onmousedown={handleComboboxMouseDown} |
| | | onmouseup={handleComboboxMouseUp} class={getListboxClass}> |
| | | <ul class="slds-listbox slds-listbox_vertical" role="presentation"> |
| | | <!-- Spinner to display when waiting for results of search --> |
| | | <div lwc:if={loading}> |
| | | <lightning-spinner |
| | | alternative-text="Loading" |
| | | size="small" |
| | | ></lightning-spinner> |
| | | <lightning-spinner alternative-text="Loading" size="small"></lightning-spinner> |
| | | </div> |
| | | |
| | | <!-- Result list start --> |
| | | <template |
| | | for:each={searchResultsLocalState} |
| | | for:item="item" |
| | | for:index="index" |
| | | lwc:if={hasResults} |
| | | > |
| | | <li |
| | | key={item.result.id} |
| | | role="presentation" |
| | | class="slds-listbox__item" |
| | | > |
| | | <div |
| | | class={item.classes} |
| | | role="option" |
| | | id={index} |
| | | aria-label={item.result.title} |
| | | onclick={handleResultClick} |
| | | data-recordid={item.result.id} |
| | | > |
| | | <span |
| | | class="slds-media__figure slds-listbox__option-icon" |
| | | > |
| | | <lightning-icon |
| | | icon-name={item.result.icon} |
| | | size="small" |
| | | alternative-text="Result item icon" |
| | | ></lightning-icon> |
| | | <template for:each={searchResultsLocalState} for:item="item" for:index="index" |
| | | lwc:if={hasResults}> |
| | | <li key={item.result.id} role="presentation" class="slds-listbox__item"> |
| | | <div class={item.classes} role="option" id={index} aria-label={item.result.title} |
| | | onclick={handleResultClick} data-recordid={item.result.id}> |
| | | <span class="slds-media__figure slds-listbox__option-icon"> |
| | | <lightning-icon icon-name={item.result.icon} size="small" |
| | | alternative-text="Result item icon"></lightning-icon> |
| | | </span> |
| | | <span class="slds-media__body"> |
| | | <span |
| | | class="slds-listbox__option-text slds-listbox__option-text_entity" |
| | | > |
| | | <lightning-formatted-rich-text |
| | | value={item.result.titleFormatted} |
| | | disable-linkify |
| | | > |
| | | <span class="slds-listbox__option-text slds-listbox__option-text_entity"> |
| | | <lightning-formatted-rich-text value={item.result.titleFormatted} |
| | | disable-linkify> |
| | | </lightning-formatted-rich-text> |
| | | </span> |
| | | <!-- <span lwc:if={item.result.subtitleFormatted} |
| | |
| | | <!-- No results start --> |
| | | <template lwc:else> |
| | | <li role="presentation"> |
| | | <span |
| | | class="slds-media slds-listbox__option_entity" |
| | | role="option" |
| | | > |
| | | <span |
| | | lwc:if={loading} |
| | | class="slds-media__body" |
| | | >Loading...</span |
| | | > |
| | | <span lwc:else class="slds-media__body" |
| | | >No results.</span |
| | | > |
| | | <span class="slds-media slds-listbox__option_entity" role="option"> |
| | | <span lwc:if={loading} class="slds-media__body">Loading...</span> |
| | | <span lwc:else class="slds-media__body">No results.</span> |
| | | </span> |
| | | </li> |
| | | </template> |
| | | <!-- No results end --> |
| | | |
| | | <!-- Create new records --> |
| | | <template |
| | | for:each={newRecordOptions} |
| | | for:item="newRecord" |
| | | > |
| | | <li |
| | | key={newRecord.value} |
| | | role="presentation" |
| | | class="slds-listbox__item" |
| | | > |
| | | <div |
| | | class="slds-media slds-media_center slds-listbox__option slds-listbox__option_entity" |
| | | onclick={handleNewRecordClick} |
| | | data-sobject={newRecord.value} |
| | | role="option" |
| | | > |
| | | <span |
| | | class="slds-media__figure slds-listbox__option-icon" |
| | | > |
| | | <lightning-icon |
| | | icon-name="utility:add" |
| | | size="small" |
| | | alternative-text={newRecord.label} |
| | | ></lightning-icon> |
| | | <template for:each={newRecordOptions} for:item="newRecord"> |
| | | <li key={newRecord.value} role="presentation" class="slds-listbox__item"> |
| | | <div class="slds-media slds-media_center slds-listbox__option slds-listbox__option_entity" |
| | | onclick={handleNewRecordClick} data-sobject={newRecord.value} role="option"> |
| | | <span class="slds-media__figure slds-listbox__option-icon"> |
| | | <lightning-icon icon-name="utility:add" size="small" |
| | | alternative-text={newRecord.label}></lightning-icon> |
| | | </span> |
| | | <span class="slds-media__body"> |
| | | <span |
| | | class="slds-listbox__option-text" |
| | | >{newRecord.label}</span |
| | | > |
| | | <span class="slds-listbox__option-text">{newRecord.label}</span> |
| | | </span> |
| | | </div> |
| | | </li> |
| | |
| | | |
| | | <!-- Multi-selection start --> |
| | | <template lwc:if={isMultiEntry}> |
| | | <div |
| | | id="selection" |
| | | role="listbox" |
| | | aria-label={label} |
| | | aria-orientation="horizontal" |
| | | > |
| | | <ul |
| | | class="slds-listbox slds-listbox_inline slds-var-p-top_xxx-small" |
| | | role="group" |
| | | aria-label="Selected options" |
| | | > |
| | | <div id="selection" role="listbox" aria-label={label} aria-orientation="horizontal"> |
| | | <ul class="slds-listbox slds-listbox_inline slds-var-p-top_xxx-small" role="group" |
| | | aria-label="Selected options"> |
| | | <template for:each={selection} for:item="item"> |
| | | <li key={item.id} role="presentation"> |
| | | <lightning-pill |
| | | label={item.title} |
| | | title={item.title} |
| | | onremove={handleRemoveSelectedItem} |
| | | name={item.id} |
| | | > |
| | | <lightning-icon |
| | | icon-name={item.icon} |
| | | ></lightning-icon> |
| | | <lightning-pill label={item.title} title={item.title} |
| | | onremove={handleRemoveSelectedItem} name={item.id}> |
| | | <lightning-icon icon-name={item.icon}></lightning-icon> |
| | | </lightning-pill> |
| | | </li> |
| | | </template> |
| | |
| | | |
| | | <!-- Errors start --> |
| | | <template for:each={_errors} for:item="error"> |
| | | <div |
| | | key={error.id} |
| | | role="alert" |
| | | class="slds-form-element__label slds-var-m-top_xx-small form-error" |
| | | > |
| | | <div key={error.id} role="alert" class="slds-form-element__label slds-var-m-top_xx-small form-error"> |
| | | {error.message} |
| | | </div> |
| | | </template> |
| | | <!-- Errors end --> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </template> |