@blocklet/payment-react 1.13.113

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 (173) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +29 -0
  3. package/babel.config.es.js +8 -0
  4. package/build.config.ts +29 -0
  5. package/es/api.d.ts +2 -0
  6. package/es/api.js +18 -0
  7. package/es/checkout/index.d.ts +15 -0
  8. package/es/checkout/index.js +61 -0
  9. package/es/components/input.d.ts +23 -0
  10. package/es/components/input.js +44 -0
  11. package/es/components/livemode.d.ts +2 -0
  12. package/es/components/livemode.js +24 -0
  13. package/es/components/pricing-table.d.ts +18 -0
  14. package/es/components/pricing-table.js +175 -0
  15. package/es/components/status.d.ts +3 -0
  16. package/es/components/status.js +20 -0
  17. package/es/components/switch.d.ts +6 -0
  18. package/es/components/switch.js +42 -0
  19. package/es/contexts/payment.d.ts +29 -0
  20. package/es/contexts/payment.js +45 -0
  21. package/es/dayjs.d.ts +2 -0
  22. package/es/dayjs.js +14 -0
  23. package/es/index.d.ts +16 -0
  24. package/es/index.js +29 -0
  25. package/es/locales/en.d.ts +2 -0
  26. package/es/locales/en.js +213 -0
  27. package/es/locales/index.d.ts +10 -0
  28. package/es/locales/index.js +20 -0
  29. package/es/locales/zh.d.ts +2 -0
  30. package/es/locales/zh.js +213 -0
  31. package/es/payment/amount.d.ts +12 -0
  32. package/es/payment/amount.js +22 -0
  33. package/es/payment/error.d.ts +13 -0
  34. package/es/payment/error.js +12 -0
  35. package/es/payment/footer.d.ts +4 -0
  36. package/es/payment/footer.js +9 -0
  37. package/es/payment/form/addon.d.ts +2 -0
  38. package/es/payment/form/addon.js +14 -0
  39. package/es/payment/form/address.d.ts +7 -0
  40. package/es/payment/form/address.js +119 -0
  41. package/es/payment/form/index.d.ts +9 -0
  42. package/es/payment/form/index.js +337 -0
  43. package/es/payment/form/phone.d.ts +4 -0
  44. package/es/payment/form/phone.js +97 -0
  45. package/es/payment/form/stripe.d.ts +13 -0
  46. package/es/payment/form/stripe.js +158 -0
  47. package/es/payment/header.d.ts +7 -0
  48. package/es/payment/header.js +29 -0
  49. package/es/payment/index.d.ts +28 -0
  50. package/es/payment/index.js +327 -0
  51. package/es/payment/product-card.d.ts +21 -0
  52. package/es/payment/product-card.js +34 -0
  53. package/es/payment/product-item.d.ts +19 -0
  54. package/es/payment/product-item.js +107 -0
  55. package/es/payment/product-skeleton.d.ts +4 -0
  56. package/es/payment/product-skeleton.js +34 -0
  57. package/es/payment/skeleton/overview.d.ts +2 -0
  58. package/es/payment/skeleton/overview.js +13 -0
  59. package/es/payment/skeleton/payment.d.ts +2 -0
  60. package/es/payment/skeleton/payment.js +19 -0
  61. package/es/payment/success.d.ts +8 -0
  62. package/es/payment/success.js +164 -0
  63. package/es/payment/summary.d.ts +12 -0
  64. package/es/payment/summary.js +178 -0
  65. package/es/theme.d.ts +1 -0
  66. package/es/theme.js +17 -0
  67. package/es/types/index.d.ts +19 -0
  68. package/es/types/index.js +0 -0
  69. package/es/types/shims.d.ts +18 -0
  70. package/es/util.d.ts +52 -0
  71. package/es/util.js +390 -0
  72. package/lib/api.d.ts +2 -0
  73. package/lib/api.js +26 -0
  74. package/lib/checkout/index.d.ts +15 -0
  75. package/lib/checkout/index.js +83 -0
  76. package/lib/components/input.d.ts +23 -0
  77. package/lib/components/input.js +72 -0
  78. package/lib/components/livemode.d.ts +2 -0
  79. package/lib/components/livemode.js +29 -0
  80. package/lib/components/pricing-table.d.ts +18 -0
  81. package/lib/components/pricing-table.js +232 -0
  82. package/lib/components/status.d.ts +3 -0
  83. package/lib/components/status.js +23 -0
  84. package/lib/components/switch.d.ts +6 -0
  85. package/lib/components/switch.js +51 -0
  86. package/lib/contexts/payment.d.ts +29 -0
  87. package/lib/contexts/payment.js +73 -0
  88. package/lib/dayjs.d.ts +2 -0
  89. package/lib/dayjs.js +21 -0
  90. package/lib/index.d.ts +16 -0
  91. package/lib/index.js +143 -0
  92. package/lib/locales/en.d.ts +2 -0
  93. package/lib/locales/en.js +220 -0
  94. package/lib/locales/index.d.ts +10 -0
  95. package/lib/locales/index.js +33 -0
  96. package/lib/locales/zh.d.ts +2 -0
  97. package/lib/locales/zh.js +220 -0
  98. package/lib/payment/amount.d.ts +12 -0
  99. package/lib/payment/amount.js +28 -0
  100. package/lib/payment/error.d.ts +13 -0
  101. package/lib/payment/error.js +52 -0
  102. package/lib/payment/footer.d.ts +4 -0
  103. package/lib/payment/footer.js +25 -0
  104. package/lib/payment/form/addon.d.ts +2 -0
  105. package/lib/payment/form/addon.js +37 -0
  106. package/lib/payment/form/address.d.ts +7 -0
  107. package/lib/payment/form/address.js +152 -0
  108. package/lib/payment/form/index.d.ts +9 -0
  109. package/lib/payment/form/index.js +464 -0
  110. package/lib/payment/form/phone.d.ts +4 -0
  111. package/lib/payment/form/phone.js +133 -0
  112. package/lib/payment/form/stripe.d.ts +13 -0
  113. package/lib/payment/form/stripe.js +213 -0
  114. package/lib/payment/header.d.ts +7 -0
  115. package/lib/payment/header.js +58 -0
  116. package/lib/payment/index.d.ts +28 -0
  117. package/lib/payment/index.js +382 -0
  118. package/lib/payment/product-card.d.ts +21 -0
  119. package/lib/payment/product-card.js +81 -0
  120. package/lib/payment/product-item.d.ts +19 -0
  121. package/lib/payment/product-item.js +160 -0
  122. package/lib/payment/product-skeleton.d.ts +4 -0
  123. package/lib/payment/product-skeleton.js +71 -0
  124. package/lib/payment/skeleton/overview.d.ts +2 -0
  125. package/lib/payment/skeleton/overview.js +48 -0
  126. package/lib/payment/skeleton/payment.d.ts +2 -0
  127. package/lib/payment/skeleton/payment.js +54 -0
  128. package/lib/payment/success.d.ts +8 -0
  129. package/lib/payment/success.js +215 -0
  130. package/lib/payment/summary.d.ts +12 -0
  131. package/lib/payment/summary.js +225 -0
  132. package/lib/theme.d.ts +1 -0
  133. package/lib/theme.js +19 -0
  134. package/lib/types/index.d.ts +19 -0
  135. package/lib/types/index.js +1 -0
  136. package/lib/types/shims.d.ts +18 -0
  137. package/lib/util.d.ts +52 -0
  138. package/lib/util.js +487 -0
  139. package/package.json +104 -0
  140. package/src/api.ts +24 -0
  141. package/src/checkout/index.tsx +74 -0
  142. package/src/components/input.tsx +58 -0
  143. package/src/components/livemode.tsx +23 -0
  144. package/src/components/pricing-table.tsx +207 -0
  145. package/src/components/status.tsx +19 -0
  146. package/src/components/switch.tsx +48 -0
  147. package/src/contexts/payment.tsx +74 -0
  148. package/src/dayjs.ts +17 -0
  149. package/src/index.ts +32 -0
  150. package/src/locales/en.tsx +218 -0
  151. package/src/locales/index.tsx +30 -0
  152. package/src/locales/zh.tsx +214 -0
  153. package/src/payment/amount.tsx +24 -0
  154. package/src/payment/error.tsx +29 -0
  155. package/src/payment/footer.tsx +12 -0
  156. package/src/payment/form/addon.tsx +24 -0
  157. package/src/payment/form/address.tsx +119 -0
  158. package/src/payment/form/index.tsx +401 -0
  159. package/src/payment/form/phone.tsx +103 -0
  160. package/src/payment/form/stripe.tsx +195 -0
  161. package/src/payment/header.tsx +40 -0
  162. package/src/payment/index.tsx +367 -0
  163. package/src/payment/product-card.tsx +55 -0
  164. package/src/payment/product-item.tsx +121 -0
  165. package/src/payment/product-skeleton.tsx +39 -0
  166. package/src/payment/skeleton/overview.tsx +21 -0
  167. package/src/payment/skeleton/payment.tsx +35 -0
  168. package/src/payment/success.tsx +186 -0
  169. package/src/payment/summary.tsx +198 -0
  170. package/src/theme.ts +18 -0
  171. package/src/types/index.ts +29 -0
  172. package/src/types/shims.d.ts +18 -0
  173. package/src/util.ts +543 -0
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2018-2024 ArcBlock
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Payment Kit Components
2
+
3
+ ```tsx
4
+ import { PaymentProvider, Checkout, PricingTable } from '@blocklet/payment-react';
5
+
6
+ export default function Payment() {
7
+ const { session, connectApi } = useSessionContext();
8
+ const { locale } = useLocaleContext();
9
+
10
+ return (<PaymentProvider session={session} connect={connectApi} locale={locale}>
11
+ <Checkout checkoutSessionId="" onComplete={noop} onError={noop} params={{}} />
12
+ <Checkout paymentLinkId="" onComplete={noop} onError={noop} params={{}} />
13
+ <Checkout pricingTableId="" onSelect={noop} onComplete={noop} onError={noop} params={{}} />
14
+ </PaymentProvider>);
15
+ }
16
+ ```
17
+
18
+ ## I18n
19
+
20
+ ```tsx
21
+ import { createTranslator, translations as extraTranslations } from '@blocklet/payment-react';
22
+ import merge from 'lodash/merge';
23
+
24
+ import en from './en';
25
+ import zh from './zh';
26
+
27
+ // eslint-disable-next-line import/prefer-default-export
28
+ export const translations = merge({ zh, en }, extraTranslations);
29
+ ```
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ presets: [
3
+ ['@babel/preset-env', { modules: false, targets: 'chrome 114' }],
4
+ ['@babel/preset-react', { useBuiltIns: true, runtime: 'automatic' }],
5
+ ],
6
+ plugins: ['babel-plugin-inline-react-svg'],
7
+ ignore: ['src/**/*.stories.js', 'src/**/demo'],
8
+ };
@@ -0,0 +1,29 @@
1
+ import { defineBuildConfig, BuildEntry } from 'unbuild';
2
+
3
+ const pattern = ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx', '**/*.png', '!**/*.stories.js', '!**/demo'];
4
+
5
+ const shared: BuildEntry = {
6
+ builder: 'mkdist',
7
+ input: './src',
8
+ pattern,
9
+ ext: 'js',
10
+ esbuild: {
11
+ jsx: 'automatic',
12
+ },
13
+ declaration: true,
14
+ };
15
+ export default defineBuildConfig({
16
+ failOnWarn: false,
17
+ entries: [
18
+ {
19
+ ...shared,
20
+ outDir: './es',
21
+ format: 'esm',
22
+ },
23
+ {
24
+ ...shared,
25
+ outDir: './lib',
26
+ format: 'cjs',
27
+ },
28
+ ],
29
+ });
package/es/api.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ declare const api: import("axios").AxiosInstance;
2
+ export default api;
package/es/api.js ADDED
@@ -0,0 +1,18 @@
1
+ import { getLocale } from "@arcblock/ux/lib/Locale/context";
2
+ import axios from "axios";
3
+ import isNull from "lodash/isNull";
4
+ import { getPrefix } from "./util.js";
5
+ const api = axios.create();
6
+ api.interceptors.request.use(
7
+ (config) => {
8
+ const prefix = getPrefix();
9
+ config.baseURL = prefix || "";
10
+ config.timeout = 8e3;
11
+ const livemode = localStorage.getItem("livemode");
12
+ const locale = getLocale(window.blocklet.languages);
13
+ config.params = { ...config.params || {}, livemode: isNull(livemode) ? true : JSON.parse(livemode), locale };
14
+ return config;
15
+ },
16
+ (err) => Promise.reject(err)
17
+ );
18
+ export default api;
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ import { CheckoutProps } from '../types';
3
+ declare function Checkout({ id, onPaid, onError, mode, extraParams }: CheckoutProps): import("react").JSX.Element;
4
+ declare namespace Checkout {
5
+ var defaultProps: {
6
+ onPaid: any;
7
+ onError: {
8
+ (...data: any[]): void;
9
+ (message?: any, ...optionalParams: any[]): void;
10
+ };
11
+ mode: string;
12
+ extraParams: {};
13
+ };
14
+ }
15
+ export default Checkout;
@@ -0,0 +1,61 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useRequest, useSetState } from "ahooks";
3
+ import noop from "lodash/noop";
4
+ import { useEffect } from "react";
5
+ import { joinURL } from "ufo";
6
+ import api from "../api.js";
7
+ import Payment from "../payment/index.js";
8
+ import { getPrefix, mergeExtraParams } from "../util.js";
9
+ const startFromPaymentLink = async (id, params) => {
10
+ const { data } = await api.post(`/api/checkout-sessions/start/${id}?${mergeExtraParams(params)}`);
11
+ return data;
12
+ };
13
+ const fetchCheckoutSession = async (id) => {
14
+ const { data } = await api.get(`/api/checkout-sessions/retrieve/${id}`);
15
+ return data;
16
+ };
17
+ export default function Checkout({ id, onPaid, onError, mode, extraParams }) {
18
+ if (!id.startsWith("plink_") && !id.startsWith("cs_")) {
19
+ throw new Error("Either a checkout session or a payment link id is required.");
20
+ }
21
+ const type = id.startsWith("plink_") ? "paymentLink" : "checkoutSession";
22
+ const [state, setState] = useSetState({ completed: false, appError: null });
23
+ const { error: apiError, data } = useRequest(
24
+ () => type === "paymentLink" ? startFromPaymentLink(id, extraParams) : fetchCheckoutSession(id)
25
+ );
26
+ useEffect(() => {
27
+ if (type === "paymentLink" && mode === "standalone" && data) {
28
+ window.location.replace(joinURL(getPrefix(), `/checkout/pay/${data.checkoutSession.id}`));
29
+ }
30
+ }, [type, mode, data]);
31
+ const handlePaid = () => {
32
+ setState({ completed: true });
33
+ onPaid?.(data);
34
+ };
35
+ const handleError = (err) => {
36
+ console.error(err);
37
+ setState({ appError: err });
38
+ onError?.(err);
39
+ };
40
+ return /* @__PURE__ */ jsx(
41
+ Payment,
42
+ {
43
+ checkoutSession: data?.checkoutSession,
44
+ paymentMethods: data?.paymentMethods,
45
+ paymentIntent: data?.paymentIntent,
46
+ paymentLink: data?.paymentLink,
47
+ customer: data?.customer,
48
+ completed: state.completed,
49
+ error: apiError || state.appError,
50
+ onPaid: handlePaid,
51
+ onError: handleError,
52
+ mode
53
+ }
54
+ );
55
+ }
56
+ Checkout.defaultProps = {
57
+ onPaid: noop,
58
+ onError: console.error,
59
+ mode: "inline",
60
+ extraParams: {}
61
+ };
@@ -0,0 +1,23 @@
1
+ /// <reference types="react" />
2
+ import { TextFieldProps } from '@mui/material';
3
+ import { RegisterOptions } from 'react-hook-form';
4
+ type InputProps = TextFieldProps & {
5
+ name: string;
6
+ label?: string;
7
+ placeholder?: string;
8
+ errorPosition?: 'right' | 'bottom';
9
+ rules?: RegisterOptions;
10
+ };
11
+ export declare function FormInputError({ error }: {
12
+ error: string;
13
+ }): import("react").JSX.Element;
14
+ declare function FormInput({ name, label, placeholder, rules, errorPosition, ...rest }: InputProps): import("react").JSX.Element;
15
+ declare namespace FormInput {
16
+ var defaultProps: {
17
+ label: string;
18
+ placeholder: string;
19
+ errorPosition: string;
20
+ rules: {};
21
+ };
22
+ }
23
+ export default FormInput;
@@ -0,0 +1,44 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Box, FormLabel, InputAdornment, TextField, Typography } from "@mui/material";
3
+ import get from "lodash/get";
4
+ import { Controller, useFormContext } from "react-hook-form";
5
+ FormInput.defaultProps = {
6
+ label: "",
7
+ placeholder: "",
8
+ errorPosition: "bottom",
9
+ rules: {}
10
+ };
11
+ export function FormInputError({ error }) {
12
+ return /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx(Typography, { component: "span", color: "error", children: error }) });
13
+ }
14
+ export default function FormInput({ name, label, placeholder, rules, errorPosition, ...rest }) {
15
+ const { control, formState } = useFormContext();
16
+ const error = get(formState.errors, name)?.message;
17
+ return /* @__PURE__ */ jsx(
18
+ Controller,
19
+ {
20
+ name,
21
+ control,
22
+ rules,
23
+ render: ({ field }) => /* @__PURE__ */ jsxs(Box, { sx: { width: "100%" }, children: [
24
+ !!label && /* @__PURE__ */ jsx(FormLabel, { children: label }),
25
+ /* @__PURE__ */ jsx(
26
+ TextField,
27
+ {
28
+ fullWidth: true,
29
+ error: !!get(formState.errors, name),
30
+ helperText: errorPosition === "bottom" && error ? error : "",
31
+ placeholder,
32
+ size: "small",
33
+ ...field,
34
+ ...rest,
35
+ InputProps: Object.assign(
36
+ rest.InputProps || {},
37
+ errorPosition === "right" && error ? { endAdornment: /* @__PURE__ */ jsx(FormInputError, { error }) } : {}
38
+ )
39
+ }
40
+ )
41
+ ] })
42
+ }
43
+ );
44
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export default function Livemode(): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
3
+ import { Chip } from "@mui/material";
4
+ export default function Livemode() {
5
+ const { t } = useLocaleContext();
6
+ return /* @__PURE__ */ jsx(
7
+ Chip,
8
+ {
9
+ label: t("common.livemode"),
10
+ size: "small",
11
+ sx: {
12
+ ml: 2,
13
+ height: 18,
14
+ lineHeight: 1,
15
+ textTransform: "uppercase",
16
+ fontSize: "0.8rem",
17
+ fontWeight: "bold",
18
+ borderRadius: "4px",
19
+ backgroundColor: "#ffde92",
20
+ color: "#bb5504"
21
+ }
22
+ }
23
+ );
24
+ }
@@ -0,0 +1,18 @@
1
+ /// <reference types="react" />
2
+ import type { TPricingTableExpanded } from '@blocklet/payment-types';
3
+ type Props = {
4
+ table: TPricingTableExpanded;
5
+ onSelect: (priceId: string) => void;
6
+ alignItems?: 'center' | 'left';
7
+ mode?: 'checkout' | 'select';
8
+ interval?: string;
9
+ };
10
+ declare function PricingTable({ table, alignItems, interval, mode, onSelect }: Props): import("react").JSX.Element;
11
+ declare namespace PricingTable {
12
+ var defaultProps: {
13
+ alignItems: string;
14
+ mode: string;
15
+ interval: string;
16
+ };
17
+ }
18
+ export default PricingTable;
@@ -0,0 +1,175 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
3
+ import Toast from "@arcblock/ux/lib/Toast";
4
+ import { CheckOutlined } from "@mui/icons-material";
5
+ import { LoadingButton } from "@mui/lab";
6
+ import {
7
+ Box,
8
+ Chip,
9
+ Fade,
10
+ List,
11
+ ListItem,
12
+ ListItemIcon,
13
+ ListItemText,
14
+ Stack,
15
+ ToggleButton,
16
+ ToggleButtonGroup,
17
+ Typography
18
+ } from "@mui/material";
19
+ import { useSetState } from "ahooks";
20
+ import { useEffect } from "react";
21
+ import Amount from "../payment/amount.js";
22
+ import { formatError, formatPriceAmount, formatRecurring } from "../util.js";
23
+ const groupItemsByRecurring = (items) => {
24
+ const grouped = {};
25
+ const recurring = {};
26
+ items.forEach((x) => {
27
+ const key = [x.price.recurring?.interval, x.price.recurring?.interval_count].join("-");
28
+ recurring[key] = x.price.recurring;
29
+ if (!grouped[key]) {
30
+ grouped[key] = [];
31
+ }
32
+ grouped[key].push(x);
33
+ });
34
+ return { recurring, grouped };
35
+ };
36
+ PricingTable.defaultProps = {
37
+ alignItems: "center",
38
+ mode: "checkout",
39
+ interval: ""
40
+ };
41
+ export default function PricingTable({ table, alignItems, interval, mode, onSelect }) {
42
+ const { t, locale } = useLocaleContext();
43
+ const [state, setState] = useSetState({ interval, loading: "" });
44
+ const { recurring, grouped } = groupItemsByRecurring(table.items);
45
+ useEffect(() => {
46
+ if (table) {
47
+ if (!state.interval || !grouped[state.interval]) {
48
+ const keys = Object.keys(recurring);
49
+ if (keys[0]) {
50
+ setState({ interval: keys[0] });
51
+ }
52
+ }
53
+ }
54
+ }, [table]);
55
+ const handleSelect = async (priceId) => {
56
+ try {
57
+ setState({ loading: priceId });
58
+ await onSelect(priceId);
59
+ } catch (err) {
60
+ console.error(err);
61
+ Toast.error(formatError(err));
62
+ } finally {
63
+ setState({ loading: "" });
64
+ }
65
+ };
66
+ return /* @__PURE__ */ jsxs(
67
+ Stack,
68
+ {
69
+ direction: "column",
70
+ alignItems: alignItems === "center" ? "center" : "flex-start",
71
+ sx: {
72
+ pt: {
73
+ xs: 4,
74
+ sm: 2
75
+ },
76
+ gap: {
77
+ xs: 3,
78
+ sm: mode === "select" ? 3 : 5
79
+ }
80
+ },
81
+ children: [
82
+ Object.keys(recurring).length > 1 && /* @__PURE__ */ jsx(
83
+ ToggleButtonGroup,
84
+ {
85
+ color: "primary",
86
+ value: state.interval,
87
+ onChange: (_, value) => {
88
+ if (value !== null) {
89
+ setState({ interval: value });
90
+ }
91
+ },
92
+ exclusive: true,
93
+ children: Object.keys(recurring).map((x) => /* @__PURE__ */ jsx(ToggleButton, { value: x, sx: { textTransform: "capitalize" }, children: formatRecurring(recurring[x], true, "", locale) }, x))
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsx(
97
+ Stack,
98
+ {
99
+ flexWrap: "wrap",
100
+ direction: "row",
101
+ gap: { xs: 3, sm: 5, md: mode === "checkout" ? 10 : 5 },
102
+ justifyContent: alignItems === "center" ? "center" : "flex-start",
103
+ children: grouped[state.interval]?.map((x) => {
104
+ let action = x.subscription_data?.trial_period_days ? t("payment.checkout.try") : t("payment.checkout.subscription");
105
+ if (mode === "select") {
106
+ action = x.is_selected ? t("payment.checkout.selected") : t("payment.checkout.select");
107
+ }
108
+ return /* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(
109
+ Stack,
110
+ {
111
+ padding: 4,
112
+ spacing: 2,
113
+ direction: "column",
114
+ alignItems: "center",
115
+ sx: {
116
+ width: 320,
117
+ cursor: "pointer",
118
+ borderWidth: "1px",
119
+ borderStyle: "solid",
120
+ borderColor: mode === "select" && x.is_selected ? "primary.main" : "#eee",
121
+ borderRadius: 1,
122
+ transition: "border-color 0.3s ease 0s, box-shadow 0.3s ease 0s",
123
+ boxShadow: "0 4px 8px rgba(0, 0, 0, 20%)",
124
+ "&:hover": {
125
+ borderColor: mode === "select" && x.is_selected ? "primary.main" : "#ddd",
126
+ boxShadow: "0 8px 16px rgba(0, 0, 0, 20%)"
127
+ }
128
+ },
129
+ children: [
130
+ /* @__PURE__ */ jsxs(Box, { textAlign: "center", children: [
131
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 1, children: [
132
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", color: "text.primary", fontWeight: 600, children: x.product.name }),
133
+ x.is_highlight && /* @__PURE__ */ jsx(Chip, { label: x.highlight_text, color: "default", size: "small" })
134
+ ] }),
135
+ /* @__PURE__ */ jsx(Typography, { color: "text.secondary", children: x.product.description })
136
+ ] }),
137
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 1, children: [
138
+ /* @__PURE__ */ jsx(Amount, { amount: formatPriceAmount(x.price, table.currency, x.product.unit_label) }),
139
+ /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-start", children: [
140
+ /* @__PURE__ */ jsx(Typography, { component: "span", color: "text.secondary", fontSize: "0.8rem", children: t("payment.checkout.per") }),
141
+ /* @__PURE__ */ jsx(Typography, { component: "span", color: "text.secondary", fontSize: "0.8rem", children: formatRecurring(x.price.recurring, false, "", locale) })
142
+ ] })
143
+ ] }),
144
+ /* @__PURE__ */ jsx(
145
+ LoadingButton,
146
+ {
147
+ fullWidth: true,
148
+ size: "large",
149
+ loadingPosition: "end",
150
+ variant: x.is_highlight || x.is_selected ? "contained" : "outlined",
151
+ color: x.is_highlight || x.is_selected ? "primary" : "info",
152
+ sx: { fontSize: "1.2rem" },
153
+ loading: state.loading === x.price_id,
154
+ disabled: x.is_disabled,
155
+ onClick: () => handleSelect(x.price_id),
156
+ children: action
157
+ }
158
+ ),
159
+ x.product.features.length > 0 && /* @__PURE__ */ jsxs(Box, { children: [
160
+ /* @__PURE__ */ jsx(Typography, { children: t("payment.checkout.include") }),
161
+ /* @__PURE__ */ jsx(List, { dense: true, children: x.product.features.map((f) => /* @__PURE__ */ jsxs(ListItem, { disableGutters: true, disablePadding: true, children: [
162
+ /* @__PURE__ */ jsx(ListItemIcon, { sx: { minWidth: 25 }, children: /* @__PURE__ */ jsx(CheckOutlined, { color: "success", fontSize: "small" }) }),
163
+ /* @__PURE__ */ jsx(ListItemText, { primary: f.name })
164
+ ] }, f.name)) })
165
+ ] })
166
+ ]
167
+ }
168
+ ) }, x.price_id);
169
+ })
170
+ }
171
+ )
172
+ ]
173
+ }
174
+ );
175
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { ChipProps } from '@mui/material';
3
+ export default function Status(props: ChipProps): import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Chip } from "@mui/material";
3
+ export default function Status(props) {
4
+ return /* @__PURE__ */ jsx(
5
+ Chip,
6
+ {
7
+ size: "small",
8
+ variant: "outlined",
9
+ ...props,
10
+ sx: {
11
+ ...props.sx || {},
12
+ borderRadius: "4px",
13
+ height: 20,
14
+ lineHeight: 1,
15
+ textTransform: "capitalize",
16
+ marginRight: "10px"
17
+ }
18
+ }
19
+ );
20
+ }
@@ -0,0 +1,6 @@
1
+ import type { LiteralUnion } from 'type-fest';
2
+ type SwitchProps = {
3
+ variant?: LiteralUnion<'success' | 'error' | 'warning' | 'info' | 'primary' | 'secondary', string>;
4
+ };
5
+ declare const _default: import("@emotion/styled").StyledComponent<import("@mui/material").SwitchProps & import("@mui/system").MUIStyledCommonProps<import("@mui/system").Theme> & SwitchProps, {}, {}>;
6
+ export default _default;
@@ -0,0 +1,42 @@
1
+ import { Switch } from "@mui/material";
2
+ import { styled } from "@mui/system";
3
+ export default styled(Switch)(({ variant = "success", theme }) => ({
4
+ width: 28,
5
+ height: 16,
6
+ padding: 0,
7
+ display: "inline-flex",
8
+ "&:active": {
9
+ "& .MuiSwitch-thumb": {
10
+ width: 15
11
+ },
12
+ "& .MuiSwitch-switchBase.Mui-checked": {
13
+ transform: "translateX(9px)"
14
+ }
15
+ },
16
+ "& .MuiSwitch-switchBase": {
17
+ padding: 2,
18
+ "&.Mui-checked": {
19
+ transform: "translateX(12px)",
20
+ color: "#fff",
21
+ "& + .MuiSwitch-track": {
22
+ opacity: 1,
23
+ backgroundColor: theme.palette[variant].light
24
+ }
25
+ }
26
+ },
27
+ "& .MuiSwitch-thumb": {
28
+ boxShadow: "0 2px 4px 0 rgb(0 35 11 / 20%)",
29
+ width: 12,
30
+ height: 12,
31
+ borderRadius: 6,
32
+ transition: theme.transitions.create(["width"], {
33
+ duration: 200
34
+ })
35
+ },
36
+ "& .MuiSwitch-track": {
37
+ borderRadius: 16 / 2,
38
+ opacity: 1,
39
+ backgroundColor: theme.palette.mode === "dark" ? "rgba(255,255,255,.35)" : "rgba(0,0,0,.25)",
40
+ boxSizing: "border-box"
41
+ }
42
+ }));
@@ -0,0 +1,29 @@
1
+ /// <reference types="react" />
2
+ import type { TPaymentCurrency, TPaymentMethodExpanded } from '@blocklet/payment-types';
3
+ import type { Axios } from 'axios';
4
+ export interface Settings {
5
+ paymentMethods: TPaymentMethodExpanded[];
6
+ baseCurrency: TPaymentCurrency;
7
+ }
8
+ export type PaymentContextType = {
9
+ livemode: boolean;
10
+ session: any;
11
+ connect: any;
12
+ prefix: string;
13
+ settings: Settings;
14
+ refresh: () => void;
15
+ setLivemode: (livemode: boolean) => void;
16
+ api: Axios;
17
+ };
18
+ declare const PaymentContext: import("react").Context<PaymentContextType>;
19
+ declare const Consumer: import("react").Consumer<PaymentContextType>;
20
+ declare function PaymentProvider({ children, session, connect }: {
21
+ children: any;
22
+ session: any;
23
+ connect: any;
24
+ }): JSX.Element;
25
+ declare namespace PaymentProvider {
26
+ var defaultProps: {};
27
+ }
28
+ declare function usePaymentContext(): PaymentContextType;
29
+ export { PaymentContext, PaymentProvider, Consumer as SettingsConsumer, usePaymentContext };
@@ -0,0 +1,45 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Alert, CircularProgress } from "@mui/material";
3
+ import { useLocalStorageState, useRequest } from "ahooks";
4
+ import { createContext, useContext } from "react";
5
+ import api from "../api.js";
6
+ import { getPrefix } from "../util.js";
7
+ const prefix = getPrefix();
8
+ const PaymentContext = createContext({ api });
9
+ const { Provider, Consumer } = PaymentContext;
10
+ const getSettings = async () => {
11
+ const { data } = await api.get("/api/settings");
12
+ return data;
13
+ };
14
+ function PaymentProvider({ children, session, connect }) {
15
+ const { data, error, run, loading } = useRequest(getSettings);
16
+ const [livemode, setLivemode] = useLocalStorageState("livemode", { defaultValue: true });
17
+ if (error) {
18
+ return /* @__PURE__ */ jsx(Alert, { severity: "error", children: error.message });
19
+ }
20
+ if (loading) {
21
+ return /* @__PURE__ */ jsx(CircularProgress, {});
22
+ }
23
+ return /* @__PURE__ */ jsx(
24
+ Provider,
25
+ {
26
+ value: {
27
+ session,
28
+ connect,
29
+ prefix,
30
+ livemode: !!livemode,
31
+ settings: data,
32
+ refresh: run,
33
+ setLivemode,
34
+ api
35
+ },
36
+ children
37
+ }
38
+ );
39
+ }
40
+ function usePaymentContext() {
41
+ const context = useContext(PaymentContext);
42
+ return context;
43
+ }
44
+ PaymentProvider.defaultProps = {};
45
+ export { PaymentContext, PaymentProvider, Consumer as SettingsConsumer, usePaymentContext };
package/es/dayjs.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import dayjs from 'dayjs';
2
+ export default dayjs;
package/es/dayjs.js ADDED
@@ -0,0 +1,14 @@
1
+ import dayjs from "dayjs";
2
+ import duration from "dayjs/plugin/duration";
3
+ import localizedFormat from "dayjs/plugin/localizedFormat";
4
+ import relativeTime from "dayjs/plugin/relativeTime";
5
+ import timezone from "dayjs/plugin/timezone";
6
+ import utc from "dayjs/plugin/utc";
7
+ import("dayjs/locale/en");
8
+ import("dayjs/locale/zh");
9
+ dayjs.extend(relativeTime);
10
+ dayjs.extend(localizedFormat);
11
+ dayjs.extend(duration);
12
+ dayjs.extend(utc);
13
+ dayjs.extend(timezone);
14
+ export default dayjs;
package/es/index.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import api from './api';
2
+ import Checkout from './checkout';
3
+ import FormInput from './components/input';
4
+ import Livemode from './components/livemode';
5
+ import PricingTable from './components/pricing-table';
6
+ import Status from './components/status';
7
+ import Switch from './components/switch';
8
+ import dayjs from './dayjs';
9
+ import Amount from './payment/amount';
10
+ import PhoneInput from './payment/form/phone';
11
+ import Payment from './payment/index';
12
+ import ProductSkeleton from './payment/product-skeleton';
13
+ export * from './util';
14
+ export * from './contexts/payment';
15
+ export { translations, createTranslator } from './locales';
16
+ export { api, dayjs, FormInput, PhoneInput, Status, Livemode, Switch, Checkout, Payment, PricingTable, ProductSkeleton, Amount, };