or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-types.mdcore-components.mdindex.mdinteractive-components.md

core-components.mddocs/

0

# Core Components

1

2

The fundamental drawer components that form the building blocks of any drawer interface. These components work together to create the basic drawer structure and behavior.

3

4

## Capabilities

5

6

### Drawer.Root

7

8

Main root component that provides context and state management for the entire drawer system. This component must wrap all other drawer components.

9

10

```typescript { .api }

11

/**

12

* Root component that provides drawer context and manages state

13

* @param props - Configuration props for the drawer

14

* @returns Root drawer component

15

*/

16

interface Drawer.Root extends React.Component<DialogProps> {}

17

18

interface DialogProps {

19

/** Controlled open state */

20

open?: boolean;

21

/** Callback fired when open state changes */

22

onOpenChange?: (open: boolean) => void;

23

/** Default open state for uncontrolled usage */

24

defaultOpen?: boolean;

25

/** Child components */

26

children?: React.ReactNode;

27

/** Array for snap point behavior - numbers 0-100 for % or px values */

28

snapPoints?: (number | string)[];

29

/** Index from which overlay fade should be applied */

30

fadeFromIndex?: number;

31

/** Controlled active snap point */

32

activeSnapPoint?: number | string | null;

33

/** Callback to set active snap point */

34

setActiveSnapPoint?: (snapPoint: number | string | null) => void;

35

/** Threshold for closing (default: 0.25) */

36

closeThreshold?: number;

37

/** Prevent body style changes */

38

noBodyStyles?: boolean;

39

/** Enable background scaling effect */

40

shouldScaleBackground?: boolean;

41

/** Change background color when scaling */

42

setBackgroundColorOnScale?: boolean;

43

/** Duration for scroll lock in ms (default: 100) */

44

scrollLockTimeout?: number;

45

/** Fixed positioning behavior */

46

fixed?: boolean;

47

/** Restrict dragging to handle only */

48

handleOnly?: boolean;

49

/** Allow dismissal via gestures (default: true) */

50

dismissible?: boolean;

51

/** Drag event handler */

52

onDrag?: (event: React.PointerEvent<HTMLDivElement>, percentageDragged: number) => void;

53

/** Release event handler */

54

onRelease?: (event: React.PointerEvent<HTMLDivElement>, open: boolean) => void;

55

/** Modal behavior (default: true) */

56

modal?: boolean;

57

/** Nested drawer support */

58

nested?: boolean;

59

/** Close callback */

60

onClose?: () => void;

61

/** Drawer direction (default: 'bottom') */

62

direction?: 'top' | 'bottom' | 'left' | 'right';

63

/** Disable scroll prevention */

64

disablePreventScroll?: boolean;

65

/** Reposition inputs on keyboard */

66

repositionInputs?: boolean;

67

/** Disable velocity-based snapping */

68

snapToSequentialPoint?: boolean;

69

/** Portal container */

70

container?: HTMLElement | null;

71

/** Animation end callback */

72

onAnimationEnd?: (open: boolean) => void;

73

/** Prevent scroll restoration */

74

preventScrollRestoration?: boolean;

75

/** Auto focus behavior */

76

autoFocus?: boolean;

77

}

78

```

79

80

**Usage Examples:**

81

82

```typescript

83

import { Drawer } from "vaul";

84

85

// Basic drawer

86

function BasicDrawer() {

87

return (

88

<Drawer.Root>

89

<Drawer.Trigger>Open</Drawer.Trigger>

90

<Drawer.Portal>

91

<Drawer.Content>Content</Drawer.Content>

92

</Drawer.Portal>

93

</Drawer.Root>

94

);

95

}

96

97

// Controlled drawer with snap points

98

function ControlledDrawer() {

99

const [open, setOpen] = React.useState(false);

100

101

return (

102

<Drawer.Root

103

open={open}

104

onOpenChange={setOpen}

105

snapPoints={[0.2, 0.5, 0.8]}

106

fadeFromIndex={1}

107

>

108

<Drawer.Trigger>Open Drawer</Drawer.Trigger>

109

<Drawer.Portal>

110

<Drawer.Overlay />

111

<Drawer.Content>

112

<p>Drawer with snap points</p>

113

</Drawer.Content>

114

</Drawer.Portal>

115

</Drawer.Root>

116

);

117

}

118

```

