@coinbase/cdp-react 0.0.18 → 0.0.19

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 (133) hide show
  1. package/dist/assets/Button.css +1 -1
  2. package/dist/assets/EmailForm.css +1 -0
  3. package/dist/assets/Error.css +1 -1
  4. package/dist/assets/Field.css +1 -1
  5. package/dist/assets/FlowEmailOTP.css +1 -0
  6. package/dist/assets/FlowPhoneNumberOTP.css +1 -0
  7. package/dist/assets/Input.css +1 -1
  8. package/dist/assets/Label.css +1 -0
  9. package/dist/assets/OTP.css +1 -1
  10. package/dist/assets/OTPForm.css +1 -0
  11. package/dist/assets/PhoneNumberForm.css +1 -0
  12. package/dist/assets/PhoneNumberInput.css +1 -0
  13. package/dist/assets/SignIn.css +1 -1
  14. package/dist/assets/SignInAuthMethodButtons.css +1 -0
  15. package/dist/assets/SignInBackButton.css +1 -0
  16. package/dist/assets/SignInCredentials.css +1 -0
  17. package/dist/assets/SignInDescription.css +1 -1
  18. package/dist/assets/SignInFooter.css +1 -0
  19. package/dist/assets/SignInForm.css +1 -1
  20. package/dist/assets/SignInImage.css +1 -1
  21. package/dist/assets/SignInModal.css +1 -1
  22. package/dist/assets/SignInTitle.css +1 -1
  23. package/dist/assets/SuccessMessage.css +1 -0
  24. package/dist/assets/SwitchFadeTransition.css +1 -0
  25. package/dist/assets/SwitchSlideTransition.css +1 -0
  26. package/dist/assets/SwitchTransition.css +1 -0
  27. package/dist/assets/ThemeProvider.css +1 -1
  28. package/dist/chunks/index.BzllgVaP.js +12 -0
  29. package/dist/components/AuthButton/index.js +1 -1
  30. package/dist/components/Button/index.d.ts +2 -1
  31. package/dist/components/Button/index.js +47 -22
  32. package/dist/components/CDPReactProvider/index.d.ts +3 -0
  33. package/dist/components/CDPReactProvider/index.js +20 -13
  34. package/dist/components/EmailForm/index.d.ts +11 -0
  35. package/dist/components/EmailForm/index.js +56 -0
  36. package/dist/components/Error/index.d.ts +2 -2
  37. package/dist/components/Error/index.js +11 -11
  38. package/dist/components/Field/index.d.ts +2 -1
  39. package/dist/components/Field/index.js +20 -18
  40. package/dist/components/FlowEmailOTP/index.d.ts +18 -0
  41. package/dist/components/FlowEmailOTP/index.js +70 -0
  42. package/dist/components/FlowPhoneNumberOTP/index.d.ts +18 -0
  43. package/dist/components/FlowPhoneNumberOTP/index.js +75 -0
  44. package/dist/components/Label/index.d.ts +7 -0
  45. package/dist/components/Label/index.js +13 -0
  46. package/dist/components/OTP/index.d.ts +3 -0
  47. package/dist/components/OTP/index.js +48 -33
  48. package/dist/components/OTPForm/index.d.ts +16 -0
  49. package/dist/components/OTPForm/index.js +76 -0
  50. package/dist/components/PhoneNumberForm/index.d.ts +14 -0
  51. package/dist/components/PhoneNumberForm/index.js +68 -0
  52. package/dist/components/PhoneNumberInput/PhoneNumberMetadata.d.ts +2 -0
  53. package/dist/components/PhoneNumberInput/PhoneNumberMetadata.js +5 -0
  54. package/dist/components/PhoneNumberInput/index.d.ts +10 -0
  55. package/dist/components/PhoneNumberInput/index.js +76 -0
  56. package/dist/components/PhoneNumberInput/maskOverride.d.ts +8 -0
  57. package/dist/components/PhoneNumberInput/maskOverride.js +61 -0
  58. package/dist/components/PhoneNumberInput/usePhoneNumberFormatter.d.ts +7 -0
  59. package/dist/components/PhoneNumberInput/usePhoneNumberFormatter.js +52 -0
  60. package/dist/components/ServerError/index.js +4 -4
  61. package/dist/components/SignIn/SignInAuthMethodButtons.d.ts +13 -0
  62. package/dist/components/SignIn/SignInAuthMethodButtons.js +57 -0
  63. package/dist/components/SignIn/SignInBackButton.d.ts +9 -0
  64. package/dist/components/SignIn/SignInBackButton.js +38 -0
  65. package/dist/components/SignIn/SignInCredentials.d.ts +2 -0
  66. package/dist/components/SignIn/SignInCredentials.js +8 -0
  67. package/dist/components/SignIn/SignInDescription.d.ts +4 -3
  68. package/dist/components/SignIn/SignInDescription.js +16 -23
  69. package/dist/components/SignIn/SignInFooter.d.ts +2 -0
  70. package/dist/components/SignIn/SignInFooter.js +18 -0
  71. package/dist/components/SignIn/SignInForm.d.ts +12 -4
  72. package/dist/components/SignIn/SignInForm.js +25 -196
  73. package/dist/components/SignIn/SignInImage.d.ts +2 -2
  74. package/dist/components/SignIn/SignInImage.js +11 -14
  75. package/dist/components/SignIn/SignInProvider.d.ts +1 -1
  76. package/dist/components/SignIn/SignInProvider.js +24 -16
  77. package/dist/components/SignIn/SignInTitle.d.ts +4 -3
  78. package/dist/components/SignIn/SignInTitle.js +18 -13
  79. package/dist/components/SignIn/flows/SignInWithEmail.d.ts +5 -0
  80. package/dist/components/SignIn/flows/SignInWithEmail.js +71 -0
  81. package/dist/components/SignIn/flows/SignInWithSms.d.ts +5 -0
  82. package/dist/components/SignIn/flows/SignInWithSms.js +2994 -0
  83. package/dist/components/SignIn/hooks/useEmailForm.d.ts +13 -0
  84. package/dist/components/SignIn/hooks/useEmailForm.js +42 -0
  85. package/dist/components/SignIn/hooks/useOTPForm.d.ts +16 -0
  86. package/dist/components/SignIn/hooks/useOTPForm.js +59 -0
  87. package/dist/components/SignIn/hooks/usePhoneNumberForm.d.ts +13 -0
  88. package/dist/components/SignIn/hooks/usePhoneNumberForm.js +42 -0
  89. package/dist/components/SignIn/index.d.ts +5 -2
  90. package/dist/components/SignIn/index.js +42 -24
  91. package/dist/components/SignIn/types.d.ts +106 -0
  92. package/dist/components/SignIn/types.js +3 -0
  93. package/dist/components/SignIn/useSignInReducer.d.ts +1 -57
  94. package/dist/components/SignIn/useSignInReducer.js +62 -20
  95. package/dist/components/SignInModal/index.d.ts +2 -2
  96. package/dist/components/SignInModal/index.js +62 -43
  97. package/dist/components/SuccessMessage/index.d.ts +7 -0
  98. package/dist/components/SuccessMessage/index.js +16 -0
  99. package/dist/components/SwitchFadeTransition/index.d.ts +5 -0
  100. package/dist/components/SwitchFadeTransition/index.js +24 -0
  101. package/dist/components/SwitchSlideTransition/index.d.ts +7 -0
  102. package/dist/components/SwitchSlideTransition/index.js +27 -0
  103. package/dist/components/SwitchTransition/index.d.ts +25 -0
  104. package/dist/components/SwitchTransition/index.js +155 -0
  105. package/dist/data/countries.d.ts +12 -0
  106. package/dist/data/countries.js +25 -0
  107. package/dist/data/countryNames.d.ts +1 -0
  108. package/dist/data/countryNames.js +6 -0
  109. package/dist/hooks/usePhoneNumberValidators.d.ts +14 -0
  110. package/dist/hooks/usePhoneNumberValidators.js +36 -0
  111. package/dist/hooks/useTimer.d.ts +5 -0
  112. package/dist/hooks/useTimer.js +24 -0
  113. package/dist/icons/IconArrowLeft.d.ts +2 -0
  114. package/dist/icons/IconArrowLeft.js +14 -0
  115. package/dist/icons/IconCheckCircle.js +2 -3
  116. package/dist/icons/IconCoinbaseWordmark.js +5 -5
  117. package/dist/icons/IconEnvelope.d.ts +2 -0
  118. package/dist/icons/IconEnvelope.js +7 -0
  119. package/dist/icons/IconExclamationCircle.js +3 -4
  120. package/dist/icons/IconPhone.d.ts +2 -0
  121. package/dist/icons/IconPhone.js +7 -0
  122. package/dist/icons/IconXMark.js +6 -5
  123. package/dist/icons/index.d.ts +3 -0
  124. package/dist/icons/index.js +14 -8
  125. package/dist/index.js +66 -53
  126. package/dist/theme/theme.d.ts +11 -2
  127. package/dist/theme/tokens.d.ts +30 -6
  128. package/dist/theme/tokens.js +7 -3
  129. package/dist/utils/parseValuesFromPhoneNumber.d.ts +6 -0
  130. package/dist/utils/parseValuesFromPhoneNumber.js +16 -0
  131. package/dist/utils/validatePhoneNumber.d.ts +1 -0
  132. package/dist/utils/validatePhoneNumber.js +1 -0
  133. package/package.json +11 -7
