Pin Code
The PinCode
component is optimized for entering sequences of digits.
The most common application is for entering single-use security codes.
It is optimized for entering digits quickly.
Examples
Each input collects one digit at a time. When a digit is entered, focus transfers to the next input in the sequence, until every input is filled in. A few things to note:
- You canʼt enter anything other than a digit.
- You can only enter one character per input.
- To overwrite the value of an input, you donʼt need to select the text in the input. If you type a digit while the input is focused, the input will update. This is an optimization for quickly editing the inputs.
- Pressing
Delete
when there is nothing in the input will transfer focus to, and clear the value of, the previous input (if any). This avoids the need to explicitly Shift+Tab & Delete.
PinCode
expects an array of strings for the values
prop.
The number of inputs rendered will match the length of the array.
You can pass an individual id
or name
prop.
name
will be shared amongst the inputs, meaning they will each have their name
set to this value.
id
will have an index appended to whatever string you provide and passed to the respective input.
In the above example, the resulting ids are foo-0
, foo-1
, foo-2
, and foo-3
and each input has the name pin-code
.
PinCode
accepts most of the same boolean props as our other inputs: disabled
, error
, positive
, etc.
You can control the size of the inputs with the size
prop.
If you donʼt like the default placeholder (○
), you can change that too.
Notice how each placeholder disappears when any of the inputs have focus.
You can disable PinCode
ʼs built-in focusing logic by toggling the manageFocus
prop.
It defaults to true
, which makes it so that when an input receives a digit, focus is automatically changed to the next input.
It also transfers focus to a previous input when Delete
is pressed with focus on an empty input.
Set manageFocus
to false
if, for some reason, you donʼt want this nifty behavior.
You can use the onChange
handler to implement your own thing.
The object passed to onChange
has two properties.
values
is the new array of strings that PinCode
thinks you should update your state with.
Of course, you can decide not to use those values.
If, for some reason, you do not want to use values
, the onChange
object also includes an event
property which references the original input change event.
We do not envision a lot of scenarios where you would need this level of control- but just in case, it is there for you.
Note, if you do decide to go off the rails with event
, you may want to turn off manageFocus
as well.
Otherwise you may have focus jumping around in ways inconsistent with your customizations.
There is a decent chance that if you are using PinCode
you want it to be focused from the start.
Simply set autoFocus
to true
to focus the first input upon initial mounting of the component.
In the example above, click Mount PinCode
to ...mount the PinCode component.
With autoFocus
toggled on, the first input receives focus immediately.
It is a common pattern to immediately submit the userʼs input once the full pin code has been entered. In the above example, we shift focus to the submit button once all of our inputs have been filled in. Keep in mind that folks may have mistyped a digit so auto-submitting might be a bit aggressive.
Try copying & pasting 1234
into any of the inputs in the example above.
By default, you can only change one input at a time. But what if a user wants to copy and paste a value in? Or what if the userʼs browser can autocomplete verification codes.
If one of the individual inputs receives a longer string, PinCode
does some basic validation (is the length right? does it contain only digits?) to see if it can fill all the inputs.
If things seem promising, PinCode
will call onChange
will all of the values updated.
As with many of our components, there is also an uncontrolled version, StatefulPinCode
, which manages its own state. The default code length for this component is four, but you can change that by passing in an array of a different length to initialState
.
Overrides
Additionally, you can fully customize any part of the Pin Code through the overrides prop. The Pin Code consists of multiple subcomponents that are listed bellow and you can override each one of them. To help you identify the names of these subcomponents, you can highlight them through this selector:
Note: You should always use longhand CSS properties. Mixing shorthands and longhands will lead into strange behaviors!
Second Note: You may have noticed that the Input
override above does not highlight.
To set the background and/or border styles for an Input
component, you need to style the nested InputContainer
override like so:
API
PinCode API
"aria-label"
nullable string
= "Please enter your pin code"
Sets aria-label attribute for each input element.
"aria-labelledby"
nullable string
= null
Sets aria-labelledby attribute for each input element.
"aria-describedby"
nullable string
= null
Sets aria-describedby attribute for each input element.
autoFocus
boolean
= false
If true, the first input will be focused upon mounting.
disabled
boolean
= false
Render the component in a disabled state.
error
boolean
= false
Renders the component in an error state.
id
nullable string
= null
Sets the base id string that will be applied to the id attribute of each input element. The index of the input will be appended to this base string. Ex: id="foo"
-> id="foo-1"
, id="foo-2",
etc...
name
nullable string
= null
Sets the name attribute of each input element.
onChange
function
= () => undefined
A handler for when any pin code input changes value.
values arrayType required Arraystringevent required InputEvent => mixed
overrides
object
= {}
Root { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>*Input { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>*
placeholder
string
= "○"
Sets the placeholder text for each pin code input element.
positive
boolean
= false
Renders the component in a positive state.
required
boolean
= false
Sets the required attribute of each pin code input element.
size
$Keys<typeof SIZE>
=
Renders the component at a given size.
$Keys{ default: "default", compact: "compact", large: "large" }
manageFocus
boolean
= true
If true, when a pin code input receives a valid value, focus will be transfered to the next pin code input (until the end of the inputs).
values
arrayType
= ["", "", "", ""]
An array of values respective to each pin code input.
Arraystring
StatefulPinCode API
"aria-label"
nullable string
required
Sets aria-label attribute for each input element.
"aria-labelledby"
nullable string
required
Sets aria-labelledby attribute for each input element.
"aria-describedby"
nullable string
required
Sets aria-describedby attribute for each input element.
autoFocus
boolean
required
If true, the first input will be focused upon mounting.
disabled
boolean
required
Render the component in a disabled state.
error
boolean
required
Renders the component in an error state.
id
nullable string
required
Sets the base id string that will be applied to the id attribute of each input element. The index of the input will be appended to this base string. Ex: id="foo"
-> id="foo-1"
, id="foo-2",
etc...
name
nullable string
required
Sets the name attribute of each input element.
onChange
function
required
A handler for when any pin code input changes value.
values arrayType required Arraystringevent required InputEvent => mixed
overrides
object
required
Root { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>*Input { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>*
placeholder
string
required
Sets the placeholder text for each pin code input element.
positive
boolean
required
Renders the component in a positive state.
required
boolean
required
Sets the required attribute of each pin code input element.
size
$Keys<typeof SIZE>
required
Renders the component at a given size.
$Keys{ default: "default", compact: "compact", large: "large" }
manageFocus
boolean
required
If true, when a pin code input receives a valid value, focus will be transfered to the next pin code input (until the end of the inputs).
values
arrayType
required
An array of values respective to each pin code input.
Arraystring
initialState
object
values arrayType required Arraystring
onChange
function
values arrayType required Arraystringevent required InputEvent => mixed
stateReducer
function
function $Keys{ change: "change" }, values arrayType required Arraystring, values arrayType required Arraystring => values arrayType required Arraystring
Pin Code exports
You can import this module like so:
import {PinCode} from 'baseui/pin-code'
It exports the following components or utility functions:
- PinCode
- StatefulPinCodeContainer
- StatefulPinCode