Combobox

Tailwind CSS and Alpine JS Combobox

Comboboxes, also known as listboxes, dropdowns, or select, allow users to choose an option from a customized list. Unlike default select components, comboboxes offer customization options, including the ability to incorporate elements like checkboxes.

Requires Alpine JS

This component requires Alpine JS v3 to function properly. Some advanced features may require additional Alpine plugins (such as focus).

Tell Me More

Simple combobox

Requires Alpine JS Focus Plugin

A simple dropdown with a list of text options, pressing a key will focus on the first option that starts with that key. The selected value will be stored in a hidden input field for easy retrieval.

HTML
<div x-data="{
        options: [
            {
                value: 'Agriculture',
                label: 'Agriculture',
            },
            {
                value: 'Construction',
                label: 'Construction',
            },
            {
                value: 'Education',
                label: 'Education',
            },
            {
                value: 'Entertainment',
                label: 'Entertainment',
            },
            {
                value: 'Finance',
                label: 'Finance',
            },
            {
                value: 'Healthcare',
                label: 'Healthcare',
            },
            {
                value: 'Hospitality',
                label: 'Hospitality',
            },
            {
                value: 'IT',
                label: 'IT',
            },
            {
                value: 'Manufacturing',
                label: 'Manufacturing',
            },
            {
                value: 'Marketing',
                label: 'Marketing',
            },
            {
                value: 'Real Estate',
                label: 'Real Estate',
            },
            {
                value: 'Retail',
                label: 'Retail',
            },
            {
                value: 'Transportation',
                label: 'Transportation',
            },
        ],
        isOpen: false,
        openedWithKeyboard: false,
        selectedOption: null,
        setSelectedOption(option) {
            this.selectedOption = option
            this.isOpen = false
            this.openedWithKeyboard = false
            this.$refs.hiddenTextField.value = option.value
        },
        highlightFirstMatchingOption(pressedKey) {
            const option = this.options.find((item) =>
                item.label.toLowerCase().startsWith(pressedKey.toLowerCase()),
            )
            if (option) {
                const index = this.options.indexOf(option)
                const allOptions = document.querySelectorAll('.combobox-option')
                if (allOptions[index]) {
                    allOptions[index].focus()
                }
            }
        },
    }" class="" x-on:keydown="highlightFirstMatchingOption($event.key)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="industry" class="">Industry</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" role="combobox" class="" aria-haspopup="listbox" aria-controls="industriesList" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" x-bind:aria-expanded="isOpen || openedWithKeyboard">
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- hidden input to grab the selected value  -->
        <input id="industry" name="industry" type="text" x-ref="hiddenTextField" hidden/>
        <ul x-cloak x-show="isOpen || openedWithKeyboard" id="industriesList" class="" role="listbox" aria-label="industries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
            <template x-for="(item, index) in options" x-bind:key="item.value">   
                <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0" >
                    <!-- Label  -->
                    <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                    <!-- Screen reader 'selected' indicator  -->
                    <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                    <!-- Checkmark  -->
                    <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
                    </svg>
                </li>
            </template>
        </ul>
    </div>
</div>
<div x-data="combobox({
        options: [
            {
                value: 'Agriculture',
                label: 'Agriculture',
            },
            {
                value: 'Construction',
                label: 'Construction',
            },
            {
                value: 'Education',
                label: 'Education',
            },
            {
                value: 'Entertainment',
                label: 'Entertainment',
            },
            {
                value: 'Finance',
                label: 'Finance',
            },
            {
                value: 'Healthcare',
                label: 'Healthcare',
            },
            {
                value: 'Hospitality',
                label: 'Hospitality',
            },
            {
                value: 'IT',
                label: 'IT',
            },
            {
                value: 'Manufacturing',
                label: 'Manufacturing',
            },
            {
                value: 'Marketing',
                label: 'Marketing',
            },
            {
                value: 'Real Estate',
                label: 'Real Estate',
            },
            {
                value: 'Retail',
                label: 'Retail',
            },
            {
                value: 'Transportation',
                label: 'Transportation',
            },
        ],
})" class="" x-on:keydown="highlightFirstMatchingOption($event.key)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="industry" class="">Industry</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" role="combobox" class="" aria-haspopup="listbox" aria-controls="industriesList" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" x-bind:aria-expanded="isOpen || openedWithKeyboard">
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- hidden input to grab the selected value  -->
        <input id="industry" name="industry" type="text" x-ref="hiddenTextField" hidden/>
        <ul x-cloak x-show="isOpen || openedWithKeyboard" id="industriesList" class="" role="listbox" aria-label="industries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
            <template x-for="(item, index) in options" x-bind:key="item.value">   
                <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0" >
                    <!-- Label  -->
                    <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                    <!-- Screen reader 'selected' indicator  -->
                    <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                    <!-- Checkmark  -->
                    <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
                    </svg>
                </li>
            </template>
        </ul>
    </div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('combobox', (comboboxData = {
            options: [],
        },) => ({
            options: comboboxData.options,
            isOpen: false,
            openedWithKeyboard: false,
            selectedOption: null,
            setSelectedOption(option) {
                this.selectedOption = option
                this.isOpen = false
                this.openedWithKeyboard = false
                this.$refs.hiddenTextField.value = option.value
            },
            highlightFirstMatchingOption(pressedKey) {
                const option = this.options.find((item) =>
                    item.label.toLowerCase().startsWith(pressedKey.toLowerCase()),
                )
                if (option) {
                    const index = this.options.indexOf(option)
                    const allOptions = document.querySelectorAll('.combobox-option')
                    if (allOptions[index]) {
                        allOptions[index].focus()
                    }
                }
            },
        }))
    })
</script>

Combobox with images

Requires Alpine JS Focus Plugin

A dropdown with options that include images, pressing a key will focus on the first option that starts with that key.

HTML
<div x-data="{
        options: [
            {
                value: 'Aiden Walker',
                label: 'Aiden Walker',
                email: 'aiden.walker@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-1.webp',
            },
            {
                value: 'Alex Martinez',
                label: 'Alex Martinez',
                email: 'alex.martinez@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-6.webp',
            },
            {
                value: 'Ava Collins',
                label: 'Ava Collins',
                email: 'ava.collins@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-8.webp',
            },
            {
                value: 'Bob Johnson',
                label: 'Bob Johnson',
                email: 'bob.johnson@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-2.webp',
            },
            {
                value: 'Emily Rodriguez',
                label: 'Emily Rodriguez',
                email: 'emily.rodriguez@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-5.webp',
            },
            {
                value: 'Emma Thompson',
                label: 'Emma Thompson',
                email: 'emma.thompson@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-4.webp',
            },
            {
                value: 'Ethan Brown',
                label: 'Ethan Brown',
                email: 'ethan.brown@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-9.webp',
            },
            {
                value: 'Isabella Davis',
                label: 'Isabella Davis',
                email: 'isabellea.davis@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-3.webp',
            },
            {
                value: 'Noah Brooks',
                label: 'Noah Brooks',
                email: 'noah.brooks@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-7.webp',
            },
        ],
        isOpen: false,
        openedWithKeyboard: false,
        selectedOption: null,
        setSelectedOption(option) {
            this.selectedOption = option
            this.isOpen = false
            this.openedWithKeyboard = false
            this.$refs.hiddenTextField.value = option.value
        },
        highlightFirstMatchingOption(pressedKey) {
            const option = this.options.find((item) =>
                item.label.toLowerCase().startsWith(pressedKey.toLowerCase()),
            )
            if (option) {
                const index = this.options.indexOf(option)
                const allOptions = document.querySelectorAll('.combobox-option')
                if (allOptions[index]) {
                    allOptions[index].focus()
                }
            }
        },
    }" class="" x-on:keydown="highlightFirstMatchingOption($event.key)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="user" class="">Share with</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" role="combobox" class="" aria-haspopup="listbox" aria-controls="usersList" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" x-bind:aria-expanded="isOpen || openedWithKeyboard">
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- hidden input to grab the selected value  -->
        <input id="user" name="user" type="text" x-ref="hiddenTextField" hidden/>
        <ul x-cloak x-show="isOpen || openedWithKeyboard" id="usersList" class="" role="listbox" aria-label="users list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
            <template x-for="(item, index) in options" x-bind:key="item.value">   
                <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0" >
                    <div class="">
                        <img class="" x-bind:src="item.img" alt="" aria-hidden="true"/>
                        <!-- Label -->
                        <div class="">
                            <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                            <span class=""x-text="item.email"></span>
                            <!-- Screen reader 'selected' indicator  -->
                            <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        </div>
                    </div>
                    <!-- Checkmark  -->
                    <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
                    </svg>
                </li>
            </template>
        </ul>
    </div>
</div>
<div x-data="combobox({
        options: [
            {
                value: 'Aiden Walker',
                label: 'Aiden Walker',
                email: 'aiden.walker@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-1.webp',
            },
            {
                value: 'Alex Martinez',
                label: 'Alex Martinez',
                email: 'alex.martinez@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-6.webp',
            },
            {
                value: 'Ava Collins',
                label: 'Ava Collins',
                email: 'ava.collins@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-8.webp',
            },
            {
                value: 'Bob Johnson',
                label: 'Bob Johnson',
                email: 'bob.johnson@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-2.webp',
            },
            {
                value: 'Emily Rodriguez',
                label: 'Emily Rodriguez',
                email: 'emily.rodriguez@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-5.webp',
            },
            {
                value: 'Emma Thompson',
                label: 'Emma Thompson',
                email: 'emma.thompson@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-4.webp',
            },
            {
                value: 'Ethan Brown',
                label: 'Ethan Brown',
                email: 'ethan.brown@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-9.webp',
            },
            {
                value: 'Isabella Davis',
                label: 'Isabella Davis',
                email: 'isabellea.davis@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-3.webp',
            },
            {
                value: 'Noah Brooks',
                label: 'Noah Brooks',
                email: 'noah.brooks@example.com',
                img: 'https://res.cloudinary.com/ds8pgw1pf/image/upload/penguinui/component-assets/avatars/avatar-7.webp',
            },
        ],
})" class="" x-on:keydown="highlightFirstMatchingOption($event.key)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="user" class="">Share with</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" role="combobox" class="" aria-haspopup="listbox" aria-controls="usersList" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" x-bind:aria-expanded="isOpen || openedWithKeyboard">
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- hidden input to grab the selected value  -->
        <input id="user" name="user" type="text" x-ref="hiddenTextField" hidden/>
        <ul x-cloak x-show="isOpen || openedWithKeyboard" id="usersList" class="" role="listbox" aria-label="users list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
            <template x-for="(item, index) in options" x-bind:key="item.value">   
                <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0" >
                    <div class="">
                        <img class="" x-bind:src="item.img" alt="" aria-hidden="true"/>
                        <!-- Label -->
                        <div class="">
                            <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                            <span class=""x-text="item.email"></span>
                            <!-- Screen reader 'selected' indicator  -->
                            <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        </div>
                    </div>
                    <!-- Checkmark  -->
                    <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
                    </svg>
                </li>
            </template>
        </ul>
    </div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('combobox', (comboboxData = {
            options: [],
        },) => ({
            options: comboboxData.options,
            isOpen: false,
            openedWithKeyboard: false,
            selectedOption: null,
            setSelectedOption(option) {
                this.selectedOption = option
                this.isOpen = false
                this.openedWithKeyboard = false
                this.$refs.hiddenTextField.value = option.value
            },
            highlightFirstMatchingOption(pressedKey) {
                const option = this.options.find((item) =>
                    item.label.toLowerCase().startsWith(pressedKey.toLowerCase()),
                )
                if (option) {
                    const index = this.options.indexOf(option)
                    const allOptions = document.querySelectorAll('.combobox-option')
                    if (allOptions[index]) {
                        allOptions[index].focus()
                    }
                }
            },
        }))
    })
</script>

Combobox with checkboxes

Requires Alpine JS Focus Plugin

A multiselect combobox with checkboxes that allow users to select multiple options from a list of options. All the selected value will be stored in a hidden input field for easy retrieval.

HTML
<div x-data="{
        options: [
            {
                value: 'C++',
                label: 'C++',
            },
            {
                value: 'CSS',
                label: 'CSS',
            },
            {
                value: 'Golang',
                label: 'Golang',
            },
            {
                value: 'HTML',
                label: 'HTML',
            },
            {
                value: 'Java',
                label: 'Java',
            },
            {
                value: 'Javascript',
                label: 'Javascript',
            },
            {
                value: 'Kotlin',
                label: 'Kotlin',
            },
            {
                value: 'Perl',
                label: 'Perl',
            },
            {
                value: 'PHP',
                label: 'PHP',
            },
            {
                value: 'Python',
                label: 'Python',
            },
            {
                value: 'Ruby',
                label: 'Ruby',
            },
            {
                value: 'Rust',
                label: 'Rust',
            },
            {
                value: 'TypeScript',
                label: 'TypeScript',
            },
        ],
        isOpen: false,
        openedWithKeyboard: false,
        selectedOptions: [],
        setLabelText() {
            const count = this.selectedOptions.length;

            // if there are no selected options
            if (count === 0) return 'Please Select';

            // join the selected options with a comma
            return this.selectedOptions.join(', ');
        },
        highlightFirstMatchingOption(pressedKey) {
            // if Enter pressed, do nothing
            if (pressedKey === 'Enter') return

            // find and focus the option that starts with the pressed key
            const option = this.options.find((item) =>
                item.label.toLowerCase().startsWith(pressedKey.toLowerCase()),
            )
            if (option) {
                const index = this.options.indexOf(option)
                const allOptions = document.querySelectorAll('.combobox-option')
                if (allOptions[index]) {
                    allOptions[index].focus()
                }
            }
        },
        handleOptionToggle(option) {
            if (option.checked) {
                this.selectedOptions.push(option.value)
            } else {
                // remove the unchecked option from the selectedOptions array
                this.selectedOptions = this.selectedOptions.filter(
                    (opt) => opt !== option.value,
                )
            }
            // set the value of the hidden field to the selectedOptions array
            this.$refs.hiddenTextField.value = this.selectedOptions
        },
    }" class="" x-on:keydown="highlightFirstMatchingOption($event.key)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="skills" class="">Skills(s)</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" role="combobox" class="" aria-haspopup="listbox" aria-controls="skillsList" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-label="setLabelText()" x-bind:aria-expanded="isOpen || openedWithKeyboard">
            <span class=""  x-text="setLabelText()"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- hidden input to grab the selected value  -->
        <input id="skills" name="skills" type="text" x-ref="hiddenTextField" hidden />
        <ul x-cloak x-show="isOpen || openedWithKeyboard" id="skillsList" class="" role="listbox" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
            <template x-for="(item, index) in options" x-bind:key="item.value">
                <!-- option  -->
                <li role="option">
                    <label class="" x-bind:for="'checkboxOption' + index">
                        <div class="">
                            <input type="checkbox" class="" x-on:change="handleOptionToggle($el)" x-on:keydown.enter.prevent="$el.checked = ! $el.checked; handleOptionToggle($el)" x-bind:value="item.value" x-bind:id="'checkboxOption' + index" />
                            <!-- Checkmark  -->
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="4" class="" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
                            </svg>
                        </div>
                        <span x-text="item.label"></span>
                    </label>
                </li>
            </template>
        </ul>
    </div>
</div>
<div x-data="combobox({
    options: [
        {
            value: 'C++',
            label: 'C++',
        },
        {
            value: 'CSS',
            label: 'CSS',
        },
        {
            value: 'Golang',
            label: 'Golang',
        },
        {
            value: 'HTML',
            label: 'HTML',
        },
        {
            value: 'Java',
            label: 'Java',
        },
        {
            value: 'Javascript',
            label: 'Javascript',
        },
        {
            value: 'Kotlin',
            label: 'Kotlin',
        },
        {
            value: 'Perl',
            label: 'Perl',
        },
        {
            value: 'PHP',
            label: 'PHP',
        },
        {
            value: 'Python',
            label: 'Python',
        },
        {
            value: 'Ruby',
            label: 'Ruby',
        },
        {
            value: 'Rust',
            label: 'Rust',
        },
        {
            value: 'TypeScript',
            label: 'TypeScript',
        },
    ]
})" class="" x-on:keydown="highlightFirstMatchingOption($event.key)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="skills" class="">Skills(s)</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" role="combobox" class="" aria-haspopup="listbox" aria-controls="skillsList" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-label="setLabelText()" x-bind:aria-expanded="isOpen || openedWithKeyboard">
            <span class=""  x-text="setLabelText()"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- hidden input to grab the selected value  -->
        <input id="skills" name="skills" type="text" x-ref="hiddenTextField" hidden />
        <ul x-cloak x-show="isOpen || openedWithKeyboard" id="skillsList" class="" role="listbox" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
            <template x-for="(item, index) in options" x-bind:key="item.value">
                <!-- option  -->
                <li role="option">
                    <label class="" x-bind:for="'checkboxOption' + index">
                        <div class="">
                            <input type="checkbox" class="" x-on:change="handleOptionToggle($el)" x-on:keydown.enter.prevent="$el.checked = ! $el.checked; handleOptionToggle($el)" x-bind:value="item.value" x-bind:id="'checkboxOption' + index" />
                            <!-- Checkmark  -->
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="4" class="" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
                            </svg>
                        </div>
                        <span x-text="item.label"></span>
                    </label>
                </li>
            </template>
        </ul>
    </div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('combobox', (comboboxData = {
            options: [],
        },) => ({
            options: comboboxData.options,
            isOpen: false,
            openedWithKeyboard: false,
            selectedOptions: [],
            setLabelText() {
                const count = this.selectedOptions.length;

                // if there are no selected options
                if (count === 0) return 'Please Select';

                // if there is only one selected option
                return this.selectedOptions.join(', ');
            },
            highlightFirstMatchingOption(pressedKey) {
                // if Enter pressed, do nothing
                if (pressedKey === 'Enter') return

                // find and focus the option that starts with the pressed key
                const option = this.options.find((item) =>
                    item.label.toLowerCase().startsWith(pressedKey.toLowerCase()),
                )
                if (option) {
                    const index = this.options.indexOf(option)
                    const allOptions = document.querySelectorAll('.combobox-option')
                    if (allOptions[index]) {
                        allOptions[index].focus()
                    }
                }
            },
            handleOptionToggle(option) {
                if (option.checked) {
                    this.selectedOptions.push(option.value)
                } else {
                    // remove the unchecked option from the selectedOptions array
                    this.selectedOptions = this.selectedOptions.filter(
                        (opt) => opt !== option.value
                    )
                }
                // set the value of the hidden field to the selectedOptions array
                this.$refs.hiddenTextField.value = this.selectedOptions
            },
        }))
    })
