Skip to content
DomainKit
Esc
navigateopen⌘Jpreview
On this page

Host connection

Compose DomainKit connection state into an existing product surface while retaining the packaged controller and dialog.

Use the connection controller and semantic parts when your application already owns the surrounding card, navigation, provider copy, or action layout.

import { Dialog } from "@base-ui/react/dialog";
import { Connection, Provider } from "@domainkit/react";

export function ConnectionRow({ domain }: { domain: string }) {
  const controller = Connection.useController(domain);
  const state = controller.state;
  const snapshot = state._tag === "Disconnected" ? state : undefined;

  return snapshot ? (
    <Connection.Root status={state._tag}>
      <Provider.Mark provider={snapshot.provider} />
      <Dialog.Root>
        <Connection.ConnectTrigger provider={snapshot.provider} />
        <Connection.Dialog controller={controller} snapshot={snapshot} />
      </Dialog.Root>
    </Connection.Root>
  ) : (
    <Connection.Status state={state} />
  );
}

Installation

npm install @domainkit/react domainkit effect @effect/atom-react react react-dom
pnpm add @domainkit/react domainkit effect @effect/atom-react react react-dom
yarn add @domainkit/react domainkit effect @effect/atom-react react react-dom
bun add @domainkit/react domainkit effect @effect/atom-react react react-dom

Usage

Create one controller for the domain and derive the visible surface from its tagged state. Keep the controller and the rendered dialog together so pending OAuth or token submissions cannot diverge from the displayed state.

const controller = Connection.useController(domain);

return (
  <Connection.Root status={controller.state._tag}>
    <Connection.Status state={controller.state} />
  </Connection.Root>
);

Composition contract

  • useController owns the connection model and commands for one domain.
  • Root exposes the state through data-state and accepts host styling.
  • Status renders the current human-readable outcome.
  • ConnectTrigger and Dialog compose with Base UI dialog state.
  • RetryAction follows the failure’s explicit retry policy.

The host still owns authenticated endpoints, tenant checks, credential storage, connection persistence, and OAuth callback routes.

Accessibility

Use a real button for the connection trigger. If you replace its visible text, include the provider name in the accessible label. Preserve dialog focus management and the disabled state while a submission or redirect is pending.

API reference

Connection.Root

PropType
status?Connection.State["_tag"]

State tag exposed through data-state and state-aware styling.

TypeConnection.State["_tag"]
Default"Loading"

Connection.Status

PropType
stateConnection.State

Connection state used to derive the visible status message.

TypeConnection.State

Connection.ConnectTrigger

PropType
children?ReactNode

Optional custom trigger content; the default includes the provider mark and label.

TypeReactNode
providerProvider.Provider

Provider descriptor whose authentication dialog the trigger opens.

TypeProvider.Provider

Connection.Dialog

PropType
controllerConnection.Controller

Controller that owns connection commands and state.

TypeConnection.Controller
snapshotDisconnected

Disconnected provider snapshot used to render authorization options.

TypeDisconnected

See Composition for the shared part-prop and state-aware styling model.

Was this page helpful?