119

120

### Drawer.Content

121

122

Main drawer content container that holds the actual drawer content. This component handles pointer events and provides the visual container for drawer contents.

123

124

```typescript { .api }

125

/**

126

* Main drawer content container

127

* @param props - Content component props extending Radix Dialog.Content

128

* @param ref - Forwarded ref to the content element

129

* @returns Content container component

130

*/

131

interface Drawer.Content extends React.ForwardRefExoticComponent<ContentProps> {}

132

133

type ContentProps = React.ComponentProps<typeof DialogPrimitive.Content>;

134

```

135

136

**Usage Examples:**

137

138

```typescript

139

// Basic content

140

<Drawer.Content>

141

<h2>Drawer Title</h2>

142

<p>Drawer content goes here.</p>

143

</Drawer.Content>

144

145

// Content with custom styling

146

<Drawer.Content className="drawer-content">

147

<div className="drawer-header">

148

<Drawer.Title>Settings</Drawer.Title>

149

<Drawer.Close>×</Drawer.Close>

150

</div>

151

<div className="drawer-body">

152

<p>Settings content...</p>

153

</div>

154

</Drawer.Content>

155

```

156

157

### Drawer.Overlay

158

159

Backdrop overlay component that appears behind the drawer content. Clicking the overlay typically closes the drawer (unless configured otherwise).

160

161

```typescript { .api }

162

/**

163

* Backdrop overlay component

164

* @param props - Overlay component props extending Radix Dialog.Overlay

165

* @param ref - Forwarded ref to the overlay element

166

* @returns Overlay backdrop component

167

*/

168

interface Drawer.Overlay extends React.ForwardRefExoticComponent<React.ComponentProps<typeof DialogPrimitive.Overlay>> {}

169

```

170

171

**Usage Examples:**

172

173

```typescript

174

// Basic overlay

175

<Drawer.Overlay />

176

177

// Overlay with custom styling

178

<Drawer.Overlay className="drawer-overlay" />

179

180

// Overlay with click handler

181

<Drawer.Overlay onClick={() => console.log('Overlay clicked')} />

182

```

183

184

### Drawer.Trigger

185

186

Button or element that triggers the drawer to open when activated. Can be any interactive element.

187

188

```typescript { .api }

189

/**

190

* Element that triggers drawer open when activated

191

*/

192

interface Drawer.Trigger extends typeof DialogPrimitive.Trigger {}

193

```

194

195

**Usage Examples:**

196

197

```typescript

198

// Button trigger

199

<Drawer.Trigger>Open Drawer</Drawer.Trigger>

200

201

// Custom trigger with styling

202

<Drawer.Trigger className="custom-trigger">

203

<Icon name="menu" />

204

Menu

205

</Drawer.Trigger>

206

207

// Trigger as different element

208

<Drawer.Trigger asChild>

209

<button className="my-button">Custom Button</button>

210

</Drawer.Trigger>

211

```

212

213

### Drawer.Portal

214

215

Portal component that renders the drawer outside the normal DOM tree. This ensures proper layering and prevents styling conflicts.

216

217

```typescript { .api }

218

/**

219

* Portal component for rendering drawer outside normal DOM tree

220

* @param props - Portal props extending Radix Dialog.Portal with container override

221

* @returns Portal component

222

*/

223

interface Drawer.Portal extends React.Component<PortalProps> {}

224

225

interface PortalProps extends React.ComponentProps<typeof DialogPrimitive.Portal> {

226

/** Override container for portal rendering */

227

container?: HTMLElement;

228

}

229

```

230

231

**Usage Examples:**

232

233

```typescript

234

// Default portal (renders to document.body)

235

<Drawer.Portal>

236

<Drawer.Overlay />

237

<Drawer.Content>Content</Drawer.Content>

238

</Drawer.Portal>

239

240

// Portal to custom container

241

<Drawer.Portal container={customContainer}>

242

<Drawer.Overlay />

243

<Drawer.Content>Content</Drawer.Content>

244

</Drawer.Portal>

245

```