</script>

Combobox with search

Requires Alpine JS Focus Plugin

A dropdown with a text input that allows users to filter the list of options.

HTML
<div x-data="{
        allOptions: [
            { 
                label: 'Acura', 
                value: 'Acura' 
            },
            { 
                label: 'Alfa Romeo',
                value: 'Alfa Romeo' 
            },
            { 
                label: 'Aston Martin',
                value: 'Aston Martin' 
            },
            { 
                label: 'Audi', 
                value: 'Audi' 
            },
            { 
                label: 'Bentley', 
                value: 'Bentley' 
            },
            { 
                label: 'BMW', 
                value: 'BMW' 
            },
            { 
                label: 'Bugatti', 
                value: 'Bugatti' 
            },
            { 
                label: 'Buick', 
                value: 'Buick' 
            },
            { 
                label: 'Cadillac', 
                value: 'Cadillac' 
            },
            { 
                label: 'Chevrolet', 
                value: 'Chevrolet' 
            },
            { 
                label: 'Chrysler', 
                value: 'Chrysler' 
            },
            { 
                label: 'Citroën', 
                value: 'Citroën' 
            },
            { 
                label: 'Dodge', 
                value: 'Dodge' 
            },
            { 
                label: 'Ferrari', 
                value: 'Ferrari' 
            },
            { 
                label: 'Fiat', 
                value: 'Fiat' 
            },
            { 
                label: 'Ford', 
                value: 'Ford' 
            },
            { 
                label: 'Genesis', 
                value: 'Genesis' 
            },
            { 
                label: 'GMC', 
                value: 'GMC' 
            },
            { 
                label: 'Honda', 
                value: 'Honda' 
            },
            { 
                label: 'Hyundai', 
                value: 'Hyundai' 
            },
            { 
                label: 'Infiniti', 
                value: 'Infiniti' 
            },
            { 
                label: 'Jaguar', 
                value: 'Jaguar' 
            },
            { 
                label: 'Jeep', 
                value: 'Jeep' 
            },
            { 
                label: 'Kia', 
                value: 'Kia' 
            },
            { 
                label: 'Lamborghini', 
                value: 'Lamborghini' 
            },
            { 
                label: 'Land Rover', 
                value: 'Land Rover' 
            },
            { 
                label: 'Lexus', 
                value: 'Lexus' 
            },
            { 
                label: 'Lincoln', 
                value: 'Lincoln' 
            },
            { 
                label: 'Maserati', 
                value: 'Maserati' 
            },
            { 
                label: 'Mazda', 
                value: 'Mazda' 
            },
            { 
                label: 'McLaren', 
                value: 'McLaren' 
            },
            { 
                label: 'Mercedes-Benz', 
                value: 'Mercedes-Benz' 
            },
            { 
                label: 'Mini', 
                value: 'Mini' 
            },
            { 
                label: 'Mitsubishi', 
                value: 'Mitsubishi' 
            },
            { 
                label: 'Nissan', 
                value: 'Nissan' 
            },
            { 
                label: 'Peugeot', 
                value: 'Peugeot' 
            },
            { 
                label: 'Porsche', 
                value: 'Porsche' 
            },
            { 
                label: 'Ram', 
                value: 'Ram' 
            },
            { 
                label: 'Renault', 
                value: 'Renault' 
            },
            { 
                label: 'Rolls-Royce', 
                value: 'Rolls-Royce' 
            },
            { 
                label: 'Subaru', 
                value: 'Subaru' 
            },
            { 
                label: 'Suzuki', 
                value: 'Suzuki' 
            },
            { 
                label: 'Tesla', 
                value: 'Tesla' 
            },
            { 
                label: 'Toyota', 
                value: 'Toyota' 
            },
            { 
                label: 'Volkswagen', 
                value: 'Volkswagen' 
            },
            { 
                label: 'Volvo', 
                value: 'Volvo' 
            },
        ],
        options: [],
        isOpen: false,
        openedWithKeyboard: false,
        selectedOption: null,
        setSelectedOption(option) {
            this.selectedOption = option
            this.isOpen = false
            this.openedWithKeyboard = false
            this.$refs.hiddenTextField.value = option.value
        },
        getFilteredOptions(query) {
            this.options = this.allOptions.filter((option) =>
                option.label.toLowerCase().includes(query.toLowerCase()),
            )
            if (this.options.length === 0) {
                this.$refs.noResultsMessage.classList.remove('hidden')
            } else {
                this.$refs.noResultsMessage.classList.add('hidden')
            }
        },
        handleKeydownOnOptions(event) {
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                this.$refs.searchField.focus()
            }
        },
    }" class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false" x-init="options = allOptions">
    <label for="make" class="">Make</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" class="" role="combobox" aria-controls="makesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" >
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"class="" aria-hidden="true">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- Hidden Input To Grab The Selected Value  -->
        <input id="make" name="make" x-ref="hiddenTextField" hidden=""/>
        <div x-show="isOpen || openedWithKeyboard" id="makesList" class="" role="listbox" aria-label="industries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">

            <!-- Search  -->
            <div class="">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true" >
                    <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                </svg>
                <input type="text" class="" name="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" x-ref="searchField" placeholder="Search" />
            </div>

            <!-- Options  -->
            <ul class="">
                <li class="" x-ref="noResultsMessage">
                    <span>No matches found</span>
                </li>
                <template x-for="(item, index) in options" x-bind:key="item.value">
                    <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                        <!-- Label  -->
                        <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                        <!-- Screen reader 'selected' indicator  -->
                        <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        <!-- Checkmark  -->
                        <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5">
                        </svg>
                    </li>
                </template>
            </ul>
        </div>
    </div>
</div>
<div x-data="combobox({
    allOptions: [
        { 
            label: 'Acura', 
            value: 'Acura' 
        },
        { 
            label: 'Alfa Romeo',
            value: 'Alfa Romeo' 
        },
        { 
            label: 'Aston Martin',
            value: 'Aston Martin' 
        },
        { 
            label: 'Audi', 
            value: 'Audi' 
        },
        { 
            label: 'Bentley', 
            value: 'Bentley' 
        },
        { 
            label: 'BMW', 
            value: 'BMW' 
        },
        { 
            label: 'Bugatti', 
            value: 'Bugatti' 
        },
        { 
            label: 'Buick', 
            value: 'Buick' 
        },
        { 
            label: 'Cadillac', 
            value: 'Cadillac' 
        },
        { 
            label: 'Chevrolet', 
            value: 'Chevrolet' 
        },
        { 
            label: 'Chrysler', 
            value: 'Chrysler' 
        },
        { 
            label: 'Citroën', 
            value: 'Citroën' 
        },
        { 
            label: 'Dodge', 
            value: 'Dodge' 
        },
        { 
            label: 'Ferrari', 
            value: 'Ferrari' 
        },
        { 
            label: 'Fiat', 
            value: 'Fiat' 
        },
        { 
            label: 'Ford', 
            value: 'Ford' 
        },
        { 
            label: 'Genesis', 
            value: 'Genesis' 
        },
        { 
            label: 'GMC', 
            value: 'GMC' 
        },
        { 
            label: 'Honda', 
            value: 'Honda' 
        },
        { 
            label: 'Hyundai', 
            value: 'Hyundai' 
        },
        { 
            label: 'Infiniti', 
            value: 'Infiniti' 
        },
        { 
            label: 'Jaguar', 
            value: 'Jaguar' 
        },
        { 
            label: 'Jeep', 
            value: 'Jeep' 
        },
        { 
            label: 'Kia', 
            value: 'Kia' 
        },
        { 
            label: 'Lamborghini', 
            value: 'Lamborghini' 
        },
        { 
            label: 'Land Rover', 
            value: 'Land Rover' 
        },
        { 
            label: 'Lexus', 
            value: 'Lexus' 
        },
        { 
            label: 'Lincoln', 
            value: 'Lincoln' 
        },
        { 
            label: 'Maserati', 
            value: 'Maserati' 
        },
        { 
            label: 'Mazda', 
            value: 'Mazda' 
        },
        { 
            label: 'McLaren', 
            value: 'McLaren' 
        },
        { 
            label: 'Mercedes-Benz', 
            value: 'Mercedes-Benz' 
        },
        { 
            label: 'Mini', 
            value: 'Mini' 
        },
        { 
            label: 'Mitsubishi', 
            value: 'Mitsubishi' 
        },
        { 
            label: 'Nissan', 
            value: 'Nissan' 
        },
        { 
            label: 'Peugeot', 
            value: 'Peugeot' 
        },
        { 
            label: 'Porsche', 
            value: 'Porsche' 
        },
        { 
            label: 'Ram', 
            value: 'Ram' 
        },
        { 
            label: 'Renault', 
            value: 'Renault' 
        },
        { 
            label: 'Rolls-Royce', 
            value: 'Rolls-Royce' 
        },
        { 
            label: 'Subaru', 
            value: 'Subaru' 
        },
        { 
            label: 'Suzuki', 
            value: 'Suzuki' 
        },
        { 
            label: 'Tesla', 
            value: 'Tesla' 
        },
        { 
            label: 'Toyota', 
            value: 'Toyota' 
        },
        { 
            label: 'Volkswagen', 
            value: 'Volkswagen' 
        },
        { 
            label: 'Volvo', 
            value: 'Volvo' 
        },
    ],
})" class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="make" class="">Make</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" class="" role="combobox" aria-controls="makesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" >
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"class="" aria-hidden="true">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- Hidden Input To Grab The Selected Value  -->
        <input id="make" name="make" x-ref="hiddenTextField" hidden=""/>
        <div x-show="isOpen || openedWithKeyboard" id="makesList" class="" role="listbox" aria-label="industries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">

            <!-- Search  -->
            <div class="">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true" >
                    <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                </svg>
                <input type="text" class="" name="searchField" x-ref="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" placeholder="Search" />
            </div>

            <!-- Options  -->
            <ul class="">
                <li class="" x-ref="noResultsMessage">
                    <span>No matches found</span>
                </li>
                <template x-for="(item, index) in options" x-bind:key="item.value">
                    <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                        <!-- Label  -->        
                        <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                        <!-- Screen reader 'selected' indicator  -->
                        <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        <!-- Checkmark  -->
                        <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5">
                        </svg>
                    </li>
                </template>
            </ul>
        </div>
    </div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('combobox', (comboboxData = {
            allOptions: [],
        },) => ({
            options: comboboxData.allOptions,
            isOpen: false,
            openedWithKeyboard: false,
            selectedOption: null,
            setSelectedOption(option) {
                this.selectedOption = option
                this.isOpen = false
                this.openedWithKeyboard = false
                this.$refs.hiddenTextField.value = option.value
            },
            getFilteredOptions(query) {
                this.options = comboboxData.allOptions.filter((option) =>
                    option.label.toLowerCase().includes(query.toLowerCase()),
                )
                if (this.options.length === 0) {
                    this.$refs.noResultsMessage.classList.remove('hidden')
                } else {
                    this.$refs.noResultsMessage.classList.add('hidden')
                }
            },
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            handleKeydownOnOptions(event) {
                if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                    this.$refs.searchField.focus()
                }
            },
        }))
    })
</script>
|| event.keyCode === 8

Country selector with flags and search

Requires Alpine JS Focus Plugin

A country selector dropdown with flags and a search field. This component uses flagpedia.net for the flags. The selected value will be stored in a hidden input field for easy retrieval.

