tf-checkout-react 1.7.31 → 2.0.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 (453) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +141 -1033
  3. package/dist/checkout.css +17 -0
  4. package/dist/index.d.mts +3930 -0
  5. package/dist/index.d.ts +3930 -30
  6. package/dist/index.esm.js +9123 -0
  7. package/dist/index.esm.js.map +1 -0
  8. package/dist/index.js +9277 -6
  9. package/dist/index.js.map +1 -0
  10. package/dist/styles/addons.css +75 -0
  11. package/dist/styles/auth.css +294 -0
  12. package/dist/styles/billing.css +98 -0
  13. package/dist/styles/confirmation.css +51 -0
  14. package/dist/styles/foundation.css +146 -0
  15. package/dist/styles/payment.css +179 -0
  16. package/dist/styles/primitives.css +356 -0
  17. package/dist/styles/seat-map.css +46 -0
  18. package/dist/styles/tickets.css +285 -0
  19. package/dist/styles/verification-confirmation.css +258 -0
  20. package/package.json +93 -78
  21. package/src/.d.ts +1 -1
  22. package/src/CardInput.tsx +374 -0
  23. package/src/EmbeddedCheckout.tsx +400 -0
  24. package/src/ResumedCheckout.tsx +132 -0
  25. package/src/auth/AuthModal.tsx +231 -0
  26. package/src/auth/ForgotPasswordForm.tsx +93 -0
  27. package/src/auth/LoginForm.tsx +104 -0
  28. package/src/auth/PasswordInput.tsx +33 -0
  29. package/src/auth/RegisterForm.tsx +333 -0
  30. package/src/auth/ResetPasswordForm.tsx +112 -0
  31. package/src/auth/index.ts +5 -0
  32. package/src/checkout.css +17 -0
  33. package/src/configure.ts +29 -0
  34. package/src/confirmer.ts +439 -0
  35. package/src/index.ts +41 -30
  36. package/src/instance.ts +21 -0
  37. package/src/sections/AddOns.tsx +241 -0
  38. package/src/sections/BillingInfo.tsx +743 -0
  39. package/src/sections/Confirmation.tsx +146 -0
  40. package/src/sections/IDVerification.tsx +76 -0
  41. package/src/sections/OrderConfirmation.tsx +277 -0
  42. package/src/sections/OrderIDVerification.tsx +117 -0
  43. package/src/sections/OrderSummary.tsx +84 -0
  44. package/src/sections/Payment.tsx +541 -0
  45. package/src/sections/SeatMap.tsx +512 -0
  46. package/src/sections/Tickets.tsx +573 -0
  47. package/src/sections/billing/BillingAddressFields.tsx +138 -0
  48. package/src/sections/billing/BuyerField.tsx +75 -0
  49. package/src/sections/billing/TicketHoldersCard.tsx +119 -0
  50. package/src/sections/billing/types.ts +10 -0
  51. package/src/sections/index.ts +15 -0
  52. package/src/sections/seatMap.utils.ts +105 -0
  53. package/src/styles/addons.css +75 -0
  54. package/src/styles/auth.css +294 -0
  55. package/src/styles/billing.css +98 -0
  56. package/src/styles/confirmation.css +51 -0
  57. package/src/styles/foundation.css +146 -0
  58. package/src/styles/payment.css +179 -0
  59. package/src/styles/primitives.css +356 -0
  60. package/src/styles/seat-map.css +46 -0
  61. package/src/styles/tickets.css +285 -0
  62. package/src/styles/verification-confirmation.css +258 -0
  63. package/src/typings.d.ts +2 -2
  64. package/src/ui/Button.tsx +38 -0
  65. package/src/ui/Card.tsx +54 -0
  66. package/src/ui/CheckoutProvider.tsx +172 -0
  67. package/src/ui/CustomFields.tsx +195 -0
  68. package/src/ui/Field.tsx +114 -0
  69. package/src/ui/I18nProvider.tsx +36 -0
  70. package/src/ui/InstallmentPicker.tsx +69 -0
  71. package/src/ui/Loader.tsx +12 -0
  72. package/src/ui/PaymentMethods.tsx +133 -0
  73. package/src/ui/PriceLine.tsx +24 -0
  74. package/src/ui/QuantitySelect.tsx +50 -0
  75. package/src/ui/Stepper.tsx +36 -0
  76. package/src/ui/Timer.tsx +34 -0
  77. package/src/ui/TimerBanner.tsx +55 -0
  78. package/src/ui/cx.ts +3 -0
  79. package/src/ui/index.ts +54 -0
  80. package/src/ui/theme.ts +83 -0
  81. package/src/useCheckout.ts +35 -0
  82. package/src/xendit.ts +438 -0
  83. package/dist/adapters/customFields.d.ts +0 -12
  84. package/dist/adapters/index.d.ts +0 -1
  85. package/dist/api/auth.d.ts +0 -27
  86. package/dist/api/cart.d.ts +0 -2
  87. package/dist/api/checkout.d.ts +0 -3
  88. package/dist/api/common.d.ts +0 -11
  89. package/dist/api/guestTicketDelegation.d.ts +0 -47
  90. package/dist/api/index.d.ts +0 -82
  91. package/dist/api/interceptors.d.ts +0 -1
  92. package/dist/api/orders.d.ts +0 -2
  93. package/dist/api/payment.d.ts +0 -5
  94. package/dist/api/preRegistrationComplete.d.ts +0 -3
  95. package/dist/api/publicRequest.d.ts +0 -9
  96. package/dist/api/resale.d.ts +0 -5
  97. package/dist/components/account-settings/index.d.ts +0 -3
  98. package/dist/components/addonsContainer/AddonComponent.d.ts +0 -18
  99. package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +0 -20
  100. package/dist/components/addonsContainer/adapters/index.d.ts +0 -12
  101. package/dist/components/addonsContainer/index.d.ts +0 -22
  102. package/dist/components/addonsContainer/normalizers/index.d.ts +0 -1
  103. package/dist/components/addonsContainer/useAddons.d.ts +0 -23
  104. package/dist/components/addonsContainer/utils/index.d.ts +0 -16
  105. package/dist/components/billing-info-container/hooks/index.d.ts +0 -3
  106. package/dist/components/billing-info-container/hooks/usePaymentContext.d.ts +0 -5
  107. package/dist/components/billing-info-container/hooks/usePaymentRedirect.d.ts +0 -14
  108. package/dist/components/billing-info-container/hooks/useStripePayment.d.ts +0 -18
  109. package/dist/components/billing-info-container/index.d.ts +0 -69
  110. package/dist/components/billing-info-container/utils.d.ts +0 -59
  111. package/dist/components/common/Checkbox.d.ts +0 -11
  112. package/dist/components/common/CheckboxField/index.d.ts +0 -9
  113. package/dist/components/common/CopyField.d.ts +0 -12
  114. package/dist/components/common/CopyMessageModal.d.ts +0 -7
  115. package/dist/components/common/CustomField.d.ts +0 -26
  116. package/dist/components/common/DatePickerField.d.ts +0 -20
  117. package/dist/components/common/FieldSection/index.d.ts +0 -19
  118. package/dist/components/common/FieldSection/utils/index.d.ts +0 -8
  119. package/dist/components/common/FormikPhoneNumberField.d.ts +0 -11
  120. package/dist/components/common/Loader.d.ts +0 -2
  121. package/dist/components/common/ModalComponent/index.d.ts +0 -16
  122. package/dist/components/common/NativeSelectFeild/index.d.ts +0 -21
  123. package/dist/components/common/PhoneNumberField.d.ts +0 -14
  124. package/dist/components/common/PoweredBy.d.ts +0 -2
  125. package/dist/components/common/RadioField.d.ts +0 -11
  126. package/dist/components/common/RadioGroupField/index.d.ts +0 -17
  127. package/dist/components/common/RedirectModal.d.ts +0 -7
  128. package/dist/components/common/SelectField/index.d.ts +0 -19
  129. package/dist/components/common/SnackbarAlert.d.ts +0 -13
  130. package/dist/components/common/index.d.ts +0 -11
  131. package/dist/components/common/socials.d.ts +0 -10
  132. package/dist/components/confirmModal/index.d.ts +0 -10
  133. package/dist/components/confirmationContainer/config.d.ts +0 -1
  134. package/dist/components/confirmationContainer/index.d.ts +0 -46
  135. package/dist/components/confirmationContainer/social-buttons.d.ts +0 -16
  136. package/dist/components/countdown/index.d.ts +0 -14
  137. package/dist/components/delegationsContainer/IssueComponent.d.ts +0 -10
  138. package/dist/components/delegationsContainer/IssueTicketForm.d.ts +0 -9
  139. package/dist/components/delegationsContainer/TicketsAssignedTable.d.ts +0 -11
  140. package/dist/components/delegationsContainer/TicketsAvailableTable.d.ts +0 -11
  141. package/dist/components/delegationsContainer/index.d.ts +0 -10
  142. package/dist/components/forgotPasswordModal/index.d.ts +0 -12
  143. package/dist/components/idVerificationContainer/VerificationPendingModal.d.ts +0 -10
  144. package/dist/components/idVerificationContainer/constants.d.ts +0 -21
  145. package/dist/components/idVerificationContainer/index.d.ts +0 -16
  146. package/dist/components/index.d.ts +0 -12
  147. package/dist/components/loginForm/index.d.ts +0 -31
  148. package/dist/components/loginModal/SignUpForm.d.ts +0 -10
  149. package/dist/components/loginModal/constants.d.ts +0 -39
  150. package/dist/components/loginModal/index.d.ts +0 -22
  151. package/dist/components/myTicketsContainer/index.d.ts +0 -16
  152. package/dist/components/myTicketsContainer/row.d.ts +0 -3
  153. package/dist/components/myTicketsContainer/tableConfig.d.ts +0 -5
  154. package/dist/components/orderDetailsContainer/CustomFieldsForm.d.ts +0 -12
  155. package/dist/components/orderDetailsContainer/TicketHolderCustomFields.d.ts +0 -10
  156. package/dist/components/orderDetailsContainer/index.d.ts +0 -66
  157. package/dist/components/orderDetailsContainer/ticketsTable.d.ts +0 -46
  158. package/dist/components/orderDetailsContainer/utils/index.d.ts +0 -6
  159. package/dist/components/paymentContainer/OrderDetails.d.ts +0 -9
  160. package/dist/components/paymentContainer/PaymentPlanSection.d.ts +0 -10
  161. package/dist/components/paymentContainer/handlePayment.d.ts +0 -15
  162. package/dist/components/paymentContainer/index.d.ts +0 -39
  163. package/dist/components/preRegistration/FieldsSection.d.ts +0 -19
  164. package/dist/components/preRegistration/Influancers.d.ts +0 -2
  165. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +0 -13
  166. package/dist/components/preRegistration/PreRegistrationInformations.d.ts +0 -2
  167. package/dist/components/preRegistration/Prewards.d.ts +0 -2
  168. package/dist/components/preRegistration/ShareOptions.d.ts +0 -2
  169. package/dist/components/preRegistration/constants.d.ts +0 -2
  170. package/dist/components/preRegistration/index.d.ts +0 -23
  171. package/dist/components/preRegistration/utils.d.ts +0 -12
  172. package/dist/components/registerForm/adapters/index.d.ts +0 -4
  173. package/dist/components/registerForm/constants.d.ts +0 -1
  174. package/dist/components/registerForm/index.d.ts +0 -16
  175. package/dist/components/registerModal/index.d.ts +0 -12
  176. package/dist/components/resetPasswordContainer/index.d.ts +0 -10
  177. package/dist/components/rsvpContainer/index.d.ts +0 -7
  178. package/dist/components/seatMapContainer/SeatMapComponent.d.ts +0 -8
  179. package/dist/components/seatMapContainer/TicketsSection.d.ts +0 -9
  180. package/dist/components/seatMapContainer/addToCart.d.ts +0 -14
  181. package/dist/components/seatMapContainer/index.d.ts +0 -2
  182. package/dist/components/seatMapContainer/utils.d.ts +0 -6
  183. package/dist/components/signupModal/index.d.ts +0 -12
  184. package/dist/components/ticketResale/index.d.ts +0 -12
  185. package/dist/components/ticketResaleModal/index.d.ts +0 -19
  186. package/dist/components/ticketsContainer/AccessCodeSection.d.ts +0 -7
  187. package/dist/components/ticketsContainer/InfoIcon.d.ts +0 -5
  188. package/dist/components/ticketsContainer/PromoCodeSection.d.ts +0 -15
  189. package/dist/components/ticketsContainer/ReferralLogic.d.ts +0 -5
  190. package/dist/components/ticketsContainer/TicketRow.d.ts +0 -13
  191. package/dist/components/ticketsContainer/TicketsSection.d.ts +0 -20
  192. package/dist/components/ticketsContainer/TimeSlotTicketRow.d.ts +0 -19
  193. package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +0 -25
  194. package/dist/components/ticketsContainer/index.d.ts +0 -93
  195. package/dist/components/ticketsContainer/utils.d.ts +0 -13
  196. package/dist/components/timerWidget/index.d.ts +0 -16
  197. package/dist/components/waitingList/index.d.ts +0 -9
  198. package/dist/constants/index.d.ts +0 -7
  199. package/dist/env.d.ts +0 -16
  200. package/dist/hoc/CustomFields/index.d.ts +0 -3
  201. package/dist/hoc/index.d.ts +0 -1
  202. package/dist/hooks/index.d.ts +0 -1
  203. package/dist/hooks/useCookieListener.d.ts +0 -1
  204. package/dist/hooks/useEventListener.d.ts +0 -1
  205. package/dist/hooks/useLocalStorageListener.d.ts +0 -1
  206. package/dist/hooks/useOnline.d.ts +0 -1
  207. package/dist/hooks/usePixel.d.ts +0 -6
  208. package/dist/images/Polygon.png +0 -0
  209. package/dist/images/cross.svg +0 -44
  210. package/dist/images/done.svg +0 -3
  211. package/dist/images/edit.svg +0 -10
  212. package/dist/images/email.svg +0 -1
  213. package/dist/images/instagram.svg +0 -5
  214. package/dist/images/logo-ttf.png +0 -0
  215. package/dist/images/spotify.svg +0 -6
  216. package/dist/images/user.svg +0 -1
  217. package/dist/images/xmark.svg +0 -92
  218. package/dist/normalizers/index.d.ts +0 -4
  219. package/dist/tf-checkout-react.cjs.development.js +0 -16149
  220. package/dist/tf-checkout-react.cjs.development.js.map +0 -1
  221. package/dist/tf-checkout-react.cjs.production.min.js +0 -2
  222. package/dist/tf-checkout-react.cjs.production.min.js.map +0 -1
  223. package/dist/tf-checkout-react.esm.js +0 -16116
  224. package/dist/tf-checkout-react.esm.js.map +0 -1
  225. package/dist/tf-checkout-styles.css +0 -1
  226. package/dist/types/add_on.d.ts +0 -8
  227. package/dist/types/billing-info-data.d.ts +0 -27
  228. package/dist/types/checkoutPageConfigs.d.ts +0 -13
  229. package/dist/types/index.d.ts +0 -6
  230. package/dist/types/order-data.d.ts +0 -15
  231. package/dist/types/payment-field.d.ts +0 -6
  232. package/dist/types/payment-plan-configuration.d.ts +0 -18
  233. package/dist/types/referral-promotion.d.ts +0 -6
  234. package/dist/types/verification.d.ts +0 -12
  235. package/dist/utils/adaptStripeErrors.d.ts +0 -8
  236. package/dist/utils/auth.d.ts +0 -21
  237. package/dist/utils/cookies.d.ts +0 -3
  238. package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +0 -23
  239. package/dist/utils/createMarkup.d.ts +0 -3
  240. package/dist/utils/customFields.d.ts +0 -35
  241. package/dist/utils/downloadPDF.d.ts +0 -1
  242. package/dist/utils/form.d.ts +0 -3
  243. package/dist/utils/formikErrorFocus.d.ts +0 -2
  244. package/dist/utils/getDomain.d.ts +0 -1
  245. package/dist/utils/getImage.d.ts +0 -1
  246. package/dist/utils/getQueryVariable.d.ts +0 -1
  247. package/dist/utils/htmlNodeFromString.d.ts +0 -1
  248. package/dist/utils/index.d.ts +0 -15
  249. package/dist/utils/isBrowser.d.ts +0 -1
  250. package/dist/utils/isValidNumber.d.ts +0 -1
  251. package/dist/utils/jsonUtils.d.ts +0 -1
  252. package/dist/utils/replaceVarInString.d.ts +0 -1
  253. package/dist/utils/setConfigs.d.ts +0 -11
  254. package/dist/utils/showZero.d.ts +0 -1
  255. package/dist/validators/index.d.ts +0 -8
  256. package/src/adapters/customFields.ts +0 -85
  257. package/src/adapters/index.ts +0 -1
  258. package/src/api/auth.ts +0 -88
  259. package/src/api/cart.ts +0 -28
  260. package/src/api/checkout.ts +0 -28
  261. package/src/api/common.ts +0 -190
  262. package/src/api/guestTicketDelegation.ts +0 -79
  263. package/src/api/index.ts +0 -346
  264. package/src/api/interceptors.ts +0 -77
  265. package/src/api/orders.ts +0 -30
  266. package/src/api/payment.ts +0 -77
  267. package/src/api/preRegistrationComplete.ts +0 -37
  268. package/src/api/publicRequest.ts +0 -47
  269. package/src/api/resale.ts +0 -28
  270. package/src/assets/images/Polygon.png +0 -0
  271. package/src/assets/images/cross.svg +0 -44
  272. package/src/assets/images/done.svg +0 -3
  273. package/src/assets/images/edit.svg +0 -10
  274. package/src/assets/images/email.svg +0 -1
  275. package/src/assets/images/instagram.svg +0 -5
  276. package/src/assets/images/logo-ttf.png +0 -0
  277. package/src/assets/images/spotify.svg +0 -6
  278. package/src/assets/images/user.svg +0 -1
  279. package/src/assets/images/xmark.svg +0 -92
  280. package/src/components/account-settings/index.tsx +0 -161
  281. package/src/components/account-settings/style.css +0 -200
  282. package/src/components/addonsContainer/AddonComponent.tsx +0 -204
  283. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +0 -459
  284. package/src/components/addonsContainer/adapters/index.tsx +0 -62
  285. package/src/components/addonsContainer/index.tsx +0 -353
  286. package/src/components/addonsContainer/normalizers/index.ts +0 -5
  287. package/src/components/addonsContainer/useAddons.ts +0 -248
  288. package/src/components/addonsContainer/utils/index.tsx +0 -231
  289. package/src/components/billing-info-container/hooks/index.ts +0 -3
  290. package/src/components/billing-info-container/hooks/usePaymentContext.ts +0 -22
  291. package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +0 -145
  292. package/src/components/billing-info-container/hooks/useStripePayment.ts +0 -119
  293. package/src/components/billing-info-container/index.tsx +0 -1695
  294. package/src/components/billing-info-container/style.css +0 -150
  295. package/src/components/billing-info-container/utils.tsx +0 -413
  296. package/src/components/common/Checkbox.tsx +0 -51
  297. package/src/components/common/CheckboxField/index.tsx +0 -41
  298. package/src/components/common/CopyField.tsx +0 -53
  299. package/src/components/common/CopyMessageModal.tsx +0 -34
  300. package/src/components/common/CustomField.tsx +0 -168
  301. package/src/components/common/DatePickerField.tsx +0 -126
  302. package/src/components/common/FieldSection/index.tsx +0 -141
  303. package/src/components/common/FieldSection/utils/index.tsx +0 -92
  304. package/src/components/common/FormikPhoneNumberField.tsx +0 -51
  305. package/src/components/common/Loader.tsx +0 -8
  306. package/src/components/common/ModalComponent/index.tsx +0 -68
  307. package/src/components/common/NativeSelectFeild/index.tsx +0 -86
  308. package/src/components/common/PhoneNumberField.tsx +0 -117
  309. package/src/components/common/PoweredBy.tsx +0 -15
  310. package/src/components/common/RadioField.tsx +0 -36
  311. package/src/components/common/RadioGroupField/index.tsx +0 -76
  312. package/src/components/common/RedirectModal.tsx +0 -43
  313. package/src/components/common/SelectField/index.tsx +0 -104
  314. package/src/components/common/SnackbarAlert.tsx +0 -52
  315. package/src/components/common/index.tsx +0 -11
  316. package/src/components/common/socials.tsx +0 -33
  317. package/src/components/confirmModal/index.tsx +0 -60
  318. package/src/components/confirmationContainer/config.ts +0 -79
  319. package/src/components/confirmationContainer/index.tsx +0 -349
  320. package/src/components/confirmationContainer/social-buttons.tsx +0 -149
  321. package/src/components/confirmationContainer/style.css +0 -206
  322. package/src/components/countdown/index.tsx +0 -100
  323. package/src/components/countdown/style.css +0 -10
  324. package/src/components/delegationsContainer/IssueComponent.tsx +0 -156
  325. package/src/components/delegationsContainer/IssueTicketForm.tsx +0 -109
  326. package/src/components/delegationsContainer/TicketsAssignedTable.tsx +0 -55
  327. package/src/components/delegationsContainer/TicketsAvailableTable.tsx +0 -54
  328. package/src/components/delegationsContainer/index.tsx +0 -83
  329. package/src/components/forgotPasswordModal/index.tsx +0 -138
  330. package/src/components/forgotPasswordModal/style.css +0 -47
  331. package/src/components/idVerificationContainer/VerificationPendingModal.tsx +0 -47
  332. package/src/components/idVerificationContainer/constants.ts +0 -27
  333. package/src/components/idVerificationContainer/index.tsx +0 -323
  334. package/src/components/index.ts +0 -12
  335. package/src/components/loginForm/index.tsx +0 -202
  336. package/src/components/loginModal/SignUpForm.tsx +0 -329
  337. package/src/components/loginModal/constants.ts +0 -46
  338. package/src/components/loginModal/index.tsx +0 -263
  339. package/src/components/loginModal/style.css +0 -116
  340. package/src/components/myTicketsContainer/index.tsx +0 -228
  341. package/src/components/myTicketsContainer/row.tsx +0 -46
  342. package/src/components/myTicketsContainer/style.css +0 -40
  343. package/src/components/myTicketsContainer/tableConfig.tsx +0 -80
  344. package/src/components/myTicketsContainer/types.d.ts +0 -41
  345. package/src/components/orderDetailsContainer/CustomFieldsForm.tsx +0 -75
  346. package/src/components/orderDetailsContainer/TicketHolderCustomFields.tsx +0 -100
  347. package/src/components/orderDetailsContainer/index.tsx +0 -586
  348. package/src/components/orderDetailsContainer/style.css +0 -77
  349. package/src/components/orderDetailsContainer/ticketsTable.tsx +0 -246
  350. package/src/components/orderDetailsContainer/utils/index.tsx +0 -55
  351. package/src/components/paymentContainer/OrderDetails.tsx +0 -277
  352. package/src/components/paymentContainer/PaymentPlanSection.tsx +0 -169
  353. package/src/components/paymentContainer/handlePayment.ts +0 -86
  354. package/src/components/paymentContainer/index.tsx +0 -643
  355. package/src/components/paymentContainer/style.css +0 -196
  356. package/src/components/preRegistration/FieldsSection.tsx +0 -150
  357. package/src/components/preRegistration/Influancers.tsx +0 -34
  358. package/src/components/preRegistration/PreRegistrationComplete.tsx +0 -186
  359. package/src/components/preRegistration/PreRegistrationInformations.tsx +0 -60
  360. package/src/components/preRegistration/Prewards.tsx +0 -41
  361. package/src/components/preRegistration/ShareOptions.tsx +0 -77
  362. package/src/components/preRegistration/constants.tsx +0 -169
  363. package/src/components/preRegistration/index.tsx +0 -330
  364. package/src/components/preRegistration/style.css +0 -3
  365. package/src/components/preRegistration/utils.ts +0 -163
  366. package/src/components/registerForm/adapters/index.tsx +0 -10
  367. package/src/components/registerForm/constants.tsx +0 -98
  368. package/src/components/registerForm/index.tsx +0 -188
  369. package/src/components/registerModal/index.tsx +0 -154
  370. package/src/components/registerModal/style.css +0 -18
  371. package/src/components/resetPasswordContainer/index.tsx +0 -102
  372. package/src/components/resetPasswordContainer/style.css +0 -36
  373. package/src/components/rsvpContainer/index.tsx +0 -126
  374. package/src/components/seatMapContainer/SeatMapComponent.tsx +0 -77
  375. package/src/components/seatMapContainer/TicketsSection.tsx +0 -286
  376. package/src/components/seatMapContainer/addToCart.ts +0 -66
  377. package/src/components/seatMapContainer/index.tsx +0 -443
  378. package/src/components/seatMapContainer/utils.ts +0 -133
  379. package/src/components/signupModal/index.tsx +0 -178
  380. package/src/components/signupModal/style.css +0 -58
  381. package/src/components/ticketResale/index.tsx +0 -86
  382. package/src/components/ticketResaleModal/index.tsx +0 -224
  383. package/src/components/ticketResaleModal/style.css +0 -28
  384. package/src/components/ticketsContainer/AccessCodeSection.tsx +0 -50
  385. package/src/components/ticketsContainer/InfoIcon.tsx +0 -35
  386. package/src/components/ticketsContainer/PromoCodeSection.tsx +0 -116
  387. package/src/components/ticketsContainer/ReferralLogic.tsx +0 -33
  388. package/src/components/ticketsContainer/TicketRow.tsx +0 -107
  389. package/src/components/ticketsContainer/TicketsSection.tsx +0 -350
  390. package/src/components/ticketsContainer/TimeSlotTicketRow.tsx +0 -243
  391. package/src/components/ticketsContainer/TimeSlotsSection.tsx +0 -194
  392. package/src/components/ticketsContainer/index.tsx +0 -986
  393. package/src/components/ticketsContainer/style.css +0 -178
  394. package/src/components/ticketsContainer/utils.ts +0 -35
  395. package/src/components/timerWidget/index.tsx +0 -97
  396. package/src/components/timerWidget/style.css +0 -35
  397. package/src/components/waitingList/index.tsx +0 -190
  398. package/src/components/waitingList/style.css +0 -27
  399. package/src/constants/index.ts +0 -3
  400. package/src/env.ts +0 -29
  401. package/src/hoc/CustomFields/index.tsx +0 -85
  402. package/src/hoc/index.ts +0 -1
  403. package/src/hooks/index.ts +0 -1
  404. package/src/hooks/useCookieListener.ts +0 -32
  405. package/src/hooks/useEventListener.ts +0 -32
  406. package/src/hooks/useLocalStorageListener.ts +0 -32
  407. package/src/hooks/useOnline.ts +0 -21
  408. package/src/hooks/usePixel.ts +0 -88
  409. package/src/normalizers/index.ts +0 -49
  410. package/src/types/add_on.ts +0 -8
  411. package/src/types/api/auth.d.ts +0 -63
  412. package/src/types/api/axiosResponse.d.ts +0 -6
  413. package/src/types/api/cart.d.ts +0 -73
  414. package/src/types/api/checkout.d.ts +0 -92
  415. package/src/types/api/common.d.ts +0 -153
  416. package/src/types/api/guestTicketDelegation.d.ts +0 -18
  417. package/src/types/api/orders.d.ts +0 -116
  418. package/src/types/api/payment.d.ts +0 -180
  419. package/src/types/api/preRegistration.d.ts +0 -11
  420. package/src/types/api/preRegistrationComplete.d.ts +0 -95
  421. package/src/types/api/ticketResale.d.ts +0 -13
  422. package/src/types/billing-info-data.ts +0 -37
  423. package/src/types/checkoutPageConfigs.ts +0 -13
  424. package/src/types/formFields.d.ts +0 -29
  425. package/src/types/index.ts +0 -6
  426. package/src/types/order-data.ts +0 -16
  427. package/src/types/payment-field.ts +0 -7
  428. package/src/types/payment-plan-configuration.ts +0 -19
  429. package/src/types/pre-registration-complete.d.ts +0 -47
  430. package/src/types/referral-promotion.ts +0 -7
  431. package/src/types/seatMap.d.ts +0 -159
  432. package/src/types/verification.ts +0 -12
  433. package/src/utils/adaptStripeErrors.ts +0 -26
  434. package/src/utils/auth.ts +0 -45
  435. package/src/utils/cookies.ts +0 -73
  436. package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +0 -81
  437. package/src/utils/createMarkup.ts +0 -1
  438. package/src/utils/customFields.ts +0 -80
  439. package/src/utils/downloadPDF.tsx +0 -42
  440. package/src/utils/form.ts +0 -34
  441. package/src/utils/formikErrorFocus.ts +0 -24
  442. package/src/utils/getDomain.ts +0 -21
  443. package/src/utils/getImage.ts +0 -14
  444. package/src/utils/getQueryVariable.ts +0 -13
  445. package/src/utils/htmlNodeFromString.ts +0 -6
  446. package/src/utils/index.ts +0 -15
  447. package/src/utils/isBrowser.ts +0 -2
  448. package/src/utils/isValidNumber.ts +0 -8
  449. package/src/utils/jsonUtils.ts +0 -8
  450. package/src/utils/replaceVarInString.ts +0 -9
  451. package/src/utils/setConfigs.ts +0 -24
  452. package/src/utils/showZero.tsx +0 -10
  453. package/src/validators/index.ts +0 -61
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.7.31",
2
+ "version": "2.0.0-beta.0",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -11,109 +11,124 @@
11
11
  "node": ">=10"
