Simple Auto Complete search using Lightning Web Component in Salesforce

Sample Code:
Apex Class:
public with sharing class AccountController {  
      
    @AuraEnabled( cacheable = true )  
    public static List< Account > fetchAccounts( String searchKey ) {  
        
        String strKey = '%' + searchKey + '%';  
        return [
            SELECT Id, Name
            FROM Account
            WHERE Name LIKE: strKey LIMIT 10
        ];  
            
    }  
        
}
 
HTML:
<template>
    <lightning-card title="Account Search" icon-name="standard:search">
        <div class="slds-m-around_medium">
            <lightning-input
                label="Search"
                type="search"
                onchange={handleChange}
                value={searchKey}
            ></lightning-input>
        </div>
        <template if:true={accounts}>  
            <div class="slds-box">
                <template iterator:it={accounts} for:index="index">  
                    <div onclick={handleSelect} key={it.value.Id} data-id={it.index} style="cursor: pointer;">  
                        <div class="slds-m-around_medium">                              
                            <lightning-formatted-rich-text value={it.value.formattedName}>
                            </lightning-formatted-rich-text>  
                        </div>  
                    </div>  
                </template>
            </div>
        </template>
        <template if:true={selectedAccountId}>
            <div class="slds-m-around_medium">
                <b>Selected Account Id is</b> {selectedAccountId}.
            </div>
        </template>
    </lightning-card>
</template>
 
JavaScript:
import { LightningElement } from 'lwc';
import fetchAccounts from '@salesforce/apex/AccountController.fetchAccounts';   

export default class SampleLWC extends LightningElement {
    
    accounts;  
    error;  
    searchKey;
    selectedAccountId;

    handleChange( event ) {

        this.searchKey = event.detail.value;
        console.log( 'searchKey is', this.searchKey );

        if ( this.searchKey ) {  
    
            fetchAccounts( { searchKey: this.searchKey } )    
            .then( result => {  
                
                console.log( 'result is', JSON.stringify( result ) );
                let tempAccounts = [];
                result.forEach( ( record ) => {

                    let tempRec = Object.assign( {}, record );      
                    tempRec.formattedName = tempRec.Name.replace( new RegExp( this.searchKey, 'i' ),( value ) => `<b>${value}</b>` );                    
                    tempAccounts.push( tempRec );
                    
                });
                this.accounts = tempAccounts;  
    
            } )  
            .catch( error => {  
                
                console.log( 'Error Occured', JSON.stringify( error ) );
                this.error = error;  
    
            } );  
    
        } else  {

            this.accounts = undefined;  

        }

    }

    handleSelect( event ) {
        
        let strIndex = event.currentTarget.dataset.id;
        console.log( 'strIndex is', strIndex );
        let tempRecs =  JSON.parse( JSON.stringify( this.accounts ) );
        let selectedRecId = tempRecs[ strIndex ].Id;
        console.log( 'Record Id is', selectedRecId );
        let strAccName = tempRecs[ strIndex ].Name;
        console.log( 'Name Id is', strAccName );
        this.selectedAccountId = selectedRecId;
        this.searchKey = strAccName;
        this.accounts = undefined;

    }

}

 
JS-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

 
Output: