Skip to content
DomainKit
Esc
↑↓navigate↵open⌘Jpreview
On this page

Records table

A React table of the DNS records a domain needs, each with its plan or observed status, a copy button per value, and the reason a record is blocked.

records-table lists the records your product needs at a domain, one row each, with the type, the name, a copy control for the value, and where the record stands.

import { Domain } from "@domainkit/react";

import { ProviderRow } from "@/components/domainkit/provider-row";
import { RecordsTable } from "@/components/domainkit/records-table";

import {
  PreviewRoot,
  previewDomain,
  previewMarks,
  previewRequirements,
} from "../../lib/preview-flow.tsx";

function Table() {
  const flow = Domain.useFlow({ domain: previewDomain, requirements: previewRequirements });
  return <RecordsTable flow={flow} header={<ProviderRow flow={flow} marks={previewMarks} />} />;
}

export default function RecordsTableExample() {
  return (
    <PreviewRoot>
      <Table />
    </PreviewRoot>
  );
}

Installation

npx shadcn@latest add https://domain-kit.dev/r/records-table.json
pnpm dlx shadcn@latest add https://domain-kit.dev/r/records-table.json
yarn dlx shadcn@latest add https://domain-kit.dev/r/records-table.json
bunx shadcn@latest add https://domain-kit.dev/r/records-table.json
nubx shadcn@latest add https://domain-kit.dev/r/records-table.json
aube dlx shadcn@latest add https://domain-kit.dev/r/records-table.json

What a row says

A plan still awaiting its apply gets a column of its own saying what it will do: add the record, leave it, or nothing while it is blocked. The status column beside it is always what the observers read back. Records.standingOf hands the row both facts, so the table renders each column from the one that is about it.

A blocked record gets a second row under it naming what is in the way and what to do about it, both from the message catalog.

Here an A record already sits on the tracking host, so its CNAME is a conflict. The plan approves the records that can be added and leaves the blocked one for the customer to fix at their provider.

import { Domain } from "@domainkit/react";

import { PlanAction } from "@/components/domainkit/plan-action";
import { ProviderRow } from "@/components/domainkit/provider-row";
import { RecordsTable } from "@/components/domainkit/records-table";

import {
  PreviewRoot,
  previewConflictSeed,
  previewDomain,
  previewMarks,
  previewRequirements,
} from "../../lib/preview-flow.tsx";

// Hydrate on load: the preview renders nothing until its grant lands, so the island has no
// server-rendered element for the default visible trigger to observe.
export const client = "load";

function Table() {
  const flow = Domain.useFlow({ domain: previewDomain, requirements: previewRequirements });
  return (
    <div className="space-y-3">
      <RecordsTable flow={flow} header={<ProviderRow flow={flow} marks={previewMarks} />} />
      <PlanAction flow={flow} />
    </div>
  );
}

/** A zone whose A record on the tracking host blocks the CNAME, so the plan carries a conflict. */
export default function RecordsTableConflictExample() {
  return (
    <PreviewRoot connected seed={previewConflictSeed}>
      <Table />
    </PreviewRoot>
  );
}

API

Prop Type Required Description
flow Domain.Flow yes The flow whose requirements the table renders.
header ReactNode no The line above the table, where the row goes.

Boundary

The table renders what the plan and the observation already decided. Observing DNS, and deciding what readiness means for your product, both stay outside it.

Last updated on

Was this page helpful?