@liveblocks/react-ui 3.16.0 → 3.17.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,7 @@ var config = require('../config.cjs');
12
12
  require('../icons/index.cjs');
13
13
  var capitalize = require('../utils/capitalize.cjs');
14
14
  var cn = require('../utils/cn.cjs');
15
+ var cursorSpring = require('../utils/cursor-spring.cjs');
15
16
  var Portal = require('../utils/Portal.cjs');
16
17
  var useInitial = require('../utils/use-initial.cjs');
17
18
  var useRefs = require('../utils/use-refs.cjs');
@@ -94,6 +95,7 @@ exports.User = User.User;
94
95
  exports.useLiveblocksUiConfig = config.useLiveblocksUiConfig;
95
96
  exports.capitalize = capitalize.capitalize;
96
97
  exports.cn = cn.cn;
98
+ exports.makeCursorSpring = cursorSpring.makeCursorSpring;
97
99
  exports.Portal = Portal.Portal;
98
100
  exports.useInitial = useInitial.useInitial;
99
101
  exports.useRefs = useRefs.useRefs;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as _liveblocks_core from '@liveblocks/core';
2
3
  import { Relax, AiTextPart, AiReasoningPart, AiChatMessage } from '@liveblocks/core';
3
4
  import * as react from 'react';
4
5
  import { ComponentProps, ReactNode, ComponentPropsWithoutRef, ElementType, ComponentType, Ref, RefCallback, FormEvent } from 'react';
@@ -494,6 +495,17 @@ declare function capitalize(string: string): string;
494
495
  */
495
496
  declare function cn(...args: (string | number | boolean | undefined | null)[]): string;
496
497
 
498
+ type CursorCoordinates = {
499
+ x: number;
500
+ y: number;
501
+ };
502
+ declare function makeCursorSpring(): {
503
+ get(): CursorCoordinates | null;
504
+ set(point: CursorCoordinates | null): void;
505
+ subscribe: (callback: (event: CursorCoordinates | null) => void) => _liveblocks_core.UnsubscribeCallback;
506
+ dispose(): void;
507
+ };
508
+
497
509
  declare const Portal: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & SlotProp & react.RefAttributes<HTMLDivElement>>;
498
510
 
499
511
  /**
@@ -726,4 +738,4 @@ declare namespace index {
726
738
  };
727
739
  }
728
740
 
729
- export { index$2 as AiComposer, AiComposerEditorProps, AiComposerFormProps, AiComposerSubmitProps, index$1 as AiMessage, AiMessageContentComponents, AiMessageContentProps, AiMessageContentReasoningPartProps, AiMessageContentTextPartProps, ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, Avatar, BellCrossedIcon, BellIcon, BlockquoteIcon, BoldIcon, Button, CheckCircleFillIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, index as Collapsible, CommentIcon, CopyIcon, CrossCircleFillIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon, EmojiIcon, EmojiPlusIcon, GlobeIcon, Group, GroupDescription, H1Icon, H2Icon, H3Icon, ItalicIcon, LengthenIcon, List, ListOrderedIcon, ListUnorderedIcon, Markdown, MarkdownComponents, MarkdownComponentsBlockquoteProps, MarkdownComponentsCodeBlockProps, MarkdownComponentsHeadingProps, MarkdownComponentsImageProps, MarkdownComponentsInlineProps, MarkdownComponentsLinkProps, MarkdownComponentsListProps, MarkdownComponentsParagraphProps, MarkdownComponentsTableProps, MarkdownProps, MentionIcon, MinusCircleIcon, PlusIcon, Portal, Prose, QuestionMarkIcon, RedoIcon, RestoreIcon, RetryIcon, SearchIcon, SelectButton, SendIcon, ShortcutTooltip, ShortenIcon, SparklesIcon, SparklesTextIcon, SpinnerIcon, StopIcon, StrikethroughIcon, TextIcon, Tooltip, TooltipProvider, TranslateIcon, UnderlineIcon, UndoIcon, User, UserIcon, UsersIcon, WarningIcon, capitalize, cn, useAiComposer, useInitial, useLiveblocksUiConfig, useRefs, useStableComponent };
741
+ export { index$2 as AiComposer, AiComposerEditorProps, AiComposerFormProps, AiComposerSubmitProps, index$1 as AiMessage, AiMessageContentComponents, AiMessageContentProps, AiMessageContentReasoningPartProps, AiMessageContentTextPartProps, ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, Avatar, BellCrossedIcon, BellIcon, BlockquoteIcon, BoldIcon, Button, CheckCircleFillIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, index as Collapsible, CommentIcon, CopyIcon, CrossCircleFillIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon, EmojiIcon, EmojiPlusIcon, GlobeIcon, Group, GroupDescription, H1Icon, H2Icon, H3Icon, ItalicIcon, LengthenIcon, List, ListOrderedIcon, ListUnorderedIcon, Markdown, MarkdownComponents, MarkdownComponentsBlockquoteProps, MarkdownComponentsCodeBlockProps, MarkdownComponentsHeadingProps, MarkdownComponentsImageProps, MarkdownComponentsInlineProps, MarkdownComponentsLinkProps, MarkdownComponentsListProps, MarkdownComponentsParagraphProps, MarkdownComponentsTableProps, MarkdownProps, MentionIcon, MinusCircleIcon, PlusIcon, Portal, Prose, QuestionMarkIcon, RedoIcon, RestoreIcon, RetryIcon, SearchIcon, SelectButton, SendIcon, ShortcutTooltip, ShortenIcon, SparklesIcon, SparklesTextIcon, SpinnerIcon, StopIcon, StrikethroughIcon, TextIcon, Tooltip, TooltipProvider, TranslateIcon, UnderlineIcon, UndoIcon, User, UserIcon, UsersIcon, WarningIcon, capitalize, cn, makeCursorSpring, useAiComposer, useInitial, useLiveblocksUiConfig, useRefs, useStableComponent };
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as _liveblocks_core from '@liveblocks/core';
2
3
  import { Relax, AiTextPart, AiReasoningPart, AiChatMessage } from '@liveblocks/core';
3
4
  import * as react from 'react';
4
5
  import { ComponentProps, ReactNode, ComponentPropsWithoutRef, ElementType, ComponentType, Ref, RefCallback, FormEvent } from 'react';
@@ -494,6 +495,17 @@ declare function capitalize(string: string): string;
494
495
  */
495
496
  declare function cn(...args: (string | number | boolean | undefined | null)[]): string;
496
497
 
498
+ type CursorCoordinates = {
499
+ x: number;
500
+ y: number;
501
+ };
502
+ declare function makeCursorSpring(): {
503
+ get(): CursorCoordinates | null;
504
+ set(point: CursorCoordinates | null): void;
505
+ subscribe: (callback: (event: CursorCoordinates | null) => void) => _liveblocks_core.UnsubscribeCallback;
506
+ dispose(): void;
507
+ };
508
+
497
509
  declare const Portal: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & SlotProp & react.RefAttributes<HTMLDivElement>>;
498
510
 
499
511
  /**
@@ -726,4 +738,4 @@ declare namespace index {
726
738
  };
727
739
  }
728
740
 
729
- export { index$2 as AiComposer, AiComposerEditorProps, AiComposerFormProps, AiComposerSubmitProps, index$1 as AiMessage, AiMessageContentComponents, AiMessageContentProps, AiMessageContentReasoningPartProps, AiMessageContentTextPartProps, ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, Avatar, BellCrossedIcon, BellIcon, BlockquoteIcon, BoldIcon, Button, CheckCircleFillIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, index as Collapsible, CommentIcon, CopyIcon, CrossCircleFillIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon, EmojiIcon, EmojiPlusIcon, GlobeIcon, Group, GroupDescription, H1Icon, H2Icon, H3Icon, ItalicIcon, LengthenIcon, List, ListOrderedIcon, ListUnorderedIcon, Markdown, MarkdownComponents, MarkdownComponentsBlockquoteProps, MarkdownComponentsCodeBlockProps, MarkdownComponentsHeadingProps, MarkdownComponentsImageProps, MarkdownComponentsInlineProps, MarkdownComponentsLinkProps, MarkdownComponentsListProps, MarkdownComponentsParagraphProps, MarkdownComponentsTableProps, MarkdownProps, MentionIcon, MinusCircleIcon, PlusIcon, Portal, Prose, QuestionMarkIcon, RedoIcon, RestoreIcon, RetryIcon, SearchIcon, SelectButton, SendIcon, ShortcutTooltip, ShortenIcon, SparklesIcon, SparklesTextIcon, SpinnerIcon, StopIcon, StrikethroughIcon, TextIcon, Tooltip, TooltipProvider, TranslateIcon, UnderlineIcon, UndoIcon, User, UserIcon, UsersIcon, WarningIcon, capitalize, cn, useAiComposer, useInitial, useLiveblocksUiConfig, useRefs, useStableComponent };
741
+ export { index$2 as AiComposer, AiComposerEditorProps, AiComposerFormProps, AiComposerSubmitProps, index$1 as AiMessage, AiMessageContentComponents, AiMessageContentProps, AiMessageContentReasoningPartProps, AiMessageContentTextPartProps, ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, Avatar, BellCrossedIcon, BellIcon, BlockquoteIcon, BoldIcon, Button, CheckCircleFillIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, index as Collapsible, CommentIcon, CopyIcon, CrossCircleFillIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon, EmojiIcon, EmojiPlusIcon, GlobeIcon, Group, GroupDescription, H1Icon, H2Icon, H3Icon, ItalicIcon, LengthenIcon, List, ListOrderedIcon, ListUnorderedIcon, Markdown, MarkdownComponents, MarkdownComponentsBlockquoteProps, MarkdownComponentsCodeBlockProps, MarkdownComponentsHeadingProps, MarkdownComponentsImageProps, MarkdownComponentsInlineProps, MarkdownComponentsLinkProps, MarkdownComponentsListProps, MarkdownComponentsParagraphProps, MarkdownComponentsTableProps, MarkdownProps, MentionIcon, MinusCircleIcon, PlusIcon, Portal, Prose, QuestionMarkIcon, RedoIcon, RestoreIcon, RetryIcon, SearchIcon, SelectButton, SendIcon, ShortcutTooltip, ShortenIcon, SparklesIcon, SparklesTextIcon, SpinnerIcon, StopIcon, StrikethroughIcon, TextIcon, Tooltip, TooltipProvider, TranslateIcon, UnderlineIcon, UndoIcon, User, UserIcon, UsersIcon, WarningIcon, capitalize, cn, makeCursorSpring, useAiComposer, useInitial, useLiveblocksUiConfig, useRefs, useStableComponent };
@@ -10,6 +10,7 @@ export { useLiveblocksUiConfig } from '../config.js';
10
10
  import '../icons/index.js';
11
11
  export { capitalize } from '../utils/capitalize.js';
12
12
  export { cn } from '../utils/cn.js';
13
+ export { makeCursorSpring } from '../utils/cursor-spring.js';
13
14
  export { Portal } from '../utils/Portal.js';
14
15
  export { useInitial } from '../utils/use-initial.js';
15
16
  export { useRefs } from '../utils/use-refs.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -5,15 +5,13 @@ var core = require('@liveblocks/core');
5
5
  var react = require('@liveblocks/react');
6
6
  var _private = require('@liveblocks/react/_private');
7
7
  var react$1 = require('react');
8
- var animationLoop = require('../utils/animation-loop.cjs');
9
8
  var cn = require('../utils/cn.cjs');
9
+ var cursorSpring = require('../utils/cursor-spring.cjs');
10
10
  var useRefs = require('../utils/use-refs.cjs');
11
+ var useStableComponent = require('../utils/use-stable-component.cjs');
11
12
  var useWindowFocus = require('../utils/use-window-focus.cjs');
12
13
  var Cursor = require('./Cursor.cjs');
13
14
 
14
- const STIFFNESS = 320;
15
- const DAMPING = 32;
16
- const EPSILON = 0.01;
17
15
  const DEFAULT_PRESENCE_KEY = "cursor";
18
16
  function $string(value) {
19
17
  return typeof value === "string" ? value : void 0;
@@ -24,103 +22,34 @@ function $coordinates(value) {
24
22
  }
25
23
  return void 0;
26
24
  }
27
- const loop = animationLoop.makeAnimationLoop();
28
- function makeCoordinatesSpring() {
29
- const updates = core.makeEventSource();
30
- let value = null;
31
- let target = null;
32
- const velocity = { x: 0, y: 0 };
33
- const spring = {
34
- active: false,
35
- step(dt) {
36
- if (value === null || target === null) {
37
- spring.active = false;
38
- return;
39
- }
40
- const k = STIFFNESS;
41
- const d = DAMPING;
42
- const dx = value.x - target.x;
43
- const dy = value.y - target.y;
44
- velocity.x += (-k * dx - d * velocity.x) * dt;
45
- velocity.y += (-k * dy - d * velocity.y) * dt;
46
- const nx = value.x + velocity.x * dt;
47
- const ny = value.y + velocity.y * dt;
48
- if (nx !== value.x || ny !== value.y) {
49
- value.x = nx;
50
- value.y = ny;
51
- updates.notify(value);
52
- }
53
- if (Math.abs(velocity.x) < EPSILON && Math.abs(velocity.y) < EPSILON && Math.abs(target.x - value.x) < EPSILON && Math.abs(target.y - value.y) < EPSILON) {
54
- if (value.x !== target.x || value.y !== target.y) {
55
- value.x = target.x;
56
- value.y = target.y;
57
- updates.notify(value);
58
- }
59
- velocity.x = 0;
60
- velocity.y = 0;
61
- spring.active = false;
62
- }
63
- }
64
- };
65
- return {
66
- get() {
67
- return value;
68
- },
69
- set(point) {
70
- if (point === null) {
71
- value = null;
72
- target = null;
73
- velocity.x = 0;
74
- velocity.y = 0;
75
- spring.active = false;
76
- loop.remove(spring);
77
- updates.notify(null);
78
- return;
79
- }
80
- if (value === null) {
81
- value = { x: point.x, y: point.y };
82
- target = point;
83
- velocity.x = 0;
84
- velocity.y = 0;
85
- updates.notify(value);
86
- return;
87
- }
88
- target = point;
89
- if (!spring.active && (value.x !== target.x || value.y !== target.y)) {
90
- spring.active = true;
91
- loop.add(spring);
92
- }
93
- },
94
- subscribe: updates.subscribe,
95
- dispose() {
96
- spring.active = false;
97
- loop.remove(spring);
98
- updates.dispose();
99
- }
100
- };
25
+ function DefaultCursorWithUserInfo({ userId }) {
26
+ const { user, isLoading } = react.useUser(userId ?? "");
27
+ const color = $string(user?.color);
28
+ const name = $string(user?.name);
29
+ if (isLoading) {
30
+ return null;
31
+ }
32
+ return /* @__PURE__ */ jsxRuntime.jsx(Cursor.Cursor, { color, label: name });
101
33
  }
