@blocklet/payment-react 1.15.34 → 1.15.35

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.
@@ -16,11 +16,12 @@ export type DonateProps = Pick<CheckoutProps, 'onPaid' | 'onError'> & {
16
16
  settings: DonationSettings;
17
17
  livemode?: boolean;
18
18
  timeout?: number;
19
- mode?: 'inline' | 'default';
19
+ mode?: 'inline' | 'default' | 'custom';
20
20
  inlineOptions?: {
21
21
  button?: ButtonType;
22
22
  };
23
23
  theme?: 'default' | 'inherit' | PaymentThemeOptions;
24
+ children?: (openDialog: () => void, donateTotalAmount: string, supporters: DonateHistory) => React.ReactNode;
24
25
  };
25
26
  declare function CheckoutDonate(props: DonateProps): import("react").JSX.Element;
26
27
  declare namespace CheckoutDonate {
@@ -224,7 +224,8 @@ function CheckoutDonateInner({
224
224
  onError,
225
225
  mode,
226
226
  inlineOptions = {},
227
- theme
227
+ theme,
228
+ children
228
229
  }) {
229
230
  const { state, setState, donation, supporters } = useDonation(settings, livemode, mode);
230
231
  const [anchorEl, setAnchorEl] = useState(null);
@@ -250,102 +251,126 @@ function CheckoutDonateInner({
250
251
  const handlePopoverClose = () => {
251
252
  setPopoverOpen(false);
252
253
  };
253
- return /* @__PURE__ */ jsxs(Fragment, { children: [
254
- mode === "inline" ? /* @__PURE__ */ jsxs(Fragment, { children: [
255
- /* @__PURE__ */ jsx(
256
- Button,
257
- {
258
- size: settings.appearance?.button?.size || "medium",
259
- color: settings.appearance?.button?.color || "primary",
260
- variant: settings.appearance?.button?.variant || "contained",
261
- ...settings.appearance?.button,
262
- onClick: handlePopoverOpen,
263
- children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
264
- settings.appearance.button.icon,
265
- typeof settings.appearance.button.text === "string" ? /* @__PURE__ */ jsx(Typography, { sx: { whiteSpace: "nowrap" }, children: settings.appearance.button.text }) : settings.appearance.button.text
266
- ] })
267
- }
268
- ),
269
- /* @__PURE__ */ jsx(
270
- Popover,
271
- {
272
- id: "mouse-over-popper",
273
- open: popoverOpen,
274
- anchorEl,
275
- onClose: handlePopoverClose,
276
- anchorOrigin: {
277
- vertical: "top",
278
- horizontal: "center"
279
- },
280
- transformOrigin: {
281
- vertical: "bottom",
282
- horizontal: "center"
283
- },
284
- children: /* @__PURE__ */ jsxs(
285
- Box,
286
- {
287
- sx: {
288
- minWidth: 320,
289
- padding: "20px"
290
- },
291
- children: [
292
- supporters.loading && /* @__PURE__ */ jsx(
293
- "div",
294
- {
295
- style: {
296
- position: "absolute",
297
- top: 0,
298
- left: 0,
299
- right: 0,
300
- bottom: 0,
301
- display: "flex",
302
- justifyContent: "center",
303
- alignItems: "center",
304
- backgroundColor: "rgba(255, 255, 255, 0.7)"
305
- },
306
- children: /* @__PURE__ */ jsx(CircularProgress, {})
307
- }
308
- ),
309
- /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", flexDirection: "column", gap: 2, children: [
310
- /* @__PURE__ */ jsx(Button, { ...inlineOptions.button, onClick: () => setState({ open: true }), children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
311
- inlineOptions?.button?.icon,
312
- typeof inlineOptions?.button?.text === "string" ? /* @__PURE__ */ jsx(Typography, { sx: { whiteSpace: "nowrap" }, children: inlineOptions?.button?.text }) : inlineOptions?.button?.text
313
- ] }) }),
314
- /* @__PURE__ */ jsx(SupporterSimple, { ...supporters.data })
315
- ] })
316
- ]
317
- }
318
- )
319
- }
320
- )
321
- ] }) : /* @__PURE__ */ jsxs(
322
- Box,
254
+ const startDonate = () => {
255
+ setState({ open: true });
256
+ };
257
+ const inlineRender = /* @__PURE__ */ jsxs(Fragment, { children: [
258
+ /* @__PURE__ */ jsx(
259
+ Button,
323
260
  {
324
- sx: { width: "100%", minWidth: 300, maxWidth: 720 },
325
- display: "flex",
326
- flexDirection: "column",
327
- alignItems: "center",
328
- gap: { xs: 1, sm: 2 },
329
- children: [
330
- /* @__PURE__ */ jsx(
331
- Button,
332
- {
333
- size: settings.appearance?.button?.size || "medium",
334
- color: settings.appearance?.button?.color || "primary",
335
- variant: settings.appearance?.button?.variant || "contained",
336
- ...settings.appearance?.button,
337
- onClick: () => setState({ open: true }),
338
- children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
339
- settings.appearance.button.icon,
340
- typeof settings.appearance.button.text === "string" ? /* @__PURE__ */ jsx(Typography, { children: settings.appearance.button.text }) : settings.appearance.button.text
341
- ] })
342
- }
343
- ),
344
- supporters.data && settings.appearance.history.variant === "avatar" && /* @__PURE__ */ jsx(SupporterAvatar, { ...supporters.data }),
345
- supporters.data && settings.appearance.history.variant === "table" && /* @__PURE__ */ jsx(SupporterTable, { ...supporters.data })
346
- ]
261
+ size: settings.appearance?.button?.size || "medium",
262
+ color: settings.appearance?.button?.color || "primary",
263
+ variant: settings.appearance?.button?.variant || "contained",
264
+ ...settings.appearance?.button,
265
+ onClick: handlePopoverOpen,
266
+ children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
267
+ settings.appearance.button.icon,
268
+ typeof settings.appearance.button.text === "string" ? /* @__PURE__ */ jsx(Typography, { sx: { whiteSpace: "nowrap" }, children: settings.appearance.button.text }) : settings.appearance.button.text
269
+ ] })
347
270
  }
