or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-react.mdcss-styling.mddom-integration.mderror-boundaries.mdevent-system.mdindex.mdreact-hooks.mdrouting.mdserver-side-rendering.mdtesting-utilities.md
tile.json

event-system.mddocs/

Event System

Type-safe synthetic event system with 16 specialized event modules covering all React event types. Provides complete event property access with compile-time safety.

Base Event System

type synthetic('a);

/* Cast any event to generic synthetic event */
external toSyntheticEvent: synthetic('a) => Synthetic.t = "%identity";

Synthetic Event Module

Base event properties available on all events:

module Synthetic = {
  type tag;
  type t = synthetic(tag);
  
  /* Event properties */
  [@bs.get] external bubbles: synthetic('a) => bool = "bubbles";
  [@bs.get] external cancelable: synthetic('a) => bool = "cancelable";
  [@bs.get] external currentTarget: synthetic('a) => Js.t({..}) = "currentTarget";
  [@bs.get] external defaultPrevented: synthetic('a) => bool = "defaultPrevented";
  [@bs.get] external eventPhase: synthetic('a) => int = "eventPhase";
  [@bs.get] external isTrusted: synthetic('a) => bool = "isTrusted";
  [@bs.get] external nativeEvent: synthetic('a) => Js.t({..}) = "nativeEvent";
  [@bs.get] external target: synthetic('a) => Js.t({..}) = "target";
  [@bs.get] external timeStamp: synthetic('a) => float = "timeStamp";
  [@bs.get] external type_: synthetic('a) => string = "type";
  
  /* Event methods */
  [@bs.send] external preventDefault: synthetic('a) => unit = "preventDefault";
  [@bs.send] external isDefaultPrevented: synthetic('a) => bool = "isDefaultPrevented";
  [@bs.send] external stopPropagation: synthetic('a) => unit = "stopPropagation";
  [@bs.send] external isPropagationStopped: synthetic('a) => bool = "isPropagationStopped";
  [@bs.send] external persist: synthetic('a) => unit = "persist";
};

Mouse Events

module Mouse = {
  type tag;
  type t = synthetic(tag);
  
  /* Mouse-specific properties */
  [@bs.get] external altKey: t => bool = "altKey";
  [@bs.get] external button: t => int = "button";
  [@bs.get] external buttons: t => int = "buttons";
  [@bs.get] external clientX: t => int = "clientX";
  [@bs.get] external clientY: t => int = "clientY";
  [@bs.get] external ctrlKey: t => bool = "ctrlKey";
  [@bs.send] external getModifierState: (t, string) => bool = "getModifierState";
  [@bs.get] external metaKey: t => bool = "metaKey";
  [@bs.get] external movementX: t => int = "movementX";
  [@bs.get] external movementY: t => int = "movementY";
  [@bs.get] external pageX: t => int = "pageX";
  [@bs.get] external pageY: t => int = "pageY";
  [@bs.get] [@bs.return nullable] external relatedTarget: t => option(Js.t({..})) = "relatedTarget";
  [@bs.get] external screenX: t => int = "screenX";
  [@bs.get] external screenY: t => int = "screenY";
  [@bs.get] external shiftKey: t => bool = "shiftKey";
  
  /* All Synthetic properties also available */
};

Keyboard Events

module Keyboard = {
  type tag;
  type t = synthetic(tag);
  
  /* Keyboard-specific properties */
  [@bs.get] external altKey: t => bool = "altKey";
  [@bs.get] external charCode: t => int = "charCode";
  [@bs.get] external ctrlKey: t => bool = "ctrlKey";
  [@bs.send] external getModifierState: (t, string) => bool = "getModifierState";
  [@bs.get] external key: t => string = "key";
  [@bs.get] external keyCode: t => int = "keyCode";
  [@bs.get] external locale: t => string = "locale";
  [@bs.get] external location: t => int = "location";
  [@bs.get] external metaKey: t => bool = "metaKey";
  [@bs.get] external repeat: t => bool = "repeat";
  [@bs.get] external shiftKey: t => bool = "shiftKey";
  [@bs.get] external which: t => int = "which";
};

Form Events

module Form = {
  type tag;
  type t = synthetic(tag);
  /* Only includes Synthetic properties */
};

Focus Events

module Focus = {
  type tag;
  type t = synthetic(tag);
  
  [@bs.get] [@bs.return nullable] 
  external relatedTarget: t => option(Js.t({..})) = "relatedTarget";
};

Touch Events

module Touch = {
  type tag;
  type t = synthetic(tag);
  
  [@bs.get] external altKey: t => bool = "altKey";
  [@bs.get] external changedTouches: t => Js.t({..}) = "changedTouches";
  [@bs.get] external ctrlKey: t => bool = "ctrlKey";
  [@bs.send] external getModifierState: (t, string) => bool = "getModifierState";
  [@bs.get] external metaKey: t => bool = "metaKey";
  [@bs.get] external shiftKey: t => bool = "shiftKey";
  [@bs.get] external targetTouches: t => Js.t({..}) = "targetTouches";
  [@bs.get] external touches: t => Js.t({..}) = "touches";
};

Drag Events

module Drag = {
  type tag;
  type t = synthetic(tag);
  
  [@bs.get] external dataTransfer: t => Js.t({..}) = "dataTransfer";
  /* Also includes all Mouse properties */
};

Wheel Events

module Wheel = {
  type tag;
  type t = synthetic(tag);
  
  [@bs.get] external deltaMode: t => int = "deltaMode";
  [@bs.get] external deltaX: t => float = "deltaX";
  [@bs.get] external deltaY: t => float = "deltaY";
  [@bs.get] external deltaZ: t => float = "deltaZ";
};

Other Event Modules

module Clipboard = {
  type t = synthetic(tag);
  [@bs.get] external clipboardData: t => Js.t({..}) = "clipboardData";
};

module Composition = {
  type t = synthetic(tag);
  [@bs.get] external data: t => string = "data";
};

module UI = {
  type t = synthetic(tag);
  [@bs.get] external detail: t => int = "detail";
  [@bs.get] external view: t => Dom.window = "view";
};

module Pointer = {
  type t = synthetic(tag);
  [@bs.get] external pointerId: t => Dom.eventPointerId = "pointerId";
  [@bs.get] external width: t => float = "width";
  [@bs.get] external height: t => float = "height";
  [@bs.get] external pressure: t => float = "pressure";
  [@bs.get] external tangentialPressure: t => float = "tangentialPressure";
  [@bs.get] external tiltX: t => int = "tiltX";
  [@bs.get] external tiltY: t => int = "tiltY";
  [@bs.get] external twist: t => int = "twist";
  [@bs.get] external pointerType: t => string = "pointerType";  
  [@bs.get] external isPrimary: t => bool = "isPrimary";
  /* Also includes all Mouse properties */
};

module Animation = {
  type t = synthetic(tag);
  [@bs.get] external animationName: t => string = "animationName";
  [@bs.get] external pseudoElement: t => string = "pseudoElement";
  [@bs.get] external elapsedTime: t => float = "elapsedTime";
};

module Transition = {
  type t = synthetic(tag);
  [@bs.get] external propertyName: t => string = "propertyName";
  [@bs.get] external pseudoElement: t => string = "pseudoElement";
  [@bs.get] external elapsedTime: t => float = "elapsedTime";
};

module Selection = {
  type t = synthetic(tag);
  /* Only includes Synthetic properties */
};

module Media = {
  type t = synthetic(tag);
  /* Only includes Synthetic properties */
};

module Image = {
  type t = synthetic(tag);
  /* Only includes Synthetic properties */
};

Usage Examples

Mouse Event Handling

[@react.component]
let make = () => {
  let handleClick = (event: ReactEvent.Mouse.t) => {
    ReactEvent.Mouse.preventDefault(event);
    
    let x = ReactEvent.Mouse.clientX(event);
    let y = ReactEvent.Mouse.clientY(event);
    let button = ReactEvent.Mouse.button(event);
    let isShiftPressed = ReactEvent.Mouse.shiftKey(event);
    
    Js.log2("Click at:", (x, y));
    Js.log2("Button:", button);
    Js.log2("Shift key:", isShiftPressed);
  };
  
  <button onClick=handleClick>
    {React.string("Click me")}
  </button>
}

Keyboard Event Handling

[@react.component]
let make = () => {
  let handleKeyPress = (event: ReactEvent.Keyboard.t) => {
    let key = ReactEvent.Keyboard.key(event);
    let keyCode = ReactEvent.Keyboard.keyCode(event);
    let isCtrlPressed = ReactEvent.Keyboard.ctrlKey(event);
    
    if (key === "Enter" && isCtrlPressed) {
      ReactEvent.Keyboard.preventDefault(event);
      submitForm();
    };
  };
  
  <textarea onKeyDown=handleKeyPress placeholder="Press Ctrl+Enter to submit" />
}

Form Event Handling

[@react.component]
let make = () => {
  let (inputValue, setInputValue) = React.useState(() => "");
  
  let handleChange = (event: ReactEvent.Form.t) => {
    let target = ReactEvent.Form.target(event);
    let value = target##value;
    setInputValue(_ => value);
  };
  
  let handleSubmit = (event: ReactEvent.Form.t) => {
    ReactEvent.Form.preventDefault(event);
    submitData(inputValue);
  };
  
  <form onSubmit=handleSubmit>
    <input value=inputValue onChange=handleChange />
    <button type_="submit"> {React.string("Submit")} </button>
  </form>
}

Touch Event Handling

[@react.component]
let make = () => {
  let handleTouchStart = (event: ReactEvent.Touch.t) => {
    let touches = ReactEvent.Touch.touches(event);
    let touchCount = touches##length;
    
    if (touchCount > 1) {
      ReactEvent.Touch.preventDefault(event);
      Js.log("Multi-touch detected");
    };
  };
  
  <div onTouchStart=handleTouchStart className="touch-area">
    {React.string("Touch me")}  
  </div>
}

Drag and Drop

[@react.component] 
let make = () => {
  let handleDragStart = (event: ReactEvent.Drag.t) => {
    let dataTransfer = ReactEvent.Drag.dataTransfer(event);
    dataTransfer##setData("text/plain", "dragged-item");
  };
  
  let handleDrop = (event: ReactEvent.Drag.t) => {
    ReactEvent.Drag.preventDefault(event);
    let dataTransfer = ReactEvent.Drag.dataTransfer(event);
    let data = dataTransfer##getData("text/plain");
    Js.log2("Dropped:", data);
  };
  
  let handleDragOver = (event: ReactEvent.Drag.t) => {
    ReactEvent.Drag.preventDefault(event);
  };
  
  <div>
    <div draggable=true onDragStart=handleDragStart>
      {React.string("Drag me")}
    </div>
    <div onDrop=handleDrop onDragOver=handleDragOver className="drop-zone">
      {React.string("Drop here")}
    </div>
  </div>
}