or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

css-styling.mdevent-handling.mdform-controls.mdhtml-attributes.mdhtml-elements.mdindex.md

event-handling.mddocs/

0

# Event Handling

1

2

Synthetic event system providing type-safe event handling for all DOM events with proper event delegation, lifecycle management, and seamless integration with Compose's reactive system.

3

4

## Core Imports

5

6

```kotlin

7

import org.jetbrains.compose.web.events.*

8

import org.jetbrains.compose.web.attributes.*

9

import androidx.compose.runtime.*

10

```

11

12

## Capabilities

13

14

### Base Event System

15

16

Core event interfaces and base functionality providing consistent event handling across all DOM events.

17

18

```kotlin { .api }

19

/**

20

* Base class for all synthetic events with common properties and methods

21

*/

22

abstract class SyntheticEvent<out Element> {

23

/** The element that triggered the event */

24

val target: Element

25

26

/** The element that the event listener is attached to */

27

val currentTarget: Element

28

29

/** Whether the event bubbles up the DOM tree */

30

val bubbles: Boolean

31

32

/** Whether the event can be cancelled */

33

val cancelable: Boolean

34

35

/** Whether the default action has been prevented */

36

val defaultPrevented: Boolean

37

38

/** The event phase (capturing, at target, bubbling) */

39

val eventPhase: Short

40

41

/** Whether the event is trusted (generated by user action) */

42

val isTrusted: Boolean

43

44

/** Timestamp when the event was created */

45

val timeStamp: Double

46

47

/** Event type string */

48

val type: String

49

50

/**

51

* Prevent the default action associated with the event

52

*/

53

fun preventDefault()

54

55

/**

56

* Stop the event from bubbling up the DOM tree

57

*/

58

fun stopPropagation()

59

60

/**

61

* Stop the event from bubbling and prevent other listeners on the same element

62

*/

63

fun stopImmediatePropagation()

64

}

65

66

/**

67

* Interface for event listener registration scope

68

*/

69

interface EventsListenerScope<TElement> {

70

fun addEventListener(type: String, listener: (SyntheticEvent<TElement>) -> Unit)

71

}

72

```

73

74

### Mouse Events

75

76

Comprehensive mouse event handling with detailed position and button information.

77

78

```kotlin { .api }

79

/**

80

* Mouse event with position and button details

81

*/

82

interface SyntheticMouseEvent : SyntheticEvent<Element> {

83

/** Horizontal coordinate relative to the viewport */

84

val clientX: Double

85

86

/** Vertical coordinate relative to the viewport */

87

val clientY: Double

88

89

/** Horizontal coordinate relative to the entire document */

90

val pageX: Double

91

92

/** Vertical coordinate relative to the entire document */

93

val pageY: Double

94

95

/** Horizontal coordinate relative to the target element */

96

val offsetX: Double

97

98

/** Vertical coordinate relative to the target element */

99

val offsetY: Double

100

101

/** Horizontal coordinate relative to the screen */

102

val screenX: Double

103

104

/** Vertical coordinate relative to the screen */

105

val screenY: Double

106

107

/** Mouse button that was pressed (0: left, 1: middle, 2: right) */

108

val button: Short

109

110

/** Bitmask of all pressed mouse buttons */

111

val buttons: Short

112

113

/** Whether Alt key was pressed */

114

val altKey: Boolean

115

116

/** Whether Ctrl key was pressed */

117

val ctrlKey: Boolean

118

119

/** Whether Meta key was pressed (Cmd on Mac, Windows key on PC) */

120

val metaKey: Boolean

121

122

/** Whether Shift key was pressed */

123

val shiftKey: Boolean

124

125

/** Related target element (for mouseover/mouseout events) */

126

val relatedTarget: Element?

127

}

128

```

129

130

**Mouse Event Handlers:**

131

132

