@stigg/react-sdk 4.2.2 → 4.3.0-beta.0

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 (165) hide show
  1. package/README.md +1 -1
  2. package/dist/components/checkout/Checkout.d.ts +5 -0
  3. package/dist/components/checkout/CheckoutContainer.d.ts +22 -0
  4. package/dist/components/checkout/CheckoutContainer.style.d.ts +29 -0
  5. package/dist/components/checkout/CheckoutProvider.d.ts +33 -0
  6. package/dist/components/checkout/CheckoutSummary.d.ts +9 -0
  7. package/dist/components/checkout/components/Button.d.ts +6 -0
  8. package/dist/components/checkout/components/InputField.d.ts +8 -0
  9. package/dist/components/checkout/components/index.d.ts +2 -0
  10. package/dist/components/checkout/formatting.d.ts +2 -0
  11. package/dist/components/checkout/hooks/index.d.ts +8 -0
  12. package/dist/components/checkout/hooks/useAddonsStepModel.d.ts +21 -0
  13. package/dist/components/checkout/hooks/useCheckoutModel.d.ts +9 -0
  14. package/dist/components/checkout/hooks/useCouponModel.d.ts +7 -0
  15. package/dist/components/checkout/hooks/useLoadCheckout.d.ts +13 -0
  16. package/dist/components/checkout/hooks/usePaymentStepModel.d.ts +16 -0
  17. package/dist/components/checkout/hooks/usePlanStepModel.d.ts +23 -0
  18. package/dist/components/checkout/hooks/usePreviewSubscription.d.ts +13 -0
  19. package/dist/components/checkout/hooks/useProgressBarModel.d.ts +26 -0
  20. package/dist/components/checkout/hooks/useSubscriptionModel.d.ts +5 -0
  21. package/dist/components/checkout/hooks/useSubscriptionState.d.ts +2 -0
  22. package/dist/components/checkout/index.d.ts +3 -0
  23. package/dist/components/checkout/planHeader/PlanHeader.d.ts +7 -0
  24. package/dist/components/checkout/planHeader/PlanHeader.style.d.ts +25 -0
  25. package/dist/components/checkout/planHeader/index.d.ts +1 -0
  26. package/dist/components/checkout/progressBar/CheckoutProgressBar.d.ts +2 -0
  27. package/dist/components/checkout/progressBar/CheckoutProgressBar.style.d.ts +45 -0
  28. package/dist/components/checkout/promotionCode/AddPromotionCode.d.ts +5 -0
  29. package/dist/components/checkout/promotionCode/AddPromotionCodeButton.d.ts +7 -0
  30. package/dist/components/checkout/promotionCode/AppliedPromotionCode.d.ts +6 -0
  31. package/dist/components/checkout/promotionCode/PromotionCodeSection.d.ts +5 -0
  32. package/dist/components/checkout/promotionCode/index.d.ts +1 -0
  33. package/dist/components/checkout/steps/addons/CheckoutAddonsStep.d.ts +2 -0
  34. package/dist/components/checkout/steps/addons/CheckoutAddonsStep.style.d.ts +93 -0
  35. package/dist/components/checkout/steps/addons/addon.utils.d.ts +15 -0
  36. package/dist/components/checkout/steps/addons/index.d.ts +1 -0
  37. package/dist/components/checkout/steps/payment/PaymentMethods.d.ts +19 -0
  38. package/dist/components/checkout/steps/payment/PaymentMethods.style.d.ts +113 -0
  39. package/dist/components/checkout/steps/payment/PaymentStep.d.ts +2 -0
  40. package/dist/components/checkout/steps/payment/index.d.ts +1 -0
  41. package/dist/components/checkout/steps/payment/stripe/StripePaymentForm.d.ts +2 -0
  42. package/dist/components/checkout/steps/payment/stripe/index.d.ts +3 -0
  43. package/dist/components/checkout/steps/payment/stripe/stripe.utils.d.ts +33 -0
  44. package/dist/components/checkout/steps/payment/stripe/useStripeIntegration.d.ts +5 -0
  45. package/dist/components/checkout/steps/payment/stripe/useSubmit.d.ts +10 -0
  46. package/dist/components/checkout/steps/plan/BillingPeriodPicker.d.ts +9 -0
  47. package/dist/components/checkout/steps/plan/BillingPeriodPicker.style.d.ts +52 -0
  48. package/dist/components/checkout/steps/plan/CheckoutChargeList.d.ts +16 -0
  49. package/dist/components/checkout/steps/plan/CheckoutPlanStep.d.ts +4 -0
  50. package/dist/components/checkout/steps/plan/CheckoutPlanStep.style.d.ts +12 -0
  51. package/dist/components/checkout/steps/plan/index.d.ts +1 -0
  52. package/dist/components/checkout/steps/surprise/SurpriseStep.d.ts +2 -0
  53. package/dist/components/checkout/textOverrides.d.ts +28 -0
  54. package/dist/components/checkout/theme.d.ts +8 -0
  55. package/dist/components/checkout/types.d.ts +7 -0
  56. package/dist/components/common/Icon.d.ts +3 -2
  57. package/dist/components/common/PoweredByStigg.d.ts +1 -1
  58. package/dist/components/{paywall/TiersLayout.d.ts → common/TiersSelectContainer.d.ts} +2 -3
  59. package/dist/components/common/customIcons.d.ts +17 -5
  60. package/dist/components/common/mapExternalTheme.d.ts +2 -0
  61. package/dist/components/customerPortal/subscriptionOverview/tabs/SubscriptionTabs.d.ts +1 -1
  62. package/dist/components/hooks/useChargeSort.d.ts +3 -0
  63. package/dist/components/utils/calculateDiscountRate.d.ts +1 -0
  64. package/dist/components/utils/currencyUtils.d.ts +1 -1
  65. package/dist/components/{paywall/planPriceTier.d.ts → utils/priceTierUtils.d.ts} +3 -1
  66. package/dist/components/utils/priceUtils.d.ts +2 -0
  67. package/dist/index.d.ts +1 -0
  68. package/dist/react-sdk.cjs.development.js +3472 -219
  69. package/dist/react-sdk.cjs.development.js.map +1 -1
  70. package/dist/react-sdk.cjs.production.min.js +1 -1
  71. package/dist/react-sdk.cjs.production.min.js.map +1 -1
  72. package/dist/react-sdk.esm.js +3615 -225
  73. package/dist/react-sdk.esm.js.map +1 -1
  74. package/dist/stories/Checkout.stories.d.ts +3 -0
  75. package/dist/theme/getResolvedTheme.d.ts +1 -0
  76. package/dist/theme/types.d.ts +1 -0
  77. package/package.json +7 -4
  78. package/src/assets/arrow-forward.svg +3 -0
  79. package/src/assets/arrow-right.svg +6 -0
  80. package/src/assets/close.svg +3 -0
  81. package/src/assets/nyancat.svg +634 -0
  82. package/src/assets/outlined-checked-circle.svg +6 -0
  83. package/src/assets/outlined-circle.svg +3 -0
  84. package/src/assets/payment-method.svg +11 -0
  85. package/src/assets/plus-icon.svg +6 -0
  86. package/src/assets/trash.svg +8 -0
  87. package/src/components/StiggProvider.tsx +5 -5
  88. package/src/components/checkout/Checkout.tsx +30 -0
  89. package/src/components/checkout/CheckoutContainer.style.ts +34 -0
  90. package/src/components/checkout/CheckoutContainer.tsx +92 -0
  91. package/src/components/checkout/CheckoutProvider.tsx +135 -0
  92. package/src/components/checkout/CheckoutSummary.tsx +361 -0
  93. package/src/components/checkout/components/Button.tsx +30 -0
  94. package/src/components/checkout/components/InputField.tsx +23 -0
  95. package/src/components/checkout/components/index.ts +2 -0
  96. package/src/components/checkout/formatting.ts +12 -0
  97. package/src/components/checkout/hooks/index.ts +8 -0
  98. package/src/components/checkout/hooks/useAddonsStepModel.ts +96 -0
  99. package/src/components/checkout/hooks/useCheckoutModel.ts +31 -0
  100. package/src/components/checkout/hooks/useCouponModel.ts +28 -0
  101. package/src/components/checkout/hooks/useLoadCheckout.ts +40 -0
  102. package/src/components/checkout/hooks/usePaymentStepModel.ts +49 -0
  103. package/src/components/checkout/hooks/usePlanStepModel.ts +170 -0
  104. package/src/components/checkout/hooks/usePreviewSubscription.ts +82 -0
  105. package/src/components/checkout/hooks/useProgressBarModel.ts +89 -0
  106. package/src/components/checkout/hooks/useSubscriptionModel.ts +16 -0
  107. package/src/components/checkout/hooks/useSubscriptionState.ts +26 -0
  108. package/src/components/checkout/index.ts +3 -0
  109. package/src/components/checkout/planHeader/PlanHeader.style.tsx +23 -0
  110. package/src/components/checkout/planHeader/PlanHeader.tsx +61 -0
  111. package/src/components/checkout/planHeader/index.ts +1 -0
  112. package/src/components/checkout/progressBar/CheckoutProgressBar.style.ts +29 -0
  113. package/src/components/checkout/progressBar/CheckoutProgressBar.tsx +48 -0
  114. package/src/components/checkout/promotionCode/AddPromotionCode.tsx +85 -0
  115. package/src/components/checkout/promotionCode/AddPromotionCodeButton.tsx +39 -0
  116. package/src/components/checkout/promotionCode/AppliedPromotionCode.tsx +37 -0
  117. package/src/components/checkout/promotionCode/PromotionCodeSection.tsx +27 -0
  118. package/src/components/checkout/promotionCode/index.ts +1 -0
  119. package/src/components/checkout/steps/addons/CheckoutAddonsStep.style.tsx +24 -0
  120. package/src/components/checkout/steps/addons/CheckoutAddonsStep.tsx +125 -0
  121. package/src/components/checkout/steps/addons/addon.utils.ts +68 -0
  122. package/src/components/checkout/steps/addons/index.ts +1 -0
  123. package/src/components/checkout/steps/payment/PaymentMethods.style.ts +26 -0
  124. package/src/components/checkout/steps/payment/PaymentMethods.tsx +83 -0
  125. package/src/components/checkout/steps/payment/PaymentStep.tsx +41 -0
  126. package/src/components/checkout/steps/payment/index.ts +1 -0
  127. package/src/components/checkout/steps/payment/stripe/StripePaymentForm.tsx +43 -0
  128. package/src/components/checkout/steps/payment/stripe/index.ts +3 -0
  129. package/src/components/checkout/steps/payment/stripe/stripe.utils.ts +109 -0
  130. package/src/components/checkout/steps/payment/stripe/useStripeIntegration.ts +27 -0
  131. package/src/components/checkout/steps/payment/stripe/useSubmit.ts +100 -0
  132. package/src/components/checkout/steps/plan/BillingPeriodPicker.style.tsx +46 -0
  133. package/src/components/checkout/steps/plan/BillingPeriodPicker.tsx +63 -0
  134. package/src/components/checkout/steps/plan/CheckoutChargeList.tsx +138 -0
  135. package/src/components/checkout/steps/plan/CheckoutPlanStep.style.tsx +6 -0
  136. package/src/components/checkout/steps/plan/CheckoutPlanStep.tsx +22 -0
  137. package/src/components/checkout/steps/plan/index.ts +1 -0
  138. package/src/components/checkout/steps/surprise/SurpriseStep.tsx +27 -0
  139. package/src/components/checkout/textOverrides.ts +58 -0
  140. package/src/components/checkout/theme.ts +26 -0
  141. package/src/components/checkout/types.ts +7 -0
  142. package/src/components/common/Icon.tsx +17 -22
  143. package/src/components/common/PoweredByStigg.tsx +1 -1
  144. package/src/components/{paywall/TiersLayout.tsx → common/TiersSelectContainer.tsx} +8 -7
  145. package/src/components/common/Typography.tsx +11 -1
  146. package/src/components/common/customIcons.ts +17 -28
  147. package/src/components/common/mapExternalTheme.ts +6 -0
  148. package/src/components/customerPortal/subscriptionOverview/tabs/SubscriptionTabs.tsx +6 -12
  149. package/src/components/hooks/useChargeSort.ts +17 -0
  150. package/src/components/paywall/BillingPeriodPicker.tsx +1 -1
  151. package/src/components/paywall/Paywall.tsx +1 -1
  152. package/src/components/paywall/PlanOffering.tsx +1 -1
  153. package/src/components/paywall/PlanOfferingButton.tsx +1 -1
  154. package/src/components/paywall/PlanPrice.tsx +3 -3
  155. package/src/components/paywall/utils/calculateUnitQuantityText.ts +9 -4
  156. package/src/components/utils/calculateDiscountRate.ts +26 -14
  157. package/src/components/utils/currencyUtils.ts +1 -1
  158. package/src/components/utils/getPaidPriceText.ts +2 -2
  159. package/src/components/{paywall/planPriceTier.ts → utils/priceTierUtils.ts} +25 -3
  160. package/src/components/utils/priceUtils.ts +10 -0
  161. package/src/index.ts +1 -0
  162. package/src/stories/Checkout.stories.tsx +59 -0
  163. package/src/theme/Theme.tsx +9 -8
  164. package/src/theme/getResolvedTheme.ts +1 -0
  165. package/src/theme/types.ts +1 -0