102
34
  function PresenceCursor({
103
35
  connectionId,
104
36
  presenceKey,
105
37
  sizeRef,
106
- sizeEvents
38
+ sizeEvents,
39
+ Cursor: Cursor$1
107
40
  }) {
108
41
  const room = react.useRoom();
109
42
  const cursorRef = react$1.useRef(null);
110
43
  const userId = react.useOther(connectionId, (other) => $string(other.id));
111
- const { user, isLoading } = react.useUser(userId ?? "");
112
- const hasUserInfo = userId !== void 0 && !isLoading;
113
- const color = $string(user?.color);
114
- const name = $string(user?.name);
115
44
  _private.useLayoutEffect(() => {
116
- const spring = makeCoordinatesSpring();
45
+ const spring = cursorSpring.makeCursorSpring();
117
46
  function update() {
118
47
  const element = cursorRef.current;
119
48
  const coordinates = spring.get();
120
49
  if (!element) {
121
50
  return;
122
51
  }
123
- if (!hasUserInfo || coordinates === null) {
52
+ if (coordinates === null) {
124
53
  element.style.transform = "translate3d(0, 0, 0)";
125
54
  element.style.display = "none";
126
55
  return;
@@ -144,19 +73,21 @@ function PresenceCursor({
144
73
  unsubscribeSize();
145
74
  unsubscribeOther();
146
75
  };
147
- }, [room, connectionId, presenceKey, sizeRef, sizeEvents, hasUserInfo]);
148
- return /* @__PURE__ */ jsxRuntime.jsx(
149
- Cursor.Cursor,
150
- {
151
- color,
152
- label: name,
153
- ref: cursorRef,
154
- style: { display: "none" }
155
- }
156
- );
76
+ }, [room, connectionId, presenceKey, sizeRef, sizeEvents]);
77
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: cursorRef, style: { display: "none" }, children: userId ? /* @__PURE__ */ jsxRuntime.jsx(Cursor$1, { userId, connectionId }) : /* @__PURE__ */ jsxRuntime.jsx(Cursor.Cursor, {}) });
157
78
  }
158
79
  const Cursors = react$1.forwardRef(
159
- ({ className, children, presenceKey = DEFAULT_PRESENCE_KEY, ...props }, forwardedRef) => {
80
+ ({
81
+ className,
82
+ children,
83
+ presenceKey = DEFAULT_PRESENCE_KEY,
84
+ components,
85
+ ...props
86
+ }, forwardedRef) => {
87
+ const Cursor = useStableComponent.useStableComponent(
88
+ components?.Cursor,
89
+ DefaultCursorWithUserInfo
90
+ );
160
91
  const containerRef = react$1.useRef(null);
161
92
  const mergedRefs = useRefs.useRefs(forwardedRef, containerRef);
162
93
  const updateMyPresence = react.useUpdateMyPresence();
@@ -238,7 +169,8 @@ const Cursors = react$1.forwardRef(
238
169
  connectionId,
239
170
  presenceKey,
240
171
  sizeRef,
241
- sizeEvents
172
+ sizeEvents,
173
+ Cursor
242
174
  },
243
175
  connectionId
244
176
  )) }),
@@ -1 +1 @@
1
- {"version":3,"file":"Cursors.cjs","sources":["../../src/components/Cursors.tsx"],"sourcesContent":["import type { EventSource } from \"@liveblocks/core\";\nimport { isPlainObject, makeEventSource } from \"@liveblocks/core\";\nimport {\n useOther,\n useOthersConnectionIds,\n useRoom,\n useUpdateMyPresence,\n useUser,\n} from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n MutableRefObject,\n PointerEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { type Animatable, makeAnimationLoop } from \"../utils/animation-loop\";\nimport { cn } from \"../utils/cn\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport { Cursor } from \"./Cursor\";\n\nconst STIFFNESS = 320;\nconst DAMPING = 32;\nconst EPSILON = 0.01;\n\nconst DEFAULT_PRESENCE_KEY = \"cursor\";\n\nexport interface CursorsProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The key used to store the cursors in users' Presence.\n * This can be used to have multiple `Cursors` in a single room.\n */\n presenceKey?: string;\n}\n\ntype Coordinates = {\n x: number;\n y: number;\n};\n\ntype Size = {\n width: number;\n height: number;\n};\n\nfunction $string(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction $coordinates(value: unknown): Coordinates | undefined {\n if (\n isPlainObject(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n ) {\n return value as Coordinates;\n }\n\n return undefined;\n}\n\n// Use a shared animation loop for all (active) springs.\nconst loop = makeAnimationLoop();\n\nfunction makeCoordinatesSpring() {\n const updates = makeEventSource<Coordinates | null>();\n let value: Coordinates | null = null;\n let target: Coordinates | null = null;\n const velocity = { x: 0, y: 0 };\n\n const spring: Animatable = {\n active: false,\n step(dt: number) {\n if (value === null || target === null) {\n spring.active = false;\n return;\n }\n\n const k = STIFFNESS;\n const d = DAMPING;\n const dx = value.x - target.x;\n const dy = value.y - target.y;\n\n velocity.x += (-k * dx - d * velocity.x) * dt;\n velocity.y += (-k * dy - d * velocity.y) * dt;\n\n const nx = value.x + velocity.x * dt;\n const ny = value.y + velocity.y * dt;\n\n if (nx !== value.x || ny !== value.y) {\n value.x = nx;\n value.y = ny;\n updates.notify(value);\n }\n\n if (\n Math.abs(velocity.x) < EPSILON &&\n Math.abs(velocity.y) < EPSILON &&\n Math.abs(target.x - value.x) < EPSILON &&\n Math.abs(target.y - value.y) < EPSILON\n ) {\n if (value.x !== target.x || value.y !== target.y) {\n value.x = target.x;\n value.y = target.y;\n updates.notify(value);\n }\n\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n }\n },\n };\n\n return {\n get() {\n return value;\n },\n set(point: Coordinates | null) {\n if (point === null) {\n value = null;\n target = null;\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n loop.remove(spring);\n updates.notify(null);\n return;\n }\n\n if (value === null) {\n value = { x: point.x, y: point.y };\n target = point;\n velocity.x = 0;\n velocity.y = 0;\n updates.notify(value);\n return;\n }\n\n target = point;\n\n if (!spring.active && (value.x !== target.x || value.y !== target.y)) {\n spring.active = true;\n loop.add(spring);\n }\n },\n subscribe: updates.subscribe,\n dispose() {\n spring.active = false;\n loop.remove(spring);\n updates.dispose();\n },\n };\n}\n\nfunction PresenceCursor({\n connectionId,\n presenceKey,\n sizeRef,\n sizeEvents,\n}: {\n connectionId: number;\n presenceKey: string;\n sizeRef: MutableRefObject<Size | null>;\n sizeEvents: EventSource<void>;\n}) {\n const room = useRoom();\n const cursorRef = useRef<HTMLDivElement>(null);\n const userId = useOther(connectionId, (other) => $string(other.id));\n const { user, isLoading } = useUser(userId ?? \"\");\n const hasUserInfo = userId !== undefined && !isLoading;\n const color = $string(user?.color);\n const name = $string(user?.name);\n\n useLayoutEffect(() => {\n const spring = makeCoordinatesSpring();\n\n function update() {\n const element = cursorRef.current;\n const coordinates = spring.get();\n\n if (!element) {\n return;\n }\n\n if (!hasUserInfo || coordinates === null) {\n element.style.transform = \"translate3d(0, 0, 0)\";\n element.style.display = \"none\";\n return;\n }\n\n if (sizeRef.current) {\n element.style.transform = `translate3d(${coordinates.x * sizeRef.current.width}px, ${coordinates.y * sizeRef.current.height}px, 0)`;\n }\n\n element.style.display = \"\";\n }\n\n const unsubscribeSpring = spring.subscribe(update);\n const unsubscribeSize = sizeEvents.subscribe(update);\n update();\n\n const unsubscribeOther = room.events.others.subscribe(({ others }) => {\n const other = others.find((other) => other.connectionId === connectionId);\n const cursor = $coordinates(other?.presence[presenceKey]);\n\n spring.set(cursor ?? null);\n });\n\n return () => {\n spring.dispose();\n unsubscribeSpring();\n unsubscribeSize();\n unsubscribeOther();\n };\n }, [room, connectionId, presenceKey, sizeRef, sizeEvents, hasUserInfo]);\n\n return (\n <Cursor\n color={color}\n label={name}\n ref={cursorRef}\n style={{ display: \"none\" }}\n />\n );\n}\n\n/**\n * Displays multiplayer cursors.\n */\nexport const Cursors = forwardRef<HTMLDivElement, CursorsProps>(\n (\n { className, children, presenceKey = DEFAULT_PRESENCE_KEY, ...props },\n forwardedRef\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, containerRef);\n const updateMyPresence = useUpdateMyPresence();\n const othersConnectionIds = useOthersConnectionIds();\n const sizeRef = useRef<Size | null>(null);\n const [sizeEvents] = useState(() => makeEventSource<void>());\n const isWindowFocused = useWindowFocus();\n\n useEffect(() => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n function setSize(size: Size) {\n sizeRef.current = size;\n sizeEvents.notify();\n }\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target === container) {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n }\n });\n\n setSize({\n width: container.clientWidth,\n height: container.clientHeight,\n });\n\n observer.observe(container);\n\n return () => {\n observer.disconnect();\n };\n }, [sizeEvents]);\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const bounds = container.getBoundingClientRect();\n\n if (bounds.width === 0 || bounds.height === 0) {\n return;\n }\n\n updateMyPresence({\n [presenceKey]: {\n x: (event.clientX - bounds.left) / bounds.width,\n y: (event.clientY - bounds.top) / bounds.height,\n },\n });\n },\n [updateMyPresence, presenceKey]\n );\n\n const handlePointerLeave = useCallback(() => {\n updateMyPresence({\n [presenceKey]: null,\n });\n }, [updateMyPresence, presenceKey]);\n\n useEffect(() => {\n if (!isWindowFocused) {\n updateMyPresence({\n [presenceKey]: null,\n });\n }\n }, [isWindowFocused, updateMyPresence, presenceKey]);\n\n return (\n <div\n className={cn(\"lb-root lb-cursors\", className)}\n {...props}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n ref={mergedRefs}\n >\n <div className=\"lb-cursors-container\">\n {othersConnectionIds.map((connectionId) => (\n <PresenceCursor\n key={connectionId}\n connectionId={connectionId}\n presenceKey={presenceKey}\n sizeRef={sizeRef}\n sizeEvents={sizeEvents}\n />\n ))}\n </div>\n\n {children}\n </div>\n );\n }\n);\n"],"names":["isPlainObject","makeAnimationLoop","makeEventSource","useRoom","useRef","useOther","useUser","useLayoutEffect","other","jsx","Cursor","forwardRef","useRefs","useUpdateMyPresence","useOthersConnectionIds","useState","useWindowFocus","useEffect","useCallback","jsxs","cn"],"mappings":"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"}
1
+ {"version":3,"file":"Cursors.cjs","sources":["../../src/components/Cursors.tsx"],"sourcesContent":["import type { EventSource } from \"@liveblocks/core\";\nimport { isPlainObject, makeEventSource } from \"@liveblocks/core\";\nimport {\n useOther,\n useOthersConnectionIds,\n useRoom,\n useUpdateMyPresence,\n useUser,\n} from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n ComponentType,\n MutableRefObject,\n PointerEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport type { GlobalComponents } from \"../components\";\nimport { cn } from \"../utils/cn\";\nimport { makeCursorSpring } from \"../utils/cursor-spring\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useStableComponent } from \"../utils/use-stable-component\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport { Cursor as DefaultCursor } from \"./Cursor\";\n\nconst DEFAULT_PRESENCE_KEY = \"cursor\";\n\nexport interface CursorsCursorProps {\n /**\n * The user ID for this cursor.\n */\n userId: string;\n\n /**\n * The connection ID for this cursor.\n */\n connectionId: number;\n}\n\ninterface CursorsComponents {\n /**\n * The component used to display each cursor.\n */\n Cursor: ComponentType<CursorsCursorProps>;\n}\n\nexport interface CursorsProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The key used to store the cursors in users' Presence.\n * This can be used to have multiple `Cursors` in a single room.\n *\n * Defaults to `\"cursor\"`.\n */\n presenceKey?: string;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents & CursorsComponents>;\n}\n\ntype Coordinates = {\n x: number;\n y: number;\n};\n\ntype Size = {\n width: number;\n height: number;\n};\n\nfunction $string(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction $coordinates(value: unknown): Coordinates | undefined {\n if (\n isPlainObject(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n ) {\n return value as Coordinates;\n }\n\n return undefined;\n}\n\nfunction DefaultCursorWithUserInfo({ userId }: CursorsCursorProps) {\n const { user, isLoading } = useUser(userId ?? \"\");\n const color = $string(user?.color);\n const name = $string(user?.name);\n\n if (isLoading) {\n return null;\n }\n\n return <DefaultCursor color={color} label={name} />;\n}\n\nfunction PresenceCursor({\n connectionId,\n presenceKey,\n sizeRef,\n sizeEvents,\n Cursor,\n}: {\n connectionId: number;\n presenceKey: string;\n sizeRef: MutableRefObject<Size | null>;\n sizeEvents: EventSource<void>;\n Cursor: ComponentType<CursorsCursorProps>;\n}) {\n const room = useRoom();\n const cursorRef = useRef<HTMLDivElement>(null);\n const userId = useOther(connectionId, (other) => $string(other.id));\n\n useLayoutEffect(() => {\n const spring = makeCursorSpring();\n\n function update() {\n const element = cursorRef.current;\n const coordinates = spring.get();\n\n if (!element) {\n return;\n }\n\n if (coordinates === null) {\n element.style.transform = \"translate3d(0, 0, 0)\";\n element.style.display = \"none\";\n return;\n }\n\n if (sizeRef.current) {\n element.style.transform = `translate3d(${coordinates.x * sizeRef.current.width}px, ${coordinates.y * sizeRef.current.height}px, 0)`;\n }\n\n element.style.display = \"\";\n }\n\n const unsubscribeSpring = spring.subscribe(update);\n const unsubscribeSize = sizeEvents.subscribe(update);\n update();\n\n const unsubscribeOther = room.events.others.subscribe(({ others }) => {\n const other = others.find((other) => other.connectionId === connectionId);\n const cursor = $coordinates(other?.presence[presenceKey]);\n\n spring.set(cursor ?? null);\n });\n\n return () => {\n spring.dispose();\n unsubscribeSpring();\n unsubscribeSize();\n unsubscribeOther();\n };\n }, [room, connectionId, presenceKey, sizeRef, sizeEvents]);\n\n return (\n <div ref={cursorRef} style={{ display: \"none\" }}>\n {userId ? (\n <Cursor userId={userId} connectionId={connectionId} />\n ) : (\n <DefaultCursor />\n )}\n </div>\n );\n}\n\n/**\n * Displays multiplayer cursors.\n */\nexport const Cursors = forwardRef<HTMLDivElement, CursorsProps>(\n (\n {\n className,\n children,\n presenceKey = DEFAULT_PRESENCE_KEY,\n components,\n ...props\n },\n forwardedRef\n ) => {\n const Cursor = useStableComponent(\n components?.Cursor,\n DefaultCursorWithUserInfo\n );\n const containerRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, containerRef);\n const updateMyPresence = useUpdateMyPresence();\n const othersConnectionIds = useOthersConnectionIds();\n const sizeRef = useRef<Size | null>(null);\n const [sizeEvents] = useState(() => makeEventSource<void>());\n const isWindowFocused = useWindowFocus();\n\n useEffect(() => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n function setSize(size: Size) {\n sizeRef.current = size;\n sizeEvents.notify();\n }\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target === container) {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n }\n });\n\n setSize({\n width: container.clientWidth,\n height: container.clientHeight,\n });\n\n observer.observe(container);\n\n return () => {\n observer.disconnect();\n };\n }, [sizeEvents]);\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const bounds = container.getBoundingClientRect();\n\n if (bounds.width === 0 || bounds.height === 0) {\n return;\n }\n\n updateMyPresence({\n [presenceKey]: {\n x: (event.clientX - bounds.left) / bounds.width,\n y: (event.clientY - bounds.top) / bounds.height,\n },\n });\n },\n [updateMyPresence, presenceKey]\n );\n\n const handlePointerLeave = useCallback(() => {\n updateMyPresence({\n [presenceKey]: null,\n });\n }, [updateMyPresence, presenceKey]);\n\n useEffect(() => {\n if (!isWindowFocused) {\n updateMyPresence({\n [presenceKey]: null,\n });\n }\n }, [isWindowFocused, updateMyPresence, presenceKey]);\n\n return (\n <div\n className={cn(\"lb-root lb-cursors\", className)}\n {...props}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n ref={mergedRefs}\n >\n <div className=\"lb-cursors-container\">\n {othersConnectionIds.map((connectionId) => (\n <PresenceCursor\n key={connectionId}\n connectionId={connectionId}\n presenceKey={presenceKey}\n sizeRef={sizeRef}\n sizeEvents={sizeEvents}\n Cursor={Cursor}\n />\n ))}\n </div>\n\n {children}\n </div>\n );\n }\n);\n"],"names":["isPlainObject","useUser","jsx","DefaultCursor","Cursor","useRoom","useRef","useOther","useLayoutEffect","makeCursorSpring","other","forwardRef","useStableComponent","useRefs","useUpdateMyPresence","useOthersConnectionIds","useState","makeEventSource","useWindowFocus","useEffect","useCallback","jsxs","cn"],"mappings":"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"}
@@ -1,17 +1,15 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { isPlainObject, makeEventSource } from '@liveblocks/core';
3
- import { useRoom, useOther, useUser, useUpdateMyPresence, useOthersConnectionIds } from '@liveblocks/react';
3
+ import { useUser, useRoom, useOther, useUpdateMyPresence, useOthersConnectionIds } from '@liveblocks/react';
4
4
  import { useLayoutEffect } from '@liveblocks/react/_private';
