or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-api.mddrag-config.mdevent-handling.mdindex.mdresize-config.mdsize-position.md

event-handling.mddocs/

0

# Event Handling

1

2

Callback props for all drag and resize interaction phases with detailed event data. React RnD provides comprehensive event handling for all user interactions.

3

4

## Capabilities

5

6

### Drag Event Callbacks

7

8

Handle all phases of drag interactions with detailed position and delta information.

9

10

```typescript { .api }

11

/**

12

* Called when drag operation starts

13

* Can return false to cancel the drag operation

14

*/

15

onDragStart?: RndDragCallback;

16

17

/**

18

* Called continuously during drag operation

19

* Can return false to cancel the drag operation

20

*/

21

onDrag?: RndDragCallback;

22

23

/**

24

* Called when drag operation completes

25

*/

26

onDragStop?: RndDragCallback;

27

28

// RndDragCallback is imported from react-draggable as DraggableEventHandler

29

type RndDragCallback = import("react-draggable").DraggableEventHandler;

30

31

type RndDragEvent =

32

| React.MouseEvent<HTMLElement | SVGElement>

33

| React.TouchEvent<HTMLElement | SVGElement>

34

| MouseEvent

35

| TouchEvent;

36

37

interface DraggableData extends Position {

38

/** DOM element being dragged */

39

node: HTMLElement;

40

/** X coordinate in pixels */

41

x: number;

42

/** Y coordinate in pixels */

43

y: number;

44

/** Change in X since last event */

45

deltaX: number;

46

/** Change in Y since last event */

47

deltaY: number;

48

/** Previous X coordinate */

49

lastX: number;

50

/** Previous Y coordinate */

51

lastY: number;

52

}

53

```

54

55

**Usage Examples:**

56

57

```typescript

58

function DragTrackingExample() {

59

const [dragInfo, setDragInfo] = React.useState<string>('');

60

61

return (

62

<div>

63

<div>Drag Status: {dragInfo}</div>

64

<Rnd

65

default={{ x: 0, y: 0, width: 200, height: 150 }}

66

onDragStart={(e, d) => {

67

setDragInfo(`Drag started at (${d.x}, ${d.y})`);

68

console.log('Drag started:', d);

69

}}

70

onDrag={(e, d) => {

71

setDragInfo(`Dragging to (${d.x}, ${d.y}), delta: (${d.deltaX}, ${d.deltaY})`);

72

}}

73

onDragStop={(e, d) => {

74

setDragInfo(`Drag ended at (${d.x}, ${d.y})`);

75

console.log('Final position:', d.x, d.y);

76

}}

77

>

78

Drag me and watch the console

79

</Rnd>

80

</div>

81

);

82

}

83

84

// Conditional drag prevention

85

<Rnd

86

default={{ x: 0, y: 0, width: 200, height: 150 }}

87

onDragStart={(e, d) => {

88

// Prevent drag if certain condition is met

89

if (someCondition) {

90

console.log('Drag prevented');

91

return false; // Cancel drag

92

}

93

}}

94

>

95

Conditionally draggable

96

</Rnd>

97

```

98

99

### Resize Event Callbacks

100

101

Handle all phases of resize interactions with size delta and position information.

102

103

```typescript { .api }

104

/**

105

* Called when resize operation starts

106

* Can return false to cancel the resize operation

107

*/

108

onResizeStart?: RndResizeStartCallback;

109

110

/**

111

* Called continuously during resize operation

112

*/

113

onResize?: RndResizeCallback;

114

115

/**

116

* Called when resize operation completes

117

*/

118

onResizeStop?: RndResizeCallback;

119

120

type RndResizeStartCallback = (

121

e: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>,

122

dir: ResizeDirection,

123

elementRef: HTMLElement

124

) => void | boolean;

125

126

type RndResizeCallback = (

127

e: MouseEvent | TouchEvent,

128

dir: ResizeDirection,

129

elementRef: HTMLElement,

130

delta: ResizableDelta,

131

position: Position

132

) => void;

133

134

interface ResizableDelta {

135

/** Change in width since resize started */

136

width: number;

137

/** Change in height since resize started */

138

height: number;

139

}

140

141

type ResizeDirection =

142

| "top" | "right" | "bottom" | "left"

143

| "topRight" | "bottomRight" | "bottomLeft" | "topLeft";

144

```

145

146

**Usage Examples:**

147

148

```typescript

149

function ResizeTrackingExample() {

150

const [resizeInfo, setResizeInfo] = React.useState<string>('');

151

152

return (

153

<div>

154

<div>Resize Status: {resizeInfo}</div>

155

<Rnd

156

default={{ x: 0, y: 0, width: 200, height: 150 }}

157

onResizeStart={(e, dir, ref) => {

158

setResizeInfo(`Resize started from ${dir} handle`);

159

console.log('Resize started:', dir, ref.getBoundingClientRect());

160

}}

161

onResize={(e, dir, ref, delta, position) => {

162

setResizeInfo(

163

`Resizing ${dir}: ${ref.style.width} x ${ref.style.height}, ` +

164

`delta: (${delta.width}, ${delta.height}), pos: (${position.x}, ${position.y})`

165

);

166

}}

167

onResizeStop={(e, dir, ref, delta, position) => {

168

setResizeInfo(`Resize ended: ${ref.style.width} x ${ref.style.height}`);

169

console.log('Final size:', ref.style.width, ref.style.height);

170

console.log('Final position:', position);

171

}}

172

>

173

Resize me and watch the console

174

</Rnd>

175

</div>

176

);

177

}

178

179

// Conditional resize prevention

180

<Rnd

181

default={{ x: 0, y: 0, width: 200, height: 150 }}

182

onResizeStart={(e, dir, ref) => {

183

// Prevent resize from certain handles

184

if (dir === 'top' || dir === 'topLeft' || dir === 'topRight') {

185

console.log('Top resize prevented');

186

return false; // Cancel resize

187

}

188

}}

189

>

190

Only bottom/side resize allowed

191

</Rnd>

192

```

