@blocklet/payment-react 1.15.23 → 1.15.25

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,17 @@
1
+ import React from 'react';
2
+ interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
3
+ to: string;
4
+ children: React.ReactNode;
5
+ replace?: boolean;
6
+ target?: string;
7
+ outLink?: boolean;
8
+ }
9
+ declare function Link({ to, children, onClick, replace, target, outLink, ...props }: LinkProps): JSX.Element;
10
+ declare namespace Link {
11
+ var defaultProps: {
12
+ replace: boolean;
13
+ target: undefined;
14
+ outLink: boolean;
15
+ };
16
+ }
17
+ export default Link;
@@ -0,0 +1,22 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useNavigate } from "react-router-dom";
3
+ export default function Link({ to, children, onClick, replace, target, outLink = false, ...props }) {
4
+ const navigate = useNavigate();
5
+ const handleClick = (e) => {
6
+ const isInternal = to.startsWith("/") || to.startsWith("#") || to.startsWith("?");
7
+ if (!outLink && isInternal) {
8
+ e.preventDefault();
9
+ navigate(to, { replace });
10
+ } else if (!target) {
11
+ e.preventDefault();
12
+ window.location.href = to;
13
+ }
14
+ onClick?.(e);
15
+ };
16
+ return /* @__PURE__ */ jsx("a", { href: to, onClick: handleClick, target, rel: "noreferrer", ...props, children });
17
+ }
18
+ Link.defaultProps = {
19
+ replace: false,
20
+ target: void 0,
21
+ outLink: false
22
+ };
@@ -21,7 +21,7 @@ import { styled } from "@mui/system";
21
21
  import { useSetState } from "ahooks";
22
22
  import { useEffect, useMemo, useState } from "react";
23
23
  import { BN } from "@ocap/util";
24
- import { isEmpty } from "lodash";
24
+ import isEmpty from "lodash/isEmpty";
25
25
  import { usePaymentContext } from "../contexts/payment.js";