@@ -0,0 +1,6 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g id="Group 16159">
3
+ <circle id="Ellipse 5" cx="10" cy="10" r="9.25" fill="#327EEE" stroke="#327EEE" stroke-width="1.5"/>
4
+ <path id="Shape" d="M5 10.3636L8.63667 14L12.637 10L14.6372 8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
5
+ </g>
6
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <circle cx="10.333" cy="10" r="9" fill="white" stroke="#327EEE" stroke-width="2"/>
3
+ </svg>
@@ -0,0 +1,11 @@
1
+ <svg width="24" height="16" viewBox="0 0 24 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_239_13697)">
3
+ <path d="M22 0H2C0.89543 0 0 0.89543 0 2V14C0 15.1046 0.89543 16 2 16H22C23.1046 16 24 15.1046 24 14V2C24 0.89543 23.1046 0 22 0Z" fill="#C6C6C7"/>
4
+ </g>
5
+ <path opacity="0.3" d="M18.75 12.4286H16.5C16.0125 12.4286 15.75 12.2 15.75 11.6667C15.75 11.1334 16.0125 10.9048 16.5 10.9048H18.75C19.2375 10.9048 19.5 11.1334 19.5 11.6667C19.5 12.2 19.2375 12.4286 18.75 12.4286ZM14.25 12.4286H12C11.5125 12.4286 11.25 12.2 11.25 11.6667C11.25 11.1334 11.5125 10.9048 12 10.9048H14.25C14.7375 10.9048 15 11.1334 15 11.6667C15 12.2 14.7375 12.4286 14.25 12.4286ZM9.75 12.4286H7.5C7.0125 12.4286 6.75 12.2 6.75 11.6667C6.75 11.1334 7.0125 10.9048 7.5 10.9048H9.75C10.2375 10.9048 10.5 11.1334 10.5 11.6667C10.5 12.2 10.2375 12.4286 9.75 12.4286ZM5.25 12.4286H3C2.5125 12.4286 2.25 12.2 2.25 11.6667C2.25 11.1334 2.5125 10.9048 3 10.9048H5.25C5.7375 10.9048 6 11.1334 6 11.6667C6 12.2 5.7375 12.4286 5.25 12.4286Z" fill="black"/>
6
+ <defs>
7
+ <clipPath id="clip0_239_13697">
8
+ <rect width="24" height="16" fill="white"/>
9
+ </clipPath>
10
+ </defs>
11
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g id="plus">
3
+ <path id="Shape" d="M10 4.16666V15.8333" stroke="#327EEE" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
4
+ <path id="Shape_2" d="M4.16699 10H15.8337" stroke="#327EEE" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
5
+ </g>
6
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g id="trash-2">
3
+ <path id="Shape" d="M3 6H5H21" stroke="#F88078" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
4
+ <path id="Shape_2" d="M20 6C20 5.44772 19.5523 5 19 5C18.4477 5 18 5.44772 18 6H20ZM6 6C6 5.44772 5.55228 5 5 5C4.44772 5 4 5.44772 4 6H6ZM7 6C7 6.55228 7.44772 7 8 7C8.55228 7 9 6.55228 9 6H7ZM15 6C15 6.55228 15.4477 7 16 7C16.5523 7 17 6.55228 17 6H15ZM18 6V20H20V6H18ZM18 20C18 20.5523 17.5523 21 17 21V23C18.6569 23 20 21.6569 20 20H18ZM17 21H7V23H17V21ZM7 21C6.44772 21 6 20.5523 6 20H4C4 21.6569 5.34315 23 7 23V21ZM6 20V6H4V20H6ZM9 6V4H7V6H9ZM9 4C9 3.44772 9.44772 3 10 3V1C8.34315 1 7 2.34315 7 4H9ZM10 3H14V1H10V3ZM14 3C14.5523 3 15 3.44772 15 4H17C17 2.34315 15.6569 1 14 1V3ZM15 4V6H17V4H15Z" fill="#F88078"/>
5
+ <path id="Shape_3" d="M10 11V17" stroke="#F88078" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
6
+ <path id="Shape_4" d="M14 11V17" stroke="#F88078" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
7
+ </g>
8
+ </svg>
@@ -76,7 +76,7 @@ export const StiggProvider: React.FC<PropsWithChildren<StiggProviderProps>> = ({
76
76
  isInitialized: false,
77
77
  theme,
78
78
  refreshData: async () => {
79
- setContext(ctx => ({ ...ctx, customerPortalUpdatedAt: new Date() }));
79
+ setContext((ctx) => ({ ...ctx, customerPortalUpdatedAt: new Date() }));
80
80
  await ctx.stigg.refresh();
81
81
  },
82
82
  }));
