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