A footer action was always a handler. But some of them LEAVE the dialog —
"Go to post", "Open in Contracts" — and a place you cannot cmd-click is
a place the reader has to come back from: no new tab, no copied link, no
middle click. `DialogControls` already takes a `url` for its resource
affordance, and says why in its own comment; footer actions could not.
`primaryAction` and `secondaryAction` now take a route OR a handler, as a
union, so a link cannot be declared without somewhere to go and a handler
cannot be declared without something to do. Both together is a link that
also reports the press. The footer spreads whichever it was given into
`F0Button`, which has supported `href` all along.
The multi-action (dropdown) form is unchanged: `ButtonDropdownItem` has
no href, so a footer of several actions still carries handlers only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
A footer action was always a handler:
primaryAction/secondaryActionrequiredonClickand took nohref.But some footer actions leave the dialog — "Go to post", "Open in Contracts" — and a place you cannot cmd-click is a place the reader has to come back from: no new tab, no copied link, no middle click.
DialogControlsalready takes aurlfor its resource affordance and says why in its own comment ("routed through the app'sLinkProvider, so it is cmd/middle-clickable"); footer actions had no equivalent.Came up wiring the Home's Communities carousel: a post opens in
F0CarouselDialog, and the way out to the post's own page belongs in the footer as a link.Public API
F0DialogPrimaryActionandF0DialogSecondaryActionnow take a route or a handler:A union rather than two optional fields, so a link cannot be declared without somewhere to go and a handler cannot be declared without something to do. Both together is a link that also reports the press (analytics, closing what's behind it). The footer spreads whichever it was given into
F0Button, which has supportedhrefall along — so nothing new renders, an existing button just becomes an anchor when it's given a route.Unchanged: every existing call site (they all pass
onClick), and the multi-action dropdown form —ButtonDropdownItemhas no href, so a footer of several actions still carries handlers only. Worth a follow-up if a dropdown ever needs a link in it.Tests
F0Dialog.footer-actions.test.tsx— a primary action with a route renders as a link with that href, a secondary one too, a handler action stays a button and fires, and a link that also hasonClickreports the press. 10 pass acrosssrc/patterns/F0Dialog/;build:typesand oxlint clean.Pairs with #5256, which exports
F0CarouselDialogso an app can use it at all.🤖 Generated with Claude Code