Pin
An input for typing pin codes / one time codes.
Showcase
import { Pin, PinLabel, PinInput, PinGroup, PinSlots, PinSlot} from '@klnjs/react-pin'import classes from './pin.module.css'
export default () => ( <Pin className={classes.pin}> <PinInput /> <PinLabel className={classes.label}>Pincode</PinLabel> <PinGroup className={classes.group}> <PinSlots> {({ slot }) => ( <PinSlot key={slot} slot={slot} className={classes.slot} /> )} </PinSlots> </PinGroup> </Pin>)
.pin { display: flex; gap: 16px; align-items: center; flex-direction: column;}
.group { display: flex; gap: 8px; align-items: center;}
.label { font-size: 22px;}
.slot { display: flex; align-items: center; justify-content: center; position: relative; height: 56px; width: 56px; line-height: 56px; cursor: text; border-radius: 0.5rem; border: 1px solid var(--sl-color-hairline-light); overflow: hidden; background: var(--sl-color-black); background-clip: padding-box;}
.slot:hover { color: var(--sl-color-white); border-color: var(--sl-color-white);}
.slot[data-focused] { border-color: var(--sl-color-accent-high);}
.slot[data-concealed] { font-size: 64px;}
.slot[data-placeholder] { color: var(--sl-color-hairline-light);}
.slot[data-caret]::after { display: block; content: ''; position: absolute; width: 1px; height: 26px; animation: blink 1.2s ease-out infinite; background: var(--sl-color-accent-high);}
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; }}
Features
-
Controlled or uncontrolled.
-
Concealing the pin while typing.
-
Auto complete one time codes.
Installation
bun install @klnjs/react-pin
Definitions
Pin (Root)
Contains all the parts of a pin.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
PinType | - | |
PinConceal | - | |
PinDirection | - | |
PinSlotItem | - |
Components
Contains all the parts of a pin. Use the conceal
property to conceal the pin while typing, and the type
to determine the allowed characters. Use value
or defaultValue
to control the input and onChange
to listen to changes.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
conceal | PinConceal | false |
defaultValue | string | - |
disabled | boolean | false |
length | number | 4 |
type | PinType | alphanumeric |
value | string | - |
onChange | (value: string) => void | - |
Input
Used to render a hidden input which is accessible by keyboard. The input can be shown by setting hidden
to false. It will auto complete one time codes by default, and handle sanitising of input based on root property type
.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
autoComplete | string | one-time-code |
hidden | boolean | true |
Label
Used to optionally render an input label, and attach it to the input so it is accessible. If omitted, you should add a label to the input with property aria-label
, so the component stays accessible.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
Group
Used to group slot items.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
Slots
Given the dynamic length of the pin, this utility component provides means to render slots of the pin using a render function as child.
Prop | Type | Default |
---|---|---|
children | (item: PinSlotItem) => ReactNode | - |
Slot
Used to render individual slots, it should be used in conjunction with the slots component. A slot will conceal its content based on the root property conceal
, this concealing only occurs when slot has an internal value.
Clicking a slot will focus the input, therefore focus events should be attached to the input. The slot is primarily visual, and it provides data-*
attributes enabling styling of the different states.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
placeholder | string | - |
Data attribute | Present when |
---|---|
data-caret | caret is shown |
data-concealed | slot is concealed |
data-disabled | slot is disabled |
data-end | slot is last slot |
data-focused | slot is focused |
data-placeholder | placeholder is shown |
data-start | slot is first slot |