```kotlin { .api }

133

/**

134

* Click event (mouse button press and release)

135

*/

136

fun AttrsScope<*>.onClick(listener: (SyntheticMouseEvent) -> Unit)

137

138

/**

139

* Double-click event

140

*/

141

fun AttrsScope<*>.onDoubleClick(listener: (SyntheticMouseEvent) -> Unit)

142

143

/**

144

* Mouse button press

145

*/

146

fun AttrsScope<*>.onMouseDown(listener: (SyntheticMouseEvent) -> Unit)

147

148

/**

149

* Mouse button release

150

*/

151

fun AttrsScope<*>.onMouseUp(listener: (SyntheticMouseEvent) -> Unit)

152

153

/**

154

* Mouse enters element (does not bubble)

155

*/

156

fun AttrsScope<*>.onMouseEnter(listener: (SyntheticMouseEvent) -> Unit)

157

158

/**

159

* Mouse leaves element (does not bubble)

160

*/

161

fun AttrsScope<*>.onMouseLeave(listener: (SyntheticMouseEvent) -> Unit)

162

163

/**

164

* Mouse enters element or its children (bubbles)

165

*/

166

fun AttrsScope<*>.onMouseOver(listener: (SyntheticMouseEvent) -> Unit)

167

168

/**

169

* Mouse leaves element or its children (bubbles)

170

*/

171

fun AttrsScope<*>.onMouseOut(listener: (SyntheticMouseEvent) -> Unit)

172

173

/**

174

* Mouse moves over element

175

*/

176

fun AttrsScope<*>.onMouseMove(listener: (SyntheticMouseEvent) -> Unit)

177

178

/**

179

* Context menu event (right-click)

180

*/

181

fun AttrsScope<*>.onContextMenu(listener: (SyntheticMouseEvent) -> Unit)

182

```

183

184

**Usage Examples:**

185

186

```kotlin

187

Button({

188

onClick { event ->

189

console.log("Button clicked at (${event.clientX}, ${event.clientY})")

190

if (event.ctrlKey) {

191

console.log("Ctrl+Click detected")

192

}

193

}

194

195

onMouseEnter { event ->

196

// Change visual state on hover

197

event.target.style.backgroundColor = "lightblue"

198

}

199

200

onMouseLeave { event ->

201

// Reset visual state

202

event.target.style.backgroundColor = ""

203

}

204

}) {

205

Text("Interactive Button")

206

}

207

208

Div({

209

onMouseMove { event ->

210

// Track mouse position

211

updateMousePosition(event.offsetX, event.offsetY)

212

}

213

214

onContextMenu { event ->

215

event.preventDefault() // Prevent default context menu

216

showCustomContextMenu(event.clientX, event.clientY)

217

}

218

}) {

219

Text("Mouse tracking area")

220

}

221

```

222

223

### Keyboard Events

224

225

Keyboard event handling with key identification and modifier key support.

226

227

```kotlin { .api }

228

/**

229

* Keyboard event with key and modifier information

230

*/

231

interface SyntheticKeyboardEvent : SyntheticEvent<Element> {

232

/** The key value (human-readable key name) */

233

val key: String

234

235

/** The physical key code */

236

val code: String

237

238

/** Legacy key code (deprecated but sometimes needed) */

239

val keyCode: Int

240

241

/** Whether Alt key was pressed */

242

val altKey: Boolean

243

244

/** Whether Ctrl key was pressed */

245

val ctrlKey: Boolean

246

247

/** Whether Meta key was pressed */

248

val metaKey: Boolean

249

250

/** Whether Shift key was pressed */

251

val shiftKey: Boolean

252

253

/** Whether the key is being held down (for keydown) */

254

val repeat: Boolean

255

256

/** Location of the key on the keyboard */

257

val location: Int

258

}

259

```

260

261

**Keyboard Event Handlers:**

262

263

```kotlin { .api }

264

/**

265

* Key press down

266

*/

267

fun AttrsScope<*>.onKeyDown(listener: (SyntheticKeyboardEvent) -> Unit)

268

269

/**

270

* Key release

271

*/

272

fun AttrsScope<*>.onKeyUp(listener: (SyntheticKeyboardEvent) -> Unit)

273

274

/**

275

* Key press (deprecated, use keydown instead)

276

*/

277

fun AttrsScope<*>.onKeyPress(listener: (SyntheticKeyboardEvent) -> Unit)

278

```

279

280

**Usage Examples:**

281

282

