Skip to content

Commit 4edd8f1

Browse files
committed
refactor: Align PhoneAuth{Screen,Form} with API spec
1 parent e765077 commit 4edd8f1

File tree

3 files changed

+34
-30
lines changed

3 files changed

+34
-30
lines changed

packages/react/src/auth/forms/phone-form.test.tsx renamed to packages/react/src/auth/forms/phone-auth-form.test.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import { describe, it, expect, vi, beforeEach } from "vitest";
1818
import { render, screen, fireEvent } from "@testing-library/react";
19-
import { PhoneForm } from "../../../../src/auth/forms/phone-form";
19+
import { PhoneAuthForm } from "./phone-auth-form";
2020
import { act } from "react";
2121

2222
// Mock Firebase Auth
@@ -156,7 +156,7 @@ vi.mock("../../../../src/components/country-selector", () => ({
156156
// Import the actual functions after mocking
157157
import { signInWithPhoneNumber } from "@firebase-ui/core";
158158

159-
describe("PhoneForm", () => {
159+
describe("PhoneAuthForm", () => {
160160
beforeEach(() => {
161161
vi.clearAllMocks();
162162
// Reset the global state
@@ -165,7 +165,7 @@ describe("PhoneForm", () => {
165165
});
166166

167167
it("renders the phone number form initially", () => {
168-
render(<PhoneForm />);
168+
render(<PhoneAuthForm />);
169169

170170
expect(screen.getByRole("textbox", { name: /phone number/i })).toBeInTheDocument();
171171
expect(screen.getByTestId("country-selector")).toBeInTheDocument();
@@ -174,7 +174,7 @@ describe("PhoneForm", () => {
174174
});
175175

176176
it("attempts to send verification code when phone number is submitted", async () => {
177-
render(<PhoneForm />);
177+
render(<PhoneAuthForm />);
178178

179179
// Get the submit button
180180
const submitButton = screen.getByTestId("submit-button");
@@ -208,7 +208,7 @@ describe("PhoneForm", () => {
208208
(mockError as any).code = "auth/invalid-phone-number";
209209
(signInWithPhoneNumber as unknown as ReturnType<typeof vi.fn>).mockRejectedValueOnce(mockError);
210210

211-
render(<PhoneForm />);
211+
render(<PhoneAuthForm />);
212212

213213
// Get the submit button
214214
const submitButton = screen.getByTestId("submit-button");
@@ -236,7 +236,7 @@ describe("PhoneForm", () => {
236236
});
237237

238238
it("validates on blur for the first time", async () => {
239-
render(<PhoneForm />);
239+
render(<PhoneAuthForm />);
240240

241241
const phoneInput = screen.getByRole("textbox", { name: /phone number/i });
242242

@@ -249,7 +249,7 @@ describe("PhoneForm", () => {
249249
});
250250

251251
it("validates on input after first blur", async () => {
252-
render(<PhoneForm />);
252+
render(<PhoneAuthForm />);
253253

254254
const phoneInput = screen.getByRole("textbox", { name: /phone number/i });
255255

packages/react/src/auth/forms/phone-form.tsx renamed to packages/react/src/auth/forms/phone-auth-form.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { useForm } from "@tanstack/react-form";
3030
import { ConfirmationResult, RecaptchaVerifier } from "firebase/auth";
3131
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3232
import { z } from "zod";
33-
import { useAuth, useUI } from "~/hooks";
33+
import { useUI } from "~/hooks";
3434
import { Button } from "../../components/button";
3535
import { CountrySelector } from "../../components/country-selector";
3636
import { FieldInfo } from "../../components/field-info";
@@ -46,6 +46,7 @@ interface PhoneNumberFormProps {
4646
function PhoneNumberForm({ onSubmit, formError, recaptchaVerifier, recaptchaContainerRef }: PhoneNumberFormProps) {
4747
const ui = useUI();
4848

49+
// TODO(ehesp): How does this support allowed countries?
4950
const [selectedCountry, setSelectedCountry] = useState<CountryData>(countryData[0]);
5051
const [firstValidationOccured, setFirstValidationOccured] = useState(false);
5152

@@ -71,6 +72,8 @@ function PhoneNumberForm({ onSubmit, formError, recaptchaVerifier, recaptchaCont
7172
},
7273
});
7374

75+
// TODO(ehesp): Country data onChange types are not matching
76+
7477
return (
7578
<form
7679
className="fui-form"
@@ -91,7 +94,7 @@ function PhoneNumberForm({ onSubmit, formError, recaptchaVerifier, recaptchaCont
9194
<div className="fui-phone-input">
9295
<CountrySelector
9396
value={selectedCountry}
94-
onChange={setSelectedCountry}
97+
onChange={(country) => setSelectedCountry(country as CountryData)}
9598
className="fui-phone-input__country-selector"
9699
/>
97100
<input
@@ -291,13 +294,12 @@ function VerificationForm({
291294
);
292295
}
293296

294-
export interface PhoneFormProps {
297+
export type PhoneAuthFormProps = {
295298
resendDelay?: number;
296299
}
297300

298-
export function PhoneForm({ resendDelay = 30 }: PhoneFormProps) {
301+
export function PhoneAuthForm({ resendDelay = 30 }: PhoneAuthFormProps) {
299302
const ui = useUI();
300-
const auth = useAuth(ui);
301303

302304
const [formError, setFormError] = useState<string | null>(null);
303305
const [confirmationResult, setConfirmationResult] = useState<ConfirmationResult | null>(null);
@@ -310,8 +312,9 @@ export function PhoneForm({ resendDelay = 30 }: PhoneFormProps) {
310312
useEffect(() => {
311313
if (!recaptchaContainerRef.current) return;
312314

313-
const verifier = new RecaptchaVerifier(auth, recaptchaContainerRef.current, {
314-
size: ui.recaptchaMode ?? "normal",
315+
const verifier = new RecaptchaVerifier(ui.auth, recaptchaContainerRef.current, {
316+
// size: ui.recaptchaMode ?? "normal", TODO(ehesp): Get this from the useRecaptchaVerifier hook once implemented
317+
size: "normal",
315318
});
316319

317320
setRecaptchaVerifier(verifier);
@@ -320,7 +323,7 @@ export function PhoneForm({ resendDelay = 30 }: PhoneFormProps) {
320323
verifier.clear();
321324
setRecaptchaVerifier(null);
322325
};
323-
}, [auth, ui.recaptchaMode]);
326+
}, [ui]);
324327

325328
const handlePhoneSubmit = async (number: string) => {
326329
setFormError(null);
@@ -356,8 +359,9 @@ export function PhoneForm({ resendDelay = 30 }: PhoneFormProps) {
356359
recaptchaVerifier.clear();
357360
}
358361

359-
const verifier = new RecaptchaVerifier(auth, recaptchaContainerRef.current, {
360-
size: ui.recaptchaMode ?? "normal",
362+
const verifier = new RecaptchaVerifier(ui.auth, recaptchaContainerRef.current, {
363+
// size: ui.recaptchaMode ?? "normal", // TODO(ehesp): Get this from the useRecaptchaVerifier hook once implemented
364+
size: "normal",
361365
});
362366
setRecaptchaVerifier(verifier);
363367

packages/react/src/auth/screens/phone-auth-screen.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ import type { PropsWithChildren } from "react";
1818
import { getTranslation } from "@firebase-ui/core";
1919
import { Divider } from "~/components/divider";
2020
import { useUI } from "~/hooks";
21-
import { Card, CardHeader, CardSubtitle, CardTitle } from "../../components/card";
22-
import { PhoneForm } from "../forms/phone-form";
21+
import { Card, CardContent, CardHeader, CardSubtitle, CardTitle } from "../../components/card";
22+
import { PhoneAuthForm, type PhoneAuthFormProps } from "../forms/phone-auth-form";
2323

24-
export type PhoneAuthScreenProps = PropsWithChildren<{
25-
resendDelay?: number;
26-
}>;
24+
export type PhoneAuthScreenProps = PropsWithChildren<PhoneAuthFormProps>;
2725

28-
export function PhoneAuthScreen({ children, resendDelay }: PhoneAuthScreenProps) {
26+
export function PhoneAuthScreen({ children, ...props }: PhoneAuthScreenProps) {
2927
const ui = useUI();
3028

3129
const titleText = getTranslation(ui, "labels", "signIn");
@@ -38,13 +36,15 @@ export function PhoneAuthScreen({ children, resendDelay }: PhoneAuthScreenProps)
3836
<CardTitle>{titleText}</CardTitle>
3937
<CardSubtitle>{subtitleText}</CardSubtitle>
4038
</CardHeader>
41-
<PhoneForm resendDelay={resendDelay} />
42-
{children ? (
43-
<>
44-
<Divider>{getTranslation(ui, "messages", "dividerOr")}</Divider>
45-
<div className="space-y-4">{children}</div>
46-
</>
47-
) : null}
39+
<CardContent>
40+
<PhoneAuthForm {...props} />
41+
{children ? (
42+
<>
43+
<Divider>{getTranslation(ui, "messages", "dividerOr")}</Divider>
44+
<div className="space-y-4">{children}</div>
45+
</>
46+
) : null}
47+
</CardContent>
4848
</Card>
4949
</div>
5050
);

0 commit comments

Comments
 (0)