@liveblocks/react-tiptap 2.16.0 → 2.16.1-ai

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 (46) hide show
  1. package/dist/LiveblocksExtension.js +141 -21
  2. package/dist/LiveblocksExtension.js.map +1 -1
  3. package/dist/LiveblocksExtension.mjs +141 -21
  4. package/dist/LiveblocksExtension.mjs.map +1 -1
  5. package/dist/ai/AiExtension.js +288 -0
  6. package/dist/ai/AiExtension.js.map +1 -0
  7. package/dist/ai/AiExtension.mjs +285 -0
  8. package/dist/ai/AiExtension.mjs.map +1 -0
  9. package/dist/ai/AiToolbar.js +540 -0
  10. package/dist/ai/AiToolbar.js.map +1 -0
  11. package/dist/ai/AiToolbar.mjs +537 -0
  12. package/dist/ai/AiToolbar.mjs.map +1 -0
  13. package/dist/comments/CommentsExtension.js.map +1 -1
  14. package/dist/comments/CommentsExtension.mjs.map +1 -1
  15. package/dist/index.d.mts +54 -14
  16. package/dist/index.d.ts +54 -14
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +1 -0
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/toolbar/FloatingToolbar.js +7 -0
  22. package/dist/toolbar/FloatingToolbar.js.map +1 -1
  23. package/dist/toolbar/FloatingToolbar.mjs +7 -0
  24. package/dist/toolbar/FloatingToolbar.mjs.map +1 -1
  25. package/dist/toolbar/Toolbar.js +36 -2
  26. package/dist/toolbar/Toolbar.js.map +1 -1
  27. package/dist/toolbar/Toolbar.mjs +37 -3
  28. package/dist/toolbar/Toolbar.mjs.map +1 -1
  29. package/dist/toolbar/shared.js +4 -1
  30. package/dist/toolbar/shared.js.map +1 -1
  31. package/dist/toolbar/shared.mjs +5 -2
  32. package/dist/toolbar/shared.mjs.map +1 -1
  33. package/dist/types.js.map +1 -1
  34. package/dist/types.mjs.map +1 -1
  35. package/dist/utils.js +29 -1
  36. package/dist/utils.js.map +1 -1
  37. package/dist/utils.mjs +27 -2
  38. package/dist/utils.mjs.map +1 -1
  39. package/dist/version.js +1 -1
  40. package/dist/version.js.map +1 -1
  41. package/dist/version.mjs +1 -1
  42. package/dist/version.mjs.map +1 -1
  43. package/package.json +7 -6
  44. package/src/styles/index.css +319 -3
  45. package/styles.css +1 -1
  46. package/styles.css.map +1 -1
