or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-apis.mddevice.mddom-events.mdindex.mdnavigation.mdnetwork.mdobservers.mdspecialized.mdstate-management.mdstorage.mdtiming.mdutilities.md

dom-events.mddocs/

0

# DOM Events & Interactions

1

2

Event handling hooks for click detection, keyboard shortcuts, mouse interactions, hover states, focus management, and touch gestures.

3

4

## Capabilities

5

6

### useClickOutside

7

8

Detect clicks outside target element(s) with configurable events and multiple node support.

9

10

```typescript { .api }

11

/**

12

* Detect clicks outside target element(s)

13

* @param handler - Function to call when click outside occurs

14

* @param events - Array of event names to listen for (default: ['mousedown', 'touchstart'])

15

* @param nodes - Additional nodes to consider as "inside"

16

* @returns Ref callback to attach to target element

17

*/

18

function useClickOutside<T extends HTMLElement = any>(

19

handler: () => void,

20

events?: string[] | null,

21

nodes?: HTMLElement[]

22

): React.RefCallback<T | null>;

23

```

24

25

**Usage Examples:**

26

27

```typescript

28

import { useClickOutside } from "@mantine/hooks";

29

import { useRef } from "react";

30

31

// Basic modal/dropdown

32

function Modal({ onClose }: { onClose: () => void }) {

33

const ref = useClickOutside(onClose);

34

35

return <div ref={ref}>Modal content</div>;

36

}

37

38

// Multiple elements considered "inside"

39

function ComplexDropdown() {

40

const triggerRef = useRef<HTMLButtonElement>(null);

41

const dropdownRef = useClickOutside(

42

() => setOpened(false),

43

['mousedown', 'touchstart'],

44

[triggerRef.current] // Don't close when clicking trigger

45

);

46

47

return (

48

<>

49

<button ref={triggerRef}>Open</button>

50

<div ref={dropdownRef}>Dropdown content</div>

51

</>

52

);

53

}

54

```

55

56

### useHotkeys

57

58

Keyboard shortcuts handler with key combinations and configurable options.

59

60

```typescript { .api }

61

/**

62

* Keyboard shortcuts handler

63

* @param hotkeys - Array of [key combination, handler, options] tuples

64

* @param tagsToIgnore - HTML tags to ignore (default: ['INPUT', 'TEXTAREA', 'SELECT'])

65

* @param triggerOnContentEditable - Whether to trigger on contentEditable elements

66

*/

67

function useHotkeys(

68

hotkeys: HotkeyItem[],

69

tagsToIgnore?: string[],

70

triggerOnContentEditable?: boolean

71

): void;

72

73

/**

74

* Get hotkey handler for manual event handling

75

* @param hotkeys - Array of hotkey configurations

76

* @returns Event handler function

77

*/

78

function getHotkeyHandler(hotkeys: HotkeyItem[]): (event: React.KeyboardEvent<HTMLElement> | KeyboardEvent) => void;

79

80

type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?];

81

82

interface HotkeyItemOptions {

83

preventDefault?: boolean;

84

usePhysicalKeys?: boolean;

85

}

86

```

87

88

**Usage Examples:**

89

90

```typescript

91

import { useHotkeys, getHotkeyHandler } from "@mantine/hooks";

92

93

// Global hotkeys

94

function App() {

95

useHotkeys([

96

['mod+S', () => save()], // Cmd+S on Mac, Ctrl+S on Windows

97

['mod+K', () => openSearch(), { preventDefault: true }],

98

['Escape', () => closeModal()],

99

['shift+?', () => showHelp()],

100

]);

101

}

102

103

// Manual event handling

104

function Editor() {

105

const handleKeyDown = getHotkeyHandler([

106

['mod+B', () => toggleBold()],

107

['mod+I', () => toggleItalic()],

108

]);

109

110

return <textarea onKeyDown={handleKeyDown} />;

111

}

112

```

113

114

### useHover

115

116

Detect hover state on elements with ref-based attachment.

117

118

```typescript { .api }

119

/**

120

* Detect hover state on elements

121

* @returns Object with hover state and ref callback

122

*/

123

function useHover<T extends HTMLElement = any>(): UseHoverReturnValue<T>;

124

125

interface UseHoverReturnValue<T extends HTMLElement = any> {

126

hovered: boolean;

127

ref: React.RefCallback<T | null>;

128

}

129

```

130

131

**Usage Examples:**

132

133

```typescript

134

import { useHover } from "@mantine/hooks";

135

136

function HoverCard() {

137

const { hovered, ref } = useHover();

138

139

return (

140

<div ref={ref} style={{ background: hovered ? 'blue' : 'gray' }}>

141

{hovered ? 'Hovered!' : 'Hover me'}

142

</div>

143

);

144

}

145

```

146

147

### useMove

148

149

Mouse/touch drag interactions with position tracking and directional support.

150

151