HTML
<div x-data="{
        allOptions: [
            { label: 'Afghanistan', value: 'Afghanistan', iso: 'af' },
            { label: 'Albania', value: 'Albania', iso: 'al' },
            { label: 'Algeria', value: 'Algeria', iso: 'dz' },
            { label: 'Andorra', value: 'Andorra', iso: 'ad' },
            { label: 'Angola', value: 'Angola', iso: 'ao' },
            { label: 'Anguilla', value: 'Anguilla', iso: 'ai' },
            { label: 'Antigua and Barbuda', value: 'Antigua and Barbuda', iso: 'ag' },
            { label: 'Argentina', value: 'Argentina', iso: 'ar' },
            { label: 'Armenia', value: 'Armenia', iso: 'am' },
            { label: 'Aruba', value: 'Aruba', iso: 'aw' },
            { label: 'Australia', value: 'Australia', iso: 'au' },
            { label: 'Austria', value: 'Austria', iso: 'at' },
            { label: 'Azerbaijan', value: 'Azerbaijan', iso: 'az' },
            { label: 'Bahamas', value: 'Bahamas', iso: 'bs' },
            { label: 'Bahrain', value: 'Bahrain', iso: 'bh' },
            { label: 'Bangladesh', value: 'Bangladesh', iso: 'bd' },
            { label: 'Barbados', value: 'Barbados', iso: 'bb' },
            { label: 'Belarus', value: 'Belarus', iso: 'by' },
            { label: 'Belgium', value: 'Belgium', iso: 'be' },
            { label: 'Belize', value: 'Belize', iso: 'bz' },
            { label: 'Benin', value: 'Benin', iso: 'bj' },
            { label: 'Bermuda', value: 'Bermuda', iso: 'bm' },
            { label: 'Bhutan', value: 'Bhutan', iso: 'bt' },
            { label: 'Bolivia', value: 'Bolivia', iso: 'bo' },
            { label: 'Bosnia and Herzegovina', value: 'Bosnia and Herzegovina', iso: 'ba' },
            { label: 'Botswana', value: 'Botswana', iso: 'bw' },
            { label: 'Brazil', value: 'Brazil', iso: 'br' },
            { label: 'British Indian Ocean Territory', value: 'British Indian Ocean Territory', iso: 'io' },
            { label: 'British Virgin Islands', value: 'British Virgin Islands', iso: 'vg' },
            { label: 'Brunei', value: 'Brunei', iso: 'bn' },
            { label: 'Bulgaria', value: 'Bulgaria', iso: 'bg' },
            { label: 'Burkina Faso', value: 'Burkina Faso', iso: 'bf' },
            { label: 'Burundi', value: 'Burundi', iso: 'bi' },
            { label: 'Cambodia', value: 'Cambodia', iso: 'kh' },
            { label: 'Cameroon', value: 'Cameroon', iso: 'cm' },
            { label: 'Canada', value: 'Canada', iso: 'ca' },
            { label: 'Cape Verde', value: 'Cape Verde', iso: 'cv' },
            { label: 'Cayman Islands', value: 'Cayman Islands', iso: 'ky' },
            { label: 'Central African Republic', value: 'Central African Republic', iso: 'cf' },
            { label: 'Chad', value: 'Chad', iso: 'td' },
            { label: 'Chile', value: 'Chile', iso: 'cl' },
            { label: 'China', value: 'China', iso: 'cn' },
            { label: 'Colombia', value: 'Colombia', iso: 'co' },
            { label: 'Comoros', value: 'Comoros', iso: 'km' },
            { label: 'Congo (Brazzaville)', value: 'Congo (Brazzaville)', iso: 'cg' },
            { label: 'Congo (Kinshasa)', value: 'Congo (Kinshasa)', iso: 'cd' },
            { label: 'Cook Islands', value: 'Cook Islands', iso: 'ck' },
            { label: 'Costa Rica', value: 'Costa Rica', iso: 'cr' },
            { label: 'Croatia', value: 'Croatia', iso: 'hr' },
            { label: 'Cuba', value: 'Cuba', iso: 'cu' },
            { label: 'Curaçao', value: 'Curaçao', iso: 'cw' },
            { label: 'Cyprus', value: 'Cyprus', iso: 'cy' },
            { label: 'Czechia', value: 'Czechia', iso: 'cz' },
            { label: 'Denmark', value: 'Denmark', iso: 'dk' },
            { label: 'Djibouti', value: 'Djibouti', iso: 'dj' },
            { label: 'Dominica', value: 'Dominica', iso: 'dm' },
            { label: 'Dominican Republic', value: 'Dominican Republic', iso: 'do' },
            { label: 'Ecuador', value: 'Ecuador', iso: 'ec' },
            { label: 'Egypt', value: 'Egypt', iso: 'eg' },
            { label: 'El Salvador', value: 'El Salvador', iso: 'sv' },
            { label: 'England', value: 'England', iso: 'gb-eng' },
            { label: 'Equatorial Guinea', value: 'Equatorial Guinea', iso: 'gq' },
            { label: 'Eritrea', value: 'Eritrea', iso: 'er' },
            { label: 'Estonia', value: 'Estonia', iso: 'ee' },
            { label: 'Eswatini (Swaziland)', value: 'Eswatini (Swaziland)', iso: 'sz' },
            { label: 'Ethiopia', value: 'Ethiopia', iso: 'et' },
            { label: 'Falkland Islands (Islas Malvinas)', value: 'Falkland Islands (Islas Malvinas)', iso: 'fk' },
            { label: 'Faroe Islands', value: 'Faroe Islands', iso: 'fo' },
            { label: 'Fiji', value: 'Fiji', iso: 'fj' },
            { label: 'Finland', value: 'Finland', iso: 'fi' },
            { label: 'France', value: 'France', iso: 'fr' },
            { label: 'French Guiana', value: 'French Guiana', iso: 'gf' },
            { label: 'French Polynesia', value: 'French Polynesia', iso: 'pf' },
            { label: 'French Southern and Antarctic Lands', value: 'French Southern and Antarctic Lands', iso: 'tf' },
            { label: 'Gabon', value: 'Gabon', iso: 'ga' },
            { label: 'Gambia', value: 'Gambia', iso: 'gm' },
            { label: 'Georgia', value: 'Georgia', iso: 'ge' },
            { label: 'Germany', value: 'Germany', iso: 'de' },
            { label: 'Ghana', value: 'Ghana', iso: 'gh' },
            { label: 'Gibraltar', value: 'Gibraltar', iso: 'gi' },
            { label: 'Greece', value: 'Greece', iso: 'gr' },
            { label: 'Greenland', value: 'Greenland', iso: 'gl' },
            { label: 'Grenada', value: 'Grenada', iso: 'gd' },
            { label: 'Guadeloupe', value: 'Guadeloupe', iso: 'gp' },
            { label: 'Guam', value: 'Guam', iso: 'gu' },
            { label: 'Guatemala', value: 'Guatemala', iso: 'gt' },
            { label: 'Guernsey', value: 'Guernsey', iso: 'gg' },
            { label: 'Guinea', value: 'Guinea', iso: 'gn' },
            { label: 'Guinea-Bissau', value: 'Guinea-Bissau', iso: 'gw' },
            { label: 'Guyana', value: 'Guyana', iso: 'gy' },
            { label: 'Haiti', value: 'Haiti', iso: 'ht' },
            { label: 'Honduras', value: 'Honduras', iso: 'hn' },
            { label: 'Hong Kong', value: 'Hong Kong', iso: 'hk' },
            { label: 'Hungary', value: 'Hungary', iso: 'hu' },
            { label: 'Iceland', value: 'Iceland', iso: 'is' },
            { label: 'India', value: 'India', iso: 'in' },
            { label: 'Indonesia', value: 'Indonesia', iso: 'id' },
            { label: 'Iran', value: 'Iran', iso: 'ir' },
            { label: 'Iraq', value: 'Iraq', iso: 'iq' },
            { label: 'Ireland', value: 'Ireland', iso: 'ie' },
            { label: 'Isle of Man', value: 'Isle of Man', iso: 'im' },
            { label: 'Israel', value: 'Israel', iso: 'il' },
            { label: 'Italy', value: 'Italy', iso: 'it' },
            { label: 'Ivory Coast', value: 'Ivory Coast', iso: 'ci' },
            { label: 'Jamaica', value: 'Jamaica', iso: 'jm' },
            { label: 'Japan', value: 'Japan', iso: 'jp' },
            { label: 'Jersey', value: 'Jersey', iso: 'je' },
            { label: 'Jordan', value: 'Jordan', iso: 'jo' },
            { label: 'Kazakhstan', value: 'Kazakhstan', iso: 'kz' },
            { label: 'Kenya', value: 'Kenya', iso: 'ke' },
            { label: 'Kiribati', value: 'Kiribati', iso: 'ki' },
            { label: 'Kosovo', value: 'Kosovo', iso: 'xk' },
            { label: 'Kuwait', value: 'Kuwait', iso: 'kw' },
            { label: 'Kyrgyzstan', value: 'Kyrgyzstan', iso: 'kg' },
            { label: 'Laos', value: 'Laos', iso: 'la' },
            { label: 'Latvia', value: 'Latvia', iso: 'lv' },
            { label: 'Lebanon', value: 'Lebanon', iso: 'lb' },
            { label: 'Lesotho', value: 'Lesotho', iso: 'ls' },
            { label: 'Liberia', value: 'Liberia', iso: 'lr' },
            { label: 'Libya', value: 'Libya', iso: 'ly' },
            { label: 'Liechtenstein', value: 'Liechtenstein', iso: 'li' },
            { label: 'Lithuania', value: 'Lithuania', iso: 'lt' },
            { label: 'Luxembourg', value: 'Luxembourg', iso: 'lu' },
            { label: 'Macao', value: 'Macao', iso: 'mo' },
            { label: 'Madagascar', value: 'Madagascar', iso: 'mg' },
            { label: 'Malawi', value: 'Malawi', iso: 'mw' },
            { label: 'Malaysia', value: 'Malaysia', iso: 'my' },
            { label: 'Maldives', value: 'Maldives', iso: 'mv' },
            { label: 'Mali', value: 'Mali', iso: 'ml' },
            { label: 'Malta', value: 'Malta', iso: 'mt' },
            { label: 'Marshall Islands', value: 'Marshall Islands', iso: 'mh' },
            { label: 'Martinique', value: 'Martinique', iso: 'mq' },
            { label: 'Mauritania', value: 'Mauritania', iso: 'mr' },
            { label: 'Mauritius', value: 'Mauritius', iso: 'mu' },
            { label: 'Mayotte', value: 'Mayotte', iso: 'yt' },
            { label: 'Mexico', value: 'Mexico', iso: 'mx' },
            { label: 'Micronesia', value: 'Micronesia', iso: 'fm' },
            { label: 'Moldova', value: 'Moldova', iso: 'md' },
            { label: 'Monaco', value: 'Monaco', iso: 'mc' },
            { label: 'Mongolia', value: 'Mongolia', iso: 'mn' },
            { label: 'Montenegro', value: 'Montenegro', iso: 'me' },
            { label: 'Montserrat', value: 'Montserrat', iso: 'ms' },
            { label: 'Morocco', value: 'Morocco', iso: 'ma' },
            { label: 'Mozambique', value: 'Mozambique', iso: 'mz' },
            { label: 'Myanmar (Burma)', value: 'Myanmar (Burma)', iso: 'mm' },
            { label: 'Namibia', value: 'Namibia', iso: 'na' },
            { label: 'Nauru', value: 'Nauru', iso: 'nr' },
            { label: 'Nepal', value: 'Nepal', iso: 'np' },
            { label: 'Netherlands', value: 'Netherlands', iso: 'nl' },
            { label: 'New Caledonia', value: 'New Caledonia', iso: 'nc' },
            { label: 'New Zealand', value: 'New Zealand', iso: 'nz' },
            { label: 'Nicaragua', value: 'Nicaragua', iso: 'ni' },
            { label: 'Niger', value: 'Niger', iso: 'ne' },
            { label: 'Nigeria', value: 'Nigeria', iso: 'ng' },
            { label: 'Niue', value: 'Niue', iso: 'nu' },
            { label: 'Norfolk Island', value: 'Norfolk Island', iso: 'nf' },
            { label: 'North Korea', value: 'North Korea', iso: 'kp' },
            { label: 'North Macedonia', value: 'North Macedonia', iso: 'mk' },
            { label: 'Northern Ireland', value: 'Northern Ireland', iso: 'gb-nir' },
            { label: 'Northern Mariana Islands', value: 'Northern Mariana Islands', iso: 'mp' },
            { label: 'Norway', value: 'Norway', iso: 'no' },
            { label: 'Oman', value: 'Oman', iso: 'om' },
            { label: 'Pakistan', value: 'Pakistan', iso: 'pk' },
            { label: 'Palau', value: 'Palau', iso: 'pw' },
            { label: 'Palestine', value: 'Palestine', iso: 'ps' },
            { label: 'Panama', value: 'Panama', iso: 'pa' },
            { label: 'Papua New Guinea', value: 'Papua New Guinea', iso: 'pg' },
            { label: 'Paraguay', value: 'Paraguay', iso: 'py' },
            { label: 'Peru', value: 'Peru', iso: 'pe' },
            { label: 'Philippines', value: 'Philippines', iso: 'ph' },
            { label: 'Pitcairn Islands', value: 'Pitcairn Islands', iso: 'pn' },
            { label: 'Poland', value: 'Poland', iso: 'pl' },
            { label: 'Portugal', value: 'Portugal', iso: 'pt' },
            { label: 'Puerto Rico', value: 'Puerto Rico', iso: 'pr' },
            { label: 'Qatar', value: 'Qatar', iso: 'qa' },
            { label: 'Romania', value: 'Romania', iso: 'ro' },
            { label: 'Russia', value: 'Russia', iso: 'ru' },
            { label: 'Rwanda', value: 'Rwanda', iso: 'rw' },
            { label: 'Saint Helena, Ascension and Tristan da Cunha', value: 'Saint Helena, Ascension and Tristan da Cunha', iso: 'sh' },
            { label: 'Saint Kitts and Nevis', value: 'Saint Kitts and Nevis', iso: 'kn' },
            { label: 'Saint Lucia', value: 'Saint Lucia', iso: 'lc' },
            { label: 'Saint Pierre and Miquelon', value: 'Saint Pierre and Miquelon', iso: 'pm' },
            { label: 'Saint Vincent and the Grenadines', value: 'Saint Vincent and the Grenadines', iso: 'vc' },
            { label: 'Samoa', value: 'Samoa', iso: 'ws' },
            { label: 'San Marino', value: 'San Marino', iso: 'sm' },
            { label: 'Sao Tome and Principe', value: 'Sao Tome and Principe', iso: 'st' },
            { label: 'Saudi Arabia', value: 'Saudi Arabia', iso: 'sa' },
            { label: 'Scotland', value: 'Scotland', iso: 'gb-sct' },
            { label: 'Senegal', value: 'Senegal', iso: 'sn' },
            { label: 'Serbia', value: 'Serbia', iso: 'rs' },
            { label: 'Seychelles', value: 'Seychelles', iso: 'sc' },
            { label: 'Sierra Leone', value: 'Sierra Leone', iso: 'sl' },
            { label: 'Singapore', value: 'Singapore', iso: 'sg' },
            { label: 'Sint Maarten', value: 'Sint Maarten', iso: 'sx' },
            { label: 'Slovakia', value: 'Slovakia', iso: 'sk' },
            { label: 'Slovenia', value: 'Slovenia', iso: 'si' },
            { label: 'Solomon Islands', value: 'Solomon Islands', iso: 'sb' },
            { label: 'Somalia', value: 'Somalia', iso: 'so' },
            { label: 'South Africa', value: 'South Africa', iso: 'za' },
            { label: 'South Korea', value: 'South Korea', iso: 'kr' },
            { label: 'South Sudan', value: 'South Sudan', iso: 'ss' },
            { label: 'Spain', value: 'Spain', iso: 'es' },
            { label: 'Sri Lanka', value: 'Sri Lanka', iso: 'lk' },
            { label: 'Sudan', value: 'Sudan', iso: 'sd' },
            { label: 'Suriname', value: 'Suriname', iso: 'sr' },
            { label: 'Svalbard and Jan Mayen', value: 'Svalbard and Jan Mayen', iso: 'sj' },
            { label: 'Sweden', value: 'Sweden', iso: 'se' },
            { label: 'Switzerland', value: 'Switzerland', iso: 'ch' },
            { label: 'Syria', value: 'Syria', iso: 'sy' },
            { label: 'Taiwan', value: 'Taiwan', iso: 'tw' },
            { label: 'Tajikistan', value: 'Tajikistan', iso: 'tj' },
            { label: 'Tanzania', value: 'Tanzania', iso: 'tz' },
            { label: 'Thailand', value: 'Thailand', iso: 'th' },
            { label: 'Timor-Leste', value: 'Timor-Leste', iso: 'tl' },
            { label: 'Togo', value: 'Togo', iso: 'tg' },
            { label: 'Tokelau', value: 'Tokelau', iso: 'tk' },
            { label: 'Tonga', value: 'Tonga', iso: 'to' },
            { label: 'Trinidad and Tobago', value: 'Trinidad and Tobago', iso: 'tt' },
            { label: 'Tunisia', value: 'Tunisia', iso: 'tn' },
            { label: 'Turkey', value: 'Turkey', iso: 'tr' },
            { label: 'Turkmenistan', value: 'Turkmenistan', iso: 'tm' },
            { label: 'Turks and Caicos Islands', value: 'Turks and Caicos Islands', iso: 'tc' },
            { label: 'Tuvalu', value: 'Tuvalu', iso: 'tv' },
            { label: 'Uganda', value: 'Uganda', iso: 'ug' },
            { label: 'Ukraine', value: 'Ukraine', iso: 'ua' },
            { label: 'United Arab Emirates', value: 'United Arab Emirates', iso: 'ae' },
            { label: 'United Kingdom', value: 'United Kingdom', iso: 'gb' },
            { label: 'United States of America', value: 'United States of America', iso: 'us' },
            { label: 'Uruguay', value: 'Uruguay', iso: 'uy' },
            { label: 'Uzbekistan', value: 'Uzbekistan', iso: 'uz' },
            { label: 'Vanuatu', value: 'Vanuatu', iso: 'vu' },
            { label: 'Vatican City (Holy See)', value: 'Vatican City (Holy See)', iso: 'va' },
            { label: 'Venezuela', value: 'Venezuela', iso: 've' },
            { label: 'Vietnam', value: 'Vietnam', iso: 'vn' },
            { label: 'Wales', value: 'Wales', iso: 'gb-wls' },
            { label: 'Western Sahara', value: 'Western Sahara', iso: 'eh' },
            { label: 'Yemen', value: 'Yemen', iso: 'ye' },
            { label: 'Zambia', value: 'Zambia', iso: 'zm' },
            { label: 'Zimbabwe', value: 'Zimbabwe', iso: 'zw' },
        ],
        options: [],
        isOpen: false,
        openedWithKeyboard: false,
        selectedOption: null,
        setSelectedOption(option) {
            this.selectedOption = option
            this.isOpen = false
            this.openedWithKeyboard = false
            this.$refs.hiddenTextField.value = option.value
        },
        getFilteredOptions(query) {
            this.options = this.allOptions.filter((option) =>
                option.label.toLowerCase().includes(query.toLowerCase()),
            )
            if (this.options.length === 0) {
                this.$refs.noResultsMessage.classList.remove('hidden')
            } else {
                this.$refs.noResultsMessage.classList.add('hidden')
            }
        },
        handleKeydownOnOptions(event) {
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                this.$refs.searchField.focus()
            }
        },
    }" class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false" x-init="options = allOptions">
    <label for="country" class="">Country</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" class="" role="combobox" aria-controls="countriesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" >
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"class="" aria-hidden="true">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- Hidden Input To Grab The Selected Value  -->
        <input id="country" name="country" autocomplete="off" x-ref="hiddenTextField" hidden=""/>
        <div x-show="isOpen || openedWithKeyboard" id="countriesList" class="" role="listbox" aria-label="countries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">

            <!-- Search  -->
            <div class="">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true" >
                    <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                </svg>
                <input type="text" class="" name="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" x-ref="searchField" placeholder="Search" />
            </div>

            <!-- Options  -->
            <ul class="">
                <li class="" x-ref="noResultsMessage">
                    <span>No matches found</span>
                </li>
                <template x-for="(item, index) in options" x-bind:key="item.value">
                    <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                        <div class="">
                            <!-- Country name  -->
                            <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                            <!-- Screen reader 'selected' indicator  -->
                            <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        </div>
                        <!-- Checkmark  -->
                        <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5">
                        </svg>
                    </li>
                </template>
            </ul>
        </div>
    </div>
