@domainkit/react 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,23 +1,10 @@
1
1
  # @domainkit/react
2
2
 
3
- Copy a DNS record. Download a zone file. Then connect the domain if you want DomainKit to do the rest.
3
+ Accessible React flows and composable UI parts for DomainKit.
4
4
 
5
- The presentational record parts take a `DnsRecord[]` and do not need `DomainKit.Root` or a transport.
6
-
7
- ```tsx
8
- import { Records } from "@domainkit/react";
9
- import "@domainkit/react/styles.css";
10
-
11
- <Records.Table records={records} />
12
- <Records.CopyValue value="v=spf1 include:example.net ~all" />
13
- <Records.ZoneFile domain="mail.example.com" records={records} />
14
- <Records.Card record={records[0]} />
15
- <Records.Status evidence={{ _tag: "Found", recordId: "mx" }} />
16
- ```
17
-
18
- `Records.Table` copies name and value per row. Pass `evidence` to add Found / Missing / Mismatch / Unavailable chips. `Records.Card` is the stacked layout for the same data. `Records.ZoneFile` copies and downloads BIND text via `Records.toZoneFile`.
19
-
20
- `Table` and `Card` are conveniences over public parts. Hosts that already have a table can assemble `Root`, `Header`, `Body`, `Row`, `Head`, `Cell`, `Value`, `Priority`, and `Status` themselves. `Status` children replace the `_tag` label.
5
+ The package can render the complete domain lifecycle, one focused lifecycle, or model-free DNS
6
+ records. Every stateful operation goes through your authenticated server transport; provider
7
+ credentials never belong in the browser.
21
8
 
22
9
  ## Install
23
10
 
@@ -25,15 +12,13 @@ import "@domainkit/react/styles.css";
25
12
  npm install @domainkit/react domainkit effect@rc @effect/atom-react@rc react react-dom
26
13
  ```
27
14
 
28
- React 19 is required.
15
+ React 19 is required. Install `domainkit` and `@domainkit/react` at the same release version.
29
16
 
30
- ## Domain lifecycle
31
-
32
- When you do have a host-owned transport layer, `Domain.Flow` connects the provider, reviews an exact plan, observes DNS, removes receipt-bound records, and disconnects the current domain grant.
17
+ ## Complete flow
33
18
 
34
19
  ```tsx
35
20
  import { Domain, DomainKit } from "@domainkit/react";
36
- import { Transport } from "domainkit";
21
+ import "@domainkit/react/styles.css";
37
22
 
