react-bootstrap-typeahead
react-bootstrap-typeahead copied to clipboard
Force case
What issue does this pull request resolve?
Adds one new prop to force the input to use the specified case styling to keep new custom options in a consistent style.
Currently, if a specific style is needed for custom (i.e. user-defined) options this must be applied once the selection has been made (either onChange
or at some other post-input stage). The end user sees exactly what they type, which is fine for searching existing options but will not reflect how their entry will be saved as a new option.
For example, if the Typeahead
component is populated with search tags that are all lower case, forceCase: "lower"
will keep the input in lowercase. Or if it is populated with company names, forceCase: "title"
will force the input to be styled according to toTitleCase()
. Or if it is populated with directory names, forceCase: "snake"
will keep the input in snake_case.
As this modifies the input as it's typed, the user is aware of the style changes before they are comitted to e.g. a database. The result is also returned as normal with other events e.g. onChange
, meaning selected
does not need to be modified again to achieve the same effect.
What changes did you make?
- Added
setCase.js
file toutils
, which processes the string conversion into the specified case style - Added
forceCase
prop, which if set to a string will converttext
inside_handleInputChange
to the specified case style (if an unknown style string is passed,setCase
just returns the text) - Added examples
Is there anything that requires more attention while reviewing?
- [ ] Currently I have included a long list of aliases for each case name, this may be overkill
- [ ]
npm lint
has issues in my enviroment, not sure where the problem is - [ ] Forced to install and use
cross-env
to get babel working in my environment
npm run test
- all pass (36/36 suites, 297/207 tests, 11/11 snapshots)
Hey @laurenceks, thanks for submitting such a comprehensive PR! It's a little unclear to me how generally useful this feature is, and I'm therefore reluctant to include it as part of the package. I am curious about whether you tried implementing this using the current API (eg: filterBy
) and whether you encountered limitations that required changes to the internals.
Hi @ericgio, thanks for taking the time to reply (sorry for my slow response - been on holiday!).
As far as I can tell, filterBy
does not provide the desired functionality beacuse it does not affect new values in real-time, meaning the "New selection: x" token at the bottom of the menu will always be one step behind (customOption: true
). It also requires me to take ownership of the filtering of options, which is not something I'd like to do for every new component when I just want the custom options stylised,
Looking through the docs I could try to use renderMenu
, but again this requires me to go in and manage the menu rendering myself. This means I have to write a fair bit of code to get the exact funcitonality the component already provides, with just one small change (the case of the custom option).
At the very least, if this can be achieved with filterBy
and renderMenu
, then it would be quite messy and have a lot of 'reinventing the wheel'.
I therefore made the addition to provide this functionality. With a single prop, the input is updated as the user types and is refelcted in the "New selection: x" token.
The only signifcant change I made was in _handleInputChange
, where if a new prop forceCase is set thgen the text
variable to changed accordingly (let text = forceCase ? setCase(e.currentTarget.value, forceCase) : e.currentTarget.value;
). Obviously I may be wrong and you will know far more than me, but as far as I can see this is a very minor tweak that should be safe.
There are multiple use cases for this, for example if a Typeahead
component is being used to search existing tags on a social media post, then it made be desirable to force lower case and have the input and "New selection: x" reflect this so that the end user sees exactly what will be saved. This PR allows that to be quickly enabled.