diff --git a/example/examples/TokenFocusExample.react.js b/example/examples/TokenFocusExample.react.js new file mode 100644 index 00000000..5bb9330d --- /dev/null +++ b/example/examples/TokenFocusExample.react.js @@ -0,0 +1,45 @@ +import React, {Fragment} from 'react'; + +import {Typeahead} from '../../src'; +import options from '../exampleData'; + +/* example-start */ +class TokenFocusExample extends React.Component { + state = { + selected: undefined, + }; + + render() { + const {selected} = this.state; + + return ( + + + { + selected ? + + {`${selected.name} has a population of + ${selected.population}. Its capital is ${selected.capital}.`} + : null + } + + ); + } + + _onTokenFocus = (option, focused) => { + this.setState({ + selected: focused ? option : undefined, + }); + } +} +/* example-start */ + +export default TokenFocusExample; diff --git a/example/sections/BehaviorsSection.react.js b/example/sections/BehaviorsSection.react.js index 9a4e52ae..6e8ee661 100644 --- a/example/sections/BehaviorsSection.react.js +++ b/example/sections/BehaviorsSection.react.js @@ -7,6 +7,7 @@ import InputSizeExample from '../examples/InputSizeExample.react'; import MenuAlignExample from '../examples/MenuAlignExample.react'; import PaginationExample from '../examples/PaginationExample.react'; import SelectionsExample from '../examples/SelectionsExample.react'; +import TokenFocusExample from '../examples/TokenFocusExample.react'; /* eslint-disable import/no-unresolved */ import BasicBehaviorsExampleCode from '!raw-loader!../examples/BasicBehaviorsExample.react'; @@ -16,6 +17,7 @@ import InputSizeExampleCode from '!raw-loader!../examples/InputSizeExample.react import MenuAlignExampleCode from '!raw-loader!../examples/MenuAlignExample.react'; import PaginationExampleCode from '!raw-loader!../examples/PaginationExample.react'; import SelectionsExampleCode from '!raw-loader!../examples/SelectionsExample.react'; +import TokenFocusExampleCode from '!raw-loader!../examples/TokenFocusExample.react'; /* eslint-enable import/no-unresolved */ import ExampleSection from '../components/ExampleSection.react'; @@ -45,6 +47,14 @@ const BehaviorsSection = (props) => ( + Token focus + + You can react on tokens being focused, by setting the ```onTokenFocus``` + handler. + + + + Input Size Besides the default input size, you can specify either a `small` or diff --git a/src/Typeahead.react.js b/src/Typeahead.react.js index 85039110..0ff2f837 100644 --- a/src/Typeahead.react.js +++ b/src/Typeahead.react.js @@ -45,6 +45,7 @@ class Typeahead extends React.Component { 'onFocus', 'onKeyDown', 'onRemove', + 'onTokenFocus', 'placeholder', 'renderToken', 'selected', diff --git a/src/TypeaheadInputMulti.react.js b/src/TypeaheadInputMulti.react.js index e5f61401..51e4c660 100644 --- a/src/TypeaheadInputMulti.react.js +++ b/src/TypeaheadInputMulti.react.js @@ -22,6 +22,7 @@ class TypeaheadInputMulti extends React.Component { onRemove, renderToken, selected, + onTokenFocus, ...props } = this.props; @@ -128,6 +129,9 @@ TypeaheadInputMulti.defaultProps = { disabled={props.disabled} key={idx} onRemove={props.onRemove} + onTokenFocus={props.onTokenFocus ? + (focused) => props.onTokenFocus(option, focused) : undefined + } tabIndex={props.tabIndex}> {getOptionLabel(option, props.labelKey)} diff --git a/src/TypeaheadInputSingle.react.js b/src/TypeaheadInputSingle.react.js index 587b221d..ca8ae217 100644 --- a/src/TypeaheadInputSingle.react.js +++ b/src/TypeaheadInputSingle.react.js @@ -6,7 +6,7 @@ import inputContainer from './containers/inputContainer'; class TypeaheadInputSingle extends React.Component { render() { - const {className, inputRef, ...props} = this.props; + const {className, inputRef, onTokenFocus, ...props} = this.props; return ( { }; render() { + const {onTokenFocus, ...props} = this.props; return ( { } _handleBlur = (e) => { + if (this.state.active && this.props.onTokenFocus) { + this.props.onTokenFocus(false); + } this.setState({active: false}); } @@ -50,6 +54,9 @@ const tokenContainer = (Component) => { _handleActive = (e) => { e.stopPropagation(); + if (!this.state.active && this.props.onTokenFocus) { + this.props.onTokenFocus(true); + } this.setState({active: true}); } } diff --git a/src/containers/typeaheadContainer.js b/src/containers/typeaheadContainer.js index fd9eef26..2cbf5814 100644 --- a/src/containers/typeaheadContainer.js +++ b/src/containers/typeaheadContainer.js @@ -645,6 +645,10 @@ function typeaheadContainer(Component) { * Invoked when the pagination menu item is clicked. Receives an event. */ onPaginate: PropTypes.func, + /** + * Invoked when the focus on a token changes. + */ + onTokenFocus: PropTypes.func, /** * Whether or not the menu should be displayed. `undefined` allows the * component to control visibility, while `true` and `false` show and hide