@@ -0,0 +1,75 @@
1
+ import { jsx as r, Fragment as x } from "react/jsx-runtime";
2
+ import "react";
3
+ import { OTPForm as g } from "../OTPForm/index.js";
4
+ import { PhoneNumberForm as j } from "../PhoneNumberForm/index.js";
5
+ import { SwitchSlideTransition as v } from "../SwitchSlideTransition/index.js";
6
+ import '../../assets/FlowPhoneNumberOTP.css';const E = {
7
+ "step-wrapper": "FlowPhoneNumberOTP-module__step-wrapper___TtbeW"
8
+ }, B = ({
9
+ animateHeight: u = !0,
10
+ autoFocus: l = !0,
11
+ canResetOTP: h,
12
+ children: m,
13
+ className: p = "",
14
+ countryCode: b,
15
+ error: i,
16
+ isPending: n,
17
+ onCountryCodeChange: s,
18
+ onOTPChange: a,
19
+ onPhoneNumberChange: c,
20
+ onResendOTP: f,
21
+ onSubmitOTP: F,
22
+ onSubmitPhoneNumber: d,
23
+ otp: w,
24
+ otpInputsRef: N,
25
+ phoneNumber: P,
26
+ resendCountdown: T,
27
+ step: o,
28
+ successMessage: _,
29
+ transitionRef: S
30
+ }) => /* @__PURE__ */ r(x, { children: /* @__PURE__ */ r(
31
+ v,
32
+ {
33
+ autoFocus: l,
34
+ animateHeight: u,
35
+ items: ["phoneNumber", "otp"],
36
+ initialEntered: !0,
37
+ direction: o === "otp" ? "left" : "right",
38
+ transitionRef: S,
39
+ children: ({ itemKey: e, ...O }) => {
40
+ let t = null;
41
+ return e === "phoneNumber" && (t = /* @__PURE__ */ r(
42
+ j,
43
+ {
44
+ className: p,
45
+ countryCode: b,
46
+ error: o === "phoneNumber" ? i : "",
47
+ isPending: n,
48
+ onCountryCodeChange: s,
49
+ onPhoneNumberChange: c,
50
+ onSubmit: d,
51
+ phoneNumber: P
52
+ }
53
+ )), e === "otp" && (t = /* @__PURE__ */ r(
54
+ g,
55
+ {
56
+ autoFocus: o === "otp",
57
+ canResetOTP: h,
58
+ className: p,
59
+ error: o === "otp" ? i : "",
60
+ isPending: n,
61
+ onOTPChange: a,
62
+ onResendOTP: f,
63
+ onSubmit: F,
64
+ otp: w,
65
+ otpInputsRef: N,
66
+ resendCountdown: T,
67
+ successMessage: _
68
+ }
69
+ )), /* @__PURE__ */ r("div", { ...O, className: E["step-wrapper"], children: m ? m({ step: e, Form: t }) : t });
70
+ }
71
+ }
72
+ ) });
73
+ export {
74
+ B as FlowPhoneNumberOTP
75
+ };
@@ -0,0 +1,7 @@
1
+ import { ElementType, HTMLAttributes, ReactNode } from 'react';
2
+ interface LabelProps extends HTMLAttributes<HTMLLabelElement> {
3
+ as?: ElementType;
4
+ children?: ReactNode;
5
+ }
6
+ export declare const Label: ({ as: Component, children, className, ...props }: LabelProps) => import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,13 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import "react";
3
+ import '../../assets/Label.css';const t = "Label-module__label___RaRvM", b = {
4
+ label: t
5
+ }, _ = ({
6
+ as: l = "label",
7
+ children: e,
8
+ className: a = "",
9
+ ...s
10
+ }) => /* @__PURE__ */ o(l, { className: `${b.label} ${a}`, ...s, children: e });
11
+ export {
12
+ _ as Label
13
+ };
@@ -1,6 +1,9 @@
1
1
  import { OneTimePasswordFieldProps } from '@radix-ui/react-one-time-password-field';
