@xsolla/xui-input-payment 0.99.0 → 0.100.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.
- package/README.md +284 -19
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,39 +1,304 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Input Payment
|
|
3
|
+
subtitle: Credit card number input with auto-detection.
|
|
4
|
+
description: A cross-platform React payment card input with automatic card type detection, payment icons display, and validation support.
|
|
5
|
+
---
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
# Input Payment
|
|
8
|
+
|
|
9
|
+
A cross-platform React payment card input that automatically detects the card type from the entered number and displays relevant payment icons.
|
|
4
10
|
|
|
5
11
|
## Installation
|
|
6
12
|
|
|
7
13
|
```bash
|
|
14
|
+
npm install @xsolla/xui-input-payment
|
|
15
|
+
# or
|
|
8
16
|
yarn add @xsolla/xui-input-payment
|
|
9
17
|
```
|
|
10
18
|
|
|
11
|
-
##
|
|
19
|
+
## Demo
|
|
20
|
+
|
|
21
|
+
### Basic Payment Input
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import * as React from 'react';
|
|
25
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
26
|
+
|
|
27
|
+
export default function BasicPayment() {
|
|
28
|
+
const [cardNumber, setCardNumber] = React.useState('');
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<InputPayment
|
|
32
|
+
value={cardNumber}
|
|
33
|
+
onChangeText={setCardNumber}
|
|
34
|
+
placeholder="Card number"
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### With Auto-Detection Callback
|
|
12
41
|
|
|
13
42
|
```tsx
|
|
43
|
+
import * as React from 'react';
|
|
44
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
45
|
+
|
|
46
|
+
export default function WithDetection() {
|
|
47
|
+
const [cardNumber, setCardNumber] = React.useState('');
|
|
48
|
+
const [cardType, setCardType] = React.useState<string | null>(null);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
<InputPayment
|
|
53
|
+
value={cardNumber}
|
|
54
|
+
onChangeText={setCardNumber}
|
|
55
|
+
onRecognizedPaymentChange={(type) => setCardType(type)}
|
|
56
|
+
/>
|
|
57
|
+
{cardType && <p>Detected: {cardType}</p>}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Different Sizes
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import * as React from 'react';
|
|
67
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
68
|
+
|
|
69
|
+
export default function Sizes() {
|
|
70
|
+
return (
|
|
71
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
72
|
+
<InputPayment size="sm" placeholder="Small" />
|
|
73
|
+
<InputPayment size="md" placeholder="Medium" />
|
|
74
|
+
<InputPayment size="lg" placeholder="Large" />
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Anatomy
|
|
81
|
+
|
|
82
|
+
```jsx
|
|
14
83
|
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
15
84
|
|
|
16
85
|
<InputPayment
|
|
17
|
-
value={cardNumber}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
86
|
+
value={cardNumber} // Card number value
|
|
87
|
+
onChangeText={setCardNumber} // Change handler
|
|
88
|
+
size="md" // Input size
|
|
89
|
+
placeholder="Card number" // Placeholder text
|
|
90
|
+
possiblePayments={['visa', 'mastercard']} // Accepted cards
|
|
91
|
+
maxVisiblePossiblePayments={5} // Max icons shown
|
|
92
|
+
recognizedPayment="visa" // Force recognized type
|
|
93
|
+
autoDetect={true} // Enable auto-detection
|
|
94
|
+
errorMessage="Invalid card" // Error message
|
|
95
|
+
disabled={false} // Disabled state
|
|
21
96
|
/>
|
|
22
97
|
```
|
|
23
98
|
|
|
24
|
-
##
|
|
99
|
+
## Examples
|
|
100
|
+
|
|
101
|
+
### Custom Accepted Cards
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import * as React from 'react';
|
|
105
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
106
|
+
|
|
107
|
+
export default function CustomCards() {
|
|
108
|
+
return (
|
|
109
|
+
<InputPayment
|
|
110
|
+
possiblePayments={['visa', 'mastercard', 'amex']}
|
|
111
|
+
maxVisiblePossiblePayments={3}
|
|
112
|
+
placeholder="We accept Visa, Mastercard, Amex"
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### With Error State
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import * as React from 'react';
|
|
122
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
123
|
+
|
|
124
|
+
export default function WithError() {
|
|
125
|
+
const [cardNumber, setCardNumber] = React.useState('');
|
|
126
|
+
const [error, setError] = React.useState('');
|
|
127
|
+
|
|
128
|
+
const validate = (value: string) => {
|
|
129
|
+
if (value.length > 0 && value.length < 13) {
|
|
130
|
+
setError('Card number too short');
|
|
131
|
+
} else {
|
|
132
|
+
setError('');
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<InputPayment
|
|
138
|
+
value={cardNumber}
|
|
139
|
+
onChangeText={(text) => {
|
|
140
|
+
setCardNumber(text);
|
|
141
|
+
validate(text);
|
|
142
|
+
}}
|
|
143
|
+
errorMessage={error}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Controlled Recognition
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
import * as React from 'react';
|
|
153
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
154
|
+
|
|
155
|
+
export default function ControlledRecognition() {
|
|
156
|
+
const [cardNumber, setCardNumber] = React.useState('');
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<InputPayment
|
|
160
|
+
value={cardNumber}
|
|
161
|
+
onChangeText={setCardNumber}
|
|
162
|
+
autoDetect={false}
|
|
163
|
+
recognizedPayment={cardNumber.startsWith('4') ? 'visa' : undefined}
|
|
164
|
+
/>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### With Icon
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import * as React from 'react';
|
|
173
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
174
|
+
import { CreditCard } from '@xsolla/xui-icons-base';
|
|
175
|
+
|
|
176
|
+
export default function WithIcon() {
|
|
177
|
+
return (
|
|
178
|
+
<InputPayment
|
|
179
|
+
icon={<CreditCard />}
|
|
180
|
+
placeholder="Enter card number"
|
|
181
|
+
/>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### In Payment Form
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import * as React from 'react';
|
|
190
|
+
import { InputPayment } from '@xsolla/xui-input-payment';
|
|
191
|
+
import { Input } from '@xsolla/xui-input';
|
|
192
|
+
import { Button } from '@xsolla/xui-button';
|
|
193
|
+
|
|
194
|
+
export default function PaymentForm() {
|
|
195
|
+
const [cardNumber, setCardNumber] = React.useState('');
|
|
196
|
+
const [cardType, setCardType] = React.useState<string | null>(null);
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<form style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 400 }}>
|
|
200
|
+
<InputPayment
|
|
201
|
+
value={cardNumber}
|
|
202
|
+
onChangeText={setCardNumber}
|
|
203
|
+
onRecognizedPaymentChange={setCardType}
|
|
204
|
+
placeholder="Card number"
|
|
205
|
+
/>
|
|
206
|
+
<div style={{ display: 'flex', gap: 16 }}>
|
|
207
|
+
<Input placeholder="MM/YY" style={{ flex: 1 }} />
|
|
208
|
+
<Input placeholder="CVV" style={{ width: 100 }} />
|
|
209
|
+
</div>
|
|
210
|
+
<Input placeholder="Cardholder name" />
|
|
211
|
+
<Button onPress={() => console.log('Submit', { cardNumber, cardType })}>
|
|
212
|
+
Pay Now
|
|
213
|
+
</Button>
|
|
214
|
+
</form>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## API Reference
|
|
25
220
|
|
|
26
221
|
### InputPayment
|
|
27
222
|
|
|
223
|
+
**InputPaymentProps:**
|
|
224
|
+
|
|
28
225
|
| Prop | Type | Default | Description |
|
|
29
|
-
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
226
|
+
| :--- | :--- | :------ | :---------- |
|
|
227
|
+
| value | `string` | - | Card number value. |
|
|
228
|
+
| onChange | `(e: ChangeEvent) => void` | - | Standard change event handler. |
|
|
229
|
+
| onChangeText | `(text: string) => void` | - | Text change handler. |
|
|
230
|
+
| size | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Input size variant. |
|
|
231
|
+
| placeholder | `string` | `"Card number"` | Placeholder text. |
|
|
232
|
+
| icon | `ReactNode` | - | Left icon. |
|
|
233
|
+
| disabled | `boolean` | `false` | Disabled state. |
|
|
234
|
+
| error | `boolean` | - | Error state indicator. |
|
|
235
|
+
| errorMessage | `string` | - | Error message text. |
|
|
236
|
+
| possiblePayments | `PaymentSystemKey[]` | See below | Accepted payment types. |
|
|
237
|
+
| maxVisiblePossiblePayments | `number` | `5` | Max payment icons shown. |
|
|
238
|
+
| recognizedPayment | `PaymentSystemKey` | - | Force recognized payment type. |
|
|
239
|
+
| onRecognizedPaymentChange | `(type: PaymentSystemKey \| null) => void` | - | Detection callback. |
|
|
240
|
+
| autoDetect | `boolean` | `true` | Enable auto-detection. |
|
|
241
|
+
| aria-label | `string` | `"Card number"` | Accessible label. |
|
|
242
|
+
| testID | `string` | - | Test identifier. |
|
|
243
|
+
|
|
244
|
+
**Default possiblePayments:**
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
['mastercard', 'visa', 'maestro', 'diners', 'amex', 'discover', 'jcb', 'unionpay']
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**PaymentSystemKey:**
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
type PaymentSystemKey =
|
|
254
|
+
| 'visa'
|
|
255
|
+
| 'mastercard'
|
|
256
|
+
| 'amex'
|
|
257
|
+
| 'diners'
|
|
258
|
+
| 'maestro'
|
|
259
|
+
| 'unionpay'
|
|
260
|
+
| 'discover'
|
|
261
|
+
| 'jcb'
|
|
262
|
+
| 'aura'
|
|
263
|
+
| 'cartesbancaires'
|
|
264
|
+
| 'cirrus'
|
|
265
|
+
| 'dankort'
|
|
266
|
+
| 'elo'
|
|
267
|
+
| 'hipercard'
|
|
268
|
+
| 'mir'
|
|
269
|
+
| 'naranja'
|
|
270
|
+
| 'paypal'
|
|
271
|
+
| 'sodexo'
|
|
272
|
+
| 'uatp';
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Card Detection
|
|
276
|
+
|
|
277
|
+
The component automatically detects card types based on BIN (Bank Identification Number) ranges:
|
|
278
|
+
|
|
279
|
+
| Card Type | BIN Pattern |
|
|
280
|
+
| :-------- | :---------- |
|
|
281
|
+
| Visa | Starts with 4 |
|
|
282
|
+
| Mastercard | 51-55 or 2221-2720 |
|
|
283
|
+
| American Express | 34, 37 |
|
|
284
|
+
| Discover | 6011, 644-649, 65 |
|
|
285
|
+
| JCB | 3528-3589 |
|
|
286
|
+
| Diners Club | 300-305, 36, 38 |
|
|
287
|
+
| UnionPay | 62 (except Discover range) |
|
|
288
|
+
| Maestro | 50, 56-69 |
|
|
289
|
+
| Mir | 2200-2204 |
|
|
290
|
+
|
|
291
|
+
## Icon Animation
|
|
292
|
+
|
|
293
|
+
- Payment icons cycle through when multiple are available
|
|
294
|
+
- When a card type is detected, other icons slide out
|
|
295
|
+
- The recognized card icon remains visible
|
|
296
|
+
- Animation is smooth with 300ms transitions
|
|
297
|
+
|
|
298
|
+
## Accessibility
|
|
299
|
+
|
|
300
|
+
- Input has `aria-label` for screen readers
|
|
301
|
+
- Error messages are linked via `aria-describedby`
|
|
302
|
+
- Payment icons have descriptive `aria-label`
|
|
303
|
+
- Disabled state is announced with `aria-disabled`
|
|
304
|
+
- `inputMode="numeric"` shows numeric keyboard on mobile
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-input-payment",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.100.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-core": "0.
|
|
17
|
-
"@xsolla/xui-icons-payment": "0.
|
|
18
|
-
"@xsolla/xui-primitives-core": "0.
|
|
16
|
+
"@xsolla/xui-core": "0.100.0",
|
|
17
|
+
"@xsolla/xui-icons-payment": "0.100.0",
|
|
18
|
+
"@xsolla/xui-primitives-core": "0.100.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"react": ">=16.8.0",
|