diff --git a/packages/react/src/patterns/F0Form/F0Form.tsx b/packages/react/src/patterns/F0Form/F0Form.tsx index 005e4d3536..c6509690ea 100644 --- a/packages/react/src/patterns/F0Form/F0Form.tsx +++ b/packages/react/src/patterns/F0Form/F0Form.tsx @@ -132,6 +132,7 @@ function F0FormPerSection( } = props const showSectionsSidepanel = styling?.showSectionsSidepanel ?? false + const noPadding = styling?.noPadding ?? false const sectionIds = useMemo(() => Object.keys(schema), [schema]) @@ -218,7 +219,11 @@ function F0FormPerSection( ) } - return
{content}
+ return ( +
+ {content} +
+ ) } /** @@ -538,6 +543,7 @@ function F0FormSingleSchema( // Resolve styling configuration const showSectionsSidepanel = styling?.showSectionsSidepanel ?? false + const noPadding = styling?.noPadding ?? false // Resolve submit type from config const isActionBar = submitConfig?.type === "action-bar" @@ -1167,7 +1173,9 @@ function F0FormSingleSchema( ) : ( -
{formContent}
+
+ {formContent} +
)} {!hideActionBar && ( diff --git a/packages/react/src/patterns/F0Form/__stories__/F0Form.mdx b/packages/react/src/patterns/F0Form/__stories__/F0Form.mdx index ccdc22c68a..7b74823730 100644 --- a/packages/react/src/patterns/F0Form/__stories__/F0Form.mdx +++ b/packages/react/src/patterns/F0Form/__stories__/F0Form.mdx @@ -403,6 +403,23 @@ Use `sections` to split a long form into named groups with independent submit bu +## Styling + +The optional `styling` config controls the form layout: + +- `showSectionsSidepanel` — render a sticky table-of-contents sidebar for the form's sections (see the example above). +- `noPadding` — remove the default `p-4` padding around the form content. Use it when embedding the form flush inside a host surface (e.g. an AI canvas panel) that already provides its own spacing. Defaults to `false`, so existing forms are unaffected. + +```tsx + +``` + ## Conditional rendering Use `renderIf` to show or hide fields based on the values of other fields. diff --git a/packages/react/src/patterns/F0Form/__tests__/F0Form.test.tsx b/packages/react/src/patterns/F0Form/__tests__/F0Form.test.tsx index abb47ae6b7..34df68eaf0 100644 --- a/packages/react/src/patterns/F0Form/__tests__/F0Form.test.tsx +++ b/packages/react/src/patterns/F0Form/__tests__/F0Form.test.tsx @@ -3662,6 +3662,72 @@ describe("F0Form sections sidepanel scroll", () => { expect(stickyElement).toBeInTheDocument() expect(stickyElement).toHaveClass("top-0") }) + + it("keeps the default content padding (p-4) when noPadding is not set", () => { + const formSchema = z.object({ + name: f0FormField(z.string(), { label: "Name" }), + }) + + const { container } = render( + ({ success: true })} + /> + ) + + expect(container.querySelector(".justify-center.p-4")).toBeInTheDocument() + }) + + it("removes the content padding when styling.noPadding is true (single schema)", () => { + const formSchema = z.object({ + name: f0FormField(z.string(), { label: "Name" }), + }) + + const { container } = render( + ({ success: true })} + styling={{ noPadding: true }} + /> + ) + + // The centered wrapper is still there, just without the p-4 padding. + expect( + container.querySelector(".justify-center.p-4") + ).not.toBeInTheDocument() + expect(container.querySelector(".justify-center")).toBeInTheDocument() + }) + + it("removes the content padding when styling.noPadding is true (per-section schema)", () => { + const formSchema = { + personal: z.object({ + name: f0FormField(z.string(), { label: "Name" }), + }), + } + + const sections: Record = { + personal: { title: "Personal" }, + } + + const { container } = render( + ({ success: true })} + sections={sections} + styling={{ noPadding: true }} + /> + ) + + expect( + container.querySelector(".justify-center.p-4") + ).not.toBeInTheDocument() + }) }) describe("F0Form renderIf hidden field layout", () => { diff --git a/packages/react/src/patterns/F0Form/types.ts b/packages/react/src/patterns/F0Form/types.ts index e15515ded0..e835d41eb2 100644 --- a/packages/react/src/patterns/F0Form/types.ts +++ b/packages/react/src/patterns/F0Form/types.ts @@ -252,6 +252,11 @@ export interface F0FormStylingConfig { * @default false */ showSectionsSidepanel?: boolean + /** + * Removes the default padding around the form content. + * @default false + */ + noPadding?: boolean } /**