API differs from React-Bootstrap
See original GitHub issueThis is more of a discussion into a larger change in the component. The typeahead is trying to be react-bootstrap-esque, howerver it is quite difficult to use as a drop in replacement for existing form fields. This is due to the component being quite opinionated, being in favour of being a multiselect vs a single value field, and being uncontrolled (see https://github.com/ericgio/react-bootstrap-typeahead/issues/266) but also that many of the props are named differently for the same/similar functionality.
My proposal is to step back and ignore the actual autocomplete functionality for a second, check out the text FormControl in react-bootstrap and see what the differences are when using the typeahead as a regular input (no options), and then take a look at the default react select component (https://reactjs.org/docs/forms.html#the-select-tag) and see what was added. This should be a superset of both select and the text FormControl so that the functionality is as expected from a react-bootstrap user. The basic API should ideally be pretty much identical, however, we already have a number of unexpected things that I can think of:
- onChange is not firing when expected since it’s usually used for input value change, but in this component it’s used for multiple selections being changed. IMO onInputChange should be merged into it, and it should be invoked with an event that caused the input change, rather than the value. The value itself would depend on if multiple is true or not: an array of strings if true, and a string if false.
- value is missing as a prop. We have the array “selected” and the string “defaultInputValue” instead. selected is the closest we are at the moment to having a controlled input and ideally, this would be “value” if matching with any of the existing components. Select takes both an array and string based on if the prop “multiple” is true or not.
- options should probably be listed as react children rather than values. This would be in line with the way many components are going these days such as <select/> <Tabs/> <Panel/> etc. It would also remove the need for the renderMenuItemChildren function since the user could control the rendering of the option directly
<option value="grapefruit">Grapefruit</option>
.
These are the few i can think of that could be tweaked in the API without removing functionality or changing too much of the internals. Much more can be done in terms of making it a true controlled component but this would be a step in the right direction of simplifying and making it a bit more generic. (IMO)
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:5 (3 by maintainers)
Top GitHub Comments
I disagree with that statement.
onChange
fires when the selected value changes, which is consistent with how aselect
element would work. The problem is that there are essentially two form elements working together: a text input and a select. I made the decision to haveonChange
handle the selection andonInputChange
handle the input change.It’s not exactly “missing”, it’s just called something else 😃 If I really wanted to be more consistent with how native DOM elements work in React, I suppose I’d change
selected
anddefaultSelected
tovalue
anddefaultValue
, respectively. I’m not sure I see a compelling case to make that change other than consistency, though.I agree that ideally it would be nice for the component to be more declarative. The problem is that the component fundamentally deals with data so it would need to extract data from the children and pass back a result set for rendering. This starts to move a lot of complexity outside the component and onto the consumer. I think the current API provides simplicity for a broad set of use cases, while still allowing relatively easy customization for complex ones. I’d be interested to hear your ideas for how a more declarative API would work, though.
Closing this issue since there is no plan to explicitly mirror React-Bootstrap’s API. More than happy to consider general thoughts on the API in a separate issue.