@liveblocks/react-ui 3.15.0-feeds2 → 3.15.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.
Files changed (148) hide show
  1. package/dist/_private/index.cjs +3 -5
  2. package/dist/_private/index.cjs.map +1 -1
  3. package/dist/_private/index.d.cts +10 -4
  4. package/dist/_private/index.d.ts +10 -4
  5. package/dist/_private/index.js +2 -2
  6. package/dist/components/AiChat.cjs +10 -2
  7. package/dist/components/AiChat.cjs.map +1 -1
  8. package/dist/components/AiChat.js +10 -2
  9. package/dist/components/AiChat.js.map +1 -1
  10. package/dist/components/AvatarStack.cjs +117 -0
  11. package/dist/components/AvatarStack.cjs.map +1 -0
  12. package/dist/components/AvatarStack.js +115 -0
  13. package/dist/components/AvatarStack.js.map +1 -0
  14. package/dist/components/Comment.cjs +259 -250
  15. package/dist/components/Comment.cjs.map +1 -1
  16. package/dist/components/Comment.js +264 -236
  17. package/dist/components/Comment.js.map +1 -1
  18. package/dist/components/CommentPin.cjs +36 -0
  19. package/dist/components/CommentPin.cjs.map +1 -0
  20. package/dist/components/CommentPin.js +34 -0
  21. package/dist/components/CommentPin.js.map +1 -0
  22. package/dist/components/Composer.cjs +2 -4
  23. package/dist/components/Composer.cjs.map +1 -1
  24. package/dist/components/Composer.js +3 -5
  25. package/dist/components/Composer.js.map +1 -1
  26. package/dist/components/Cursor.cjs +40 -0
  27. package/dist/components/Cursor.cjs.map +1 -0
  28. package/dist/components/Cursor.js +38 -0
  29. package/dist/components/Cursor.js.map +1 -0
  30. package/dist/components/Cursors.cjs +256 -0
  31. package/dist/components/Cursors.cjs.map +1 -0
  32. package/dist/components/Cursors.js +254 -0
  33. package/dist/components/Cursors.js.map +1 -0
  34. package/dist/components/FloatingComposer.cjs +82 -0
  35. package/dist/components/FloatingComposer.cjs.map +1 -0
  36. package/dist/components/FloatingComposer.js +80 -0
  37. package/dist/components/FloatingComposer.js.map +1 -0
  38. package/dist/components/FloatingThread.cjs +82 -0
  39. package/dist/components/FloatingThread.cjs.map +1 -0
  40. package/dist/components/FloatingThread.js +80 -0
  41. package/dist/components/FloatingThread.js.map +1 -0
  42. package/dist/components/InboxNotification.cjs +4 -6
  43. package/dist/components/InboxNotification.cjs.map +1 -1
  44. package/dist/components/InboxNotification.js +5 -7
  45. package/dist/components/InboxNotification.js.map +1 -1
  46. package/dist/components/Thread.cjs +61 -51
  47. package/dist/components/Thread.cjs.map +1 -1
  48. package/dist/components/Thread.js +66 -37
  49. package/dist/components/Thread.js.map +1 -1
  50. package/dist/components/internal/AiComposer.cjs +1 -2
  51. package/dist/components/internal/AiComposer.cjs.map +1 -1
  52. package/dist/components/internal/AiComposer.js +1 -2
  53. package/dist/components/internal/AiComposer.js.map +1 -1
  54. package/dist/components/internal/Avatar.cjs +10 -13
  55. package/dist/components/internal/Avatar.cjs.map +1 -1
  56. package/dist/components/internal/Avatar.js +11 -14
  57. package/dist/components/internal/Avatar.js.map +1 -1
  58. package/dist/components/internal/CodeBlock.cjs +1 -2
  59. package/dist/components/internal/CodeBlock.cjs.map +1 -1
  60. package/dist/components/internal/CodeBlock.js +1 -2
  61. package/dist/components/internal/CodeBlock.js.map +1 -1
  62. package/dist/components/internal/Dropdown.cjs +7 -28
  63. package/dist/components/internal/Dropdown.cjs.map +1 -1
  64. package/dist/components/internal/Dropdown.js +7 -7
  65. package/dist/components/internal/Dropdown.js.map +1 -1
  66. package/dist/components/internal/EmojiPicker.cjs +6 -27
  67. package/dist/components/internal/EmojiPicker.cjs.map +1 -1
  68. package/dist/components/internal/EmojiPicker.js +6 -6
  69. package/dist/components/internal/EmojiPicker.js.map +1 -1
  70. package/dist/components/internal/List.cjs +2 -2
  71. package/dist/components/internal/List.cjs.map +1 -1
  72. package/dist/components/internal/List.js +2 -2
  73. package/dist/components/internal/List.js.map +1 -1
  74. package/dist/components/internal/Tooltip.cjs +7 -28
  75. package/dist/components/internal/Tooltip.cjs.map +1 -1
  76. package/dist/components/internal/Tooltip.js +7 -7
  77. package/dist/components/internal/Tooltip.js.map +1 -1
  78. package/dist/index.cjs +12 -0
  79. package/dist/index.cjs.map +1 -1
  80. package/dist/index.d.cts +298 -130
  81. package/dist/index.d.ts +298 -130
  82. package/dist/index.js +6 -0
  83. package/dist/index.js.map +1 -1
  84. package/dist/primitives/AiComposer/index.cjs +5 -4
  85. package/dist/primitives/AiComposer/index.cjs.map +1 -1
  86. package/dist/primitives/AiComposer/index.js +5 -4
  87. package/dist/primitives/AiComposer/index.js.map +1 -1
  88. package/dist/primitives/AiMessage/index.cjs +2 -2
  89. package/dist/primitives/AiMessage/index.cjs.map +1 -1
  90. package/dist/primitives/AiMessage/index.js +2 -2
  91. package/dist/primitives/AiMessage/index.js.map +1 -1
  92. package/dist/primitives/Collapsible/index.cjs +4 -4
  93. package/dist/primitives/Collapsible/index.cjs.map +1 -1
  94. package/dist/primitives/Collapsible/index.js +4 -4
  95. package/dist/primitives/Collapsible/index.js.map +1 -1
  96. package/dist/primitives/Comment/index.cjs +4 -4
  97. package/dist/primitives/Comment/index.cjs.map +1 -1
  98. package/dist/primitives/Comment/index.js +4 -4
  99. package/dist/primitives/Comment/index.js.map +1 -1
  100. package/dist/primitives/Composer/index.cjs +23 -35
  101. package/dist/primitives/Composer/index.cjs.map +1 -1
  102. package/dist/primitives/Composer/index.js +23 -16
  103. package/dist/primitives/Composer/index.js.map +1 -1
  104. package/dist/primitives/Duration.cjs +2 -2
  105. package/dist/primitives/Duration.cjs.map +1 -1
  106. package/dist/primitives/Duration.js +2 -2
  107. package/dist/primitives/Duration.js.map +1 -1
  108. package/dist/primitives/FileSize.cjs +2 -2
  109. package/dist/primitives/FileSize.cjs.map +1 -1
  110. package/dist/primitives/FileSize.js +2 -2
  111. package/dist/primitives/FileSize.js.map +1 -1
  112. package/dist/primitives/Markdown.cjs +2 -2
  113. package/dist/primitives/Markdown.cjs.map +1 -1
  114. package/dist/primitives/Markdown.js +2 -2
  115. package/dist/primitives/Markdown.js.map +1 -1
  116. package/dist/primitives/Timestamp.cjs +2 -2
  117. package/dist/primitives/Timestamp.cjs.map +1 -1
  118. package/dist/primitives/Timestamp.js +2 -2
  119. package/dist/primitives/Timestamp.js.map +1 -1
  120. package/dist/utils/Portal.cjs +2 -2
  121. package/dist/utils/Portal.cjs.map +1 -1
  122. package/dist/utils/Portal.js +2 -2
  123. package/dist/utils/Portal.js.map +1 -1
  124. package/dist/utils/animation-loop.cjs +44 -0
  125. package/dist/utils/animation-loop.cjs.map +1 -0
  126. package/dist/utils/animation-loop.js +42 -0
  127. package/dist/utils/animation-loop.js.map +1 -0
  128. package/dist/utils/use-pre-resolve-user.cjs +18 -0
  129. package/dist/utils/use-pre-resolve-user.cjs.map +1 -0
  130. package/dist/utils/use-pre-resolve-user.js +16 -0
  131. package/dist/utils/use-pre-resolve-user.js.map +1 -0
  132. package/dist/utils/use-stable-component.cjs +32 -0
  133. package/dist/utils/use-stable-component.cjs.map +1 -0
  134. package/dist/utils/use-stable-component.js +30 -0
  135. package/dist/utils/use-stable-component.js.map +1 -0
  136. package/dist/version.cjs +1 -1
  137. package/dist/version.cjs.map +1 -1
  138. package/dist/version.js +1 -1
  139. package/dist/version.js.map +1 -1
  140. package/package.json +6 -10
  141. package/src/styles/dark/index.css +1 -1
  142. package/src/styles/index.css +252 -4
  143. package/styles/dark/attributes.css +1 -1
  144. package/styles/dark/attributes.css.map +1 -1
  145. package/styles/dark/media-query.css +1 -1
  146. package/styles/dark/media-query.css.map +1 -1
  147. package/styles.css +1 -1
  148. package/styles.css.map +1 -1