12
12
  },
13
13
  "scripts": {
14
- "start": "tsdx watch",
15
- "build": "tsdx build",
16
- "test": "tsdx test --passWithNoTests",
17
- "lint": "tsdx lint",
18
- "prepare": "tsdx build",
14
+ "start": "tsup --watch",
15
+ "build": "pnpm check:architecture && tsup",
16
+ "check:architecture": "node scripts/check-checkout-architecture.mjs",
17
+ "test": "echo \"No tests specified\" && exit 0",
18
+ "lint": "eslint src",
19
+ "lint:fix": "eslint src --fix",
20
+ "prepare": "tsup",
19
21
  "size": "size-limit",
20
22
  "analyze": "size-limit --why",
21
- "release:beta": "npm version prerelease --preid beta",
22
- "release:patch": "npm version patch",
23
- "release:minor": "npm version minor",
24
- "publish:current": "export $(cat .env | xargs) && npm publish && git push && git push --tags",
25
- "publish:patch": "export $(cat .env | xargs) && npm version patch && npm publish && git push && git push --tags",
26
- "publish:minor": "export $(cat .env | xargs) && npm version minor && npm publish && git push && git push --tags",
27
- "publish:beta": "export $(cat .env | xargs) && npm version prerelease --preid beta && npm publish --tag beta && git push && git push --tags",
28
- "start-example": "PORT=3002 parcel example/index.html --dist-dir example-dist --no-cache"
23
+ "release": "release-it",
24
+ "release:current": "release-it --no-increment",
25
+ "release:patch": "release-it patch",
26
+ "release:minor": "release-it minor",
27
+ "release:major": "release-it major",
28
+ "release:beta": "release-it --preRelease=beta",
29
+ "start-example": "vite",
30
+ "build-example": "vite build"
29
31
  },
