Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/darrenjennings/vue-autosuggest

πŸ” Vue autosuggest component.
https://github.com/darrenjennings/vue-autosuggest

accessibility autocomplete autosuggest javascript typeahead vue

Last synced: 27 days ago
JSON representation

πŸ” Vue autosuggest component.

Awesome Lists containing this project

README

        

ο»Ώ


Vue logo

vue-autosuggest

πŸ” Autosuggest component built for Vue.



[![Build Status][build-badge]][build]
[![Code Coverage][coverage-badge]][coverage]
[![version][version-badge]][package]
[![downloads][downloads-badge]][npmtrends]
[![MIT License][license-badge]][LICENSE]
[![gzip size][size-badge]](https://unpkg.com/vue-autosuggest@latest)

[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors)
[![PRs Welcome][prs-badge]][prs]
[![Code of Conduct][coc-badge]][coc]

[![Watch on GitHub][github-watch-badge]][github-watch]
[![Star on GitHub][github-star-badge]][github-star]
[![Tweet][twitter-badge]][twitter]

## Table of Contents

* [Examples](#examples)
* [Features](#features)
* [Installation](#installation)
* [Usage](#usage)
* [Props](#props)
* [Inspiration](#inspiration)
* [Contributors](#contributors)
* [LICENSE](#license)

## Examples

* Demo
* Storybook Helpful to see all
variations of component's props.

* JSFiddle Helpful for playing around
and sharing.
* Codesandbox Demos:

* [Deeply nested data objects as suggestions](https://codesandbox.io/s/vueautosuggest-api-data-objects-0nudq)
* [Api Fetching suggestions with Multiple sections](https://codesandbox.io/s/vueautosuggest-api-fetching-57d4e)
* [Form Validation with VeeValidate](https://codesandbox.io/s/vueautosuggest-vee-validate-ve13m)
* [Multiple VueAutosuggest instances on same page](https://codesandbox.io/s/vueautosuggest-multiple-vue-autosuggests-545ee)
* [Integration with Algolia](https://www.algolia.com/doc/guides/building-search-ui/resources/ui-and-ux-patterns/in-depth/autocomplete/vue/?language=vue#results-page-with-autocomplete) thanks to [@haroenv](https://github.com/haroenv)!

## Features

* WAI-ARIA complete autosuggest component built with the power of Vue.
* Full control over rendering with built in defaults or custom components for rendering.
* Easily integrate AJAX data fetching for list presentation.
* Supports multiple sections.
* No opinions on CSS, full control over styling.
* Rigorously tested.

## Installation

This module is distributed via [npm][npm] which is bundled with [node][node] and
should be installed as one of your project's `dependencies`:

```
npm install vue-autosuggest
```

or

```
yarn add vue-autosuggest
```

## Usage

Load VueAutosuggest into your vue app globally.

```js
import VueAutosuggest from "vue-autosuggest";
Vue.use(VueAutosuggest);
```

or locally inside a component:

```js
import { VueAutosuggest } from 'vue-autosuggest';
export default {
...
components: {
VueAutosuggest
}
...
};
```

Place the component into your app!

```html


{{suggestion.item}}

```

Advanced usage:

Click to expand

```html



You have selected {{selected.name}}, the {{selected.race}}





{{suggestion.item.name}}




import { VueAutosuggest } from "vue-autosuggest";

export default {
components: {
VueAutosuggest
},
data() {
return {
query: "",
selected: "",
suggestions: [
{
data: [
{ id: 1, name: "Frodo", race: "Hobbit", avatar: "https://upload.wikimedia.org/wikipedia/en/thumb/4/4e/Elijah_Wood_as_Frodo_Baggins.png/220px-Elijah_Wood_as_Frodo_Baggins.png" },
{ id: 2, name: "Samwise", race: "Hobbit", avatar: "https://upload.wikimedia.org/wikipedia/en/thumb/7/7b/Sean_Astin_as_Samwise_Gamgee.png/200px-Sean_Astin_as_Samwise_Gamgee.png" },
{ id: 3, name: "Gandalf", race: "Maia", avatar: "https://upload.wikimedia.org/wikipedia/en/thumb/e/e9/Gandalf600ppx.jpg/220px-Gandalf600ppx.jpg" },
{ id: 4, name: "Aragorn", race: "Human", avatar: "https://upload.wikimedia.org/wikipedia/en/thumb/3/35/Aragorn300ppx.png/150px-Aragorn300ppx.png" }
]
}
]
};
},
computed: {
filteredOptions() {
return [
{
data: this.suggestions[0].data.filter(option => {
return option.name.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
})
}
];
}
},
methods: {
clickHandler(item) {
// event fired when clicking on the input
},
onSelected(item) {
this.selected = item.item;
},
onInputChange(text) {
// event fired when the input changes
console.log(text)
},
/**
* This is what the <input/> value is set to when you are selecting a suggestion.
*/
getSuggestionValue(suggestion) {
return suggestion.item.name;
},
focusMe(e) {
console.log(e) // FocusEvent
}
}
}

.demo {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

input {
width: 260px;
padding: 0.5rem;
}

ul {
width: 100%;
color: rgba(30, 39, 46,1.0);
list-style: none;
margin: 0;
padding: 0.5rem 0 .5rem 0;
}
li {
margin: 0 0 0 0;
border-radius: 5px;
padding: 0.75rem 0 0.75rem 0.75rem;
display: flex;
align-items: center;
}
li:hover {
cursor: pointer;
}

.autosuggest-container {
display: flex;
justify-content: center;
width: 280px;
}

#autosuggest { width: 100%; display: block;}
.autosuggest__results-item--highlighted {
background-color: rgba(51, 217, 178,0.2);
}

```

For more advanced usage, check out the examples below, and explore the
properties you can use.

## [Slots](#slots)

### header/footer
Slots for injecting content around the results/input. Useful for header/footer like slots or empty state.

```html

content before the goes here
content after the goes here
content before the

    goes here

section header content for specific section goes here
footer content goes here for specific section.
Default footer content for all sections
content after the
    goes here

```

### Adding labels

It is common in forms to add a label next to the `` tag for semantic html / accessibility. You can use the
`before-input` slot to accomplish this in conjunction with the `inputProps.id`:

```html


Search here:

...

```

### suggestion item (i.e. default slot)
Used to style each suggestion inside the `

  • ` tag. Using [scoped slots](https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots)
    you have access to the `suggestion` item inside the `v-for` suggestions loop. This gives you the power of Vue templating, since
    vue-autosuggest does not have an opinion about how you render the items in your list.

    ```vue





    {{suggestion.item.value}}

    {{suggestion.item}}

    ```

    > This slot will be overridden when the [`render-suggestion`](#renderSuggestion) prop is used.

    ## [Props](#props)

    | Prop | Type | Required | Description |
    | :------------------------------------------ | :------- | :------: | :-------------------------------------------------------- |
    | [`suggestions`](#suggestionsProp) | Array | βœ“ | Array of sections, each containing suggestions to be rendered. e.g.`suggestions: [{data: ['harry','ron','hermione']}]` |
    | [`input-props`](#inputPropsTable) | Object | βœ“ | Add props to the ``. |
    | [`section-configs`](#sectionConfigsProp) | Object | | Define multiple sections ``. |
    | [`render-suggestion`](#renderSuggestion) | Function | | Tell vue-autosuggest how to render inside the `

  • ` tag. Overrides what is inside the default suggestion template slot. |
    | [`get-suggestion-value`](#getSuggestionValue) | Function | | Tells vue-autosuggest what to put in the `` value |
    | [`should-render-suggestions`](#shouldRenderSuggestions) | Function | | Tell vue-autosuggest if it should render the suggestions results popover |
    | `component-attr-id-autosuggest` | String | | `id` of entire component |
    | `component-attr-class-autosuggest-results-container` | String | | `class` of container of results container |
    | `component-attr-class-autosuggest-results` | String | | `class` of results container |
    | `component-attr-prefix` | String | | prefix to be used for results item classes/ids. default: `autosuggest` |

    ### inputProps

    | Prop | Type | Required | Description |
    | :----------------------- | :------------------ | :--------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | [`id`](#inputPropsTable) | String | βœ“ | id attribute on ``. |
    | Any DOM Props | \* | | You can add any props to `` as the component will `v-bind` inputProps. Similar to rest spread in JSX. See more details here: https://vuejs.org/v2/api/#v-bind. The `name` attribute is set to "`q`" by default. |

    ### sectionConfigs

    Multiple sections can be defined in the `sectionConfigs` prop which defines the control behavior for
    each section.

    | Prop | Type | Required | Description |
    | :----------- | :------- | :------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `on-selected` | Function | βœ“ | Determine behavior for what should happen when a suggestion is selected. e.g. Submit a form, open a link, update a vue model, tweet at Ken Wheeler etc. |
    | `limit` | Number | | Limit each section by some value. Default: `Infinity` |

    Below we have defined a `default` section and a `blog` section. The `blog` section has a component
    `type` of `url-section` which corresponds to which component the Autosuggest loads. When type is not
    defined, Vue-autosuggest will use a built in `DefaultSection.vue` component.

    ```js
    sectionConfigs: {
    'default': {
    limit: 6,
    onSelected: function(item, originalInput) {
    console.log(item, originalInput, `Selected "${item.item}"`);
    }
    },
    'blog': {
    limit: 3,
    type: "url-section",
    onSelected: function() {
    console.log("url: " + item.item.url);
    }
    }
    }
    ```

    ### renderSuggestion

    This function can be used to tell vue-autosuggest how to render the html inside the `

  • ` tag when you do not want to use the
    default template slot for suggestions but would rather have the power of javascript / jsx.

    In its most basic form it just returns an object property:

    ```js
    renderSuggestion(suggestion) {
    return suggestion.name;
    },
    ```

    But usually it returns a JSX fragment, which is transformed into a virtual node description with babel-plugin-transform-vue-jsx:

    ```jsx
    renderSuggestion(suggestion) {
    return

    {suggestion.name}
    ;
    },
    ```

    If you're not using babel-plugin-transform-vue-jsx, you can create the virtual node description yourself:

    ```js
    renderSuggestion(suggestion) {
    return this.$createElement('div', { 'style': { color: 'red'} }, suggestion.name);
    },
    ```

    ### getSuggestionValue

    This function will tell vue-autosuggest what to put in the `` as the value.

    ```js
    getSuggestionValue(suggestion) {
    return suggestion.item.name;
    },
    ```

    ### shouldRenderSuggestions

    This function will tell vue-autosuggest if it should display the suggestions popover

    ```js
    /**
    * @param {Array} size - total results displayed
    * @param {Boolean} loading - value that indicates if vue-autosuggest _thinks_ that the
    * the popover should be open (e.g. if user hit escape, or
    * user clicked away)
    * @returns {Boolean}
    */
    shouldRenderSuggestions (size, loading) {
    // This is the default behavior
    return size >= 0 && !loading
    }
    ```

    ## [Events](#events)

    Below are the list of supported events. `@` is short-hand for
    [v-on](https://vuejs.org/v2/guide/events.html#Listening-to-Events).

    | Prop | Returns | Description |
    | :-------------------------------- | :-------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `@selected` | suggestionItem, index | suggestion select handler. equivalent to sectionConfigs `on-selected` but for all items |
    | `@input`, `@focus`, `@blur`, etc. | \* | there is a transparent wrapper on the underlying `` so vue-autosuggest will use any DOM event you pass it for listening. This is implemented using `v-on:`. |
    | `@opened`, `@closed` | \* | suggestions visibility handler, indicates when the suggestions are opened and closed. This is called alongside [shouldRenderSuggestions](#shouldRenderSuggestions). |
    | `@item-changed` | suggestionItem, index | when keying through the results, this event signals which item is highlighted before being selected. |

    ## Browser support

    For IE11 and below, some functionality may not work. For example, you will have to manually [polyfill](https://github.com/Financial-Times/polyfill-service/issues/177) `Node.prototype.contains`

    ## Inspiration

    * Misha Moroshko's react-autosuggest component inspired the api + WAI-ARIA completeness
    https://github.com/moroshko/react-autosuggest

    ## Contributors

    Thanks goes to these people ([emoji key][emojis]):

    | [
    Darren Jennings](https://darrenjennings.github.io)
    [πŸ’»](https://github.com/darrenjennings/vue-autosuggest/commits?author=darrenjennings "Code") [πŸ“–](https://github.com/darrenjennings/vue-autosuggest/commits?author=darrenjennings "Documentation") [πŸš‡](#infra-darrenjennings "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/darrenjennings/vue-autosuggest/commits?author=darrenjennings "Tests") [🎨](#design-darrenjennings "Design") [πŸ’‘](#example-darrenjennings "Examples") | [
    Evgeniy Kulish](https://github.com/ekulish)
    [πŸ’»](https://github.com/darrenjennings/vue-autosuggest/commits?author=ekulish "Code") [🎨](#design-ekulish "Design") [πŸ’‘](#example-ekulish "Examples") [⚠️](https://github.com/darrenjennings/vue-autosuggest/commits?author=ekulish "Tests") | [
    Scott Smith](https://github.com/scottadamsmith)
    [πŸ›](https://github.com/darrenjennings/vue-autosuggest/issues?q=author%3Ascottadamsmith "Bug reports") [πŸ’»](https://github.com/darrenjennings/vue-autosuggest/commits?author=scottadamsmith "Code") [⚠️](https://github.com/darrenjennings/vue-autosuggest/commits?author=scottadamsmith "Tests") | [
    Fernando Machuca](https://github.com/chuca)
    [🎨](#design-chuca "Design") | [
    BerniML](https://github.com/BerniML)
    [πŸ’»](https://github.com/darrenjennings/vue-autosuggest/commits?author=BerniML "Code") [⚠️](https://github.com/darrenjennings/vue-autosuggest/commits?author=BerniML "Tests") | [
    Kristoffer NordstrΓΆm](https://github.com/42tte)
    [πŸ’»](https://github.com/darrenjennings/vue-autosuggest/commits?author=42tte "Code") [⚠️](https://github.com/darrenjennings/vue-autosuggest/commits?author=42tte "Tests") | [
    Dan Wilson](https://www.danjwilson.co.uk)
    [πŸ’»](https://github.com/darrenjennings/vue-autosuggest/commits?author=djw "Code") |
    | :---: | :---: | :---: | :---: | :---: | :---: | :---: |

    Thanks to [@chuca](https://github.com/chuca) for the logo design.

    This project follows the [all-contributors][all-contributors] specification. Contributions of any
    kind welcome!

    ## LICENSE

    MIT

    [npm]: https://www.npmjs.com/
    [node]: https://nodejs.org
    [build-badge]: https://img.shields.io/travis/darrenjennings/vue-autosuggest.svg?style=flat-square
    [build]: https://travis-ci.org/darrenjennings/vue-autosuggest
    [size-badge]: https://img.badgesize.io/https://unpkg.com/vue-autosuggest@latest/dist/vue-autosuggest.esm.js?compression=gzip&style=flat-square
    [coverage-badge]: https://img.shields.io/codecov/c/github/darrenjennings/vue-autosuggest.svg?style=flat-square
    [coverage]: https://codecov.io/github/darrenjennings/vue-autosuggest
    [version-badge]: https://img.shields.io/npm/v/vue-autosuggest.svg?style=flat-square
    [package]: https://www.npmjs.com/package/vue-autosuggest
    [downloads-badge]: https://img.shields.io/npm/dm/vue-autosuggest.svg?style=flat-square
    [npmtrends]: http://www.npmtrends.com/vue-autosuggest
    [license-badge]: https://img.shields.io/npm/l/vue-autosuggest.svg?style=flat-square
    [license]: https://github.com/darrenjennings/vue-autosuggest/blob/master/LICENSE
    [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
    [prs]: http://makeapullrequest.com
    [coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
    [coc]: https://github.com/darrenjennings/vue-autosuggest/blob/master/other/CODE_OF_CONDUCT.md
    [github-watch-badge]: https://img.shields.io/github/watchers/darrenjennings/vue-autosuggest.svg?style=social
    [github-watch]: https://github.com/darrenjennings/vue-autosuggest/watchers
    [github-star-badge]: https://img.shields.io/github/stars/darrenjennings/vue-autosuggest.svg?style=social
    [github-star]: https://github.com/darrenjennings/vue-autosuggest/stargazers
    [twitter]: https://twitter.com/intent/tweet?text=Check%20out%20vue-autosuggest%20by%20%40darrenjennings%20https%3A%2F%2Fgithub.com%2Fdarrenjennings%2Fvue-autosuggest%20%F0%9F%91%8D
    [twitter-badge]: https://img.shields.io/twitter/url/https/github.com/darrenjennings/vue-autosuggest.svg?style=social
    [emojis]: https://github.com/kentcdodds/all-contributors#emoji-key
    [all-contributors]: https://github.com/kentcdodds/all-contributors