or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connect.mdindex.mdmachine.md

machine.mddocs/

0

# Dialog State Machine

1

2

The dialog state machine manages all dialog behaviors including state transitions, effects, and accessibility features. It provides a framework-agnostic foundation that can be connected to any UI framework.

3

4

## Capabilities

5

6

### Machine Creation

7

8

Creates a configured dialog state machine with all necessary behaviors and effects.

9

10

```typescript { .api }

11

/**

12

* Creates a dialog state machine with configuration and behaviors

13

* @param props - Configuration props for the dialog machine

14

* @returns Configured state machine instance

15

*/

16

function machine(props: Props): Machine;

17

18

interface Machine extends StateMachine<DialogSchema> {

19

/** Current state of the machine */

20

state: State;

21

/** Send events to the machine */

22

send: (event: MachineEvent) => void;

23

/** Access machine context */

24

context: Context;

25

/** Get prop values */

26

prop: (key: keyof Props) => any;

27

/** DOM scope for element access */

28

scope: Scope;

29

}

30

```

31

32

**Usage Example:**

33

34

```typescript

35

import { machine } from "@zag-js/dialog";

36

37

const dialogMachine = machine({

38

id: "my-dialog",

39

modal: true,

40

trapFocus: true,

41

onOpenChange: (details) => {

42

console.log("Dialog state changed:", details.open);

43

},

44

closeOnEscape: true,

45

closeOnInteractOutside: true

46

});

47

```

48

49

### Machine Events

50

51

Events that can be sent to the dialog machine to trigger state changes.

52

53

```typescript { .api }

54

interface MachineEvent {

55

type:

56

| "OPEN" // Open the dialog

57

| "CLOSE" // Close the dialog

58

| "TOGGLE" // Toggle dialog state

59

| "CONTROLLED.OPEN" // Open via controlled prop

60

| "CONTROLLED.CLOSE"; // Close via controlled prop

61

62

/** Optional source information */

63

src?: string;

64

/** Previous event reference */

65

previousEvent?: MachineEvent;

66

}

67

```

68

69

**Usage Examples:**

70

71

```typescript

72

// Open dialog programmatically

73

machine.send({ type: "OPEN" });

74

75

// Close dialog programmatically

76

machine.send({ type: "CLOSE" });

77

78

// Toggle dialog state

79

machine.send({ type: "TOGGLE" });

80

81

// Close via interaction outside (internal use)

82

machine.send({ type: "CLOSE", src: "interact-outside" });

83

```

84

85

### Machine States

86

87

The dialog machine has two primary states with different behaviors and effects.

88

89

```typescript { .api }

90

type DialogState = "open" | "closed";

91

92

interface StateConfig {

93

/** State name */

94

value: DialogState;

95

/** Whether state matches given state(s) */

96

matches: (state: DialogState | DialogState[]) => boolean;

97

/** Active effects in this state */

98

effects?: string[];

99

/** Entry actions when entering state */

100

entry?: string[];

101

/** Available transitions from this state */

102

on?: Record<string, TransitionConfig>;

103

}

104

```

105

106

**State Behaviors:**

107

108

- **"closed"**: Dialog is hidden, no effects active, can transition to "open"

109

- **"open"**: Dialog is visible, all effects active (focus trap, scroll prevention, etc.)

110

111

### Machine Effects

112

113

Effects that run when the dialog is in the "open" state, providing accessibility and interaction features.

114

115

```typescript { .api }

116

interface MachineEffects {

117

/** Track dismissible element for outside interactions */

118

trackDismissableElement: Effect;

119

/** Prevent background scrolling */

120

preventScroll: Effect;

121

/** Trap focus within dialog */

122

trapFocus: Effect;

123

/** Hide content below modal */

124

hideContentBelow: Effect;

125

}

126

127

interface Effect {

128

/** Effect cleanup function */

129

(): (() => void) | void;

130

}

131

```

132

133

**Effect Details:**

134

135

- **trackDismissableElement**: Handles clicks/focus outside dialog, escape key, and dismissal logic

136

- **preventScroll**: Prevents body scrolling when dialog is open (if `preventScroll: true`)

137

- **trapFocus**: Constrains tab navigation within dialog (if `trapFocus: true`)

138

- **hideContentBelow**: Hides content behind modal using `aria-hidden` (if `modal: true`)

139

140

### Machine Actions

141

142

Actions that execute during state transitions to handle side effects and updates.

143

144

```typescript { .api }

145

interface MachineActions {

146

/** Check if title and description elements are rendered */

147

checkRenderedElements: Action;

148

/** Synchronize z-index between positioner and backdrop */

149

syncZIndex: Action;

150

/** Invoke onOpenChange callback with open: false */

151

invokeOnClose: Action;

152

/** Invoke onOpenChange callback with open: true */

153

invokeOnOpen: Action;

154

/** Toggle visibility based on controlled open prop */

155

toggleVisibility: Action;

156

}

157

158

interface Action {

159

/** Action execution context */

160

(context: ActionContext): void;

161

}

162

163

interface ActionContext {

164

/** Machine context */

165

context: Context;

166

/** DOM scope */

167

scope: Scope;

168

/** Get prop value */

169

prop: (key: string) => any;

170

/** Send event to machine */

171

send: (event: MachineEvent) => void;

172

/** Current event being processed */

173

event: MachineEvent;

174

}

175

```

176

177

### Machine Guards

178

179

Guards that determine whether state transitions should occur based on current conditions.

180

181

```typescript { .api }

182

interface MachineGuards {

183

/** Check if open state is controlled via props */

184

isOpenControlled: Guard;

185

}

186

187

interface Guard {

188

/** Guard evaluation */

189

(context: GuardContext): boolean;

190

}

191

192

interface GuardContext {

193

/** Machine context */

194

context: Context;

195

/** Get prop value */

196

prop: (key: string) => any;

197

/** Current event */

198

event: MachineEvent;

199

}

200

```

201

202

**Guard Logic:**

203

204

- **isOpenControlled**: Returns `true` if `open` prop is defined, indicating controlled mode

205

206

### Machine Context

207

208

Internal context maintained by the machine for tracking rendered elements and other state.

209

210

```typescript { .api }

211

interface MachineContext {

212

/** Tracks which elements are currently rendered in DOM */

213

rendered: {

214

title: boolean;

215

description: boolean;

216

};

217

}

218

```

219

220

The context is automatically updated by machine actions and used for proper ARIA labeling and descriptions.

221

222

### Machine Schema

223

224

Complete schema definition for the dialog state machine, used for type safety and validation.

225

226

```typescript { .api }

227

interface DialogSchema {

228

/** Props type for the machine */

229

props: Props;

230

/** Available states */

231

state: "open" | "closed";

232

/** Machine context */

233

context: MachineContext;

234

/** Available guards */

235

guard: "isOpenControlled";

236

/** Available effects */

237

effect: "trackDismissableElement" | "preventScroll" | "trapFocus" | "hideContentBelow";

238

/** Available actions */

239

action: "checkRenderedElements" | "syncZIndex" | "invokeOnClose" | "invokeOnOpen" | "toggleVisibility";

240

/** Event types */

241

event: MachineEvent;

242

}

243

```