@object-ui/collaboration
v18.3.0
Published
Real-time collaboration for ObjectUI with presence tracking, live cursors, conflict resolution, and comment threads.
Maintainers
Readme
@object-ui/collaboration
Real-time collaboration for Object UI — presence tracking, comment threads, and conflict resolution.
Features
- 👥 Presence Avatars - Show active users with
PresenceAvatars - 💬 Comment Threads - Threaded comments with @mentions via
CommentThread - 🔄 Realtime Subscriptions - WebSocket data subscriptions with
useRealtimeSubscription - 👁️ Presence Tracking - Track who's viewing or editing with
usePresence - ⚔️ Conflict Resolution - Version history and merge conflicts with
useConflictResolution - 🎯 Type-Safe - Full TypeScript support with exported types
Installation
npm install @object-ui/collaborationPeer Dependencies:
react^19.0.0
Quick Start
import {
usePresence,
useRealtimeSubscription,
PresenceAvatars,
CommentThread,
type Comment,
type PresenceUser,
} from '@object-ui/collaboration';
declare const broadcastPresence: (user: PresenceUser) => void;
declare const comments: Comment[];
declare const currentUser: { id: string; name: string };
function CollaborativeEditor() {
const { users, updateCursor } = usePresence(broadcastPresence, {
user: { id: 'user-1', name: 'Alice' },
});
const { lastMessage, connectionState } = useRealtimeSubscription({
channel: 'document-123',
});
return (
<div data-connection={connectionState}>
<PresenceAvatars users={users} />
<div onMouseMove={(event) => updateCursor({ x: event.clientX, y: event.clientY })}>
{lastMessage ? lastMessage.channel : 'waiting for updates'}
</div>
<CommentThread threadId="thread-1" comments={comments} currentUser={currentUser} />
</div>
);
}API
useRealtimeSubscription
Hook for WebSocket data subscriptions. channel is the only required key, and the
result carries the connection state plus the messages received so far:
import { useRealtimeSubscription } from '@object-ui/collaboration';
const { lastMessage, messages, connectionState, error } = useRealtimeSubscription({
channel: 'orders',
});usePresence
Hook for tracking user presence. The broadcast callback comes first and the configuration second; the configuration carries the current user:
import { usePresence, type PresenceUser } from '@object-ui/collaboration';
declare const broadcastPresence: (user: PresenceUser) => void;
const { users, updateCursor, currentUser } = usePresence(broadcastPresence, {
user: { id: 'user-1', name: 'Alice' },
});useConflictResolution
Hook for version history and conflict management. It is called with the current user's id, optionally their name:
import { useConflictResolution } from '@object-ui/collaboration';
const { versions, conflicts, resolveConflict } = useConflictResolution('user-1', 'Alice');PresenceAvatars
Shows avatar badges for active users:
import { PresenceAvatars, type PresenceUser } from '@object-ui/collaboration';
declare const presenceUsers: PresenceUser[];
const avatars = <PresenceAvatars users={presenceUsers} maxVisible={5} />;CommentThread
Threaded comment component with @mentions. comments and currentUser are
required; new comments arrive through onAddComment:
import { CommentThread, type Comment } from '@object-ui/collaboration';
declare const comments: Comment[];
declare const currentUser: { id: string; name: string };
declare const saveComment: (content: string, mentions: string[]) => void;
const thread = (
<CommentThread
threadId="thread-1"
comments={comments}
currentUser={currentUser}
onAddComment={(content, mentions) => saveComment(content, mentions)}
/>
);Links
License
MIT — see LICENSE.