38
23
  export function DomainSetup() {
39
24
  return (
@@ -44,23 +29,22 @@ export function DomainSetup() {
44
29
  }
45
30
  ```
46
31
 
47
- `Provisioning.Flow` accepts `showRecords={false}` when the host already renders the DNS record list with `Records.Table`.
48
-
49
- Effect applications can compose lifecycle UI directly from `Connection.useModel`,
50
- `Provisioning.useModel`, `Verification.useModel`, and `Cleanup.useModel`. Each model exposes
51
- `state` and `command` atoms; dispatch values with the corresponding exported `Command`
52
- constructors. The packaged controllers and flows consume those same models rather than maintaining
53
- second state machines.
32
+ `Domain.Flow` coordinates connection, plan review, apply, verification, receipt-bound cleanup, and
33
+ removing the domain grant. Your application still owns authentication, authorization, durable
34
+ attempts, provider credentials, and the server-side `Transport` implementation.
54
35
 
55
- `Operations.List` is the shared provisioning and cleanup review recipe. Hosts can instead assemble
56
- `Operations.Root`, `Item`, `Kind`, `Type`, `Record`, `Name`, `Value`, `Priority`, and `Reason` with
57
- Base UI render props.
36
+ ## Adopt only the surface you need
58
37
 
59
- ## Transport ownership
38
+ - `Domain.Flow` — the complete lifecycle;
39
+ - `Connection.Flow`, `Provisioning.Flow`, `Verification.Flow`, and `Cleanup.Flow` — focused flows;
40
+ - `useModel` hooks and semantic parts — host-owned composition and interaction chrome;
41
+ - `Records.Table`, `Records.Card`, and record parts — model-free DNS presentation without a root or
42
+ transport.
60
43
 
61
- `DomainKit.Root` receives a `Layer<Transport.Service>`. Controllers run the service through Effect Atom, so request interruption, stale result suppression, and subtree disposal follow the Effect lifecycle. Implement the service with authenticated application endpoints. Do not place provider credentials or provider API clients in the browser.
44
+ The packaged flows use the same exported models and parts. Components support server rendering;
45
+ clipboard, download, and navigation behavior runs only from browser interactions.
62
46
 
63
- Foreign Promise clients can be adapted once at the boundary:
47
+ ## Host transport
64
48
 
65
49
  ```ts
66
50
  import { Transport } from "domainkit";
@@ -73,90 +57,18 @@ export const transport = Transport.layerFromAsync({
73
57
  });
74
58
  ```
75
59
 
76
- - `connection` detects providers, starts OAuth or token authorization, reuses an existing account, and removes one domain grant while preserving DNS.
77
- - `provisioning` asks the server for an exact plan and applies only the returned digest.
78
- - `verification.observe(config)` is the single observation operation. `sources` selects provider evidence, public DNS, or both.
79
- - `cleanup` creates a fresh receipt-bound deletion plan and applies only its reviewed digest. The server fails closed when records drift or ownership cannot be proven.
60
+ The stylesheet is opt-in. `DomainKit.Root` accepts host messages, provider marks, icons, design
61
+ tokens, color scheme, and portal container, so product branding remains outside the package.
62
+ Cloudflare and Vercel use bundled, theme-aware marks sourced from SVGL; hosts can replace either
63
+ through the `marks` prop.
80
64
 
81
- Successful outcomes use schema-backed tagged models. Failures travel through the Effect error channel.
65
+ ## Learn more
82
66
 
83
- ## Composition and theming
84
-
85
- Every semantic component accepts Base UI's `render` prop.
86
-
87
- ```tsx
88
- <Connection.OAuthAction
89
- controller={controller}
90
- label="Connect"
91
- render={<MyButton variant="primary" />}
92
- />
93
- ```
94
-
95
- `DomainKit.Root` sets theme tokens, messages, provider marks, icons, color scheme, and a portal container. The stylesheet is opt-in and uses `--domainkit-*` CSS custom properties. Record parts pick those tokens up when they sit inside Root; they still function without it.
96
-
97
- `Connection.Flow` is a recipe over the same parts a host can assemble. `Connection.Root` fills the host column and stretches children. `Connection.Trigger` is a dialog opener: its required `children` supply the label, `render` replaces the button, and it does not inject a provider mark. `Connection.ConnectTrigger` accepts a provider and is the packaged button with a mark and default chrome.
98
-
99
- ```tsx
100
- <Connection.Root status={state._tag}>
101
- <HostCard>
102
- <Provider.Mark provider={snapshot.provider} />
103
- <div>
104
- <strong>{snapshot.provider.name}</strong>
105
- <p>Manages DNS for this domain.</p>
106
- </div>
107
- <BaseDialog.Root>
108
- <Connection.Trigger render={<HostButton />}>
109
- Connect {snapshot.provider.name}
110
- </Connection.Trigger>
111
- <Connection.Dialog controller={controller} snapshot={snapshot} />
112
- </BaseDialog.Root>
113
- </HostCard>
114
- </Connection.Root>
115
- ```
116
-
117
- Pass host icons so the package never owns an icon library. `Records.CopyValue` and `Records.ZoneFile` also accept `copyIcon` / `copiedIcon` / `downloadIcon` when you are not wrapping in Root.
118
-
119
- ```tsx
120
- <DomainKit.Root
121
- icons={{
122
- copy: <Copy />,
123
- copied: <Check />,
124
- download: <Download />,
125
- }}
126
- transport={transport}
127
- >
128
- {children}
129
- </DomainKit.Root>
130
- ```
131
-
132
- ```tsx
133
- <Records.Root>
134
- <Records.Header>
135
- <Records.Row>
136
- <Records.Head scope="col">Type</Records.Head>
137
- <Records.Head scope="col">Name</Records.Head>
138
- <Records.Head scope="col">Value</Records.Head>
139
- </Records.Row>
140
- </Records.Header>
141
- <Records.Body>
142
- {records.map((record) => (
143
- <Records.Row key={record.id}>
144
- <Records.Cell>{record.type}</Records.Cell>
145
- <Records.Cell>
146
- <Records.CopyValue value={record.name} />
147
- </Records.Cell>
148
- <Records.Cell>
149
- <Records.Value>
150
- <Records.CopyValue value={record.value} />
151
- {record.priority === undefined ? null : <Records.Priority priority={record.priority} />}
152
- </Records.Value>
153
- </Records.Cell>
154
- </Records.Row>
155
- ))}
156
- </Records.Body>
157
- </Records.Root>
158
- ```
67
+ - [React source and examples](https://github.com/AryaLabsHQ/domainkit/tree/main/packages/react)
68
+ - [Vite workshop source](https://github.com/AryaLabsHQ/domainkit/tree/main/packages/react/examples/vite)
69
+ - [Application transport contract](https://github.com/AryaLabsHQ/domainkit/blob/main/packages/domainkit/src/Transport.ts)
70
+ - [Issues](https://github.com/AryaLabsHQ/domainkit/issues)
159
71
 
160
- ## Server rendering
72
+ ## License
161
73
 
162
- The package is ESM and safe to import on the server. Clipboard and download run in the browser when the user clicks Copy or Download.
74
+ MIT