348
271
  ),
272
+ /* @__PURE__ */ jsx(
273
+ Popover,
274
+ {
275
+ id: "mouse-over-popper",
276
+ open: popoverOpen,
277
+ anchorEl,
278
+ onClose: handlePopoverClose,
279
+ anchorOrigin: {
280
+ vertical: "top",
281
+ horizontal: "center"
282
+ },
283
+ transformOrigin: {
284
+ vertical: "bottom",
285
+ horizontal: "center"
286
+ },
287
+ children: /* @__PURE__ */ jsxs(
288
+ Box,
289
+ {
290
+ sx: {
291
+ minWidth: 320,
292
+ padding: "20px"
293
+ },
294
+ children: [
295
+ supporters.loading && /* @__PURE__ */ jsx(
296
+ "div",
297
+ {
298
+ style: {
299
+ position: "absolute",
300
+ top: 0,
301
+ left: 0,
302
+ right: 0,
303
+ bottom: 0,
304
+ display: "flex",
305
+ justifyContent: "center",
306
+ alignItems: "center",
307
+ backgroundColor: "rgba(255, 255, 255, 0.7)"
308
+ },
309
+ children: /* @__PURE__ */ jsx(CircularProgress, {})
310
+ }
311
+ ),
312
+ /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", flexDirection: "column", gap: 2, children: [
313
+ /* @__PURE__ */ jsx(Button, { ...inlineOptions.button, onClick: () => startDonate(), children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
314
+ inlineOptions?.button?.icon,
315
+ typeof inlineOptions?.button?.text === "string" ? /* @__PURE__ */ jsx(Typography, { sx: { whiteSpace: "nowrap" }, children: inlineOptions?.button?.text }) : inlineOptions?.button?.text
316
+ ] }) }),
317
+ /* @__PURE__ */ jsx(SupporterSimple, { ...supporters.data })
318
+ ] })
319
+ ]
320
+ }
321
+ )
322
+ }
323
+ )
324
+ ] });
325
+ const defaultRender = /* @__PURE__ */ jsxs(
326
+ Box,
327
+ {
328
+ sx: { width: "100%", minWidth: 300, maxWidth: 720 },
329
+ display: "flex",
330
+ flexDirection: "column",
331
+ alignItems: "center",
332
+ gap: { xs: 1, sm: 2 },
333
+ children: [
334
+ /* @__PURE__ */ jsx(
335
+ Button,
336
+ {
337
+ size: settings.appearance?.button?.size || "medium",
338
+ color: settings.appearance?.button?.color || "primary",
339
+ variant: settings.appearance?.button?.variant || "contained",
340
+ ...settings.appearance?.button,
341
+ onClick: () => startDonate(),
342
+ children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
343
+ settings.appearance.button.icon,
344
+ typeof settings.appearance.button.text === "string" ? /* @__PURE__ */ jsx(Typography, { children: settings.appearance.button.text }) : settings.appearance.button.text
345
+ ] })
346
+ }
347
+ ),
348
+ supporters.data && settings.appearance.history.variant === "avatar" && /* @__PURE__ */ jsx(SupporterAvatar, { ...supporters.data }),
349
+ supporters.data && settings.appearance.history.variant === "table" && /* @__PURE__ */ jsx(SupporterTable, { ...supporters.data })
350
+ ]
351
+ }
352
+ );
353
+ const renderInnerView = () => {
354
+ if (mode === "inline") {
355
+ return inlineRender;
356
+ }
357
+ if (mode === "custom") {
358
+ return children && typeof children === "function" ? /* @__PURE__ */ jsx(Fragment, { children: children(
359
+ startDonate,
360
+ `${formatAmount(
361
+ supporters.data?.totalAmount || "0",
362
+ supporters.data?.currency?.decimal
363
+ )} ${supporters.data?.currency?.symbol}`,
364
+ supporters.data || {}
365
+ ) }) : /* @__PURE__ */ jsxs(Typography, { children: [
366
+ "Please provide a valid render function ",
367
+ /* @__PURE__ */ jsx("pre", { children: "(openDonate, donateTotalAmount, supporters) => ReactNode" })
368
+ ] });
369
+ }
370
+ return defaultRender;
371
+ };
372
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
373
+ renderInnerView(),
349
374
  donation.data && /* @__PURE__ */ jsx(
350
375
  Dialog,
351
376
  {
@@ -31,7 +31,6 @@ import {
31
31
  getPriceUintAmountByCurrency,
32
32
  isMobileSafari
33
33
  } from "../libs/util.js";
34
- import Amount from "../payment/amount.js";
35
34
  import { useMobile } from "../hooks/mobile.js";
36
35
  import TruncatedText from "./truncated-text.js";
37
36
  const sortOrder = {
@@ -172,10 +171,10 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
172
171
  max-width: 360px !important;
173
172
  }
174
173
  .price-table-wrap:has(> div:nth-child(2)) {
175
- max-width: 720px !important;
174
+ max-width: 780px !important;
176
175
  }
177
176
  .price-table-wrap:has(> div:nth-child(3)) {
178
- max-width: 1080px !important;
177
+ max-width: 1200px !important;
179
178
  }
180
179
  }
181
180
  `;
@@ -288,6 +287,7 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
288
287
  if (mode === "select") {
289
288
  action = x.is_selected ? t("payment.checkout.selected") : t("payment.checkout.select");
290
289
  }
290
+ const [amount, unit] = formatPriceAmount(x.price, currency, x.product.unit_label).split("/");
291
291
  return /* @__PURE__ */ jsxs(
292
292
  Stack,
293
293
  {
@@ -311,13 +311,12 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
311
311
  },
312
312
  width: {
313
313
  xs: "100%",
314
- md: "320px"
314
+ md: "360px"
315
315
  },
316
316
  maxWidth: "360px",
317
317
  minWidth: "300px",
318
318
  padding: "20px",
319
- position: "relative",
320
- height: "fit-content"
319
+ position: "relative"
321
320
  },
322
321
  children: [
323
322
  /* @__PURE__ */ jsx(Box, { textAlign: "center", children: /* @__PURE__ */ jsxs(
@@ -333,7 +332,7 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
333
332
  /* @__PURE__ */ jsx(
334
333
  Typography,
335
334
  {
336
- color: "text.primary",
335
+ color: "text.secondary",
337
336
  fontWeight: 600,
338
337
  sx: {
339
338
  fontSize: "18px !important",
@@ -346,7 +345,7 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
346
345
  Chip,
347
346
  {
348
347
  label: x.highlight_text,
349
- color: "default",
348
+ color: "primary",
350
349
  size: "small",
351
350
  sx: {
352
351
  position: "absolute",
@@ -356,11 +355,34 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
356
355
  }
357
356
  )
358
357
  ] }),
359
- /* @__PURE__ */ jsx(
360
- Amount,
358
+ /* @__PURE__ */ jsxs(
359
+ Typography,
361
360
  {
362
- amount: formatPriceAmount(x.price, currency, x.product.unit_label),
363
- sx: { my: 0, marginTop: "0px !important", fontSize: "48px", fontWeight: "bold" }
361
+ component: "div",
362
+ sx: {
363
+ my: 0,
364
+ fontWeight: "700",
365
+ fontSize: "32px",
366
+ letterSpacing: "-0.03rem",
367
+ fontVariantNumeric: "tabular-nums",
368
+ display: "flex",
369
+ alignItems: "baseline",
370
+ gap: "4px",
371
+ flexWrap: "wrap"
372
+ },
373
+ children: [
374
+ amount,
375
+ unit ? /* @__PURE__ */ jsxs(
376
+ Typography,
377
+ {
378
+ sx: { fontSize: "16px", fontWeight: "400", color: "text.secondary", textAlign: "left" },
379
+ children: [
380
+ "/ ",
381
+ unit
382
+ ]
383
+ }
384
+ ) : ""
385
+ ]
364
386
  }
365
387
  ),
366
388
  /* @__PURE__ */ jsx(
@@ -450,7 +472,7 @@ function Subscribe({ x, action, onSelect, currencyId }) {
450
472
  fullWidth: true,
451
473
  size: "medium",
452
474
  variant: "contained",
453
- color: x.is_highlight || x.is_selected ? "info" : "primary",
475
+ color: "primary",
454
476
  sx: {
455
477
  fontSize: "16px",
456
478
  padding: "10px 20px",
@@ -0,0 +1 @@
1
+ export declare function usePreventWheel(): void;
@@ -0,0 +1,14 @@
1
+ import { useEffect } from "react";
2
+ export function usePreventWheel() {
3
+ useEffect(() => {
4
+ const handleWheel = (e) => {
5
+ if (document.activeElement?.type === "number") {
6
+ e.preventDefault();
7
+ }
8
+ };
9
+ window.addEventListener("wheel", handleWheel, { passive: false });
10
+ return () => {
11
+ window.removeEventListener("wheel", handleWheel);
12
+ };
13
+ }, []);
14
+ }
package/es/index.d.ts CHANGED
@@ -36,5 +36,6 @@ export * from './contexts/payment';
36
36
  export * from './hooks/subscription';
37
37
  export * from './hooks/mobile';
38
38
  export * from './hooks/table';
39
+ export * from './hooks/scroll';
39
40
  export { translations, createTranslator } from './locales';
40
41
  export { createLazyComponent, 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
@@ -36,6 +36,7 @@ export * from "./contexts/payment.js";
36
36
  export * from "./hooks/subscription.js";
37
37
  export * from "./hooks/mobile.js";
38
38
  export * from "./hooks/table.js";
39
+ export * from "./hooks/scroll.js";
39
40
  export { translations, createTranslator } from "./locales/index.js";
40
41
  export {
41
42
  createLazyComponent,
package/es/libs/util.js CHANGED
@@ -862,24 +862,30 @@ export function getInvoiceDescriptionAndReason(invoice, locale = "en") {
862
862
  upcoming: t("payment.invoice.reason.upcoming", locale),
863
863
  slash_stake: t("payment.invoice.reason.slashStake", locale),
864
864
  stake: t("payment.invoice.reason.stake", locale),
865
- return_stake: t("payment.invoice.reason.returnStake", locale)
865
+ return_stake: t("payment.invoice.reason.returnStake", locale),
866
+ recharge: t("payment.invoice.reason.recharge", locale)
866
867
  };
868
+ let invoiceType = t("payment.invoice.reason.payment", locale);
869
+ if (reason.includes("stake") || reason.includes("recharge")) {
870
+ invoiceType = reasonMap[reason];
871
+ }
867
872
  if (description?.startsWith("Subscription ") || description?.startsWith("Slash stake")) {
868
873
  return {
869
874
  description: reasonMap[reason],
870
875
  reason: reasonMap[reason],
871
- type: reason.includes("stake") ? reasonMap[reason] : t("payment.invoice.reason.payment", locale)
876
+ type: invoiceType
872
877
  };
873
878
  }
874
879
  const descMap = {
875
880
  "Stake for subscription plan change": t("payment.invoice.reason.stakeForChangePlan", locale),
876
881
  "Stake for subscription payment change": t("payment.invoice.reason.stakeForChangePayment", locale),
877
882
  "Stake for subscription": t("payment.invoice.reason.staking", locale),
878
- "Return Subscription staking": t("payment.invoice.reason.returnStake", locale)
883
+ "Return Subscription staking": t("payment.invoice.reason.returnStake", locale),
884
+ "Recharge for subscription": t("payment.invoice.reason.rechargeForSubscription", locale)
879
885
  };
880
886
  return {
881
887
  description: descMap[description] || description,
882
888
  reason: reasonMap[reason] || reason,
883
- type: reason.includes("stake") ? reasonMap[reason] : t("payment.invoice.reason.payment", locale)
889
+ type: invoiceType
884
890
  };
885
891
  }
package/es/locales/en.js CHANGED
@@ -312,7 +312,9 @@ export default flat({
312
312
  payment: "Payment",
313
313
  returnStake: "Return stake",
314
314
  stakeForChangePlan: "Subscription plan update",
315
- stakeForChangePayment: "Subscription payment method update"
315
+ stakeForChangePayment: "Subscription payment method update",
316
+ recharge: "Recharge",
317
+ rechargeForSubscription: "Subscription recharge"
316
318
  }
317
319
  }
318
320
  },
package/es/locales/zh.js CHANGED
@@ -312,7 +312,9 @@ export default flat({
312
312
  payment: "\u4ED8\u6B3E",
313
313
  returnStake: "\u9000\u62BC\u91D1",
314
314
  stakeForChangePlan: "\u8BA2\u9605\u5957\u9910\u66F4\u65B0",
315
- stakeForChangePayment: "\u8BA2\u9605\u652F\u4ED8\u65B9\u5F0F\u66F4\u65B0"
315
+ stakeForChangePayment: "\u8BA2\u9605\u652F\u4ED8\u65B9\u5F0F\u66F4\u65B0",
316
+ recharge: "\u5145\u503C",
317
+ rechargeForSubscription: "\u8BA2\u9605\u5145\u503C"
316
318
  }
317
319
  }
318
320
  },
@@ -6,6 +6,7 @@ import { useEffect } from "react";
6
6
  import Switch from "../components/switch-button.js";
7
7
  import { formatAmountPrecisionLimit } from "../libs/util.js";
8
8
  import { usePaymentContext } from "../contexts/payment.js";
9
+ import { usePreventWheel } from "../hooks/scroll.js";
9
10
  export default function ProductDonation({
10
11
  item,
11
12
  settings,
@@ -14,6 +15,7 @@ export default function ProductDonation({
14
15
  }) {
15
16
  const { t, locale } = useLocaleContext();
16
17
  const { setPayable } = usePaymentContext();
18
+ usePreventWheel();
17
19
  const preset = settings.amount.preset || settings.amount.presets?.[0] || "0";
18
20
  const [state, setState] = useSetState({
19
21
  selected: preset,
@@ -16,11 +16,12 @@ export type DonateProps = Pick<CheckoutProps, 'onPaid' | 'onError'> & {
16
16
  settings: DonationSettings;
17
17
  livemode?: boolean;
18
18
  timeout?: number;
19
- mode?: 'inline' | 'default';
19
+ mode?: 'inline' | 'default' | 'custom';
20
20
  inlineOptions?: {
21
21
  button?: ButtonType;
22
22
  };
23
23
  theme?: 'default' | 'inherit' | PaymentThemeOptions;
24
+ children?: (openDialog: () => void, donateTotalAmount: string, supporters: DonateHistory) => React.ReactNode;
24
25
  };
25
26
  declare function CheckoutDonate(props: DonateProps): import("react").JSX.Element;
26
27
  declare namespace CheckoutDonate {