Composed flow
Replace one slot of the domain flow with your own component, place the slots in your own layout, and keep every other part of the lifecycle intact.
Every part of Domain.Flow is a slot with a default. Replacing one changes that part and nothing
else, and the flow adds no layout container around a slot’s output.
/** One slot replaced, the rest of the flow untouched. */
export function DomainSetupWithMyTable() {
return (
<Domain.Flow
domain={domain}
requirements={requirements}
slots={{
records: ({ readiness, records }) => (
<Records.Table caption="Add these records" readiness={readiness} records={records} />
),
}}
/>
);
}Usage
/** Own one piece of the flow and keep the rest. Every slot has a default. */
export function DomainSettings() {
return (
<DomainKit.Root transport={transport}>
<Domain.Flow
domain="app.example.com"
requirements={requirements}
slots={{
records: ({ records, readiness }) =>
records.map((record) => (
<Records.Card
className="my-card"
key={Records.identity(record)}
readiness={readiness}
record={record}
/>
)),
}}
onApplied={(receipt) => track("dns.applied", { receiptId: receipt.id })}
/>
</DomainKit.Root>
);
}Slots
| Slot | Receives | Default |
|---|---|---|
connection |
{ controller, domain } |
Connect.Card once connected, Connect.Dialog until then |
records |
{ records, readiness, controller, domain } |
Records.Table |
verification |
{ controller, domain } |
Verify.Status |
actions |
{ connection, provisioning, cleanup, domain } |
Review changes, Approve, Decline, Remove records |
Your own layout
/**
* `Domain.Flow` wraps no slot in a container of its own, so the slot output is a direct child of
* the flow root and your grid places it.
*/
export function DomainSettingsInAGrid() {
return (
<DomainKit.Root transport={transport}>
<Domain.Flow
className="settings-grid"
domain="app.example.com"
requirements={requirements}
slots={{
connection: ({ controller }) => <Connect.Card controller={controller} />,
verification: ({ controller }) => <Verify.Status controller={controller} />,
}}
/>
</DomainKit.Root>
);
}Your own actions
/** The actions slot receives all three controllers, so a host can drive its own buttons. */
export function DomainSettingsWithMyButtons() {
return (
<DomainKit.Root transport={transport}>
<Domain.Flow
domain="app.example.com"
requirements={requirements}
slots={{
actions: ({ cleanup, provisioning }) => (
<div className="my-actions">
<button onClick={provisioning.plan} type="button">
Review DNS changes
</button>
<button onClick={cleanup.plan} type="button">
Remove records
</button>
</div>
),
}}
/>
</DomainKit.Root>
);
}Read composition for parts, render, and state-aware className.