</div>
<div x-data="combobox" class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="country" class="">Country</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" class="" role="combobox" aria-controls="countriesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" >
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"class="" aria-hidden="true">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- Hidden Input To Grab The Selected Value  -->
        <input id="country" name="country" autocomplete="off" x-ref="hiddenTextField" hidden=""/>
        <div x-show="isOpen || openedWithKeyboard" id="countriesList" class="" role="listbox" aria-label="countries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">

            <!-- Search  -->
            <div class="">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true" >
                    <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                </svg>
                <input type="text" class="" name="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" x-ref="searchField" placeholder="Search" />
            </div>

            <!-- Options  -->
            <ul class="">
                <li class="" x-ref="noResultsMessage">
                    <span>No matches found</span>
                </li>
                <template x-for="(item, index) in options" x-bind:key="item.value">
                    <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                        <div class="">
                            <!-- Country name  -->
                            <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                            <!-- Screen reader 'selected' indicator  -->
                            <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        </div>
                        <!-- Checkmark  -->
                        <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5">
                        </svg>
                    </li>
                </template>
            </ul>
        </div>
    </div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('combobox', (comboboxData = {
            allOptions: [
                { label: 'Afghanistan', value: 'Afghanistan', iso: 'af' },
                { label: 'Albania', value: 'Albania', iso: 'al' },
                { label: 'Algeria', value: 'Algeria', iso: 'dz' },
                { label: 'Andorra', value: 'Andorra', iso: 'ad' },
                { label: 'Angola', value: 'Angola', iso: 'ao' },
                { label: 'Anguilla', value: 'Anguilla', iso: 'ai' },
                { label: 'Antigua and Barbuda', value: 'Antigua and Barbuda', iso: 'ag' },
                { label: 'Argentina', value: 'Argentina', iso: 'ar' },
                { label: 'Armenia', value: 'Armenia', iso: 'am' },
                { label: 'Aruba', value: 'Aruba', iso: 'aw' },
                { label: 'Australia', value: 'Australia', iso: 'au' },
                { label: 'Austria', value: 'Austria', iso: 'at' },
                { label: 'Azerbaijan', value: 'Azerbaijan', iso: 'az' },
                { label: 'Bahamas', value: 'Bahamas', iso: 'bs' },
                { label: 'Bahrain', value: 'Bahrain', iso: 'bh' },
                { label: 'Bangladesh', value: 'Bangladesh', iso: 'bd' },
                { label: 'Barbados', value: 'Barbados', iso: 'bb' },
                { label: 'Belarus', value: 'Belarus', iso: 'by' },
                { label: 'Belgium', value: 'Belgium', iso: 'be' },
                { label: 'Belize', value: 'Belize', iso: 'bz' },
                { label: 'Benin', value: 'Benin', iso: 'bj' },
                { label: 'Bermuda', value: 'Bermuda', iso: 'bm' },
                { label: 'Bhutan', value: 'Bhutan', iso: 'bt' },
                { label: 'Bolivia', value: 'Bolivia', iso: 'bo' },
                { label: 'Bosnia and Herzegovina', value: 'Bosnia and Herzegovina', iso: 'ba' },
                { label: 'Botswana', value: 'Botswana', iso: 'bw' },
                { label: 'Brazil', value: 'Brazil', iso: 'br' },
                { label: 'British Indian Ocean Territory', value: 'British Indian Ocean Territory', iso: 'io' },
                { label: 'British Virgin Islands', value: 'British Virgin Islands', iso: 'vg' },
                { label: 'Brunei', value: 'Brunei', iso: 'bn' },
                { label: 'Bulgaria', value: 'Bulgaria', iso: 'bg' },
                { label: 'Burkina Faso', value: 'Burkina Faso', iso: 'bf' },
                { label: 'Burundi', value: 'Burundi', iso: 'bi' },
                { label: 'Cambodia', value: 'Cambodia', iso: 'kh' },
                { label: 'Cameroon', value: 'Cameroon', iso: 'cm' },
                { label: 'Canada', value: 'Canada', iso: 'ca' },
                { label: 'Cape Verde', value: 'Cape Verde', iso: 'cv' },
                { label: 'Cayman Islands', value: 'Cayman Islands', iso: 'ky' },
                { label: 'Central African Republic', value: 'Central African Republic', iso: 'cf' },
                { label: 'Chad', value: 'Chad', iso: 'td' },
                { label: 'Chile', value: 'Chile', iso: 'cl' },
                { label: 'China', value: 'China', iso: 'cn' },
                { label: 'Colombia', value: 'Colombia', iso: 'co' },
                { label: 'Comoros', value: 'Comoros', iso: 'km' },
                { label: 'Congo (Brazzaville)', value: 'Congo (Brazzaville)', iso: 'cg' },
                { label: 'Congo (Kinshasa)', value: 'Congo (Kinshasa)', iso: 'cd' },
                { label: 'Cook Islands', value: 'Cook Islands', iso: 'ck' },
                { label: 'Costa Rica', value: 'Costa Rica', iso: 'cr' },
                { label: 'Croatia', value: 'Croatia', iso: 'hr' },
                { label: 'Cuba', value: 'Cuba', iso: 'cu' },
                { label: 'Curaçao', value: 'Curaçao', iso: 'cw' },
                { label: 'Cyprus', value: 'Cyprus', iso: 'cy' },
                { label: 'Czechia', value: 'Czechia', iso: 'cz' },
                { label: 'Denmark', value: 'Denmark', iso: 'dk' },
                { label: 'Djibouti', value: 'Djibouti', iso: 'dj' },
                { label: 'Dominica', value: 'Dominica', iso: 'dm' },
                { label: 'Dominican Republic', value: 'Dominican Republic', iso: 'do' },
                { label: 'Ecuador', value: 'Ecuador', iso: 'ec' },
                { label: 'Egypt', value: 'Egypt', iso: 'eg' },
                { label: 'El Salvador', value: 'El Salvador', iso: 'sv' },
                { label: 'England', value: 'England', iso: 'gb-eng' },
                { label: 'Equatorial Guinea', value: 'Equatorial Guinea', iso: 'gq' },
                { label: 'Eritrea', value: 'Eritrea', iso: 'er' },
                { label: 'Estonia', value: 'Estonia', iso: 'ee' },
                { label: 'Eswatini (Swaziland)', value: 'Eswatini (Swaziland)', iso: 'sz' },
                { label: 'Ethiopia', value: 'Ethiopia', iso: 'et' },
                { label: 'Falkland Islands (Islas Malvinas)', value: 'Falkland Islands (Islas Malvinas)', iso: 'fk' },
                { label: 'Faroe Islands', value: 'Faroe Islands', iso: 'fo' },
                { label: 'Fiji', value: 'Fiji', iso: 'fj' },
                { label: 'Finland', value: 'Finland', iso: 'fi' },
                { label: 'France', value: 'France', iso: 'fr' },
                { label: 'French Guiana', value: 'French Guiana', iso: 'gf' },
                { label: 'French Polynesia', value: 'French Polynesia', iso: 'pf' },
                { label: 'French Southern and Antarctic Lands', value: 'French Southern and Antarctic Lands', iso: 'tf' },
                { label: 'Gabon', value: 'Gabon', iso: 'ga' },
                { label: 'Gambia', value: 'Gambia', iso: 'gm' },
                { label: 'Georgia', value: 'Georgia', iso: 'ge' },
                { label: 'Germany', value: 'Germany', iso: 'de' },
                { label: 'Ghana', value: 'Ghana', iso: 'gh' },
                { label: 'Gibraltar', value: 'Gibraltar', iso: 'gi' },
                { label: 'Greece', value: 'Greece', iso: 'gr' },
                { label: 'Greenland', value: 'Greenland', iso: 'gl' },
                { label: 'Grenada', value: 'Grenada', iso: 'gd' },
                { label: 'Guadeloupe', value: 'Guadeloupe', iso: 'gp' },
                { label: 'Guam', value: 'Guam', iso: 'gu' },
                { label: 'Guatemala', value: 'Guatemala', iso: 'gt' },
                { label: 'Guernsey', value: 'Guernsey', iso: 'gg' },
                { label: 'Guinea', value: 'Guinea', iso: 'gn' },
                { label: 'Guinea-Bissau', value: 'Guinea-Bissau', iso: 'gw' },
                { label: 'Guyana', value: 'Guyana', iso: 'gy' },
                { label: 'Haiti', value: 'Haiti', iso: 'ht' },
                { label: 'Honduras', value: 'Honduras', iso: 'hn' },
                { label: 'Hong Kong', value: 'Hong Kong', iso: 'hk' },
                { label: 'Hungary', value: 'Hungary', iso: 'hu' },
                { label: 'Iceland', value: 'Iceland', iso: 'is' },
                { label: 'India', value: 'India', iso: 'in' },
                { label: 'Indonesia', value: 'Indonesia', iso: 'id' },
                { label: 'Iran', value: 'Iran', iso: 'ir' },
                { label: 'Iraq', value: 'Iraq', iso: 'iq' },
                { label: 'Ireland', value: 'Ireland', iso: 'ie' },
                { label: 'Isle of Man', value: 'Isle of Man', iso: 'im' },
                { label: 'Israel', value: 'Israel', iso: 'il' },
                { label: 'Italy', value: 'Italy', iso: 'it' },
                { label: 'Ivory Coast', value: 'Ivory Coast', iso: 'ci' },
                { label: 'Jamaica', value: 'Jamaica', iso: 'jm' },
                { label: 'Japan', value: 'Japan', iso: 'jp' },
                { label: 'Jersey', value: 'Jersey', iso: 'je' },
                { label: 'Jordan', value: 'Jordan', iso: 'jo' },
                { label: 'Kazakhstan', value: 'Kazakhstan', iso: 'kz' },
                { label: 'Kenya', value: 'Kenya', iso: 'ke' },
                { label: 'Kiribati', value: 'Kiribati', iso: 'ki' },
                { label: 'Kosovo', value: 'Kosovo', iso: 'xk' },
                { label: 'Kuwait', value: 'Kuwait', iso: 'kw' },
                { label: 'Kyrgyzstan', value: 'Kyrgyzstan', iso: 'kg' },
                { label: 'Laos', value: 'Laos', iso: 'la' },
                { label: 'Latvia', value: 'Latvia', iso: 'lv' },
                { label: 'Lebanon', value: 'Lebanon', iso: 'lb' },
                { label: 'Lesotho', value: 'Lesotho', iso: 'ls' },
                { label: 'Liberia', value: 'Liberia', iso: 'lr' },
                { label: 'Libya', value: 'Libya', iso: 'ly' },
                { label: 'Liechtenstein', value: 'Liechtenstein', iso: 'li' },
                { label: 'Lithuania', value: 'Lithuania', iso: 'lt' },
                { label: 'Luxembourg', value: 'Luxembourg', iso: 'lu' },
                { label: 'Macao', value: 'Macao', iso: 'mo' },
                { label: 'Madagascar', value: 'Madagascar', iso: 'mg' },
                { label: 'Malawi', value: 'Malawi', iso: 'mw' },
                { label: 'Malaysia', value: 'Malaysia', iso: 'my' },
                { label: 'Maldives', value: 'Maldives', iso: 'mv' },
                { label: 'Mali', value: 'Mali', iso: 'ml' },
                { label: 'Malta', value: 'Malta', iso: 'mt' },
                { label: 'Marshall Islands', value: 'Marshall Islands', iso: 'mh' },
                { label: 'Martinique', value: 'Martinique', iso: 'mq' },
                { label: 'Mauritania', value: 'Mauritania', iso: 'mr' },
                { label: 'Mauritius', value: 'Mauritius', iso: 'mu' },
                { label: 'Mayotte', value: 'Mayotte', iso: 'yt' },
                { label: 'Mexico', value: 'Mexico', iso: 'mx' },
                { label: 'Micronesia', value: 'Micronesia', iso: 'fm' },
                { label: 'Moldova', value: 'Moldova', iso: 'md' },
                { label: 'Monaco', value: 'Monaco', iso: 'mc' },
                { label: 'Mongolia', value: 'Mongolia', iso: 'mn' },
                { label: 'Montenegro', value: 'Montenegro', iso: 'me' },
                { label: 'Montserrat', value: 'Montserrat', iso: 'ms' },
                { label: 'Morocco', value: 'Morocco', iso: 'ma' },
                { label: 'Mozambique', value: 'Mozambique', iso: 'mz' },
                { label: 'Myanmar (Burma)', value: 'Myanmar (Burma)', iso: 'mm' },
                { label: 'Namibia', value: 'Namibia', iso: 'na' },
                { label: 'Nauru', value: 'Nauru', iso: 'nr' },
                { label: 'Nepal', value: 'Nepal', iso: 'np' },
                { label: 'Netherlands', value: 'Netherlands', iso: 'nl' },
                { label: 'New Caledonia', value: 'New Caledonia', iso: 'nc' },
                { label: 'New Zealand', value: 'New Zealand', iso: 'nz' },
                { label: 'Nicaragua', value: 'Nicaragua', iso: 'ni' },
                { label: 'Niger', value: 'Niger', iso: 'ne' },
                { label: 'Nigeria', value: 'Nigeria', iso: 'ng' },
                { label: 'Niue', value: 'Niue', iso: 'nu' },
                { label: 'Norfolk Island', value: 'Norfolk Island', iso: 'nf' },
                { label: 'North Korea', value: 'North Korea', iso: 'kp' },
                { label: 'North Macedonia', value: 'North Macedonia', iso: 'mk' },
                { label: 'Northern Ireland', value: 'Northern Ireland', iso: 'gb-nir' },
                { label: 'Northern Mariana Islands', value: 'Northern Mariana Islands', iso: 'mp' },
                { label: 'Norway', value: 'Norway', iso: 'no' },
                { label: 'Oman', value: 'Oman', iso: 'om' },
                { label: 'Pakistan', value: 'Pakistan', iso: 'pk' },
                { label: 'Palau', value: 'Palau', iso: 'pw' },
                { label: 'Palestine', value: 'Palestine', iso: 'ps' },
                { label: 'Panama', value: 'Panama', iso: 'pa' },
                { label: 'Papua New Guinea', value: 'Papua New Guinea', iso: 'pg' },
                { label: 'Paraguay', value: 'Paraguay', iso: 'py' },
                { label: 'Peru', value: 'Peru', iso: 'pe' },
                { label: 'Philippines', value: 'Philippines', iso: 'ph' },
                { label: 'Pitcairn Islands', value: 'Pitcairn Islands', iso: 'pn' },
                { label: 'Poland', value: 'Poland', iso: 'pl' },
                { label: 'Portugal', value: 'Portugal', iso: 'pt' },
                { label: 'Puerto Rico', value: 'Puerto Rico', iso: 'pr' },
                { label: 'Qatar', value: 'Qatar', iso: 'qa' },
                { label: 'Romania', value: 'Romania', iso: 'ro' },
                { label: 'Russia', value: 'Russia', iso: 'ru' },
                { label: 'Rwanda', value: 'Rwanda', iso: 'rw' },
                { label: 'Saint Helena, Ascension and Tristan da Cunha', value: 'Saint Helena, Ascension and Tristan da Cunha', iso: 'sh' },
                { label: 'Saint Kitts and Nevis', value: 'Saint Kitts and Nevis', iso: 'kn' },
                { label: 'Saint Lucia', value: 'Saint Lucia', iso: 'lc' },
                { label: 'Saint Pierre and Miquelon', value: 'Saint Pierre and Miquelon', iso: 'pm' },
                { label: 'Saint Vincent and the Grenadines', value: 'Saint Vincent and the Grenadines', iso: 'vc' },
                { label: 'Samoa', value: 'Samoa', iso: 'ws' },
                { label: 'San Marino', value: 'San Marino', iso: 'sm' },
                { label: 'Sao Tome and Principe', value: 'Sao Tome and Principe', iso: 'st' },
                { label: 'Saudi Arabia', value: 'Saudi Arabia', iso: 'sa' },
                { label: 'Scotland', value: 'Scotland', iso: 'gb-sct' },
                { label: 'Senegal', value: 'Senegal', iso: 'sn' },
                { label: 'Serbia', value: 'Serbia', iso: 'rs' },
                { label: 'Seychelles', value: 'Seychelles', iso: 'sc' },
                { label: 'Sierra Leone', value: 'Sierra Leone', iso: 'sl' },
                { label: 'Singapore', value: 'Singapore', iso: 'sg' },
                { label: 'Sint Maarten', value: 'Sint Maarten', iso: 'sx' },
                { label: 'Slovakia', value: 'Slovakia', iso: 'sk' },
                { label: 'Slovenia', value: 'Slovenia', iso: 'si' },
                { label: 'Solomon Islands', value: 'Solomon Islands', iso: 'sb' },
                { label: 'Somalia', value: 'Somalia', iso: 'so' },
                { label: 'South Africa', value: 'South Africa', iso: 'za' },
                { label: 'South Korea', value: 'South Korea', iso: 'kr' },
                { label: 'South Sudan', value: 'South Sudan', iso: 'ss' },
                { label: 'Spain', value: 'Spain', iso: 'es' },
                { label: 'Sri Lanka', value: 'Sri Lanka', iso: 'lk' },
                { label: 'Sudan', value: 'Sudan', iso: 'sd' },
                { label: 'Suriname', value: 'Suriname', iso: 'sr' },
                { label: 'Svalbard and Jan Mayen', value: 'Svalbard and Jan Mayen', iso: 'sj' },
                { label: 'Sweden', value: 'Sweden', iso: 'se' },
                { label: 'Switzerland', value: 'Switzerland', iso: 'ch' },
                { label: 'Syria', value: 'Syria', iso: 'sy' },
                { label: 'Taiwan', value: 'Taiwan', iso: 'tw' },
                { label: 'Tajikistan', value: 'Tajikistan', iso: 'tj' },
                { label: 'Tanzania', value: 'Tanzania', iso: 'tz' },
                { label: 'Thailand', value: 'Thailand', iso: 'th' },
                { label: 'Timor-Leste', value: 'Timor-Leste', iso: 'tl' },
                { label: 'Togo', value: 'Togo', iso: 'tg' },
                { label: 'Tokelau', value: 'Tokelau', iso: 'tk' },
                { label: 'Tonga', value: 'Tonga', iso: 'to' },
                { label: 'Trinidad and Tobago', value: 'Trinidad and Tobago', iso: 'tt' },
                { label: 'Tunisia', value: 'Tunisia', iso: 'tn' },
                { label: 'Turkey', value: 'Turkey', iso: 'tr' },
                { label: 'Turkmenistan', value: 'Turkmenistan', iso: 'tm' },
                { label: 'Turks and Caicos Islands', value: 'Turks and Caicos Islands', iso: 'tc' },
                { label: 'Tuvalu', value: 'Tuvalu', iso: 'tv' },
                { label: 'Uganda', value: 'Uganda', iso: 'ug' },
                { label: 'Ukraine', value: 'Ukraine', iso: 'ua' },
                { label: 'United Arab Emirates', value: 'United Arab Emirates', iso: 'ae' },
                { label: 'United Kingdom', value: 'United Kingdom', iso: 'gb' },
                { label: 'United States of America', value: 'United States of America', iso: 'us' },
                { label: 'Uruguay', value: 'Uruguay', iso: 'uy' },
                { label: 'Uzbekistan', value: 'Uzbekistan', iso: 'uz' },
                { label: 'Vanuatu', value: 'Vanuatu', iso: 'vu' },
                { label: 'Vatican City (Holy See)', value: 'Vatican City (Holy See)', iso: 'va' },
                { label: 'Venezuela', value: 'Venezuela', iso: 've' },
                { label: 'Vietnam', value: 'Vietnam', iso: 'vn' },
                { label: 'Wales', value: 'Wales', iso: 'gb-wls' },
                { label: 'Western Sahara', value: 'Western Sahara', iso: 'eh' },
                { label: 'Yemen', value: 'Yemen', iso: 'ye' },
                { label: 'Zambia', value: 'Zambia', iso: 'zm' },
                { label: 'Zimbabwe', value: 'Zimbabwe', iso: 'zw' },
            ],
        },) => ({
            options: comboboxData.allOptions,
            isOpen: false,
            openedWithKeyboard: false,
            selectedOption: null,
            setSelectedOption(option) {
                this.selectedOption = option
                this.isOpen = false
                this.openedWithKeyboard = false
                this.$refs.hiddenTextField.value = option.value
            },
            getFilteredOptions(query) {
                this.options = comboboxData.allOptions.filter((option) =>
                    option.label.toLowerCase().includes(query.toLowerCase()),
                )
                if (this.options.length === 0) {
                    this.$refs.noResultsMessage.classList.remove('hidden')
                } else {
                    this.$refs.noResultsMessage.classList.add('hidden')
                }
            },
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            handleKeydownOnOptions(event) {
                if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                    this.$refs.searchField.focus()
                }
            },
        }))
    })