@@ -0,0 +1,254 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { isPlainObject, makeEventSource } from '@liveblocks/core';
3
+ import { useRoom, useOther, useUser, useUpdateMyPresence, useOthersConnectionIds } from '@liveblocks/react';
4
+ import { useLayoutEffect } from '@liveblocks/react/_private';
5
+ import { useRef, forwardRef, useState, useEffect, useCallback, useImperativeHandle } from 'react';
6
+ import { makeAnimationLoop } from '../utils/animation-loop.js';
7
+ import { cn } from '../utils/cn.js';
8
+ import { useWindowFocus } from '../utils/use-window-focus.js';
9
+ import { Cursor } from './Cursor.js';
10
+
11
+ const STIFFNESS = 320;
12
+ const DAMPING = 32;
13
+ const EPSILON = 0.01;
14
+ const DEFAULT_PRESENCE_KEY = "cursor";
15
+ function $string(value) {
16
+ return typeof value === "string" ? value : void 0;
17
+ }
18
+ function $coordinates(value) {
19
+ if (isPlainObject(value) && typeof value.x === "number" && typeof value.y === "number") {
20
+ return value;
21
+ }
22
+ return void 0;
23
+ }
24
+ const loop = makeAnimationLoop();
25
+ function makeCoordinatesSpring() {
26
+ const updates = makeEventSource();
27
+ let value = null;
28
+ let target = null;
29
+ const velocity = { x: 0, y: 0 };
30
+ const spring = {
31
+ active: false,
32
+ step(dt) {
33
+ if (value === null || target === null) {
34
+ spring.active = false;
35
+ return;
36
+ }
37
+ const k = STIFFNESS;
38
+ const d = DAMPING;
39
+ const dx = value.x - target.x;
40
+ const dy = value.y - target.y;
41
+ velocity.x += (-k * dx - d * velocity.x) * dt;
42
+ velocity.y += (-k * dy - d * velocity.y) * dt;
43
+ const nx = value.x + velocity.x * dt;
44
+ const ny = value.y + velocity.y * dt;
45
+ if (nx !== value.x || ny !== value.y) {
46
+ value.x = nx;
47
+ value.y = ny;
48
+ updates.notify(value);
49
+ }
50
+ 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) {
51
+ if (value.x !== target.x || value.y !== target.y) {
52
+ value.x = target.x;
53
+ value.y = target.y;
54
+ updates.notify(value);
55
+ }
56
+ velocity.x = 0;
57
+ velocity.y = 0;
58
+ spring.active = false;
59
+ }
60
+ }
61
+ };
62
+ return {
63
+ get() {
64
+ return value;
65
+ },
66
+ set(point) {
67
+ if (point === null) {
68
+ value = null;
69
+ target = null;
70
+ velocity.x = 0;
71
+ velocity.y = 0;
72
+ spring.active = false;
73
+ loop.remove(spring);
74
+ updates.notify(null);
75
+ return;
76
+ }
77
+ if (value === null) {
78
+ value = { x: point.x, y: point.y };
79
+ target = point;
80
+ velocity.x = 0;
81
+ velocity.y = 0;
82
+ updates.notify(value);
83
+ return;
84
+ }
85
+ target = point;
86
+ if (!spring.active && (value.x !== target.x || value.y !== target.y)) {
87
+ spring.active = true;
88
+ loop.add(spring);
89
+ }
90
+ },
91
+ subscribe: updates.subscribe,
92
+ dispose() {
93
+ spring.active = false;
94
+ loop.remove(spring);
95
+ updates.dispose();
96
+ }
97
+ };
98
+ }
99
+ function PresenceCursor({
100
+ connectionId,
101
+ presenceKey,
102
+ sizeRef,
103
+ sizeEvents
104
+ }) {
105
+ const room = useRoom();
106
+ const cursorRef = useRef(null);
107
+ const userId = useOther(connectionId, (other) => $string(other.id));
108
+ const { user, isLoading } = useUser(userId ?? "");
109
+ const hasUserInfo = userId !== void 0 && !isLoading;
110
+ const color = $string(user?.color);
111
+ const name = $string(user?.name);
112
+ useLayoutEffect(() => {
113
+ const spring = makeCoordinatesSpring();
114
+ function update() {
115
+ const element = cursorRef.current;
116
+ const coordinates = spring.get();
117
+ if (!element) {
118
+ return;
119
+ }
120
+ if (!hasUserInfo || coordinates === null) {
121
+ element.style.transform = "translate3d(0, 0, 0)";
122
+ element.style.display = "none";
123
+ return;
124
+ }
125
+ if (sizeRef.current) {
126
+ element.style.transform = `translate3d(${coordinates.x * sizeRef.current.width}px, ${coordinates.y * sizeRef.current.height}px, 0)`;
127
+ }
128
+ element.style.display = "";
129
+ }
130
+ const unsubscribeSpring = spring.subscribe(update);
131
+ const unsubscribeSize = sizeEvents.subscribe(update);
132
+ update();
133
+ const unsubscribeOther = room.events.others.subscribe(({ others }) => {
134
+ const other = others.find((other2) => other2.connectionId === connectionId);
135
+ const cursor = $coordinates(other?.presence[presenceKey]);
136
+ spring.set(cursor ?? null);
137
+ });
138
+ return () => {
139
+ spring.dispose();
140
+ unsubscribeSpring();
141
+ unsubscribeSize();
142
+ unsubscribeOther();
143
+ };
144
+ }, [room, connectionId, presenceKey, sizeRef, sizeEvents, hasUserInfo]);
145
+ return /* @__PURE__ */ jsx(
146
+ Cursor,
147
+ {
148
+ color,
149
+ label: name,
150
+ ref: cursorRef,
151
+ style: { display: "none" }
152
+ }
153
+ );
154
+ }
155
+ const Cursors = forwardRef(
156
+ ({ className, children, presenceKey = DEFAULT_PRESENCE_KEY, ...props }, forwardedRef) => {
157
+ const ref = useRef(null);
158
+ const updateMyPresence = useUpdateMyPresence();
159
+ const othersConnectionIds = useOthersConnectionIds();
160
+ const sizeRef = useRef(null);
161
+ const [sizeEvents] = useState(() => makeEventSource());
162
+ const isWindowFocused = useWindowFocus();
163
+ useEffect(() => {
164
+ const element = ref.current;
165
+ if (!element) {
166
+ return;
167
+ }
168
+ function setSize(size) {
169
+ sizeRef.current = size;
170
+ sizeEvents.notify();
171
+ }
172
+ const observer = new ResizeObserver((entries) => {
173
+ for (const entry of entries) {
174
+ if (entry.target === element) {
175
+ setSize({
176
+ width: entry.contentRect.width,
177
+ height: entry.contentRect.height
178
+ });
179
+ }
180
+ }
181
+ });
182
+ setSize({
183
+ width: element.clientWidth,
184
+ height: element.clientHeight
185
+ });
186
+ observer.observe(element);
187
+ return () => {
188
+ observer.disconnect();
189
+ };
190
+ }, [sizeEvents]);
191
+ const handlePointerMove = useCallback(
192
+ (event) => {
193
+ const element = ref.current;
194
+ if (!element) {
195
+ return;
196
+ }
197
+ const bounds = element.getBoundingClientRect();
198
+ if (bounds.width === 0 || bounds.height === 0) {
199
+ return;
200
+ }
201
+ updateMyPresence({
202
+ [presenceKey]: {
203
+ x: (event.clientX - bounds.left) / bounds.width,
204
+ y: (event.clientY - bounds.top) / bounds.height
205
+ }
206
+ });
207
+ },
208
+ [updateMyPresence, presenceKey]
209
+ );
210
+ const handlePointerLeave = useCallback(() => {
211
+ updateMyPresence({
212
+ [presenceKey]: null
213
+ });
214
+ }, [updateMyPresence, presenceKey]);
215
+ useEffect(() => {
216
+ if (!isWindowFocused) {
217
+ updateMyPresence({
218
+ [presenceKey]: null
219
+ });
220
+ }
221
+ }, [isWindowFocused, updateMyPresence, presenceKey]);
222
+ useImperativeHandle(
223
+ forwardedRef,
224
+ () => ref.current,
225
+ []
226
+ );
227
+ return /* @__PURE__ */ jsxs(
228
+ "div",
229
+ {
230
+ className: cn("lb-root lb-cursors", className),
231
+ ...props,
232
+ onPointerMove: handlePointerMove,
233
+ onPointerLeave: handlePointerLeave,
234
+ ref,
235
+ children: [
236
+ /* @__PURE__ */ jsx("div", { className: "lb-cursors-container", children: othersConnectionIds.map((connectionId) => /* @__PURE__ */ jsx(
237
+ PresenceCursor,
238
+ {
239
+ connectionId,
240
+ presenceKey,
241
+ sizeRef,
242
+ sizeEvents
243
+ },
244
+ connectionId
245
+ )) }),
246
+ children
247
+ ]
248
+ }
249
+ );
250
+ }
251
+ );
252
+
253
+ export { Cursors };
254
+ //# sourceMappingURL=Cursors.js.map
@@ -0,0 +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 {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { type Animatable, makeAnimationLoop } from \"../utils/animation-loop\";\nimport { cn } from \"../utils/cn\";\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 ref = useRef<HTMLDivElement>(null);\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 element = ref.current;\n\n if (!element) {\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 === element) {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n }\n });\n\n setSize({\n width: element.clientWidth,\n height: element.clientHeight,\n });\n\n observer.observe(element);\n\n return () => {\n observer.disconnect();\n };\n }, [sizeEvents]);\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const element = ref.current;\n\n if (!element) {\n return;\n }\n\n const bounds = element.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 useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => ref.current,\n []\n );\n\n return (\n <div\n className={cn(\"lb-root lb-cursors\", className)}\n {...props}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n ref={ref}\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":"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"}
@@ -0,0 +1,82 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var radixUi = require('radix-ui');
6
+ var react = require('react');
7
+ var config = require('../config.cjs');
8
+ var constants = require('../constants.cjs');
9
+ var overrides = require('../overrides.cjs');
10
+ var cn = require('../utils/cn.cjs');
11
+ var useControllableState = require('../utils/use-controllable-state.cjs');
12
+ var Composer = require('./Composer.cjs');
13
+
14
+
15
+ const FloatingComposer = react.forwardRef(
16
+ ({
17
+ children,
18
+ defaultOpen,
19
+ open,
20
+ onOpenChange,
21
+ side = "right",
22
+ sideOffset = constants.FLOATING_ELEMENT_SIDE_OFFSET,
23
+ align = "start",
24
+ alignOffset,
25
+ overrides: overrides$1,
26
+ className,
27
+ ...props
28
+ }, forwardedRef) => {
29
+ const $ = overrides.useOverrides(overrides$1);
30
+ const { portalContainer } = config.useLiveblocksUiConfig();
31
+ const [isOpen, setIsOpen] = useControllableState.useControllableState(
32
+ defaultOpen ?? false,
33
+ open,
34
+ onOpenChange
35
+ );
36
+ return /* @__PURE__ */ jsxRuntime.jsxs(radixUi.Popover.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
37
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Trigger, { asChild: true, children }),
38
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
39
+ radixUi.Popover.Content,
40
+ {
41
+ className: cn.cn(
42
+ "lb-root lb-portal lb-elevation lb-floating-composer",
43
+ className
44
+ ),
45
+ dir: $.dir,
46
+ side,
47
+ sideOffset,
48
+ align,
49
+ alignOffset,
50
+ collisionPadding: constants.FLOATING_ELEMENT_COLLISION_PADDING,
51
+ onEscapeKeyDown: (event) => {
52
+ if (event.defaultPrevented) {
53
+ return;
54
+ }
55
+ setIsOpen(false);
56
+ event.preventDefault();
57
+ },
58
+ onInteractOutside: (event) => {
59
+ const target = event.target;
60
+ if (target.closest(".lb-portal")) {
61
+ event.preventDefault();
62
+ }
63
+ },
64
+ asChild: true,
65
+ children: /* @__PURE__ */ jsxRuntime.jsx(
66
+ Composer.Composer,
67
+ {
68
+ ref: forwardedRef,
69
+ overrides: overrides$1,
70
+ autoFocus: true,
71
+ collapsed: false,
72
+ ...props
73
+ }
74
+ )
75
+ }
76
+ ) })
77
+ ] });
78
+ }
79
+ );
80
+
81
+ exports.FloatingComposer = FloatingComposer;
82
+ //# sourceMappingURL=FloatingComposer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingComposer.cjs","sources":["../../src/components/FloatingComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\n\nexport interface FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<\n ComposerProps<TM, CM>,\n \"collapsed\" | \"onCollapsedChange\" | \"defaultCollapsed\"\n >,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating composer.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating composer attached to a trigger element.\n */\nexport const FloatingComposer = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingComposerProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-composer\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Composer\n ref={forwardedRef}\n overrides={overrides}\n autoFocus\n collapsed={false}\n {...(props as ComposerProps<TM, CM>)}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingComposerProps<TM, CM> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAgDO;AAAyB;AAE5B;AACE;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACS;AACE;AACN;AAAA;AACP;AAAA;AAEJ;AACF;AAGN;;"}
@@ -0,0 +1,80 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { Popover } from 'radix-ui';
4
+ import { forwardRef } from 'react';
5
+ import { useLiveblocksUiConfig } from '../config.js';
6
+ import { FLOATING_ELEMENT_COLLISION_PADDING, FLOATING_ELEMENT_SIDE_OFFSET } from '../constants.js';
7
+ import { useOverrides } from '../overrides.js';
8
+ import { cn } from '../utils/cn.js';
9
+ import { useControllableState } from '../utils/use-controllable-state.js';
10
+ import { Composer } from './Composer.js';
11
+
12
+
13
+ const FloatingComposer = forwardRef(
14
+ ({
15
+ children,
16
+ defaultOpen,
17
+ open,
18
+ onOpenChange,
19
+ side = "right",
20
+ sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,
21
+ align = "start",
22
+ alignOffset,
23
+ overrides,
24
+ className,
25
+ ...props
26
+ }, forwardedRef) => {
27
+ const $ = useOverrides(overrides);
28
+ const { portalContainer } = useLiveblocksUiConfig();
29
+ const [isOpen, setIsOpen] = useControllableState(
30
+ defaultOpen ?? false,
31
+ open,
32
+ onOpenChange
33
+ );
34
+ return /* @__PURE__ */ jsxs(Popover.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
35
+ /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children }),
36
+ /* @__PURE__ */ jsx(Popover.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
37
+ Popover.Content,
38
+ {
39
+ className: cn(
40
+ "lb-root lb-portal lb-elevation lb-floating-composer",
41
+ className
42
+ ),
43
+ dir: $.dir,
44
+ side,
45
+ sideOffset,
46
+ align,
47
+ alignOffset,
48
+ collisionPadding: FLOATING_ELEMENT_COLLISION_PADDING,
49
+ onEscapeKeyDown: (event) => {
50
+ if (event.defaultPrevented) {
51
+ return;
52
+ }
53
+ setIsOpen(false);
54
+ event.preventDefault();
55
+ },
56
+ onInteractOutside: (event) => {
57
+ const target = event.target;
58
+ if (target.closest(".lb-portal")) {
59
+ event.preventDefault();
60
+ }
61
+ },
62
+ asChild: true,
63
+ children: /* @__PURE__ */ jsx(
64
+ Composer,
65
+ {
66
+ ref: forwardedRef,
67
+ overrides,
68
+ autoFocus: true,
69
+ collapsed: false,
70
+ ...props
71
+ }
72
+ )
73
+ }
74
+ ) })
75
+ ] });
76
+ }
77
+ );
78
+
79
+ export { FloatingComposer };
80
+ //# sourceMappingURL=FloatingComposer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingComposer.js","sources":["../../src/components/FloatingComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\n\nexport interface FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<\n ComposerProps<TM, CM>,\n \"collapsed\" | \"onCollapsedChange\" | \"defaultCollapsed\"\n >,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating composer.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating composer attached to a trigger element.\n */\nexport const FloatingComposer = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingComposerProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-composer\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Composer\n ref={forwardedRef}\n overrides={overrides}\n autoFocus\n collapsed={false}\n {...(props as ComposerProps<TM, CM>)}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingComposerProps<TM, CM> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;AAgDO;AAAyB;AAE5B;AACE;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACS;AACE;AACN;AAAA;AACP;AAAA;AAEJ;AACF;AAGN;;"}
@@ -0,0 +1,82 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var radixUi = require('radix-ui');
6
+ var react = require('react');
7
+ var config = require('../config.cjs');
8
+ var constants = require('../constants.cjs');
9
+ var overrides = require('../overrides.cjs');
10
+ var cn = require('../utils/cn.cjs');
11
+ var useControllableState = require('../utils/use-controllable-state.cjs');
12
+ var Thread = require('./Thread.cjs');
13
+
14
+
15
+ const FloatingThread = react.forwardRef(
16
+ ({
17
+ thread,
18
+ children,
19
+ defaultOpen,
20
+ open,
21
+ onOpenChange,
22
+ side = "right",
23
+ sideOffset = constants.FLOATING_ELEMENT_SIDE_OFFSET,
24
+ align = "start",
25
+ alignOffset,
26
+ overrides: overrides$1,
27
+ className,
28
+ ...props
29
+ }, forwardedRef) => {
30
+ const $ = overrides.useOverrides(overrides$1);
31
+ const { portalContainer } = config.useLiveblocksUiConfig();
32
+ const [isOpen, setIsOpen] = useControllableState.useControllableState(
33
+ defaultOpen ?? false,
34
+ open,
35
+ onOpenChange
36
+ );
37
+ return /* @__PURE__ */ jsxRuntime.jsxs(radixUi.Popover.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
38
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Trigger, { asChild: true, children }),
39
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
40
+ radixUi.Popover.Content,
41
+ {
42
+ className: cn.cn(
43
+ "lb-root lb-portal lb-elevation lb-floating-thread",
44
+ className
45
+ ),
46
+ dir: $.dir,
47
+ side,
48
+ sideOffset,
49
+ align,
50
+ alignOffset,
51
+ collisionPadding: constants.FLOATING_ELEMENT_COLLISION_PADDING,
52
+ onEscapeKeyDown: (event) => {
53
+ if (event.defaultPrevented) {
54
+ return;
55
+ }
56
+ setIsOpen(false);
57
+ event.preventDefault();
58
+ },
59
+ onInteractOutside: (event) => {
60
+ const target = event.target;
61
+ if (target.closest(".lb-portal")) {
62
+ event.preventDefault();
63
+ }
64
+ },
65
+ asChild: true,
66
+ children: /* @__PURE__ */ jsxRuntime.jsx(
67
+ Thread.Thread,
68
+ {
69
+ ref: forwardedRef,
70
+ thread,
71
+ overrides: overrides$1,
72
+ ...props
73
+ }
74
+ )
75
+ }
76
+ ) })
77
+ ] });
78
+ }
79
+ );
80
+
81
+ exports.FloatingThread = FloatingThread;
82
+ //# sourceMappingURL=FloatingThread.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingThread.cjs","sources":["../../src/components/FloatingThread.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ThreadProps } from \"./Thread\";\nimport { Thread } from \"./Thread\";\n\nexport interface FloatingThreadProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends ThreadProps<TM, CM>,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating thread.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating thread attached to a trigger element.\n */\nexport const FloatingThread = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n thread,\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingThreadProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-thread\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Thread\n ref={forwardedRef}\n thread={thread}\n overrides={overrides}\n {...props}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingThreadProps<TM, CM> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AA6CO;AAAuB;AAE1B;AACE;AACA;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACI;AAAA;AACN;AAAA;AAEJ;AACF;AAGN;;"}
@@ -0,0 +1,80 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { Popover } from 'radix-ui';
4
+ import { forwardRef } from 'react';
5
+ import { useLiveblocksUiConfig } from '../config.js';
6
+ import { FLOATING_ELEMENT_COLLISION_PADDING, FLOATING_ELEMENT_SIDE_OFFSET } from '../constants.js';
7
+ import { useOverrides } from '../overrides.js';
8
+ import { cn } from '../utils/cn.js';
9
+ import { useControllableState } from '../utils/use-controllable-state.js';
10
+ import { Thread } from './Thread.js';
11
+
12
+
13
+ const FloatingThread = forwardRef(
14
+ ({
15
+ thread,
16
+ children,
17
+ defaultOpen,
18
+ open,
19
+ onOpenChange,
20
+ side = "right",
21
+ sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,
22
+ align = "start",
23
+ alignOffset,
24
+ overrides,
25
+ className,
26
+ ...props
27
+ }, forwardedRef) => {
28
+ const $ = useOverrides(overrides);
29
+ const { portalContainer } = useLiveblocksUiConfig();
30
+ const [isOpen, setIsOpen] = useControllableState(
31
+ defaultOpen ?? false,
32
+ open,
33
+ onOpenChange
34
+ );
35
+ return /* @__PURE__ */ jsxs(Popover.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
36
+ /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children }),
37
+ /* @__PURE__ */ jsx(Popover.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
38
+ Popover.Content,
39
+ {
40
+ className: cn(
41
+ "lb-root lb-portal lb-elevation lb-floating-thread",
42
+ className
43
+ ),
44
+ dir: $.dir,
45
+ side,
46
+ sideOffset,
47
+ align,
48
+ alignOffset,
49
+ collisionPadding: FLOATING_ELEMENT_COLLISION_PADDING,
50
+ onEscapeKeyDown: (event) => {
51
+ if (event.defaultPrevented) {
52
+ return;
53
+ }
54
+ setIsOpen(false);
55
+ event.preventDefault();
56
+ },
57
+ onInteractOutside: (event) => {
58
+ const target = event.target;
59
+ if (target.closest(".lb-portal")) {
60
+ event.preventDefault();
61
+ }
62
+ },
63
+ asChild: true,
64
+ children: /* @__PURE__ */ jsx(
65
+ Thread,
66
+ {
67
+ ref: forwardedRef,
68
+ thread,
69
+ overrides,
70
+ ...props
71
+ }
72
+ )
73
+ }
74
+ ) })
75
+ ] });
76
+ }
77
+ );
78
+
79
+ export { FloatingThread };
80
+ //# sourceMappingURL=FloatingThread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingThread.js","sources":["../../src/components/FloatingThread.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ThreadProps } from \"./Thread\";\nimport { Thread } from \"./Thread\";\n\nexport interface FloatingThreadProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends ThreadProps<TM, CM>,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating thread.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating thread attached to a trigger element.\n */\nexport const FloatingThread = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n thread,\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingThreadProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-thread\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Thread\n ref={forwardedRef}\n thread={thread}\n overrides={overrides}\n {...props}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingThreadProps<TM, CM> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;AA6CO;AAAuB;AAE1B;AACE;AACA;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACI;AAAA;AACN;AAAA;AAEJ;AACF;AAGN;;"}