react-bootstrap-typeahead icon indicating copy to clipboard operation
react-bootstrap-typeahead copied to clipboard

Force case

Open laurenceks opened this issue 3 years ago • 2 comments

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?

  1. Added setCase.js file to utils, which processes the string conversion into the specified case style
  2. Added forceCase prop, which if set to a string will convert text inside _handleInputChange to the specified case style (if an unknown style string is passed, setCase just returns the text)
  3. 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)

laurenceks avatar Aug 17 '21 11:08 laurenceks

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.

ericgio avatar Sep 07 '21 06:09 ericgio

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.

laurenceks avatar Sep 25 '21 17:09 laurenceks