From 9cce76503a1e3bdcab310d5b8b606b562b387781 Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Wed, 29 Oct 2025 15:04:15 +0000 Subject: [PATCH 1/2] fix(react,angular): forgot password link inline with the label --- .../src/lib/auth/forms/sign-in-auth-form.ts | 2 +- .../angular/src/lib/components/form.spec.ts | 40 ++++++++++++++++++- packages/angular/src/lib/components/form.ts | 24 ++++++----- .../src/auth/forms/sign-in-auth-form.tsx | 18 +++++---- packages/react/src/components/form.test.tsx | 30 ++++++++++++++ packages/react/src/components/form.tsx | 9 ++++- packages/styles/src/base.css | 10 +++-- 7 files changed, 109 insertions(+), 24 deletions(-) diff --git a/packages/angular/src/lib/auth/forms/sign-in-auth-form.ts b/packages/angular/src/lib/auth/forms/sign-in-auth-form.ts index 89bd9954..d91ad501 100644 --- a/packages/angular/src/lib/auth/forms/sign-in-auth-form.ts +++ b/packages/angular/src/lib/auth/forms/sign-in-auth-form.ts @@ -55,7 +55,7 @@ import {
@if (forgotPassword) { - } diff --git a/packages/angular/src/lib/components/form.spec.ts b/packages/angular/src/lib/components/form.spec.ts index 3c1d60be..d7bf7fb2 100644 --- a/packages/angular/src/lib/components/form.spec.ts +++ b/packages/angular/src/lib/components/form.spec.ts @@ -16,8 +16,15 @@ import { render, screen } from "@testing-library/angular"; import { Component, signal } from "@angular/core"; - -import { FormMetadataComponent, FormActionComponent, FormSubmitComponent, FormErrorMessageComponent } from "./form"; +import { injectForm, TanStackAppField } from "@tanstack/angular-form"; + +import { + FormMetadataComponent, + FormActionComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormInputComponent, +} from "./form"; import { ButtonComponent } from "./button"; @Component({ @@ -164,6 +171,35 @@ describe("Form Components", () => { }); }); + describe("", () => { + @Component({ + template: ` + + + + `, + standalone: true, + imports: [FormInputComponent, TanStackAppField, FormActionComponent], + }) + class TestFormInputHostComponent { + form = injectForm({ + defaultValues: { + test: "", + }, + }); + } + + it("renders action content when provided", async () => { + await render(TestFormInputHostComponent, { + imports: [TestFormInputHostComponent], + }); + + const actionButton = screen.getByTestId("test-action"); + expect(actionButton).toBeTruthy(); + expect(actionButton).toHaveTextContent("Action"); + }); + }); + describe("", () => { it("renders error message when onSubmit error exists", async () => { await render(TestFormErrorMessageHostComponent); diff --git a/packages/angular/src/lib/components/form.ts b/packages/angular/src/lib/components/form.ts index 44b23b30..b68f2527 100644 --- a/packages/angular/src/lib/components/form.ts +++ b/packages/angular/src/lib/components/form.ts @@ -30,15 +30,21 @@ export class FormMetadataComponent { imports: [FormMetadataComponent], template: ` diff --git a/packages/react/src/auth/forms/sign-in-auth-form.tsx b/packages/react/src/auth/forms/sign-in-auth-form.tsx index b592e88f..adad5441 100644 --- a/packages/react/src/auth/forms/sign-in-auth-form.tsx +++ b/packages/react/src/auth/forms/sign-in-auth-form.tsx @@ -95,13 +95,17 @@ export function SignInAuthForm({ onSignIn, onForgotPasswordClick, onRegisterClic
{(field) => ( - - {onForgotPasswordClick ? ( - - {getTranslation(ui, "labels", "forgotPassword")} - - ) : null} - + + {getTranslation(ui, "labels", "forgotPassword")} + + ) : null + } + /> )}
diff --git a/packages/react/src/components/form.test.tsx b/packages/react/src/components/form.test.tsx index 4a4a1f64..1568c34f 100644 --- a/packages/react/src/components/form.test.tsx +++ b/packages/react/src/components/form.test.tsx @@ -90,6 +90,36 @@ describe("form export", () => { expect(screen.getByTestId("test-child")).toBeInTheDocument(); }); + it("should render the Input action prop when provided", () => { + const { result } = renderHook(() => { + return form.useAppForm({ + defaultValues: { foo: "bar" }, + }); + }); + + const hook = result.current; + + render( + + + {(field) => ( + + Action + + } + /> + )} + + + ); + + expect(screen.getByTestId("test-action")).toBeInTheDocument(); + expect(screen.getByTestId("test-action")).toHaveTextContent("Action"); + }); + it("should render the Input metadata when available", async () => { const { result } = renderHook(() => { return form.useAppForm({ diff --git a/packages/react/src/components/form.tsx b/packages/react/src/components/form.tsx index 2cf57dd9..7b10e5d7 100644 --- a/packages/react/src/components/form.tsx +++ b/packages/react/src/components/form.tsx @@ -19,12 +19,17 @@ function FieldMetadata({ className, ...props }: ComponentProps<"div"> & { field: ); } -function Input(props: PropsWithChildren & { label: string; before?: ReactNode }>) { +function Input( + props: PropsWithChildren & { label: string; before?: ReactNode; action?: ReactNode }> +) { const field = useFieldContext(); return (