26
26
  import {
27
27
  formatError,
@@ -1,5 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { Tooltip, tooltipClasses } from "@mui/material";
2
+ import { Tooltip } from "@mui/material";
3
+ import { tooltipClasses } from "@mui/material/Tooltip";
3
4
  import { styled } from "@mui/system";
4
5
  import { truncateText } from "../libs/util.js";
5
6
  const CustomTooltip = styled(({ className, ...props }) => /* @__PURE__ */ jsx(Tooltip, { ...props, classes: { popper: className } }))({
package/es/index.d.ts CHANGED
@@ -26,12 +26,14 @@ import PaymentSummary from './payment/summary';
26
26
  import PricingItem from './components/pricing-item';
27
27
  import CountrySelect from './components/country-select';
28
28
  import TruncatedText from './components/truncated-text';
29
+ import Link from './components/link';
29
30
  export { PaymentThemeProvider } from './theme';
30
31
  export * from './libs/util';
31
32
  export * from './libs/connect';
33
+ export * from './libs/phone-validator';
32
34
  export * from './contexts/payment';
33
35
  export * from './hooks/subscription';
34
36
  export * from './hooks/mobile';
35
37
  export * from './hooks/table';
36
38
  export { translations, createTranslator } from './locales';
37
- export { api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, };
39
+ export { api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, Link, };
package/es/index.js CHANGED
@@ -26,9 +26,11 @@ import PaymentSummary from "./payment/summary.js";
26
26
  import PricingItem from "./components/pricing-item.js";
27
27
  import CountrySelect from "./components/country-select.js";
28
28
  import TruncatedText from "./components/truncated-text.js";
29
+ import Link from "./components/link.js";
29
30
  export { PaymentThemeProvider } from "./theme/index.js";
30
31
  export * from "./libs/util.js";
31
32
  export * from "./libs/connect.js";
33
+ export * from "./libs/phone-validator.js";
32
34
  export * from "./contexts/payment.js";
33
35
  export * from "./hooks/subscription.js";
34
36
  export * from "./hooks/mobile.js";
@@ -62,5 +64,6 @@ export {
62
64
  PricingItem,
63
65
  CountrySelect,
64
66
  Table,
65
- TruncatedText
67
+ TruncatedText,
68
+ Link
66
69
  };
@@ -0,0 +1,2 @@
1
+ export declare const getPhoneUtil: () => Promise<any>;
2
+ export declare const validatePhoneNumber: (phoneNumber: string) => Promise<any>;
@@ -0,0 +1,21 @@
1
+ let phoneUtil = null;
2
+ export const getPhoneUtil = async () => {
3
+ if (!phoneUtil) {
4
+ const { PhoneNumberUtil } = await import(
5
+ /* webpackChunkName: "phone-util" */
6
+ "google-libphonenumber"
7
+ );
8
+ phoneUtil = PhoneNumberUtil.getInstance();
9
+ }
10
+ return phoneUtil;
11
+ };
12
+ export const validatePhoneNumber = async (phoneNumber) => {
13
+ try {
14
+ const util = await getPhoneUtil();
15
+ const parsed = util.parseAndKeepRawInput(phoneNumber);
16
+ return util.isValidNumber(parsed);
17
+ } catch (err) {
18
+ console.error("Phone validation error:", err);
19
+ return false;
20
+ }
21
+ };
@@ -1,4 +1,4 @@
1
- import { template } from "lodash";
1
+ import template from "lodash/template";
2
2
  import en from "./en.js";
3
3
  import zh from "./zh.js";
4
4
  export const translations = {
@@ -5,14 +5,13 @@ import Toast from "@arcblock/ux/lib/Toast";
5
5
  import { LoadingButton } from "@mui/lab";
6
6
  import { Box, Divider, Fade, FormLabel, Stack, Typography } from "@mui/material";
7
7
  import { useMemoizedFn, useSetState } from "ahooks";
8
- import { PhoneNumberUtil } from "google-libphonenumber";
9
8
  import pWaitFor from "p-wait-for";
10
9
  import { useEffect, useMemo, useRef, useState } from "react";
11
10
  import { Controller, useFormContext, useWatch } from "react-hook-form";
12
11
  import { joinURL } from "ufo";
13
12
  import { dispatch } from "use-bus";
14
13
  import isEmail from "validator/es/lib/isEmail";
15
- import { isEmpty } from "lodash";
14
+ import isEmpty from "lodash/isEmpty";
16
15
  import ConfirmDialog from "../../components/confirm.js";
17
16
  import FormInput from "../../components/input.js";
18
17
  import { usePaymentContext } from "../../contexts/payment.js";
@@ -31,7 +30,7 @@ import CurrencySelector from "./currency.js";
31
30
  import PhoneInput from "./phone.js";
32
31
  import StripeCheckout from "./stripe.js";
33
32
  import { useMobile } from "../../hooks/mobile.js";
34
- const phoneUtil = PhoneNumberUtil.getInstance();
33
+ import { validatePhoneNumber } from "../../libs/phone-validator.js";
35
34
  const waitForCheckoutComplete = async (sessionId) => {
36
35
  let result;
37
36
  await pWaitFor(
@@ -409,13 +408,9 @@ export default function PaymentForm({
409
408
  placeholder: "Phone number",
410
409
  rules: {
411
410
  required: t("payment.checkout.required"),
412
- validate: (x) => {
413
- try {
414
- const parsed = phoneUtil.parseAndKeepRawInput(x);
415
- return phoneUtil.isValidNumber(parsed) ? true : t("payment.checkout.invalid");
416
- } catch {
417
- return t("payment.checkout.invalid");
418
- }
411
+ validate: async (x) => {
412
+ const isValid = await validatePhoneNumber(x);
413
+ return isValid ? true : t("payment.checkout.invalid");
419
414
  }
420
415
  }
421
416
  }
package/es/theme/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { ThemeProvider, useTheme } from "@mui/material/styles";
3
3
  import { create } from "@arcblock/ux/lib/Theme";
4
- import { cloneDeep, merge } from "lodash";
4
+ import cloneDeep from "lodash/cloneDeep";
5
+ import merge from "lodash/merge";
5
6
  import { Box, CssBaseline } from "@mui/material";
6
7
  import { typography } from "./typography.js";
7
8
  import "./index.css";
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
3
+ to: string;
4
+ children: React.ReactNode;
5
+ replace?: boolean;
6
+ target?: string;
7
+ outLink?: boolean;
8
+ }
9
+ declare function Link({ to, children, onClick, replace, target, outLink, ...props }: LinkProps): JSX.Element;
10
+ declare namespace Link {
11
+ var defaultProps: {
12
+ replace: boolean;
13
+ target: undefined;
14
+ outLink: boolean;
15
+ };
16
+ }
17
+ export default Link;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ module.exports = Link;
7
+ var _jsxRuntime = require("react/jsx-runtime");
8
+ var _reactRouterDom = require("react-router-dom");
9
+ function Link({
10
+ to,
11
+ children,
12
+ onClick,
13
+ replace,
14
+ target,
15
+ outLink = false,
16
+ ...props
17
+ }) {
18
+ const navigate = (0, _reactRouterDom.useNavigate)();
19
+ const handleClick = e => {
20
+ const isInternal = to.startsWith("/") || to.startsWith("#") || to.startsWith("?");
21
+ if (!outLink && isInternal) {
22
+ e.preventDefault();
23
+ navigate(to, {
24
+ replace
25
+ });
26
+ } else if (!target) {
27
+ e.preventDefault();
28
+ window.location.href = to;
29
+ }
30
+ onClick?.(e);
31
+ };
32
+ return /* @__PURE__ */(0, _jsxRuntime.jsx)("a", {
33
+ href: to,
34
+ onClick: handleClick,
35
+ target,
36
+ rel: "noreferrer",
37
+ ...props,
38
+ children
39
+ });
40
+ }
41
+ Link.defaultProps = {
42
+ replace: false,
43
+ target: void 0,
44
+ outLink: false
45
+ };
@@ -14,7 +14,7 @@ var _system = require("@mui/system");
14
14
  var _ahooks = require("ahooks");
15
15
  var _react = require("react");
16
16
  var _util = require("@ocap/util");
17
- var _lodash = require("lodash");
17
+ var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
18
18
  var _payment = require("../contexts/payment");
19
19
  var _util2 = require("../libs/util");
20
20
  var _amount = _interopRequireDefault(require("../payment/amount"));
@@ -86,7 +86,7 @@ function PricingTable({
86
86
  grouped
87
87
  } = (0, _react.useMemo)(() => groupItemsByRecurring(table.items, currency), [table.items, currency]);
88
88
  const recurringKeysList = (0, _react.useMemo)(() => {
89
- if ((0, _lodash.isEmpty)(recurring)) {
89
+ if ((0, _isEmpty.default)(recurring)) {
90
90
  return [];
91
91
  }
92
92
  return Object.keys(recurring).sort((a, b) => {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  module.exports = TruncatedText;
7
7
  var _jsxRuntime = require("react/jsx-runtime");
8
8
  var _material = require("@mui/material");
9
+ var _Tooltip = require("@mui/material/Tooltip");
9
10
  var _system = require("@mui/system");
10
11
  var _util = require("../libs/util");
11
12
  const CustomTooltip = (0, _system.styled)(({
@@ -17,7 +18,7 @@ const CustomTooltip = (0, _system.styled)(({
17
18
  popper: className
18
19
  }
19
20
  }))({
20
- [`& .${_material.tooltipClasses.tooltip}`]: {
21
+ [`& .${_Tooltip.tooltipClasses.tooltip}`]: {
21
22
  fontSize: 11,
22
23
  maxHeight: 120,
23
24
  maxWidth: 500,
package/lib/index.d.ts CHANGED
@@ -26,12 +26,14 @@ import PaymentSummary from './payment/summary';
26
26
  import PricingItem from './components/pricing-item';
27
27
  import CountrySelect from './components/country-select';
28
28
  import TruncatedText from './components/truncated-text';
29
+ import Link from './components/link';
29
30
  export { PaymentThemeProvider } from './theme';
30
31
  export * from './libs/util';
31
32
  export * from './libs/connect';
33
+ export * from './libs/phone-validator';
32
34
  export * from './contexts/payment';
33
35
  export * from './hooks/subscription';
34
36
  export * from './hooks/mobile';
35
37
  export * from './hooks/table';
36
38
  export { translations, createTranslator } from './locales';
37
- export { api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, };
39
+ export { api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, Link, };
package/lib/index.js CHANGED
@@ -32,6 +32,7 @@ var _exportNames = {
32
32
  PricingItem: true,
33
33
  CountrySelect: true,
34
34
  TruncatedText: true,
35
+ Link: true,
35
36
  PaymentThemeProvider: true,
36
37
  translations: true,
37
38
  createTranslator: true
@@ -102,6 +103,12 @@ Object.defineProperty(exports, "FormInput", {
102
103
  return _input.default;
103
104
  }
104
105
  });
106
+ Object.defineProperty(exports, "Link", {
107
+ enumerable: true,
108
+ get: function () {
109
+ return _link.default;
110
+ }
111
+ });
105
112
  Object.defineProperty(exports, "Livemode", {
106
113
  enumerable: true,
107
114
  get: function () {
@@ -250,6 +257,7 @@ var _summary = _interopRequireDefault(require("./payment/summary"));
250
257
  var _pricingItem = _interopRequireDefault(require("./components/pricing-item"));
251
258
  var _countrySelect = _interopRequireDefault(require("./components/country-select"));
252
259
  var _truncatedText = _interopRequireDefault(require("./components/truncated-text"));
260
+ var _link = _interopRequireDefault(require("./components/link"));
253
261
  var _theme = require("./theme");
254
262
  var _util = require("./libs/util");
255
263
  Object.keys(_util).forEach(function (key) {
@@ -275,6 +283,18 @@ Object.keys(_connect).forEach(function (key) {
275
283
  }
276
284
  });
277
285
  });
286
+ var _phoneValidator = require("./libs/phone-validator");
287
+ Object.keys(_phoneValidator).forEach(function (key) {
288
+ if (key === "default" || key === "__esModule") return;
289
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
290
+ if (key in exports && exports[key] === _phoneValidator[key]) return;
291
+ Object.defineProperty(exports, key, {
292
+ enumerable: true,
293
+ get: function () {
294
+ return _phoneValidator[key];
295
+ }
296
+ });
297
+ });
278
298
  var _payment = require("./contexts/payment");
279
299
  Object.keys(_payment).forEach(function (key) {
280
300
  if (key === "default" || key === "__esModule") return;
@@ -0,0 +1,2 @@
1
+ export declare const getPhoneUtil: () => Promise<any>;
2
+ export declare const validatePhoneNumber: (phoneNumber: string) => Promise<any>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.validatePhoneNumber = exports.getPhoneUtil = void 0;
7
+ let phoneUtil = null;
8
+ const getPhoneUtil = async () => {
9
+ if (!phoneUtil) {
10
+ const {
11
+ PhoneNumberUtil
12
+ } = await Promise.resolve().then(() => require("google-libphonenumber"));
13
+ phoneUtil = PhoneNumberUtil.getInstance();
14
+ }
15
+ return phoneUtil;
16
+ };
17
+ exports.getPhoneUtil = getPhoneUtil;
18
+ const validatePhoneNumber = async phoneNumber => {
19
+ try {
20
+ const util = await getPhoneUtil();
21
+ const parsed = util.parseAndKeepRawInput(phoneNumber);
22
+ return util.isValidNumber(parsed);
23
+ } catch (err) {
24
+ console.error("Phone validation error:", err);
25
+ return false;
26
+ }
27
+ };
28
+ exports.validatePhoneNumber = validatePhoneNumber;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.translations = exports.translate = exports.t = exports.createTranslator = void 0;
7
- var _lodash = require("lodash");
7
+ var _template = _interopRequireDefault(require("lodash/template"));
8
8
  var _en = _interopRequireDefault(require("./en"));
9
9
  var _zh = _interopRequireDefault(require("./zh"));
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -14,7 +14,7 @@ const translations = exports.translations = {
14
14
  };
15
15
  const replace = (t2, data = {}) => {
16
16
  try {
17
- const compiled = (0, _lodash.template)(t2, {
17
+ const compiled = (0, _template.default)(t2, {
18
18
  interpolate: /{([\s\S]+?)}/g,
19
19
  escape: /{([\s\S]+?)}/g
20
20
  });
@@ -11,14 +11,13 @@ var _Toast = _interopRequireDefault(require("@arcblock/ux/lib/Toast"));
11
11
  var _lab = require("@mui/lab");
12
12
  var _material = require("@mui/material");
13
13
  var _ahooks = require("ahooks");
14
- var _googleLibphonenumber = require("google-libphonenumber");
15
14
  var _pWaitFor = _interopRequireDefault(require("p-wait-for"));
16
15
  var _react = require("react");
17
16
  var _reactHookForm = require("react-hook-form");
18
17
  var _ufo = require("ufo");
19
18
  var _useBus = require("use-bus");
20
19
  var _isEmail = _interopRequireDefault(require("validator/es/lib/isEmail"));
21
- var _lodash = require("lodash");
20
+ var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
22
21
  var _confirm = _interopRequireDefault(require("../../components/confirm"));
23
22
  var _input = _interopRequireDefault(require("../../components/input"));
24
23
  var _payment = require("../../contexts/payment");
@@ -30,8 +29,8 @@ var _currency = _interopRequireDefault(require("./currency"));
30
29
  var _phone = _interopRequireDefault(require("./phone"));
31
30
  var _stripe = _interopRequireDefault(require("./stripe"));
32
31
  var _mobile = require("../../hooks/mobile");
32
+ var _phoneValidator = require("../../libs/phone-validator");
33
33
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34
- const phoneUtil = _googleLibphonenumber.PhoneNumberUtil.getInstance();
35
34
  const waitForCheckoutComplete = async sessionId => {
36
35
  let result;
37
36
  await (0, _pWaitFor.default)(async () => {
@@ -202,7 +201,7 @@ function PaymentForm({
202
201
  }
203
202
  };
204
203
  (0, _react.useEffect)(() => {
205
- if (errorRef.current && !(0, _lodash.isEmpty)(errors) && isMobile) {
204
+ if (errorRef.current && !(0, _isEmpty.default)(errors) && isMobile) {
206
205
  errorRef.current.scrollIntoView({
207
206
  behavior: "smooth"
208
207
  });
@@ -336,7 +335,7 @@ function PaymentForm({
336
335
  });
337
336
  };
338
337
  const onAction = () => {
339
- if (errorRef.current && !(0, _lodash.isEmpty)(errors) && isMobile) {
338
+ if (errorRef.current && !(0, _isEmpty.default)(errors) && isMobile) {
340
339
  errorRef.current.scrollIntoView({
341
340
  behavior: "smooth"
342
341
  });
@@ -431,7 +430,7 @@ function PaymentForm({
431
430
  className: "cko-payment-form",
432
431
  id: "cko-payment-form",
433
432
  spacing: 0,
434
- ref: !(0, _lodash.isEmpty)(errors) ? errorRef : void 0,
433
+ ref: !(0, _isEmpty.default)(errors) ? errorRef : void 0,
435
434
  sx: {
436
435
  flex: 1,
437
436
  overflow: "auto",
@@ -469,13 +468,9 @@ function PaymentForm({
469
468
  placeholder: "Phone number",
470
469
  rules: {
471
470
  required: t("payment.checkout.required"),
472
- validate: x => {
473
- try {
474
- const parsed = phoneUtil.parseAndKeepRawInput(x);
475
- return phoneUtil.isValidNumber(parsed) ? true : t("payment.checkout.invalid");
476
- } catch {
477
- return t("payment.checkout.invalid");
478
- }
471
+ validate: async x => {
472
+ const isValid = await (0, _phoneValidator.validatePhoneNumber)(x);
473
+ return isValid ? true : t("payment.checkout.invalid");
479
474
  }
480
475
  }
481
476
  })]
@@ -13,10 +13,12 @@ Object.defineProperty(exports, "typography", {
13
13
  var _jsxRuntime = require("react/jsx-runtime");
14
14
  var _styles = require("@mui/material/styles");
15
15
  var _Theme = require("@arcblock/ux/lib/Theme");
16
- var _lodash = require("lodash");
16
+ var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
17
+ var _merge = _interopRequireDefault(require("lodash/merge"));
17
18
  var _material = require("@mui/material");
18
19
  var _typography = require("./typography");
19
20
  require("./index.css");
21
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
22
  PaymentThemeProvider.defaultProps = {
21
23
  theme: {}
22
24
  };
@@ -246,7 +248,7 @@ function PaymentThemeProvider({
246
248
  }
247
249
  }
248
250
  };
249
- const mergeTheme = (0, _Theme.create)((0, _lodash.merge)((0, _lodash.cloneDeep)({
251
+ const mergeTheme = (0, _Theme.create)((0, _merge.default)((0, _cloneDeep.default)({
250
252
  ...parentTheme,
251
253
  typography: _typography.typography,
252
254
  palette: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/payment-react",
3
- "version": "1.15.23",
3
+ "version": "1.15.25",
4
4
  "description": "Reusable react components for payment kit v2",
5
5
  "keywords": [
6
6
  "react",
@@ -53,15 +53,15 @@
53
53
  }
54
54
  },
55
55
  "dependencies": {
56
- "@arcblock/did-connect": "^2.10.51",
57
- "@arcblock/ux": "^2.10.51",
58
- "@arcblock/ws": "^1.18.136",
59
- "@blocklet/ui-react": "^2.10.51",
56
+ "@arcblock/did-connect": "^2.10.55",
57
+ "@arcblock/ux": "^2.10.55",
58
+ "@arcblock/ws": "^1.18.137",
59
+ "@blocklet/ui-react": "^2.10.55",
60
60
  "@mui/icons-material": "^5.16.6",
61
61
  "@mui/lab": "^5.0.0-alpha.173",
62
62
  "@mui/material": "^5.16.6",
63
63
  "@mui/system": "^5.16.6",
64
- "@ocap/util": "^1.18.136",
64
+ "@ocap/util": "^1.18.137",
65
65
  "@stripe/react-stripe-js": "^2.7.3",
66
66
  "@stripe/stripe-js": "^2.4.0",
67
67
  "@vitejs/plugin-legacy": "^5.4.1",
@@ -92,7 +92,7 @@
92
92
  "@babel/core": "^7.25.2",
93
93
  "@babel/preset-env": "^7.25.2",
94
94
  "@babel/preset-react": "^7.24.7",
95
- "@blocklet/payment-types": "1.15.23",
95
+ "@blocklet/payment-types": "1.15.25",
96
96
  "@storybook/addon-essentials": "^7.6.20",
97
97
  "@storybook/addon-interactions": "^7.6.20",
98
98
  "@storybook/addon-links": "^7.6.20",
@@ -122,5 +122,5 @@
122
122
  "vite-plugin-babel": "^1.2.0",
123
123
  "vite-plugin-node-polyfills": "^0.21.0"
124
124
  },
125
- "gitHead": "94862642b9c4f0f753a47e8c68d9b70315d8f008"
125
+ "gitHead": "c7d493c6e185b11844ef0ceb8abe688f1faad67c"
126
126
  }
@@ -0,0 +1,39 @@
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
+ import { useNavigate } from 'react-router-dom';
3
+ import React from 'react';
4
+
5
+ interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
6
+ to: string;
7
+ children: React.ReactNode;
8
+ replace?: boolean; // 是否替换当前历史记录
9
+ target?: string; // 打开方式
10
+ outLink?: boolean;
11
+ }
12
+
13
+ export default function Link({ to, children, onClick, replace, target, outLink = false, ...props }: LinkProps) {
14
+ const navigate = useNavigate();
15
+
16
+ const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
17
+ const isInternal = to.startsWith('/') || to.startsWith('#') || to.startsWith('?');
18
+ if (!outLink && isInternal) {
19
+ e.preventDefault();
20
+ navigate(to, { replace });
21
+ } else if (!target) {
22
+ e.preventDefault();
23
+ window.location.href = to;
24
+ }
25
+ onClick?.(e);
26
+ };
27
+
28
+ return (
29
+ <a href={to} onClick={handleClick} target={target} rel="noreferrer" {...props}>
30
+ {children}
31
+ </a>
32
+ );
33
+ }
34
+
35
+ Link.defaultProps = {
36
+ replace: false,
37
+ target: undefined,
38
+ outLink: false,
39
+ };
@@ -23,7 +23,7 @@ import { useSetState } from 'ahooks';
23
23
  import { useEffect, useMemo, useState } from 'react';
24
24
 
25
25
  import { BN } from '@ocap/util';
26
- import { isEmpty } from 'lodash';
26
+ import isEmpty from 'lodash/isEmpty';
27
27
  import { usePaymentContext } from '../contexts/payment';
28
28
  import {
29
29
  formatError,
@@ -1,4 +1,5 @@
1
- import { Tooltip, TooltipProps, tooltipClasses } from '@mui/material';
1
+ import { Tooltip, TooltipProps } from '@mui/material';
2
+ import { tooltipClasses } from '@mui/material/Tooltip';
2
3
  import { styled } from '@mui/system';
3
4
  import { truncateText } from '../libs/util';
4
5
 
package/src/index.ts CHANGED
@@ -26,11 +26,13 @@ import PaymentSummary from './payment/summary';
26
26
  import PricingItem from './components/pricing-item';
27
27
  import CountrySelect from './components/country-select';
28
28
  import TruncatedText from './components/truncated-text';
29
+ import Link from './components/link';
29
30
 
30
31
  export { PaymentThemeProvider } from './theme';
31
32
 
32
33
  export * from './libs/util';
33
34
  export * from './libs/connect';
35
+ export * from './libs/phone-validator';
34
36
  export * from './contexts/payment';
35
37
  export * from './hooks/subscription';
36
38
  export * from './hooks/mobile';
@@ -67,4 +69,5 @@ export {
67
69
  CountrySelect,
68
70
  Table,
69
71
  TruncatedText,
72
+ Link,
70
73
  };
@@ -0,0 +1,20 @@
1
+ let phoneUtil: any = null;
2
+
3
+ export const getPhoneUtil = async () => {
4
+ if (!phoneUtil) {
5
+ const { PhoneNumberUtil } = await import(/* webpackChunkName: "phone-util" */ 'google-libphonenumber');
6
+ phoneUtil = PhoneNumberUtil.getInstance();
7
+ }
8
+ return phoneUtil;
9
+ };
10
+
11
+ export const validatePhoneNumber = async (phoneNumber: string) => {
12
+ try {
13
+ const util = await getPhoneUtil();
14
+ const parsed = util.parseAndKeepRawInput(phoneNumber);
15
+ return util.isValidNumber(parsed);
16
+ } catch (err) {
17
+ console.error('Phone validation error:', err);
18
+ return false;
19
+ }
20
+ };
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-prototype-builtins */
2
- import { template } from 'lodash';
2
+ import template from 'lodash/template';
3
3
  import en from './en';
4
4
  import zh from './zh';
5
5
 
@@ -13,7 +13,6 @@ import type {
13
13
  import { LoadingButton } from '@mui/lab';
14
14
  import { Box, Divider, Fade, FormLabel, Stack, Typography } from '@mui/material';
15
15
  import { useMemoizedFn, useSetState } from 'ahooks';
16
- import { PhoneNumberUtil } from 'google-libphonenumber';
17
16
  import pWaitFor from 'p-wait-for';
18
17
  import { useEffect, useMemo, useRef, useState } from 'react';
19
18
  import { Controller, useFormContext, useWatch } from 'react-hook-form';
@@ -21,7 +20,7 @@ import { joinURL } from 'ufo';
21
20
  import { dispatch } from 'use-bus';
22
21
  import isEmail from 'validator/es/lib/isEmail';
23
22
 
24
- import { isEmpty } from 'lodash';
23
+ import isEmpty from 'lodash/isEmpty';
25
24
  import ConfirmDialog from '../../components/confirm';
26
25
  import FormInput from '../../components/input';
27
26
  import { usePaymentContext } from '../../contexts/payment';
@@ -41,8 +40,7 @@ import CurrencySelector from './currency';
41
40
  import PhoneInput from './phone';
42
41
  import StripeCheckout from './stripe';
43
42
  import { useMobile } from '../../hooks/mobile';
44
-
45
- const phoneUtil = PhoneNumberUtil.getInstance();
43
+ import { validatePhoneNumber } from '../../libs/phone-validator';
46
44
 
47
45
  const waitForCheckoutComplete = async (sessionId: string) => {
48
46
  let result: CheckoutContext;
@@ -482,13 +480,9 @@ export default function PaymentForm({
482
480
  placeholder="Phone number"
483
481
  rules={{
484
482
  required: t('payment.checkout.required'),
485
- validate: (x: string) => {
486
- try {
487
- const parsed = phoneUtil.parseAndKeepRawInput(x);
488
- return phoneUtil.isValidNumber(parsed) ? true : t('payment.checkout.invalid');
489
- } catch {
490
- return t('payment.checkout.invalid');
491
- }
483
+ validate: async (x: string) => {
484
+ const isValid = await validatePhoneNumber(x);
485
+ return isValid ? true : t('payment.checkout.invalid');
492
486
  },
493
487
  }}
494
488
  />
@@ -1,6 +1,7 @@
1
1
  import { type Theme, ThemeProvider, useTheme } from '@mui/material/styles';
2
2
  import { create } from '@arcblock/ux/lib/Theme';
3
- import { cloneDeep, merge } from 'lodash';
3
+ import cloneDeep from 'lodash/cloneDeep';
4
+ import merge from 'lodash/merge';
4
5
  import { Box, CssBaseline } from '@mui/material';
5
6
  import React from 'react';
6
7