```kotlin

283

TextInput(

284

value = inputValue,

285

attrs = {

286

onKeyDown { event ->

287

when (event.key) {

288

"Enter" -> {

289

if (event.ctrlKey) {

290

// Ctrl+Enter: submit form

291

submitForm()

292

} else {

293

// Enter: new line

294

handleEnterKey()

295

}

296

}

297

"Escape" -> {

298

// Cancel operation

299

cancelEdit()

300

}

301

"Tab" -> {

302

if (event.shiftKey) {

303

// Shift+Tab: previous field

304

focusPreviousField()

305

}

306

// Tab is handled by browser

307

}

308

}

309

}

310

311

onKeyUp { event ->

312

// Handle key release if needed

313

if (event.key == "Control") {

314

hideShortcutHints()

315

}

316

}

317

}

318

)

319

320

// Global keyboard shortcuts

321

Div({

322

tabIndex(0) // Make focusable

323

onKeyDown { event ->

324

if (event.ctrlKey) {

325

when (event.key) {

326

"s" -> {

327

event.preventDefault()

328

saveDocument()

329

}

330

"z" -> {

331

event.preventDefault()

332

if (event.shiftKey) redo() else undo()

333

}

334

}

335

}

336

}

337

}) {

338

// Application content

339

}

340

```

341

342

### Focus Events

343

344

Focus and blur events for managing element focus states and accessibility.

345

346

```kotlin { .api }

347

/**

348

* Focus event

349

*/

350

interface SyntheticFocusEvent : SyntheticEvent<Element> {

351

/** Related target element (element losing/gaining focus) */

352

val relatedTarget: Element?

353

}

354

```

355

356

**Focus Event Handlers:**

357

358

```kotlin { .api }

359

/**

360

* Element gains focus

361

*/

362

fun AttrsScope<*>.onFocus(listener: (SyntheticFocusEvent) -> Unit)

363

364

/**

365

* Element loses focus

366

*/

367

fun AttrsScope<*>.onBlur(listener: (SyntheticFocusEvent) -> Unit)

368

369

/**

370

* Element gains focus (bubbles)

371

*/

372

fun AttrsScope<*>.onFocusIn(listener: (SyntheticFocusEvent) -> Unit)

373

374

/**

375

* Element loses focus (bubbles)

376

*/

377

fun AttrsScope<*>.onFocusOut(listener: (SyntheticFocusEvent) -> Unit)

378

```

379

380

**Usage Examples:**

381

382

```kotlin

383

TextInput(

384

value = inputValue,

385

attrs = {

386

onFocus { event ->

387

// Highlight field on focus

388

event.target.style.borderColor = "blue"

389

showFieldHelp()

390

}

391

392

onBlur { event ->

393

// Validate field on blur

394

event.target.style.borderColor = ""

395

validateField(inputValue)

396

hideFieldHelp()

397

}

398

}

399

)

400

```

401

402

### Form Events

403

404

Events specific to form elements and form interactions.

405

406

```kotlin { .api }

407

/**

408

* Input event for real-time input changes

409

*/

410

interface SyntheticInputEvent : SyntheticEvent<Element> {

411

/** Input value for input elements */

412

val value: String

413

414

/** Input data for composition events */

415

val data: String?

416

417

/** Input type information */

418

val inputType: String

419

}

420

421

/**

422

* Change event for input value changes (on blur/commit)

423

*/

424

interface SyntheticChangeEvent : SyntheticEvent<Element> {

425

/** Changed value */

426

val value: String

427

}

428

429

/**

430

* Form submission event

431

*/

432

interface SyntheticSubmitEvent : SyntheticEvent<HTMLFormElement>

433

434

/**

435

* Form reset event

436

*/

437

interface SyntheticResetEvent : SyntheticEvent<HTMLFormElement>

438

```

439

440

**Form Event Handlers:**

441

442

```kotlin { .api }

443

/**

444

* Input value changes (real-time)

445

*/

446

fun AttrsScope<HTMLInputElement>.onInput(listener: (SyntheticInputEvent) -> Unit)

447

fun AttrsScope<HTMLTextAreaElement>.onInput(listener: (SyntheticInputEvent) -> Unit)

448

449

/**

450

* Input value committed (on blur or enter)

451

*/

452

fun AttrsScope<HTMLInputElement>.onChange(listener: (SyntheticChangeEvent) -> Unit)

453

fun AttrsScope<HTMLSelectElement>.onChange(listener: (SyntheticChangeEvent) -> Unit)

454

455

/**

456

* Form submission

457

*/

458

fun AttrsScope<HTMLFormElement>.onSubmit(listener: (SyntheticSubmitEvent) -> Unit)

459

460

/**

461

* Form reset

462

*/

463

fun AttrsScope<HTMLFormElement>.onReset(listener: (SyntheticResetEvent) -> Unit)

464

465

/**

466

* Invalid input (validation failure)

467

*/

468

fun AttrsScope<HTMLInputElement>.onInvalid(listener: (SyntheticEvent<HTMLInputElement>) -> Unit)

469

```

470

471

**Usage Examples:**

