@xsolla/xui-input-pin 0.174.2 → 0.175.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +66 -0
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -1,6 +1,72 @@
1
1
  # Input Pin
2
2
 
3
3
  A cross-platform React PIN/OTP input component with individual cells for each digit. Features auto-advance between cells, paste support, and completion callbacks.
4
+ <!-- BEGIN:xui-mcp-instructions:input-pin -->
5
+ A specialised input for entering a short numeric or alphanumeric code — typically a PIN, OTP (one-time password), or verification code. Renders as a horizontal row of individual character cells (.pin-item), one per expected digit. Each cell has independent state, and the component supports masking, placeholder dots, and a visibility toggle.
6
+
7
+ ### When to use
8
+ - For entering a PIN, OTP, SMS verification code, or 2FA code
9
+ - When a fixed-length code must be collected and each character should be visually distinct and finger-friendly
10
+ - In authentication flows, payment confirmation screens, and account verification modals
11
+ - When real-time digit-by-digit visual feedback improves the entry experience
12
+
13
+ ### When not to use
14
+
15
+ - For variable-length passwords — use InputPassword
16
+ - For long codes (more than 8 characters) that do not benefit from individual cell rendering — use a standard Input with masking
17
+ - For alphanumeric codes where the user must type non-numeric characters (letters) that are already clearly visible — use a styled Input instead of a PIN field
18
+ - When the code length is unknown ahead of time — InputPin requires a fixed number of cells
19
+
20
+ ### Behaviour guidelines
21
+
22
+ Auto-advance — after the user types a digit into the active cell, focus automatically moves to the next empty cell. The user should never need to manually click individual cells.
23
+
24
+ Auto-submit — when the last cell receives a value and all cells are filled (State=Filled), submit the form automatically without requiring the user to press Enter or a Submit button. This is the expected UX for OTP and PIN flows.
25
+
26
+ Backspace — pressing Backspace clears the value in the current active cell and moves focus back to the previous cell. If the active cell is already empty, Backspace moves focus back and clears the previous cell.
27
+
28
+ Paste — when the user pastes a string of the correct length, distribute the characters across all cells immediately and submit if auto-submit is enabled. Trim whitespace and hyphens from pasted values (e.g. 1234 5678 → 12345678).
29
+
30
+ Numeric-only enforcement — for numeric PINs/OTPs, reject non-numeric characters silently (do not show an error for a single wrong keypress — just ignore it). Use inputmode=*"numeric"* to trigger a numeric keyboard on mobile.
31
+
32
+ Error state — switch to State=Error when the code fails server-side validation (wrong OTP, expired code, incorrect PIN). All cells switch to error appearance simultaneously. Show a specific error message below the component. Clear the error state when the user starts typing again and reset all cells.
33
+
34
+ OTP code expiry — for time-based OTPs, show a countdown timer or *"Resend code"* link near the component. If the code expires mid-entry, show State=Error with the message *"Code has expired. Request a new one."*
35
+
36
+ Resend flow — after an error due to expiry or incorrect code, provide a *"Resend code"* action that clears all cells, resets to State=Default, and moves focus to the first cell.
37
+
38
+ Disabled state — use State=Disable when the PIN entry is temporarily locked (e.g. too many failed attempts). Show a reason nearby (e.g. *"Too many attempts. Try again in 30 seconds."*).
39
+
40
+ Mobile keyboard — use inputmode=*"numeric"* and pattern=*"[0-9]*"* on the underlying input. Consider rendering a single hidden text input that captures keystrokes and distributes characters to the visual cells, rather than using multiple separate <input> elements.
41
+
42
+ ### Content guidelines
43
+
44
+ Label — always provide a visible label above the component: *"Enter PIN"*, *"Verification code"*, *"Enter the 6-digit code sent to +7 (900) •••• 1234"*. Include the code length and delivery channel in the label for OTP flows.
45
+ Error messages — be specific and actionable:
46
+ - *"Incorrect PIN. 2 attempts remaining."*
47
+ - *"Code expired. Request a new code below."*
48
+ - *"Incorrect code. Please try again."*
49
+ - Resend link label — use *"Resend code"* or *"Send a new code"*. Include a cooldown timer: *"Resend code in 0:45"*.
50
+ - Placeholder dot vs empty — prefer Placeholder-dots=True for PIN entry screens where the digit count helps the user count positions. Use Placeholder-dots=False for cleaner designs where the code length is communicated in the label.
51
+
52
+ ### Accessibility
53
+
54
+ The underlying input mechanism must be accessible via keyboard. The preferred implementation is a single visually-hidden <input> element that captures keyboard input and distributes it to the visual cells — this avoids focus-management complexity across multiple inputs.
55
+
56
+ If multiple <input> elements are used (one per cell), each must have aria-label identifying the position: e.g. aria-label=*"Digit 1 of 6"*.
57
+
58
+ The component container must have aria-label describing the whole field: e.g. aria-label=*"6-digit verification code"*.
59
+
60
+ When State=Error, the error message must be in an aria-live=*"polite"* region and associated via aria-describedby so screen readers announce it.
61
+
62
+ The visual dot masking is cosmetic — the underlying <input> must still use type=*"password"* (or inputmode=*"numeric"* on a text input with custom masking) to ensure the value is treated as sensitive.
63
+
64
+ Auto-advance (moving focus to the next cell) must also move focus for keyboard users, not just update visual state.
65
+
66
+ When the last cell is filled and the form is auto-submitted, announce the submission to screen readers via aria-live=*"assertive"* or by focussing a confirmation message.
67
+
68
+ Ensure a minimum touch target of 44 × 44 px on mobile. For XS [32] and S [40] sizes, add layout padding to meet this requirement.
69
+ <!-- END:xui-mcp-instructions:input-pin -->
4
70
 
5
71
  ## Installation
6
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-input-pin",
3
- "version": "0.174.2",
3
+ "version": "0.175.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,9 +13,9 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-button": "0.174.2",
17
- "@xsolla/xui-core": "0.174.2",
18
- "@xsolla/xui-primitives-core": "0.174.2"
16
+ "@xsolla/xui-button": "0.175.0",
17
+ "@xsolla/xui-core": "0.175.0",
18
+ "@xsolla/xui-primitives-core": "0.175.0"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=16.8.0",