2
+ import { ReactNode } from 'react';
2
3
  type OTPProps = {
3
4
  error?: string | null;
5
+ successMessage?: string | null;
6
+ label?: ReactNode;
4
7
  passwordLength?: number;
5
8
  } & OneTimePasswordFieldProps;
6
9
  export declare const OTP: import('react').ForwardRefExoticComponent<Omit<OTPProps, "ref"> & import('react').RefAttributes<HTMLInputElement[]>>;
@@ -1,50 +1,65 @@
1
- import { jsxs as d, jsx as o } from "react/jsx-runtime";
2
- import { OneTimePasswordField as _, OneTimePasswordFieldInput as f, OneTimePasswordFieldHiddenInput as P } from "@radix-ui/react-one-time-password-field";
3
- import { forwardRef as O, useId as T, useRef as h, useEffect as y } from "react";
4
- import { Input as I } from "../Input/index.js";
5
- import { Error as v } from "../Error/index.js";
6
- import '../../assets/OTP.css';const w = "OTP-module__otp___EUcSo", N = "OTP-module__input___MEBPV", r = {
7
- otp: w,
1
+ import { jsxs as f, jsx as t } from "react/jsx-runtime";
2
+ import { OneTimePasswordField as y, OneTimePasswordFieldInput as T, OneTimePasswordFieldHiddenInput as I } from "@radix-ui/react-one-time-password-field";
3
+ import { forwardRef as v, useId as s, useMemo as w, useRef as N, useEffect as R } from "react";
4
+ import { Error as $ } from "../Error/index.js";
5
+ import { Input as E } from "../Input/index.js";
6
+ import { Label as B } from "../Label/index.js";
7
+ import { SuccessMessage as F } from "../SuccessMessage/index.js";
8
+ import '../../assets/OTP.css';const j = "OTP-module__otp___EUcSo", x = "OTP-module__input___MEBPV", A = "OTP-module__label___71Oaw", o = {
9
+ otp: j,
8
10
  "group-container": "OTP-module__group-container___rfrCo",
9
11
  "input-container": "OTP-module__input-container___-yRBL",
10
- input: N
11
- }, R = O(
12
- ({ error: i, passwordLength: s = 6, className: l = "", ...c }, n) => {
13
- const u = T(), a = h(/* @__PURE__ */ new Map()), p = (e, t) => {
14
- e ? a.current.set(t, e) : a.current.delete(t);
12
+ input: x,
13
+ label: A
14
+ }, C = v(
15
+ ({ error: e, successMessage: i, passwordLength: d = 6, className: b = "", label: l, ...m }, r) => {
16
+ const c = s(), p = s(), _ = s(), O = w(() => {
17
+ if (e)
18
+ return c;
19
+ if (i)
20
+ return p;
21
+ }, [e, c, i, p]), u = N(/* @__PURE__ */ new Map()), P = (a, n) => {
22
+ a ? u.current.set(n, a) : u.current.delete(n);
15
23
  };
16
- return y(() => {
17
- const e = Array.from(a.current.values());
18
- typeof n == "function" ? n(e) : n && (n.current = e);
19
- }, [s, n]), /* @__PURE__ */ d("div", { className: `${r.otp} ${l}`, children: [
20
- /* @__PURE__ */ d(
21
- _,
24
+ return R(() => {
25
+ const a = Array.from(u.current.values());
26
+ typeof r == "function" ? r(a) : r && (r.current = a);
27
+ }, [d, r]), /* @__PURE__ */ f("div", { className: `${o.otp} ${b}`, children: [
28
+ l && /* @__PURE__ */ t(B, { as: "p", id: _, className: o.label, "data-part": "label", children: l }),
29
+ /* @__PURE__ */ f(
30
+ y,
22
31
  {
23
- ...c,
24
- className: r["group-container"],
25
- "aria-invalid": !!i,
26
- "aria-describedby": i ? u : void 0,
32
+ ...m,
33
+ className: o["group-container"],
34
+ "data-part": "input-group",
35
+ "aria-invalid": !!e,
36
+ "aria-describedby": O,
37
+ "aria-labelledby": l ? _ : void 0,
27
38
  style: {
28
- "--cdp-web-otp-input-width": `${Math.floor(100 / s)}%`
39
+ "--cdp-web-otp-input-width": `${Math.floor(100 / d)}%`
29
40
  },
30
41
  children: [
31
- Array.from({ length: s }, (e, t) => /* @__PURE__ */ o("div", { className: r["input-container"], children: /* @__PURE__ */ o(f, { asChild: !0, children: /* @__PURE__ */ o(
32
- I,
42
+ Array.from({ length: d }, (a, n) => /* @__PURE__ */ t("div", { className: o["input-container"], "data-part": "input-container", children: /* @__PURE__ */ t(T, { asChild: !0, children: /* @__PURE__ */ t(
43
+ E,
33
44
  {
34
- name: `${c.name || "otp"}-${t}`,
35
- ref: (m) => p(m, t),
36
- className: r.input
45
+ name: `${m.name || "otp"}-${n}`,
46
+ ref: (h) => P(h, n),
47
+ className: o.input,
48
+ "aria-invalid": !!e,
49
+ "data-part": "input",
50
+ "data-success": !!i
37
51
  }
38
- ) }) }, t)),
39
- /* @__PURE__ */ o(P, {})
52
+ ) }) }, n)),
53
+ /* @__PURE__ */ t(I, {})
40
54
  ]
41
55
  }
42
56
  ),
43
- i && /* @__PURE__ */ o(v, { id: u, children: i })
57
+ !!e && /* @__PURE__ */ t($, { id: c, "data-part": "error", children: e }),
58
+ !!i && /* @__PURE__ */ t(F, { id: p, "data-part": "success", children: i })
44
59
  ] });
45
60
  }
46
61
  );
47
- R.displayName = "OTP";
62
+ C.displayName = "OTP";
48
63
  export {
49
- R as OTP
64
+ C as OTP
50
65
  };
@@ -0,0 +1,16 @@
1
+ import { APIError } from '@coinbase/cdp-hooks';
2
+ import { FormHTMLAttributes, Ref } from 'react';
3
+ export interface OTPFormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "children"> {
4
+ canResetOTP?: boolean;
5
+ error?: string | APIError;
6
+ isPending?: boolean;
7
+ onClearServerErrors?: () => void;
8
+ onOTPChange?: (value: string) => void;
9
+ onResendOTP?: () => void;
10
+ otp?: string;
11
+ otpInputsRef?: Ref<HTMLInputElement[]>;
12
+ passwordLength?: number;
13
+ resendCountdown?: number | null;
14
+ successMessage?: string;
15
+ }
16
+ export declare const OTPForm: ({ canResetOTP, error, isPending, onOTPChange, onResendOTP, otp, otpInputsRef, passwordLength, resendCountdown, successMessage, ...props }: OTPFormProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,76 @@
1
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
2
+ import "@coinbase/cdp-hooks";
3
+ import { Form as h, FormSubmit as u } from "@radix-ui/react-form";
4
+ import "react";
5
+ import { Button as v } from "../Button/index.js";
6
+ import { LoadingSpinner as F } from "../LoadingSpinner/index.js";
7
+ import { OTP as N } from "../OTP/index.js";
8
+ import { VisuallyHidden as g } from "../VisuallyHidden/index.js";
9
+ import { isApiError as P } from "../../utils/isApiError.js";
10
+ import '../../assets/OTPForm.css';const o = {
11
+ "otp-form": "OTPForm-module__otp-form___jQN4H",
12
+ "form-footer": "OTPForm-module__form-footer___JhfLr",
13
+ "server-state-wrapper": "OTPForm-module__server-state-wrapper___PS7UP",
14
+ "loading-spinner": "OTPForm-module__loading-spinner___fJRqe",
15
+ "resend-wrapper": "OTPForm-module__resend-wrapper___HeIR2",
16
+ "reset-timer": "OTPForm-module__reset-timer___MEkQh"
17
+ }, E = ({
18
+ canResetOTP: m,
19
+ error: t,
20
+ isPending: a,
21
+ onOTPChange: s,
22
+ onResendOTP: l,
23
+ otp: p,
24
+ otpInputsRef: n,
25
+ passwordLength: d,
26
+ resendCountdown: i,
27
+ successMessage: _,
28
+ ...c
29
+ }) => /* @__PURE__ */ r(h, { ...c, children: [
30
+ /* @__PURE__ */ e(
31
+ N,
32
+ {
33
+ ref: n,
34
+ name: "otp",
35
+ "aria-label": "Enter code",
36
+ autoSubmit: !0,
37
+ passwordLength: d || 6,
38
+ value: p,
39
+ error: P(t) ? t.message : t,
40
+ onChange: (f) => f.preventDefault(),
41
+ onValueChange: s,
42
+ className: o["otp-form"],
43
+ successMessage: _
44
+ }
45
+ ),
46
+ /* @__PURE__ */ r("div", { className: o["form-footer"], children: [
47
+ a && !m && /* @__PURE__ */ e("div", { className: o["server-state-wrapper"], children: a && !m && /* @__PURE__ */ e(F, { className: o["loading-spinner"] }) }),
48
+ /* @__PURE__ */ r("div", { className: o["resend-wrapper"], children: [
49
+ m && /* @__PURE__ */ e(u, { asChild: !0, children: /* @__PURE__ */ e(
50
+ v,
51
+ {
52
+ type: "button",
53
+ onClick: l,
54
+ isPending: a,
55
+ variant: "linkPrimary",
56
+ children: "Resend code"
57
+ }
58
+ ) }),
59
+ !m && i !== null && /* @__PURE__ */ e("div", { className: o["reset-timer"], children: /* @__PURE__ */ r("p", { children: [
60
+ "Resend code in ",
61
+ /* @__PURE__ */ r("span", { "aria-hidden": "true", children: [
62
+ i,
63
+ "s"
64
+ ] }),
65
+ /* @__PURE__ */ r(g, { children: [
66
+ i,
67
+ " ",
68
+ i === 1 ? "second" : "seconds"
69
+ ] })
70
+ ] }) })
71
+ ] })
72
+ ] })
73
+ ] });
74
+ export {
75
+ E as OTPForm
76
+ };
@@ -0,0 +1,14 @@
1
+ import { APIError } from '@coinbase/cdp-hooks';
2
+ import { FormHTMLAttributes, ReactNode } from 'react';
3
+ import { PhoneNumberInputProps } from '../PhoneNumberInput/PhoneNumberInput';
4
+ export interface PhoneNumberFormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "children"> {
5
+ countryCode: PhoneNumberInputProps["countryCode"];
6
+ error?: string | APIError;
7
+ isPending?: boolean;
8
+ onClearServerErrors?: () => void;
9
+ onCountryCodeChange: PhoneNumberInputProps["onCountryCodeChange"];
10
+ onPhoneNumberChange: PhoneNumberInputProps["onPhoneNumberChange"];
11
+ phoneNumber: PhoneNumberInputProps["phoneNumber"];
12
+ submitLabel?: ReactNode;
13
+ }
14
+ export declare const PhoneNumberForm: ({ className, countryCode, error, isPending, onCountryCodeChange, onPhoneNumberChange, phoneNumber, submitLabel, ...props }: PhoneNumberFormProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,68 @@
1
+ import { jsxs as _, jsx as e } from "react/jsx-runtime";
2
+ import "@coinbase/cdp-hooks";
3
+ import { Form as I, FormSubmit as F } from "@radix-ui/react-form";
4
+ import { useMemo as g } from "react";
5
+ import { Button as E } from "../Button/index.js";
6
+ import { Field as S } from "../Field/index.js";
7
+ import { PhoneNumberInput as x } from "../PhoneNumberInput/index.js";
8
+ import { ServerError as C } from "../ServerError/index.js";
9
+ import { usePhoneNumberValidators as U } from "../../hooks/usePhoneNumberValidators.js";
10
+ import '../../assets/PhoneNumberForm.css';const y = "PhoneNumberForm-module__form___xIcYN", t = {
11
+ form: y,
12
+ "server-error": "PhoneNumberForm-module__server-error___-98Dt"
13
+ }, V = ({
14
+ className: s = "",
15
+ countryCode: n = "US",
16
+ error: r,
17
+ isPending: u,
18
+ onCountryCodeChange: l,
19
+ onPhoneNumberChange: a,
20
+ phoneNumber: h,
21
+ submitLabel: d = "Continue",
22
+ ...p
23
+ }) => {
24
+ const {
25
+ isInvalidCountry: v,
26
+ isInvalidLength: b,
27
+ isInvalidNumber: c,
28
+ isInvalidTooShort: f,
29
+ isInvalidTooLong: P,
30
+ isInvalidPhoneNumberError: i
31
+ } = U({ countryCode: n }), o = g(() => r && i(r) ? "Use a valid phone number" : "", [r, i]), N = !!r && !o;
32
+ return /* @__PURE__ */ _(I, { className: `${t.form} ${s}`, ...p, children: [
33
+ /* @__PURE__ */ e(
34
+ S,
35
+ {
36
+ label: "Phone number",
37
+ name: "phone",
38
+ inlineError: o,
39
+ validators: [
40
+ ["valueMissing", "Phone number is required"],
41
+ ["typeMismatch", "Use a valid phone number"],
42
+ [c, "Use a valid phone number"],
43
+ [v, "Country is not supported"],
44
+ [f, "Phone number is too short"],
45
+ [P, "Phone number is too long"],
46
+ [b, "Phone number is the wrong length"]
47
+ ],
48
+ children: (m) => /* @__PURE__ */ e(
49
+ x,
50
+ {
51
+ "aria-invalid": !(m === void 0 || m.valid) || !!o,
52
+ autoComplete: "tel-national",
53
+ phoneNumber: h,
54
+ onPhoneNumberChange: a,
55
+ countryCode: n,
56
+ onCountryCodeChange: l,
57
+ required: !0
58
+ }
59
+ )
60
+ }
61
+ ),
62
+ N && /* @__PURE__ */ e(C, { error: r, className: t["server-error"] }),
63
+ /* @__PURE__ */ e(F, { asChild: !0, children: /* @__PURE__ */ e(E, { type: "submit", isPending: u, children: d }) })
64
+ ] });
65
+ };
66
+ export {
67
+ V as PhoneNumberForm
68
+ };
@@ -0,0 +1,2 @@
1
+ import { Metadata } from 'libphonenumber-js';
2
+ export declare const PhoneNumberMetadata: Metadata;
@@ -0,0 +1,5 @@
1
+ import { Metadata as t } from "libphonenumber-js";
2
+ const e = new t();
3
+ export {
4
+ e as PhoneNumberMetadata
5
+ };
@@ -0,0 +1,10 @@
1
+ import { CountryCode } from 'libphonenumber-js';
2
+ import { InputHTMLAttributes } from 'react';
3
+ import { PhoneNumber } from '../../utils/parseValuesFromPhoneNumber';
4
+ export interface PhoneNumberInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "onChange"> {
5
+ onCountryCodeChange: (newCountry: CountryCode) => void;
6
+ countryCode?: CountryCode;
7
+ onPhoneNumberChange: (phoneNumber: PhoneNumber) => void;
8
+ phoneNumber: PhoneNumber;
9
+ }
10
+ export declare const PhoneNumberInput: ({ autoComplete, className, countryCode, onCountryCodeChange, onPhoneNumberChange, phoneNumber, ...props }: PhoneNumberInputProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,76 @@
1
+ import { jsxs as o, jsx as i } from "react/jsx-runtime";
2
+ import "libphonenumber-js";
3
+ import { useCallback as f, useEffect as P } from "react";
4
+ import { Input as y } from "../Input/index.js";
5
+ import { VisuallyHidden as C } from "../VisuallyHidden/index.js";
6
+ import { countries as $ } from "../../data/countries.js";
7
+ import { usePhoneNumberFormatter as j } from "./usePhoneNumberFormatter.js";
8
+ import '../../assets/PhoneNumberInput.css';const U = "PhoneNumberInput-module__invalid___qs2M2", V = "PhoneNumberInput-module__success___awnfm", k = "PhoneNumberInput-module__input___ZkUYh", l = {
9
+ "phone-number-input": "PhoneNumberInput-module__phone-number-input___c7QxX",
10
+ invalid: U,
11
+ success: V,
12
+ input: k,
13
+ "country-calling-code": "PhoneNumberInput-module__country-calling-code___xUjx5"
14
+ }, M = ({
15
+ autoComplete: a = "tel-national",
16
+ className: h = "",
17
+ countryCode: s = "US",
18
+ onCountryCodeChange: r,
19
+ onPhoneNumberChange: c,
20
+ phoneNumber: u,
21
+ ...t
22
+ }) => {
23
+ const {
24
+ formatBeforePhoneNumberChange: m,
25
+ formatBeforeCountryCodeChange: d,
26
+ placeholder: v,
27
+ formattedDisplayNumber: b
28
+ } = j(u.value, s), g = f(
29
+ (e) => {
30
+ let n = e.target.value.replace(/\D/g, "");
31
+ n === u.value && (n = n.slice(0, -1));
32
+ const x = m(n);
33
+ c?.(x);
34
+ },
35
+ [m, c, u]
36
+ ), _ = f(
37
+ (e) => {
38
+ const n = d(e);
39
+ r(e), c?.(n);
40
+ },
41
+ [d, r, c]
42
+ ), p = $.find((e) => e.code === s), I = t["aria-invalid"] && t["aria-invalid"] !== "false", N = t["data-success"] && t["data-success"] !== "false";
43
+ return P(() => {
44
+ _(s);
45
+ }, [s, _]), /* @__PURE__ */ o(
46
+ "div",
47
+ {
48
+ className: `${l["phone-number-input"]} ${I ? l.invalid : ""} ${N ? l.success : ""} ${h}`,
49
+ children: [
50
+ p && /* @__PURE__ */ i(w, { country: p }),
51
+ /* @__PURE__ */ i(
52
+ y,
53
+ {
54
+ ...t,
55
+ className: l.input,
56
+ autoComplete: a,
57
+ onChange: g,
58
+ placeholder: v,
59
+ type: "tel",
60
+ value: b
61
+ }
62
+ )
63
+ ]
64
+ }
65
+ );
66
+ }, w = ({ country: a }) => /* @__PURE__ */ o("span", { className: l["country-calling-code"], children: [
67
+ /* @__PURE__ */ i("span", { "aria-hidden": "true", children: a.flag }),
68
+ /* @__PURE__ */ i(C, { children: a.name }),
69
+ /* @__PURE__ */ o("span", { children: [
70
+ "+",
71
+ a.callingCode
72
+ ] })
73
+ ] });
74
+ export {
75
+ M as PhoneNumberInput
76
+ };
@@ -0,0 +1,8 @@
1
+ import { CountryCode } from 'libphonenumber-js';
2
+ type MaskFormatOverride = {
3
+ prefix?: string;
4
+ maxLength?: number;
5
+ normalizer?: (value: string) => string;
6
+ };
7
+ export declare const getMaskOverride: (countryCode?: CountryCode) => MaskFormatOverride;
8
+ export {};
@@ -0,0 +1,61 @@
1
+ import "libphonenumber-js";
2
+ import { nonThrowingGetCountryCallingCode as e } from "../../data/countries.js";
3
+ const n = (r) => r.startsWith("1") ? r.slice(1) : r, i = {
4
+ 234: {
5
+ /**
6
+ * libphonenumber-js bug:
7
+ *
8
+ * Nigerial phone numbers require a 0 prefix for the mask to work.
9
+ */
10
+ prefix: "0"
11
+ },
12
+ 33: {
13
+ /**
14
+ * libphonenumber-js bug:
15
+ *
16
+ * French phone numbers require a 0 prefix for the mask to work.
17
+ * On top of that, libphonenumber does not take that 0 into account on maxLength.
18
+ * This means that if the user types a number with the 0, the number will be cropped short.
19
+ *
20
+ * Example: 01 23 45 67 89 would be cropped to 01 23 45 67 8.
21
+ * Users could overcome this by omiting the 0, but this would mean the mask formatting would
22
+ * not work, and the input would look plain 123456789.
23
+ */
24
+ prefix: "0",
25
+ maxLength: 10
26
+ },
27
+ 1: {
28
+ /**
29
+ * libphonenumber-js bug:
30
+ *
31
+ * Calling code 1 Phone numbers cannot start with 1.
32
+ * If we allow them to, the masks will show 1 (234) 567-890, and limit the length to 10
33
+ * The above is an invalid US number though, as phone numbers need to have 10 digits EXCLUDING
34
+ * the internation code 1.
35
+ *
36
+ * This does not introduce a bug because we already have the Country Code picker, so adding
37
+ * the international code to the Phone input is a user mistake.
38
+ */
39
+ normalizer: n
40
+ },
41
+ 44: {
42
+ /**
43
+ * libphonenumber-js bug:
44
+ *
45
+ * GB has max 10 digit phone numbers AFTER A LEADING 0 (so actually 11)
46
+ * On top of that, the libphonenumber-js mask does not work without the leading 0.
47
+ *
48
+ * This will enforce adding the leading 0, and override the max length to 11 instead of 10.
49
+ */
50
+ prefix: "0",
51
+ maxLength: 11
52
+ }
53
+ }, a = (r) => {
54
+ if (!r)
55
+ return {};
56
+ const t = e(r);
57
+ return t ? i[t] ?? {} : {};
58
+ };
59
+ export {
60
+ a as getMaskOverride
61
+ };
@@ -0,0 +1,7 @@
1
+ import { CountryCode } from 'libphonenumber-js';
2
+ export declare const usePhoneNumberFormatter: (phoneNumber: string, countryCode: CountryCode | undefined) => {
3
+ formatBeforePhoneNumberChange: (inputPhoneNumber: string) => import('../../utils/parseValuesFromPhoneNumber').PhoneNumber;
4
+ formatBeforeCountryCodeChange: (newCountryCode: CountryCode) => import('../../utils/parseValuesFromPhoneNumber').PhoneNumber;
5
+ placeholder: string | undefined;
6
+ formattedDisplayNumber: string;
7
+ };
@@ -0,0 +1,52 @@
1
+ import { parseIncompletePhoneNumber as I, getExampleNumber as l, AsYouType as K } from "libphonenumber-js";
2
+ import { useCallback as S, useMemo as N } from "react";
3
+ import { parseValuesFromPhoneNumber as B } from "../../utils/parseValuesFromPhoneNumber.js";
4
+ import { getMaskOverride as L } from "./maskOverride.js";
5
+ import { PhoneNumberMetadata as G } from "./PhoneNumberMetadata.js";
6
+ const i = { AC: "40123", AD: "312345", AE: "501234567", AF: "701234567", AG: "2684641234", AI: "2642351234", AL: "672123456", AM: "77123456", AO: "923123456", AR: "91123456789", AS: "6847331234", AT: "664123456", AU: "412345678", AW: "5601234", AX: "412345678", AZ: "401234567", BA: "61123456", BB: "2462501234", BD: "1812345678", BE: "470123456", BF: "70123456", BG: "43012345", BH: "36001234", BI: "79561234", BJ: "0195123456", BL: "690001234", BM: "4413701234", BN: "7123456", BO: "71234567", BQ: "3181234", BR: "11961234567", BS: "2423591234", BT: "17123456", BW: "71123456", BY: "294911911", BZ: "6221234", CA: "5062345678", CC: "412345678", CD: "991234567", CF: "70012345", CG: "061234567", CH: "781234567", CI: "0123456789", CK: "71234", CL: "221234567", CM: "671234567", CN: "13123456789", CO: "3211234567", CR: "83123456", CU: "51234567", CV: "9911234", CW: "95181234", CX: "412345678", CY: "96123456", CZ: "601123456", DE: "15123456789", DJ: "77831001", DK: "34412345", DM: "7672251234", DO: "8092345678", DZ: "551234567", EC: "991234567", EE: "51234567", EG: "1001234567", EH: "650123456", ER: "7123456", ES: "612345678", ET: "911234567", FI: "412345678", FJ: "7012345", FK: "51234", FM: "3501234", FO: "211234", FR: "612345678", GA: "06031234", GB: "7400123456", GD: "4734031234", GE: "555123456", GF: "694201234", GG: "7781123456", GH: "231234567", GI: "57123456", GL: "221234", GM: "3012345", GN: "601123456", GP: "690001234", GQ: "222123456", GR: "6912345678", GT: "51234567", GU: "6713001234", GW: "955012345", GY: "6091234", HK: "51234567", HN: "91234567", HR: "921234567", HT: "34101234", HU: "201234567", ID: "812345678", IE: "850123456", IL: "502345678", IM: "7924123456", IN: "8123456789", IO: "3801234", IQ: "7912345678", IR: "9123456789", IS: "6111234", IT: "3123456789", JE: "7797712345", JM: "8762101234", JO: "790123456", JP: "9012345678", KE: "712123456", KG: "700123456", KH: "91234567", KI: "72001234", KM: "3212345", KN: "8697652917", KP: "1921234567", KR: "1020000000", KW: "50012345", KY: "3453231234", KZ: "7710009998", LA: "2023123456", LB: "71123456", LC: "7582845678", LI: "660234567", LK: "712345678", LR: "770123456", LS: "50123456", LT: "61234567", LU: "628123456", LV: "21234567", LY: "912345678", MA: "650123456", MC: "612345678", MD: "62112345", ME: "67622901", MF: "690001234", MG: "321234567", MH: "2351234", MK: "72345678", ML: "65012345", MM: "92123456", MN: "88123456", MO: "66123456", MP: "6702345678", MQ: "696201234", MR: "22123456", MS: "6644923456", MT: "96961234", MU: "52512345", MV: "7712345", MW: "991234567", MX: "2221234567", MY: "123456789", MZ: "821234567", NA: "811234567", NC: "751234", NE: "93123456", NF: "381234", NG: "8021234567", NI: "81234567", NL: "612345678", NO: "40612345", NP: "9841234567", NR: "5551234", NU: "8884012", NZ: "211234567", OM: "92123456", PA: "61234567", PE: "912345678", PF: "87123456", PG: "70123456", PH: "9051234567", PK: "3012345678", PL: "512345678", PM: "551234", PR: "7872345678", PS: "599123456", PT: "912345678", PW: "6201234", PY: "961456789", QA: "33123456", RE: "692123456", RO: "712034567", RS: "601234567", RU: "9123456789", RW: "720123456", SA: "512345678", SB: "7421234", SC: "2510123", SD: "911231234", SE: "701234567", SG: "81234567", SH: "51234", SI: "31234567", SJ: "41234567", SK: "912123456", SL: "25123456", SM: "66661212", SN: "701234567", SO: "71123456", SR: "7412345", SS: "977123456", ST: "9812345", SV: "70123456", SX: "7215205678", SY: "944567890", SZ: "76123456", TA: "8999", TC: "6492311234", TD: "63012345", TG: "90112345", TH: "812345678", TJ: "917123456", TK: "7290", TL: "77212345", TM: "66123456", TN: "20123456", TO: "7715123", TR: "5012345678", TT: "8682911234", TV: "901234", TW: "912345678", TZ: "621234567", UA: "501234567", UG: "712345678", US: "2015550123", UY: "94231234", UZ: "912345678", VA: "3123456789", VC: "7844301234", VE: "4121234567", VG: "2843001234", VI: "3406421234", VN: "912345678", VU: "5912345", WF: "821234", WS: "7212345", XK: "43201234", YE: "712345678", YT: "639012345", ZA: "711234567", ZM: "955123456", ZW: "712345678" }, u = (n, r) => {
7
+ const s = S(() => {
8
+ if (!G.numberingPlan || !r)
9
+ return 20;
10
+ const { maxLength: e } = L(r);
11
+ return e || (Math.max(...G.numberingPlan.possibleLengths()) ?? 20);
12
+ }, [r]), m = S(
13
+ (e, t) => {
14
+ const { prefix: M, normalizer: a } = L(t);
15
+ if (M && e && !e.startsWith(M))
16
+ return M + e;
17
+ const E = a ? a(e) : e;
18
+ return I(E);
19
+ },
20
+ []
21
+ ), T = S(
22
+ (e) => {
23
+ const t = s(), a = m(e, r).slice(0, t);
24
+ return B(a, r);
25
+ },
26
+ [r, s, m]
27
+ ), A = S(
28
+ (e) => {
29
+ G.selectNumberingPlan(e);
30
+ const t = s(), M = n.slice(0, t), a = m(M, e);
31
+ return B(a, e);
32
+ },
33
+ [n, s, m]
34
+ ), o = N(() => r ? l(r ?? "US", i)?.formatNational().replace(/\d/g, "0") : "", [r]), P = N(() => r ? new K(r).input(n) : n, [r, n]);
35
+ return N(
36
+ () => ({
37
+ formatBeforePhoneNumberChange: T,
38
+ formatBeforeCountryCodeChange: A,
39
+ placeholder: o,
40
+ formattedDisplayNumber: P
41
+ }),
42
+ [
43
+ A,
44
+ T,
45
+ P,
46
+ o
47
+ ]
48
+ );
49
+ };
50
+ export {
51
+ u as usePhoneNumberFormatter
52
+ };
@@ -1,12 +1,12 @@
1
1
  import { jsx as s } from "react/jsx-runtime";
2
2
  import "@coinbase/cdp-hooks";
3
3
  import { forwardRef as t } from "react";
4
- import { isApiError as p } from "../../utils/isApiError.js";
5
- import { Error as f } from "../Error/index.js";
4
+ import { Error as p } from "../Error/index.js";
5
+ import { isApiError as f } from "../../utils/isApiError.js";
6
6
  const a = t(
7
7
  ({ error: r, id: o, className: e = "" }, m) => {
8
- const i = p(r) ? r.errorMessage : r;
9
- return /* @__PURE__ */ s(f, { ref: m, id: o, className: e, children: i });
8
+ const i = f(r) ? r.errorMessage : r;
9
+ return /* @__PURE__ */ s(p, { ref: m, id: o, className: e, children: i });
10
10
  }
11
11
  );
12
12
  a.displayName = "ServerError";