🧱 Very Downshift like autocomplete solution for Vue

Overview

Vue Combo Blocks 🧱

Provides all the building blocks needed for accessible autocomplete, combobox, or typeahead component.

A very Downshift like autocomplete solution for Vue

Downshift for Vue.js

size gzip size downloads

The problem

You want to build an autocomplete/combobox component, and it needs to be accessible, lightweight and you don't really want extra dependencies or styling you would not use, or you'd have to hack around to to make it your own.

The solution

This library provides you the state and the controls for your combobox. You provide the elements and styles to build the thing you need.

Usage

Try it out in codesandbox

<template>
  <vue-combo-blocks
    v-model="selected"
    :itemToString="itemToString"
    :items="filteredList"
    @input-value-change="updateList"
    v-slot="{
      getInputProps,
      getInputEventListeners,
      hoveredIndex,
      isOpen,
      getMenuProps,
      getMenuEventListeners,
      getItemProps,
      getItemEventListeners,
      getComboboxProps,
      reset,
    }"
  >
    <div v-bind="getComboboxProps()">
      <button @click="reset">resetbutton>
      <input v-bind="getInputProps()" v-on="getInputEventListeners()" placeholder="Search" />
      <ul v-show="isOpen" v-bind="getMenuProps()" v-on="getMenuEventListeners()">
        <li
          v-for="(item, index) in filteredList"
          :key="item.id"
          :style="{
            backgroundColor: hoveredIndex === index ? 'lightgray' : 'white',
            fontWeight: selected === item ? 'bold' : 'normal',
          }"
          v-bind="getItemProps({ item, index })"
          v-on="getItemEventListeners({ item, index })"
        >
          {{ item.value }}
        li>
      ul>
    div>
  vue-combo-blocks>
template>

<script>
import VueComboBlocks from 'vue-combo-blocks';

// This list could come from an external api
const list = [
  { value: 'Gretsch', id: '1' },
  { value: 'Ludwig', id: '2' },
  { value: 'Mapex', id: '3' },
  { value: 'Pearl', id: '4' },
  { value: 'Sonor', id: '5' },
  { value: 'Tama', id: '6' },
  { value: 'Zildjian', id: '7' },
];
export default {
  components: {
    VueComboBlocks,
  },
  data() {
    return {
      selected: null,
      filteredList: list,
    };
  },
  methods: {
    itemToString(item) {
      return item ? item.value : '';
    },
    // This could be a call to an api that returns the options
    updateList(text) {
      this.filteredList = list.filter((item) =>
        item.value.toLowerCase().includes(text.toLowerCase()),
      );
    },
  },
};
script>
  • {{ item.value }}
" aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w">

Props

Name Type Default description
items Array required
itemToString Function (item) => (item ? String(item) : '')
value Any null Sets the selected item. Prop part of v-model
stateReducer Function(state: object, actionAndChanges: object) optional Very handy feature that gives you a complete control of the vue-combo-blocks state. Read more about it in the State Reducer section
scrollIntoView Boolean true Controls whether or not the hovered item is scrolled into view when navigating with up and down keys. Note: the menu (ul) element must be positioned either relative or absolute for it to work
inputId String generated ID Used for aria attributes and the id prop of the element (input)
labelId String generated ID Used for aria attributes and the id prop of the element (label)
menuId String generated ID Used for aria attributes and the id prop of the element (ul)
getItemId Function(index) optional defaults to a function that generates an ID based on the index

Events

Emitted events return 2 parameters. First is the new value, and second is the state change type.

Name Type Description
select (New in 0.3.0) selectedItem: Any, type: stateChangeType Emitted when the item is selected
change selectedItem: Any, type: stateChangeType Emitted when the selected item changes
input-value-change inputValue: String, type: stateChangeType Emitted when the input value changes
is-open-change isOpen: Boolean, type: stateChangeType Emitted when the isOpen value changes
hovered-index-change hoveredIndex: Number, type: stateChangeType Emitted when the hoveredIndex value changes
state-change state:Object, type: stateChangeType Emitted when the state changes. Contains all the changes

Default Slot & returned props

Default slot's scope contains: prop getters, event listeners, component state and actions.

Prop getters

Bind the prop getters to their elements with v-bind and event listeners with v-on. You can add your own event listeners to these elements too and any other props needed.

<input v-bind="getInputProps()" v-on="getInputEventListeners()" />
" aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w">
Name Type Description
getComboboxProps function() returns the props you should apply to an element that wraps the input element that you render.
getInputProps function() returns the props you should apply to the input element that you render.
getLabelProps function() returns the props you should apply to the label element that you render.
getItemProps function({ item: any, index: number, disabled: boolean }) returns the props you should apply to any menu item elements you render. item property is required!
getMenuProps function() returns the props you should apply to the ul element (or root of your menu) that you render.

