Posted on • Originally published atstephencharlesweiss.com on
Masking Inputs And More Ref Fun
In learning aboutAuto-Complete In HTML Forms, I discovered that thetype
of an<input>
makes can make a significant difference in how they are presented to users. The differences, however, are browser specific.
Taketype="date"
for example. Chromium browsers supply quite a bit of styling for free. Safari adds nothing.
The standard inputs in the screenshots below are simply:
constapp=()=>{return({/* … */}<p>Standarddateinput</p><inputtype="date"placeholder={"dob mm/dd/yyyy"}/>{/* … */})}
To not be at the whim of a browser, I reverted back to a standard input and sought other approaches.
In this particular case, I really wanted to provide guidance to users on how to put the information in since formatting is important for the application to work properly.
To think about how this would work, I thought about passwords, but in reverse. Instead of taking a password and turning it into a string of ● (e.g.,pa$$w0rd
becomes●●●●●●●●
), I wanted a string that could be overwritten. In this case__/__ / ____
.
CSS Tricks outlined several approaches depending on the stack - vanilla JS, jQuery, etc. and also noted some accessibility considerations to bear in mind (like that certain approaches will use thevalue
of the input, not theplaceholder
to display the mask).1
I ended up selecting the libraryreact-text-mask
because of it’s support for React andstyled-components
. The latter, however, turned out to be more fun than I was expecting when I started, largely thanks torefs
.
The library provides arender
method for custom<input>
components which is noted helpfullyin the docs. Interestingly for me, the way this method works is by providing its own ref which can be passed along to the styled component.
From the docs:
For example, to use with styled-components,which requires an innerRef:
<MaskedInputmask={[‘(‘,/[1-9]/,/\d/,/\d/,‘)’,‘‘,/\d/,/\d/,/\d/,‘-‘,/\d/,/\d/,/\d/,/\d/]}placeholder="Enter a phone number"id="my-input-id"render={(ref,props)=>(<MyStyledInputinnerRef={ref}{…props}/>)}/>constMyStyledInput=styled.input`background: papayawhip;`;
Notice that the render method has an argumentref
that’s passed along to the<MyStyledInput>
? That’s provided by the component! There’s no need to create a ref in a containing component, no need foruseRef
orforwardRef
! It’s actually quite simple.
Part of my confusion lay in the demonstration of usinginnerRef
. As of v4,styled-components
do not require aninnerRef
, however, despite havingread thestyled-component
documentation, it still took a conversation with several others to understand that theinnerRef
was part of thestyled-component
api and not thereact-text-mask
. In retrospect should have been more obvious.
After all of that, I arrived at a working solution: Masking the input, guiding my users, and providing a consistent user experience across browsers and devices.
If you’re interested, you can see my prototype in aCode Sandbox.
Footnotes
- 1Input Masking | CSS-Tricks is a great start, and as noted, Estelle Wyel has a React compatible approach, though I ended up using a different library.
- 2react-text-mask | npm
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse