@blocklet/payment-react 1.14.21 → 1.14.23
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 +77 -0
- package/es/checkout/donate.d.ts +4 -2
- package/es/checkout/donate.js +13 -10
- package/es/checkout/form.d.ts +1 -1
- package/es/checkout/form.js +50 -4
- package/es/checkout/table.d.ts +1 -1
- package/es/checkout/table.js +11 -1
- package/es/components/blockchain/tx.js +2 -1
- package/es/components/country-select.d.ts +16 -0
- package/es/components/country-select.js +82 -0
- package/es/components/input.d.ts +21 -21
- package/es/components/input.js +43 -42
- package/es/components/livemode.js +1 -0
- package/es/components/pricing-table.js +0 -2
- package/es/components/status.js +2 -3
- package/es/components/table.d.ts +2 -0
- package/es/components/table.js +186 -0
- package/es/contexts/payment.d.ts +2 -0
- package/es/contexts/payment.js +5 -2
- package/es/history/invoice/list.d.ts +3 -1
- package/es/history/invoice/list.js +215 -48
- package/es/hooks/mobile.d.ts +4 -0
- package/es/hooks/mobile.js +10 -0
- package/es/index.d.ts +5 -1
- package/es/index.js +7 -1
- package/es/libs/util.d.ts +21 -8
- package/es/libs/util.js +92 -28
- package/es/locales/en.js +22 -7
- package/es/locales/index.d.ts +0 -1
- package/es/locales/index.js +10 -1
- package/es/locales/zh.js +21 -6
- package/es/payment/error.js +2 -2
- package/es/payment/footer.js +1 -1
- package/es/payment/form/address.d.ts +9 -2
- package/es/payment/form/address.js +69 -69
- package/es/payment/form/currency.js +39 -25
- package/es/payment/form/index.d.ts +1 -1
- package/es/payment/form/index.js +83 -81
- package/es/payment/form/phone.js +15 -51
- package/es/payment/index.d.ts +3 -10
- package/es/payment/index.js +295 -224
- package/es/payment/product-card.js +4 -4
- package/es/payment/product-donation.js +9 -3
- package/es/payment/product-item.d.ts +2 -2
- package/es/payment/product-item.js +120 -81
- package/es/payment/summary.js +188 -118
- package/es/theme/index.css +240 -0
- package/es/theme/index.d.ts +14 -0
- package/es/theme/index.js +256 -0
- package/es/theme/typography.d.ts +2 -0
- package/es/theme/typography.js +53 -0
- package/es/types/index.d.ts +16 -0
- package/lib/checkout/donate.d.ts +4 -2
- package/lib/checkout/donate.js +23 -2
- package/lib/checkout/form.d.ts +1 -1
- package/lib/checkout/form.js +60 -15
- package/lib/checkout/table.d.ts +1 -1
- package/lib/checkout/table.js +22 -1
- package/lib/components/blockchain/tx.js +4 -1
- package/lib/components/country-select.d.ts +16 -0
- package/lib/components/country-select.js +115 -0
- package/lib/components/input.d.ts +21 -21
- package/lib/components/input.js +21 -12
- package/lib/components/livemode.js +1 -0
- package/lib/components/pricing-table.js +0 -2
- package/lib/components/status.js +2 -3
- package/lib/components/table.d.ts +2 -0
- package/lib/components/table.js +220 -0
- package/lib/contexts/payment.d.ts +2 -0
- package/lib/contexts/payment.js +4 -1
- package/lib/history/invoice/list.d.ts +3 -1
- package/lib/history/invoice/list.js +290 -62
- package/lib/hooks/mobile.d.ts +4 -0
- package/lib/hooks/mobile.js +17 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +36 -0
- package/lib/libs/util.d.ts +21 -8
- package/lib/libs/util.js +115 -37
- package/lib/locales/en.js +22 -7
- package/lib/locales/index.d.ts +0 -1
- package/lib/locales/index.js +14 -3
- package/lib/locales/zh.js +21 -6
- package/lib/payment/error.js +5 -1
- package/lib/payment/footer.js +1 -1
- package/lib/payment/form/address.d.ts +9 -2
- package/lib/payment/form/address.js +67 -59
- package/lib/payment/form/currency.js +31 -24
- package/lib/payment/form/index.d.ts +1 -1
- package/lib/payment/form/index.js +92 -93
- package/lib/payment/form/phone.js +11 -59
- package/lib/payment/index.d.ts +3 -10
- package/lib/payment/index.js +302 -225
- package/lib/payment/product-card.js +5 -4
- package/lib/payment/product-donation.js +11 -7
- package/lib/payment/product-item.d.ts +2 -2
- package/lib/payment/product-item.js +38 -19
- package/lib/payment/summary.js +219 -127
- package/lib/theme/index.css +240 -0
- package/lib/theme/index.d.ts +14 -0
- package/lib/theme/index.js +273 -0
- package/lib/theme/typography.d.ts +2 -0
- package/lib/theme/typography.js +59 -0
- package/lib/types/index.d.ts +16 -0
- package/package.json +14 -11
- package/src/checkout/donate.tsx +25 -11
- package/src/checkout/form.tsx +63 -15
- package/src/checkout/table.tsx +20 -1
- package/src/components/blockchain/tx.tsx +2 -1
- package/src/components/country-select.tsx +93 -0
- package/src/components/input.tsx +49 -46
- package/src/components/livemode.tsx +1 -0
- package/src/components/pricing-table.tsx +0 -2
- package/src/components/status.tsx +1 -2
- package/src/components/table.tsx +200 -0
- package/src/contexts/payment.tsx +6 -1
- package/src/history/invoice/list.tsx +254 -49
- package/src/hooks/mobile.ts +13 -0
- package/src/index.ts +7 -0
- package/src/libs/util.ts +120 -31
- package/src/locales/en.tsx +18 -4
- package/src/locales/index.tsx +10 -3
- package/src/locales/zh.tsx +17 -3
- package/src/payment/error.tsx +2 -2
- package/src/payment/footer.tsx +1 -1
- package/src/payment/form/address.tsx +56 -47
- package/src/payment/form/currency.tsx +29 -23
- package/src/payment/form/index.tsx +89 -76
- package/src/payment/form/phone.tsx +14 -51
- package/src/payment/index.tsx +298 -231
- package/src/payment/product-card.tsx +4 -4
- package/src/payment/product-donation.tsx +9 -4
- package/src/payment/product-item.tsx +49 -20
- package/src/payment/summary.tsx +191 -108
- package/src/theme/index.css +240 -0
- package/src/theme/index.tsx +271 -0
- package/src/theme/typography.ts +56 -0
- package/src/types/index.ts +17 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.23",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"scripts": {
|
|
19
19
|
"lint": "tsc --noEmit && eslint src tests --ext js --ext jsx --ext ts --ext tsx",
|
|
20
20
|
"lint:fix": "npm run lint -- --fix",
|
|
21
|
-
"build": "tsc --noEmit && unbuild && node tools/auto-exports.js",
|
|
21
|
+
"build": "tsc --noEmit && unbuild && node tools/auto-exports.js && npm run cpfiles",
|
|
22
22
|
"watch": "CONSOLA_LEVEL=1 nodemon -e .jsx,.js,.ts,.tsx -w src -x 'yalc publish --push'",
|
|
23
23
|
"precommit": "CI=1 npm run lint",
|
|
24
24
|
"prepush": "CI=1 npm run lint",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"test": "node tools/jest.js",
|
|
27
27
|
"coverage": "npm run test -- --coverage",
|
|
28
28
|
"storybook": "storybook dev -p 6006",
|
|
29
|
-
"build-storybook": "storybook build"
|
|
29
|
+
"build-storybook": "storybook build",
|
|
30
|
+
"cpfiles": "copyfiles -u 1 './src/**/*.css' lib/ && copyfiles -u 1 './src/**/*.css' es/"
|
|
30
31
|
},
|
|
31
32
|
"bugs": {
|
|
32
33
|
"url": "https://github.com/blocklet/payment-kit/issues"
|
|
@@ -52,15 +53,16 @@
|
|
|
52
53
|
}
|
|
53
54
|
},
|
|
54
55
|
"dependencies": {
|
|
55
|
-
"@arcblock/did-connect": "^2.10.
|
|
56
|
-
"@arcblock/ux": "^2.10.
|
|
57
|
-
"@arcblock/ws": "^1.18.
|
|
56
|
+
"@arcblock/did-connect": "^2.10.16",
|
|
57
|
+
"@arcblock/ux": "^2.10.16",
|
|
58
|
+
"@arcblock/ws": "^1.18.128",
|
|
59
|
+
"@blocklet/ui-react": "^2.10.16",
|
|
58
60
|
"@mui/icons-material": "^5.16.6",
|
|
59
61
|
"@mui/lab": "^5.0.0-alpha.173",
|
|
60
62
|
"@mui/material": "^5.16.6",
|
|
61
63
|
"@mui/styles": "^5.16.6",
|
|
62
64
|
"@mui/system": "^5.16.6",
|
|
63
|
-
"@ocap/util": "^1.18.
|
|
65
|
+
"@ocap/util": "^1.18.128",
|
|
64
66
|
"@stripe/react-stripe-js": "^2.7.3",
|
|
65
67
|
"@stripe/stripe-js": "^2.4.0",
|
|
66
68
|
"@vitejs/plugin-legacy": "^5.4.1",
|
|
@@ -91,7 +93,7 @@
|
|
|
91
93
|
"@babel/core": "^7.25.2",
|
|
92
94
|
"@babel/preset-env": "^7.25.2",
|
|
93
95
|
"@babel/preset-react": "^7.24.7",
|
|
94
|
-
"@blocklet/payment-types": "1.14.
|
|
96
|
+
"@blocklet/payment-types": "1.14.23",
|
|
95
97
|
"@storybook/addon-essentials": "^7.6.20",
|
|
96
98
|
"@storybook/addon-interactions": "^7.6.20",
|
|
97
99
|
"@storybook/addon-links": "^7.6.20",
|
|
@@ -103,14 +105,15 @@
|
|
|
103
105
|
"@types/react": "^18.3.3",
|
|
104
106
|
"@types/react-dom": "^18.3.0",
|
|
105
107
|
"@vitejs/plugin-legacy": "^5.4.1",
|
|
108
|
+
"copyfiles": "^2.4.1",
|
|
106
109
|
"eslint": "^8.57.0",
|
|
107
110
|
"glob": "^10.4.5",
|
|
108
111
|
"import-sort-style-module": "^6.0.0",
|
|
109
112
|
"jest": "^29.7.0",
|
|
110
113
|
"prettier": "^3.3.3",
|
|
111
114
|
"prettier-plugin-import-sort": "^0.0.7",
|
|
112
|
-
"react": "
|
|
113
|
-
"react-dom": "
|
|
115
|
+
"react": "18.2.0",
|
|
116
|
+
"react-dom": "18.2.0",
|
|
114
117
|
"rollup-plugin-node-builtins": "^2.1.2",
|
|
115
118
|
"storybook": "^7.6.20",
|
|
116
119
|
"ts-jest": "^29.2.3",
|
|
@@ -120,5 +123,5 @@
|
|
|
120
123
|
"vite-plugin-babel": "^1.2.0",
|
|
121
124
|
"vite-plugin-node-polyfills": "^0.21.0"
|
|
122
125
|
},
|
|
123
|
-
"gitHead": "
|
|
126
|
+
"gitHead": "868311b6e37e21e5755e7a78daf335f3057dd1c8"
|
|
124
127
|
}
|
package/src/checkout/donate.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable react/require-default-props */
|
|
1
2
|
/* eslint-disable @typescript-eslint/indent */
|
|
2
3
|
import Dialog from '@arcblock/ux/lib/Dialog';
|
|
3
4
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
@@ -34,8 +35,9 @@ import { useEffect, useState } from 'react';
|
|
|
34
35
|
import TxLink from '../components/blockchain/tx';
|
|
35
36
|
import api from '../libs/api';
|
|
36
37
|
import { formatAmount, formatBNStr, formatDateTime, formatError, lazyLoad } from '../libs/util';
|
|
37
|
-
import { CheckoutProps } from '../types';
|
|
38
|
+
import { CheckoutProps, PaymentThemeOptions } from '../types';
|
|
38
39
|
import CheckoutForm from './form';
|
|
40
|
+
import { PaymentThemeProvider } from '../theme';
|
|
39
41
|
|
|
40
42
|
export type DonateHistory = {
|
|
41
43
|
supporters: TCheckoutSessionExpanded[];
|
|
@@ -58,6 +60,7 @@ export type DonateProps = Pick<CheckoutProps, 'onPaid' | 'onError'> & {
|
|
|
58
60
|
inlineOptions?: {
|
|
59
61
|
button?: ButtonType;
|
|
60
62
|
};
|
|
63
|
+
theme?: 'default' | 'inherit' | PaymentThemeOptions;
|
|
61
64
|
};
|
|
62
65
|
|
|
63
66
|
const donationCache: { [key: string]: Promise<TPaymentLink> } = {};
|
|
@@ -298,15 +301,7 @@ function useDonation(settings: DonationSettings, livemode: boolean = true, mode
|
|
|
298
301
|
};
|
|
299
302
|
}
|
|
300
303
|
|
|
301
|
-
|
|
302
|
-
settings,
|
|
303
|
-
livemode,
|
|
304
|
-
timeout,
|
|
305
|
-
onPaid,
|
|
306
|
-
onError,
|
|
307
|
-
mode,
|
|
308
|
-
inlineOptions = {},
|
|
309
|
-
}: DonateProps) {
|
|
304
|
+
function CheckoutDonateInner({ settings, livemode, timeout, onPaid, onError, mode, inlineOptions = {} }: DonateProps) {
|
|
310
305
|
// eslint-disable-line
|
|
311
306
|
const { state, setState, donation, supporters } = useDonation(settings, livemode, mode);
|
|
312
307
|
|
|
@@ -448,7 +443,7 @@ export default function CheckoutDonate({
|
|
|
448
443
|
showCloseButton
|
|
449
444
|
disableEscapeKeyDown
|
|
450
445
|
onClose={(e: any, reason: string) => setState({ open: reason === 'backdropClick' })}>
|
|
451
|
-
<Box sx={{ mb: 1,
|
|
446
|
+
<Box sx={{ mb: 1, height: '100%' }}>
|
|
452
447
|
<CheckoutForm
|
|
453
448
|
id={donation.data?.id}
|
|
454
449
|
onPaid={handlePaid}
|
|
@@ -463,7 +458,26 @@ export default function CheckoutDonate({
|
|
|
463
458
|
);
|
|
464
459
|
}
|
|
465
460
|
|
|
461
|
+
export default function CheckoutDonate(props: DonateProps) {
|
|
462
|
+
if (props.theme === 'inherit') {
|
|
463
|
+
return <CheckoutDonateInner {...props} />;
|
|
464
|
+
}
|
|
465
|
+
if (props.theme && typeof props.theme === 'object') {
|
|
466
|
+
return (
|
|
467
|
+
<PaymentThemeProvider theme={props.theme}>
|
|
468
|
+
<CheckoutDonateInner {...props} />
|
|
469
|
+
</PaymentThemeProvider>
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
return (
|
|
473
|
+
<PaymentThemeProvider>
|
|
474
|
+
<CheckoutDonateInner {...props} />
|
|
475
|
+
</PaymentThemeProvider>
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
|
|
466
479
|
CheckoutDonate.defaultProps = {
|
|
480
|
+
theme: 'default',
|
|
467
481
|
livemode: true,
|
|
468
482
|
timeout: 5000,
|
|
469
483
|
mode: 'default',
|
package/src/checkout/form.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import api from '../libs/api';
|
|
|
8
8
|
import { getPrefix, mergeExtraParams } from '../libs/util';
|
|
9
9
|
import Payment from '../payment';
|
|
10
10
|
import { CheckoutContext, CheckoutProps } from '../types';
|
|
11
|
+
import { PaymentThemeProvider } from '../theme';
|
|
11
12
|
|
|
12
13
|
const promises: { [key: string]: Promise<any> } = {};
|
|
13
14
|
const startFromPaymentLink = (id: string, params?: Record<string, any>): Promise<CheckoutContext> => {
|
|
@@ -39,6 +40,8 @@ export default function CheckoutForm({
|
|
|
39
40
|
goBack,
|
|
40
41
|
extraParams,
|
|
41
42
|
action,
|
|
43
|
+
theme = 'default',
|
|
44
|
+
...restProps
|
|
42
45
|
}: CheckoutProps) {
|
|
43
46
|
if (!id.startsWith('plink_') && !id.startsWith('cs_')) {
|
|
44
47
|
throw new Error('Either a checkoutSession or a paymentLink id is required.');
|
|
@@ -73,22 +76,67 @@ export default function CheckoutForm({
|
|
|
73
76
|
onError?.(err);
|
|
74
77
|
};
|
|
75
78
|
|
|
79
|
+
if (theme === 'inherit') {
|
|
80
|
+
return (
|
|
81
|
+
<Payment
|
|
82
|
+
checkoutSession={data?.checkoutSession as TCheckoutSessionExpanded}
|
|
83
|
+
paymentMethods={data?.paymentMethods as TPaymentMethodExpanded[]}
|
|
84
|
+
paymentIntent={data?.paymentIntent}
|
|
85
|
+
paymentLink={data?.paymentLink}
|
|
86
|
+
customer={data?.customer}
|
|
87
|
+
completed={state.completed}
|
|
88
|
+
error={apiError || state.appError}
|
|
89
|
+
onPaid={handlePaid}
|
|
90
|
+
onError={handleError}
|
|
91
|
+
onChange={onChange}
|
|
92
|
+
goBack={goBack}
|
|
93
|
+
mode={mode as string}
|
|
94
|
+
action={action}
|
|
95
|
+
{...restProps}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
if (theme && typeof theme === 'object') {
|
|
100
|
+
return (
|
|
101
|
+
<PaymentThemeProvider theme={theme}>
|
|
102
|
+
<Payment
|
|
103
|
+
checkoutSession={data?.checkoutSession as TCheckoutSessionExpanded}
|
|
104
|
+
paymentMethods={data?.paymentMethods as TPaymentMethodExpanded[]}
|
|
105
|
+
paymentIntent={data?.paymentIntent}
|
|
106
|
+
paymentLink={data?.paymentLink}
|
|
107
|
+
customer={data?.customer}
|
|
108
|
+
completed={state.completed}
|
|
109
|
+
error={apiError || state.appError}
|
|
110
|
+
onPaid={handlePaid}
|
|
111
|
+
onError={handleError}
|
|
112
|
+
onChange={onChange}
|
|
113
|
+
goBack={goBack}
|
|
114
|
+
mode={mode as string}
|
|
115
|
+
action={action}
|
|
116
|
+
{...restProps}
|
|
117
|
+
/>
|
|
118
|
+
</PaymentThemeProvider>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
76
121
|
return (
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
122
|
+
<PaymentThemeProvider>
|
|
123
|
+
<Payment
|
|
124
|
+
checkoutSession={data?.checkoutSession as TCheckoutSessionExpanded}
|
|
125
|
+
paymentMethods={data?.paymentMethods as TPaymentMethodExpanded[]}
|
|
126
|
+
paymentIntent={data?.paymentIntent}
|
|
127
|
+
paymentLink={data?.paymentLink}
|
|
128
|
+
customer={data?.customer}
|
|
129
|
+
completed={state.completed}
|
|
130
|
+
error={apiError || state.appError}
|
|
131
|
+
onPaid={handlePaid}
|
|
132
|
+
onError={handleError}
|
|
133
|
+
onChange={onChange}
|
|
134
|
+
goBack={goBack}
|
|
135
|
+
mode={mode as string}
|
|
136
|
+
action={action}
|
|
137
|
+
{...restProps}
|
|
138
|
+
/>
|
|
139
|
+
</PaymentThemeProvider>
|
|
92
140
|
);
|
|
93
141
|
}
|
|
94
142
|
|
package/src/checkout/table.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import api from '../libs/api';
|
|
|
12
12
|
import { mergeExtraParams } from '../libs/util';
|
|
13
13
|
import { CheckoutProps } from '../types';
|
|
14
14
|
import CheckoutForm from './form';
|
|
15
|
+
import { PaymentThemeProvider } from '../theme';
|
|
15
16
|
|
|
16
17
|
const fetchData = async (id: string): Promise<TPricingTableExpanded> => {
|
|
17
18
|
const { data } = await api.get(`/api/pricing-tables/${id}`);
|
|
@@ -25,7 +26,7 @@ const ensureProtocol = (url: string): string => {
|
|
|
25
26
|
return url;
|
|
26
27
|
};
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
function CheckoutTableInner({ id, mode, onPaid, onError, onChange, extraParams, goBack }: CheckoutProps) {
|
|
29
30
|
if (!id.startsWith('prctbl_')) {
|
|
30
31
|
throw new Error('A valid pricing table id is required.');
|
|
31
32
|
}
|
|
@@ -123,3 +124,21 @@ export default function CheckoutTable({ id, mode, onPaid, onError, onChange, ext
|
|
|
123
124
|
</Box>
|
|
124
125
|
);
|
|
125
126
|
}
|
|
127
|
+
|
|
128
|
+
export default function CheckoutTable(props: CheckoutProps) {
|
|
129
|
+
if (props.theme === 'inherit') {
|
|
130
|
+
return <CheckoutTableInner {...props} />;
|
|
131
|
+
}
|
|
132
|
+
if (props.theme && typeof props.theme === 'object') {
|
|
133
|
+
return (
|
|
134
|
+
<PaymentThemeProvider theme={props.theme}>
|
|
135
|
+
<CheckoutTableInner {...props} />
|
|
136
|
+
</PaymentThemeProvider>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return (
|
|
140
|
+
<PaymentThemeProvider>
|
|
141
|
+
<CheckoutTableInner {...props} />
|
|
142
|
+
</PaymentThemeProvider>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
@@ -36,8 +36,9 @@ export default function TxLink(props: {
|
|
|
36
36
|
direction="row"
|
|
37
37
|
alignItems="center"
|
|
38
38
|
justifyContent={props.align === 'left' ? 'flex-start' : 'flex-end'}
|
|
39
|
+
sx={{ color: 'text.link' }}
|
|
39
40
|
spacing={1}>
|
|
40
|
-
<Typography component="span" color="
|
|
41
|
+
<Typography component="span" color="text.link">
|
|
41
42
|
{text.length > 40 ? [text.slice(0, 6), text.slice(-6)].join('...') : text}
|
|
42
43
|
</Typography>
|
|
43
44
|
<OpenInNewOutlined fontSize="small" />
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* eslint-disable react/prop-types */
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
|
+
import { Box, MenuItem, Select, SxProps, Typography } from '@mui/material';
|
|
5
|
+
import { useFormContext } from 'react-hook-form';
|
|
6
|
+
import { CountryIso2, FlagEmoji, defaultCountries, parseCountry } from 'react-international-phone';
|
|
7
|
+
|
|
8
|
+
export type CountrySelectProps = {
|
|
9
|
+
value: CountryIso2;
|
|
10
|
+
onChange: (value: CountryIso2) => void;
|
|
11
|
+
name: string;
|
|
12
|
+
sx?: SxProps;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
CountrySelect.defaultProps = {
|
|
16
|
+
sx: {},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default function CountrySelect({ value, onChange, name, sx }: CountrySelectProps) {
|
|
20
|
+
const { setValue } = useFormContext();
|
|
21
|
+
const countryDetail = useMemo(() => {
|
|
22
|
+
const item = defaultCountries.find((v) => v[1] === value);
|
|
23
|
+
return value && item ? parseCountry(item) : { name: '' };
|
|
24
|
+
}, [value]);
|
|
25
|
+
|
|
26
|
+
const onCountryChange = (e: any) => {
|
|
27
|
+
onChange(e.target.value as CountryIso2);
|
|
28
|
+
setValue(name, e.target.value);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Select
|
|
33
|
+
MenuProps={{
|
|
34
|
+
style: {
|
|
35
|
+
height: '300px',
|
|
36
|
+
top: '10px',
|
|
37
|
+
},
|
|
38
|
+
anchorOrigin: {
|
|
39
|
+
vertical: 'bottom',
|
|
40
|
+
horizontal: 'left',
|
|
41
|
+
},
|
|
42
|
+
transformOrigin: {
|
|
43
|
+
vertical: 'top',
|
|
44
|
+
horizontal: 'left',
|
|
45
|
+
},
|
|
46
|
+
}}
|
|
47
|
+
sx={{
|
|
48
|
+
width: '100%',
|
|
49
|
+
// Remove default outline (display only on focus)
|
|
50
|
+
fieldset: {
|
|
51
|
+
display: 'none',
|
|
52
|
+
},
|
|
53
|
+
'&.Mui-focused:has(div[aria-expanded="false"])': {
|
|
54
|
+
fieldset: {
|
|
55
|
+
display: 'block',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
// Update default spacing
|
|
59
|
+
'.MuiSelect-select': {
|
|
60
|
+
padding: '8px',
|
|
61
|
+
paddingRight: '24px !important',
|
|
62
|
+
},
|
|
63
|
+
svg: {
|
|
64
|
+
right: 0,
|
|
65
|
+
},
|
|
66
|
+
'.MuiMenuItem-root': {
|
|
67
|
+
justifyContent: 'flex-start', // 确保内容左对齐
|
|
68
|
+
},
|
|
69
|
+
...sx,
|
|
70
|
+
}}
|
|
71
|
+
value={value}
|
|
72
|
+
onChange={onCountryChange}
|
|
73
|
+
renderValue={(code) => {
|
|
74
|
+
return (
|
|
75
|
+
<Box display="flex" alignItems="center" flexWrap="nowrap" gap={0.5} sx={{ cursor: 'pointer' }}>
|
|
76
|
+
<FlagEmoji iso2={code} style={{ display: 'flex' }} />
|
|
77
|
+
<Typography>{countryDetail?.name}</Typography>
|
|
78
|
+
</Box>
|
|
79
|
+
);
|
|
80
|
+
}}>
|
|
81
|
+
{defaultCountries.map((c) => {
|
|
82
|
+
const parsed = parseCountry(c);
|
|
83
|
+
return (
|
|
84
|
+
<MenuItem key={parsed.iso2} value={parsed.iso2}>
|
|
85
|
+
<FlagEmoji iso2={parsed.iso2} style={{ marginRight: '8px' }} />
|
|
86
|
+
<Typography marginRight="8px">{parsed.name}</Typography>
|
|
87
|
+
<Typography color="gray">+{parsed.dialCode}</Typography>
|
|
88
|
+
</MenuItem>
|
|
89
|
+
);
|
|
90
|
+
})}
|
|
91
|
+
</Select>
|
|
92
|
+
);
|
|
93
|
+
}
|
package/src/components/input.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
|
1
2
|
import { Box, FormLabel, InputAdornment, TextField, TextFieldProps, Typography } from '@mui/material';
|
|
2
3
|
import get from 'lodash/get';
|
|
3
4
|
import { Controller, RegisterOptions, useFormContext } from 'react-hook-form';
|
|
@@ -11,15 +12,7 @@ type InputProps = TextFieldProps & {
|
|
|
11
12
|
wrapperStyle?: React.CSSProperties;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
label: '',
|
|
16
|
-
placeholder: '',
|
|
17
|
-
errorPosition: 'bottom',
|
|
18
|
-
rules: {},
|
|
19
|
-
wrapperStyle: {},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export function FormInputError({ error }: { error: string }) {
|
|
15
|
+
function FormInputError({ error }: { error: string }) {
|
|
23
16
|
return (
|
|
24
17
|
<InputAdornment position="end">
|
|
25
18
|
<Typography component="span" color="error">
|
|
@@ -29,40 +22,50 @@ export function FormInputError({ error }: { error: string }) {
|
|
|
29
22
|
);
|
|
30
23
|
}
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
name,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
25
|
+
const FormInput = forwardRef<HTMLInputElement, InputProps>(
|
|
26
|
+
({ name, label, placeholder, rules, errorPosition, wrapperStyle, ...rest }, ref) => {
|
|
27
|
+
const { control, formState } = useFormContext();
|
|
28
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
29
|
+
useImperativeHandle(ref, () => {
|
|
30
|
+
return inputRef.current as HTMLInputElement;
|
|
31
|
+
});
|
|
32
|
+
const error = get(formState.errors, name)?.message as string;
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Controller
|
|
36
|
+
name={name}
|
|
37
|
+
control={control}
|
|
38
|
+
rules={rules}
|
|
39
|
+
render={({ field }) => (
|
|
40
|
+
<Box sx={{ width: '100%', ...wrapperStyle }}>
|
|
41
|
+
{!!label && <FormLabel sx={{ color: 'text.primary' }}>{label}</FormLabel>}
|
|
42
|
+
<TextField
|
|
43
|
+
fullWidth
|
|
44
|
+
error={!!get(formState.errors, name)}
|
|
45
|
+
helperText={errorPosition === 'bottom' && error ? error : ''}
|
|
46
|
+
placeholder={placeholder}
|
|
47
|
+
size="small"
|
|
48
|
+
{...field}
|
|
49
|
+
{...rest}
|
|
50
|
+
inputRef={inputRef}
|
|
51
|
+
InputProps={Object.assign(
|
|
52
|
+
rest.InputProps || {},
|
|
53
|
+
errorPosition === 'right' && error ? { endAdornment: <FormInputError error={error} /> } : {}
|
|
54
|
+
)}
|
|
55
|
+
/>
|
|
56
|
+
</Box>
|
|
57
|
+
)}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
FormInput.defaultProps = {
|
|
64
|
+
label: '',
|
|
65
|
+
placeholder: '',
|
|
66
|
+
errorPosition: 'bottom',
|
|
67
|
+
rules: {},
|
|
68
|
+
wrapperStyle: {},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default FormInput;
|
|
@@ -276,7 +276,6 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
|
|
|
276
276
|
color="text.primary"
|
|
277
277
|
fontWeight={600}
|
|
278
278
|
sx={{
|
|
279
|
-
color: '#4B5563',
|
|
280
279
|
fontSize: '18px !important',
|
|
281
280
|
fontWeight: '600',
|
|
282
281
|
}}>
|
|
@@ -303,7 +302,6 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
|
|
|
303
302
|
color="text.secondary"
|
|
304
303
|
sx={{
|
|
305
304
|
marginTop: '0px !important',
|
|
306
|
-
color: '#4b5563',
|
|
307
305
|
fontWeight: '400',
|
|
308
306
|
fontSize: '16px',
|
|
309
307
|
textAlign: 'left',
|
|
@@ -4,14 +4,13 @@ export default function Status(props: ChipProps) {
|
|
|
4
4
|
return (
|
|
5
5
|
<Chip
|
|
6
6
|
size="small"
|
|
7
|
-
variant="
|
|
7
|
+
variant="filled"
|
|
8
8
|
{...props}
|
|
9
9
|
sx={{
|
|
10
10
|
...(props.sx || {}),
|
|
11
11
|
borderRadius: '4px',
|
|
12
12
|
height: 20,
|
|
13
13
|
textTransform: 'capitalize',
|
|
14
|
-
marginRight: '10px',
|
|
15
14
|
}}
|
|
16
15
|
/>
|
|
17
16
|
);
|