0
# API Connection Methods
1
2
The connect function transforms the dialog state machine into framework-agnostic prop functions that provide complete accessibility, interaction handling, and ARIA attributes for UI elements.
3
4
## Capabilities
5
6
### Connect Function
7
8
Connects a dialog service to UI framework normalization, returning an API object with prop functions for each dialog element.
9
10
```typescript { .api }
11
/**
12
* Connects dialog service to UI framework, returning prop functions
13
* @param service - Dialog state machine service
14
* @param normalize - Framework-specific prop normalization function
15
* @returns API object with prop functions for dialog elements
16
*/
17
function connect<T extends PropTypes>(
18
service: Service,
19
normalize: NormalizeProps<T>
20
): Api<T>;
21
22
interface Service {
23
/** Current machine state */
24
state: State;
25
/** Send events to machine */
26
send: (event: MachineEvent) => void;
27
/** Machine context */
28
context: Context;
29
/** Get prop value */
30
prop: (key: string) => any;
31
/** DOM scope for element access */
32
scope: Scope;
33
}
34
35
interface Api<T extends PropTypes> {
36
/** Current open state */
37
open: boolean;
38
/** Programmatically set open state */
39
setOpen: (open: boolean) => void;
40
41
// Element prop functions
42
getTriggerProps: () => T["button"];
43
getBackdropProps: () => T["element"];
44
getPositionerProps: () => T["element"];
45
getContentProps: () => T["element"];
46
getTitleProps: () => T["element"];
47
getDescriptionProps: () => T["element"];
48
getCloseTriggerProps: () => T["button"];
49
}
50
```
51
52
**Usage Example:**
53
54
```typescript
55
import { machine, connect } from "@zag-js/dialog";
56
import { normalizeProps } from "@zag-js/react";
57
58
const service = useMachine(machine({ id: "dialog-1" }));
59
const api = connect(service, normalizeProps);
60
61
// Use api.getTriggerProps(), api.getContentProps(), etc.
62
```
63
64
### Open State Management
65
66
Direct access to dialog open state and programmatic control.
67
68
```typescript { .api }
69
interface OpenStateAPI {
70
/** Whether dialog is currently open */
71
open: boolean;
72
73
/**
74
* Set dialog open state programmatically
75
* @param open - True to open dialog, false to close
76
*/
77
setOpen: (open: boolean) => void;
78
}
79
```
80
81
**Usage Examples:**
82
83
```typescript
84
// Check if dialog is open
85
if (api.open) {
86
console.log("Dialog is currently open");
87
}
88
89
// Open dialog programmatically
90
api.setOpen(true);
91
92
// Close dialog programmatically
93
api.setOpen(false);
94
95
// Toggle dialog
96
api.setOpen(!api.open);
97
```
98
99
### Trigger Element Props
100
101
Props for the button that opens the dialog, with proper ARIA attributes and click handling.
102
103
```typescript { .api }
104
/**
105
* Get props for dialog trigger button
106
* @returns Button props with accessibility and click handling
107
*/
108
getTriggerProps(): ButtonProps;
109
110
interface ButtonProps {
111
/** Element ID */
112
id: string;
113
/** Button type */
114
type: "button";
115
/** Text direction */
116
dir: "ltr" | "rtl";
117
/** ARIA popup type */
118
"aria-haspopup": "dialog";
119
/** ARIA expanded state */
120
"aria-expanded": boolean;
121
/** Data state attribute */
122
"data-state": "open" | "closed";
123
/** Controls relationship */
124
"aria-controls": string;
125
/** Click handler */
126
onClick: (event: MouseEvent) => void;
127
}
128
```
129
130
**Usage Example:**
131
132
```typescript
133
<button {...api.getTriggerProps()}>
134
Open Dialog
135
</button>
136
```
137
138
### Backdrop Element Props
139
140
Props for the modal backdrop that appears behind the dialog content.
141
142
```typescript { .api }
143
/**
144
* Get props for dialog backdrop
145
* @returns Element props for backdrop
146
*/
147
getBackdropProps(): ElementProps;
148
149
interface ElementProps {
150
/** Element ID */
151
id: string;
152
/** Text direction */
153
dir: "ltr" | "rtl";
154
/** Hidden state */
155
hidden: boolean;
156
/** Data state attribute */
157
"data-state": "open" | "closed";
158
}
159
```
160
161
**Usage Example:**
162
163
```typescript
164
<div {...api.getBackdropProps()} />
165
```
166
167
### Positioner Element Props
168
169
Props for the element that positions the dialog content, typically a full-screen container.
170
171
```typescript { .api }
172
/**
173
* Get props for dialog positioner
174
* @returns Element props for positioner container
175
*/
176
getPositionerProps(): PositionerProps;
177
178
interface PositionerProps {
179
/** Element ID */
180
id: string;
181
/** Text direction */
182
dir: "ltr" | "rtl";
183
/** CSS styles */
184
style: {
185
pointerEvents: "none" | undefined;
186
};
187
}
188
```
189
190
**Usage Example:**
191
192
```typescript
193
<div {...api.getPositionerProps()}>
194
{/* Dialog content container */}
195
</div>
196
```
197
198
### Content Element Props
199
200
Props for the main dialog content container with full accessibility attributes.
201
202
```typescript { .api }
203
/**
204
* Get props for dialog content container
205
* @returns Element props with full ARIA attributes
206
*/
207
getContentProps(): ContentProps;
208
209
interface ContentProps {
210
/** Element ID */
211
id: string;
212
/** Text direction */
213
dir: "ltr" | "rtl";
214
/** ARIA role */
215
role: "dialog" | "alertdialog";
216
/** Hidden state */
217
hidden: boolean;
218
/** Tab index for focus */
219
tabIndex: -1;
220
/** Data state attribute */
221
"data-state": "open" | "closed";
222
/** Modal flag */
223
"aria-modal": true;
224
/** Accessible label */
225
"aria-label"?: string;
226
/** Labeled by title element */
227
"aria-labelledby"?: string;
228
/** Described by description element */
229
"aria-describedby"?: string;
230
}
231
```
232
233
**Usage Example:**
234
235
```typescript
236
<div {...api.getContentProps()}>
237
<h2 {...api.getTitleProps()}>Dialog Title</h2>
238
<p {...api.getDescriptionProps()}>Dialog description</p>
239
{/* Dialog content */}
240
</div>
241
```
242
243
### Title Element Props
244
245
Props for the dialog title element, used for ARIA labeling.
246
247
```typescript { .api }
248
/**
249
* Get props for dialog title element
250
* @returns Element props for title
251
*/
252
getTitleProps(): TitleProps;
253
254
interface TitleProps {
255
/** Element ID */
256
id: string;
257
/** Text direction */
258
dir: "ltr" | "rtl";
259
}
260
```
261
262
**Usage Example:**
263
264
```typescript
265
<h2 {...api.getTitleProps()}>
266
My Dialog Title
267
</h2>
268
```
269
270
### Description Element Props
271
272
Props for the dialog description element, used for ARIA descriptions.
273
274
```typescript { .api }
275
/**
276
* Get props for dialog description element
277
* @returns Element props for description
278
*/
279
getDescriptionProps(): DescriptionProps;
280
281
interface DescriptionProps {
282
/** Element ID */
283
id: string;
284
/** Text direction */
285
dir: "ltr" | "rtl";
286
}
287
```
288
289
**Usage Example:**
290
291
```typescript
292
<p {...api.getDescriptionProps()}>
293
This dialog contains important information.
294
</p>
295
```
296
297
### Close Trigger Props
298
299
Props for the button that closes the dialog, with proper event handling.
300
301
```typescript { .api }
302
/**
303
* Get props for dialog close button
304
* @returns Button props with close handling
305
*/
306
getCloseTriggerProps(): CloseButtonProps;
307
308
interface CloseButtonProps {
309
/** Element ID */
310
id: string;
311
/** Button type */
312
type: "button";
313
/** Text direction */
314
dir: "ltr" | "rtl";
315
/** Click handler with event propagation control */
316
onClick: (event: MouseEvent) => void;
317
}
318
```
319
320
**Usage Example:**
321
322
```typescript
323
<button {...api.getCloseTriggerProps()}>
324
✕ Close
325
</button>
326
```
327
328
## Complete Integration Example
329
330
```typescript
331
import { machine, connect } from "@zag-js/dialog";
332
import { normalizeProps } from "@zag-js/react"; // or your framework
333
334
function MyDialog() {
335
const [state, send] = useMachine(
336
machine({
337
id: "my-dialog",
338
modal: true,
339
closeOnEscape: true,
340
onOpenChange: (details) => {
341
console.log("Dialog open state:", details.open);
342
}
343
})
344
);
345
346
const api = connect(state, normalizeProps);
347
348
return (
349
<div>
350
{/* Trigger */}
351
<button {...api.getTriggerProps()}>
352
Open Dialog
353
</button>
354
355
{/* Dialog Portal */}
356
{api.open && (
357
<div {...api.getPositionerProps()}>
358
{/* Backdrop */}
359
<div {...api.getBackdropProps()} />
360
361
{/* Content */}
362
<div {...api.getContentProps()}>
363
<h2 {...api.getTitleProps()}>
364
Confirmation
365
</h2>
366
367
<p {...api.getDescriptionProps()}>
368
Are you sure you want to delete this item?
369
</p>
370
371
<div>
372
<button {...api.getCloseTriggerProps()}>
373
Cancel
374
</button>
375
<button onClick={() => {
376
// Perform action
377
api.setOpen(false);
378
}}>
379
Delete
380
</button>
381
</div>
382
</div>
383
</div>
384
)}
385
</div>
386
);
387
}
388
```