@@ -0,0 +1,540 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var reactDom = require('@floating-ui/react-dom');
5
+ var _private$1 = require('@liveblocks/react/_private');
6
+ var _private = require('@liveblocks/react-ui/_private');
7
+ var react$1 = require('@tiptap/react');
8
+ var cmdk = require('cmdk');
9
+ var react = require('react');
10
+ var reactDom$1 = require('react-dom');
11
+ var classnames = require('../classnames.js');
12
+ var context = require('../context.js');
13
+ var utils = require('../utils.js');
14
+ var AiExtension = require('./AiExtension.js');
15
+
16
+ const AI_TOOLBAR_COLLISION_PADDING = 10;
17
+ const AiToolbarContext = react.createContext(null);
18
+ function useAiToolbarContext() {
19
+ const context = react.useContext(AiToolbarContext);
20
+ if (!context) {
21
+ throw new Error("useAiToolbarContext must be used within an AiToolbar");
22
+ }
23
+ return context;
24
+ }
25
+ function tiptapFloating(editor) {
26
+ return {
27
+ name: "tiptap",
28
+ options: editor,
29
+ fn({ elements }) {
30
+ if (!editor) {
31
+ return {};
32
+ }
33
+ const editorRect = editor.view.dom.getBoundingClientRect();
34
+ elements.floating.style.setProperty(
35
+ "--lb-tiptap-editor-width",
36
+ `${editorRect.width}px`
37
+ );
38
+ elements.floating.style.setProperty(
39
+ "--lb-tiptap-editor-height",
40
+ `${editorRect.height}px`
41
+ );
42
+ return {
43
+ x: editorRect.x
44
+ };
45
+ }
46
+ };
47
+ }
48
+ const AiToolbarDropdownGroup = react.forwardRef(({ children, label, ...props }, forwardedRef) => {
49
+ return /* @__PURE__ */ jsxRuntime.jsx(cmdk.Command.Group, {
50
+ heading: /* @__PURE__ */ jsxRuntime.jsx("span", {
51
+ className: "lb-dropdown-label",
52
+ children: label
53
+ }),
54
+ ...props,
55
+ ref: forwardedRef,
56
+ children
57
+ });
58
+ });
59
+ const AiToolbarSuggestionsGroup = react.forwardRef((props, forwardedRef) => {
60
+ return /* @__PURE__ */ jsxRuntime.jsx(AiToolbarDropdownGroup, {
61
+ ref: forwardedRef,
62
+ ...props
63
+ });
64
+ });
65
+ const AiToolbarDropdownItem = react.forwardRef(({ children, onSelect, icon, ...props }, forwardedRef) => {
66
+ return /* @__PURE__ */ jsxRuntime.jsxs(cmdk.Command.Item, {
67
+ className: "lb-dropdown-item",
68
+ onSelect,
69
+ ...props,
70
+ ref: forwardedRef,
71
+ children: [
72
+ icon ? /* @__PURE__ */ jsxRuntime.jsx("span", {
73
+ className: "lb-icon-container",
74
+ children: icon
75
+ }) : null,
76
+ children ? /* @__PURE__ */ jsxRuntime.jsx("span", {
77
+ className: "lb-dropdown-item-label",
78
+ children
79
+ }) : null
80
+ ]
81
+ });
82
+ });
83
+ const AiToolbarSuggestion = react.forwardRef(({ prompt: manualPrompt, ...props }, forwardedRef) => {
84
+ const editor = context.useCurrentEditor("Suggestion", "AiToolbar");
85
+ const handleSelect = react.useCallback(
86
+ (prompt) => {
87
+ editor.commands.$startAiToolbarThinking(
88
+ manualPrompt ?? prompt
89
+ );
90
+ },
91
+ [editor, manualPrompt]
92
+ );
93
+ return /* @__PURE__ */ jsxRuntime.jsx(AiToolbarDropdownItem, {
94
+ ...props,
95
+ onSelect: handleSelect,
96
+ ref: forwardedRef
97
+ });
98
+ });
99
+ function AiToolbarReviewingSuggestions() {
100
+ const editor = context.useCurrentEditor("ReviewingSuggestions", "AiToolbar");
101
+ const { state } = useAiToolbarContext();
102
+ const { prompt } = state;
103
+ const handleRetry = react.useCallback(() => {
104
+ editor.commands.$startAiToolbarThinking(prompt);
105
+ }, [editor, prompt]);
106
+ const handleDiscard = react.useCallback(() => {
107
+ editor.commands.$closeAiToolbar();
108
+ }, [editor]);
109
+ const handleAccept = react.useCallback(() => {
110
+ editor.commands.$acceptAiToolbarOutput();
111
+ }, [editor]);
112
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
113
+ children: [
114
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarDropdownItem, {
115
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.CheckIcon, {}),
116
+ onSelect: handleAccept,
117
+ children: "Replace selection"
118
+ }),
119
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarDropdownItem, {
120
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.CheckIcon, {}),
121
+ children: "Insert below"
122
+ }),
123
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarDropdownItem, {
124
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.UndoIcon, {}),
125
+ onSelect: handleRetry,
126
+ children: "Try again"
127
+ }),
128
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarDropdownItem, {
129
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.CrossIcon, {}),
130
+ onSelect: handleDiscard,
131
+ children: "Discard"
132
+ })
133
+ ]
134
+ });
135
+ }
136
+ function AiToolbarCustomPromptContent() {
137
+ const editor = context.useCurrentEditor("CustomPromptContent", "AiToolbar");
138
+ const aiName = editor.storage.liveblocksAi.name;
139
+ const textAreaRef = react.useRef(null);
140
+ const { state, dropdownRef, isDropdownHidden } = useAiToolbarContext();
141
+ const { customPrompt } = state;
142
+ const isCustomPromptEmpty = react.useMemo(
143
+ () => customPrompt.trim() === "",
144
+ [customPrompt]
145
+ );
146
+ _private$1.useLayoutEffect(
147
+ () => {
148
+ setTimeout(() => {
149
+ const textArea = textAreaRef.current;
150
+ if (!textArea) {
151
+ return;
152
+ }
153
+ textArea.focus();
154
+ textArea.setSelectionRange(
155
+ textArea.value.length,
156
+ textArea.value.length
157
+ );
158
+ }, 0);
159
+ },
160
+ []
161
+ );
162
+ const handlePromptKeyDown = (event) => {
163
+ if (event.key === "Enter") {
164
+ event.preventDefault();
165
+ event.stopPropagation();
166
+ if (event.shiftKey) {
167
+ editor.commands._updateAiToolbarCustomPrompt(
168
+ (customPrompt2) => customPrompt2 + "\n"
169
+ );
170
+ } else {
171
+ const selectedDropdownItem = dropdownRef.current?.querySelector(
172
+ "[role='option'][data-selected='true']"
173
+ );
174
+ if (!isDropdownHidden && selectedDropdownItem) {
175
+ selectedDropdownItem.click();
176
+ } else if (!isCustomPromptEmpty) {
177
+ editor.commands.$startAiToolbarThinking(
178
+ customPrompt
179
+ );
180
+ }
181
+ }
182
+ }
183
+ };
184
+ const handleCustomPromptChange = react.useCallback(
185
+ (customPrompt2) => {
186
+ editor.commands._updateAiToolbarCustomPrompt(
187
+ customPrompt2
188
+ );
189
+ },
190
+ [editor]
191
+ );
192
+ const handleSendClick = react.useCallback(() => {
193
+ if (isCustomPromptEmpty) {
194
+ return;
195
+ }
196
+ editor.commands.$startAiToolbarThinking(
197
+ customPrompt
198
+ );
199
+ }, [editor, customPrompt, isCustomPromptEmpty]);
200
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", {
201
+ className: "lb-tiptap-ai-toolbar-content",
202
+ children: [
203
+ /* @__PURE__ */ jsxRuntime.jsx("span", {
204
+ className: "lb-icon-container lb-tiptap-ai-toolbar-icon-container",
205
+ children: /* @__PURE__ */ jsxRuntime.jsx(_private.SparklesIcon, {})
206
+ }),
207
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
208
+ className: "lb-tiptap-ai-toolbar-custom-prompt-container",
209
+ "data-value": customPrompt,
210
+ children: /* @__PURE__ */ jsxRuntime.jsx(cmdk.Command.Input, {
211
+ value: customPrompt,
212
+ onValueChange: handleCustomPromptChange,
213
+ asChild: true,
214
+ children: /* @__PURE__ */ jsxRuntime.jsx("textarea", {
215
+ ref: textAreaRef,
216
+ className: "lb-tiptap-ai-toolbar-custom-prompt",
217
+ placeholder: `Ask ${aiName} anything\u2026`,
218
+ onKeyDown: handlePromptKeyDown,
219
+ rows: 1,
220
+ autoFocus: true
221
+ })
222
+ })
223
+ }),
224
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
225
+ className: "lb-tiptap-ai-toolbar-actions",
226
+ children: /* @__PURE__ */ jsxRuntime.jsx(_private.ShortcutTooltip, {
227
+ content: `Ask ${aiName}`,
228
+ shortcut: "Enter",
229
+ children: /* @__PURE__ */ jsxRuntime.jsx(_private.Button, {
230
+ className: "lb-tiptap-ai-toolbar-action",
231
+ variant: "primary",
232
+ "aria-label": `Ask ${aiName}`,
233
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.SendIcon, {}),
234
+ disabled: isCustomPromptEmpty,
235
+ onClick: handleSendClick
236
+ })
237
+ })
238
+ })
239
+ ]
240
+ });
241
+ }
242
+ function AiToolbarAsking() {
243
+ return /* @__PURE__ */ jsxRuntime.jsx(AiToolbarCustomPromptContent, {});
244
+ }
245
+ function AiToolbarThinking() {
246
+ const editor = context.useCurrentEditor("AiToolbarThinking", "AiToolbar");
247
+ const contentRef = react.useRef(null);
248
+ const aiName = editor.storage.liveblocksAi.name;
249
+ const handleCancel = react.useCallback(() => {
250
+ editor.commands.$cancelAiToolbarThinking();
251
+ }, [editor]);
252
+ _private$1.useLayoutEffect(() => {
253
+ contentRef.current?.focus();
254
+ window.getSelection()?.removeAllRanges();
255
+ }, []);
256
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {
257
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", {
258
+ className: "lb-tiptap-ai-toolbar-content",
259
+ tabIndex: 0,
260
+ ref: contentRef,
261
+ children: [
262
+ /* @__PURE__ */ jsxRuntime.jsx("span", {
263
+ className: "lb-icon-container lb-tiptap-ai-toolbar-icon-container",
264
+ children: /* @__PURE__ */ jsxRuntime.jsx(_private.SparklesIcon, {})
265
+ }),
266
+ /* @__PURE__ */ jsxRuntime.jsxs("div", {
267
+ className: "lb-tiptap-ai-toolbar-thinking",
268
+ children: [
269
+ aiName,
270
+ " is thinking\u2026"
271
+ ]
272
+ }),
273
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
274
+ className: "lb-tiptap-ai-toolbar-actions",
275
+ children: /* @__PURE__ */ jsxRuntime.jsx(_private.ShortcutTooltip, {
276
+ content: "Cancel",
277
+ shortcut: "Escape",
278
+ children: /* @__PURE__ */ jsxRuntime.jsx(_private.Button, {
279
+ className: "lb-tiptap-ai-toolbar-action",
280
+ variant: "secondary",
281
+ "aria-label": "Cancel",
282
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.UndoIcon, {}),
283
+ onClick: handleCancel
284
+ })
285
+ })
286
+ })
287
+ ]
288
+ })
289
+ });
290
+ }
291
+ function AiToolbarReviewing() {
292
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {
293
+ children: /* @__PURE__ */ jsxRuntime.jsx(AiToolbarCustomPromptContent, {})
294
+ });
295
+ }
296
+ function AiToolbarContainer({
297
+ state,
298
+ toolbarRef,
299
+ dropdownRef,
300
+ children
301
+ }) {
302
+ const editor = context.useCurrentEditor("AiToolbarContainer", "AiToolbar");
303
+ const phase = state.phase;
304
+ const customPrompt = state.customPrompt;
305
+ const isCustomPromptMultiline = react.useMemo(
306
+ () => customPrompt?.includes("\n"),
307
+ [customPrompt]
308
+ );
309
+ const hasDropdownItems = cmdk.useCommandState(
310
+ (state2) => state2.filtered.count > 0
311
+ );
312
+ const isDropdownHidden = isCustomPromptMultiline || !hasDropdownItems;
313
+ react.useEffect(() => {
314
+ if (!editor) {
315
+ return;
316
+ }
317
+ const handleKeyDown = (event) => {
318
+ if (!event.defaultPrevented && event.key === "Escape") {
319
+ event.preventDefault();
320
+ event.stopPropagation();
321
+ if (phase === "thinking") {
322
+ editor.commands.$cancelAiToolbarThinking();
323
+ } else {
324
+ editor.chain().$closeAiToolbar().focus().run();
325
+ }
326
+ }
327
+ };
328
+ document.addEventListener("keydown", handleKeyDown);
329
+ return () => {
330
+ document.removeEventListener("keydown", handleKeyDown);
331
+ };
332
+ }, [editor, phase]);
333
+ return /* @__PURE__ */ jsxRuntime.jsxs(AiToolbarContext.Provider, {
334
+ value: { state, toolbarRef, dropdownRef, isDropdownHidden },
335
+ children: [
336
+ /* @__PURE__ */ jsxRuntime.jsxs("div", {
337
+ className: "lb-tiptap-ai-toolbar-container",
338
+ children: [
339
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
340
+ className: "lb-elevation lb-tiptap-ai-toolbar",
341
+ children: state.phase === "asking" ? /* @__PURE__ */ jsxRuntime.jsx(AiToolbarAsking, {}) : state.phase === "thinking" ? /* @__PURE__ */ jsxRuntime.jsx(AiToolbarThinking, {}) : state.phase === "reviewing" ? /* @__PURE__ */ jsxRuntime.jsx(AiToolbarReviewing, {}) : null
342
+ }),
343
+ /* @__PURE__ */ jsxRuntime.jsxs("div", {
344
+ className: "lb-tiptap-ai-toolbar-halo",
345
+ "data-active": state.phase === "thinking" ? "" : void 0,
346
+ "aria-hidden": true,
347
+ children: [
348
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
349
+ className: "lb-tiptap-ai-toolbar-halo-horizontal"
350
+ }),
351
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
352
+ className: "lb-tiptap-ai-toolbar-halo-vertical"
353
+ })
354
+ ]
355
+ })
356
+ ]
357
+ }),
358
+ state.phase === "asking" || state.phase === "reviewing" ? /* @__PURE__ */ jsxRuntime.jsx(cmdk.Command.List, {
359
+ className: "lb-elevation lb-dropdown lb-tiptap-ai-toolbar-dropdown",
360
+ "data-hidden": isDropdownHidden ? "" : void 0,
361
+ ref: dropdownRef,
362
+ children: state.phase === "reviewing" ? /* @__PURE__ */ jsxRuntime.jsx(AiToolbarReviewingSuggestions, {}) : children
363
+ }) : null
364
+ ]
365
+ });
366
+ }
367
+ const defaultSuggestions = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
368
+ children: [
369
+ /* @__PURE__ */ jsxRuntime.jsxs(AiToolbarSuggestionsGroup, {
370
+ label: "Modify",
371
+ children: [
372
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarSuggestion, {
373
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.EditIcon, {}),
374
+ children: "Improve writing"
375
+ }),
376
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarSuggestion, {
377
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.CheckIcon, {}),
378
+ children: "Fix mistakes"
379
+ }),
380
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarSuggestion, {
381
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.ShortenIcon, {}),
382
+ children: "Simplify"
383
+ }),
384
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarSuggestion, {
385
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.LengthenIcon, {}),
386
+ children: "Add more detail"
387
+ })
388
+ ]
389
+ }),
390
+ /* @__PURE__ */ jsxRuntime.jsx(AiToolbarSuggestionsGroup, {
391
+ label: "Generate",
392
+ children: /* @__PURE__ */ jsxRuntime.jsx(AiToolbarSuggestion, {
393
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private.QuestionMarkIcon, {}),
394
+ children: "Explain"
395
+ })
396
+ })
397
+ ]
398
+ });
399
+ const AiToolbar = Object.assign(
400
+ react.forwardRef(
401
+ ({
402
+ position = "bottom",
403
+ offset: sideOffset = 6,
404
+ editor,
405
+ className,
406
+ suggestions: Suggestions = defaultSuggestions,
407
+ ...props
408
+ }, forwardedRef) => {
409
+ const state = react$1.useEditorState({
410
+ editor,
411
+ selector: (ctx) => {
412
+ return ctx.editor?.storage.liveblocksAi?.state;
413
+ }
414
+ }) ?? AiExtension.DEFAULT_STATE;
415
+ const selection = editor?.state.selection;
416
+ const phase = state.phase;
417
+ const floatingOptions = react.useMemo(() => {
418
+ const detectOverflowOptions = {
419
+ padding: AI_TOOLBAR_COLLISION_PADDING
420
+ };
421
+ return {
422
+ strategy: "fixed",
423
+ placement: position,
424
+ middleware: [
425
+ tiptapFloating(editor),
426
+ reactDom.hide(detectOverflowOptions),
427
+ reactDom.offset(sideOffset)
428
+ ],
429
+ whileElementsMounted: (...args) => {
430
+ return reactDom.autoUpdate(...args, {
431
+ animationFrame: true
432
+ });
433
+ }
434
+ };
435
+ }, [editor, position, sideOffset]);
436
+ const isOpen = selection !== void 0 && state.phase !== "closed";
437
+ const {
438
+ refs: { setReference, setFloating },
439
+ strategy,
440
+ x,
441
+ y,
442
+ isPositioned
443
+ } = reactDom.useFloating({
444
+ ...floatingOptions,
445
+ open: isOpen
446
+ });
447
+ const toolbarRef = react.useRef(null);
448
+ const mergedRefs = _private.useRefs(forwardedRef, toolbarRef, setFloating);
449
+ const dropdownRef = react.useRef(null);
450
+ react.useEffect(() => {
451
+ if (!editor) {
452
+ return;
453
+ }
454
+ if (!selection && phase !== "closed") {
455
+ editor.commands.$closeAiToolbar();
456
+ }
457
+ }, [phase, editor, selection]);
458
+ _private$1.useLayoutEffect(() => {
459
+ if (!editor || !isOpen) {
460
+ return;
461
+ }
462
+ setReference(null);
463
+ setTimeout(() => {
464
+ if (state.phase === "reviewing") {
465
+ const domRange = utils.getDomRangeFromSelection(state.contentTarget, editor);
466
+ setReference(domRange);
467
+ } else if (!selection) {
468
+ setReference(null);
469
+ } else {
470
+ const domRange = utils.getDomRangeFromSelection(selection, editor);
471
+ setReference(domRange);
472
+ }
473
+ }, 0);
474
+ }, [selection, editor, isOpen, state.phase, state.contentTarget, setReference]);
475
+ react.useEffect(() => {
476
+ if (!editor || !isOpen) {
477
+ return;
478
+ }
479
+ const handleOutsideEvent = (event) => {
480
+ if (!toolbarRef.current) {
481
+ return;
482
+ }
483
+ if (event.target && !toolbarRef.current.contains(event.target) && (dropdownRef.current ? !dropdownRef.current.contains(event.target) : true)) {
484
+ editor.commands.$closeAiToolbar();
485
+ }
486
+ };
487
+ setTimeout(() => {
488
+ document.addEventListener("pointerdown", handleOutsideEvent);
489
+ }, 0);
490
+ return () => {
491
+ document.removeEventListener("pointerdown", handleOutsideEvent);
492
+ };
493
+ }, [editor, isOpen]);
494
+ if (!editor || !isOpen) {
495
+ return null;
496
+ }
497
+ return reactDom$1.createPortal(
498
+ /* @__PURE__ */ jsxRuntime.jsx(_private.TooltipProvider, {
499
+ children: /* @__PURE__ */ jsxRuntime.jsx(context.EditorProvider, {
500
+ editor,
501
+ children: /* @__PURE__ */ jsxRuntime.jsx(cmdk.Command, {
502
+ role: "toolbar",
503
+ label: "AI toolbar",
504
+ "aria-orientation": "horizontal",
505
+ className: classnames.classNames(
506
+ "lb-root lb-portal lb-tiptap-ai-toolbar-portal",
507
+ className
508
+ ),
509
+ ref: mergedRefs,
510
+ style: {
511
+ position: strategy,
512
+ top: 0,
513
+ left: 0,
514
+ transform: isPositioned ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)` : "translate3d(0, -200%, 0)"
515
+ },
516
+ ...props,
517
+ children: /* @__PURE__ */ jsxRuntime.jsx(AiToolbarContainer, {
518
+ state,
519
+ dropdownRef,
520
+ toolbarRef,
521
+ children: typeof Suggestions === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Suggestions, {
522
+ children: defaultSuggestions
523
+ }) : Suggestions
524
+ })
525
+ })
526
+ })
527
+ }),
528
+ document.body
529
+ );
530
+ }
531
+ ),
532
+ {
533
+ SuggestionsGroup: AiToolbarSuggestionsGroup,
534
+ Suggestion: AiToolbarSuggestion
535
+ }
536
+ );
537
+
538
+ exports.AI_TOOLBAR_COLLISION_PADDING = AI_TOOLBAR_COLLISION_PADDING;
539
+ exports.AiToolbar = AiToolbar;
540
+ //# sourceMappingURL=AiToolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiToolbar.js","sources":["../../src/ai/AiToolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n hide,\n type Middleware,\n offset,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Button,\n CheckIcon,\n CrossIcon,\n EditIcon,\n LengthenIcon,\n QuestionMarkIcon,\n SendIcon,\n ShortcutTooltip,\n ShortenIcon,\n SparklesIcon,\n TooltipProvider,\n UndoIcon,\n useRefs,\n} from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport { Command, useCommandState } from \"cmdk\";\nimport type {\n ComponentProps,\n ComponentType,\n KeyboardEvent as ReactKeyboardEvent,\n PropsWithChildren,\n ReactNode,\n RefObject,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { EditorProvider, useCurrentEditor } from \"../context\";\nimport type {\n AiCommands,\n AiExtensionStorage,\n AiToolbarState,\n ChainedAiCommands,\n FloatingPosition,\n} from \"../types\";\nimport { getDomRangeFromSelection } from \"../utils\";\nimport { DEFAULT_STATE } from \"./AiExtension\";\n\nexport const AI_TOOLBAR_COLLISION_PADDING = 10;\n\nexport interface AiToolbarProps\n extends Omit<ComponentProps<\"div\">, \"value\" | \"defaultValue\"> {\n editor: Editor | null;\n position?: FloatingPosition;\n offset?: number;\n suggestions?: ReactNode | ComponentType<PropsWithChildren>;\n}\n\ninterface AiToolbarDropdownGroupProps extends ComponentProps<\"div\"> {\n label: string;\n}\n\ninterface AiToolbarDropdownItemProps\n extends ComponentProps<typeof Command.Item> {\n icon?: ReactNode;\n}\n\ntype AiToolbarSuggestionsGroupProps = AiToolbarDropdownGroupProps;\n\ninterface AiToolbarSuggestionProps extends ComponentProps<\"div\"> {\n prompt?: string;\n icon?: ReactNode;\n}\n\ninterface AiToolbarContext {\n state: AiToolbarState;\n toolbarRef: RefObject<HTMLDivElement>;\n dropdownRef: RefObject<HTMLDivElement>;\n isDropdownHidden: boolean;\n}\n\nconst AiToolbarContext = createContext<AiToolbarContext | null>(null);\n\nfunction useAiToolbarContext() {\n const context = useContext(AiToolbarContext);\n\n if (!context) {\n throw new Error(\"useAiToolbarContext must be used within an AiToolbar\");\n }\n\n return context;\n}\n\n/**\n * A custom Floating UI middleware to position/scale the toolbar:\n * - Vertically: relative to the reference (e.g. selection)\n * - Horizontally: relative to the editor\n * - Width: relative to the editor\n */\nfunction tiptapFloating(editor: Editor | null): Middleware {\n return {\n name: \"tiptap\",\n options: editor,\n fn({ elements }) {\n if (!editor) {\n return {};\n }\n\n const editorRect = editor.view.dom.getBoundingClientRect();\n\n elements.floating.style.setProperty(\n \"--lb-tiptap-editor-width\",\n `${editorRect.width}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-editor-height\",\n `${editorRect.height}px`\n );\n\n return {\n x: editorRect.x,\n };\n },\n };\n}\n\nconst AiToolbarDropdownGroup = forwardRef<\n HTMLDivElement,\n AiToolbarDropdownGroupProps\n>(({ children, label, ...props }, forwardedRef) => {\n return (\n <Command.Group\n heading={<span className=\"lb-dropdown-label\">{label}</span>}\n {...props}\n ref={forwardedRef}\n >\n {children}\n </Command.Group>\n );\n});\n\nconst AiToolbarSuggestionsGroup = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionsGroupProps\n>((props, forwardedRef) => {\n return <AiToolbarDropdownGroup ref={forwardedRef} {...props} />;\n});\n\nconst AiToolbarDropdownItem = forwardRef<\n HTMLDivElement,\n AiToolbarDropdownItemProps\n>(({ children, onSelect, icon, ...props }, forwardedRef) => {\n return (\n <Command.Item\n className=\"lb-dropdown-item\"\n onSelect={onSelect}\n {...props}\n ref={forwardedRef}\n >\n {icon ? <span className=\"lb-icon-container\">{icon}</span> : null}\n {children ? (\n <span className=\"lb-dropdown-item-label\">{children}</span>\n ) : null}\n </Command.Item>\n );\n});\n\nconst AiToolbarSuggestion = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionProps\n>(({ prompt: manualPrompt, ...props }, forwardedRef) => {\n const editor = useCurrentEditor(\"Suggestion\", \"AiToolbar\");\n\n const handleSelect = useCallback(\n (prompt: string) => {\n (editor.commands as unknown as AiCommands).$startAiToolbarThinking(\n manualPrompt ?? prompt\n );\n },\n [editor, manualPrompt]\n );\n\n return (\n <AiToolbarDropdownItem\n {...props}\n onSelect={handleSelect}\n ref={forwardedRef}\n />\n );\n});\n\nfunction AiToolbarReviewingSuggestions() {\n const editor = useCurrentEditor(\"ReviewingSuggestions\", \"AiToolbar\");\n const { state } = useAiToolbarContext();\n const { prompt } = state as Extract<AiToolbarState, { phase: \"reviewing\" }>;\n\n const handleRetry = useCallback(() => {\n (editor.commands as unknown as AiCommands).$startAiToolbarThinking(prompt);\n }, [editor, prompt]);\n\n const handleDiscard = useCallback(() => {\n (editor.commands as unknown as AiCommands).$closeAiToolbar();\n }, [editor]);\n\n const handleAccept = useCallback(() => {\n (editor.commands as unknown as AiCommands).$acceptAiToolbarOutput();\n }, [editor]);\n\n return (\n <>\n <AiToolbarDropdownItem icon={<CheckIcon />} onSelect={handleAccept}>\n {/* TODO: Add logic */}\n Replace selection\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem icon={<CheckIcon />}>\n {/* TODO: Add logic */}\n Insert below\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem icon={<UndoIcon />} onSelect={handleRetry}>\n Try again\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem icon={<CrossIcon />} onSelect={handleDiscard}>\n Discard\n </AiToolbarDropdownItem>\n </>\n );\n}\n\nfunction AiToolbarCustomPromptContent() {\n const editor = useCurrentEditor(\"CustomPromptContent\", \"AiToolbar\");\n const aiName = (editor.storage.liveblocksAi as AiExtensionStorage).name;\n const textAreaRef = useRef<HTMLTextAreaElement>(null);\n const { state, dropdownRef, isDropdownHidden } = useAiToolbarContext();\n const { customPrompt } = state as Exclude<\n AiToolbarState,\n { phase: \"closed\" }\n >;\n const isCustomPromptEmpty = useMemo(\n () => customPrompt.trim() === \"\",\n [customPrompt]\n );\n\n useLayoutEffect(\n () => {\n setTimeout(() => {\n const textArea = textAreaRef.current;\n\n if (!textArea) {\n return;\n }\n\n textArea.focus();\n textArea.setSelectionRange(\n textArea.value.length,\n textArea.value.length\n );\n }, 0);\n },\n [] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const handlePromptKeyDown = (\n event: ReactKeyboardEvent<HTMLTextAreaElement>\n ) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (event.shiftKey) {\n // If the shift key is pressed, add a new line\n (editor.commands as unknown as AiCommands)._updateAiToolbarCustomPrompt(\n (customPrompt) => customPrompt + \"\\n\"\n );\n } else {\n const selectedDropdownItem = dropdownRef.current?.querySelector(\n \"[role='option'][data-selected='true']\"\n ) as HTMLElement | null;\n\n if (!isDropdownHidden && selectedDropdownItem) {\n // If there's a selected dropdown item, select it\n selectedDropdownItem.click();\n } else if (!isCustomPromptEmpty) {\n // Otherwise, submit the custom prompt\n (editor.commands as unknown as AiCommands).$startAiToolbarThinking(\n customPrompt\n );\n }\n }\n }\n };\n\n const handleCustomPromptChange = useCallback(\n (customPrompt: string) => {\n (editor.commands as unknown as AiCommands)._updateAiToolbarCustomPrompt(\n customPrompt\n );\n },\n [editor]\n );\n\n const handleSendClick = useCallback(() => {\n if (isCustomPromptEmpty) {\n return;\n }\n\n (editor.commands as unknown as AiCommands).$startAiToolbarThinking(\n customPrompt\n );\n }, [editor, customPrompt, isCustomPromptEmpty]);\n\n return (\n <div className=\"lb-tiptap-ai-toolbar-content\">\n <span className=\"lb-icon-container lb-tiptap-ai-toolbar-icon-container\">\n <SparklesIcon />\n </span>\n <div\n className=\"lb-tiptap-ai-toolbar-custom-prompt-container\"\n data-value={customPrompt}\n >\n <Command.Input\n value={customPrompt}\n onValueChange={handleCustomPromptChange}\n asChild\n >\n <textarea\n ref={textAreaRef}\n className=\"lb-tiptap-ai-toolbar-custom-prompt\"\n placeholder={`Ask ${aiName} anything…`}\n onKeyDown={handlePromptKeyDown}\n rows={1}\n autoFocus\n />\n </Command.Input>\n </div>\n <div className=\"lb-tiptap-ai-toolbar-actions\">\n <ShortcutTooltip content={`Ask ${aiName}`} shortcut=\"Enter\">\n <Button\n className=\"lb-tiptap-ai-toolbar-action\"\n variant=\"primary\"\n aria-label={`Ask ${aiName}`}\n icon={<SendIcon />}\n disabled={isCustomPromptEmpty}\n onClick={handleSendClick}\n />\n </ShortcutTooltip>\n </div>\n </div>\n );\n}\n\nfunction AiToolbarAsking() {\n return <AiToolbarCustomPromptContent />;\n}\n\nfunction AiToolbarThinking() {\n const editor = useCurrentEditor(\"AiToolbarThinking\", \"AiToolbar\");\n const contentRef = useRef<HTMLDivElement>(null);\n const aiName = (editor.storage.liveblocksAi as AiExtensionStorage).name;\n\n const handleCancel = useCallback(() => {\n (editor.commands as unknown as AiCommands).$cancelAiToolbarThinking();\n }, [editor]);\n\n // Focus the toolbar content and clear the current window selection while thinking\n useLayoutEffect(() => {\n contentRef.current?.focus();\n window.getSelection()?.removeAllRanges();\n }, []);\n\n return (\n <>\n <div\n className=\"lb-tiptap-ai-toolbar-content\"\n tabIndex={0}\n ref={contentRef}\n >\n <span className=\"lb-icon-container lb-tiptap-ai-toolbar-icon-container\">\n <SparklesIcon />\n </span>\n <div className=\"lb-tiptap-ai-toolbar-thinking\">\n {aiName} is thinking…\n </div>\n <div className=\"lb-tiptap-ai-toolbar-actions\">\n <ShortcutTooltip content=\"Cancel\" shortcut=\"Escape\">\n <Button\n className=\"lb-tiptap-ai-toolbar-action\"\n variant=\"secondary\"\n aria-label=\"Cancel\"\n icon={<UndoIcon />}\n onClick={handleCancel}\n />\n </ShortcutTooltip>\n </div>\n </div>\n </>\n );\n}\n\nfunction AiToolbarReviewing() {\n return (\n <>\n {/* <div className=\"lb-tiptap-ai-toolbar-output-container\">\n <div className=\"lb-tiptap-ai-toolbar-output\">\n TODO: Display non-diff outputs inline here\n </div>\n </div> */}\n <AiToolbarCustomPromptContent />\n </>\n );\n}\n\nfunction AiToolbarContainer({\n state,\n toolbarRef,\n dropdownRef,\n children,\n}: PropsWithChildren<{\n state: AiExtensionStorage[\"state\"];\n toolbarRef: RefObject<HTMLDivElement>;\n dropdownRef: RefObject<HTMLDivElement>;\n}>) {\n const editor = useCurrentEditor(\"AiToolbarContainer\", \"AiToolbar\");\n const phase = state.phase;\n const customPrompt = state.customPrompt;\n const isCustomPromptMultiline = useMemo(\n () => customPrompt?.includes(\"\\n\"),\n [customPrompt]\n );\n const hasDropdownItems = useCommandState(\n (state) => state.filtered.count > 0\n ) as boolean;\n const isDropdownHidden = isCustomPromptMultiline || !hasDropdownItems;\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (!event.defaultPrevented && event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (phase === \"thinking\") {\n (editor.commands as unknown as AiCommands).$cancelAiToolbarThinking();\n } else {\n (editor.chain() as ChainedAiCommands).$closeAiToolbar().focus().run();\n }\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, phase]);\n\n return (\n <AiToolbarContext.Provider\n value={{ state, toolbarRef, dropdownRef, isDropdownHidden }}\n >\n <div className=\"lb-tiptap-ai-toolbar-container\">\n <div className=\"lb-elevation lb-tiptap-ai-toolbar\">\n {state.phase === \"asking\" ? (\n <AiToolbarAsking />\n ) : state.phase === \"thinking\" ? (\n <AiToolbarThinking />\n ) : state.phase === \"reviewing\" ? (\n <AiToolbarReviewing />\n ) : null}\n </div>\n <div\n className=\"lb-tiptap-ai-toolbar-halo\"\n data-active={state.phase === \"thinking\" ? \"\" : undefined}\n aria-hidden\n >\n <div className=\"lb-tiptap-ai-toolbar-halo-horizontal\" />\n <div className=\"lb-tiptap-ai-toolbar-halo-vertical\" />\n </div>\n </div>\n {state.phase === \"asking\" || state.phase === \"reviewing\" ? (\n <Command.List\n className=\"lb-elevation lb-dropdown lb-tiptap-ai-toolbar-dropdown\"\n data-hidden={isDropdownHidden ? \"\" : undefined}\n ref={dropdownRef}\n >\n {state.phase === \"reviewing\" ? (\n <AiToolbarReviewingSuggestions />\n ) : (\n children\n )}\n </Command.List>\n ) : null}\n </AiToolbarContext.Provider>\n );\n}\n\nconst defaultSuggestions = (\n <>\n <AiToolbarSuggestionsGroup label=\"Modify\">\n <AiToolbarSuggestion icon={<EditIcon />}>\n Improve writing\n </AiToolbarSuggestion>\n <AiToolbarSuggestion icon={<CheckIcon />}>\n Fix mistakes\n </AiToolbarSuggestion>\n <AiToolbarSuggestion icon={<ShortenIcon />}>Simplify</AiToolbarSuggestion>\n <AiToolbarSuggestion icon={<LengthenIcon />}>\n Add more detail\n </AiToolbarSuggestion>\n </AiToolbarSuggestionsGroup>\n <AiToolbarSuggestionsGroup label=\"Generate\">\n <AiToolbarSuggestion icon={<QuestionMarkIcon />}>\n Explain\n </AiToolbarSuggestion>\n </AiToolbarSuggestionsGroup>\n </>\n);\n\nexport const AiToolbar = Object.assign(\n forwardRef<HTMLDivElement, AiToolbarProps>(\n (\n {\n position = \"bottom\",\n offset: sideOffset = 6,\n editor,\n className,\n suggestions: Suggestions = defaultSuggestions,\n ...props\n },\n forwardedRef\n ) => {\n const state =\n useEditorState({\n editor,\n selector: (ctx) => {\n return (\n ctx.editor?.storage.liveblocksAi as AiExtensionStorage | undefined\n )?.state;\n },\n }) ?? DEFAULT_STATE;\n const selection = editor?.state.selection;\n const phase = state.phase;\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: AI_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: position,\n middleware: [\n tiptapFloating(editor),\n hide(detectOverflowOptions),\n offset(sideOffset),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [editor, position, sideOffset]);\n const isOpen = selection !== undefined && state.phase !== \"closed\";\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: isOpen,\n });\n const toolbarRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (!selection && phase !== \"closed\") {\n (editor.commands as unknown as AiCommands).$closeAiToolbar();\n }\n }, [phase, editor, selection]);\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n setReference(null);\n\n setTimeout(() => {\n if (state.phase === \"reviewing\") {\n const domRange = getDomRangeFromSelection(state.contentTarget, editor);\n setReference(domRange);\n } else if (!selection) {\n setReference(null);\n } else {\n const domRange = getDomRangeFromSelection(selection, editor);\n setReference(domRange);\n }\n }, 0);\n }, [selection, editor, isOpen, state.phase, state.contentTarget, setReference]);\n\n // Close the toolbar when clicking anywhere outside of it\n useEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n const handleOutsideEvent = (event: MouseEvent) => {\n if (!toolbarRef.current) {\n return;\n }\n\n if (\n event.target &&\n !toolbarRef.current.contains(event.target as Node) &&\n (dropdownRef.current\n ? !dropdownRef.current.contains(event.target as Node)\n : true)\n ) {\n (editor.commands as unknown as AiCommands).$closeAiToolbar();\n }\n };\n\n setTimeout(() => {\n document.addEventListener(\"pointerdown\", handleOutsideEvent);\n }, 0);\n\n return () => {\n document.removeEventListener(\"pointerdown\", handleOutsideEvent);\n };\n }, [editor, isOpen]);\n\n if (!editor || !isOpen) {\n return null;\n }\n\n return createPortal(\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <Command\n role=\"toolbar\"\n label=\"AI toolbar\"\n aria-orientation=\"horizontal\"\n className={classNames(\n \"lb-root lb-portal lb-tiptap-ai-toolbar-portal\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n }}\n {...props}\n >\n <AiToolbarContainer\n state={state}\n dropdownRef={dropdownRef}\n toolbarRef={toolbarRef}\n >\n {typeof Suggestions === \"function\" ? (\n <Suggestions children={defaultSuggestions} />\n ) : (\n Suggestions\n )}\n </AiToolbarContainer>\n </Command>\n </EditorProvider>\n </TooltipProvider>,\n document.body\n );\n }\n ),\n {\n SuggestionsGroup: AiToolbarSuggestionsGroup,\n Suggestion: AiToolbarSuggestion,\n }\n);\n"],"names":["createContext","useContext","forwardRef","jsx","Command","jsxs","useCurrentEditor","useCallback","Fragment","CheckIcon","UndoIcon","CrossIcon","useRef","useMemo","useLayoutEffect","customPrompt","SparklesIcon","ShortcutTooltip","Button","SendIcon","useCommandState","state","useEffect","EditIcon","ShortenIcon","LengthenIcon","QuestionMarkIcon","useEditorState","DEFAULT_STATE","hide","offset","autoUpdate","useFloating","useRefs","getDomRangeFromSelection","createPortal","TooltipProvider","EditorProvider","classNames"],"mappings":"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"}