@monei-js/react-components 2.0.1

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 ADDED
@@ -0,0 +1,132 @@
1
+ # @monei-js/react-components
2
+
3
+ React components for MONEI payments. Typed props, `ref`-based `submit()`, and idiomatic React API.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @monei-js/react-components @monei-js/components
9
+ ```
10
+
11
+ ## Components
12
+
13
+ | Component | Description |
14
+ | ---------------- | ------------------------------------------ |
15
+ | `CardInput` | Secure card input (iframe) with `submit()` |
16
+ | `Bizum` | Bizum button + phone verification modal |
17
+ | `PayPal` | PayPal checkout button |
18
+ | `PaymentRequest` | Apple Pay / browser Payment Request button |
19
+
20
+ ## Quick Start
21
+
22
+ ```tsx
23
+ import {useRef} from 'react';
24
+ import {CardInput, type CardInputHandle} from '@monei-js/react-components';
25
+ import {confirmPayment} from '@monei-js/components';
26
+
27
+ function PaymentForm({paymentId}: {paymentId: string}) {
28
+ const cardRef = useRef<CardInputHandle>(null);
29
+
30
+ const handleSubmit = async () => {
31
+ const {token, error} = await cardRef.current!.submit();
32
+ if (error) return console.error(error);
33
+ await confirmPayment({paymentId, paymentToken: token});
34
+ };
35
+
36
+ return (
37
+ <div>
38
+ <CardInput ref={cardRef} paymentId={paymentId} />
39
+ <button onClick={handleSubmit}>Pay</button>
40
+ </div>
41
+ );
42
+ }
43
+ ```
44
+
45
+ ## Dual-import pattern
46
+
47
+ Components come from this package. API functions and types come from the base package:
48
+
49
+ ```tsx
50
+ import {CardInput, Bizum} from '@monei-js/react-components';
51
+ import {confirmPayment, api} from '@monei-js/components';
52
+ import type {PaymentStatus} from '@monei-js/components';
53
+ ```
54
+
55
+ ## Migrating from `.driver('react')`
56
+
57
+ ### Import changes
58
+
59
+ Before:
60
+
61
+ ```tsx
62
+ import {CardInput, Bizum, PayPal, PaymentRequest, createToken} from '@monei-js/components';
63
+ import React, {useRef} from 'react';
64
+
65
+ const ReactCardInput = CardInput.driver('react', {React});
66
+ const ReactBizum = Bizum.driver('react', {React});
67
+ const ReactPayPal = PayPal.driver('react', {React});
68
+ const ReactPaymentRequest = PaymentRequest.driver('react', {React});
69
+ ```
70
+
71
+ After:
72
+
73
+ ```tsx
74
+ import {CardInput, Bizum, PayPal, PaymentRequest} from '@monei-js/react-components';
75
+ ```
76
+
77
+ ### submit() migration
78
+
79
+ Before (standalone `createToken`):
80
+
81
+ ```tsx
82
+ import {createToken} from '@monei-js/components';
83
+
84
+ const ref = useRef(null);
85
+ // ...
86
+ const {token} = await createToken(ref.current, {cardholderName: 'John'});
87
+ ```
88
+
89
+ After (instance `submit()`):
90
+
91
+ ```tsx
92
+ import {CardInput, type CardInputHandle} from '@monei-js/react-components';
93
+
94
+ const ref = useRef<CardInputHandle>(null);
95
+ // ...
96
+ const {token} = await ref.current!.submit({cardholderName: 'John'});
97
+ ```
98
+
99
+ ### Full example
100
+
101
+ ```tsx
102
+ import {useRef, useState} from 'react';
103
+ import {CardInput, type CardInputHandle} from '@monei-js/react-components';
104
+ import {confirmPayment} from '@monei-js/components';
105
+
106
+ function PaymentForm({paymentId}: {paymentId: string}) {
107
+ const cardRef = useRef<CardInputHandle>(null);
108
+ const [error, setError] = useState('');
109
+
110
+ const handleSubmit = async () => {
111
+ const {token, error} = await cardRef.current!.submit();
112
+ if (error) return setError(error);
113
+ await confirmPayment({paymentId, paymentToken: token});
114
+ };
115
+
116
+ return (
117
+ <div>
118
+ <CardInput ref={cardRef} paymentId={paymentId} onChange={({isValid}) => setError('')} />
119
+ <button onClick={handleSubmit}>Pay</button>
120
+ {error && <p>{error}</p>}
121
+ </div>
122
+ );
123
+ }
124
+ ```
125
+
126
+ ## Documentation
127
+
128
+ Full API reference: [docs.monei.com/monei-js/reference](https://docs.monei.com/monei-js/reference/)
129
+
130
+ ## License
131
+
132
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,103 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let _monei_js_components = require("@monei-js/components");
25
+ let react = require("react");
26
+ react = __toESM(react);
27
+ //#region src/create-bridge-component.ts
28
+ /**
29
+ * Creates a React wrapper for a bridge component.
30
+ *
31
+ * - On mount: creates bridge instance, renders into container div
32
+ * - On update: shallow-compares props, calls updateProps on change
33
+ * - On unmount: calls destroy
34
+ * - If `imperativeHandle` is provided, exposes the handle via ref AFTER render resolves
35
+ * (deferred ref — not useImperativeHandle which runs synchronously before connection)
36
+ */
37
+ function createBridgeComponent(Constructor, imperativeHandle) {
38
+ return react.default.forwardRef(function BridgeReactWrapper(props, ref) {
39
+ const containerRef = react.default.useRef(null);
40
+ const instanceRef = react.default.useRef(null);
41
+ const isMounted = react.default.useRef(false);
42
+ const prevPropsRef = react.default.useRef({});
43
+ react.default.useLayoutEffect(() => {
44
+ const el = containerRef.current;
45
+ if (!el) return;
46
+ let cancelled = false;
47
+ const instance = new Constructor({ ...props });
48
+ instanceRef.current = instance;
49
+ instance.render(el).then(() => {
50
+ if (cancelled) return;
51
+ if (imperativeHandle && ref) setRef(ref, imperativeHandle(instance));
52
+ isMounted.current = true;
53
+ prevPropsRef.current = { ...props };
54
+ }).catch((err) => {
55
+ if (!cancelled) console.error(err);
56
+ });
57
+ return () => {
58
+ cancelled = true;
59
+ instance.destroy();
60
+ instanceRef.current = null;
61
+ isMounted.current = false;
62
+ if (imperativeHandle && ref) setRef(ref, null);
63
+ };
64
+ }, []);
65
+ react.default.useEffect(() => {
66
+ if (!isMounted.current || !instanceRef.current) return;
67
+ if (shallowEqual(prevPropsRef.current, props)) return;
68
+ prevPropsRef.current = { ...props };
69
+ instanceRef.current.updateProps({ ...props }).catch(noop);
70
+ });
71
+ return react.default.createElement("div", { ref: containerRef });
72
+ });
73
+ }
74
+ /** Set a React ref (callback or object ref) */
75
+ function setRef(ref, value) {
76
+ if (typeof ref === "function") ref(value);
77
+ else if (ref && typeof ref === "object" && "current" in ref) ref.current = value;
78
+ }
79
+ function shallowEqual(a, b) {
80
+ const keysA = Object.keys(a);
81
+ const keysB = Object.keys(b);
82
+ if (keysA.length !== keysB.length) return false;
83
+ for (const key of keysA) if (a[key] !== b[key]) return false;
84
+ return true;
85
+ }
86
+ function noop() {}
87
+ //#endregion
88
+ //#region src/card-input.ts
89
+ const CardInput = createBridgeComponent(_monei_js_components.CardInput, (instance) => ({ submit: (opts) => instance.submit(opts) }));
90
+ //#endregion
91
+ //#region src/bizum.ts
92
+ const Bizum = createBridgeComponent(_monei_js_components.Bizum);
93
+ //#endregion
94
+ //#region src/paypal.ts
95
+ const PayPal = createBridgeComponent(_monei_js_components.PayPal);
96
+ //#endregion
97
+ //#region src/payment-request.ts
98
+ const PaymentRequest = createBridgeComponent(_monei_js_components.PaymentRequest);
99
+ //#endregion
100
+ exports.Bizum = Bizum;
101
+ exports.CardInput = CardInput;
102
+ exports.PayPal = PayPal;
103
+ exports.PaymentRequest = PaymentRequest;
@@ -0,0 +1,16 @@
1
+ import * as react from "react";
2
+ import { BizumComponentProps, BizumComponentProps as BizumComponentProps$1, CardInputComponentProps, CardInputComponentProps as CardInputComponentProps$1, CardInputHandle, CardInputHandle as CardInputHandle$1, PayPalComponentProps, PayPalComponentProps as PayPalComponentProps$1, PaymentRequestComponentProps, PaymentRequestComponentProps as PaymentRequestComponentProps$1 } from "@monei-js/components";
3
+
4
+ //#region src/card-input.d.ts
5
+ declare const CardInput: react.ForwardRefExoticComponent<CardInputComponentProps$1 & react.RefAttributes<CardInputHandle$1>>;
6
+ //#endregion
7
+ //#region src/bizum.d.ts
8
+ declare const Bizum: react.ForwardRefExoticComponent<BizumComponentProps$1 & react.RefAttributes<unknown>>;
9
+ //#endregion
10
+ //#region src/paypal.d.ts
11
+ declare const PayPal: react.ForwardRefExoticComponent<PayPalComponentProps$1 & react.RefAttributes<unknown>>;
12
+ //#endregion
13
+ //#region src/payment-request.d.ts
14
+ declare const PaymentRequest: react.ForwardRefExoticComponent<PaymentRequestComponentProps$1 & react.RefAttributes<unknown>>;
15
+ //#endregion
16
+ export { Bizum, type BizumComponentProps, CardInput, type CardInputComponentProps, type CardInputHandle, PayPal, type PayPalComponentProps, PaymentRequest, type PaymentRequestComponentProps };
@@ -0,0 +1,16 @@
1
+ import { BizumComponentProps, BizumComponentProps as BizumComponentProps$1, CardInputComponentProps, CardInputComponentProps as CardInputComponentProps$1, CardInputHandle, CardInputHandle as CardInputHandle$1, PayPalComponentProps, PayPalComponentProps as PayPalComponentProps$1, PaymentRequestComponentProps, PaymentRequestComponentProps as PaymentRequestComponentProps$1 } from "@monei-js/components";
2
+ import * as react from "react";
3
+
4
+ //#region src/card-input.d.ts
5
+ declare const CardInput: react.ForwardRefExoticComponent<CardInputComponentProps$1 & react.RefAttributes<CardInputHandle$1>>;
6
+ //#endregion
7
+ //#region src/bizum.d.ts
8
+ declare const Bizum: react.ForwardRefExoticComponent<BizumComponentProps$1 & react.RefAttributes<unknown>>;
9
+ //#endregion
10
+ //#region src/paypal.d.ts
11
+ declare const PayPal: react.ForwardRefExoticComponent<PayPalComponentProps$1 & react.RefAttributes<unknown>>;
12
+ //#endregion
13
+ //#region src/payment-request.d.ts
14
+ declare const PaymentRequest: react.ForwardRefExoticComponent<PaymentRequestComponentProps$1 & react.RefAttributes<unknown>>;
15
+ //#endregion
16
+ export { Bizum, type BizumComponentProps, CardInput, type CardInputComponentProps, type CardInputHandle, PayPal, type PayPalComponentProps, PaymentRequest, type PaymentRequestComponentProps };
package/dist/index.js ADDED
@@ -0,0 +1,76 @@
1
+ import { Bizum as Bizum$1, CardInput as CardInput$1, PayPal as PayPal$1, PaymentRequest as PaymentRequest$1 } from "@monei-js/components";
2
+ import React from "react";
3
+ //#region src/create-bridge-component.ts
4
+ /**
5
+ * Creates a React wrapper for a bridge component.
6
+ *
7
+ * - On mount: creates bridge instance, renders into container div
8
+ * - On update: shallow-compares props, calls updateProps on change
9
+ * - On unmount: calls destroy
10
+ * - If `imperativeHandle` is provided, exposes the handle via ref AFTER render resolves
11
+ * (deferred ref — not useImperativeHandle which runs synchronously before connection)
12
+ */
13
+ function createBridgeComponent(Constructor, imperativeHandle) {
14
+ return React.forwardRef(function BridgeReactWrapper(props, ref) {
15
+ const containerRef = React.useRef(null);
16
+ const instanceRef = React.useRef(null);
17
+ const isMounted = React.useRef(false);
18
+ const prevPropsRef = React.useRef({});
19
+ React.useLayoutEffect(() => {
20
+ const el = containerRef.current;
21
+ if (!el) return;
22
+ let cancelled = false;
23
+ const instance = new Constructor({ ...props });
24
+ instanceRef.current = instance;
25
+ instance.render(el).then(() => {
26
+ if (cancelled) return;
27
+ if (imperativeHandle && ref) setRef(ref, imperativeHandle(instance));
28
+ isMounted.current = true;
29
+ prevPropsRef.current = { ...props };
30
+ }).catch((err) => {
31
+ if (!cancelled) console.error(err);
32
+ });
33
+ return () => {
34
+ cancelled = true;
35
+ instance.destroy();
36
+ instanceRef.current = null;
37
+ isMounted.current = false;
38
+ if (imperativeHandle && ref) setRef(ref, null);
39
+ };
40
+ }, []);
41
+ React.useEffect(() => {
42
+ if (!isMounted.current || !instanceRef.current) return;
43
+ if (shallowEqual(prevPropsRef.current, props)) return;
44
+ prevPropsRef.current = { ...props };
45
+ instanceRef.current.updateProps({ ...props }).catch(noop);
46
+ });
47
+ return React.createElement("div", { ref: containerRef });
48
+ });
49
+ }
50
+ /** Set a React ref (callback or object ref) */
51
+ function setRef(ref, value) {
52
+ if (typeof ref === "function") ref(value);
53
+ else if (ref && typeof ref === "object" && "current" in ref) ref.current = value;
54
+ }
55
+ function shallowEqual(a, b) {
56
+ const keysA = Object.keys(a);
57
+ const keysB = Object.keys(b);
58
+ if (keysA.length !== keysB.length) return false;
59
+ for (const key of keysA) if (a[key] !== b[key]) return false;
60
+ return true;
61
+ }
62
+ function noop() {}
63
+ //#endregion
64
+ //#region src/card-input.ts
65
+ const CardInput = createBridgeComponent(CardInput$1, (instance) => ({ submit: (opts) => instance.submit(opts) }));
66
+ //#endregion
67
+ //#region src/bizum.ts
68
+ const Bizum = createBridgeComponent(Bizum$1);
69
+ //#endregion
70
+ //#region src/paypal.ts
71
+ const PayPal = createBridgeComponent(PayPal$1);
72
+ //#endregion
73
+ //#region src/payment-request.ts
74
+ const PaymentRequest = createBridgeComponent(PaymentRequest$1);
75
+ //#endregion
76
+ export { Bizum, CardInput, PayPal, PaymentRequest };
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@monei-js/react-components",
3
+ "version": "2.0.1",
4
+ "author": "MONEI <support@monei.com> (https://monei.com)",
5
+ "description": "MONEI React components for accepting payments with CardInput, Bizum, PayPal, and PaymentRequest.",
6
+ "homepage": "https://monei.com",
7
+ "license": "MIT",
8
+ "contributors": [
9
+ "Dmitriy Nevzorov <dn@monei.com>"
10
+ ],
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/MONEI/monei-js",
14
+ "directory": "packages/react-components"
15
+ },
16
+ "keywords": [
17
+ "monei",
18
+ "payment gateway",
19
+ "react",
20
+ "components",
21
+ "card input",
22
+ "bizum",
23
+ "paypal",
24
+ "payment request"
25
+ ],
26
+ "type": "module",
27
+ "main": "dist/index.cjs",
28
+ "module": "dist/index.js",
29
+ "types": "dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "import": {
33
+ "types": "./dist/index.d.ts",
34
+ "default": "./dist/index.js"
35
+ },
36
+ "require": {
37
+ "types": "./dist/index.d.cts",
38
+ "default": "./dist/index.cjs"
39
+ }
40
+ }
41
+ },
42
+ "files": [
43
+ "dist"
44
+ ],
45
+ "publishConfig": {
46
+ "access": "public",
47
+ "registry": "https://registry.npmjs.org/"
48
+ },
49
+ "scripts": {
50
+ "start": "pnpm --workspace-root run sandbox:react-components",
51
+ "start:ui": "portless react-components vp dev",
52
+ "dev": "vp pack --watch",
53
+ "build": "vp pack",
54
+ "prepack": "vp pack",
55
+ "release": "release-it",
56
+ "test": "vp test --passWithNoTests"
57
+ },
58
+ "peerDependencies": {
59
+ "@monei-js/components": "^2.0.0",
60
+ "react": ">=17"
61
+ },
62
+ "devDependencies": {
63
+ "@monei-js/components": "workspace:*",
64
+ "@release-it/conventional-changelog": "10.0.6",
65
+ "@types/react": "^18.3.28",
66
+ "@types/react-dom": "^18.3.7",
67
+ "react": "^18.3.1",
68
+ "react-dom": "^18.3.1",
69
+ "release-it": "^19.2.4",
70
+ "typescript": "~5.9.3",
71
+ "vite-plus": "0.1.14"
72
+ }
73
+ }