react-simplest-typeahead v1.1.0
react-simplest-typeahead
yet another typeahead component
Motivation
Why this typeahead component?
- build for composability, two small dumb component and two hoc. Use what you need, replace the other parts.
- support styling with styled-component ( it delegates the className props )
- tested
Usage
Out of the box, the component works great with primitive values
import { injectFilterState, Typeahead } from 'react-simplest-typeahead'
// enhance the typeahead with the filter behavior
const TypeaheadWithFilterState = injectFilterState()(Typeahead)
// notice that it act like an html input ( with value / onChange props )
const NameSelector = ({ selectedName, onSelectName }) => (
<TypeaheadWithFilterState
value={selectedName}
onChange={onSelectName}
options={['tim', 'bill', 'joe']}
/>
)It also works great with complex item structure.
import { injectFilterState, Typeahead } from 'react-simplest-typeahead'
// in order to use the filterState higher order component, let's declare a filter function
// it should tell whever an item in the option list should be displayed according to the pattern inputed
const filterFunction = pattern => user => user.name.includes(pattern)
// enhance the typeahead with the filter behavior
const TypeaheadWithFilterState = injectFilterState({ filter: filterFunction })(
Typeahead
)
// let's declare a custom renderer for the options
const renderOption = ({ item, isHighlighted }) => (
<div>
<img src={item.picture} />
<span>{item.name}</span>
</div>
)
// wrap this up in a user selector
const UserSelector = ({ selectedUser, onSelectUser, users }) => (
<TypeaheadWithFilterState
value={user}
onChange={onSelectUser}
options={users}
renderOption={renderOption}
customStyle={{
input: {
fontSize: '20px',
},
}}
/>
)API
Typeahead
value : Itemcan be anything, it's the currently selected itemonChange : ( v: Item ) => voidcallback for when the selected Item changeoptions : Item[]a list of the possible values
styling
placeholder ?: stringplaceholder for the inputrenderOption ?: ({ option: Item, isHighlighted: boolean }) => Componentrender the item into the options panel. By default it renders the item as string.className ?: stringthe className to set on the container element. ( useful when using styled-component syntax )style ?: Objectthe style to apply on the container element.customClassName ?: { ['typeahead' | 'input' | 'options']: string }custom className for each elementcustomStyle ?: { ['typeahead' | 'input' | 'options']: Object }custom style object for each element
filtering state
This props handles the filtering to options, according to the search pattern inputed.
pattern : stringThe filtering patternonPatternChange : ( pattern : string) => voidcallback for when the pattern change, the pattern value should reflect this change. Usualy, this should trigger a change in theoptionsprops as well.
option state
This props handles the options panel state. By default, they are injected by the
hoc hoc.optionState. You can declare custom behavior if you skip the hoc.
opened : booleantrue is the options panel is openedopen : () => voidcallback for when the input is focusedclose : () => voidcallback for when the input is blurred
indexHighlighted : number | nullthe index of the highlighted optiononOptionHover : ( index : number | null ) => voidcallback for when a option is hoveredonKeyDown : ( event: KeyboardEvent ) => voidcallback for keydown event in input
Tokenizer
The tokenizer delegate most of the props to the typeahead. The most important change is that the value is an array of items, instead of the single one:
value : Item[]onChange : ( items: Item[] ) => void
uniqueValue : booleanif true, item should be unique in the value array
styling
Also, it take additional props for styling:
renderItem: ({ item: Item, onDelete: () => void }) => Component
And declare another elements that accepts custom styling
customClassName ?: { ['tokenizer' | 'value' | 'typeahead' | 'input' | 'options']: string }custom className for each elementcustomStyle ?: { ['tokenizer' | 'value' | 'typeahead' | 'input' | 'options']: Object }custom style object for each element
hoc.filterState
injectFilterState enhance a typeahead component. The enhanced component should receive options as props. It hold the pattern, inject the pattern and onPatternChange props and alter the options array accordingly.
injectFilterState accept as param:
filter?: (pattern: string, props: Object) => (x: Item) => booleansort?: (pattern: string, props: Object) => (a: Item, b: Item) => 1 | -1 | 0maxDisplayed?: number