```typescript { .api }

152

/**

153

* Mouse/touch drag interactions with position tracking

154

* @param onChange - Callback fired when position changes

155

* @param handlers - Optional start/end handlers

156

* @param dir - Text direction for RTL support

157

* @returns Object with ref callback and active state

158

*/

159

function useMove<T extends HTMLElement = any>(

160

onChange: (value: UseMovePosition) => void,

161

handlers?: UseMoveHandlers,

162

dir?: 'ltr' | 'rtl'

163

): UseMoveReturnValue<T>;

164

165

/**

166

* Clamp position values to 0-1 range

167

* @param position - Position object to clamp

168

* @returns Clamped position

169

*/

170

function clampUseMovePosition(position: UseMovePosition): UseMovePosition;

171

172

interface UseMovePosition {

173

x: number; // 0-1 range

174

y: number; // 0-1 range

175

}

176

177

interface UseMoveHandlers {

178

onScrubStart?: () => void;

179

onScrubEnd?: () => void;

180

}

181

182

interface UseMoveReturnValue<T extends HTMLElement = any> {

183

ref: React.RefCallback<T | null>;

184

active: boolean;

185

}

186

```

187

188

**Usage Examples:**

189

190

```typescript

191

import { useMove, clampUseMovePosition } from "@mantine/hooks";

192

193

// Color picker

194

function ColorPicker() {

195

const [value, setValue] = useState({ x: 0.5, y: 0.5 });

196

197

const { ref, active } = useMove((position) => {

198

setValue(clampUseMovePosition(position));

199

}, {

200

onScrubStart: () => console.log('Started dragging'),

201

onScrubEnd: () => console.log('Stopped dragging')

202

});

203

204

return (

205

<div ref={ref} style={{ position: 'relative', width: 200, height: 200 }}>

206

<div

207

style={{

208

position: 'absolute',

209

left: `${value.x * 100}%`,

210

top: `${value.y * 100}%`,

211

transform: 'translate(-50%, -50%)'

212

}}

213

>

214

Thumb

215

</div>

216

</div>

217

);

218

}

219

```

220

221

### useFocusWithin

222

223

Detect focus within element tree with callbacks for focus/blur events.

224

225

```typescript { .api }

226

/**

227

* Detect focus within element tree

228

* @param options - Configuration for focus callbacks

229

* @returns Object with focus state and ref callback

230

*/

231

function useFocusWithin<T extends HTMLElement = any>(options?: UseFocusWithinOptions): UseFocusWithinReturnValue<T>;

232

233

interface UseFocusWithinOptions {

234

onFocus?: () => void;

235

onBlur?: () => void;

236

}

237

238

interface UseFocusWithinReturnValue<T extends HTMLElement = any> {

239

focused: boolean;

240

ref: React.RefCallback<T | null>;

241

}

242

```

243

244

### useFocusTrap

245

246

Trap focus within element for accessibility (modals, dropdowns).

247

248

```typescript { .api }

249

/**

250

* Trap focus within element for accessibility

251

* @param active - Whether focus trap is active

252

* @returns Ref callback to attach to container element

253

*/

254

function useFocusTrap(active?: boolean): React.RefCallback<HTMLElement | null>;

255

```

256

257

### useLongPress

258

259

Detect long press gestures with configurable threshold and callbacks.

260

261

```typescript { .api }

262

/**

263

* Detect long press gestures

264

* @param callback - Function to call on long press

265

* @param options - Configuration for threshold and callbacks

266

* @returns Object with ref callback

267

*/

268

function useLongPress<T extends HTMLElement = any>(

269

callback: () => void,

270

options?: UseLongPressOptions

271

): UseLongPressReturnValue<T>;

272

273

interface UseLongPressOptions {

274

threshold?: number; // Duration in ms (default: 500)

275

onStart?: () => void;

276

onFinish?: () => void;

277

onCancel?: () => void;

278

}

279

280

interface UseLongPressReturnValue<T extends HTMLElement = any> {

281

ref: React.RefCallback<T | null>;

282

}

283

```

284

285

### useEventListener

286

287

Attach event listeners to elements with ref callback and automatic cleanup.

288

289

```typescript { .api }

290

/**

291

* Attach event listeners to elements

292

* @param type - Event type

293

* @param listener - Event handler function

294

* @param options - Event listener options

295

* @returns Ref callback to attach to target element

296

*/

297

function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = any>(

298

type: K,

299

listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any,

300

options?: boolean | AddEventListenerOptions

301

): React.RefCallback<T | null>;

302

```

303

304

### useWindowEvent

305

306

Attach event listeners to window object with automatic cleanup.

307

308

```typescript { .api }

309

/**

310

* Attach event listeners to window object

311

* @param type - Event type

312

* @param listener - Event handler function

313

* @param options - Event listener options

314

*/

315

function useWindowEvent<K extends string>(

316

type: K,

317

listener: K extends keyof WindowEventMap

318

? (this: Window, ev: WindowEventMap[K]) => void

319

: (this: Window, ev: CustomEvent) => void,

320

options?: boolean | AddEventListenerOptions

321

): void;

322

```

323

324

**Usage Examples:**

325

326

```typescript

327

import { useEventListener, useWindowEvent } from "@mantine/hooks";

328

329

// Element-specific events

330

function InteractiveElement() {

331

const ref = useEventListener('click', (event) => {

332

console.log('Element clicked', event);

333

});

334

335

return <div ref={ref}>Click me</div>;

336

}

337

338

// Global window events

339

function WindowEventHandler() {

340

useWindowEvent('resize', () => {

341

console.log('Window resized');

342

});

343

344

useWindowEvent('keydown', (event) => {

345

if (event.key === 'Escape') {

346

console.log('Escape pressed');

347

}

348

});

349

350

return <div>Component with window event handlers</div>;

351

}

352

```