5
5
  import { useRef, forwardRef, useState, useEffect, useCallback } from 'react';
6
- import { makeAnimationLoop } from '../utils/animation-loop.js';
7
6
  import { cn } from '../utils/cn.js';
7
+ import { makeCursorSpring } from '../utils/cursor-spring.js';
8
8
  import { useRefs } from '../utils/use-refs.js';
9
+ import { useStableComponent } from '../utils/use-stable-component.js';
9
10
  import { useWindowFocus } from '../utils/use-window-focus.js';
10
11
  import { Cursor } from './Cursor.js';
11
12
 
12
- const STIFFNESS = 320;
13
- const DAMPING = 32;
14
- const EPSILON = 0.01;
15
13
  const DEFAULT_PRESENCE_KEY = "cursor";
16
14
  function $string(value) {
17
15
  return typeof value === "string" ? value : void 0;
@@ -22,103 +20,34 @@ function $coordinates(value) {
22
20
  }
23
21
  return void 0;
24
22
  }
25
- const loop = makeAnimationLoop();
26
- function makeCoordinatesSpring() {
27
- const updates = makeEventSource();
28
- let value = null;
29
- let target = null;
30
- const velocity = { x: 0, y: 0 };
31
- const spring = {
32
- active: false,
33
- step(dt) {
34
- if (value === null || target === null) {
35
- spring.active = false;
36
- return;
37
- }
38
- const k = STIFFNESS;
39
- const d = DAMPING;
40
- const dx = value.x - target.x;
41
- const dy = value.y - target.y;
42
- velocity.x += (-k * dx - d * velocity.x) * dt;
43
- velocity.y += (-k * dy - d * velocity.y) * dt;
44
- const nx = value.x + velocity.x * dt;
45
- const ny = value.y + velocity.y * dt;
46
- if (nx !== value.x || ny !== value.y) {
47
- value.x = nx;
48
- value.y = ny;
49
- updates.notify(value);
50
- }
51
- if (Math.abs(velocity.x) < EPSILON && Math.abs(velocity.y) < EPSILON && Math.abs(target.x - value.x) < EPSILON && Math.abs(target.y - value.y) < EPSILON) {
52
- if (value.x !== target.x || value.y !== target.y) {
53
- value.x = target.x;
54
- value.y = target.y;
55
- updates.notify(value);
56
- }
57
- velocity.x = 0;
58
- velocity.y = 0;
59
- spring.active = false;
60
- }
61
- }
62
- };
63
- return {
64
- get() {
65
- return value;
66
- },
67
- set(point) {
68
- if (point === null) {
69
- value = null;
70
- target = null;
71
- velocity.x = 0;
72
- velocity.y = 0;
73
- spring.active = false;
74
- loop.remove(spring);
75
- updates.notify(null);
76
- return;
77
- }
78
- if (value === null) {
79
- value = { x: point.x, y: point.y };
80
- target = point;
81
- velocity.x = 0;
82
- velocity.y = 0;
83
- updates.notify(value);
84
- return;
85
- }
86
- target = point;
87
- if (!spring.active && (value.x !== target.x || value.y !== target.y)) {
88
- spring.active = true;
89
- loop.add(spring);
90
- }
91
- },
92
- subscribe: updates.subscribe,
93
- dispose() {
94
- spring.active = false;
95
- loop.remove(spring);
96
- updates.dispose();
97
- }
98
- };
23
+ function DefaultCursorWithUserInfo({ userId }) {
24
+ const { user, isLoading } = useUser(userId ?? "");
25
+ const color = $string(user?.color);
26
+ const name = $string(user?.name);
27
+ if (isLoading) {
28
+ return null;
29
+ }
30
+ return /* @__PURE__ */ jsx(Cursor, { color, label: name });
99
31
  }
100
32
  function PresenceCursor({
101
33
  connectionId,
102
34
  presenceKey,
103
35
  sizeRef,
104
- sizeEvents
36
+ sizeEvents,
37
+ Cursor: Cursor$1
105
38
  }) {
106
39
  const room = useRoom();
107
40
  const cursorRef = useRef(null);
108
41
  const userId = useOther(connectionId, (other) => $string(other.id));
109
- const { user, isLoading } = useUser(userId ?? "");
110
- const hasUserInfo = userId !== void 0 && !isLoading;
111
- const color = $string(user?.color);
112
- const name = $string(user?.name);
113
42
  useLayoutEffect(() => {
114
- const spring = makeCoordinatesSpring();
43
+ const spring = makeCursorSpring();
115
44
  function update() {
116
45
  const element = cursorRef.current;
117
46
  const coordinates = spring.get();
118
47
  if (!element) {
119
48
  return;
120
49
  }
121
- if (!hasUserInfo || coordinates === null) {
50
+ if (coordinates === null) {
122
51
  element.style.transform = "translate3d(0, 0, 0)";
123
52
  element.style.display = "none";
124
53
  return;
@@ -142,19 +71,21 @@ function PresenceCursor({
142
71
  unsubscribeSize();
143
72
  unsubscribeOther();
144
73
  };
145
- }, [room, connectionId, presenceKey, sizeRef, sizeEvents, hasUserInfo]);
146
- return /* @__PURE__ */ jsx(
147
- Cursor,
148
- {
149
- color,
150
- label: name,
151
- ref: cursorRef,
152
- style: { display: "none" }
153
- }
154
- );
74
+ }, [room, connectionId, presenceKey, sizeRef, sizeEvents]);
75
+ return /* @__PURE__ */ jsx("div", { ref: cursorRef, style: { display: "none" }, children: userId ? /* @__PURE__ */ jsx(Cursor$1, { userId, connectionId }) : /* @__PURE__ */ jsx(Cursor, {}) });
155
76
  }
156
77
  const Cursors = forwardRef(
157
- ({ className, children, presenceKey = DEFAULT_PRESENCE_KEY, ...props }, forwardedRef) => {
78
+ ({
79
+ className,
80
+ children,
81
+ presenceKey = DEFAULT_PRESENCE_KEY,
82
+ components,
83
+ ...props
84
+ }, forwardedRef) => {
85
+ const Cursor = useStableComponent(
86
+ components?.Cursor,
87
+ DefaultCursorWithUserInfo
88
+ );
158
89
  const containerRef = useRef(null);
159
90
  const mergedRefs = useRefs(forwardedRef, containerRef);
160
91
  const updateMyPresence = useUpdateMyPresence();
@@ -236,7 +167,8 @@ const Cursors = forwardRef(
236
167
  connectionId,
237
168
  presenceKey,
238
169
  sizeRef,
239
- sizeEvents
170
+ sizeEvents,
171
+ Cursor
240
172
  },
241
173
  connectionId
242
174
  )) }),
@@ -1 +1 @@
1
- {"version":3,"file":"Cursors.js","sources":["../../src/components/Cursors.tsx"],"sourcesContent":["import type { EventSource } from \"@liveblocks/core\";\nimport { isPlainObject, makeEventSource } from \"@liveblocks/core\";\nimport {\n useOther,\n useOthersConnectionIds,\n useRoom,\n useUpdateMyPresence,\n useUser,\n} from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n MutableRefObject,\n PointerEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { type Animatable, makeAnimationLoop } from \"../utils/animation-loop\";\nimport { cn } from \"../utils/cn\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport { Cursor } from \"./Cursor\";\n\nconst STIFFNESS = 320;\nconst DAMPING = 32;\nconst EPSILON = 0.01;\n\nconst DEFAULT_PRESENCE_KEY = \"cursor\";\n\nexport interface CursorsProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The key used to store the cursors in users' Presence.\n * This can be used to have multiple `Cursors` in a single room.\n */\n presenceKey?: string;\n}\n\ntype Coordinates = {\n x: number;\n y: number;\n};\n\ntype Size = {\n width: number;\n height: number;\n};\n\nfunction $string(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction $coordinates(value: unknown): Coordinates | undefined {\n if (\n isPlainObject(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n ) {\n return value as Coordinates;\n }\n\n return undefined;\n}\n\n// Use a shared animation loop for all (active) springs.\nconst loop = makeAnimationLoop();\n\nfunction makeCoordinatesSpring() {\n const updates = makeEventSource<Coordinates | null>();\n let value: Coordinates | null = null;\n let target: Coordinates | null = null;\n const velocity = { x: 0, y: 0 };\n\n const spring: Animatable = {\n active: false,\n step(dt: number) {\n if (value === null || target === null) {\n spring.active = false;\n return;\n }\n\n const k = STIFFNESS;\n const d = DAMPING;\n const dx = value.x - target.x;\n const dy = value.y - target.y;\n\n velocity.x += (-k * dx - d * velocity.x) * dt;\n velocity.y += (-k * dy - d * velocity.y) * dt;\n\n const nx = value.x + velocity.x * dt;\n const ny = value.y + velocity.y * dt;\n\n if (nx !== value.x || ny !== value.y) {\n value.x = nx;\n value.y = ny;\n updates.notify(value);\n }\n\n if (\n Math.abs(velocity.x) < EPSILON &&\n Math.abs(velocity.y) < EPSILON &&\n Math.abs(target.x - value.x) < EPSILON &&\n Math.abs(target.y - value.y) < EPSILON\n ) {\n if (value.x !== target.x || value.y !== target.y) {\n value.x = target.x;\n value.y = target.y;\n updates.notify(value);\n }\n\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n }\n },\n };\n\n return {\n get() {\n return value;\n },\n set(point: Coordinates | null) {\n if (point === null) {\n value = null;\n target = null;\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n loop.remove(spring);\n updates.notify(null);\n return;\n }\n\n if (value === null) {\n value = { x: point.x, y: point.y };\n target = point;\n velocity.x = 0;\n velocity.y = 0;\n updates.notify(value);\n return;\n }\n\n target = point;\n\n if (!spring.active && (value.x !== target.x || value.y !== target.y)) {\n spring.active = true;\n loop.add(spring);\n }\n },\n subscribe: updates.subscribe,\n dispose() {\n spring.active = false;\n loop.remove(spring);\n updates.dispose();\n },\n };\n}\n\nfunction PresenceCursor({\n connectionId,\n presenceKey,\n sizeRef,\n sizeEvents,\n}: {\n connectionId: number;\n presenceKey: string;\n sizeRef: MutableRefObject<Size | null>;\n sizeEvents: EventSource<void>;\n}) {\n const room = useRoom();\n const cursorRef = useRef<HTMLDivElement>(null);\n const userId = useOther(connectionId, (other) => $string(other.id));\n const { user, isLoading } = useUser(userId ?? \"\");\n const hasUserInfo = userId !== undefined && !isLoading;\n const color = $string(user?.color);\n const name = $string(user?.name);\n\n useLayoutEffect(() => {\n const spring = makeCoordinatesSpring();\n\n function update() {\n const element = cursorRef.current;\n const coordinates = spring.get();\n\n if (!element) {\n return;\n }\n\n if (!hasUserInfo || coordinates === null) {\n element.style.transform = \"translate3d(0, 0, 0)\";\n element.style.display = \"none\";\n return;\n }\n\n if (sizeRef.current) {\n element.style.transform = `translate3d(${coordinates.x * sizeRef.current.width}px, ${coordinates.y * sizeRef.current.height}px, 0)`;\n }\n\n element.style.display = \"\";\n }\n\n const unsubscribeSpring = spring.subscribe(update);\n const unsubscribeSize = sizeEvents.subscribe(update);\n update();\n\n const unsubscribeOther = room.events.others.subscribe(({ others }) => {\n const other = others.find((other) => other.connectionId === connectionId);\n const cursor = $coordinates(other?.presence[presenceKey]);\n\n spring.set(cursor ?? null);\n });\n\n return () => {\n spring.dispose();\n unsubscribeSpring();\n unsubscribeSize();\n unsubscribeOther();\n };\n }, [room, connectionId, presenceKey, sizeRef, sizeEvents, hasUserInfo]);\n\n return (\n <Cursor\n color={color}\n label={name}\n ref={cursorRef}\n style={{ display: \"none\" }}\n />\n );\n}\n\n/**\n * Displays multiplayer cursors.\n */\nexport const Cursors = forwardRef<HTMLDivElement, CursorsProps>(\n (\n { className, children, presenceKey = DEFAULT_PRESENCE_KEY, ...props },\n forwardedRef\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, containerRef);\n const updateMyPresence = useUpdateMyPresence();\n const othersConnectionIds = useOthersConnectionIds();\n const sizeRef = useRef<Size | null>(null);\n const [sizeEvents] = useState(() => makeEventSource<void>());\n const isWindowFocused = useWindowFocus();\n\n useEffect(() => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n function setSize(size: Size) {\n sizeRef.current = size;\n sizeEvents.notify();\n }\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target === container) {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n }\n });\n\n setSize({\n width: container.clientWidth,\n height: container.clientHeight,\n });\n\n observer.observe(container);\n\n return () => {\n observer.disconnect();\n };\n }, [sizeEvents]);\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const bounds = container.getBoundingClientRect();\n\n if (bounds.width === 0 || bounds.height === 0) {\n return;\n }\n\n updateMyPresence({\n [presenceKey]: {\n x: (event.clientX - bounds.left) / bounds.width,\n y: (event.clientY - bounds.top) / bounds.height,\n },\n });\n },\n [updateMyPresence, presenceKey]\n );\n\n const handlePointerLeave = useCallback(() => {\n updateMyPresence({\n [presenceKey]: null,\n });\n }, [updateMyPresence, presenceKey]);\n\n useEffect(() => {\n if (!isWindowFocused) {\n updateMyPresence({\n [presenceKey]: null,\n });\n }\n }, [isWindowFocused, updateMyPresence, presenceKey]);\n\n return (\n <div\n className={cn(\"lb-root lb-cursors\", className)}\n {...props}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n ref={mergedRefs}\n >\n <div className=\"lb-cursors-container\">\n {othersConnectionIds.map((connectionId) => (\n <PresenceCursor\n key={connectionId}\n connectionId={connectionId}\n presenceKey={presenceKey}\n sizeRef={sizeRef}\n sizeEvents={sizeEvents}\n />\n ))}\n </div>\n\n {children}\n </div>\n );\n }\n);\n"],"names":["other"],"mappings":";;;;;;;;;;;AAuBA,MAAM,SAAY,GAAA,GAAA,CAAA;AAClB,MAAM,OAAU,GAAA,EAAA,CAAA;AAChB,MAAM,OAAU,GAAA,IAAA,CAAA;AAEhB,MAAM,oBAAuB,GAAA,QAAA,CAAA;AAoB7B,SAAS,QAAQ,KAAoC,EAAA;AACnD,EAAO,OAAA,OAAO,KAAU,KAAA,QAAA,GAAW,KAAQ,GAAA,KAAA,CAAA,CAAA;AAC7C,CAAA;AAEA,SAAS,aAAa,KAAyC,EAAA;AAC7D,EACE,IAAA,aAAA,CAAc,KAAK,CAAA,IACnB,OAAO,KAAA,CAAM,MAAM,QACnB,IAAA,OAAO,KAAM,CAAA,CAAA,KAAM,QACnB,EAAA;AACA,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA,KAAA,CAAA,CAAA;AACT,CAAA;AAGA,MAAM,OAAO,iBAAkB,EAAA,CAAA;AAE/B,SAAS,qBAAwB,GAAA;AAC/B,EAAA,MAAM,UAAU,eAAoC,EAAA,CAAA;AACpD,EAAA,IAAI,KAA4B,GAAA,IAAA,CAAA;AAChC,EAAA,IAAI,MAA6B,GAAA,IAAA,CAAA;AACjC,EAAA,MAAM,QAAW,GAAA,EAAE,CAAG,EAAA,CAAA,EAAG,GAAG,CAAE,EAAA,CAAA;AAE9B,EAAA,MAAM,MAAqB,GAAA;AAAA,IACzB,MAAQ,EAAA,KAAA;AAAA,IACR,KAAK,EAAY,EAAA;AACf,MAAI,IAAA,KAAA,KAAU,IAAQ,IAAA,MAAA,KAAW,IAAM,EAAA;AACrC,QAAA,MAAA,CAAO,MAAS,GAAA,KAAA,CAAA;AAChB,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,MAAM,CAAI,GAAA,SAAA,CAAA;AACV,MAAA,MAAM,CAAI,GAAA,OAAA,CAAA;AACV,MAAM,MAAA,EAAA,GAAK,KAAM,CAAA,CAAA,GAAI,MAAO,CAAA,CAAA,CAAA;AAC5B,MAAM,MAAA,EAAA,GAAK,KAAM,CAAA,CAAA,GAAI,MAAO,CAAA,CAAA,CAAA;AAE5B,MAAA,QAAA,CAAS,MAAM,CAAC,CAAA,GAAI,EAAK,GAAA,CAAA,GAAI,SAAS,CAAK,IAAA,EAAA,CAAA;AAC3C,MAAA,QAAA,CAAS,MAAM,CAAC,CAAA,GAAI,EAAK,GAAA,CAAA,GAAI,SAAS,CAAK,IAAA,EAAA,CAAA;AAE3C,MAAA,MAAM,EAAK,GAAA,KAAA,CAAM,CAAI,GAAA,QAAA,CAAS,CAAI,GAAA,EAAA,CAAA;AAClC,MAAA,MAAM,EAAK,GAAA,KAAA,CAAM,CAAI,GAAA,QAAA,CAAS,CAAI,GAAA,EAAA,CAAA;AAElC,MAAA,IAAI,EAAO,KAAA,KAAA,CAAM,CAAK,IAAA,EAAA,KAAO,MAAM,CAAG,EAAA;AACpC,QAAA,KAAA,CAAM,CAAI,GAAA,EAAA,CAAA;AACV,QAAA,KAAA,CAAM,CAAI,GAAA,EAAA,CAAA;AACV,QAAA,OAAA,CAAQ,OAAO,KAAK,CAAA,CAAA;AAAA,OACtB;AAEA,MACE,IAAA,IAAA,CAAK,GAAI,CAAA,QAAA,CAAS,CAAC,CAAA,GAAI,OACvB,IAAA,IAAA,CAAK,GAAI,CAAA,QAAA,CAAS,CAAC,CAAA,GAAI,OACvB,IAAA,IAAA,CAAK,GAAI,CAAA,MAAA,CAAO,CAAI,GAAA,KAAA,CAAM,CAAC,CAAA,GAAI,OAC/B,IAAA,IAAA,CAAK,GAAI,CAAA,MAAA,CAAO,CAAI,GAAA,KAAA,CAAM,CAAC,CAAA,GAAI,OAC/B,EAAA;AACA,QAAA,IAAI,MAAM,CAAM,KAAA,MAAA,CAAO,KAAK,KAAM,CAAA,CAAA,KAAM,OAAO,CAAG,EAAA;AAChD,UAAA,KAAA,CAAM,IAAI,MAAO,CAAA,CAAA,CAAA;AACjB,UAAA,KAAA,CAAM,IAAI,MAAO,CAAA,CAAA,CAAA;AACjB,UAAA,OAAA,CAAQ,OAAO,KAAK,CAAA,CAAA;AAAA,SACtB;AAEA,QAAA,QAAA,CAAS,CAAI,GAAA,CAAA,CAAA;AACb,QAAA,QAAA,CAAS,CAAI,GAAA,CAAA,CAAA;AACb,QAAA,MAAA,CAAO,MAAS,GAAA,KAAA,CAAA;AAAA,OAClB;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,GAAM,GAAA;AACJ,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAAA,IACA,IAAI,KAA2B,EAAA;AAC7B,MAAA,IAAI,UAAU,IAAM,EAAA;AAClB,QAAQ,KAAA,GAAA,IAAA,CAAA;AACR,QAAS,MAAA,GAAA,IAAA,CAAA;AACT,QAAA,QAAA,CAAS,CAAI,GAAA,CAAA,CAAA;AACb,QAAA,QAAA,CAAS,CAAI,GAAA,CAAA,CAAA;AACb,QAAA,MAAA,CAAO,MAAS,GAAA,KAAA,CAAA;AAChB,QAAA,IAAA,CAAK,OAAO,MAAM,CAAA,CAAA;AAClB,QAAA,OAAA,CAAQ,OAAO,IAAI,CAAA,CAAA;AACnB,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,IAAI,UAAU,IAAM,EAAA;AAClB,QAAA,KAAA,GAAQ,EAAE,CAAG,EAAA,KAAA,CAAM,CAAG,EAAA,CAAA,EAAG,MAAM,CAAE,EAAA,CAAA;AACjC,QAAS,MAAA,GAAA,KAAA,CAAA;AACT,QAAA,QAAA,CAAS,CAAI,GAAA,CAAA,CAAA;AACb,QAAA,QAAA,CAAS,CAAI,GAAA,CAAA,CAAA;AACb,QAAA,OAAA,CAAQ,OAAO,KAAK,CAAA,CAAA;AACpB,QAAA,OAAA;AAAA,OACF;AAEA,MAAS,MAAA,GAAA,KAAA,CAAA;AAET,MAAI,IAAA,CAAC,MAAO,CAAA,MAAA,KAAW,KAAM,CAAA,CAAA,KAAM,OAAO,CAAK,IAAA,KAAA,CAAM,CAAM,KAAA,MAAA,CAAO,CAAI,CAAA,EAAA;AACpE,QAAA,MAAA,CAAO,MAAS,GAAA,IAAA,CAAA;AAChB,QAAA,IAAA,CAAK,IAAI,MAAM,CAAA,CAAA;AAAA,OACjB;AAAA,KACF;AAAA,IACA,WAAW,OAAQ,CAAA,SAAA;AAAA,IACnB,OAAU,GAAA;AACR,MAAA,MAAA,CAAO,MAAS,GAAA,KAAA,CAAA;AAChB,MAAA,IAAA,CAAK,OAAO,MAAM,CAAA,CAAA;AAClB,MAAA,OAAA,CAAQ,OAAQ,EAAA,CAAA;AAAA,KAClB;AAAA,GACF,CAAA;AACF,CAAA;AAEA,SAAS,cAAe,CAAA;AAAA,EACtB,YAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AACF,CAKG,EAAA;AACD,EAAA,MAAM,OAAO,OAAQ,EAAA,CAAA;AACrB,EAAM,MAAA,SAAA,GAAY,OAAuB,IAAI,CAAA,CAAA;AAC7C,EAAM,MAAA,MAAA,GAAS,SAAS,YAAc,EAAA,CAAC,UAAU,OAAQ,CAAA,KAAA,CAAM,EAAE,CAAC,CAAA,CAAA;AAClE,EAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAc,GAAA,OAAA,CAAQ,UAAU,EAAE,CAAA,CAAA;AAChD,EAAM,MAAA,WAAA,GAAc,MAAW,KAAA,KAAA,CAAA,IAAa,CAAC,SAAA,CAAA;AAC7C,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,IAAA,EAAM,KAAK,CAAA,CAAA;AACjC,EAAM,MAAA,IAAA,GAAO,OAAQ,CAAA,IAAA,EAAM,IAAI,CAAA,CAAA;AAE/B,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,MAAM,SAAS,qBAAsB,EAAA,CAAA;AAErC,IAAA,SAAS,MAAS,GAAA;AAChB,MAAA,MAAM,UAAU,SAAU,CAAA,OAAA,CAAA;AAC1B,MAAM,MAAA,WAAA,GAAc,OAAO,GAAI,EAAA,CAAA;AAE/B,MAAA,IAAI,CAAC,OAAS,EAAA;AACZ,QAAA,OAAA;AAAA,OACF;AAEA,MAAI,IAAA,CAAC,WAAe,IAAA,WAAA,KAAgB,IAAM,EAAA;AACxC,QAAA,OAAA,CAAQ,MAAM,SAAY,GAAA,sBAAA,CAAA;AAC1B,QAAA,OAAA,CAAQ,MAAM,OAAU,GAAA,MAAA,CAAA;AACxB,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,QAAA,OAAA,CAAQ,KAAM,CAAA,SAAA,GAAY,CAAe,YAAA,EAAA,WAAA,CAAY,CAAI,GAAA,OAAA,CAAQ,OAAQ,CAAA,KAAK,CAAO,IAAA,EAAA,WAAA,CAAY,CAAI,GAAA,OAAA,CAAQ,QAAQ,MAAM,CAAA,MAAA,CAAA,CAAA;AAAA,OAC7H;AAEA,MAAA,OAAA,CAAQ,MAAM,OAAU,GAAA,EAAA,CAAA;AAAA,KAC1B;AAEA,IAAM,MAAA,iBAAA,GAAoB,MAAO,CAAA,SAAA,CAAU,MAAM,CAAA,CAAA;AACjD,IAAM,MAAA,eAAA,GAAkB,UAAW,CAAA,SAAA,CAAU,MAAM,CAAA,CAAA;AACnD,IAAO,MAAA,EAAA,CAAA;AAEP,IAAM,MAAA,gBAAA,GAAmB,KAAK,MAAO,CAAA,MAAA,CAAO,UAAU,CAAC,EAAE,QAAa,KAAA;AACpE,MAAA,MAAM,QAAQ,MAAO,CAAA,IAAA,CAAK,CAACA,MAAUA,KAAAA,MAAAA,CAAM,iBAAiB,YAAY,CAAA,CAAA;AACxE,MAAA,MAAM,MAAS,GAAA,YAAA,CAAa,KAAO,EAAA,QAAA,CAAS,WAAW,CAAC,CAAA,CAAA;AAExD,MAAO,MAAA,CAAA,GAAA,CAAI,UAAU,IAAI,CAAA,CAAA;AAAA,KAC1B,CAAA,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAQ,EAAA,CAAA;AACf,MAAkB,iBAAA,EAAA,CAAA;AAClB,MAAgB,eAAA,EAAA,CAAA;AAChB,MAAiB,gBAAA,EAAA,CAAA;AAAA,KACnB,CAAA;AAAA,GACF,EAAG,CAAC,IAAM,EAAA,YAAA,EAAc,aAAa,OAAS,EAAA,UAAA,EAAY,WAAW,CAAC,CAAA,CAAA;AAEtE,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,KAAO,EAAA,IAAA;AAAA,MACP,GAAK,EAAA,SAAA;AAAA,MACL,KAAA,EAAO,EAAE,OAAA,EAAS,MAAO,EAAA;AAAA,KAAA;AAAA,GAC3B,CAAA;AAEJ,CAAA;AAKO,MAAM,OAAU,GAAA,UAAA;AAAA,EACrB,CACE,EAAE,SAAW,EAAA,QAAA,EAAU,cAAc,oBAAsB,EAAA,GAAG,KAAM,EAAA,EACpE,YACG,KAAA;AACH,IAAM,MAAA,YAAA,GAAe,OAAuB,IAAI,CAAA,CAAA;AAChD,IAAM,MAAA,UAAA,GAAa,OAAQ,CAAA,YAAA,EAAc,YAAY,CAAA,CAAA;AACrD,IAAA,MAAM,mBAAmB,mBAAoB,EAAA,CAAA;AAC7C,IAAA,MAAM,sBAAsB,sBAAuB,EAAA,CAAA;AACnD,IAAM,MAAA,OAAA,GAAU,OAAoB,IAAI,CAAA,CAAA;AACxC,IAAA,MAAM,CAAC,UAAU,CAAA,GAAI,QAAS,CAAA,MAAM,iBAAuB,CAAA,CAAA;AAC3D,IAAA,MAAM,kBAAkB,cAAe,EAAA,CAAA;AAEvC,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,MAAM,YAAY,YAAa,CAAA,OAAA,CAAA;AAE/B,MAAA,IAAI,CAAC,SAAW,EAAA;AACd,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,SAAS,QAAQ,IAAY,EAAA;AAC3B,QAAA,OAAA,CAAQ,OAAU,GAAA,IAAA,CAAA;AAClB,QAAA,UAAA,CAAW,MAAO,EAAA,CAAA;AAAA,OACpB;AAEA,MAAA,MAAM,QAAW,GAAA,IAAI,cAAe,CAAA,CAAC,OAAY,KAAA;AAC/C,QAAA,KAAA,MAAW,SAAS,OAAS,EAAA;AAC3B,UAAI,IAAA,KAAA,CAAM,WAAW,SAAW,EAAA;AAC9B,YAAQ,OAAA,CAAA;AAAA,cACN,KAAA,EAAO,MAAM,WAAY,CAAA,KAAA;AAAA,cACzB,MAAA,EAAQ,MAAM,WAAY,CAAA,MAAA;AAAA,aAC3B,CAAA,CAAA;AAAA,WACH;AAAA,SACF;AAAA,OACD,CAAA,CAAA;AAED,MAAQ,OAAA,CAAA;AAAA,QACN,OAAO,SAAU,CAAA,WAAA;AAAA,QACjB,QAAQ,SAAU,CAAA,YAAA;AAAA,OACnB,CAAA,CAAA;AAED,MAAA,QAAA,CAAS,QAAQ,SAAS,CAAA,CAAA;AAE1B,MAAA,OAAO,MAAM;AACX,QAAA,QAAA,CAAS,UAAW,EAAA,CAAA;AAAA,OACtB,CAAA;AAAA,KACF,EAAG,CAAC,UAAU,CAAC,CAAA,CAAA;AAEf,IAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,MACxB,CAAC,KAAwB,KAAA;AACvB,QAAA,MAAM,YAAY,YAAa,CAAA,OAAA,CAAA;AAE/B,QAAA,IAAI,CAAC,SAAW,EAAA;AACd,UAAA,OAAA;AAAA,SACF;AAEA,QAAM,MAAA,MAAA,GAAS,UAAU,qBAAsB,EAAA,CAAA;AAE/C,QAAA,IAAI,MAAO,CAAA,KAAA,KAAU,CAAK,IAAA,MAAA,CAAO,WAAW,CAAG,EAAA;AAC7C,UAAA,OAAA;AAAA,SACF;AAEA,QAAiB,gBAAA,CAAA;AAAA,UACf,CAAC,WAAW,GAAG;AAAA,YACb,CAAI,EAAA,CAAA,KAAA,CAAM,OAAU,GAAA,MAAA,CAAO,QAAQ,MAAO,CAAA,KAAA;AAAA,YAC1C,CAAI,EAAA,CAAA,KAAA,CAAM,OAAU,GAAA,MAAA,CAAO,OAAO,MAAO,CAAA,MAAA;AAAA,WAC3C;AAAA,SACD,CAAA,CAAA;AAAA,OACH;AAAA,MACA,CAAC,kBAAkB,WAAW,CAAA;AAAA,KAChC,CAAA;AAEA,IAAM,MAAA,kBAAA,GAAqB,YAAY,MAAM;AAC3C,MAAiB,gBAAA,CAAA;AAAA,QACf,CAAC,WAAW,GAAG,IAAA;AAAA,OAChB,CAAA,CAAA;AAAA,KACA,EAAA,CAAC,gBAAkB,EAAA,WAAW,CAAC,CAAA,CAAA;AAElC,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,QAAiB,gBAAA,CAAA;AAAA,UACf,CAAC,WAAW,GAAG,IAAA;AAAA,SAChB,CAAA,CAAA;AAAA,OACH;AAAA,KACC,EAAA,CAAC,eAAiB,EAAA,gBAAA,EAAkB,WAAW,CAAC,CAAA,CAAA;AAEnD,IACE,uBAAA,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAG,CAAA,oBAAA,EAAsB,SAAS,CAAA;AAAA,QAC5C,GAAG,KAAA;AAAA,QACJ,aAAe,EAAA,iBAAA;AAAA,QACf,cAAgB,EAAA,kBAAA;AAAA,QAChB,GAAK,EAAA,UAAA;AAAA,QAEL,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,SAAI,SAAU,EAAA,sBAAA,EACZ,QAAoB,EAAA,mBAAA,CAAA,GAAA,CAAI,CAAC,YACxB,qBAAA,GAAA;AAAA,YAAC,cAAA;AAAA,YAAA;AAAA,cAEC,YAAA;AAAA,cACA,WAAA;AAAA,cACA,OAAA;AAAA,cACA,UAAA;AAAA,aAAA;AAAA,YAJK,YAAA;AAAA,WAMR,CACH,EAAA,CAAA;AAAA,UAEC,QAAA;AAAA,SAAA;AAAA,OAAA;AAAA,KACH,CAAA;AAAA,GAEJ;AACF;;;;"}
1
+ {"version":3,"file":"Cursors.js","sources":["../../src/components/Cursors.tsx"],"sourcesContent":["import type { EventSource } from \"@liveblocks/core\";\nimport { isPlainObject, makeEventSource } from \"@liveblocks/core\";\nimport {\n useOther,\n useOthersConnectionIds,\n useRoom,\n useUpdateMyPresence,\n useUser,\n} from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n ComponentType,\n MutableRefObject,\n PointerEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport type { GlobalComponents } from \"../components\";\nimport { cn } from \"../utils/cn\";\nimport { makeCursorSpring } from \"../utils/cursor-spring\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useStableComponent } from \"../utils/use-stable-component\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport { Cursor as DefaultCursor } from \"./Cursor\";\n\nconst DEFAULT_PRESENCE_KEY = \"cursor\";\n\nexport interface CursorsCursorProps {\n /**\n * The user ID for this cursor.\n */\n userId: string;\n\n /**\n * The connection ID for this cursor.\n */\n connectionId: number;\n}\n\ninterface CursorsComponents {\n /**\n * The component used to display each cursor.\n */\n Cursor: ComponentType<CursorsCursorProps>;\n}\n\nexport interface CursorsProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The key used to store the cursors in users' Presence.\n * This can be used to have multiple `Cursors` in a single room.\n *\n * Defaults to `\"cursor\"`.\n */\n presenceKey?: string;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents & CursorsComponents>;\n}\n\ntype Coordinates = {\n x: number;\n y: number;\n};\n\ntype Size = {\n width: number;\n height: number;\n};\n\nfunction $string(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction $coordinates(value: unknown): Coordinates | undefined {\n if (\n isPlainObject(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n ) {\n return value as Coordinates;\n }\n\n return undefined;\n}\n\nfunction DefaultCursorWithUserInfo({ userId }: CursorsCursorProps) {\n const { user, isLoading } = useUser(userId ?? \"\");\n const color = $string(user?.color);\n const name = $string(user?.name);\n\n if (isLoading) {\n return null;\n }\n\n return <DefaultCursor color={color} label={name} />;\n}\n\nfunction PresenceCursor({\n connectionId,\n presenceKey,\n sizeRef,\n sizeEvents,\n Cursor,\n}: {\n connectionId: number;\n presenceKey: string;\n sizeRef: MutableRefObject<Size | null>;\n sizeEvents: EventSource<void>;\n Cursor: ComponentType<CursorsCursorProps>;\n}) {\n const room = useRoom();\n const cursorRef = useRef<HTMLDivElement>(null);\n const userId = useOther(connectionId, (other) => $string(other.id));\n\n useLayoutEffect(() => {\n const spring = makeCursorSpring();\n\n function update() {\n const element = cursorRef.current;\n const coordinates = spring.get();\n\n if (!element) {\n return;\n }\n\n if (coordinates === null) {\n element.style.transform = \"translate3d(0, 0, 0)\";\n element.style.display = \"none\";\n return;\n }\n\n if (sizeRef.current) {\n element.style.transform = `translate3d(${coordinates.x * sizeRef.current.width}px, ${coordinates.y * sizeRef.current.height}px, 0)`;\n }\n\n element.style.display = \"\";\n }\n\n const unsubscribeSpring = spring.subscribe(update);\n const unsubscribeSize = sizeEvents.subscribe(update);\n update();\n\n const unsubscribeOther = room.events.others.subscribe(({ others }) => {\n const other = others.find((other) => other.connectionId === connectionId);\n const cursor = $coordinates(other?.presence[presenceKey]);\n\n spring.set(cursor ?? null);\n });\n\n return () => {\n spring.dispose();\n unsubscribeSpring();\n unsubscribeSize();\n unsubscribeOther();\n };\n }, [room, connectionId, presenceKey, sizeRef, sizeEvents]);\n\n return (\n <div ref={cursorRef} style={{ display: \"none\" }}>\n {userId ? (\n <Cursor userId={userId} connectionId={connectionId} />\n ) : (\n <DefaultCursor />\n )}\n </div>\n );\n}\n\n/**\n * Displays multiplayer cursors.\n */\nexport const Cursors = forwardRef<HTMLDivElement, CursorsProps>(\n (\n {\n className,\n children,\n presenceKey = DEFAULT_PRESENCE_KEY,\n components,\n ...props\n },\n forwardedRef\n ) => {\n const Cursor = useStableComponent(\n components?.Cursor,\n DefaultCursorWithUserInfo\n );\n const containerRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, containerRef);\n const updateMyPresence = useUpdateMyPresence();\n const othersConnectionIds = useOthersConnectionIds();\n const sizeRef = useRef<Size | null>(null);\n const [sizeEvents] = useState(() => makeEventSource<void>());\n const isWindowFocused = useWindowFocus();\n\n useEffect(() => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n function setSize(size: Size) {\n sizeRef.current = size;\n sizeEvents.notify();\n }\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target === container) {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n }\n });\n\n setSize({\n width: container.clientWidth,\n height: container.clientHeight,\n });\n\n observer.observe(container);\n\n return () => {\n observer.disconnect();\n };\n }, [sizeEvents]);\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const bounds = container.getBoundingClientRect();\n\n if (bounds.width === 0 || bounds.height === 0) {\n return;\n }\n\n updateMyPresence({\n [presenceKey]: {\n x: (event.clientX - bounds.left) / bounds.width,\n y: (event.clientY - bounds.top) / bounds.height,\n },\n });\n },\n [updateMyPresence, presenceKey]\n );\n\n const handlePointerLeave = useCallback(() => {\n updateMyPresence({\n [presenceKey]: null,\n });\n }, [updateMyPresence, presenceKey]);\n\n useEffect(() => {\n if (!isWindowFocused) {\n updateMyPresence({\n [presenceKey]: null,\n });\n }\n }, [isWindowFocused, updateMyPresence, presenceKey]);\n\n return (\n <div\n className={cn(\"lb-root lb-cursors\", className)}\n {...props}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n ref={mergedRefs}\n >\n <div className=\"lb-cursors-container\">\n {othersConnectionIds.map((connectionId) => (\n <PresenceCursor\n key={connectionId}\n connectionId={connectionId}\n presenceKey={presenceKey}\n sizeRef={sizeRef}\n sizeEvents={sizeEvents}\n Cursor={Cursor}\n />\n ))}\n </div>\n\n {children}\n </div>\n );\n }\n);\n"],"names":["DefaultCursor","Cursor","other"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type {\n AiChatComponents,\n AiChatComponentsEmptyProps,\n AiChatComponentsLoadingProps,\n AiChatProps,\n} from \"./components/AiChat\";\nexport { AiChat } from \"./components/AiChat\";\nexport type { AiToolIconProps, AiToolProps } from \"./components/AiTool\";\nexport { AiTool } from \"./components/AiTool\";\nexport type { AvatarStackProps } from \"./components/AvatarStack\";\nexport { AvatarStack } from \"./components/AvatarStack\";\nexport type {\n CommentAuthorProps,\n CommentAvatarProps,\n CommentDateProps,\n CommentDropdownItemProps,\n CommentProps,\n} from \"./components/Comment\";\nexport { Comment } from \"./components/Comment\";\nexport type { CommentPinProps } from \"./components/CommentPin\";\nexport { CommentPin } from \"./components/CommentPin\";\nexport type { ComposerProps } from \"./components/Composer\";\nexport { Composer } from \"./components/Composer\";\nexport type { CursorProps } from \"./components/Cursor\";\nexport { Cursor } from \"./components/Cursor\";\nexport type { CursorsProps } from \"./components/Cursors\";\nexport { Cursors } from \"./components/Cursors\";\nexport type { FloatingComposerProps } from \"./components/FloatingComposer\";\nexport { FloatingComposer } from \"./components/FloatingComposer\";\nexport type { FloatingThreadProps } from \"./components/FloatingThread\";\nexport { FloatingThread } from \"./components/FloatingThread\";\nexport type { HistoryVersionSummaryProps } from \"./components/HistoryVersionSummary\";\nexport { HistoryVersionSummary } from \"./components/HistoryVersionSummary\";\nexport type { HistoryVersionSummaryListProps } from \"./components/HistoryVersionSummaryList\";\nexport { HistoryVersionSummaryList } from \"./components/HistoryVersionSummaryList\";\nexport type {\n InboxNotificationAvatarProps,\n InboxNotificationCustomKindProps,\n InboxNotificationCustomProps,\n InboxNotificationIconProps,\n InboxNotificationInspectorProps,\n InboxNotificationProps,\n InboxNotificationTextMentionKindProps,\n InboxNotificationTextMentionProps,\n InboxNotificationThreadKindProps,\n InboxNotificationThreadProps,\n} from \"./components/InboxNotification\";\nexport { InboxNotification } from \"./components/InboxNotification\";\nexport type { InboxNotificationListProps } from \"./components/InboxNotificationList\";\nexport { InboxNotificationList } from \"./components/InboxNotificationList\";\nexport type { ThreadProps } from \"./components/Thread\";\nexport { Thread } from \"./components/Thread\";\nexport { LiveblocksUiConfig } from \"./config\";\nexport * as Icon from \"./icon\";\nexport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n LocalizationOverrides,\n Overrides,\n ThreadOverrides,\n} from \"./overrides\";\nexport { useOverrides } from \"./overrides\";\nexport type {\n AiComposerSubmitMessage,\n ComposerSubmitComment,\n} from \"./primitives\";\nexport type {\n CommentAttachmentArgs,\n ComposerBodyMark,\n ComposerBodyMarks,\n} from \"./types\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type {\n AiChatComponents,\n AiChatComponentsEmptyProps,\n AiChatComponentsLoadingProps,\n AiChatProps,\n} from \"./components/AiChat\";\nexport { AiChat } from \"./components/AiChat\";\nexport type { AiToolIconProps, AiToolProps } from \"./components/AiTool\";\nexport { AiTool } from \"./components/AiTool\";\nexport type { AvatarStackProps } from \"./components/AvatarStack\";\nexport { AvatarStack } from \"./components/AvatarStack\";\nexport type {\n CommentAuthorProps,\n CommentAvatarProps,\n CommentDateProps,\n CommentDropdownItemProps,\n CommentProps,\n} from \"./components/Comment\";\nexport { Comment } from \"./components/Comment\";\nexport type { CommentPinProps } from \"./components/CommentPin\";\nexport { CommentPin } from \"./components/CommentPin\";\nexport type { ComposerProps } from \"./components/Composer\";\nexport { Composer } from \"./components/Composer\";\nexport type { CursorProps } from \"./components/Cursor\";\nexport { Cursor } from \"./components/Cursor\";\nexport type { CursorsCursorProps, CursorsProps } from \"./components/Cursors\";\nexport { Cursors } from \"./components/Cursors\";\nexport type { FloatingComposerProps } from \"./components/FloatingComposer\";\nexport { FloatingComposer } from \"./components/FloatingComposer\";\nexport type { FloatingThreadProps } from \"./components/FloatingThread\";\nexport { FloatingThread } from \"./components/FloatingThread\";\nexport type { HistoryVersionSummaryProps } from \"./components/HistoryVersionSummary\";\nexport { HistoryVersionSummary } from \"./components/HistoryVersionSummary\";\nexport type { HistoryVersionSummaryListProps } from \"./components/HistoryVersionSummaryList\";\nexport { HistoryVersionSummaryList } from \"./components/HistoryVersionSummaryList\";\nexport type {\n InboxNotificationAvatarProps,\n InboxNotificationCustomKindProps,\n InboxNotificationCustomProps,\n InboxNotificationIconProps,\n InboxNotificationInspectorProps,\n InboxNotificationProps,\n InboxNotificationTextMentionKindProps,\n InboxNotificationTextMentionProps,\n InboxNotificationThreadKindProps,\n InboxNotificationThreadProps,\n} from \"./components/InboxNotification\";\nexport { InboxNotification } from \"./components/InboxNotification\";\nexport type { InboxNotificationListProps } from \"./components/InboxNotificationList\";\nexport { InboxNotificationList } from \"./components/InboxNotificationList\";\nexport type { ThreadProps } from \"./components/Thread\";\nexport { Thread } from \"./components/Thread\";\nexport { LiveblocksUiConfig } from \"./config\";\nexport * as Icon from \"./icon\";\nexport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n LocalizationOverrides,\n Overrides,\n ThreadOverrides,\n} from \"./overrides\";\nexport { useOverrides } from \"./overrides\";\nexport type {\n AiComposerSubmitMessage,\n ComposerSubmitComment,\n} from \"./primitives\";\nexport type {\n CommentAttachmentArgs,\n ComposerBodyMark,\n ComposerBodyMarks,\n} from \"./types\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.cts CHANGED
@@ -1265,12 +1265,34 @@ interface CursorProps extends ComponentPropsWithoutRef<"div"> {
1265
1265
  */
1266
1266
  declare const Cursor: react.ForwardRefExoticComponent<CursorProps & react.RefAttributes<HTMLDivElement>>;
1267
1267
 
1268
+ interface CursorsCursorProps {
1269
+ /**
1270
+ * The user ID for this cursor.
1271
+ */
1272
+ userId: string;
1273
+ /**
1274
+ * The connection ID for this cursor.
1275
+ */
1276
+ connectionId: number;
1277
+ }
1278
+ interface CursorsComponents {
1279
+ /**
1280
+ * The component used to display each cursor.
1281
+ */
1282
+ Cursor: ComponentType<CursorsCursorProps>;
1283
+ }
1268
1284
  interface CursorsProps extends ComponentPropsWithoutRef<"div"> {
1269
1285
  /**
1270
1286
  * The key used to store the cursors in users' Presence.
1271
1287
  * This can be used to have multiple `Cursors` in a single room.
1288
+ *
1289
+ * Defaults to `"cursor"`.
1272
1290
  */
1273
1291
  presenceKey?: string;
1292
+ /**
1293
+ * Override the component's components.
1294
+ */
1295
+ components?: Partial<GlobalComponents & CursorsComponents>;
1274
1296
  }
1275
1297
  /**
1276
1298
  * Displays multiplayer cursors.
@@ -1833,4 +1855,4 @@ declare namespace icon {
1833
1855
  };
1834
1856
  }
1835
1857
 
1836
- export { AiChat, AiChatComponents, AiChatComponentsEmptyProps, AiChatComponentsLoadingProps, AiChatProps, AiComposerSubmitMessage, AiTool, AiToolIconProps, AiToolProps, AvatarStack, AvatarStackProps, Comment, CommentAttachmentArgs, CommentAuthorProps, CommentAvatarProps, CommentDateProps, CommentDropdownItemProps, CommentOverrides, CommentPin, CommentPinProps, CommentProps, Composer, ComposerBodyMark, ComposerBodyMarks, ComposerOverrides, ComposerProps, ComposerSubmitComment, Cursor, CursorProps, Cursors, CursorsProps, FloatingComposer, FloatingComposerProps, FloatingThread, FloatingThreadProps, GlobalOverrides, HistoryVersionSummary, HistoryVersionSummaryList, HistoryVersionSummaryListProps, HistoryVersionSummaryProps, icon as Icon, InboxNotification, InboxNotificationAvatarProps, InboxNotificationCustomKindProps, InboxNotificationCustomProps, InboxNotificationIconProps, InboxNotificationInspectorProps, InboxNotificationList, InboxNotificationListProps, InboxNotificationOverrides, InboxNotificationProps, InboxNotificationTextMentionKindProps, InboxNotificationTextMentionProps, InboxNotificationThreadKindProps, InboxNotificationThreadProps, LiveblocksUiConfig, LocalizationOverrides, Overrides, Thread, ThreadOverrides, ThreadProps, useOverrides };
1858
+ export { AiChat, AiChatComponents, AiChatComponentsEmptyProps, AiChatComponentsLoadingProps, AiChatProps, AiComposerSubmitMessage, AiTool, AiToolIconProps, AiToolProps, AvatarStack, AvatarStackProps, Comment, CommentAttachmentArgs, CommentAuthorProps, CommentAvatarProps, CommentDateProps, CommentDropdownItemProps, CommentOverrides, CommentPin, CommentPinProps, CommentProps, Composer, ComposerBodyMark, ComposerBodyMarks, ComposerOverrides, ComposerProps, ComposerSubmitComment, Cursor, CursorProps, Cursors, CursorsCursorProps, CursorsProps, FloatingComposer, FloatingComposerProps, FloatingThread, FloatingThreadProps, GlobalOverrides, HistoryVersionSummary, HistoryVersionSummaryList, HistoryVersionSummaryListProps, HistoryVersionSummaryProps, icon as Icon, InboxNotification, InboxNotificationAvatarProps, InboxNotificationCustomKindProps, InboxNotificationCustomProps, InboxNotificationIconProps, InboxNotificationInspectorProps, InboxNotificationList, InboxNotificationListProps, InboxNotificationOverrides, InboxNotificationProps, InboxNotificationTextMentionKindProps, InboxNotificationTextMentionProps, InboxNotificationThreadKindProps, InboxNotificationThreadProps, LiveblocksUiConfig, LocalizationOverrides, Overrides, Thread, ThreadOverrides, ThreadProps, useOverrides };
package/dist/index.d.ts CHANGED
@@ -1265,12 +1265,34 @@ interface CursorProps extends ComponentPropsWithoutRef<"div"> {
1265
1265
  */
1266
1266
  declare const Cursor: react.ForwardRefExoticComponent<CursorProps & react.RefAttributes<HTMLDivElement>>;
1267
1267
 
1268
+ interface CursorsCursorProps {
1269
+ /**
1270
+ * The user ID for this cursor.
1271
+ */
1272
+ userId: string;
1273
+ /**
1274
+ * The connection ID for this cursor.
1275
+ */
1276
+ connectionId: number;
1277
+ }
1278
+ interface CursorsComponents {
1279
+ /**
1280
+ * The component used to display each cursor.
1281
+ */
1282
+ Cursor: ComponentType<CursorsCursorProps>;
1283
+ }
1268
1284
  interface CursorsProps extends ComponentPropsWithoutRef<"div"> {
1269
1285
  /**
1270
1286
  * The key used to store the cursors in users' Presence.
1271
1287
  * This can be used to have multiple `Cursors` in a single room.
1288
+ *
1289
+ * Defaults to `"cursor"`.
1272
1290
  */
1273
1291
  presenceKey?: string;
1292
+ /**
1293
+ * Override the component's components.
1294
+ */
1295
+ components?: Partial<GlobalComponents & CursorsComponents>;
1274
1296
  }
1275
1297
  /**
1276
1298
  * Displays multiplayer cursors.
@@ -1833,4 +1855,4 @@ declare namespace icon {
1833
1855
  };
1834
1856
  }
1835
1857
 
1836
- export { AiChat, AiChatComponents, AiChatComponentsEmptyProps, AiChatComponentsLoadingProps, AiChatProps, AiComposerSubmitMessage, AiTool, AiToolIconProps, AiToolProps, AvatarStack, AvatarStackProps, Comment, CommentAttachmentArgs, CommentAuthorProps, CommentAvatarProps, CommentDateProps, CommentDropdownItemProps, CommentOverrides, CommentPin, CommentPinProps, CommentProps, Composer, ComposerBodyMark, ComposerBodyMarks, ComposerOverrides, ComposerProps, ComposerSubmitComment, Cursor, CursorProps, Cursors, CursorsProps, FloatingComposer, FloatingComposerProps, FloatingThread, FloatingThreadProps, GlobalOverrides, HistoryVersionSummary, HistoryVersionSummaryList, HistoryVersionSummaryListProps, HistoryVersionSummaryProps, icon as Icon, InboxNotification, InboxNotificationAvatarProps, InboxNotificationCustomKindProps, InboxNotificationCustomProps, InboxNotificationIconProps, InboxNotificationInspectorProps, InboxNotificationList, InboxNotificationListProps, InboxNotificationOverrides, InboxNotificationProps, InboxNotificationTextMentionKindProps, InboxNotificationTextMentionProps, InboxNotificationThreadKindProps, InboxNotificationThreadProps, LiveblocksUiConfig, LocalizationOverrides, Overrides, Thread, ThreadOverrides, ThreadProps, useOverrides };
1858
+ export { AiChat, AiChatComponents, AiChatComponentsEmptyProps, AiChatComponentsLoadingProps, AiChatProps, AiComposerSubmitMessage, AiTool, AiToolIconProps, AiToolProps, AvatarStack, AvatarStackProps, Comment, CommentAttachmentArgs, CommentAuthorProps, CommentAvatarProps, CommentDateProps, CommentDropdownItemProps, CommentOverrides, CommentPin, CommentPinProps, CommentProps, Composer, ComposerBodyMark, ComposerBodyMarks, ComposerOverrides, ComposerProps, ComposerSubmitComment, Cursor, CursorProps, Cursors, CursorsCursorProps, CursorsProps, FloatingComposer, FloatingComposerProps, FloatingThread, FloatingThreadProps, GlobalOverrides, HistoryVersionSummary, HistoryVersionSummaryList, HistoryVersionSummaryListProps, HistoryVersionSummaryProps, icon as Icon, InboxNotification, InboxNotificationAvatarProps, InboxNotificationCustomKindProps, InboxNotificationCustomProps, InboxNotificationIconProps, InboxNotificationInspectorProps, InboxNotificationList, InboxNotificationListProps, InboxNotificationOverrides, InboxNotificationProps, InboxNotificationTextMentionKindProps, InboxNotificationTextMentionProps, InboxNotificationThreadKindProps, InboxNotificationThreadProps, LiveblocksUiConfig, LocalizationOverrides, Overrides, Thread, ThreadOverrides, ThreadProps, useOverrides };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type {\n AiChatComponents,\n AiChatComponentsEmptyProps,\n AiChatComponentsLoadingProps,\n AiChatProps,\n} from \"./components/AiChat\";\nexport { AiChat } from \"./components/AiChat\";\nexport type { AiToolIconProps, AiToolProps } from \"./components/AiTool\";\nexport { AiTool } from \"./components/AiTool\";\nexport type { AvatarStackProps } from \"./components/AvatarStack\";\nexport { AvatarStack } from \"./components/AvatarStack\";\nexport type {\n CommentAuthorProps,\n CommentAvatarProps,\n CommentDateProps,\n CommentDropdownItemProps,\n CommentProps,\n} from \"./components/Comment\";\nexport { Comment } from \"./components/Comment\";\nexport type { CommentPinProps } from \"./components/CommentPin\";\nexport { CommentPin } from \"./components/CommentPin\";\nexport type { ComposerProps } from \"./components/Composer\";\nexport { Composer } from \"./components/Composer\";\nexport type { CursorProps } from \"./components/Cursor\";\nexport { Cursor } from \"./components/Cursor\";\nexport type { CursorsProps } from \"./components/Cursors\";\nexport { Cursors } from \"./components/Cursors\";\nexport type { FloatingComposerProps } from \"./components/FloatingComposer\";\nexport { FloatingComposer } from \"./components/FloatingComposer\";\nexport type { FloatingThreadProps } from \"./components/FloatingThread\";\nexport { FloatingThread } from \"./components/FloatingThread\";\nexport type { HistoryVersionSummaryProps } from \"./components/HistoryVersionSummary\";\nexport { HistoryVersionSummary } from \"./components/HistoryVersionSummary\";\nexport type { HistoryVersionSummaryListProps } from \"./components/HistoryVersionSummaryList\";\nexport { HistoryVersionSummaryList } from \"./components/HistoryVersionSummaryList\";\nexport type {\n InboxNotificationAvatarProps,\n InboxNotificationCustomKindProps,\n InboxNotificationCustomProps,\n InboxNotificationIconProps,\n InboxNotificationInspectorProps,\n InboxNotificationProps,\n InboxNotificationTextMentionKindProps,\n InboxNotificationTextMentionProps,\n InboxNotificationThreadKindProps,\n InboxNotificationThreadProps,\n} from \"./components/InboxNotification\";\nexport { InboxNotification } from \"./components/InboxNotification\";\nexport type { InboxNotificationListProps } from \"./components/InboxNotificationList\";\nexport { InboxNotificationList } from \"./components/InboxNotificationList\";\nexport type { ThreadProps } from \"./components/Thread\";\nexport { Thread } from \"./components/Thread\";\nexport { LiveblocksUiConfig } from \"./config\";\nexport * as Icon from \"./icon\";\nexport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n LocalizationOverrides,\n Overrides,\n ThreadOverrides,\n} from \"./overrides\";\nexport { useOverrides } from \"./overrides\";\nexport type {\n AiComposerSubmitMessage,\n ComposerSubmitComment,\n} from \"./primitives\";\nexport type {\n CommentAttachmentArgs,\n ComposerBodyMark,\n ComposerBodyMarks,\n} from \"./types\";\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type {\n AiChatComponents,\n AiChatComponentsEmptyProps,\n AiChatComponentsLoadingProps,\n AiChatProps,\n} from \"./components/AiChat\";\nexport { AiChat } from \"./components/AiChat\";\nexport type { AiToolIconProps, AiToolProps } from \"./components/AiTool\";\nexport { AiTool } from \"./components/AiTool\";\nexport type { AvatarStackProps } from \"./components/AvatarStack\";\nexport { AvatarStack } from \"./components/AvatarStack\";\nexport type {\n CommentAuthorProps,\n CommentAvatarProps,\n CommentDateProps,\n CommentDropdownItemProps,\n CommentProps,\n} from \"./components/Comment\";\nexport { Comment } from \"./components/Comment\";\nexport type { CommentPinProps } from \"./components/CommentPin\";\nexport { CommentPin } from \"./components/CommentPin\";\nexport type { ComposerProps } from \"./components/Composer\";\nexport { Composer } from \"./components/Composer\";\nexport type { CursorProps } from \"./components/Cursor\";\nexport { Cursor } from \"./components/Cursor\";\nexport type { CursorsCursorProps, CursorsProps } from \"./components/Cursors\";\nexport { Cursors } from \"./components/Cursors\";\nexport type { FloatingComposerProps } from \"./components/FloatingComposer\";\nexport { FloatingComposer } from \"./components/FloatingComposer\";\nexport type { FloatingThreadProps } from \"./components/FloatingThread\";\nexport { FloatingThread } from \"./components/FloatingThread\";\nexport type { HistoryVersionSummaryProps } from \"./components/HistoryVersionSummary\";\nexport { HistoryVersionSummary } from \"./components/HistoryVersionSummary\";\nexport type { HistoryVersionSummaryListProps } from \"./components/HistoryVersionSummaryList\";\nexport { HistoryVersionSummaryList } from \"./components/HistoryVersionSummaryList\";\nexport type {\n InboxNotificationAvatarProps,\n InboxNotificationCustomKindProps,\n InboxNotificationCustomProps,\n InboxNotificationIconProps,\n InboxNotificationInspectorProps,\n InboxNotificationProps,\n InboxNotificationTextMentionKindProps,\n InboxNotificationTextMentionProps,\n InboxNotificationThreadKindProps,\n InboxNotificationThreadProps,\n} from \"./components/InboxNotification\";\nexport { InboxNotification } from \"./components/InboxNotification\";\nexport type { InboxNotificationListProps } from \"./components/InboxNotificationList\";\nexport { InboxNotificationList } from \"./components/InboxNotificationList\";\nexport type { ThreadProps } from \"./components/Thread\";\nexport { Thread } from \"./components/Thread\";\nexport { LiveblocksUiConfig } from \"./config\";\nexport * as Icon from \"./icon\";\nexport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n LocalizationOverrides,\n Overrides,\n ThreadOverrides,\n} from \"./overrides\";\nexport { useOverrides } from \"./overrides\";\nexport type {\n AiComposerSubmitMessage,\n ComposerSubmitComment,\n} from \"./primitives\";\nexport type {\n CommentAttachmentArgs,\n ComposerBodyMark,\n ComposerBodyMarks,\n} from \"./types\";\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ var core = require('@liveblocks/core');
4
+ var animationLoop = require('./animation-loop.cjs');
5
+
6
+ const STIFFNESS = 320;
7
+ const DAMPING = 32;
8
+ const EPSILON = 0.01;
9
+ const loop = animationLoop.makeAnimationLoop();
10
+ function makeCursorSpring() {
11
+ const updates = core.makeEventSource();
12
+ let value = null;
13
+ let target = null;
14
+ const velocity = { x: 0, y: 0 };
15
+ const spring = {
16
+ active: false,
17
+ step(dt) {
18
+ if (value === null || target === null) {
19
+ spring.active = false;
20
+ return;
21
+ }
22
+ const k = STIFFNESS;
23
+ const d = DAMPING;
24
+ const dx = value.x - target.x;
25
+ const dy = value.y - target.y;
26
+ velocity.x += (-k * dx - d * velocity.x) * dt;
27
+ velocity.y += (-k * dy - d * velocity.y) * dt;
28
+ const nx = value.x + velocity.x * dt;
29
+ const ny = value.y + velocity.y * dt;
30
+ if (nx !== value.x || ny !== value.y) {
31
+ value.x = nx;
32
+ value.y = ny;
33
+ updates.notify(value);
34
+ }
35
+ if (Math.abs(velocity.x) < EPSILON && Math.abs(velocity.y) < EPSILON && Math.abs(target.x - value.x) < EPSILON && Math.abs(target.y - value.y) < EPSILON) {
36
+ if (value.x !== target.x || value.y !== target.y) {
37
+ value.x = target.x;
38
+ value.y = target.y;
39
+ updates.notify(value);
40
+ }
41
+ velocity.x = 0;
42
+ velocity.y = 0;
43
+ spring.active = false;
44
+ }
45
+ }
46
+ };
47
+ return {
48
+ get() {
49
+ return value;
50
+ },
51
+ set(point) {
52
+ if (point === null) {
53
+ value = null;
54
+ target = null;
55
+ velocity.x = 0;
56
+ velocity.y = 0;
57
+ spring.active = false;
58
+ loop.remove(spring);
59
+ updates.notify(null);
60
+ return;
61
+ }
62
+ if (value === null) {
63
+ value = { x: point.x, y: point.y };
64
+ target = point;
65
+ velocity.x = 0;
66
+ velocity.y = 0;
67
+ updates.notify(value);
68
+ return;
69
+ }
70
+ target = point;
71
+ if (!spring.active && (value.x !== target.x || value.y !== target.y)) {
72
+ spring.active = true;
73
+ loop.add(spring);
74
+ }
75
+ },
76
+ subscribe: updates.subscribe,
77
+ dispose() {
78
+ spring.active = false;
79
+ loop.remove(spring);
80
+ updates.dispose();
81
+ }
82
+ };
83
+ }
84
+
85
+ exports.makeCursorSpring = makeCursorSpring;
86
+ //# sourceMappingURL=cursor-spring.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-spring.cjs","sources":["../../src/utils/cursor-spring.ts"],"sourcesContent":["import { makeEventSource } from \"@liveblocks/core\";\n\nimport { type Animatable, makeAnimationLoop } from \"./animation-loop\";\n\nconst STIFFNESS = 320;\nconst DAMPING = 32;\nconst EPSILON = 0.01;\n\ntype CursorCoordinates = {\n x: number;\n y: number;\n};\n\n// Shared animation loop for all active springs.\nconst loop = makeAnimationLoop();\n\nexport function makeCursorSpring() {\n const updates = makeEventSource<CursorCoordinates | null>();\n let value: CursorCoordinates | null = null;\n let target: CursorCoordinates | null = null;\n const velocity = { x: 0, y: 0 };\n\n const spring: Animatable = {\n active: false,\n step(dt: number) {\n if (value === null || target === null) {\n spring.active = false;\n return;\n }\n\n const k = STIFFNESS;\n const d = DAMPING;\n const dx = value.x - target.x;\n const dy = value.y - target.y;\n\n velocity.x += (-k * dx - d * velocity.x) * dt;\n velocity.y += (-k * dy - d * velocity.y) * dt;\n\n const nx = value.x + velocity.x * dt;\n const ny = value.y + velocity.y * dt;\n\n if (nx !== value.x || ny !== value.y) {\n value.x = nx;\n value.y = ny;\n updates.notify(value);\n }\n\n if (\n Math.abs(velocity.x) < EPSILON &&\n Math.abs(velocity.y) < EPSILON &&\n Math.abs(target.x - value.x) < EPSILON &&\n Math.abs(target.y - value.y) < EPSILON\n ) {\n if (value.x !== target.x || value.y !== target.y) {\n value.x = target.x;\n value.y = target.y;\n updates.notify(value);\n }\n\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n }\n },\n };\n\n return {\n get() {\n return value;\n },\n set(point: CursorCoordinates | null) {\n if (point === null) {\n value = null;\n target = null;\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n loop.remove(spring);\n updates.notify(null);\n return;\n }\n\n if (value === null) {\n value = { x: point.x, y: point.y };\n target = point;\n velocity.x = 0;\n velocity.y = 0;\n updates.notify(value);\n return;\n }\n\n target = point;\n\n if (!spring.active && (value.x !== target.x || value.y !== target.y)) {\n spring.active = true;\n loop.add(spring);\n }\n },\n subscribe: updates.subscribe,\n dispose() {\n spring.active = false;\n loop.remove(spring);\n updates.dispose();\n },\n };\n}\n"],"names":["makeAnimationLoop","makeEventSource"],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { makeEventSource } from '@liveblocks/core';
2
+ import { makeAnimationLoop } from './animation-loop.js';
3
+
4
+ const STIFFNESS = 320;
5
+ const DAMPING = 32;
6
+ const EPSILON = 0.01;
7
+ const loop = makeAnimationLoop();
8
+ function makeCursorSpring() {
9
+ const updates = makeEventSource();
10
+ let value = null;
11
+ let target = null;
12
+ const velocity = { x: 0, y: 0 };
13
+ const spring = {
14
+ active: false,
15
+ step(dt) {
16
+ if (value === null || target === null) {
17
+ spring.active = false;
18
+ return;
19
+ }
20
+ const k = STIFFNESS;
21
+ const d = DAMPING;
22
+ const dx = value.x - target.x;
23
+ const dy = value.y - target.y;
24
+ velocity.x += (-k * dx - d * velocity.x) * dt;
25
+ velocity.y += (-k * dy - d * velocity.y) * dt;
26
+ const nx = value.x + velocity.x * dt;
27
+ const ny = value.y + velocity.y * dt;
28
+ if (nx !== value.x || ny !== value.y) {
29
+ value.x = nx;
30
+ value.y = ny;
31
+ updates.notify(value);
32
+ }
33
+ if (Math.abs(velocity.x) < EPSILON && Math.abs(velocity.y) < EPSILON && Math.abs(target.x - value.x) < EPSILON && Math.abs(target.y - value.y) < EPSILON) {
34
+ if (value.x !== target.x || value.y !== target.y) {
35
+ value.x = target.x;
36
+ value.y = target.y;
37
+ updates.notify(value);
38
+ }
39
+ velocity.x = 0;
40
+ velocity.y = 0;
41
+ spring.active = false;
42
+ }
43
+ }
44
+ };
45
+ return {
46
+ get() {
47
+ return value;
48
+ },
49
+ set(point) {
50
+ if (point === null) {
51
+ value = null;
52
+ target = null;
53
+ velocity.x = 0;
54
+ velocity.y = 0;
55
+ spring.active = false;
56
+ loop.remove(spring);
57
+ updates.notify(null);
58
+ return;
59
+ }
60
+ if (value === null) {
61
+ value = { x: point.x, y: point.y };
62
+ target = point;
63
+ velocity.x = 0;
64
+ velocity.y = 0;
65
+ updates.notify(value);
66
+ return;
67
+ }
68
+ target = point;
69
+ if (!spring.active && (value.x !== target.x || value.y !== target.y)) {
70
+ spring.active = true;
71
+ loop.add(spring);
72
+ }
73
+ },
74
+ subscribe: updates.subscribe,
75
+ dispose() {
76
+ spring.active = false;
77
+ loop.remove(spring);
78
+ updates.dispose();
79
+ }
80
+ };
81
+ }
82
+
83
+ export { makeCursorSpring };
84
+ //# sourceMappingURL=cursor-spring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-spring.js","sources":["../../src/utils/cursor-spring.ts"],"sourcesContent":["import { makeEventSource } from \"@liveblocks/core\";\n\nimport { type Animatable, makeAnimationLoop } from \"./animation-loop\";\n\nconst STIFFNESS = 320;\nconst DAMPING = 32;\nconst EPSILON = 0.01;\n\ntype CursorCoordinates = {\n x: number;\n y: number;\n};\n\n// Shared animation loop for all active springs.\nconst loop = makeAnimationLoop();\n\nexport function makeCursorSpring() {\n const updates = makeEventSource<CursorCoordinates | null>();\n let value: CursorCoordinates | null = null;\n let target: CursorCoordinates | null = null;\n const velocity = { x: 0, y: 0 };\n\n const spring: Animatable = {\n active: false,\n step(dt: number) {\n if (value === null || target === null) {\n spring.active = false;\n return;\n }\n\n const k = STIFFNESS;\n const d = DAMPING;\n const dx = value.x - target.x;\n const dy = value.y - target.y;\n\n velocity.x += (-k * dx - d * velocity.x) * dt;\n velocity.y += (-k * dy - d * velocity.y) * dt;\n\n const nx = value.x + velocity.x * dt;\n const ny = value.y + velocity.y * dt;\n\n if (nx !== value.x || ny !== value.y) {\n value.x = nx;\n value.y = ny;\n updates.notify(value);\n }\n\n if (\n Math.abs(velocity.x) < EPSILON &&\n Math.abs(velocity.y) < EPSILON &&\n Math.abs(target.x - value.x) < EPSILON &&\n Math.abs(target.y - value.y) < EPSILON\n ) {\n if (value.x !== target.x || value.y !== target.y) {\n value.x = target.x;\n value.y = target.y;\n updates.notify(value);\n }\n\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n }\n },\n };\n\n return {\n get() {\n return value;\n },\n set(point: CursorCoordinates | null) {\n if (point === null) {\n value = null;\n target = null;\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n loop.remove(spring);\n updates.notify(null);\n return;\n }\n\n if (value === null) {\n value = { x: point.x, y: point.y };\n target = point;\n velocity.x = 0;\n velocity.y = 0;\n updates.notify(value);\n return;\n }\n\n target = point;\n\n if (!spring.active && (value.x !== target.x || value.y !== target.y)) {\n spring.active = true;\n loop.add(spring);\n }\n },\n subscribe: updates.subscribe,\n dispose() {\n spring.active = false;\n loop.remove(spring);\n updates.dispose();\n },\n };\n}\n"],"names":[],"mappings":"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"}
package/dist/version.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const PKG_NAME = "@liveblocks/react-ui";
4
- const PKG_VERSION = typeof "3.16.0" === "string" && "3.16.0";
4
+ const PKG_VERSION = typeof "3.17.0-rc1" === "string" && "3.17.0-rc1";
5
5
  const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
6
6
 
7
7
  exports.PKG_FORMAT = PKG_FORMAT;
@@ -1 +1 @@
1
- {"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-ui\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,uBAAA;AACX,MAAA,WAAA,GAAc,OAAO,QAAA,KAAgB,QAAY,IAAA,SAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"}
1
+ {"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-ui\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,uBAAA;AACX,MAAA,WAAA,GAAc,OAAO,YAAA,KAAgB,QAAY,IAAA,aAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"}
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const PKG_NAME = "@liveblocks/react-ui";
2
- const PKG_VERSION = typeof "3.16.0" === "string" && "3.16.0";
2
+ const PKG_VERSION = typeof "3.17.0-rc1" === "string" && "3.17.0-rc1";
3
3
  const PKG_FORMAT = typeof "esm" === "string" && "esm";
4
4
 
5
5
  export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-ui\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,uBAAA;AACX,MAAA,WAAA,GAAc,OAAO,QAAA,KAAgB,QAAY,IAAA,SAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"}
1
+ {"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-ui\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,uBAAA;AACX,MAAA,WAAA,GAAc,OAAO,YAAA,KAAgB,QAAY,IAAA,aAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/react-ui",
3
- "version": "3.16.0",
3
+ "version": "3.17.0-rc1",
4
4
  "description": "A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Liveblocks Inc.",
@@ -71,16 +71,16 @@
71
71
  "format": "eslint --fix src/; stylelint --fix src/styles/; prettier --write src/",
72
72
  "lint": "eslint src/; stylelint src/styles/",
73
73
  "lint:package": "publint --strict && attw --pack",
74
- "test": "npx liveblocks dev -c 'vitest run'",
74
+ "test": "npx liveblocks dev -p 1154 -c 'vitest run'",
75
75
  "test:ci": "vitest run",
76
76
  "test:types": "ls test-d/* | xargs -n1 tsd --files",
77
77
  "test:watch": "vitest"
78
78
  },
79
79
  "dependencies": {
80
80
  "@floating-ui/react-dom": "^2.1.0",
81
- "@liveblocks/client": "3.16.0",
82
- "@liveblocks/core": "3.16.0",
83
- "@liveblocks/react": "3.16.0",
81
+ "@liveblocks/client": "3.17.0-rc1",
82
+ "@liveblocks/core": "3.17.0-rc1",
83
+ "@liveblocks/react": "3.17.0-rc1",
84
84
  "frimousse": "^0.2.0",
85
85
  "marked": "^15.0.11",
86
86
  "radix-ui": "^1.4.0",