</script>

US state selector with flags and search

Requires Alpine JS Focus Plugin

A U.S. state selector dropdown with state flags and a search field. This component uses flagpedia.net for the flags. The selected value will be stored in a hidden input field for easy retrieval.

HTML
<div x-data="{
        allOptions: [
            {
                label: 'Alabama',
                value: 'Alabama',
                iso: 'AL'
            },
            {
                label: 'Alaska',
                value: 'Alaska',
                iso: 'AK'
            },
            {
                label: 'Arizona',
                value: 'Arizona',
                iso: 'AZ'
            },
            {
                label: 'Arkansas',
                value: 'Arkansas',
                iso: 'AR'
            },
            {
                label: 'California',
                value: 'California',
                iso: 'CA'
            },
            {
                label: 'Colorado',
                value: 'Colorado',
                iso: 'CO'
            },
            {
                label: 'Connecticut',
                value: 'Connecticut',
                iso: 'CT'
            },
            {
                label: 'Delaware',
                value: 'Delaware',
                iso: 'DE'
            },
            {
                label: 'Florida',
                value: 'Florida',
                iso: 'FL'
            },
            {
                label: 'Georgia',
                value: 'Georgia',
                iso: 'GA'
            },
            {
                label: 'Hawaii',
                value: 'Hawaii',
                iso: 'HI'
            },
            {
                label: 'Idaho',
                value: 'Idaho',
                iso: 'ID'
            },
            {
                label: 'Illinois',
                value: 'Illinois',
                iso: 'IL'
            },
            {
                label: 'Indiana',
                value: 'Indiana',
                iso: 'IN'
            },
            {
                label: 'Iowa',
                value: 'Iowa',
                iso: 'IA'
            },
            {
                label: 'Kansas',
                value: 'Kansas',
                iso: 'KS'
            },
            {
                label: 'Kentucky',
                value: 'Kentucky',
                iso: 'KY'
            },
            {
                label: 'Louisiana',
                value: 'Louisiana',
                iso: 'LA'
            },
            {
                label: 'Maine',
                value: 'Maine',
                iso: 'ME'
            },
            {
                label: 'Maryland',
                value: 'Maryland',
                iso: 'MD'
            },
            {
                label: 'Massachusetts',
                value: 'Massachusetts',
                iso: 'MA'
            },
            {
                label: 'Michigan',
                value: 'Michigan',
                iso: 'MI'
            },
            {
                label: 'Minnesota',
                value: 'Minnesota',
                iso: 'MN'
            },
            {
                label: 'Mississippi',
                value: 'Mississippi',
                iso: 'MS'
            },
            {
                label: 'Missouri',
                value: 'Missouri',
                iso: 'MO'
            },
            {
                label: 'Montana',
                value: 'Montana',
                iso: 'MT'
            },
            {
                label: 'Nebraska',
                value: 'Nebraska',
                iso: 'NE'
            },
            {
                label: 'Nevada',
                value: 'Nevada',
                iso: 'NV'
            },
            {
                label: 'New Hampshire',
                value: 'New Hampshire',
                iso: 'NH'
            },
            {
                label: 'New Jersey',
                value: 'New Jersey',
                iso: 'NJ'
            },
            {
                label: 'New Mexico',
                value: 'New Mexico',
                iso: 'NM'
            },
            {
                label: 'New York',
                value: 'New York',
                iso: 'NY'
            },
            {
                label: 'North Carolina',
                value: 'North Carolina',
                iso: 'NC'
            },
            {
                label: 'North Dakota',
                value: 'North Dakota',
                iso: 'ND'
            },
            {
                label: 'Ohio',
                value: 'Ohio',
                iso: 'OH'
            },
            {
                label: 'Oklahoma',
                value: 'Oklahoma',
                iso: 'OK'
            },
            {
                label: 'Oregon',
                value: 'Oregon',
                iso: 'OR'
            },
            {
                label: 'Pennsylvania',
                value: 'Pennsylvania',
                iso: 'PA'
            },
            {
                label: 'Rhode Island',
                value: 'Rhode Island',
                iso: 'RI'
            },
            {
                label: 'South Carolina',
                value: 'South Carolina',
                iso: 'SC'
            },
            {
                label: 'South Dakota',
                value: 'South Dakota',
                iso: 'SD'
            },
            {
                label: 'Tennessee',
                value: 'Tennessee',
                iso: 'TN'
            },
            {
                label: 'Texas',
                value: 'Texas',
                iso: 'TX'
            },
            {
                label: 'Utah',
                value: 'Utah',
                iso: 'UT'
            },
            {
                label: 'Vermont',
                value: 'Vermont',
                iso: 'VT'
            },
            {
                label: 'Virginia',
                value: 'Virginia',
                iso: 'VA'
            },
            {
                label: 'Washington',
                value: 'Washington',
                iso: 'WA'
            },
            {
                label: 'West Virginia',
                value: 'West Virginia',
                iso: 'WV'
            },
            {
                label: 'Wisconsin',
                value: 'Wisconsin',
                iso: 'WI'
            },
            {
                label: 'Wyoming',
                value: 'Wyoming',
                iso: 'WY'
            }
        ],
        options: [],
        isOpen: false,
        openedWithKeyboard: false,
        selectedOption: null,
        setSelectedOption(option) {
            this.selectedOption = option
            this.isOpen = false
            this.openedWithKeyboard = false
            this.$refs.hiddenTextField.value = option.value
        },
        getFilteredOptions(query) {
            this.options = this.allOptions.filter((option) =>
                option.label.toLowerCase().includes(query.toLowerCase()) ||
                option.iso.toLowerCase().includes(query.toLowerCase())
            )
            if (this.options.length === 0) {
                this.$refs.noResultsMessage.classList.remove('hidden')
            } else {
                this.$refs.noResultsMessage.classList.add('hidden')
            }
        },
        handleKeydownOnOptions(event) {
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                this.$refs.searchField.focus()
            }
        },
    }" class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false" x-init="options = allOptions">
    <label for="state" class="">State</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" class="" role="combobox" aria-controls="statesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" >
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"class="" aria-hidden="true">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- Hidden Input To Grab The Selected Value  -->
        <input id="state" name="state" autocomplete="off" x-ref="hiddenTextField" hidden=""/>
        <div x-show="isOpen || openedWithKeyboard" id="statesList" class="" role="listbox" aria-label="states list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">

            <!-- Search  -->
            <div class="">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true" >
                    <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                </svg>
                <input type="text" class="" name="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" x-ref="searchField" placeholder="Search" />
            </div>

            <!-- Options  -->
            <ul class="">
                <li class="" x-ref="noResultsMessage">
                    <span>No matches found</span>
                </li>
                <template x-for="(item, index) in options" x-bind:key="item.value">
                    <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                        <div class="">
                            <!-- State name  -->
                            <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                            <!-- Screen reader 'selected' indicator  -->
                            <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        </div>
                        <!-- Checkmark  -->
                        <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5">
                        </svg>
                    </li>
                </template>
            </ul>
        </div>
    </div>
</div>
<div x-data="combobox" class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false">
    <label for="state" class="">State</label>
    <div class="">

        <!-- trigger button  -->
        <button type="button" class="" role="combobox" aria-controls="statesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'" >
            <span class="" x-text="selectedOption ? selectedOption.value : 'Please Select'"></span>
            <!-- Chevron  -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"class="" aria-hidden="true">
                <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
            </svg>
        </button>

        <!-- Hidden Input To Grab The Selected Value  -->
        <input id="state" name="state" autocomplete="off" x-ref="hiddenTextField" hidden=""/>
        <div x-show="isOpen || openedWithKeyboard" id="statesList" class="" role="listbox" aria-label="states list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">

            <!-- Search  -->
            <div class="">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true" >
                    <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                </svg>
                <input type="text" class="" name="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" x-ref="searchField" placeholder="Search" />
            </div>

            <!-- Options  -->
            <ul class="">
                <li class="" x-ref="noResultsMessage">
                    <span>No matches found</span>
                </li>
                <template x-for="(item, index) in options" x-bind:key="item.value">
                    <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                        <div class="">
                            <!-- State name  -->
                            <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.label"></span>
                            <!-- Screen reader 'selected' indicator  -->
                            <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                        </div>
                        <!-- Checkmark  -->
                        <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5">
                        </svg>
                    </li>
                </template>
            </ul>
        </div>
    </div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('combobox', (comboboxData = {
            allOptions: [
                {
                    label: 'Alabama',
                    value: 'Alabama',
                    iso: 'AL'
                },
                {
                    label: 'Alaska',
                    value: 'Alaska',
                    iso: 'AK'
                },
                {
                    label: 'Arizona',
                    value: 'Arizona',
                    iso: 'AZ'
                },
                {
                    label: 'Arkansas',
                    value: 'Arkansas',
                    iso: 'AR'
                },
                {
                    label: 'California',
                    value: 'California',
                    iso: 'CA'
                },
                {
                    label: 'Colorado',
                    value: 'Colorado',
                    iso: 'CO'
                },
                {
                    label: 'Connecticut',
                    value: 'Connecticut',
                    iso: 'CT'
                },
                {
                    label: 'Delaware',
                    value: 'Delaware',
                    iso: 'DE'
                },
                {
                    label: 'Florida',
                    value: 'Florida',
                    iso: 'FL'
                },
                {
                    label: 'Georgia',
                    value: 'Georgia',
                    iso: 'GA'
                },
                {
                    label: 'Hawaii',
                    value: 'Hawaii',
                    iso: 'HI'
                },
                {
                    label: 'Idaho',
                    value: 'Idaho',
                    iso: 'ID'
                },
                {
                    label: 'Illinois',
                    value: 'Illinois',
                    iso: 'IL'
                },
                {
                    label: 'Indiana',
                    value: 'Indiana',
                    iso: 'IN'
                },
                {
                    label: 'Iowa',
                    value: 'Iowa',
                    iso: 'IA'
                },
                {
                    label: 'Kansas',
                    value: 'Kansas',
                    iso: 'KS'
                },
                {
                    label: 'Kentucky',
                    value: 'Kentucky',
                    iso: 'KY'
                },
                {
                    label: 'Louisiana',
                    value: 'Louisiana',
                    iso: 'LA'
                },
                {
                    label: 'Maine',
                    value: 'Maine',
                    iso: 'ME'
                },
                {
                    label: 'Maryland',
                    value: 'Maryland',
                    iso: 'MD'
                },
                {
                    label: 'Massachusetts',
                    value: 'Massachusetts',
                    iso: 'MA'
                },
                {
                    label: 'Michigan',
                    value: 'Michigan',
                    iso: 'MI'
                },
                {
                    label: 'Minnesota',
                    value: 'Minnesota',
                    iso: 'MN'
                },
                {
                    label: 'Mississippi',
                    value: 'Mississippi',
                    iso: 'MS'
                },
                {
                    label: 'Missouri',
                    value: 'Missouri',
                    iso: 'MO'
                },
                {
                    label: 'Montana',
                    value: 'Montana',
                    iso: 'MT'
                },
                {
                    label: 'Nebraska',
                    value: 'Nebraska',
                    iso: 'NE'
                },
                {
                    label: 'Nevada',
                    value: 'Nevada',
                    iso: 'NV'
                },
                {
                    label: 'New Hampshire',
                    value: 'New Hampshire',
                    iso: 'NH'
                },
                {
                    label: 'New Jersey',
                    value: 'New Jersey',
                    iso: 'NJ'
                },
                {
                    label: 'New Mexico',
                    value: 'New Mexico',
                    iso: 'NM'
                },
                {
                    label: 'New York',
                    value: 'New York',
                    iso: 'NY'
                },
                {
                    label: 'North Carolina',
                    value: 'North Carolina',
                    iso: 'NC'
                },
                {
                    label: 'North Dakota',
                    value: 'North Dakota',
                    iso: 'ND'
                },
                {
                    label: 'Ohio',
                    value: 'Ohio',
                    iso: 'OH'
                },
                {
                    label: 'Oklahoma',
                    value: 'Oklahoma',
                    iso: 'OK'
                },
                {
                    label: 'Oregon',
                    value: 'Oregon',
                    iso: 'OR'
                },
                {
                    label: 'Pennsylvania',
                    value: 'Pennsylvania',
                    iso: 'PA'
                },
                {
                    label: 'Rhode Island',
                    value: 'Rhode Island',
                    iso: 'RI'
                },
                {
                    label: 'South Carolina',
                    value: 'South Carolina',
                    iso: 'SC'
                },
                {
                    label: 'South Dakota',
                    value: 'South Dakota',
                    iso: 'SD'
                },
                {
                    label: 'Tennessee',
                    value: 'Tennessee',
                    iso: 'TN'
                },
                {
                    label: 'Texas',
                    value: 'Texas',
                    iso: 'TX'
                },
                {
                    label: 'Utah',
                    value: 'Utah',
                    iso: 'UT'
                },
                {
                    label: 'Vermont',
                    value: 'Vermont',
                    iso: 'VT'
                },
                {
                    label: 'Virginia',
                    value: 'Virginia',
                    iso: 'VA'
                },
                {
                    label: 'Washington',
                    value: 'Washington',
                    iso: 'WA'
                },
                {
                    label: 'West Virginia',
                    value: 'West Virginia',
                    iso: 'WV'
                },
                {
                    label: 'Wisconsin',
                    value: 'Wisconsin',
                    iso: 'WI'
                },
                {
                    label: 'Wyoming',
                    value: 'Wyoming',
                    iso: 'WY'
                }
            ],
        },) => ({
            options: comboboxData.allOptions,
            isOpen: false,
            openedWithKeyboard: false,
            selectedOption: null,
            setSelectedOption(option) {
                this.selectedOption = option
                this.isOpen = false
                this.openedWithKeyboard = false
                this.$refs.hiddenTextField.value = option.value
            },
            getFilteredOptions(query) {
                this.options = comboboxData.allOptions.filter((option) =>
                    option.label.toLowerCase().includes(query.toLowerCase()) ||
                    option.iso.toLowerCase().includes(query.toLowerCase())
                )
                if (this.options.length === 0) {
                    this.$refs.noResultsMessage.classList.remove('hidden')
                } else {
                    this.$refs.noResultsMessage.classList.add('hidden')
                }
            },
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            handleKeydownOnOptions(event) {
                if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                    this.$refs.searchField.focus()
                }
            },
        }))
    })
</script>

Phone number input with country code dropdown

Requires Alpine JS Focus Plugin

A country code selector dropdown paired with a phone input field. This component uses flagpedia.net for the flags.

