demo

Get started

z-autocomplete has been designed as a result of an attempt to using the github auto-complete element but didn't fit my needs. It is highly inspired by it.

Install via NPM

The component is available here on npm, you can install it via this command:

npm i @benavern/z-autocomplete

Then you can use it in your scripts like so in your js/ts module files:

import '@benavern/z-autocomplete';

Install via CDN

<script type="module" src="https://unpkg.com/@benavern/z-autocomplete"></script>

Have fun

Full example

Here is a full example with all features demonstrated and some styling that you can find in the demo.css file.




<z-autocomplete id="full-example-el">
    <input
        data-z-autocomplete-input
        type="text"
        placeholder="write anything here">

    <button data-z-autocomplete-clear>
        &times;
    </button>
</z-autocomplete>


<button id="full-example-clear">
    Clear from outside
</button>
import './z-autocomplete.ts'
import type { ZAutocomplete } from './z-autocomplete.ts';

type OptionItem = {
    id: number,
    name: string
};

const AUTOCOMPLETE_DATA: OptionItem[] = [
    { id: 1, name: 'Option1' },
    { id: 2, name: 'Option2' },
    { id: 3, name: 'Option3' },
    { id: 4, name: 'Option4' },
    { id: 5, name: 'Option5 (preventDefault)' },
    { id: 6, name: 'Option6' },
    { id: 7, name: 'Option7' },
    { id: 8, name: 'Option8' },
    { id: 9, name: 'Option9' },
    { id: 10, name: 'Option10' },
    { id: 11, name: 'Option11' },
    { id: 12, name: 'Option12' },
];

const fullExampleEl = document.querySelector('#full-example-el') as ZAutocomplete<OptionItem>;
const fullExampleClear = document.querySelector('#full-example-clear') as HTMLButtonElement;

fullExampleEl.fetchData = async (inputValue, abortSignal) => {
    console.log('🔎 we are looking for ... ', inputValue);

    // it is here that you will put your fetch code!
    await new Promise((resolve) => setTimeout(resolve, 1000));

    if (abortSignal?.aborted) {
        console.error(abortSignal.reason);
        return [];
    }

    return AUTOCOMPLETE_DATA;
}

fullExampleEl.dataToOption = (data) => {
    if (!data) return undefined;

    // this is fake ...
    const isTitle = [1, 4, 7].includes(data.id);

    let label: string | HTMLElement = String(data.name);

    if (isTitle) {
        label = document.createElement('strong');
        label.textContent = data.name;
    }

    return {
        label,
        inputValue: String(data.name),
        value: data,
        disabled: isTitle,
    };
}

fullExampleEl.addEventListener('autocomplete', (e: Event) => {
    const event = e as CustomEvent<OptionItem | undefined>;

    if (event.detail?.id === 5) event.preventDefault();

    console.log('🌟 Chose value', event.detail, 'with event prevented', event.defaultPrevented);
})

// default value if necessary
// fullExampleEl.value = AUTOCOMPLETE_DATA[0];

fullExampleClear.addEventListener('click', () => {
    fullExampleEl.clear();
})