@reevit/core 0.1.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.
@@ -0,0 +1,526 @@
1
+ /**
2
+ * @reevit/react - Checkout Widget Styles
3
+ * Default styles for the Reevit payment widget
4
+ */
5
+
6
+ /* CSS Variables for theming */
7
+ :root {
8
+ --reevit-primary: #0066ff;
9
+ --reevit-primary-hover: #0052cc;
10
+ --reevit-background: #ffffff;
11
+ --reevit-surface: #f8fafc;
12
+ --reevit-border: #e2e8f0;
13
+ --reevit-text: #1a1a2e;
14
+ --reevit-text-secondary: #64748b;
15
+ --reevit-success: #10b981;
16
+ --reevit-error: #ef4444;
17
+ --reevit-warning: #f59e0b;
18
+ --reevit-radius: 12px;
19
+ --reevit-radius-sm: 8px;
20
+ --reevit-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
21
+ --reevit-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
22
+ --reevit-shadow-sm: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
23
+ }
24
+
25
+ /* Dark mode support */
26
+ @media (prefers-color-scheme: dark) {
27
+ :root {
28
+ --reevit-background: #1a1a2e;
29
+ --reevit-surface: #252542;
30
+ --reevit-border: #3f3f5a;
31
+ --reevit-text: #ffffff;
32
+ --reevit-text-secondary: #a0a0b2;
33
+ }
34
+ }
35
+
36
+ /* ===== OVERLAY ===== */
37
+ .reevit-overlay {
38
+ position: fixed;
39
+ inset: 0;
40
+ background: rgba(0, 0, 0, 0.6);
41
+ backdrop-filter: blur(4px);
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ z-index: 9999;
46
+ padding: 16px;
47
+ animation: reevit-fade-in 0.2s ease-out;
48
+ }
49
+
50
+ @keyframes reevit-fade-in {
51
+ from { opacity: 0; }
52
+ to { opacity: 1; }
53
+ }
54
+
55
+ /* ===== MODAL ===== */
56
+ .reevit-modal {
57
+ background: var(--reevit-background);
58
+ border-radius: var(--reevit-radius);
59
+ box-shadow: var(--reevit-shadow);
60
+ width: 100%;
61
+ max-width: 420px;
62
+ max-height: 90vh;
63
+ overflow: hidden;
64
+ display: flex;
65
+ flex-direction: column;
66
+ font-family: var(--reevit-font);
67
+ animation: reevit-slide-up 0.3s ease-out;
68
+ }
69
+
70
+ @keyframes reevit-slide-up {
71
+ from {
72
+ opacity: 0;
73
+ transform: translateY(20px) scale(0.98);
74
+ }
75
+ to {
76
+ opacity: 1;
77
+ transform: translateY(0) scale(1);
78
+ }
79
+ }
80
+
81
+ .reevit-modal--success {
82
+ border: 2px solid var(--reevit-success);
83
+ }
84
+
85
+ /* Modal Header */
86
+ .reevit-modal__header {
87
+ display: flex;
88
+ align-items: center;
89
+ justify-content: space-between;
90
+ padding: 16px 20px;
91
+ border-bottom: 1px solid var(--reevit-border);
92
+ }
93
+
94
+ .reevit-modal__branding {
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 8px;
98
+ }
99
+
100
+ .reevit-modal__logo {
101
+ font-size: 18px;
102
+ font-weight: 700;
103
+ color: var(--reevit-text);
104
+ letter-spacing: -0.5px;
105
+ }
106
+
107
+ .reevit-modal__close {
108
+ width: 32px;
109
+ height: 32px;
110
+ border-radius: 8px;
111
+ border: none;
112
+ background: var(--reevit-surface);
113
+ color: var(--reevit-text-secondary);
114
+ font-size: 18px;
115
+ cursor: pointer;
116
+ display: flex;
117
+ align-items: center;
118
+ justify-content: center;
119
+ transition: all 0.15s ease;
120
+ }
121
+
122
+ .reevit-modal__close:hover {
123
+ background: var(--reevit-border);
124
+ color: var(--reevit-text);
125
+ }
126
+
127
+ /* Modal Amount */
128
+ .reevit-modal__amount {
129
+ padding: 24px 20px;
130
+ text-align: center;
131
+ background: linear-gradient(135deg, var(--reevit-primary) 0%, #0052cc 100%);
132
+ color: white;
133
+ }
134
+
135
+ .reevit-modal__amount-label {
136
+ display: block;
137
+ font-size: 12px;
138
+ text-transform: uppercase;
139
+ letter-spacing: 1px;
140
+ opacity: 0.8;
141
+ margin-bottom: 4px;
142
+ }
143
+
144
+ .reevit-modal__amount-value {
145
+ display: block;
146
+ font-size: 32px;
147
+ font-weight: 700;
148
+ letter-spacing: -1px;
149
+ }
150
+
151
+ /* Modal Content */
152
+ .reevit-modal__content {
153
+ flex: 1;
154
+ overflow-y: auto;
155
+ padding: 20px;
156
+ }
157
+
158
+ /* Modal Footer */
159
+ .reevit-modal__footer {
160
+ padding: 12px 20px;
161
+ border-top: 1px solid var(--reevit-border);
162
+ text-align: center;
163
+ }
164
+
165
+ .reevit-modal__secured {
166
+ font-size: 12px;
167
+ color: var(--reevit-text-secondary);
168
+ }
169
+
170
+ /* ===== PAYMENT METHOD SELECTOR ===== */
171
+ .reevit-method-selector {
172
+ margin-bottom: 20px;
173
+ }
174
+
175
+ .reevit-method-selector__label {
176
+ font-size: 14px;
177
+ font-weight: 600;
178
+ color: var(--reevit-text);
179
+ margin-bottom: 12px;
180
+ }
181
+
182
+ .reevit-method-selector__options {
183
+ display: flex;
184
+ flex-direction: column;
185
+ gap: 10px;
186
+ }
187
+
188
+ .reevit-method-option {
189
+ display: flex;
190
+ align-items: center;
191
+ gap: 12px;
192
+ padding: 14px 16px;
193
+ background: var(--reevit-surface);
194
+ border: 2px solid var(--reevit-border);
195
+ border-radius: var(--reevit-radius-sm);
196
+ cursor: pointer;
197
+ transition: all 0.15s ease;
198
+ text-align: left;
199
+ width: 100%;
200
+ }
201
+
202
+ .reevit-method-option:hover {
203
+ border-color: var(--reevit-primary);
204
+ background: var(--reevit-background);
205
+ }
206
+
207
+ .reevit-method-option--selected {
208
+ border-color: var(--reevit-primary);
209
+ background: rgba(0, 102, 255, 0.05);
210
+ }
211
+
212
+ .reevit-method-option--disabled {
213
+ opacity: 0.5;
214
+ cursor: not-allowed;
215
+ }
216
+
217
+ .reevit-method-option__icon {
218
+ font-size: 24px;
219
+ flex-shrink: 0;
220
+ }
221
+
222
+ .reevit-method-option__content {
223
+ flex: 1;
224
+ min-width: 0;
225
+ }
226
+
227
+ .reevit-method-option__label {
228
+ display: block;
229
+ font-size: 15px;
230
+ font-weight: 600;
231
+ color: var(--reevit-text);
232
+ }
233
+
234
+ .reevit-method-option__description {
235
+ display: block;
236
+ font-size: 12px;
237
+ color: var(--reevit-text-secondary);
238
+ margin-top: 2px;
239
+ }
240
+
241
+ .reevit-method-option__check {
242
+ color: var(--reevit-primary);
243
+ flex-shrink: 0;
244
+ }
245
+
246
+ /* ===== MOBILE MONEY FORM ===== */
247
+ .reevit-momo-form {
248
+ display: flex;
249
+ flex-direction: column;
250
+ gap: 20px;
251
+ }
252
+
253
+ .reevit-momo-form__field {
254
+ display: flex;
255
+ flex-direction: column;
256
+ gap: 8px;
257
+ }
258
+
259
+ .reevit-momo-form__label {
260
+ font-size: 14px;
261
+ font-weight: 600;
262
+ color: var(--reevit-text);
263
+ }
264
+
265
+ .reevit-momo-form__input {
266
+ padding: 12px 16px;
267
+ font-size: 16px;
268
+ border: 2px solid var(--reevit-border);
269
+ border-radius: var(--reevit-radius-sm);
270
+ background: var(--reevit-background);
271
+ color: var(--reevit-text);
272
+ transition: all 0.15s ease;
273
+ font-family: var(--reevit-font);
274
+ }
275
+
276
+ .reevit-momo-form__input:focus {
277
+ outline: none;
278
+ border-color: var(--reevit-primary);
279
+ box-shadow: 0 0 0 3px rgba(0, 102, 255, 0.1);
280
+ }
281
+
282
+ .reevit-momo-form__input--error {
283
+ border-color: var(--reevit-error);
284
+ }
285
+
286
+ .reevit-momo-form__input--error:focus {
287
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
288
+ }
289
+
290
+ .reevit-momo-form__formatted {
291
+ font-size: 12px;
292
+ color: var(--reevit-text-secondary);
293
+ }
294
+
295
+ .reevit-momo-form__error {
296
+ font-size: 12px;
297
+ color: var(--reevit-error);
298
+ }
299
+
300
+ .reevit-momo-form__networks {
301
+ display: flex;
302
+ gap: 10px;
303
+ }
304
+
305
+ .reevit-network-btn {
306
+ flex: 1;
307
+ padding: 12px 16px;
308
+ font-size: 14px;
309
+ font-weight: 600;
310
+ border: 2px solid var(--reevit-border);
311
+ border-radius: var(--reevit-radius-sm);
312
+ background: var(--reevit-surface);
313
+ color: var(--reevit-text);
314
+ cursor: pointer;
315
+ transition: all 0.15s ease;
316
+ font-family: var(--reevit-font);
317
+ }
318
+
319
+ .reevit-network-btn:hover {
320
+ border-color: var(--network-color, var(--reevit-primary));
321
+ }
322
+
323
+ .reevit-network-btn--selected {
324
+ border-color: var(--network-color, var(--reevit-primary));
325
+ background: var(--network-color, var(--reevit-primary));
326
+ color: #000;
327
+ }
328
+
329
+ .reevit-momo-form__actions {
330
+ display: flex;
331
+ gap: 12px;
332
+ margin-top: 8px;
333
+ }
334
+
335
+ .reevit-momo-form__hint {
336
+ font-size: 12px;
337
+ color: var(--reevit-text-secondary);
338
+ text-align: center;
339
+ margin-top: 8px;
340
+ }
341
+
342
+ /* ===== BUTTONS ===== */
343
+ .reevit-btn {
344
+ display: inline-flex;
345
+ align-items: center;
346
+ justify-content: center;
347
+ gap: 8px;
348
+ padding: 12px 24px;
349
+ font-size: 15px;
350
+ font-weight: 600;
351
+ border-radius: var(--reevit-radius-sm);
352
+ cursor: pointer;
353
+ transition: all 0.15s ease;
354
+ font-family: var(--reevit-font);
355
+ border: none;
356
+ min-height: 48px;
357
+ }
358
+
359
+ .reevit-btn--primary {
360
+ flex: 1;
361
+ background: var(--reevit-primary);
362
+ color: white;
363
+ }
364
+
365
+ .reevit-btn--primary:hover:not(:disabled) {
366
+ background: var(--reevit-primary-hover);
367
+ }
368
+
369
+ .reevit-btn--primary:disabled {
370
+ opacity: 0.5;
371
+ cursor: not-allowed;
372
+ }
373
+
374
+ .reevit-btn--secondary {
375
+ background: var(--reevit-surface);
376
+ color: var(--reevit-text);
377
+ border: 2px solid var(--reevit-border);
378
+ }
379
+
380
+ .reevit-btn--secondary:hover:not(:disabled) {
381
+ background: var(--reevit-border);
382
+ }
383
+
384
+ .reevit-trigger-btn {
385
+ padding: 12px 24px;
386
+ font-size: 15px;
387
+ font-weight: 600;
388
+ background: var(--reevit-primary);
389
+ color: white;
390
+ border: none;
391
+ border-radius: var(--reevit-radius-sm);
392
+ cursor: pointer;
393
+ font-family: var(--reevit-font);
394
+ transition: all 0.15s ease;
395
+ }
396
+
397
+ .reevit-trigger-btn:hover {
398
+ background: var(--reevit-primary-hover);
399
+ }
400
+
401
+ /* ===== STATES ===== */
402
+ .reevit-loading,
403
+ .reevit-success,
404
+ .reevit-error {
405
+ display: flex;
406
+ flex-direction: column;
407
+ align-items: center;
408
+ justify-content: center;
409
+ padding: 40px 20px;
410
+ text-align: center;
411
+ gap: 16px;
412
+ }
413
+
414
+ .reevit-success__icon {
415
+ width: 64px;
416
+ height: 64px;
417
+ border-radius: 50%;
418
+ background: var(--reevit-success);
419
+ color: white;
420
+ font-size: 32px;
421
+ display: flex;
422
+ align-items: center;
423
+ justify-content: center;
424
+ animation: reevit-pop 0.3s ease-out;
425
+ }
426
+
427
+ .reevit-error__icon {
428
+ width: 64px;
429
+ height: 64px;
430
+ border-radius: 50%;
431
+ background: var(--reevit-error);
432
+ color: white;
433
+ font-size: 32px;
434
+ display: flex;
435
+ align-items: center;
436
+ justify-content: center;
437
+ }
438
+
439
+ @keyframes reevit-pop {
440
+ 0% { transform: scale(0); }
441
+ 50% { transform: scale(1.2); }
442
+ 100% { transform: scale(1); }
443
+ }
444
+
445
+ .reevit-success h3,
446
+ .reevit-error h3 {
447
+ font-size: 18px;
448
+ font-weight: 600;
449
+ color: var(--reevit-text);
450
+ margin: 0;
451
+ }
452
+
453
+ .reevit-success p,
454
+ .reevit-error p {
455
+ font-size: 14px;
456
+ color: var(--reevit-text-secondary);
457
+ margin: 0;
458
+ }
459
+
460
+ /* ===== SPINNER ===== */
461
+ .reevit-spinner {
462
+ width: 24px;
463
+ height: 24px;
464
+ border: 3px solid var(--reevit-border);
465
+ border-top-color: var(--reevit-primary);
466
+ border-radius: 50%;
467
+ animation: reevit-spin 0.8s linear infinite;
468
+ }
469
+
470
+ @keyframes reevit-spin {
471
+ to { transform: rotate(360deg); }
472
+ }
473
+
474
+ /* Large spinner for loading states */
475
+ .reevit-loading .reevit-spinner {
476
+ width: 48px;
477
+ height: 48px;
478
+ border-width: 4px;
479
+ }
480
+
481
+ /* ===== PSP BRIDGE ===== */
482
+ .reevit-psp-bridge {
483
+ display: flex;
484
+ flex-direction: column;
485
+ align-items: center;
486
+ justify-content: center;
487
+ padding: 40px 20px;
488
+ text-align: center;
489
+ gap: 16px;
490
+ }
491
+
492
+ .reevit-psp-bridge__loading p {
493
+ font-size: 14px;
494
+ color: var(--reevit-text-secondary);
495
+ margin: 0;
496
+ }
497
+
498
+ /* ===== METHOD STEP ACTIONS ===== */
499
+ .reevit-method-step__actions {
500
+ margin-top: 20px;
501
+ }
502
+
503
+ /* ===== RESPONSIVE ===== */
504
+ @media (max-width: 480px) {
505
+ .reevit-modal {
506
+ max-width: 100%;
507
+ max-height: 100%;
508
+ border-radius: 0;
509
+ }
510
+
511
+ .reevit-modal__amount-value {
512
+ font-size: 28px;
513
+ }
514
+
515
+ .reevit-momo-form__networks {
516
+ flex-direction: column;
517
+ }
518
+
519
+ .reevit-momo-form__actions {
520
+ flex-direction: column-reverse;
521
+ }
522
+
523
+ .reevit-btn--secondary {
524
+ flex: none;
525
+ }
526
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@reevit/core",
3
+ "version": "0.1.0",
4
+ "description": "Core utilities and API client for Reevit payment SDKs",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./styles.css": "./dist/styles.css"
15
+ },
16
+ "files": ["dist"],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "dev": "tsup --watch",
20
+ "typecheck": "tsc --noEmit"
21
+ },
22
+ "keywords": ["reevit", "payments", "africa", "sdk"],
23
+ "author": "Reevit",
24
+ "license": "MIT",
25
+ "homepage": "https://github.com/Reevit-Platform/core#readme",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/Reevit-Platform/core.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/Reevit-Platform/core/issues"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^20.0.0",
35
+ "tsup": "^8.0.0",
36
+ "typescript": "^5.0.0"
37
+ }
38
+ }