472

473

```kotlin

474

Form({

475

onSubmit { event ->

476

event.preventDefault() // Prevent default form submission

477

478

if (validateForm()) {

479

submitFormData()

480

}

481

}

482

483

onReset { event ->

484

resetFormState()

485

}

486

}) {

487

TextInput(

488

value = emailValue,

489

attrs = {

490

type(InputType.Email)

491

required()

492

493

onInput { event ->

494

// Real-time validation

495

emailValue = event.value

496

validateEmail(event.value)

497

}

498

499

onChange { event ->

500

// Final validation on commit

501

if (event.value.isNotEmpty()) {

502

checkEmailAvailability(event.value)

503

}

504

}

505

506

onInvalid { event ->

507

// Handle validation failure

508

showValidationError("Please enter a valid email")

509

}

510

}

511

)

512

}

513

```

514

515

### Touch Events

516

517

Touch event handling for mobile and touch-enabled devices.

518

519

```kotlin { .api }

520

/**

521

* Touch event with touch point information

522

*/

523

interface SyntheticTouchEvent : SyntheticEvent<Element> {

524

/** List of all touch points */

525

val touches: TouchList

526

527

/** List of touch points that changed */

528

val changedTouches: TouchList

529

530

/** List of touch points on the current target */

531

val targetTouches: TouchList

532

533

/** Whether Alt key was pressed */

534

val altKey: Boolean

535

536

/** Whether Ctrl key was pressed */

537

val ctrlKey: Boolean

538

539

/** Whether Meta key was pressed */

540

val metaKey: Boolean

541

542

/** Whether Shift key was pressed */

543

val shiftKey: Boolean

544

}

545

546

/**

547

* Individual touch point

548

*/

549

interface Touch {

550

/** Unique identifier for the touch */

551

val identifier: Int

552

553

/** Target element */

554

val target: Element

555

556

/** Touch coordinates */

557

val clientX: Double

558

val clientY: Double

559

val pageX: Double

560

val pageY: Double

561

val screenX: Double

562

val screenY: Double

563

564

/** Touch area */

565

val radiusX: Double

566

val radiusY: Double

567

568

/** Touch pressure */

569

val force: Double

570

}

571

```

572

573

**Touch Event Handlers:**

574

575

```kotlin { .api }

576

/**

577

* Touch starts

578

*/

579

fun AttrsScope<*>.onTouchStart(listener: (SyntheticTouchEvent) -> Unit)

580

581

/**

582

* Touch moves

583

*/

584

fun AttrsScope<*>.onTouchMove(listener: (SyntheticTouchEvent) -> Unit)

585

586

/**

587

* Touch ends

588

*/

589

fun AttrsScope<*>.onTouchEnd(listener: (SyntheticTouchEvent) -> Unit)

590

591

/**

592

* Touch cancelled

593

*/

594

fun AttrsScope<*>.onTouchCancel(listener: (SyntheticTouchEvent) -> Unit)

595

```

596

597

### Clipboard Events

598

599

Clipboard operation events for copy, cut, and paste operations.

600

601

```kotlin { .api }

602

/**

603

* Clipboard event

604

*/

605

interface SyntheticClipboardEvent : SyntheticEvent<Element> {

606

/** Clipboard data */

607

val clipboardData: DataTransfer?

608

}

609

```

610

611

**Clipboard Event Handlers:**

612

613

```kotlin { .api }

614

/**

615

* Copy operation

616

*/

617

fun AttrsScope<*>.onCopy(listener: (SyntheticClipboardEvent) -> Unit)

618

619

/**

620

* Cut operation

621

*/

622

fun AttrsScope<*>.onCut(listener: (SyntheticClipboardEvent) -> Unit)

623

624

/**

625

* Paste operation

626

*/

627

fun AttrsScope<*>.onPaste(listener: (SyntheticClipboardEvent) -> Unit)

628

```

629

630

### Animation Events

631

632

CSS animation and transition events.

633

634

```kotlin { .api }

635

/**

636

* CSS animation event

637

*/

638

interface SyntheticAnimationEvent : SyntheticEvent<Element> {

639

/** Animation name */

640

val animationName: String

641

642

/** Elapsed time */

643

val elapsedTime: Double

644

645

/** Pseudo element */

646

val pseudoElement: String

647

}

648

649

/**

650

* CSS transition event

651

*/

652

interface SyntheticTransitionEvent : SyntheticEvent<Element> {

653

/** Property name that transitioned */

654

val propertyName: String

655

656

/** Elapsed time */

657

val elapsedTime: Double

658

659

/** Pseudo element */

660

val pseudoElement: String

661

}

662

```

