Section footers

Closes a block with a 1px divider and a row of actions: SectionFooter.Root is the row, .Actions the end cluster. One axis, isCard.

Demo

isCard is the kit’s one prop; the sheet’s booleans are children you write, and its divider switch is a class. The well is the surface each form is for.

Learn more
import { Plus } from "@untitledui/icons"; import { ButtonGroup, ButtonGroupItem } from "@/components/base/button-group/button-group"; import { Button } from "@/components/base/buttons/button"; import { SectionFooter } from "@/components/application/section-footers/section-footer"; <SectionFooter.Root> <ButtonGroup size="sm" aria-label="Date range" defaultSelectedKeys={["12m"]}> <ButtonGroupItem id="12m">12 months</ButtonGroupItem> <ButtonGroupItem id="30d">30 days</ButtonGroupItem> <ButtonGroupItem id="7d">7 days</ButtonGroupItem> <ButtonGroupItem id="custom" iconLeading={Plus}>Custom</ButtonGroupItem> </ButtonGroup> <Button color="link-gray" href="/docs/application/section-headers">Learn more</Button> <SectionFooter.Actions> <Button color="secondary">Cancel</Button> <Button>Save</Button> </SectionFooter.Actions> </SectionFooter.Root>

Two parts, and the rest is yours

SectionFooter.Root owns the divider, the padding and the gap; SectionFooter.Actions owns the end cluster. The buttons, the link and the group are the kit’s Button and ButtonGroup, composed as children, which is why the copied snippet carries their imports too. Toggle all three off and the snippet is a self-closing Root: a divider with its padding, which is a legitimate row. The Divider toggle is the sheet’s divider boolean, which the kit has no prop for: off writes className="border-t-0" into the snippet, the same override the Code tab records.

Contextual demo

A footer closes something, so the thing above it is half the argument. Six scenarios, each under real content.

The family

Two parts on one export: SectionFooter.Root and SectionFooter.Actions. There are no named exports beside it.

The components in this family, with their descriptions and import paths
ComponentDescriptionImport from
SectionFooter.RootThe row: a 1px top divider, the padding, and the gap between whatever you put inside. isCard picks the Card paddings over the Section ones.@/​components/​application/​section-footers/​section-footer
SectionFooter.ActionsThe end cluster. It takes the remaining width and pushes its children, normally a Cancel and a Save, to the end edge 12px apart.@/​components/​application/​section-footers/​section-footer

The variant space

One axis, the sheet’s Type: Card or Section — the kit’s isCard. Both live, on the surface each form is drawn for.

Learn more
Section: isCard unset, the kit’s default. No horizontal padding, so the divider and the row span the content column
Learn more
Card: isCard. The card’s own horizontal padding, and a divider that runs to the card’s edges

The paddings, read from the source

Read from section-footer.tsx, not measured: the Card form is px-4 py-3 md:py-4 lg:px-6 with gap-4, so 16px beside and 12px above and below the row on a phone, 16px all round from 768px, and 24px beside from 1024px. The Section form is pt-4 md:pt-5 with gap-5: 16px then 20px above the row and nothing below or beside it. The parity read of 2026-08-23 took the same numbers off the sheet’s Desktop and Mobile symbols, 16/12 and 24/16 for Card and 20/16 above for Section, and found them matching at both ends. The 768 to 1023px window in the middle is the kit’s own, which the Breakpoints section below sets out.

Composition

The sheet’s three booleans are children in code. Four combinations: two drawn as symbols, two allowed but not shown.

Learn more
Button group=True: the sheet’s fullest row, a date range group, the link, and the actions at the end
Learn more
Button group=False: the link and the actions, which is the sheet’s other symbol
Actions only: nothing leads, so SectionFooter.Actions takes the whole width and the buttons sit at the end
Group only: no Actions, so nothing is pushed to the end and the group sits at the start

Actions takes the width, and now keeps it

SectionFooter.Actions is flex flex-1 shrink-0 items-center justify-end gap-3. The flex-1 is why the buttons land at the end edge whatever leads them; the shrink-0 and items-center are a 2026-08-23 edit, read from the sheet’s flex: 1 0 0 and items-center, so the cluster can no longer shrink under a long leading child or stretch to a taller sibling. No row the sheet draws looks different for it; the Code tab has the before and after.

No states of its own

The footer has no hover, focus, selected or disabled treatment, because it is a row and a divider. Every state on this page belongs to the Button and ButtonGroup inside it, and their pages document those. The sheet draws none either: its eight symbols are Type × Button group × Breakpoint, and nothing else.

Breakpoints

The sheet draws 1216px and 688px artboards with no switch width. The kit switches twice: paddings at 768px and 1024px.

Edge
Below 768px
768 to 1023px
1024px and up
Card, vertical12px (py-3)16px (md:py-4)16px
Card, horizontal16px (px-4)16px24px (lg:px-6)
Section, above16px (pt-4)20px (md:pt-5)20px
Section, below and beside000

Window, not container

All three switches are media queries on the viewport, so this page cannot put the Mobile paddings beside the Desktop ones: every cell above is drawn at whatever width your window has now. Narrow the browser below 768px, or open the contextual demo, which shows the same thing with product chrome around it. A narrow column on a wide screen keeps the desktop paddings, and the sheet’s Mobile symbols change nothing else about the footer: no stacking, no full-width buttons, no size change, which the parity read of 2026-08-23 confirmed against all four Mobile symbols. What does change there is the consumer’s content: the group’s labels shorten to 12m, 30d, 7d and a bare plus. The 768 to 1023px column is a state the sheet never draws, 16px vertical with 16px horizontal, recorded on the Code tab as a kit extra rather than a mismatch.