30
32
  "peerDependencies": {
31
- "react": ">=16"
33
+ "@tanstack/react-query": ">=5",
34
+ "react": ">=16",
35
+ "react-dom": ">=16"
32
36
  },
33
- "husky": {
34
- "hooks": {
35
- "pre-commit": "tsdx lint"
37
+ "peerDependenciesMeta": {
38
+ "@tanstack/react-query": {
39
+ "optional": true
36
40
  }
37
41
  },
38
- "prettier": {
39
- "printWidth": 90,
40
- "semi": false,
41
- "singleQuote": true,
42
- "trailingComma": "es5"
42
+ "publishConfig": {
43
+ "registry": "https://registry.npmjs.org/"
44
+ },
45
+ "release-it": {
46
+ "git": {
47
+ "commitMessage": "chore: release tf-checkout-react@${version}",
48
+ "tagName": "tf-checkout-react@${version}",
49
+ "push": true,
50
+ "requireCleanWorkingDir": true
51
+ },
52
+ "npm": {
53
+ "publish": true
54
+ },
55
+ "github": {
56
+ "release": true,
57
+ "releaseName": "tf-checkout-react@${version}",
58
+ "releaseNotes": "node ../../scripts/release-notes.mjs tf-checkout-react ${version}"
59
+ },
60
+ "plugins": {
61
+ "@release-it/conventional-changelog": {
62
+ "preset": {
63
+ "name": "angular"
64
+ },
65
+ "infile": "CHANGELOG.md"
66
+ }
67
+ }
43
68
  },
44
69
  "name": "tf-checkout-react",
45
70
  "author": "ft-worker",
46
- "module": "dist/tf-checkout-react.esm.js",
71
+ "packageManager": "pnpm@10.28.1",
72
+ "module": "dist/index.esm.js",
47
73
  "size-limit": [
48
74
  {
49
- "path": "dist/tf-checkout-react.cjs.production.min.js",
75
+ "path": "dist/index.js",
50
76
  "limit": "10 KB"
51
77
  },
52
78
  {
53
- "path": "dist/tf-checkout-react.esm.js",
79
+ "path": "dist/index.esm.js",
54
80
  "limit": "10 KB"
55
81
  }
56
82
  ],
57
83
  "devDependencies": {
84
+ "@commitlint/cli": "^19.8.1",
85
+ "@commitlint/config-conventional": "^19.8.1",
86
+ "@eslint/js": "^9.36.0",
87
+ "@evilmartians/lefthook": "^1.12.3",
88
+ "@release-it/conventional-changelog": "^10.0.1",
58
89
  "@size-limit/preset-small-lib": "^6.0.4",
90
+ "@tanstack/react-query": "^5.90.20",
59
91
  "@types/lodash": "^4.14.176",
60
- "@types/react": "^17.0.34",
61
- "@types/react-dom": "^17.0.11",
62
- "@typescript-eslint/eslint-plugin": "^5.48.1",
63
- "@typescript-eslint/parser": "^5.52.0",
64
- "eslint": "^8.34.0",
65
- "eslint-config-react-app": "^7.0.1",
66
- "eslint-plugin-flowtype": "^8.0.3",
67
- "eslint-plugin-import": "^2.22.1",
68
- "eslint-plugin-jsx-a11y": "^6.4.1",
69
- "eslint-plugin-react": "^7.32.2",
70
- "eslint-plugin-react-hooks": "^4.2.0",
71
- "eslint-plugin-simple-import-sort": "^7.0.0",
72
- "eslint-plugin-unused-imports": "^2.0.0",
73
- "eslint-webpack-plugin": "^3.2.0",
74
- "husky": "^7.0.4",
75
- "parcel": "^2.8.3",
92
+ "@types/react": "^19.2.9",
93
+ "@types/react-dom": "^19.2.3",
94
+ "@vitejs/plugin-react": "^5.1.2",
95
+ "@vitejs/plugin-react-swc": "^4.2.2",
96
+ "eslint": "^9.36.0",
97
+ "eslint-config-prettier": "^10.1.8",
98
+ "eslint-plugin-import": "^2.32.0",
99
+ "eslint-plugin-react": "^7.37.5",
100
+ "eslint-plugin-react-hooks": "^5.1.0",
101
+ "globals": "^16.4.0",
102
+ "moment": "^2.30.1",
76
103
  "prettier": "^2.8.4",
77
104
  "process": "^0.11.10",
78
- "react": "^17.0.2",
79
- "react-dom": "^17.0.2",
80
- "rollup-plugin-postcss": "^4.0.2",
105
+ "react": "^19.1.0",
106
+ "react-dom": "^19.1.0",
107
+ "release-it": "^19.0.4",
108
+ "rollup-plugin-postcss": "^4.0.1",
81
109
  "rollup-plugin-static-files": "^0.2.0",
82
110
  "size-limit": "^6.0.4",
83
- "tsdx": "^0.14.1",
84
- "tslib": "^2.3.1",
85
- "typescript": "^4.9.5"
111
+ "tf-checkout-shared": "workspace:*",
112
+ "tsup": "^8.5.1",
113
+ "typescript": "^5.9.3",
114
+ "typescript-eslint": "^8.45.0",
115
+ "vite": "^7.3.1"
86
116
  },
87
117
  "dependencies": {
88
- "@emotion/react": "^11.7.0",
89
- "@emotion/styled": "^11.6.0",
90
- "@fortawesome/fontawesome-svg-core": "^6.1.1",
91
- "@mui/icons-material": "^5.18.0",
92
- "@mui/material": "^5.2.2",
93
- "@mui/private-theming": "^5.11.1",
94
- "@mui/styles": "^5.2.2",
95
- "@mui/x-date-pickers": "^5.0.1",
96
- "@stripe/react-stripe-js": "^5.2.0",
97
118
  "@stripe/stripe-js": "^8.1.0",
98
- "axios": "^1.9.0",
99
- "clsx": "^1.1.1",
100
- "formik": "^2.2.9",
101
- "jwt-decode": "^3.1.2",
102
- "lodash": "^4.17.21",
103
- "lodash-es": "^4.17.21",
104
- "material-ui-phone-number": "^3.0.0",
105
- "moment-timezone": "^0.5.34",
106
- "nanoid": "^3.1.30",
107
- "prop-types": "^15.7.2",
108
- "react-app-polyfill": "^1.0.0",
109
- "react-bootstrap": "^2.0.2",
110
- "react-countdown": "^2.3.2",
111
- "react-inlinesvg": "^2.3.0",
112
- "react-router-dom": "^6.0.2",
113
- "react-share": "^5.2.2",
114
- "react-tooltip": "^5.28.0",
115
- "rollup-plugin-svg": "^2.0.0",
116
- "tf-seat-map-view": "9.4.7-beta.33",
117
- "yup": "^0.32.11"
118
- }
119
+ "axios": "^1.7.9",
120
+ "react-international-phone": "^4.7.0",
121
+ "tf-seat-map-view": "9.4.7-beta.33"
122
+ },
123
+ "exports": {
124
+ ".": {
125
+ "types": "./dist/index.d.ts",
126
+ "import": "./dist/index.esm.js",
127
+ "require": "./dist/index.js"
128
+ },
129
+ "./checkout.css": "./dist/checkout.css",
130
+ "./*": "./*"
131
+ },
132
+ "types": "dist/index.d.ts",
133
+ "//dependencies": "tf-checkout-shared is INLINED into this bundle (tsup noExternal), so its own runtime deps are ours too — axios must stay declared here or tsup bundles it (dragging Node's stream into a browser build) / the consumer never installs it."
119
134
  }
package/src/.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  declare module '*.css'
2
2
  declare module '*.png'
3
- declare module '*.svg';
3
+ declare module '*.svg'
4
4
  declare module 'tf-seat-map-view'
@@ -0,0 +1,374 @@
1
+ /**
2
+ * The card fields. `<CardInput/>` mounts a Stripe Element as soon as the engine
3
+ * has initialized Stripe (via the confirmer's `whenReady()` — no races, renders
4
+ * before or after init) and registers it with the confirmer. `<XenditCardInput/>`
5
+ * is the inline, formatted equivalent for Xendit events.
6
+ */
7
+ import React, { useEffect, useRef, useState, type CSSProperties, type FC } from 'react'
8
+ import type {
9
+ StripeCardElementOptions,
10
+ StripeElements,
11
+ StripeElementsOptionsMode,
12
+ StripePaymentElementOptions,
13
+ } from '@stripe/stripe-js'
14
+
15
+ import { webConfirmer, webXenditTokenizer } from './instance'
16
+ import { preloadXendit, xenditCardChecks } from './xendit'
17
+
18
+ type Field = 'number' | 'expiry' | 'cvc'
19
+
20
+ /**
21
+ * The Stripe card field. Mounts against the engine's Stripe instance and
22
+ * registers itself with the confirmer; unregisters on unmount.
23
+ *
24
+ * Stripe Elements live in a cross-origin iframe and DON'T inherit page CSS, so
25
+ * by default they render black text — invisible on a dark surface. We read the
26
+ * host element's computed color/font and feed them to the Element so it matches
27
+ * whatever theme the consumer uses, no config needed. Pass `style` to override.
28
+ */
29
+ export const CardInput: FC<{
30
+ className?: string
31
+ /** Stripe base-style overrides, merged onto the inherited color/font. */
32
+ style?: StripeCardElementOptions['style']
33
+ }> = ({ className, style }) => {
34
+ const hostRef = useRef<HTMLDivElement | null>(null)
35
+
36
+ useEffect(() => {
37
+ let element: { mount: (el: HTMLElement) => void; unmount: () => void } | null = null
38
+ let cancelled = false
39
+ webConfirmer.whenReady().then((stripe) => {
40
+ if (cancelled || !hostRef.current) return
41
+ const cs = getComputedStyle(hostRef.current)
42
+ const color = cs.color || '#ffffff'
43
+ const fontSize = cs.fontSize && parseFloat(cs.fontSize) > 0 ? cs.fontSize : '16px'
44
+ // Stripe's Element style parser only accepts hex / rgb / rgba / hsl / named
45
+ // colors — NOT color-mix() or CSS vars (it silently drops the whole style,
46
+ // leaving a blank, dead field). Derive a muted placeholder as a plain rgba
47
+ // of the inherited text color.
48
+ const rgb = color.match(/\d+(?:\.\d+)?/g)
49
+ const placeholder =
50
+ rgb && rgb.length >= 3 ? `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 0.5)` : color
51
+ const card = stripe.elements().create('card', {
52
+ style: {
53
+ ...style,
54
+ base: {
55
+ color,
56
+ fontFamily: cs.fontFamily,
57
+ fontSize,
58
+ iconColor: color,
59
+ '::placeholder': { color: placeholder },
60
+ ...style?.base,
61
+ },
62
+ },
63
+ })
64
+ card.mount(hostRef.current)
65
+ webConfirmer.registerCardElement(card)
66
+ element = card
67
+ })
68
+ return () => {
69
+ cancelled = true
70
+ if (element) {
71
+ webConfirmer.registerCardElement(null)
72
+ element.unmount()
73
+ }
74
+ }
75
+ }, [])
76
+
77
+ return <div ref={hostRef} className={className} />
78
+ }
79
+
80
+ /**
81
+ * Build a Stripe Appearance from the live `--tf-checkout-*` tokens on the host
82
+ * element. This is what keeps the Payment Element CONSISTENT with the rest of the
83
+ * checkout: it inherits the same surface / text / accent / border / radius / font
84
+ * a consumer set — via the provider `theme`, their own CSS, or the default
85
+ * light/dark — so retheming the checkout (flat, branded, whatever) reflows the
86
+ * Stripe widget too, instead of it being a generic Stripe `night`/`stripe` box.
87
+ */
88
+ const checkoutAppearance = (host: HTMLElement) => {
89
+ const cs = getComputedStyle(host)
90
+ const v = (name: string) => cs.getPropertyValue(name).trim() || undefined
91
+ const surface = v('--tf-checkout-surface')
92
+ const text = v('--tf-checkout-text')
93
+ const muted = v('--tf-checkout-muted')
94
+ const border = v('--tf-checkout-border')
95
+ const accent = v('--tf-checkout-accent')
96
+ const danger = v('--tf-checkout-error')
97
+ const font = v('--tf-checkout-font')
98
+ const radius = v('--tf-checkout-radius-control')
99
+
100
+ // Pick the closest Stripe base theme from the surface luminance, then override
101
+ // its palette with our tokens so it matches exactly.
102
+ const bgRgb = ((surface ?? cs.backgroundColor).match(/\d+(?:\.\d+)?/g) ?? []).map(
103
+ Number
104
+ )
105
+ const isDark =
106
+ bgRgb.length >= 3 &&
107
+ (0.299 * bgRgb[0] + 0.587 * bgRgb[1] + 0.114 * bgRgb[2]) / 255 < 0.5
108
+
109
+ const variables: Record<string, string> = {}
110
+ const set = (k: string, val?: string) => {
111
+ if (val) variables[k] = val
112
+ }
113
+ set('colorPrimary', accent)
114
+ set('colorBackground', surface)
115
+ set('colorText', text)
116
+ set('colorTextSecondary', muted)
117
+ set('colorTextPlaceholder', muted)
118
+ set('colorDanger', danger)
119
+ set('fontFamily', font)
120
+ set('borderRadius', radius)
121
+
122
+ const rules: Record<string, Record<string, string>> = {}
123
+ if (border) {
124
+ rules['.Input'] = { border: `1px solid ${border}` }
125
+ rules['.Input:focus'] = {
126
+ border: `1px solid ${accent ?? border}`,
127
+ boxShadow: 'none',
128
+ }
129
+ rules['.Tab'] = { border: `1px solid ${border}` }
130
+ rules['.Block'] = { border: `1px solid ${border}` }
131
+ }
132
+
133
+ return {
134
+ theme: isDark ? 'night' : 'stripe',
135
+ ...(Object.keys(variables).length ? { variables } : {}),
136
+ ...(Object.keys(rules).length ? { rules } : {}),
137
+ }
138
+ }
139
+
140
+ /**
141
+ * The wallet-capable card widget — a Stripe **Payment Element** in DEFERRED mode,
142
+ * exactly how the OLD checkout rendered payment. It shows the card fields AND,
143
+ * when the event's `stripe_wallets` gate is on, the Apple Pay / Google Pay
144
+ * buttons that the buyer picks *inside* the widget. There is no separate "Apple
145
+ * Pay" method row — wallets are a property of the card widget, as in old.
146
+ *
147
+ * Confirmation rides the same `placeOrder({ method: 'card' })` rail: this mounts
148
+ * the Elements group and registers it with the confirmer, whose `confirmCard`
149
+ * then runs `elements.submit()` + `stripe.confirmPayment` (old
150
+ * `useStripePayment.processPayment`). Mount this instead of `<CardInput/>` for a
151
+ * Stripe event with wallets available — see `<Payment/>`. It needs the server's
152
+ * deferred Elements config (`checkout.stripeElementsConfig`: mode/amount/currency).
153
+ */
154
+ export const StripePaymentElement: FC<{
155
+ className?: string
156
+ /** Server deferred Elements config from `checkout.stripeElementsConfig`. */
157
+ elementsConfig?: Record<string, unknown>
158
+ /** Wallet gate from `checkout.walletAvailability`. */
159
+ wallets?: { applePay?: boolean; googlePay?: boolean }
160
+ /** Extra Payment Element options, merged over the wallet gate. */
161
+ options?: StripePaymentElementOptions
162
+ }> = ({ className, elementsConfig, wallets, options }) => {
163
+ const hostRef = useRef<HTMLDivElement | null>(null)
164
+
165
+ // Re-mount when the deferred amount/currency or the wallet gate changes.
166
+ const configKey = JSON.stringify(elementsConfig ?? null)
167
+ const applePay = Boolean(wallets?.applePay)
168
+ const googlePay = Boolean(wallets?.googlePay)
169
+
170
+ useEffect(() => {
171
+ let group: StripeElements | null = null
172
+ let element: { unmount: () => void } | null = null
173
+ let cancelled = false
174
+
175
+ webConfirmer.whenReady().then((stripe) => {
176
+ if (cancelled || !hostRef.current) return
177
+ // Deferred mode — the same `{ mode, amount, currency }` shape the old
178
+ // `<Elements options={elements_config}>` used.
179
+ const mode = (elementsConfig ?? {
180
+ mode: 'payment',
181
+ amount: 0,
182
+ currency: 'usd',
183
+ }) as unknown as StripeElementsOptionsMode
184
+ // Theme the widget from the checkout's own tokens (read live off the host)
185
+ // so it matches whatever the consumer set — not a generic Stripe preset.
186
+ // (The server sends `theme:'automatic'`, which isn't a real Stripe theme and
187
+ // just defaults to light — hence the white box on a dark checkout.)
188
+ group = stripe.elements({
189
+ ...mode,
190
+ appearance: checkoutAppearance(hostRef.current),
191
+ } as unknown as StripeElementsOptionsMode)
192
+ const pe = group.create('payment', {
193
+ ...options,
194
+ wallets: {
195
+ applePay: applePay ? 'auto' : 'never',
196
+ googlePay: googlePay ? 'auto' : 'never',
197
+ ...(options?.wallets ?? {}),
198
+ },
199
+ })
200
+ pe.mount(hostRef.current)
201
+ webConfirmer.registerPaymentElement(group)
202
+ element = pe
203
+ })
204
+
205
+ return () => {
206
+ cancelled = true
207
+ if (element) {
208
+ webConfirmer.registerPaymentElement(null)
209
+ element.unmount()
210
+ }
211
+ }
212
+ // eslint-disable-next-line react-hooks/exhaustive-deps
213
+ }, [configKey, applePay, googlePay])
214
+
215
+ return <div ref={hostRef} className={className} />
216
+ }
217
+
218
+ const onlyDigits = (v: string) => v.replace(/\D/g, '')
219
+ /** "1234567812345678" → "1234 5678 1234 5678" (max 19 digits). */
220
+ const formatCardNumber = (v: string) =>
221
+ onlyDigits(v)
222
+ .slice(0, 19)
223
+ .replace(/(\d{4})(?=\d)/g, '$1 ')
224
+ /**
225
+ * Digits → "MM/YY" (max 4 digits), inserting the slash after the month.
226
+ * A leading digit above 1 can only be a single-digit month, so it's expanded
227
+ * ("4" → "04/"); a two-digit month is clamped to 12. Without this the field
228
+ * happily accepted "44/44" and only Xendit ever objected.
229
+ */
230
+ const formatExpiry = (v: string) => {
231
+ let d = onlyDigits(v).slice(0, 4)
232
+ if (d.length === 1 && Number(d) > 1) d = `0${d}`
233
+ if (d.length >= 2) {
234
+ const mm = Math.min(Math.max(Number(d.slice(0, 2)), 1), 12)
235
+ d = String(mm).padStart(2, '0') + d.slice(2)
236
+ }
237
+ return d.length > 2 ? `${d.slice(0, 2)}/${d.slice(2)}` : d
238
+ }
239
+ const formatCvc = (v: string) => onlyDigits(v).slice(0, 4)
240
+
241
+ /**
242
+ * Inline card field for a Xendit event — the formatted, no-popup equivalent of
243
+ * `<CardInput/>`. Render it when the gateway is Xendit and the buyer picks card,
244
+ * then `placeOrder({ method: 'xenditCard' })`: the engine tokenizes these fields
245
+ * with xendit.js (3DS inline) and charges server-side.
246
+ */
247
+ export const XenditCardInput: FC<{
248
+ className?: string
249
+ inputClassName?: string
250
+ /**
251
+ * Reports the current field-level problem (or null when the fields are fine).
252
+ * The message is deliberately NOT rendered here: this component is mounted
253
+ * inside the consumer's bordered card box, and an error printed in there sits
254
+ * inside the border instead of beneath it. The consumer places it — see
255
+ * `<Payment/>`, which renders it under the box like every other field error.
256
+ */
257
+ onValidationChange?: (message: string | null) => void
258
+ }> = ({ className, inputClassName, onValidationChange }) => {
259
+ const [number, setNumber] = useState('')
260
+ const [expiry, setExpiry] = useState('')
261
+ const [cvc, setCvc] = useState('')
262
+ // Per-field messages, revealed on blur so the buyer isn't scolded mid-typing.
263
+ const [touched, setTouched] = useState<Record<Field, boolean>>({
264
+ number: false,
265
+ expiry: false,
266
+ cvc: false,
267
+ })
268
+
269
+ const [mm = '', yy = ''] = expiry.split('/')
270
+ const errors: Record<Field, string | null> = {
271
+ number: number && !xenditCardChecks.number(number) ? 'Card number is invalid' : null,
272
+ expiry:
273
+ expiry.length >= 5 && !xenditCardChecks.expiry(mm, yy)
274
+ ? 'Expiry date is invalid'
275
+ : null,
276
+ cvc: cvc && !xenditCardChecks.cvn(cvc) ? 'Security code is invalid' : null,
277
+ }
278
+ const show = (f: Field) => (touched[f] ? errors[f] : null)
279
+ const markTouched = (f: Field) => setTouched((t) => ({ ...t, [f]: true }))
280
+
281
+ // The tokenizer reads the live values at pay time via this ref (registered
282
+ // once) — no stale closure over state.
283
+ const latest = useRef({ number, expiry, cvc })
284
+ latest.current = { number, expiry, cvc }
285
+
286
+ useEffect(() => {
287
+ // Warm xendit.js so the checks above use Xendit's own rules from the first
288
+ // blur, not just the local fallback.
289
+ preloadXendit()
290
+ webXenditTokenizer.registerFields(() => {
291
+ const [m = '', y = ''] = latest.current.expiry.split('/')
292
+ return {
293
+ number: latest.current.number,
294
+ expMonth: m.trim(),
295
+ expYear: y.trim(),
296
+ cvn: latest.current.cvc,
297
+ }
298
+ })
299
+ return () => webXenditTokenizer.registerFields(null)
300
+ }, [])
301
+
302
+ // Borderless inner inputs (unless the consumer styles them) so the three
303
+ // fields read as one card field inside `className`.
304
+ const blend: CSSProperties = inputClassName
305
+ ? {}
306
+ : {
307
+ border: 0,
308
+ background: 'transparent',
309
+ outline: 'none',
310
+ padding: 0,
311
+ color: 'inherit',
312
+ font: 'inherit',
313
+ }
314
+
315
+ // First message wins. Reported upward (never rendered here) so the consumer
316
+ // can place it below its card box.
317
+ const message = show('number') || show('expiry') || show('cvc')
318
+
319
+ const reportRef = useRef(onValidationChange)
320
+ reportRef.current = onValidationChange
321
+ useEffect(() => {
322
+ // Re-report on every EDIT, not just when the message text changes. A field
323
+ // that was never blurred has no message of its own, so if the consumer is
324
+ // showing a pay-time failure ("Card number is invalid" from the submit
325
+ // attempt) a message-only dependency would never fire again and that error
326
+ // would sit there while the buyer types a perfectly good number.
327
+ //
328
+ // The callback identity is deliberately NOT a dependency — a consumer's
329
+ // inline arrow changes every render and would loop.
330
+ reportRef.current?.(message)
331
+ }, [message, number, expiry, cvc])
332
+
333
+ return (
334
+ <div
335
+ className={className}
336
+ style={{ display: 'flex', alignItems: 'center', gap: 10 }}
337
+ data-checkout-invalid={message ? 'true' : undefined}
338
+ >
339
+ <input
340
+ className={inputClassName}
341
+ style={{ ...blend, flex: 1, minWidth: 0 }}
342
+ inputMode="numeric"
343
+ autoComplete="cc-number"
344
+ placeholder="Card number"
345
+ aria-invalid={Boolean(show('number'))}
346
+ value={number}
347
+ onChange={(e) => setNumber(formatCardNumber(e.target.value))}
348
+ onBlur={() => markTouched('number')}
349
+ />
350
+ <input
351
+ className={inputClassName}
352
+ style={{ ...blend, width: 64, textAlign: 'center' }}
353
+ inputMode="numeric"
354
+ autoComplete="cc-exp"
355
+ placeholder="MM / YY"
356
+ aria-invalid={Boolean(show('expiry'))}
357
+ value={expiry}
358
+ onChange={(e) => setExpiry(formatExpiry(e.target.value))}
359
+ onBlur={() => markTouched('expiry')}
360
+ />
361
+ <input
362
+ className={inputClassName}
363
+ style={{ ...blend, width: 44, textAlign: 'center' }}
364
+ inputMode="numeric"
365
+ autoComplete="cc-csc"
366
+ placeholder="CVC"
367
+ aria-invalid={Boolean(show('cvc'))}
368
+ value={cvc}
369
+ onChange={(e) => setCvc(formatCvc(e.target.value))}
370
+ onBlur={() => markTouched('cvc')}
371
+ />
372
+ </div>
373
+ )
374
+ }