663

664

**Animation Event Handlers:**

665

666

```kotlin { .api }

667

/**

668

* Animation starts

669

*/

670

fun AttrsScope<*>.onAnimationStart(listener: (SyntheticAnimationEvent) -> Unit)

671

672

/**

673

* Animation ends

674

*/

675

fun AttrsScope<*>.onAnimationEnd(listener: (SyntheticAnimationEvent) -> Unit)

676

677

/**

678

* Animation iteration

679

*/

680

fun AttrsScope<*>.onAnimationIteration(listener: (SyntheticAnimationEvent) -> Unit)

681

682

/**

683

* Transition ends

684

*/

685

fun AttrsScope<*>.onTransitionEnd(listener: (SyntheticTransitionEvent) -> Unit)

686

```

687

688

### Media Events

689

690

Events for audio and video elements.

691

692

```kotlin { .api }

693

/**

694

* Media is ready to play

695

*/

696

fun AttrsScope<HTMLAudioElement>.onCanPlay(listener: (SyntheticEvent<HTMLAudioElement>) -> Unit)

697

fun AttrsScope<HTMLVideoElement>.onCanPlay(listener: (SyntheticEvent<HTMLVideoElement>) -> Unit)

698

699

/**

700

* Media starts playing

701

*/

702

fun AttrsScope<HTMLAudioElement>.onPlay(listener: (SyntheticEvent<HTMLAudioElement>) -> Unit)

703

fun AttrsScope<HTMLVideoElement>.onPlay(listener: (SyntheticEvent<HTMLVideoElement>) -> Unit)

704

705

/**

706

* Media pauses

707

*/

708

fun AttrsScope<HTMLAudioElement>.onPause(listener: (SyntheticEvent<HTMLAudioElement>) -> Unit)

709

fun AttrsScope<HTMLVideoElement>.onPause(listener: (SyntheticEvent<HTMLVideoElement>) -> Unit)

710

711

/**

712

* Media ends

713

*/

714

fun AttrsScope<HTMLAudioElement>.onEnded(listener: (SyntheticEvent<HTMLAudioElement>) -> Unit)

715

fun AttrsScope<HTMLVideoElement>.onEnded(listener: (SyntheticEvent<HTMLVideoElement>) -> Unit)

716

717

/**

718

* Volume changes

719

*/

720

fun AttrsScope<HTMLAudioElement>.onVolumeChange(listener: (SyntheticEvent<HTMLAudioElement>) -> Unit)

721

fun AttrsScope<HTMLVideoElement>.onVolumeChange(listener: (SyntheticEvent<HTMLVideoElement>) -> Unit)

722

```

723

724

### Window and Document Events

725

726

Global events for window and document-level interactions.

727

728

```kotlin { .api }

729

/**

730

* Window/element resize

731

*/

732

fun AttrsScope<*>.onResize(listener: (SyntheticEvent<Element>) -> Unit)

733

734

/**

735

* Scroll event

736

*/

737

fun AttrsScope<*>.onScroll(listener: (SyntheticEvent<Element>) -> Unit)

738

739

/**

740

* Content loaded

741

*/

742

fun AttrsScope<*>.onLoad(listener: (SyntheticEvent<Element>) -> Unit)

743

744

/**

745

* Loading error

746

*/

747

fun AttrsScope<*>.onError(listener: (SyntheticEvent<Element>) -> Unit)

748

749

/**

750

* Before page unload

751

*/

752

fun AttrsScope<*>.onBeforeUnload(listener: (SyntheticEvent<Element>) -> Unit)

753

754

/**

755

* Page unload

756

*/

757

fun AttrsScope<*>.onUnload(listener: (SyntheticEvent<Element>) -> Unit)

758

```

759

760

## Types

761

762

```kotlin { .api }

763

interface TouchList {

764

val length: Int

765

fun item(index: Int): Touch?

766

}

767

768

interface DataTransfer {

769

var dropEffect: String

770

var effectAllowed: String

771

val files: FileList

772

val items: DataTransferItemList

773

val types: Array<String>

774

775

fun clearData(format: String? = null)

776

fun getData(format: String): String

777

fun setData(format: String, data: String)

778

fun setDragImage(img: Element, xOffset: Int, yOffset: Int)

779

}

780

```