react-simplest-typeahead
v1.1.0
Published
Simplest typeahead with suggestion.
Downloads
4
Readme
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 : Item
can be anything, it's the currently selected itemonChange : ( v: Item ) => void
callback for when the selected Item changeoptions : Item[]
a list of the possible values
styling
placeholder ?: string
placeholder for the inputrenderOption ?: ({ option: Item, isHighlighted: boolean }) => Component
render the item into the options panel. By default it renders the item as string.className ?: string
the className to set on the container element. ( useful when using styled-component syntax )style ?: Object
the 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 : string
The filtering patternonPatternChange : ( pattern : string) => void
callback for when the pattern change, the pattern value should reflect this change. Usualy, this should trigger a change in theoptions
props 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 : boolean
true is the options panel is openedopen : () => void
callback for when the input is focusedclose : () => void
callback for when the input is blurred
indexHighlighted : number | null
the index of the highlighted optiononOptionHover : ( index : number | null ) => void
callback for when a option is hoveredonKeyDown : ( event: KeyboardEvent ) => void
callback 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 : boolean
if 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) => boolean
sort?: (pattern: string, props: Object) => (a: Item, b: Item) => 1 | -1 | 0
maxDisplayed?: number