Description
How the library works (fundamentals)
input-otp
is an accessible input that renders:
- a 100% unstyled UI layer (custom to your design system) with
pointer-events:none
- an overlay layer (native
<input />
) withpointer-events:all
andposition:absolute
inset:0
.
In short: it's 1 underlying native input as an overlay on top of N layers of render.
However, the core implementation has some limitations. The known limits are:
Visual (UI) limitations
iOS selections are always visible.
PS: iOS copy-paste touch callout menus can't be triggered if the selection is <1px in width.
iOS don't provide a way to style input::selection
in CSS, we end up with a non-transparent selection when at least 1 char of the input is selected within the underlying input. I'm applying super negative letter-spacing to ensure the visible selection becomes as thin as possible (=1px) but can't render smaller than 1px otherwise iOS touch callout doesn't pop up.
CleanShot.2024-03-11.at.12.59.21.mp4
This would barely go noticed in a normal OTP flow where the user types in an OTP code or autofills it from his password manager. The user wouldn't even notice the selection as developers usually choose to automatically submit the form using <input onComplete
prop so there's no time to look at 1px selections.
[Mobile] Firefox shows quote markers in left+right corners of the selection.
TODO: add image
Behavior (UX) limitations
Click/touch/touchmove-to-select slots
The user cannot click/touch/hold-move and select a slot since the native input's letters are shrinked into a ~1px thin width due to added CSS letter-spacing:-.5em
, resulting in all characters being a ultra thin condensed area. Unfortunately, the user cannot manually choose his selection by mouse/touch, only by keyboard.
The expected behavior would be:
CleanShot.2024-03-11.at.13.17.19.mp4
The video above has been a feature request.
Related issues by the community are #31
Activity