Documentation
v1.0.0GitHub
Core Primitive
Event System
Comprehensive event handling system for block interactions, user input, and editor state management.
System Overview
The Event System provides a unified interface for handling all user interactions and state changes in the vibecode editor. It manages block CRUD operations, drag-and-drop functionality, keyboard shortcuts, and focus management.
Design Pattern: The system uses a combination of React event handlers, custom hooks, and Zustand state management to provide type-safe, predictable event handling.
Event Categories
Block Events
CRUD operations and block manipulation events
Create & Update
- •
onAddBlock- Add new blocks - •
onUpdateBlock- Modify block content - •
onDuplicateBlock- Clone existing blocks - •
onReplaceBlock- Replace block type
Delete & Move
- •
onDeleteBlock- Remove blocks - •
onMoveBlock- Reorder blocks - •
onReorderBlocks- Drag & drop reordering
Focus Events
Block selection and focus management
Selection
- •
onFocus- Block gains focus - •
onBlur- Block loses focus - •
onSelect- Block selection - •
onSelectMultiple- Multi-selection
Navigation
- •
onNavigateUp- Move selection up - •
onNavigateDown- Move selection down - •
onNavigateToEnd- Go to last block - •
onNavigateToStart- Go to first block
Drag & Drop Events
Advanced block manipulation through drag and drop
Drag Operations
- •
onDragStart- Initialize drag operation - •
onDragEnd- Complete drag operation - •
onDragOver- Handle drag over events - •
onDrop- Handle drop events
Keyboard Events
Keyboard shortcuts and text input handling
Block Commands
- •
onSlashCommand- Slash menu trigger - •
onEnterPress- Create new block - •
onBackspacePress- Delete/merge blocks - •
onEscapePress- Cancel operations
Global Shortcuts
- •
Cmd+S- Save prompt - •
Cmd+Z- Undo changes - •
Cmd+Y- Redo changes - •
Cmd+A- Select all blocks
Implementation
useEditorEvents Hook
Central hook for managing all editor events
hooks/use-editor-events.ts
import { useCallback } from 'react';
import { useEditorStore } from '@/store/editor-store';
import { useEditorUIStore } from '@/store/editor-ui-store';
import type { Block, BlockType } from '@/types/prompt-blocks';
export function useEditorEvents() {
const {
blocks,
addBlock,
updateBlock,
deleteBlock,
moveBlock,
reorderBlocks
} = useEditorStore();
const {
focusedBlockId,
setFocusedBlock,
clearFocus
} = useEditorUIStore();
const handleAddBlock = useCallback((
type: BlockType,
afterBlockId?: string
) => {
const newBlock = createBlock(type);
addBlock(newBlock, afterBlockId);
setFocusedBlock(newBlock.id);
}, [addBlock, setFocusedBlock]);
const handleUpdateBlock = useCallback((
blockId: string,
updates: Partial<Block>
) => {
updateBlock(blockId, updates);
}, [updateBlock]);
const handleDeleteBlock = useCallback((blockId: string) => {
const blockIndex = blocks.findIndex(b => b.id === blockId);
deleteBlock(blockId);
// Focus next block or previous if at end
const nextIndex = blockIndex < blocks.length - 1
? blockIndex
: blockIndex - 1;
if (nextIndex >= 0) {
setFocusedBlock(blocks[nextIndex].id);
} else {
clearFocus();
}
}, [blocks, deleteBlock, setFocusedBlock, clearFocus]);
const handleSlashCommand = useCallback((
blockId: string,
position: { top: number; left: number }
) => {
// Show slash command menu
useEditorUIStore.getState().showSlashMenu(blockId, position);
}, []);
return {
blocks,
focusedBlockId,
onAddBlock: handleAddBlock,
onUpdateBlock: handleUpdateBlock,
onDeleteBlock: handleDeleteBlock,
onMoveBlock: moveBlock,
onReorderBlocks: reorderBlocks,
onSetFocusedBlock: setFocusedBlock,
onSlashCommand: handleSlashCommand,
};
}Event Flow
Typical Event Lifecycle
Understanding how events propagate through the system
1
User Interaction
User clicks, types, or uses keyboard shortcut
2
Event Detection
React event handler or keyboard listener captures event
3
Event Processing
Event handler processes input and determines action
4
State Update
Zustand store is updated with new state
5
UI Update
React components re-render with updated state
Best Practices
Do
- Use useCallback for event handlers to prevent unnecessary re-renders
- Debounce frequent updates like text input changes
- Provide visual feedback for all user interactions
- Handle keyboard accessibility for all interactive elements
Don't
- Directly mutate state - always use store methods
- Create event handlers inside render functions without useCallback
- Ignore event propagation - always call preventDefault when needed
- Forget to clean up event listeners in useEffect