HTML
<div x-data="{
        allOptions: [
            { label: 'Afghanistan', value: 'Afghanistan', iso: 'af', phoneCode: '+93' },
            { label: 'Albania', value: 'Albania', iso: 'al', phoneCode: '+355' },
            { label: 'Algeria', value: 'Algeria', iso: 'dz', phoneCode: '+213' },
            { label: 'Andorra', value: 'Andorra', iso: 'ad', phoneCode: '+376' },
            { label: 'Angola', value: 'Angola', iso: 'ao', phoneCode: '+244' },
            { label: 'Anguilla', value: 'Anguilla', iso: 'ai', phoneCode: '+1-264' },
            { label: 'Antigua and Barbuda', value: 'Antigua and Barbuda', iso: 'ag', phoneCode: '+1-268' },
            { label: 'Argentina', value: 'Argentina', iso: 'ar', phoneCode: '+54' },
            { label: 'Armenia', value: 'Armenia', iso: 'am', phoneCode: '+374' },
            { label: 'Aruba', value: 'Aruba', iso: 'aw', phoneCode: '+297' },
            { label: 'Australia', value: 'Australia', iso: 'au', phoneCode: '+61' },
            { label: 'Austria', value: 'Austria', iso: 'at', phoneCode: '+43' },
            { label: 'Azerbaijan', value: 'Azerbaijan', iso: 'az', phoneCode: '+994' },
            { label: 'Bahamas', value: 'Bahamas', iso: 'bs', phoneCode: '+1-242' },
            { label: 'Bahrain', value: 'Bahrain', iso: 'bh', phoneCode: '+973' },
            { label: 'Bangladesh', value: 'Bangladesh', iso: 'bd', phoneCode: '+880' },
            { label: 'Barbados', value: 'Barbados', iso: 'bb', phoneCode: '+1-246' },
            { label: 'Belarus', value: 'Belarus', iso: 'by', phoneCode: '+375' },
            { label: 'Belgium', value: 'Belgium', iso: 'be', phoneCode: '+32' },
            { label: 'Belize', value: 'Belize', iso: 'bz', phoneCode: '+501' },
            { label: 'Benin', value: 'Benin', iso: 'bj', phoneCode: '+229' },
            { label: 'Bermuda', value: 'Bermuda', iso: 'bm', phoneCode: '+1-441' },
            { label: 'Bhutan', value: 'Bhutan', iso: 'bt', phoneCode: '+975' },
            { label: 'Bolivia', value: 'Bolivia', iso: 'bo', phoneCode: '+591' },
            { label: 'Bosnia and Herzegovina', value: 'Bosnia and Herzegovina', iso: 'ba', phoneCode: '+387' },
            { label: 'Botswana', value: 'Botswana', iso: 'bw', phoneCode: '+267' },
            { label: 'Brazil', value: 'Brazil', iso: 'br', phoneCode: '+55' },
            { label: 'British Indian Ocean Territory', value: 'British Indian Ocean Territory', iso: 'io', phoneCode: '+246' },
            { label: 'British Virgin Islands', value: 'British Virgin Islands', iso: 'vg', phoneCode: '+1-284' },
            { label: 'Brunei', value: 'Brunei', iso: 'bn', phoneCode: '+673' },
            { label: 'Bulgaria', value: 'Bulgaria', iso: 'bg', phoneCode: '+359' },
            { label: 'Burkina Faso', value: 'Burkina Faso', iso: 'bf', phoneCode: '+226' },
            { label: 'Burundi', value: 'Burundi', iso: 'bi', phoneCode: '+257' },
            { label: 'Cambodia', value: 'Cambodia', iso: 'kh', phoneCode: '+855' },
            { label: 'Cameroon', value: 'Cameroon', iso: 'cm', phoneCode: '+237' },
            { label: 'Canada', value: 'Canada', iso: 'ca', phoneCode: '+1' },
            { label: 'Cape Verde', value: 'Cape Verde', iso: 'cv', phoneCode: '+238' },
            { label: 'Cayman Islands', value: 'Cayman Islands', iso: 'ky', phoneCode: '+1-345' },
            { label: 'Central African Republic', value: 'Central African Republic', iso: 'cf', phoneCode: '+236' },
            { label: 'Chad', value: 'Chad', iso: 'td', phoneCode: '+235' },
            { label: 'Chile', value: 'Chile', iso: 'cl', phoneCode: '+56' },
            { label: 'China', value: 'China', iso: 'cn', phoneCode: '+86' },
            { label: 'Colombia', value: 'Colombia', iso: 'co', phoneCode: '+57' },
            { label: 'Comoros', value: 'Comoros', iso: 'km', phoneCode: '+269' },
            { label: 'Congo (Brazzaville)', value: 'Congo (Brazzaville)', iso: 'cg', phoneCode: '+242' },
            { label: 'Congo (Kinshasa)', value: 'Congo (Kinshasa)', iso: 'cd', phoneCode: '+243' },
            { label: 'Cook Islands', value: 'Cook Islands', iso: 'ck', phoneCode: '+682' },
            { label: 'Costa Rica', value: 'Costa Rica', iso: 'cr', phoneCode: '+506' },
            { label: 'Croatia', value: 'Croatia', iso: 'hr', phoneCode: '+385' },
            { label: 'Cuba', value: 'Cuba', iso: 'cu', phoneCode: '+53' },
            { label: 'Curaçao', value: 'Curaçao', iso: 'cw', phoneCode: '+599' },
            { label: 'Cyprus', value: 'Cyprus', iso: 'cy', phoneCode: '+357' },
            { label: 'Czechia', value: 'Czechia', iso: 'cz', phoneCode: '+420' },
            { label: 'Denmark', value: 'Denmark', iso: 'dk', phoneCode: '+45' },
            { label: 'Djibouti', value: 'Djibouti', iso: 'dj', phoneCode: '+253' },
            { label: 'Dominica', value: 'Dominica', iso: 'dm', phoneCode: '+1-767' },
            { label: 'Dominican Republic', value: 'Dominican Republic', iso: 'do', phoneCode: '+1-809' },
            { label: 'Ecuador', value: 'Ecuador', iso: 'ec', phoneCode: '+593' },
            { label: 'Egypt', value: 'Egypt', iso: 'eg', phoneCode: '+20' },
            { label: 'El Salvador', value: 'El Salvador', iso: 'sv', phoneCode: '+503' },
            { label: 'England', value: 'England', iso: 'gb-eng', phoneCode: '+44' },
            { label: 'Equatorial Guinea', value: 'Equatorial Guinea', iso: 'gq', phoneCode: '+240' },
            { label: 'Eritrea', value: 'Eritrea', iso: 'er', phoneCode: '+291' },
            { label: 'Estonia', value: 'Estonia', iso: 'ee', phoneCode: '+372' },
            { label: 'Eswatini (Swaziland)', value: 'Eswatini (Swaziland)', iso: 'sz', phoneCode: '+268' },
            { label: 'Ethiopia', value: 'Ethiopia', iso: 'et', phoneCode: '+251' },
            { label: 'Falkland Islands (Islas Malvinas)', value: 'Falkland Islands (Islas Malvinas)', iso: 'fk', phoneCode: '+500' },
            { label: 'Faroe Islands', value: 'Faroe Islands', iso: 'fo', phoneCode: '+298' },
            { label: 'Fiji', value: 'Fiji', iso: 'fj', phoneCode: '+679' },
            { label: 'Finland', value: 'Finland', iso: 'fi', phoneCode: '+358' },
            { label: 'France', value: 'France', iso: 'fr', phoneCode: '+33' },
            { label: 'French Guiana', value: 'French Guiana', iso: 'gf', phoneCode: '+594' },
            { label: 'French Polynesia', value: 'French Polynesia', iso: 'pf', phoneCode: '+689' },
            { label: 'French Southern and Antarctic Lands', value: 'French Southern and Antarctic Lands', iso: 'tf', phoneCode: '+262' },
            { label: 'Gabon', value: 'Gabon', iso: 'ga', phoneCode: '+241' },
            { label: 'Gambia', value: 'Gambia', iso: 'gm', phoneCode: '+220' },
            { label: 'Georgia', value: 'Georgia', iso: 'ge', phoneCode: '+995' },
            { label: 'Germany', value: 'Germany', iso: 'de', phoneCode: '+49' },
            { label: 'Ghana', value: 'Ghana', iso: 'gh', phoneCode: '+233' },
            { label: 'Gibraltar', value: 'Gibraltar', iso: 'gi', phoneCode: '+350' },
            { label: 'Greece', value: 'Greece', iso: 'gr', phoneCode: '+30' },
            { label: 'Greenland', value: 'Greenland', iso: 'gl', phoneCode: '+299' },
            { label: 'Grenada', value: 'Grenada', iso: 'gd', phoneCode: '+1-473' },
            { label: 'Guadeloupe', value: 'Guadeloupe', iso: 'gp', phoneCode: '+590' },
            { label: 'Guam', value: 'Guam', iso: 'gu', phoneCode: '+1-671' },
            { label: 'Guatemala', value: 'Guatemala', iso: 'gt', phoneCode: '+502' },
            { label: 'Guinea', value: 'Guinea', iso: 'gn', phoneCode: '+224' },
            { label: 'Guinea-Bissau', value: 'Guinea-Bissau', iso: 'gw', phoneCode: '+245' },
            { label: 'Guyana', value: 'Guyana', iso: 'gy', phoneCode: '+592' },
            { label: 'Haiti', value: 'Haiti', iso: 'ht', phoneCode: '+509' },
            { label: 'Honduras', value: 'Honduras', iso: 'hn', phoneCode: '+504' },
            { label: 'Hong Kong', value: 'Hong Kong', iso: 'hk', phoneCode: '+852' },
            { label: 'Hungary', value: 'Hungary', iso: 'hu', phoneCode: '+36' },
            { label: 'Iceland', value: 'Iceland', iso: 'is', phoneCode: '+354' },
            { label: 'India', value: 'India', iso: 'in', phoneCode: '+91' },
            { label: 'Indonesia', value: 'Indonesia', iso: 'id', phoneCode: '+62' },
            { label: 'Iran', value: 'Iran', iso: 'ir', phoneCode: '+98' },
            { label: 'Iraq', value: 'Iraq', iso: 'iq', phoneCode: '+964' },
            { label: 'Ireland', value: 'Ireland', iso: 'ie', phoneCode: '+353' },
            { label: 'Israel', value: 'Israel', iso: 'il', phoneCode: '+972' },
            { label: 'Italy', value: 'Italy', iso: 'it', phoneCode: '+39' },
            { label: 'Ivory Coast', value: 'Ivory Coast', iso: 'ci', phoneCode: '+225' },
            { label: 'Jamaica', value: 'Jamaica', iso: 'jm', phoneCode: '+1-876' },
            { label: 'Japan', value: 'Japan', iso: 'jp', phoneCode: '+81' },
            { label: 'Jordan', value: 'Jordan', iso: 'jo', phoneCode: '+962' },
            { label: 'Kazakhstan', value: 'Kazakhstan', iso: 'kz', phoneCode: '+7' },
            { label: 'Kenya', value: 'Kenya', iso: 'ke', phoneCode: '+254' },
            { label: 'Kiribati', value: 'Kiribati', iso: 'ki', phoneCode: '+686' },
            { label: 'Kosovo', value: 'Kosovo', iso: 'xk', phoneCode: '+383' },
            { label: 'Kuwait', value: 'Kuwait', iso: 'kw', phoneCode: '+965' },
            { label: 'Kyrgyzstan', value: 'Kyrgyzstan', iso: 'kg', phoneCode: '+996' },
            { label: 'Laos', value: 'Laos', iso: 'la', phoneCode: '+856' },
            { label: 'Latvia', value: 'Latvia', iso: 'lv', phoneCode: '+371' },
            { label: 'Lebanon', value: 'Lebanon', iso: 'lb', phoneCode: '+961' },
            { label: 'Lesotho', value: 'Lesotho', iso: 'ls', phoneCode: '+266' },
            { label: 'Liberia', value: 'Liberia', iso: 'lr', phoneCode: '+231' },
            { label: 'Libya', value: 'Libya', iso: 'ly', phoneCode: '+218' },
            { label: 'Liechtenstein', value: 'Liechtenstein', iso: 'li', phoneCode: '+423' },
            { label: 'Lithuania', value: 'Lithuania', iso: 'lt', phoneCode: '+370' },
            { label: 'Luxembourg', value: 'Luxembourg', iso: 'lu', phoneCode: '+352' },
            { label: 'Macau', value: 'Macau', iso: 'mo', phoneCode: '+853' },
            { label: 'Madagascar', value: 'Madagascar', iso: 'mg', phoneCode: '+261' },
            { label: 'Malawi', value: 'Malawi', iso: 'mw', phoneCode: '+265' },
            { label: 'Malaysia', value: 'Malaysia', iso: 'my', phoneCode: '+60' },
            { label: 'Maldives', value: 'Maldives', iso: 'mv', phoneCode: '+960' },
            { label: 'Mali', value: 'Mali', iso: 'ml', phoneCode: '+223' },
            { label: 'Malta', value: 'Malta', iso: 'mt', phoneCode: '+356' },
            { label: 'Marshall Islands', value: 'Marshall Islands', iso: 'mh', phoneCode: '+692' },
            { label: 'Martinique', value: 'Martinique', iso: 'mq', phoneCode: '+596' },
            { label: 'Mauritania', value: 'Mauritania', iso: 'mr', phoneCode: '+222' },
            { label: 'Mauritius', value: 'Mauritius', iso: 'mu', phoneCode: '+230' },
            { label: 'Mexico', value: 'Mexico', iso: 'mx', phoneCode: '+52' },
            { label: 'Micronesia', value: 'Micronesia', iso: 'fm', phoneCode: '+691' },
            { label: 'Moldova', value: 'Moldova', iso: 'md', phoneCode: '+373' },
            { label: 'Monaco', value: 'Monaco', iso: 'mc', phoneCode: '+377' },
            { label: 'Mongolia', value: 'Mongolia', iso: 'mn', phoneCode: '+976' },
            { label: 'Montenegro', value: 'Montenegro', iso: 'me', phoneCode: '+382' },
            { label: 'Montserrat', value: 'Montserrat', iso: 'ms', phoneCode: '+1-664' },
            { label: 'Morocco', value: 'Morocco', iso: 'ma', phoneCode: '+212' },
            { label: 'Mozambique', value: 'Mozambique', iso: 'mz', phoneCode: '+258' },
            { label: 'Myanmar (Burma)', value: 'Myanmar (Burma)', iso: 'mm', phoneCode: '+95' },
            { label: 'Namibia', value: 'Namibia', iso: 'na', phoneCode: '+264' },
            { label: 'Nauru', value: 'Nauru', iso: 'nr', phoneCode: '+674' },
            { label: 'Nepal', value: 'Nepal', iso: 'np', phoneCode: '+977' },
            { label: 'Netherlands', value: 'Netherlands', iso: 'nl', phoneCode: '+31' },
            { label: 'New Caledonia', value: 'New Caledonia', iso: 'nc', phoneCode: '+687' },
            { label: 'New Zealand', value: 'New Zealand', iso: 'nz', phoneCode: '+64' },
            { label: 'Nicaragua', value: 'Nicaragua', iso: 'ni', phoneCode: '+505' },
            { label: 'Niger', value: 'Niger', iso: 'ne', phoneCode: '+227' },
            { label: 'Nigeria', value: 'Nigeria', iso: 'ng', phoneCode: '+234' },
            { label: 'Niue', value: 'Niue', iso: 'nu', phoneCode: '+683' },
            { label: 'Norfolk Island', value: 'Norfolk Island', iso: 'nf', phoneCode: '+672' },
            { label: 'North Korea', value: 'North Korea', iso: 'kp', phoneCode: '+850' },
            { label: 'North Macedonia', value: 'North Macedonia', iso: 'mk', phoneCode: '+389' },
            { label: 'Northern Ireland', value: 'Northern Ireland', iso: 'gb-nir', phoneCode: '+44' },
            { label: 'Northern Mariana Islands', value: 'Northern Mariana Islands', iso: 'mp', phoneCode: '+1-670' },
            { label: 'Norway', value: 'Norway', iso: 'no', phoneCode: '+47' },
            { label: 'Oman', value: 'Oman', iso: 'om', phoneCode: '+968' },
            { label: 'Pakistan', value: 'Pakistan', iso: 'pk', phoneCode: '+92' },
            { label: 'Palau', value: 'Palau', iso: 'pw', phoneCode: '+680' },
            { label: 'Palestine', value: 'Palestine', iso: 'ps', phoneCode: '+970' },
            { label: 'Panama', value: 'Panama', iso: 'pa', phoneCode: '+507' },
            { label: 'Papua New Guinea', value: 'Papua New Guinea', iso: 'pg', phoneCode: '+675' },
            { label: 'Paraguay', value: 'Paraguay', iso: 'py', phoneCode: '+595' },
            { label: 'Peru', value: 'Peru', iso: 'pe', phoneCode: '+51' },
            { label: 'Philippines', value: 'Philippines', iso: 'ph', phoneCode: '+63' },
            { label: 'Poland', value: 'Poland', iso: 'pl', phoneCode: '+48' },
            { label: 'Portugal', value: 'Portugal', iso: 'pt', phoneCode: '+351' },
            { label: 'Puerto Rico', value: 'Puerto Rico', iso: 'pr', phoneCode: '+1-787' },
            { label: 'Qatar', value: 'Qatar', iso: 'qa', phoneCode: '+974' },
            { label: 'Réunion', value: 'Réunion', iso: 're', phoneCode: '+262' },
            { label: 'Romania', value: 'Romania', iso: 'ro', phoneCode: '+40' },
            { label: 'Russia', value: 'Russia', iso: 'ru', phoneCode: '+7' },
            { label: 'Rwanda', value: 'Rwanda', iso: 'rw', phoneCode: '+250' },
            { label: 'Saint Barthélemy', value: 'Saint Barthélemy', iso: 'bl', phoneCode: '+590' },
            { label: 'Saint Helena', value: 'Saint Helena', iso: 'sh', phoneCode: '+290' },
            { label: 'Saint Kitts & Nevis', value: 'Saint Kitts & Nevis', iso: 'kn', phoneCode: '+1-869' },
            { label: 'Saint Lucia', value: 'Saint Lucia', iso: 'lc', phoneCode: '+1-758' },
            { label: 'Saint Martin', value: 'Saint Martin', iso: 'mf', phoneCode: '+590' },
            { label: 'Saint Pierre & Miquelon', value: 'Saint Pierre & Miquelon', iso: 'pm', phoneCode: '+508' },
            { label: 'Saint Vincent & Grenadines', value: 'Saint Vincent & Grenadines', iso: 'vc', phoneCode: '+1-784' },
            { label: 'Samoa', value: 'Samoa', iso: 'ws', phoneCode: '+685' },
            { label: 'San Marino', value: 'San Marino', iso: 'sm', phoneCode: '+378' },
            { label: 'São Tomé & Príncipe', value: 'São Tomé & Príncipe', iso: 'st', phoneCode: '+239' },
            { label: 'Saudi Arabia', value: 'Saudi Arabia', iso: 'sa', phoneCode: '+966' },
            { label: 'Senegal', value: 'Senegal', iso: 'sn', phoneCode: '+221' },
            { label: 'Serbia', value: 'Serbia', iso: 'rs', phoneCode: '+381' },
            { label: 'Seychelles', value: 'Seychelles', iso: 'sc', phoneCode: '+248' },
            { label: 'Sierra Leone', value: 'Sierra Leone', iso: 'sl', phoneCode: '+232' },
            { label: 'Singapore', value: 'Singapore', iso: 'sg', phoneCode: '+65' },
            { label: 'Sint Maarten', value: 'Sint Maarten', iso: 'sx', phoneCode: '+1-721' },
            { label: 'Slovakia', value: 'Slovakia', iso: 'sk', phoneCode: '+421' },
            { label: 'Slovenia', value: 'Slovenia', iso: 'si', phoneCode: '+386' },
            { label: 'Solomon Islands', value: 'Solomon Islands', iso: 'sb', phoneCode: '+677' },
            { label: 'Somalia', value: 'Somalia', iso: 'so', phoneCode: '+252' },
            { label: 'South Africa', value: 'South Africa', iso: 'za', phoneCode: '+27' },
            { label: 'South Korea', value: 'South Korea', iso: 'kr', phoneCode: '+82' },
            { label: 'South Sudan', value: 'South Sudan', iso: 'ss', phoneCode: '+211' },
            { label: 'Spain', value: 'Spain', iso: 'es', phoneCode: '+34' },
            { label: 'Sri Lanka', value: 'Sri Lanka', iso: 'lk', phoneCode: '+94' },
            { label: 'Sudan', value: 'Sudan', iso: 'sd', phoneCode: '+249' },
            { label: 'Suriname', value: 'Suriname', iso: 'sr', phoneCode: '+597' },
            { label: 'Sweden', value: 'Sweden', iso: 'se', phoneCode: '+46' },
            { label: 'Switzerland', value: 'Switzerland', iso: 'ch', phoneCode: '+41' },
            { label: 'Syria', value: 'Syria', iso: 'sy', phoneCode: '+963' },
            { label: 'Taiwan', value: 'Taiwan', iso: 'tw', phoneCode: '+886' },
            { label: 'Tajikistan', value: 'Tajikistan', iso: 'tj', phoneCode: '+992' },
            { label: 'Tanzania', value: 'Tanzania', iso: 'tz', phoneCode: '+255' },
            { label: 'Thailand', value: 'Thailand', iso: 'th', phoneCode: '+66' },
            { label: 'Timor-Leste', value: 'Timor-Leste', iso: 'tl', phoneCode: '+670' },
            { label: 'Togo', value: 'Togo', iso: 'tg', phoneCode: '+228' },
            { label: 'Tonga', value: 'Tonga', iso: 'to', phoneCode: '+676' },
            { label: 'Trinidad & Tobago', value: 'Trinidad & Tobago', iso: 'tt', phoneCode: '+1-868' },
            { label: 'Tunisia', value: 'Tunisia', iso: 'tn', phoneCode: '+216' },
            { label: 'Turkey', value: 'Turkey', iso: 'tr', phoneCode: '+90' },
            { label: 'Turkmenistan', value: 'Turkmenistan', iso: 'tm', phoneCode: '+993' },
            { label: 'Turks & Caicos Islands', value: 'Turks & Caicos Islands', iso: 'tc', phoneCode: '+1-649' },
            { label: 'Tuvalu', value: 'Tuvalu', iso: 'tv', phoneCode: '+688' },
            { label: 'Uganda', value: 'Uganda', iso: 'ug', phoneCode: '+256' },
            { label: 'Ukraine', value: 'Ukraine', iso: 'ua', phoneCode: '+380' },
            { label: 'United Arab Emirates', value: 'United Arab Emirates', iso: 'ae', phoneCode: '+971' },
            { label: 'United Kingdom', value: 'United Kingdom', iso: 'gb', phoneCode: '+44' },
            { label: 'United States', value: 'United States', iso: 'us', phoneCode: '+1' },
            { label: 'Uruguay', value: 'Uruguay', iso: 'uy', phoneCode: '+598' },
            { label: 'Uzbekistan', value: 'Uzbekistan', iso: 'uz', phoneCode: '+998' },
            { label: 'Vanuatu', value: 'Vanuatu', iso: 'vu', phoneCode: '+678' },
            { label: 'Vatican City', value: 'Vatican City', iso: 'va', phoneCode: '+379' },
            { label: 'Venezuela', value: 'Venezuela', iso: 've', phoneCode: '+58' },
            { label: 'Vietnam', value: 'Vietnam', iso: 'vn', phoneCode: '+84' },
            { label: 'Wallis & Futuna', value: 'Wallis & Futuna', iso: 'wf', phoneCode: '+681' },
            { label: 'Yemen', value: 'Yemen', iso: 'ye', phoneCode: '+967' },
            { label: 'Zambia', value: 'Zambia', iso: 'zm', phoneCode: '+260' },
            { label: 'Zimbabwe', value: 'Zimbabwe', iso: 'zw', phoneCode: '+263' }
        ],
        options: [],
        isOpen: true,
        openedWithKeyboard: false,
        selectedOption: null,
        setSelectedOption(option) {
            this.selectedOption = option
            this.isOpen = false
            this.openedWithKeyboard = false
            this.$refs.phoneNumber.value = option.phoneCode + ' '
        },
        getFilteredOptions(query) {
            this.options = this.allOptions.filter(
                (option) =>
                    option.label.toLowerCase().includes(query.toLowerCase()) ||
                    option.phoneCode.includes(query.toLowerCase()),
            )
            if (this.options.length === 0) {
                this.$refs.noResultsMessage.classList.remove('hidden')
            } else {
                this.$refs.noResultsMessage.classList.add('hidden')
            }
        },
        handleKeydownOnOptions(event) {
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                this.$refs.searchField.focus()
            }
        },
    }" class="">
    <label for="phoneNumber" class="">Phone Number</label>
    <div class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false" x-init="(options = allOptions), setSelectedOption(options[222])">

        <!-- Country Selector  -->
        <div>
            <!-- Trigger Button  -->
            <button type="button" class="" role="combobox" aria-controls="countriesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'">
                <!-- Chevron  -->
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="" aria-hidden="true">
                    <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd">
                </svg>
            </button>
            <!-- Dropdown  -->
            <div x-show="isOpen || openedWithKeyboard" id="countriesList" class="" role="listbox" aria-label="countries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
                <!-- Search  -->
                <div class="">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                    </svg>
                    <input type="text" class="" name="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" x-ref="searchField" placeholder="Search"/>
                </div>
                <!-- Options  -->
                <ul class="">
                    <li class="" x-ref="noResultsMessage">
                        <span>No matches found</span>
                    </li>
                    <template x-for="(item, index) in options" x-bind:key="item.value">
                        <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                            <div class="">
                                <!-- Label  -->
                                <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.value"></span>
                                <span class="" x-text="'(' + item.phoneCode + ')'"></span>
                                <!-- Screen reader 'selected' indicator  -->
                                <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                            </div>
                            <!-- Checkmark  -->
                            <svg x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
                            </svg>
                        </li>
                    </template>
                </ul>
            </div>
        </div>

        <input id="phoneNumber" type="tel" class="" x-ref="phoneNumber" autocomplete="phone" placeholder="+00 000-000-0000"/>
    </div>
