react-input-mask icon indicating copy to clipboard operation
react-input-mask copied to clipboard

User can move their cursor to the end of the input mask causing incorrect input

Open dbalatero opened this issue 7 years ago • 14 comments

Hey @sanniassin, I've been running into this bug in production on our site where users can click or tap into the input mask field, and find their cursor is moved to the right of where the next input character should be.

This occurs in our phone number input with a mask of (999) 999-9999. If the user clicks in the field and gets a cursor position like this: (9|99) 999-9999, they end up entering their number with a missing digit on the end. You'd think people would catch this, but we have a non-trivial amount of phone numbers missing 1-2 numbers in our database right now.

I've attached a GIF of this behavior:

phone-number

I'm curious what your thoughts are on this? I could see a few things:

  1. If the cursor selection is past what should be the next character in the mask, reset the cursor so it's at the right place.
  2. If someone types way ahead of the next character in the mask, just collapse whatever they typed so it looks correct (e.g. (123) 45 -7823 would collapse to (123) 457-823
  3. Some other clever thing!

dbalatero avatar Sep 04 '18 17:09 dbalatero

I am also happy to try and contribute a patch, but I wanted to talk it out first and see what direction (if any) would be most appreciated.

dbalatero avatar Sep 04 '18 17:09 dbalatero

@dbalatero Yeah, using space as a maskChar is tricky because it makes input look like a regular empty input (or a masked one with null maskChar) with the same behavior expected.

I think the right solution here is to add a property to enforce this behavior with non-empty maskChar. The hardest thing is to find a good name for it 🙂

sanniassin avatar Sep 04 '18 18:09 sanniassin

@sanniassin

Yeah totally. And just FYI, I am using this as the mask char:

// http://www.fileformat.info/info/unicode/char/2007/index.htm
const MASK_CHAR = '\u2007'

which is a space character that is fixed width, so that the mask doesn't jump around. So it's not just the literal space character, but any of the flavors of invisible mask chars.

I think the right solution here is to add a property to enforce this behavior with non-empty maskChar. The hardest thing is to find a good name for it 🙂

Totally! If you can describe the behavior that might be in your head, I might be able to suggest some names? ;)

dbalatero avatar Sep 04 '18 18:09 dbalatero

Nice typographic hack! Always thought I have to use monospace fonts for that.

The idea is to disallow any holes between entered characters, but I doubt that noHoles would look clear for someone who haven't read the documentation.

sanniassin avatar Sep 04 '18 18:09 sanniassin

@sanniassin Yeah totally. My coworker taught me about this, it's pretty cool. Our fields have this CSS:

input {
  font-feature-settings: "kern", "liga", "ss01", "ss02", "tnum";
}

where setting tnum sets monospaced figures (numbers). Combine that with the mask char I posted above and everything stays in the right place as you type.

The idea is to disallow any holes between entered characters, but I doubt that noHoles would look clear for someone who haven't read the documentation.

Ideas:

  • collapseHoles
  • noWhitespaceBetweenChars

Should it default to true as well?

dbalatero avatar Sep 04 '18 21:09 dbalatero

@dbalatero noWhitespaceBetweenChars might work. Anyway it shouldn't be hard to rename before release if needed.

It should be false by default because it would be a breaking change otherwise. And since this option is undoubtfully useful only in cases with invisible maskChar, I think it's better to make it opt-in anyway.

sanniassin avatar Sep 05 '18 16:09 sanniassin

Sorry, I meant noSpaceBetweenChars because it should work with any maskChar, not only with invisible "white" ones.

sanniassin avatar Sep 05 '18 16:09 sanniassin

Sorry, I meant noSpaceBetweenChars because it should work with any maskChar, not only with invisible "white" ones.

Dig that. I can work on this PR, as long as you haven't started on it? I'll update docs as well with the new param.

dbalatero avatar Sep 05 '18 20:09 dbalatero

@dbalatero Sure, I couldn't start this week anyway. Thank you.

sanniassin avatar Sep 05 '18 20:09 sanniassin

Nice typographic hack

@dbalatero's coworker here. I design and code.

This is not a hack =). The figure space character u2007 is specifically made to be used with tabular numerals for alignment purposes. Most well-made commercial fonts come with proportional and tabular figures.

The "tnum"is short for tabular numbers. This page is great for seeing the full(ish) suite of OpenType features (there are more than 100).

Here's a little more reading on tabular vs proportional figures.

crystalcui avatar Sep 06 '18 19:09 crystalcui

@crystalcui Should have used "trick" instead of "hack" 🙂

Thanks for the links. It's always a pleasure to meet developers with a warm attitude for design and typography.

sanniassin avatar Sep 06 '18 20:09 sanniassin

@sanniassin Hey, just to let you know that I'll be starting on this today at work. Thanks!

dbalatero avatar Sep 10 '18 17:09 dbalatero

@sanniassin Did you guys get the chance to fix this issue?

mitchied avatar Apr 20 '20 18:04 mitchied

@sanniassin Did you guys get the chance to fix this issue?

<InputMask {...this.props} mask="7\9999999999" maskChar="" noSpaceBetweenChars={true}>

like 9e438dc

Lbdevaa avatar Feb 18 '22 07:02 Lbdevaa