Event listeners

Name Type Description
getInputEventListeners function() Bind these to the input element.
getItemEventListeners function({ item: any, index: number, disabled: boolean }) Bind these to the li element. item property is required!
getMenuEventListeners function() Bind these to the ul element.

State

Name Type Description
isOpen Boolean the list open state
selectedItem Any the currently selected item
hoveredIndex Number the currently hovered item
inputValue String the value in the input

Actions

Name Type Description
reset function() Clears the selected item, and reset the input value
select function(item: any) Selects an item
setInputValue function(inputValue: string) Sets the input value
openMenu function() Opens the menu
closeMenu function() Closes the menu

State Reducer

function(state: object, actionAndChanges: object This function is called each time vue-combo-blocks sets its internal state. It gives you the current state and the state that will be set, and you return the state that you want to set.

  • state: The full current state of vue-combo-blocks.
  • actionAndChanges: Object that contains the action type, props needed to return a new state based on that type and the changes suggested by the vue-combo-blocks default reducer. About the type property you can learn more about in the stateChangeTypes section.

In this example, we want to keep the menu open after the item is selected, and keep the input value empty

<template>
  <vue-combo-blocks :stateReducer="stateReducer" ****>
    ****
  vue-combo-blocks>
template>
**** " aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w">
  methods: {
    stateReducer(oldState, { changes, type }) {
      switch (type) {
        case VueComboBlocks.stateChangeTypes.InputKeyUpEnter:
        case VueComboBlocks.stateChangeTypes.ItemClick:
          return {
            ...changes,
            isOpen: true,
            inputValue: '',
          };
        default:
          return changes;
      }
    },
  }

stateChangeTypes

The list of all possible values this type property can take is defined in this file and is as follows:

  • VueComboBlocks.stateChangeTypes.InputKeyDownArrowDown
  • VueComboBlocks.stateChangeTypes.InputKeyDownArrowUp
  • VueComboBlocks.stateChangeTypes.InputKeyDownTab
  • VueComboBlocks.stateChangeTypes.InputKeyUpEscape
  • VueComboBlocks.stateChangeTypes.InputKeyUpEnter
  • VueComboBlocks.stateChangeTypes.InputChange
  • VueComboBlocks.stateChangeTypes.InputBlur
  • VueComboBlocks.stateChangeTypes.ItemMouseLeave
  • VueComboBlocks.stateChangeTypes.ItemMouseMove
  • VueComboBlocks.stateChangeTypes.ItemClick
  • VueComboBlocks.stateChangeTypes.FunctionOpenMenu
  • VueComboBlocks.stateChangeTypes.FunctionCloseMenu
  • VueComboBlocks.stateChangeTypes.FunctionSelectItem
  • VueComboBlocks.stateChangeTypes.FunctionSetInputValue
  • VueComboBlocks.stateChangeTypes.FunctionReset
  • VueComboBlocks.stateChangeTypes.ControlledPropUpdatedSelectedItem
You might also like...
A simple tags input with typeahead (autocomplete) built with Vue.js 2.
A simple tags input with typeahead (autocomplete) built with Vue.js 2.

Vue Tags Input v4 Forked from voerro/vue-tagsinput A simple tags input with typeahead built with Vue.js 2. Installation via NPM npm i @seriouslag/vue-

A simple tags input with typeahead (autocomplete) built with Vue.js 2.
A simple tags input with typeahead (autocomplete) built with Vue.js 2.

Voerro Vue Tags Input v2 A simple tags input with typeahead built with Vue.js 2. Live Demo Installation via NPM npm i @voerro/vue-tagsinput --save-dev

A better vim plugin for stylus, including proper and up-to-date syntax highligting, indentation and autocomplete
A better vim plugin for stylus, including proper and up-to-date syntax highligting, indentation and autocomplete

Vim Stylus Vim + Stylus = fast, effective and convenient CSS workflow! Features All HTML5 tags and CSS3 props are covered Correct highlighting for int

A Vue2 plugin for input content suggestions, support using keyboard to navigate and quick pick, it make use experience like search engine input element
A Vue2 plugin for input content suggestions, support using keyboard to navigate and quick pick, it make use experience like search engine input element

v-suggest A Vue2 plugin for input content suggestions, support using keyboard to navigate and quick pick, it make use experience like search engine in

vue instant allows you to easily create custom search controls with auto suggestions for your vue 2 applications
vue instant allows you to easily create custom search controls with auto suggestions for your vue 2 applications

Vue Instant! vue instant allows you to easily create custom search controls with auto suggestions for your vue 2 applications. Table of contents Examp

🔍 Vue autosuggest component.
🔍 Vue autosuggest component.

vue-autosuggest 🔍 Autosuggest component built for Vue. Table of Contents Examples Features Installation Usage Props Inspiration Contributors LICENSE

A configurable & lightweight Vue wrapper component that enables
A configurable & lightweight Vue wrapper component that enables

A configurable & lightweight Vue wrapper component that enables "out of the box" email autocomplete/suggestions on input elements.

Mention component for Vue.js
Mention component for Vue.js

vue-mention Mention popper for input and textarea Documentation Sponsors Quick start script import { Mentionable } from 'vue-mention' const users =

Swapi - vue-3 front for SWAPI

swapi Project setup npm install Compiles and hot-reloads for development npm run serve Compiles and minifies for production npm run build Lints and

Comments
  • Vue 3 support?

    Vue 3 support?

    Hi @sssmi 👋

    Thanks for the great library! Is support for Vue 3 planned? I'm not sure what all would have to be done, but currently it breaks already at the Vue import:

    "export 'default' (imported as 'Vue') was not found in 'vue'
    
    opened by MaxGfeller 2
  • export 'defineComponent' was not found in 'vue'

    export 'defineComponent' was not found in 'vue'

    I'm using Vue 2 with the component, but am getting the following warning when SFC's are compiling:

     WARN  in ./node_modules/vue-combo-blocks/build/vue-combo-blocks.esm.js
    
    "export 'defineComponent' was not found in 'vue'
    

    Seems to be related to the Vue 3 check:

    import Vue, { defineComponent } from 'vue';
    ...
    const isVue3 = !!defineComponent;
    

    Maybe this would work better?

    import Vue from 'vue';
    ...
    const isVue3 = !!Vue.defineComponent;
    
    opened by patrickcate 1
  • Add input click and focus event listeners

    Add input click and focus event listeners

    It would be great if click and focus event listeners were added to the input element. This would make it easer to change state based on these events, such as opening the menu when the input is clicked on.

    opened by patrickcate 1
  • Vue3

    Vue3

    Vue 3 support

    Removed:

    • ItemMouseLeave state change type
    • Dropped support for IE11. (Unless you use babel, or similar to polyfill Object.assign)

    Added:

    • MenuMouseLeave state change type
    • circular prop controls what happens when navigation with arrow keys and list bottom or top is reached.
    opened by sssmi 0
Autocomplete component for Vue.js

v-autocomplete Autocomplete component for Vue.js This component is css-free. The idea is to be used with any framework. Installation Using yarn yarn a

Marcos 347 Jan 3, 2023
Autocomplete component for Vue js

vuejs-auto-complete A Vue autocomplete component npm install vuejs-auto-complete --save Usage Installation, add autocomplete component into your app i

Charlie Kassel 136 Nov 8, 2022
Feature-rich autocomplete component for Vue.js

vue-simple-suggest Simple yet feature-rich autocomplete component for Vue.js Install npm install --save vue-simple-suggest See installation guide for

Marketplace Technologies 442 Jan 4, 2023
An autocomplete/typeahead component for Vue 2 and Bootstrap 4

vue-bootstrap-typeahead A simple list-group based typeahead/autocomplete using Bootstrap 4 and Vue 2 View The Examples Installation From NPM: > npm i

Alex Urquhart 209 Nov 19, 2022
A Vue component for autocomplete email domains

vue-email-dropdown A Vue component for autocomplete email domains Features Allows passing a list of domains to be used in for the suggestions. Allows

Danny Feliz 27 Nov 24, 2022
Autocomplete Component for Vue.Js

vue-autocomplete Autocomplete Component for Vue.Js Intro Vue Autocomplete is a Vue.Js component to make some suggestions for user input. come with .vu

Naufal Rabbani 210 Jan 18, 2022
Google Autocomplete Vue Componet

Google Autocomplete I am sharing this component because I was overwhelmed by complicated examples to achieve this simple job. So, I will try to be as

Gustavo Ocanto 275 Aug 29, 2022
Vue 2 Component to make Autocomplete element.

Vue 2 Autocomplete Autocomplete component for Vue 2. This is a fork of vue2-autocomplete - Naufal Rabbani [email protected] Install You can imp

Eduardo Aguad 0 Oct 12, 2017
A Vue Autocomplete component with accessibility and simplicity in mind.

VueCompleter A Vue Autocomplete component with accessibility and simplicity in mind. Installation npm install vue-completer or yarn add vue-completer

Tom Elliott 3 Nov 8, 2020
vue autoComplete component

vueto-complete vue autoComplete component Index Features Installation Examples Props Slots Events Styling LICENSE Features Supports full control over

Ahmed Abdallah 16 Jan 10, 2022