</div>
<div x-data="combobox" class="">
    <label for="phoneNumber" class="">Phone Number</label>
    <div class="" x-on:keydown="handleKeydownOnOptions($event)" x-on:keydown.esc.window="isOpen = false, openedWithKeyboard = false" x-init="setSelectedOption(options[222])">

        <!-- Country Selector  -->
        <div>
            <!-- Trigger Button  -->
            <button type="button" class="" role="combobox" aria-controls="countriesList" aria-haspopup="listbox" x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true" x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true" x-bind:aria-expanded="isOpen || openedWithKeyboard" x-bind:aria-label="selectedOption ? selectedOption.value : 'Please Select'">
                <!-- Chevron  -->
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="" aria-hidden="true">
                    <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd">
                </svg>
            </button>
            <!-- Dropdown  -->
            <div x-show="isOpen || openedWithKeyboard" id="countriesList" class="" role="listbox" aria-label="countries list" x-on:click.outside="isOpen = false, openedWithKeyboard = false" x-on:keydown.down.prevent="$focus.wrap().next()" x-on:keydown.up.prevent="$focus.wrap().previous()" x-transition x-trap="openedWithKeyboard">
                <!-- Search  -->
                <div class="">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="1.5" class="" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                    </svg>
                    <input type="text" class="" name="searchField" aria-label="Search" x-on:input="getFilteredOptions($el.value)" x-ref="searchField" placeholder="Search"/>
                </div>
                <!-- Options  -->
                <ul class="">
                    <li class="" x-ref="noResultsMessage">
                        <span>No matches found</span>
                    </li>
                    <template x-for="(item, index) in options" x-bind:key="item.value">
                        <li class="" role="option" x-on:click="setSelectedOption(item)" x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0">
                            <div class="">
                                <!-- Label  -->
                                <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item.value"></span>
                                <span class="" x-text="'(' + item.phoneCode + ')'"></span>
                                <!-- Screen reader 'selected' indicator  -->
                                <span class="" x-text="selectedOption == item ? 'selected' : null"></span>
                            </div>
                            <!-- Checkmark  -->
                            <svg x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
                            </svg>
                        </li>
                    </template>
                </ul>
            </div>
        </div>

        <input id="phoneNumber" type="tel" class="" x-ref="phoneNumber" autocomplete="phone" placeholder="+00 000-000-0000"/>
    </div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('combobox', (comboboxData = {
            allOptions: [
                { label: 'Afghanistan', value: 'Afghanistan', iso: 'af', phoneCode: '+93' },
                { label: 'Albania', value: 'Albania', iso: 'al', phoneCode: '+355' },
                { label: 'Algeria', value: 'Algeria', iso: 'dz', phoneCode: '+213' },
                { label: 'Andorra', value: 'Andorra', iso: 'ad', phoneCode: '+376' },
                { label: 'Angola', value: 'Angola', iso: 'ao', phoneCode: '+244' },
                { label: 'Anguilla', value: 'Anguilla', iso: 'ai', phoneCode: '+1-264' },
                { label: 'Antigua and Barbuda', value: 'Antigua and Barbuda', iso: 'ag', phoneCode: '+1-268' },
                { label: 'Argentina', value: 'Argentina', iso: 'ar', phoneCode: '+54' },
                { label: 'Armenia', value: 'Armenia', iso: 'am', phoneCode: '+374' },
                { label: 'Aruba', value: 'Aruba', iso: 'aw', phoneCode: '+297' },
                { label: 'Australia', value: 'Australia', iso: 'au', phoneCode: '+61' },
                { label: 'Austria', value: 'Austria', iso: 'at', phoneCode: '+43' },
                { label: 'Azerbaijan', value: 'Azerbaijan', iso: 'az', phoneCode: '+994' },
                { label: 'Bahamas', value: 'Bahamas', iso: 'bs', phoneCode: '+1-242' },
                { label: 'Bahrain', value: 'Bahrain', iso: 'bh', phoneCode: '+973' },
                { label: 'Bangladesh', value: 'Bangladesh', iso: 'bd', phoneCode: '+880' },
                { label: 'Barbados', value: 'Barbados', iso: 'bb', phoneCode: '+1-246' },
                { label: 'Belarus', value: 'Belarus', iso: 'by', phoneCode: '+375' },
                { label: 'Belgium', value: 'Belgium', iso: 'be', phoneCode: '+32' },
                { label: 'Belize', value: 'Belize', iso: 'bz', phoneCode: '+501' },
                { label: 'Benin', value: 'Benin', iso: 'bj', phoneCode: '+229' },
                { label: 'Bermuda', value: 'Bermuda', iso: 'bm', phoneCode: '+1-441' },
                { label: 'Bhutan', value: 'Bhutan', iso: 'bt', phoneCode: '+975' },
                { label: 'Bolivia', value: 'Bolivia', iso: 'bo', phoneCode: '+591' },
                { label: 'Bosnia and Herzegovina', value: 'Bosnia and Herzegovina', iso: 'ba', phoneCode: '+387' },
                { label: 'Botswana', value: 'Botswana', iso: 'bw', phoneCode: '+267' },
                { label: 'Brazil', value: 'Brazil', iso: 'br', phoneCode: '+55' },
                { label: 'British Indian Ocean Territory', value: 'British Indian Ocean Territory', iso: 'io', phoneCode: '+246' },
                { label: 'British Virgin Islands', value: 'British Virgin Islands', iso: 'vg', phoneCode: '+1-284' },
                { label: 'Brunei', value: 'Brunei', iso: 'bn', phoneCode: '+673' },
                { label: 'Bulgaria', value: 'Bulgaria', iso: 'bg', phoneCode: '+359' },
                { label: 'Burkina Faso', value: 'Burkina Faso', iso: 'bf', phoneCode: '+226' },
                { label: 'Burundi', value: 'Burundi', iso: 'bi', phoneCode: '+257' },
                { label: 'Cambodia', value: 'Cambodia', iso: 'kh', phoneCode: '+855' },
                { label: 'Cameroon', value: 'Cameroon', iso: 'cm', phoneCode: '+237' },
                { label: 'Canada', value: 'Canada', iso: 'ca', phoneCode: '+1' },
                { label: 'Cape Verde', value: 'Cape Verde', iso: 'cv', phoneCode: '+238' },
                { label: 'Cayman Islands', value: 'Cayman Islands', iso: 'ky', phoneCode: '+1-345' },
                { label: 'Central African Republic', value: 'Central African Republic', iso: 'cf', phoneCode: '+236' },
                { label: 'Chad', value: 'Chad', iso: 'td', phoneCode: '+235' },
                { label: 'Chile', value: 'Chile', iso: 'cl', phoneCode: '+56' },
                { label: 'China', value: 'China', iso: 'cn', phoneCode: '+86' },
                { label: 'Colombia', value: 'Colombia', iso: 'co', phoneCode: '+57' },
                { label: 'Comoros', value: 'Comoros', iso: 'km', phoneCode: '+269' },
                { label: 'Congo (Brazzaville)', value: 'Congo (Brazzaville)', iso: 'cg', phoneCode: '+242' },
                { label: 'Congo (Kinshasa)', value: 'Congo (Kinshasa)', iso: 'cd', phoneCode: '+243' },
                { label: 'Cook Islands', value: 'Cook Islands', iso: 'ck', phoneCode: '+682' },
                { label: 'Costa Rica', value: 'Costa Rica', iso: 'cr', phoneCode: '+506' },
                { label: 'Croatia', value: 'Croatia', iso: 'hr', phoneCode: '+385' },
                { label: 'Cuba', value: 'Cuba', iso: 'cu', phoneCode: '+53' },
                { label: 'Curaçao', value: 'Curaçao', iso: 'cw', phoneCode: '+599' },
                { label: 'Cyprus', value: 'Cyprus', iso: 'cy', phoneCode: '+357' },
                { label: 'Czechia', value: 'Czechia', iso: 'cz', phoneCode: '+420' },
                { label: 'Denmark', value: 'Denmark', iso: 'dk', phoneCode: '+45' },
                { label: 'Djibouti', value: 'Djibouti', iso: 'dj', phoneCode: '+253' },
                { label: 'Dominica', value: 'Dominica', iso: 'dm', phoneCode: '+1-767' },
                { label: 'Dominican Republic', value: 'Dominican Republic', iso: 'do', phoneCode: '+1-809' },
                { label: 'Ecuador', value: 'Ecuador', iso: 'ec', phoneCode: '+593' },
                { label: 'Egypt', value: 'Egypt', iso: 'eg', phoneCode: '+20' },
                { label: 'El Salvador', value: 'El Salvador', iso: 'sv', phoneCode: '+503' },
                { label: 'England', value: 'England', iso: 'gb-eng', phoneCode: '+44' },
                { label: 'Equatorial Guinea', value: 'Equatorial Guinea', iso: 'gq', phoneCode: '+240' },
                { label: 'Eritrea', value: 'Eritrea', iso: 'er', phoneCode: '+291' },
                { label: 'Estonia', value: 'Estonia', iso: 'ee', phoneCode: '+372' },
                { label: 'Eswatini (Swaziland)', value: 'Eswatini (Swaziland)', iso: 'sz', phoneCode: '+268' },
                { label: 'Ethiopia', value: 'Ethiopia', iso: 'et', phoneCode: '+251' },
                { label: 'Falkland Islands (Islas Malvinas)', value: 'Falkland Islands (Islas Malvinas)', iso: 'fk', phoneCode: '+500' },
                { label: 'Faroe Islands', value: 'Faroe Islands', iso: 'fo', phoneCode: '+298' },
                { label: 'Fiji', value: 'Fiji', iso: 'fj', phoneCode: '+679' },
                { label: 'Finland', value: 'Finland', iso: 'fi', phoneCode: '+358' },
                { label: 'France', value: 'France', iso: 'fr', phoneCode: '+33' },
                { label: 'French Guiana', value: 'French Guiana', iso: 'gf', phoneCode: '+594' },
                { label: 'French Polynesia', value: 'French Polynesia', iso: 'pf', phoneCode: '+689' },
                { label: 'French Southern and Antarctic Lands', value: 'French Southern and Antarctic Lands', iso: 'tf', phoneCode: '+262' },
                { label: 'Gabon', value: 'Gabon', iso: 'ga', phoneCode: '+241' },
                { label: 'Gambia', value: 'Gambia', iso: 'gm', phoneCode: '+220' },
                { label: 'Georgia', value: 'Georgia', iso: 'ge', phoneCode: '+995' },
                { label: 'Germany', value: 'Germany', iso: 'de', phoneCode: '+49' },
                { label: 'Ghana', value: 'Ghana', iso: 'gh', phoneCode: '+233' },
                { label: 'Gibraltar', value: 'Gibraltar', iso: 'gi', phoneCode: '+350' },
                { label: 'Greece', value: 'Greece', iso: 'gr', phoneCode: '+30' },
                { label: 'Greenland', value: 'Greenland', iso: 'gl', phoneCode: '+299' },
                { label: 'Grenada', value: 'Grenada', iso: 'gd', phoneCode: '+1-473' },
                { label: 'Guadeloupe', value: 'Guadeloupe', iso: 'gp', phoneCode: '+590' },
                { label: 'Guam', value: 'Guam', iso: 'gu', phoneCode: '+1-671' },
                { label: 'Guatemala', value: 'Guatemala', iso: 'gt', phoneCode: '+502' },
                { label: 'Guinea', value: 'Guinea', iso: 'gn', phoneCode: '+224' },
                { label: 'Guinea-Bissau', value: 'Guinea-Bissau', iso: 'gw', phoneCode: '+245' },
                { label: 'Guyana', value: 'Guyana', iso: 'gy', phoneCode: '+592' },
                { label: 'Haiti', value: 'Haiti', iso: 'ht', phoneCode: '+509' },
                { label: 'Honduras', value: 'Honduras', iso: 'hn', phoneCode: '+504' },
                { label: 'Hong Kong', value: 'Hong Kong', iso: 'hk', phoneCode: '+852' },
                { label: 'Hungary', value: 'Hungary', iso: 'hu', phoneCode: '+36' },
                { label: 'Iceland', value: 'Iceland', iso: 'is', phoneCode: '+354' },
                { label: 'India', value: 'India', iso: 'in', phoneCode: '+91' },
                { label: 'Indonesia', value: 'Indonesia', iso: 'id', phoneCode: '+62' },
                { label: 'Iran', value: 'Iran', iso: 'ir', phoneCode: '+98' },
                { label: 'Iraq', value: 'Iraq', iso: 'iq', phoneCode: '+964' },
                { label: 'Ireland', value: 'Ireland', iso: 'ie', phoneCode: '+353' },
                { label: 'Israel', value: 'Israel', iso: 'il', phoneCode: '+972' },
                { label: 'Italy', value: 'Italy', iso: 'it', phoneCode: '+39' },
                { label: 'Ivory Coast', value: 'Ivory Coast', iso: 'ci', phoneCode: '+225' },
                { label: 'Jamaica', value: 'Jamaica', iso: 'jm', phoneCode: '+1-876' },
                { label: 'Japan', value: 'Japan', iso: 'jp', phoneCode: '+81' },
                { label: 'Jordan', value: 'Jordan', iso: 'jo', phoneCode: '+962' },
                { label: 'Kazakhstan', value: 'Kazakhstan', iso: 'kz', phoneCode: '+7' },
                { label: 'Kenya', value: 'Kenya', iso: 'ke', phoneCode: '+254' },
                { label: 'Kiribati', value: 'Kiribati', iso: 'ki', phoneCode: '+686' },
                { label: 'Kosovo', value: 'Kosovo', iso: 'xk', phoneCode: '+383' },
                { label: 'Kuwait', value: 'Kuwait', iso: 'kw', phoneCode: '+965' },
                { label: 'Kyrgyzstan', value: 'Kyrgyzstan', iso: 'kg', phoneCode: '+996' },
                { label: 'Laos', value: 'Laos', iso: 'la', phoneCode: '+856' },
                { label: 'Latvia', value: 'Latvia', iso: 'lv', phoneCode: '+371' },
                { label: 'Lebanon', value: 'Lebanon', iso: 'lb', phoneCode: '+961' },
                { label: 'Lesotho', value: 'Lesotho', iso: 'ls', phoneCode: '+266' },
                { label: 'Liberia', value: 'Liberia', iso: 'lr', phoneCode: '+231' },
                { label: 'Libya', value: 'Libya', iso: 'ly', phoneCode: '+218' },
                { label: 'Liechtenstein', value: 'Liechtenstein', iso: 'li', phoneCode: '+423' },
                { label: 'Lithuania', value: 'Lithuania', iso: 'lt', phoneCode: '+370' },
                { label: 'Luxembourg', value: 'Luxembourg', iso: 'lu', phoneCode: '+352' },
                { label: 'Macau', value: 'Macau', iso: 'mo', phoneCode: '+853' },
                { label: 'Madagascar', value: 'Madagascar', iso: 'mg', phoneCode: '+261' },
                { label: 'Malawi', value: 'Malawi', iso: 'mw', phoneCode: '+265' },
                { label: 'Malaysia', value: 'Malaysia', iso: 'my', phoneCode: '+60' },
                { label: 'Maldives', value: 'Maldives', iso: 'mv', phoneCode: '+960' },
                { label: 'Mali', value: 'Mali', iso: 'ml', phoneCode: '+223' },
                { label: 'Malta', value: 'Malta', iso: 'mt', phoneCode: '+356' },
                { label: 'Marshall Islands', value: 'Marshall Islands', iso: 'mh', phoneCode: '+692' },
                { label: 'Martinique', value: 'Martinique', iso: 'mq', phoneCode: '+596' },
                { label: 'Mauritania', value: 'Mauritania', iso: 'mr', phoneCode: '+222' },
                { label: 'Mauritius', value: 'Mauritius', iso: 'mu', phoneCode: '+230' },
                { label: 'Mexico', value: 'Mexico', iso: 'mx', phoneCode: '+52' },
                { label: 'Micronesia', value: 'Micronesia', iso: 'fm', phoneCode: '+691' },
                { label: 'Moldova', value: 'Moldova', iso: 'md', phoneCode: '+373' },
                { label: 'Monaco', value: 'Monaco', iso: 'mc', phoneCode: '+377' },
                { label: 'Mongolia', value: 'Mongolia', iso: 'mn', phoneCode: '+976' },
                { label: 'Montenegro', value: 'Montenegro', iso: 'me', phoneCode: '+382' },
                { label: 'Montserrat', value: 'Montserrat', iso: 'ms', phoneCode: '+1-664' },
                { label: 'Morocco', value: 'Morocco', iso: 'ma', phoneCode: '+212' },
                { label: 'Mozambique', value: 'Mozambique', iso: 'mz', phoneCode: '+258' },
                { label: 'Myanmar (Burma)', value: 'Myanmar (Burma)', iso: 'mm', phoneCode: '+95' },
                { label: 'Namibia', value: 'Namibia', iso: 'na', phoneCode: '+264' },
                { label: 'Nauru', value: 'Nauru', iso: 'nr', phoneCode: '+674' },
                { label: 'Nepal', value: 'Nepal', iso: 'np', phoneCode: '+977' },
                { label: 'Netherlands', value: 'Netherlands', iso: 'nl', phoneCode: '+31' },
                { label: 'New Caledonia', value: 'New Caledonia', iso: 'nc', phoneCode: '+687' },
                { label: 'New Zealand', value: 'New Zealand', iso: 'nz', phoneCode: '+64' },
                { label: 'Nicaragua', value: 'Nicaragua', iso: 'ni', phoneCode: '+505' },
                { label: 'Niger', value: 'Niger', iso: 'ne', phoneCode: '+227' },
                { label: 'Nigeria', value: 'Nigeria', iso: 'ng', phoneCode: '+234' },
                { label: 'Niue', value: 'Niue', iso: 'nu', phoneCode: '+683' },
                { label: 'Norfolk Island', value: 'Norfolk Island', iso: 'nf', phoneCode: '+672' },
                { label: 'North Korea', value: 'North Korea', iso: 'kp', phoneCode: '+850' },
                { label: 'North Macedonia', value: 'North Macedonia', iso: 'mk', phoneCode: '+389' },
                { label: 'Northern Ireland', value: 'Northern Ireland', iso: 'gb-nir', phoneCode: '+44' },
                { label: 'Northern Mariana Islands', value: 'Northern Mariana Islands', iso: 'mp', phoneCode: '+1-670' },
                { label: 'Norway', value: 'Norway', iso: 'no', phoneCode: '+47' },
                { label: 'Oman', value: 'Oman', iso: 'om', phoneCode: '+968' },
                { label: 'Pakistan', value: 'Pakistan', iso: 'pk', phoneCode: '+92' },
                { label: 'Palau', value: 'Palau', iso: 'pw', phoneCode: '+680' },
                { label: 'Palestine', value: 'Palestine', iso: 'ps', phoneCode: '+970' },
                { label: 'Panama', value: 'Panama', iso: 'pa', phoneCode: '+507' },
                { label: 'Papua New Guinea', value: 'Papua New Guinea', iso: 'pg', phoneCode: '+675' },
                { label: 'Paraguay', value: 'Paraguay', iso: 'py', phoneCode: '+595' },
                { label: 'Peru', value: 'Peru', iso: 'pe', phoneCode: '+51' },
                { label: 'Philippines', value: 'Philippines', iso: 'ph', phoneCode: '+63' },
                { label: 'Poland', value: 'Poland', iso: 'pl', phoneCode: '+48' },
                { label: 'Portugal', value: 'Portugal', iso: 'pt', phoneCode: '+351' },
                { label: 'Puerto Rico', value: 'Puerto Rico', iso: 'pr', phoneCode: '+1-787' },
                { label: 'Qatar', value: 'Qatar', iso: 'qa', phoneCode: '+974' },
                { label: 'Réunion', value: 'Réunion', iso: 're', phoneCode: '+262' },
                { label: 'Romania', value: 'Romania', iso: 'ro', phoneCode: '+40' },
                { label: 'Russia', value: 'Russia', iso: 'ru', phoneCode: '+7' },
                { label: 'Rwanda', value: 'Rwanda', iso: 'rw', phoneCode: '+250' },
                { label: 'Saint Barthélemy', value: 'Saint Barthélemy', iso: 'bl', phoneCode: '+590' },
                { label: 'Saint Helena', value: 'Saint Helena', iso: 'sh', phoneCode: '+290' },
                { label: 'Saint Kitts & Nevis', value: 'Saint Kitts & Nevis', iso: 'kn', phoneCode: '+1-869' },
                { label: 'Saint Lucia', value: 'Saint Lucia', iso: 'lc', phoneCode: '+1-758' },
                { label: 'Saint Martin', value: 'Saint Martin', iso: 'mf', phoneCode: '+590' },
                { label: 'Saint Pierre & Miquelon', value: 'Saint Pierre & Miquelon', iso: 'pm', phoneCode: '+508' },
                { label: 'Saint Vincent & Grenadines', value: 'Saint Vincent & Grenadines', iso: 'vc', phoneCode: '+1-784' },
                { label: 'Samoa', value: 'Samoa', iso: 'ws', phoneCode: '+685' },
                { label: 'San Marino', value: 'San Marino', iso: 'sm', phoneCode: '+378' },
                { label: 'São Tomé & Príncipe', value: 'São Tomé & Príncipe', iso: 'st', phoneCode: '+239' },
                { label: 'Saudi Arabia', value: 'Saudi Arabia', iso: 'sa', phoneCode: '+966' },
                { label: 'Senegal', value: 'Senegal', iso: 'sn', phoneCode: '+221' },
                { label: 'Serbia', value: 'Serbia', iso: 'rs', phoneCode: '+381' },
                { label: 'Seychelles', value: 'Seychelles', iso: 'sc', phoneCode: '+248' },
                { label: 'Sierra Leone', value: 'Sierra Leone', iso: 'sl', phoneCode: '+232' },
                { label: 'Singapore', value: 'Singapore', iso: 'sg', phoneCode: '+65' },
                { label: 'Sint Maarten', value: 'Sint Maarten', iso: 'sx', phoneCode: '+1-721' },
                { label: 'Slovakia', value: 'Slovakia', iso: 'sk', phoneCode: '+421' },
                { label: 'Slovenia', value: 'Slovenia', iso: 'si', phoneCode: '+386' },
                { label: 'Solomon Islands', value: 'Solomon Islands', iso: 'sb', phoneCode: '+677' },
                { label: 'Somalia', value: 'Somalia', iso: 'so', phoneCode: '+252' },
                { label: 'South Africa', value: 'South Africa', iso: 'za', phoneCode: '+27' },
                { label: 'South Korea', value: 'South Korea', iso: 'kr', phoneCode: '+82' },
                { label: 'South Sudan', value: 'South Sudan', iso: 'ss', phoneCode: '+211' },
                { label: 'Spain', value: 'Spain', iso: 'es', phoneCode: '+34' },
                { label: 'Sri Lanka', value: 'Sri Lanka', iso: 'lk', phoneCode: '+94' },
                { label: 'Sudan', value: 'Sudan', iso: 'sd', phoneCode: '+249' },
                { label: 'Suriname', value: 'Suriname', iso: 'sr', phoneCode: '+597' },
                { label: 'Sweden', value: 'Sweden', iso: 'se', phoneCode: '+46' },
                { label: 'Switzerland', value: 'Switzerland', iso: 'ch', phoneCode: '+41' },
                { label: 'Syria', value: 'Syria', iso: 'sy', phoneCode: '+963' },
                { label: 'Taiwan', value: 'Taiwan', iso: 'tw', phoneCode: '+886' },
                { label: 'Tajikistan', value: 'Tajikistan', iso: 'tj', phoneCode: '+992' },
                { label: 'Tanzania', value: 'Tanzania', iso: 'tz', phoneCode: '+255' },
                { label: 'Thailand', value: 'Thailand', iso: 'th', phoneCode: '+66' },
                { label: 'Timor-Leste', value: 'Timor-Leste', iso: 'tl', phoneCode: '+670' },
                { label: 'Togo', value: 'Togo', iso: 'tg', phoneCode: '+228' },
                { label: 'Tonga', value: 'Tonga', iso: 'to', phoneCode: '+676' },
                { label: 'Trinidad & Tobago', value: 'Trinidad & Tobago', iso: 'tt', phoneCode: '+1-868' },
                { label: 'Tunisia', value: 'Tunisia', iso: 'tn', phoneCode: '+216' },
                { label: 'Turkey', value: 'Turkey', iso: 'tr', phoneCode: '+90' },
                { label: 'Turkmenistan', value: 'Turkmenistan', iso: 'tm', phoneCode: '+993' },
                { label: 'Turks & Caicos Islands', value: 'Turks & Caicos Islands', iso: 'tc', phoneCode: '+1-649' },
                { label: 'Tuvalu', value: 'Tuvalu', iso: 'tv', phoneCode: '+688' },
                { label: 'Uganda', value: 'Uganda', iso: 'ug', phoneCode: '+256' },
                { label: 'Ukraine', value: 'Ukraine', iso: 'ua', phoneCode: '+380' },
                { label: 'United Arab Emirates', value: 'United Arab Emirates', iso: 'ae', phoneCode: '+971' },
                { label: 'United Kingdom', value: 'United Kingdom', iso: 'gb', phoneCode: '+44' },
                { label: 'United States', value: 'United States', iso: 'us', phoneCode: '+1' },
                { label: 'Uruguay', value: 'Uruguay', iso: 'uy', phoneCode: '+598' },
                { label: 'Uzbekistan', value: 'Uzbekistan', iso: 'uz', phoneCode: '+998' },
                { label: 'Vanuatu', value: 'Vanuatu', iso: 'vu', phoneCode: '+678' },
                { label: 'Vatican City', value: 'Vatican City', iso: 'va', phoneCode: '+379' },
                { label: 'Venezuela', value: 'Venezuela', iso: 've', phoneCode: '+58' },
                { label: 'Vietnam', value: 'Vietnam', iso: 'vn', phoneCode: '+84' },
                { label: 'Wallis & Futuna', value: 'Wallis & Futuna', iso: 'wf', phoneCode: '+681' },
                { label: 'Yemen', value: 'Yemen', iso: 'ye', phoneCode: '+967' },
                { label: 'Zambia', value: 'Zambia', iso: 'zm', phoneCode: '+260' },
                { label: 'Zimbabwe', value: 'Zimbabwe', iso: 'zw', phoneCode: '+263' }
            ],
        },) => ({
            options: comboboxData.allOptions,
            isOpen: false,
            openedWithKeyboard: false,
            selectedOption: null,
            setSelectedOption(option) {
                this.selectedOption = option
                this.isOpen = false
                this.openedWithKeyboard = false
                this.$refs.phoneNumber.value = option.phoneCode +  ' '
            },
            getFilteredOptions(query) {
                this.options = comboboxData.allOptions.filter((option) =>
                    option.label.toLowerCase().includes(query.toLowerCase()),
                )
                if (this.options.length === 0) {
                    this.$refs.noResultsMessage.classList.remove('hidden')
                } else {
                    this.$refs.noResultsMessage.classList.add('hidden')
                }
            },
            init() {
                //Set initial value to US(+1)
                this.setSelectedOption(comboboxData.allOptions[222])
            },
            // if the user presses backspace or the alpha-numeric keys, focus on the search field
            handleKeydownOnOptions(event) {
                if ((event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 48 && event.keyCode <= 57) || event.keyCode === 8) {
                    this.$refs.searchField.focus()
                }
            },
        }))
    })
</script>

Data

List of all Alpine JS data used in this component.

Property Description
options Array - List of all available options
Array - List of all filtered options (Combobox with search)
isOpen Boolean - Dropdown is open/closed
openedWithKeyboard Boolean - Dropdown has opened with keyboard
selectedOption Object - Currently selected option
setSelectedOption()
param:option
Function - Sets selected option
highlightOptionOnKeydown()
param:firstLetter
Function - Highlights(focus) the first option that matches the pressed keyboard key
For combobox with checkboxes
selectedOptions Array - Currently checked options
setLabelText() Function - Sets label text based on currently checked options
handleOptionToggle()
param:option
Function - Updates the checked options list when an option is checked or unchecked
For combobox with search
allOptions Array - List of all available options
getfilteredOptions(query)
param:query
Function - Filters options based on the search query
handleKeydownOnOptions()
param:event
Function - Checks pressed key and shifts focus to the search input on alphanumeric values

Keyboard Navigation

Key Action
Tab Next focusable element gets the focus
Space Dropdown closed: Dropdown opens
Dropdown opened: Option gets selected/(un)checked
Dropdown closed: Dropdown opens
Dropdown opened: Next option gets focus
Previous option gets focus
Esc Dropdown closes