@@ -90,10 +90,10 @@ export const StiggProvider: React.FC<PropsWithChildren<StiggProviderProps>> = ({
90
90
  }
91
91
  };
92
92
 
93
- const onEntitlementsUpdated = () => safeSetContext(ctx => ({ ...ctx, updatedAt: new Date() }));
93
+ const onEntitlementsUpdated = () => safeSetContext((ctx) => ({ ...ctx, updatedAt: new Date() }));
94
94
 
95
95
  const setStiggInstance = (stigg: StiggJs.StiggClient) =>
96
- safeSetContext(ctx => {
96
+ safeSetContext((ctx) => {
97
97
  if (ctx.stigg) {
98
98
  ctx.stigg.removeListener('entitlementsUpdated', onEntitlementsUpdated);
99
99
  }
@@ -115,7 +115,7 @@ export const StiggProvider: React.FC<PropsWithChildren<StiggProviderProps>> = ({
115
115
  stiggClient = Stigg.initialize({
116
116
  ...initializeParams,
117
117
  });
118
- safeSetContext(ctx => ({ ...ctx, isInitialized: false, updatedAt: new Date() }));
118
+ safeSetContext((ctx) => ({ ...ctx, isInitialized: false, updatedAt: new Date() }));
119
119
  }
120
120
  await stiggClient.waitForInitialization();
121
121
  setStiggInstance(stiggClient);
@@ -140,7 +140,7 @@ export const StiggProvider: React.FC<PropsWithChildren<StiggProviderProps>> = ({
140
140
  }, [customerId, customerToken, resourceId]);
141
141
 
142
142
  useEffect(() => {
143
- setContext(ctx => ({ ...ctx, theme }));
143
+ setContext((ctx) => ({ ...ctx, theme }));
144
144
  }, [theme]);
145
145
 
146
146
  return (
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { CheckoutProvider, CheckoutProviderProps } from './CheckoutProvider';
3
+ import { CheckoutContainer, CheckoutContainerProps } from './CheckoutContainer';
4
+
5
+ export type CheckoutProps = CheckoutProviderProps & CheckoutContainerProps;
6
+
7
+ export const Checkout = ({
8
+ textOverrides,
9
+ theme,
10
+ resourceId,
11
+ planId,
12
+ preferredBillingPeriod,
13
+ billingCountryCode,
14
+ billableFeatures,
15
+ ...containerProps
16
+ }: CheckoutProps) => {
17
+ return (
18
+ <CheckoutProvider
19
+ textOverrides={textOverrides}
20
+ theme={theme}
21
+ resourceId={resourceId}
22
+ planId={planId}
23
+ preferredBillingPeriod={preferredBillingPeriod}
24
+ billingCountryCode={billingCountryCode}
25
+ billableFeatures={billableFeatures}
26
+ >
27
+ <CheckoutContainer {...containerProps} />
28
+ </CheckoutProvider>
29
+ );
30
+ };
@@ -0,0 +1,34 @@
1
+ import styled from '@emotion/styled/macro';
2
+ import Box from '@mui/material/Box';
3
+
4
+ export const CheckoutLayout = styled.div<{ $backgroundColor: string; $borderColor: string }>`
5
+ margin: auto;
6
+ width: 100%;
7
+ max-width: 920px;
8
+ display: flex;
9
+ flex-direction: column;
10
+ align-items: center;
11
+
12
+ padding: 16px 32px;
13
+ border-radius: 10px;
14
+ background-color: ${({ $backgroundColor }) => $backgroundColor};
15
+ border: ${({ $borderColor }) => `1px solid ${$borderColor}`};
16
+
17
+ & * {
18
+ box-sizing: border-box;
19
+ }
20
+ `;
21
+ export const CheckoutContent = styled(Box)`
22
+ display: flex;
23
+ align-items: flex-start;
24
+ gap: 32px;
25
+ flex-wrap: wrap;
26
+ width: 100%;
27
+ `;
28
+
29
+ export const CheckoutPanel = styled(Box)`
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 0;
33
+ flex: 2;
34
+ `;
@@ -0,0 +1,92 @@
1
+ import { Elements } from '@stripe/react-stripe-js';
2
+ import React from 'react';
3
+ import { CheckoutContent, CheckoutLayout, CheckoutPanel } from './CheckoutContainer.style';
4
+ import { CheckoutProgressBar } from './progressBar/CheckoutProgressBar';
5
+ import { CheckoutSummary } from './CheckoutSummary';
6
+ import { useProgressBarModel } from './hooks';
7
+ import { PlanHeader } from './planHeader';
8
+ import { CheckoutAddonsStep } from './steps/addons';
9
+ import { PaymentStep } from './steps/payment';
10
+ import { useStripeIntegration } from './steps/payment/stripe';
11
+ import { CheckoutPlanStep } from './steps/plan';
12
+ import { ApplySubscription, CheckoutStatePlan } from '@stigg/js-client-sdk';
13
+ import { useStiggTheme } from '../../theme/Theme';
14
+
15
+ // import { SurpriseStep } from './steps/surprise/SurpriseStep';
16
+
17
+ type StepProps = {
18
+ allowChangePlan?: boolean;
19
+ content: React.ReactNode;
20
+ };
21
+
22
+ const getStepProps = (step: number): StepProps => {
23
+ switch (step) {
24
+ case 0:
25
+ return { allowChangePlan: true, content: <CheckoutPlanStep /> };
26
+ case 1:
27
+ return { content: <CheckoutAddonsStep /> };
28
+ case 2:
29
+ return { content: <PaymentStep /> };
30
+ default:
31
+ return { content: null };
32
+ }
33
+ };
34
+
35
+ export type CheckoutResult = { success: boolean; errorMessage?: string };
36
+
37
+ export type OnCheckoutParams = { checkoutParams: ApplySubscription; checkoutAction: () => Promise<CheckoutResult> };
38
+
39
+ export type OnCheckoutCompletedParams = { success: boolean; error?: string };
40
+
41
+ export type CheckoutContainerProps = {
42
+ onCheckout?: (params: OnCheckoutParams) => Promise<CheckoutResult>;
43
+ onCheckoutCompleted: (params: OnCheckoutCompletedParams) => Promise<void>;
44
+ onChangePlan?: (params: { currentPlan: CheckoutStatePlan | undefined }) => void;
45
+ };
46
+
47
+ export function CheckoutContainer({ onCheckout, onCheckoutCompleted, onChangePlan }: CheckoutContainerProps) {
48
+ const { stripePromise, setupIntentClientSecret } = useStripeIntegration();
49
+ const stiggTheme = useStiggTheme();
50
+ const { progressBarState } = useProgressBarModel();
51
+ const { activeStep } = progressBarState;
52
+
53
+ // uncomment for fun!
54
+ // if (activeStep > 2) {
55
+ // return <SurpriseStep />;
56
+ // }
57
+
58
+ const { content, allowChangePlan } = getStepProps(activeStep);
59
+
60
+ return (
61
+ <Elements
62
+ stripe={stripePromise}
63
+ options={{
64
+ clientSecret: setupIntentClientSecret,
65
+ appearance: {
66
+ theme: 'stripe',
67
+ variables: {
68
+ colorText: stiggTheme.palette.text.primary,
69
+ colorPrimaryText: stiggTheme.palette.text.primary,
70
+ colorTextPlaceholder: stiggTheme.palette.text.disabled,
71
+ fontFamily: stiggTheme.typography.fontFamily,
72
+ },
73
+ },
74
+ }}
75
+ >
76
+ <CheckoutLayout
77
+ className="stigg-checkout-layout"
78
+ $backgroundColor={stiggTheme.palette.backgroundPaper}
79
+ $borderColor={stiggTheme.palette.outlinedBorder}
80
+ >
81
+ <CheckoutProgressBar />
82
+ <CheckoutContent>
83
+ <CheckoutPanel>
84
+ <PlanHeader allowChangePlan={allowChangePlan} onChangePlan={onChangePlan} />
85
+ {content}
86
+ </CheckoutPanel>
87
+ <CheckoutSummary onCheckout={onCheckout} onCheckoutCompleted={onCheckoutCompleted} />
88
+ </CheckoutContent>
89
+ </CheckoutLayout>
90
+ </Elements>
91
+ );
92
+ }
@@ -0,0 +1,135 @@
1
+ import { produce } from 'immer';
2
+ import React, { useCallback, useContext, useMemo, useState } from 'react';
3
+
4
+ import { BillableFeature, BillingPeriod, GetCheckoutStateResults } from '@stigg/js-client-sdk';
5
+
6
+ import { SdkThemeProvider, useStiggTheme } from '../../theme/Theme';
7
+ import { DeepPartial } from '../../types';
8
+ import { mapCheckoutConfiguration } from '../common/mapExternalTheme';
9
+ import {
10
+ AddonsStepState,
11
+ getAddonsStepInitialState,
12
+ getPaymentStepInitialState,
13
+ getPlanStepInitialState,
14
+ getProgressBarInitialState,
15
+ PaymentStepState,
16
+ PlanStepState,
17
+ ProgressBarState,
18
+ useLoadCheckout,
19
+ WidgetState,
20
+ } from './hooks';
21
+ import { CheckoutLocalization, getResolvedCheckoutLocalize } from './textOverrides';
22
+ import { CheckoutTheme, getResolvedCheckoutTheme } from './theme';
23
+
24
+ export interface CheckoutContextState {
25
+ checkout?: GetCheckoutStateResults | null;
26
+ checkoutLocalization: CheckoutLocalization;
27
+ theme: CheckoutTheme;
28
+ isLoading: boolean;
29
+ resourceId?: string;
30
+ promotionCode?: string;
31
+ progressBar: ProgressBarState;
32
+ planStep: PlanStepState;
33
+ addonsStep: AddonsStepState;
34
+ paymentStep: PaymentStepState;
35
+ widgetState: WidgetState;
36
+ }
37
+
38
+ export const CheckoutContext = React.createContext<
39
+ [CheckoutContextState, (updater: (state: CheckoutContextState) => void) => void] | null
40
+ >(null);
41
+
42
+ CheckoutContext.displayName = 'CheckoutContext';
43
+
44
+ export const useCheckoutContext = () => {
45
+ const ctx = useContext(CheckoutContext);
46
+ if (!ctx) {
47
+ throw new Error(
48
+ 'Could not find Checkout context; You need to wrap your checkout components in an <CheckoutProvider> component.',
49
+ );
50
+ }
51
+ return ctx;
52
+ };
53
+
54
+ const CheckoutContextProvider: React.FC<{ children: React.ReactNode; initialState: CheckoutContextState }> = ({
55
+ children,
56
+ initialState,
57
+ }) => {
58
+ const [state, innerSetState] = useState(initialState);
59
+
60
+ const setState = useCallback(
61
+ (updater: (state: CheckoutContextState) => void) => innerSetState(old => produce(old, draft => updater(draft))),
62
+ [innerSetState],
63
+ );
64
+
65
+ const [contextValue, setContextValue] = useMemo(() => [state, setState], [state]);
66
+
67
+ return <CheckoutContext.Provider value={[contextValue, setContextValue]}>{children}</CheckoutContext.Provider>;
68
+ };
69
+
70
+ export type CheckoutProviderProps = {
71
+ textOverrides?: DeepPartial<CheckoutLocalization>;
72
+ theme?: DeepPartial<CheckoutTheme>;
73
+ resourceId?: string;
74
+ planId: string;
75
+ preferredBillingPeriod?: BillingPeriod;
76
+ billingCountryCode?: string;
77
+ billableFeatures?: BillableFeature[];
78
+ };
79
+
80
+ export function CheckoutProvider({
81
+ children,
82
+ textOverrides,
83
+ theme,
84
+ resourceId,
85
+ planId,
86
+ preferredBillingPeriod,
87
+ billingCountryCode,
88
+ billableFeatures,
89
+ }: {
90
+ children: React.ReactNode;
91
+ } & CheckoutProviderProps) {
92
+ const { checkout, isLoading } = useLoadCheckout({ resourceId, planId, billingCountryCode });
93
+ const configuration = checkout?.configuration ? mapCheckoutConfiguration(checkout.configuration) : undefined;
94
+ const globalTheme = useStiggTheme(configuration);
95
+ const checkoutTheme = getResolvedCheckoutTheme(globalTheme, theme, checkout?.configuration);
96
+ const checkoutLocalization = getResolvedCheckoutLocalize(textOverrides);
97
+
98
+ const initialState = useMemo(() => {
99
+ const planStep = getPlanStepInitialState({
100
+ preferredBillingPeriod,
101
+ plan: checkout?.plan,
102
+ activeSubscription: checkout?.activeSubscription,
103
+ billingCountryCode,
104
+ preconfiguredBillableFeatures: billableFeatures ? billableFeatures : [],
105
+ });
106
+ const addonsStep = getAddonsStepInitialState({
107
+ plan: checkout?.plan,
108
+ billingPeriod: planStep.billingPeriod,
109
+ activeSubscription: checkout?.activeSubscription,
110
+ });
111
+ const paymentStep = getPaymentStepInitialState({ customer: checkout?.customer });
112
+ const progressBar = getProgressBarInitialState({ availableAddons: addonsStep.availableAddons || [] });
113
+
114
+ const initialState: CheckoutContextState = {
115
+ checkout,
116
+ isLoading,
117
+ checkoutLocalization,
118
+ theme: checkoutTheme,
119
+ progressBar,
120
+ planStep,
121
+ addonsStep,
122
+ paymentStep,
123
+ resourceId: checkout?.resource?.id,
124
+ widgetState: { isLoading: false },
125
+ };
126
+
127
+ return initialState;
128
+ }, [billingCountryCode, preferredBillingPeriod, checkout]);
129
+
130
+ return (
131
+ <SdkThemeProvider key={checkout?.plan.id} componentTheme={configuration}>
132
+ <CheckoutContextProvider initialState={initialState}>{children}</CheckoutContextProvider>
133
+ </SdkThemeProvider>
134
+ );
135
+ }