<!---
THIS IS AN AUTOGENERATED FILE. EDIT PACKAGES/BOUNDLESS-TYPEAHEAD/INDEX.JS INSTEAD.
-->
# Typeahead

Typeahead is an enhancement upon [Input](https://github.com/enigma-io/boundless/tree/master/packages/boundless-input)
which provides two * built-in matching algorithms ("fuzzy" \[default\] and "starts-with") and supports the use of
custom matching and marking functions.

In the examples below, imagine the `<>` in the "marks" section is a wrapping `<mark>` element:

1. __"Starts-with" matching & marking__
   ```jsx
   <Typeahead
       algorithm={Typeahead.mode.STARTS_WITH}
       entities={[
           {text: 'apple'},
           {text: 'apricot'},
           {text: 'grape'},
       ]}
       inputProps={{value: 'a'}} />
   ```

   + matches: `"apple", "apricot"`
   + marks: `"<a>pple", "<a>pricot"`

1. __"Fuzzy" matching & marking__
   ```jsx
   <Typeahead
       algorithm={Typeahead.mode.FUZZY}
       entities={[
           {text: 'apple'},
           {text: 'apricot'},
           {text: 'grape'},
       ]}
       inputProps={{value: 'a'}} />
   ```

   + matches: `"apple", "apricot", "grape"`
   + marks: `"<a>pple", "<a>pricot", "gr<a>pe"`

1. __Custom matching & marking__

    Optionally, you can provide your own combination of matching and marking functions. For example, loosening the
    matching to include * unicode variants of characters could be useful, e.g. ç &rarr; c

    ```jsx
    <Typeahead
        algorithm={{
            matcher: yourMatchFunc,
            marker: yourMarkFunc,
        }} />
    ```

## Component Instance Methods

When using `Typeahead` in your project, you may call the following methods on a rendered instance of the component.
Use [`refs`](https://* facebook.github.io/react/docs/refs-and-the-dom.html) to get the instance.

- __`focus()`__
  focuses the browser oon the underlying textual input for immediate text entry

- __`getInputNode()`__
  returns the raw underlying textual input DOM node

- __`getSelectedEntityText()`__
  returns the `text` property of the currently highlighted entity (from `props.entities`), or returns an empty string

- __`getValue()`__
  retrieves the current value of the underlying textual input

- __`select()`__
  programmatically creates a full selection on the underlying textual input such that a press of the Backspace key
  would fully clear the * input

- __`setValue(value: string)`__
  sets the underlying textual input to the specified text and updates internal state; do not use this method when
  using `Typeahead` as a * "controlled input"

## Installation

```bash
npm i boundless-typeahead --save
```

Then use it like:


```jsx
/** @jsx createElement */

import { createElement, PureComponent } from 'react';
import Typeahead from 'boundless-typeahead';

const countries = [ 'Afghanistan', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana', 'Bouvet Island', 'Brazil', 'British Indian Ocean Territory', 'Brunei Darussalam', 'Bulgaria', 'Burkina Faso', 'Burundi', 'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Caribbean Netherlands', 'Cayman Islands', 'Central African Republic', 'Chad', 'Chile', 'China', 'Christmas Island', 'Cocos (Keeling) Islands', 'Colombia', 'Comoros', 'Congo', 'Congo, Democratic Republic of', 'Cook Islands', 'Costa Rica', 'Croatia', 'Cuba', 'Curaçao', 'Cyprus', 'Czech Republic', 'Côte d\'Ivoire', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Falkland Islands', 'Faroe Islands', 'Fiji', 'Finland', 'France', 'French Guiana', 'French Polynesia', 'French Southern Territories', 'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar', 'Greece', 'Greenland', 'Grenada', 'Guadeloupe', 'Guam', 'Guatemala', 'Guernsey', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Heard and McDonald Islands', 'Honduras', 'Hong Kong', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Isle of Man', 'Israel', 'Italy', 'Jamaica', 'Japan', 'Jersey', 'Jordan', 'Kazakhstan', 'Kenya', 'Kiribati', 'Kuwait', 'Kyrgyzstan', 'Lao People\'s Democratic Republic', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein', 'Lithuania', 'Luxembourg', 'Macau', 'Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Marshall Islands', 'Martinique', 'Mauritania', 'Mauritius', 'Mayotte', 'Mexico', 'Micronesia, Federated States of', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Montserrat', 'Morocco', 'Mozambique', 'Myanmar', 'Namibia', 'Nauru', 'Nepal', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', 'North Korea', 'Northern Mariana Islands', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Palestine, State of', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Pitcairn', 'Poland', 'Portugal', 'Puerto Rico', 'Qatar', 'Romania', 'Russian Federation', 'Rwanda', 'Réunion', 'Saint Barthélemy', 'Saint Helena', 'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Vincent and the Grenadines', 'Saint-Martin (France)', 'Samoa', 'San Marino', 'Sao Tome and Principe', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Sint Maarten (Dutch part)', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Georgia and the South Sandwich Islands', 'South Korea', 'South Sudan', 'Spain', 'Sri Lanka', 'St. Pierre and Miquelon', 'Sudan', 'Suriname', 'Svalbard and Jan Mayen Islands', 'Swaziland', 'Sweden', 'Switzerland', 'Syria', 'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', 'The Netherlands', 'Timor-Leste', 'Togo', 'Tokelau', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks and Caicos Islands', 'Tuvalu', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'United States Minor Outlying Islands', 'Uruguay', 'Uzbekistan', 'Vanuatu', 'Vatican', 'Venezuela', 'Vietnam', 'Virgin Islands (British)', 'Virgin Islands (U.S.)', 'Wallis and Futuna Islands', 'Western Sahara', 'Yemen', 'Zambia', 'Zimbabwe' ];

export default class TypeaheadDemo extends PureComponent {
    state = {
        countries: countries.map((name) => ({ text: name })),
        firstInputValue: '',
        secondInputValue: '',
    }

    handleFirstInputChange = (e) => this.setState({ firstInputValue: e.target.value })
    handleSecondInputChange = (e) => this.setState({ secondInputValue: e.target.value })

    render() {
        return (
            <div className='spread'>
                <div>
                    <h5>Starts-with matching</h5>
                    <Typeahead
                        algorithm={Typeahead.mode.STARTS_WITH}
                        entities={this.state.countries}
                        hint={true}
                        inputProps={{
                            onChange: this.handleFirstInputChange,
                            placeholder: 'Please enter your country of origin...',
                            value: this.state.firstInputValue,
                        }} />
                </div>

                <div style={{ marginLeft: '1em' }}>
                    <h5>Fuzzy matching</h5>
                    <Typeahead
                        algorithm={Typeahead.mode.FUZZY}
                        entities={this.state.countries}
                        hint={true}
                        inputProps={{
                            onChange: this.handleSecondInputChange,
                            placeholder: 'Please enter your country of origin...',
                            value: this.state.secondInputValue,
                        }} />
                </div>
            </div>
        );
    }
}
```



Typeahead can also just be directly used from the main [Boundless library](https://www.npmjs.com/package/boundless). This is recommended when you're getting started to avoid maintaining the package versions of several components:

```bash
npm i boundless --save
```

the ES6 `import` statement then becomes like:

```js
import { Typeahead } from 'boundless';
```



## Props

> Note: only top-level props are in the README, for the full list check out the [website](https://boundless.js.org/Typeahead).

### Required Props

There are no required props.


### Optional Props

- __`*`__ &middot; any [React-supported attribute](https://facebook.github.io/react/docs/tags-and-attributes.html#html-attributes)

  Expects | Default Value
  ---     | ---
  `any` | `n/a`

- __`algorithm`__ &middot; the mechanism used to identify and mark matching substrings; a custom set can be provided as an object
  (see the properties below)

  Expects | Default Value
  ---     | ---
  `Typeahead.mode.STARTS_WITH or Typeahead.mode.FUZZY or object` | `Typeahead.mode.FUZZY`

- __`clearOnSelection`__ &middot; if `true`, clears the input text when a (partial) match is selected

  Expects | Default Value
  ---     | ---
  `bool` | `false`

- __`component`__ &middot; overrides the HTML container tag

  Expects | Default Value
  ---     | ---
  `string` | `'div'`

- __`entities`__ &middot; an array of objects that user input is filtered against; at a minimum, each object must have a `text`
  property and any other supplied property is passed through to the resulting DOM element

  Expects | Default Value
  ---     | ---
  `arrayOf(object)` | `[]`

- __`hidePlaceholderOnFocus`__ &middot; triggers the placeholder to disappear when the input field is focused, reappears when the user has tabbed away or focus is moved

  Expects | Default Value
  ---     | ---
  `bool` | `true`

- __`hint`__ &middot; renders a disabled textfield with the full text of the currently selected input hint; will remain blank
  if the matched substring is not at the beginning of the user input

  Expects | Default Value
  ---     | ---
  `bool` | `null`

- __`hintProps`__

  Expects | Default Value
  ---     | ---
  `object` | `{}`

- __`inputProps`__

  Expects | Default Value
  ---     | ---
  `object` | `{ type: 'text' }`

- __`matchWrapperProps`__

  Expects | Default Value
  ---     | ---
  `object` | `{}`

- __`offscreenClass`__ &middot; the "offscreen" class used by your application; specifically to retain [ARIA navigability]
  (http://snook.ca/archives/html_and_css/hiding-content-for-accessibility) as `display: none` excludes the
  element from consideration

  Expects | Default Value
  ---     | ---
  `string` | `'b-offscreen'`

- __`onComplete`__ &middot; called when the user presses `Enter` with no autosuggest hint available, indicating that input is complete

  Expects | Default Value
  ---     | ---
  `function` | `() => {}`

- __`onEntityHighlighted`__ &middot; called with the index of the highlighted entity due to keyboard selection

  Expects | Default Value
  ---     | ---
  `function` | `() => {}`

- __`onEntitySelected`__ &middot; called with the index of the entity selected by the user

  Expects | Default Value
  ---     | ---
  `function` | `() => {}`


## Reference Styles
### Stylus
You can see what variables are available to override in [variables.styl](https://github.com/enigma-io/boundless/blob/master/variables.styl).

```stylus
// Redefine any variables as desired, e.g:
color-accent = royalblue

// Bring in the component styles; they will be autoconfigured based on the above
@require "node_modules/boundless-typeahead/style"
```

### CSS
If desired, a precompiled plain CSS stylesheet is available for customization at `/build/style.css`, based on Boundless's [default variables](https://github.com/enigma-io/boundless/blob/master/variables.styl).

