diff --git a/.changeset/layer-dialog-separator.md b/.changeset/layer-dialog-separator.md new file mode 100644 index 000000000..ce95d64f9 --- /dev/null +++ b/.changeset/layer-dialog-separator.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/kumo": patch +--- + +Add a full-width `LayerDialog.Separator` for dividing sections of dialog body content. diff --git a/packages/kumo-docs-astro/src/components/demos/LayerDialogDemo.tsx b/packages/kumo-docs-astro/src/components/demos/LayerDialogDemo.tsx index b9dde15b2..f78e1123b 100644 --- a/packages/kumo-docs-astro/src/components/demos/LayerDialogDemo.tsx +++ b/packages/kumo-docs-astro/src/components/demos/LayerDialogDemo.tsx @@ -180,6 +180,34 @@ export function LayerDialogSearchDemo() { ); } +export function LayerDialogSeparatorDemo() { + return ( + + } + /> + + Deployment summary + + Review the configuration before deploying. + + + + production-api will deploy to the global network. + + + + The deployment uses compatibility date 2026-10-26. + + + + Deploy + + + + ); +} + export function LayerDialogSplitActionDemo() { return (
diff --git a/packages/kumo-docs-astro/src/pages/components/layer-dialog.mdx b/packages/kumo-docs-astro/src/pages/components/layer-dialog.mdx index 59e5019c2..a72530789 100644 --- a/packages/kumo-docs-astro/src/pages/components/layer-dialog.mdx +++ b/packages/kumo-docs-astro/src/pages/components/layer-dialog.mdx @@ -20,6 +20,7 @@ import { LayerDialogNestedDemo, LayerDialogPendingDemo, LayerDialogSearchDemo, + LayerDialogSeparatorDemo, LayerDialogSizeDemo, LayerDialogSplitActionDemo, LayerDialogTopAlignDemo, @@ -127,6 +128,14 @@ A control can be the first element in `Body`. Here an unlabeled search input sit + +## Dividing body content + +Use `LayerDialog.Separator` between sections in `LayerDialog.Body`. The divider extends through the body's horizontal padding to span the full content surface. + + + + ## Multiple primary actions @@ -278,6 +287,11 @@ Height is derived from content and capped by the viewport. Following Base UI's i

The scrollable content region.

+### LayerDialog.Separator + +

A full-width divider between sections of body content.

+ + ### LayerDialog.Actions

diff --git a/packages/kumo/src/components/layer-dialog/layer-dialog.test.tsx b/packages/kumo/src/components/layer-dialog/layer-dialog.test.tsx index 9802726db..6fde783f1 100644 --- a/packages/kumo/src/components/layer-dialog/layer-dialog.test.tsx +++ b/packages/kumo/src/components/layer-dialog/layer-dialog.test.tsx @@ -29,10 +29,31 @@ describe("LayerDialog", () => { expect(LayerDialog.Title).toBeDefined(); expect(LayerDialog.Description).toBeDefined(); expect(LayerDialog.Body).toBeDefined(); + expect(LayerDialog.Separator).toBeDefined(); expect(LayerDialog.Action).toBeDefined(); expect(LayerDialog.Actions).toBeDefined(); }); + it("renders a full-width body separator", () => { + const { getByRole } = render( + + + Sections + + First + + Second + + + , + ); + + const separator = getByRole("separator"); + expect(separator.className).toContain("-mx-4"); + expect(separator.className).toContain("sm:-mx-4.5"); + expect(separator.className).toContain("bg-kumo-hairline"); + }); + it("uses a larger constrained desktop width by default", () => { expect(KUMO_LAYER_DIALOG_DEFAULT_VARIANTS.size).toBe("base"); expect(KUMO_LAYER_DIALOG_VARIANTS.size.base.classes).toBe("sm:max-w-xl"); diff --git a/packages/kumo/src/components/layer-dialog/layer-dialog.tsx b/packages/kumo/src/components/layer-dialog/layer-dialog.tsx index 455e1ad9b..facb9ac77 100644 --- a/packages/kumo/src/components/layer-dialog/layer-dialog.tsx +++ b/packages/kumo/src/components/layer-dialog/layer-dialog.tsx @@ -1,6 +1,7 @@ import { Children, createContext, + forwardRef, isValidElement, useContext, useRef, @@ -490,6 +491,25 @@ function LayerDialogBody({ children }: LayerDialogBodyProps) { LayerDialogBody.displayName = "LayerDialog.Body"; +export type LayerDialogSeparatorProps = ComponentPropsWithoutRef<"hr">; + +/** A full-width divider between sections of `LayerDialog.Body`. */ +const LayerDialogSeparator = forwardRef< + HTMLHRElement, + LayerDialogSeparatorProps +>(({ className, ...props }, ref) => ( +


+)); + +LayerDialogSeparator.displayName = "LayerDialog.Separator"; + function LayerDialogIconClose({ disabled, label, @@ -671,6 +691,7 @@ const LayerDialog = Object.assign(LayerDialogRoot, { Title: LayerDialogTitle, Description: LayerDialogDescription, Body: LayerDialogBody, + Separator: LayerDialogSeparator, Action: LayerDialogAction, Actions: LayerDialogActions, }); @@ -684,6 +705,7 @@ export { LayerDialogTitle, LayerDialogDescription, LayerDialogBody, + LayerDialogSeparator, LayerDialogAction, LayerDialogActions, };