193

194

### State Management Integration

195

196

Integrate with React state management for controlled components.

197

198

```typescript

199

function ControlledRndExample() {

200

const [state, setState] = React.useState({

201

x: 0,

202

y: 0,

203

width: 200,

204

height: 150,

205

});

206

207

return (

208

<Rnd

209

size={{ width: state.width, height: state.height }}

210

position={{ x: state.x, y: state.y }}

211

onDragStop={(e, d) => {

212

setState(prev => ({

213

...prev,

214

x: d.x,

215

y: d.y,

216

}));

217

}}

218

onResizeStop={(e, direction, ref, delta, position) => {

219

setState({

220

width: ref.style.width,

221

height: ref.style.height,

222

...position,

223

});

224

}}

225

>

226

Controlled component with state

227

</Rnd>

228

);

229

}

230

```

231

232

### Mouse Event Callbacks

233

234

Handle general mouse events on the component.

235

236

```typescript { .api }

237

/**

238

* Called on mouse down events

239

* Note: This is a native MouseEvent, not React SyntheticEvent

240

*/

241

onMouseDown?: (e: MouseEvent) => void;

242

243

/**

244

* Called on mouse up events

245

* Note: This is a native MouseEvent, not React SyntheticEvent

246

*/

247

onMouseUp?: (e: MouseEvent) => void;

248

```

249

250

**Usage Examples:**

251

252

```typescript

253

<Rnd

254

default={{ x: 0, y: 0, width: 200, height: 150 }}

255

onMouseDown={(e) => {

256

console.log('Mouse down at:', e.clientX, e.clientY);

257

}}

258

onMouseUp={(e) => {

259

console.log('Mouse up at:', e.clientX, e.clientY);

260

}}

261

>

262

General mouse event handling

263

</Rnd>

264

```

265

266

## Advanced Event Patterns

267

268

### Event Coordination

269

270

Coordinate between drag and resize events for complex interactions.

271

272

```typescript

273

function CoordinatedEventsExample() {

274

const [isDragging, setIsDragging] = React.useState(false);

275

const [isResizing, setIsResizing] = React.useState(false);

276

277

return (

278

<Rnd

279

default={{ x: 0, y: 0, width: 200, height: 150 }}

280

onDragStart={() => {

281

setIsDragging(true);

282

console.log('Started dragging');

283

}}

284

onDragStop={() => {

285

setIsDragging(false);

286

console.log('Stopped dragging');

287

}}

288

onResizeStart={() => {

289

setIsResizing(true);

290

console.log('Started resizing');

291

}}

292

onResizeStop={() => {

293

setIsResizing(false);

294

console.log('Stopped resizing');

295

}}

296

style={{

297

border: isDragging ? '2px solid blue' : isResizing ? '2px solid red' : '1px solid gray',

298

}}

299

>

300

Visual feedback during interactions

301

</Rnd>

302

);

303

}

304

```

305

306

### Validation and Constraints

307

308

Use event callbacks to implement custom validation and constraints.

309

310

```typescript

311

function ValidationExample() {

312

const [errors, setErrors] = React.useState<string[]>([]);

313

314

return (

315

<div>

316

{errors.map((error, i) => (

317

<div key={i} style={{ color: 'red' }}>{error}</div>

318

))}

319

<Rnd

320

default={{ x: 0, y: 0, width: 200, height: 150 }}

321

onDrag={(e, d) => {

322

const newErrors: string[] = [];

323

if (d.x < 0) newErrors.push('Cannot move to negative X');

324

if (d.y < 0) newErrors.push('Cannot move to negative Y');

325

setErrors(newErrors);

326

}}

327

onResize={(e, dir, ref, delta, position) => {

328

const newErrors: string[] = [];

329

const width = parseInt(ref.style.width);

330

const height = parseInt(ref.style.height);

331

if (width > 500) newErrors.push('Width cannot exceed 500px');

332

if (height > 400) newErrors.push('Height cannot exceed 400px');

333

setErrors(newErrors);

334

}}

335

>

336

Validation feedback during interaction

337

</Rnd>

338

</div>

339

);

340

}

341

```

342

343

### Performance Optimization

344

345

Optimize event handling for performance-critical applications.

346

347

```typescript

348

function OptimizedEventsExample() {

349

const [position, setPosition] = React.useState({ x: 0, y: 0 });

350

const [size, setSize] = React.useState({ width: 200, height: 150 });

351

352

// Debounced state updates

353

const debouncedUpdatePosition = React.useMemo(

354

() => debounce((x: number, y: number) => setPosition({ x, y }), 100),

355

[]

356

);

357

358

return (

359

<Rnd

360

default={{ x: 0, y: 0, width: 200, height: 150 }}

361

onDrag={(e, d) => {

362

// Update immediately for smooth interaction

363

// Debounced state update for expensive operations

364

debouncedUpdatePosition(d.x, d.y);

365

}}

366

onResizeStop={(e, dir, ref, delta, pos) => {

367

// Only update state on stop for better performance

368

setSize({

369

width: parseInt(ref.style.width),

370

height: parseInt(ref.style.height)

371

});

372

setPosition(pos);

373

}}

374

>

375

Performance optimized events

376

</Rnd>

377

);

378

}

379

```