Subchapter 1.44
references/editor-react-component/FUNCTION-HANDLERS.mdMarkdown4 KBView on GitHub
When creating a component or changing interactions, expose common optional callbacks by capability, without requiring an explicit request.
Apply defaults to the public interaction surface:
| Component capability | Default optional props |
|---|
| Pointer/click interaction, including native controls | onClick, onMouseIn, onMouseOut |
| Focusable control | onFocus, onBlur |
| Editable value, text, or selection | onChange |
Combine matching rows; leave decorative elements alone. Explicit API restrictions
override defaults. Specialized callbacks (onDblClick, onPlay, onEnded,
onActivate, etc.) require a request.
Classify composite controls by their interactive descendants. For example, a radio-based rating input matches all three rows and exposes all six callbacks.
Use the exact SDK prop name and wire it to the matching React DOM event.
| SDK prop | React DOM prop | Type | Zero config domEvent |
|---|---|---|---|
onClick | onClick | (event: React.MouseEvent) => void | POINTER |
onDblClick | onDoubleClick | (event: React.MouseEvent) => void | POINTER |
onChange | onChange | (event: React.ChangeEvent<HTMLElement>) => void | CHANGE |
onFocus | onFocus | (event: React.FocusEvent) => void | FOCUS |
onBlur | onBlur | (event: React.FocusEvent) => void | FOCUS |
onMouseIn | onMouseEnter | (event: React.MouseEvent) => void | POINTER |
onMouseOut | onMouseLeave | (event: React.MouseEvent) => void | POINTER |
React onChange fires on live text edits and selection changes. Pass that
ChangeEvent directly. Do not synthesize a commit callback from blur or cast a
FocusEvent to ChangeEvent.
Callbacks only notify; they never enable controlled mode. Internal handlers run component logic, then call the optional callback once, preserving event payloads and disabled/read-only guards. Behavior must work without callbacks or consumer prop updates. Forward directly when no internal logic is needed. Add controlled state only when requested; preserve existing controlled APIs when editing.
import * as React from 'react';
export type ActionProps = {
onClick?: (event: React.MouseEvent) => void;
onMouseIn?: (event: React.MouseEvent) => void;
onMouseOut?: (event: React.MouseEvent) => void;
onFocus?: (event: React.FocusEvent) => void;
onBlur?: (event: React.FocusEvent) => void;
};
export const Action: React.FC<ActionProps> = (props) => {
const { onClick, onMouseIn, onMouseOut, onFocus, onBlur } = props;
const [count, setCount] = React.useState(0);
const handleClick = (event: React.MouseEvent) => {
setCount((value) => value + 1);
onClick?.(event);
};
return (
<button
type="button"
onClick={handleClick}
onMouseEnter={onMouseIn}
onMouseLeave={onMouseOut}
onFocus={onFocus}
onBlur={onBlur}
>
Clicked {count} times
</button>
);
};Zero config requires SDK names, not onDoubleClick, onMouseEnter, or
onMouseLeave, in public props.
Custom notifications use () => void; zero config emits no event parameter for
unrecognized callback names. Custom callbacks must not declare React event
parameters. Use a standard SDK handler above when the event is public:
export type VideoPlayerProps = {
onPlay?: () => void;
onPause?: () => void;
onEnded?: () => void;
};
export const VideoPlayer: React.FC<VideoPlayerProps> = (props) => {
const { onPlay, onPause, onEnded } = props;
return (
<video
controls
onPlay={() => onPlay?.()}
onPause={() => onPause?.()}
onEnded={() => onEnded?.()}
/>
);
};