Documentation Index
Fetch the complete documentation index at: https://mintlify.com/RtlZeroMemory/Rezi/llms.txt
Use this file to discover all available pages before exploring further.
Rezi provides full mouse support with automatic terminal detection and event routing.
Mouse Event Types
Rezi handles three primary mouse event types:
Mouse button press and release:app.on("event", (event, state) => {
if (event.action === "press" && event.id === "button") {
// Button was clicked
console.log(`Clicked at (${event.x}, ${event.y})`);
}
});
Interactive widgets (buttons, links, etc.) emit press actions on click. Mouse wheel events:app.on("event", (event, state) => {
if (event.action === "scroll") {
const delta = event.deltaY; // Positive = scroll down, negative = scroll up
return { scrollY: state.scrollY + delta };
}
});
Mouse movement with button held:app.on("mouse", (mouseEvent, state) => {
if (mouseEvent.kind === "drag") {
return {
mouseX: mouseEvent.col,
mouseY: mouseEvent.row,
};
}
});
Enable scrolling on containers with overflow: "scroll":
ui.box({
overflow: "scroll",
scrollY: state.scrollY,
h: 10,
border: "single",
}, [
// Long content...
...state.items.map(item => ui.text(item)),
])
Mouse wheel events automatically route to the nearest scrollable ancestor.
app.on("event", (event, state) => {
if (event.action === "scroll" && event.id === "list") {
// Update scroll position
return { scrollY: event.scrollY };
}
});
Virtual Lists
Virtual lists handle mouse wheel scrolling automatically:
import { ui } from "@rezi-ui/core";
ui.virtualList({
id: "items",
items: state.items,
itemHeight: 1,
h: 10,
renderItem: (item, index) => ui.text(item.text),
})
Scroll position is managed internally. No manual scroll state needed.
All interactive widgets support mouse clicks:
ui.column({ gap: 1 }, [
ui.button({ id: "save", label: "Save" }), // Clickable
ui.link({ id: "docs", label: "Documentation" }), // Clickable
ui.checkbox({ id: "agree", checked: false }), // Clickable
])
Clicking a widget with id emits the appropriate action (press, toggle, etc.).
Raw Mouse Events
Access raw mouse events for custom handling:
app.on("mouse", (mouseEvent, state) => {
console.log(`Mouse kind: ${mouseEvent.kind}`);
console.log(`Position: (${mouseEvent.col}, ${mouseEvent.row})`);
console.log(`Button: ${mouseEvent.button}`);
console.log(`Modifiers: ctrl=${mouseEvent.ctrl}, alt=${mouseEvent.alt}`);
// Return state update or undefined
});
Mouse Event Structure
type ZrevMouseEvent = {
kind: "down" | "up" | "drag" | "scroll";
col: number; // Column position (0-based)
row: number; // Row position (0-based)
button: number; // 0 = left, 1 = middle, 2 = right
ctrl: boolean;
alt: boolean;
shift: boolean;
deltaY?: number; // For scroll events
};
Canvas Mouse Interaction
Capture mouse events on canvas widgets:
import { defineWidget } from "@rezi-ui/core";
const InteractiveCanvas = defineWidget((props, ctx) => {
const [mousePos, setMousePos] = ctx.useState({ x: 0, y: 0 });
return ui.canvas({
id: ctx.id("canvas"),
w: 40,
h: 20,
blitter: "braille",
draw: (canvasCtx) => {
canvasCtx.fillStyle = "#ff0000";
canvasCtx.fillRect(mousePos.x, mousePos.y, 10, 10);
},
onMouseMove: (x, y) => {
setMousePos({ x, y });
},
});
});
Drag and Drop
Implement drag interactions with mouse state:
import { defineWidget } from "@rezi-ui/core";
const DraggableBox = defineWidget((props, ctx) => {
const [pos, setPos] = ctx.useState({ x: 0, y: 0 });
const [dragging, setDragging] = ctx.useState(false);
ctx.useEffect(() => {
const handleMouse = (mouseEvent) => {
if (mouseEvent.kind === "down") {
setDragging(true);
} else if (mouseEvent.kind === "up") {
setDragging(false);
} else if (mouseEvent.kind === "drag" && dragging) {
setPos({ x: mouseEvent.col, y: mouseEvent.row });
}
};
// Register handler
return () => {}; // Cleanup
}, [dragging]);
return ui.box({
position: "absolute",
left: pos.x,
top: pos.y,
border: "single",
}, [ui.text("Drag me")]);
});
Terminal Mouse Support
Rezi auto-detects mouse support:
const caps = app.getCaps();
if (caps.mouse) {
console.log("Mouse is supported");
} else {
console.log("Mouse is not supported (keyboard only)");
}
Most modern terminals support mouse events. If unsupported, widgets remain keyboard-accessible.
Split Pane Resizing
Split panes support mouse-based resizing:
import { ui } from "@rezi-ui/core";
ui.splitPane({
id: "editor",
direction: "horizontal",
sizes: [0.3, 0.7], // 30% sidebar, 70% editor
}, [
ui.panel("Sidebar", sidebarContent),
ui.panel("Editor", editorContent),
])
Drag the divider with the mouse to resize panes.
Scroll events automatically route to the nearest scrollable ancestor:
ui.column({ gap: 1 }, [
ui.box({
overflow: "scroll",
scrollY: state.sidebarScroll,
h: 10,
border: "single",
}, sidebarContent), // Scrolling here affects this box
ui.box({
overflow: "scroll",
scrollY: state.editorScroll,
h: 20,
border: "single",
}, editorContent), // Scrolling here affects this box
])
The scroll target is determined by mouse position. Rezi automatically routes wheel events to the correct container.
Support horizontal mouse wheel (shift+scroll):
ui.box({
overflow: "scroll",
scrollX: state.scrollX,
scrollY: state.scrollY,
w: 40,
h: 10,
border: "single",
}, wideContent)
app.on("event", (event, state) => {
if (event.action === "scroll") {
return {
scrollX: state.scrollX + (event.deltaX || 0),
scrollY: state.scrollY + (event.deltaY || 0),
};
}
});
Distinguish between left, middle, and right clicks:
app.on("mouse", (mouseEvent, state) => {
if (mouseEvent.kind === "down") {
if (mouseEvent.button === 0) {
// Left click
} else if (mouseEvent.button === 1) {
// Middle click
} else if (mouseEvent.button === 2) {
// Right click (context menu)
}
}
});
Best Practices
Keyboard Fallback
Always provide keyboard alternatives. Not all terminals support mouse events. Interactive widgets should work with Tab + Enter.
Scroll Targets
Use overflow: "scroll" on containers that should handle wheel events. Rezi routes events to the nearest scrollable ancestor.
Virtual Lists
For long lists, use ui.virtualList instead of manual scroll handling. It’s optimized for large datasets.
Visual Feedback
Provide hover states or cursor changes when possible. Terminal capabilities vary, so don’t rely solely on mouse feedback.
Next Steps
Animation
Add smooth transitions and animations to your UI
Routing
Implement page navigation with the router