@liveblocks/react-tiptap 2.15.1 → 2.16.0-toolbars1

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 (68) hide show
  1. package/dist/LiveblocksExtension.js +1 -1
  2. package/dist/LiveblocksExtension.js.map +1 -1
  3. package/dist/LiveblocksExtension.mjs +1 -1
  4. package/dist/LiveblocksExtension.mjs.map +1 -1
  5. package/dist/comments/AnchoredThreads.js +34 -16
  6. package/dist/comments/AnchoredThreads.js.map +1 -1
  7. package/dist/comments/AnchoredThreads.mjs +33 -15
  8. package/dist/comments/AnchoredThreads.mjs.map +1 -1
  9. package/dist/comments/CommentsExtension.js +6 -2
  10. package/dist/comments/CommentsExtension.js.map +1 -1
  11. package/dist/comments/CommentsExtension.mjs +7 -3
  12. package/dist/comments/CommentsExtension.mjs.map +1 -1
  13. package/dist/comments/FloatingComposer.js +34 -33
  14. package/dist/comments/FloatingComposer.js.map +1 -1
  15. package/dist/comments/FloatingComposer.mjs +36 -35
  16. package/dist/comments/FloatingComposer.mjs.map +1 -1
  17. package/dist/comments/FloatingThreads.js +5 -2
  18. package/dist/comments/FloatingThreads.js.map +1 -1
  19. package/dist/comments/FloatingThreads.mjs +5 -2
  20. package/dist/comments/FloatingThreads.mjs.map +1 -1
  21. package/dist/context.js +24 -0
  22. package/dist/context.js.map +1 -0
  23. package/dist/context.mjs +21 -0
  24. package/dist/context.mjs.map +1 -0
  25. package/dist/index.d.mts +65 -13
  26. package/dist/index.d.ts +65 -13
  27. package/dist/index.js +4 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +2 -0
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/mentions/MentionsList.js +117 -107
  32. package/dist/mentions/MentionsList.js.map +1 -1
  33. package/dist/mentions/MentionsList.mjs +119 -109
  34. package/dist/mentions/MentionsList.mjs.map +1 -1
  35. package/dist/toolbar/FloatingToolbar.js +301 -0
  36. package/dist/toolbar/FloatingToolbar.js.map +1 -0
  37. package/dist/toolbar/FloatingToolbar.mjs +298 -0
  38. package/dist/toolbar/FloatingToolbar.mjs.map +1 -0
  39. package/dist/toolbar/FloatingToolbarContext.js +8 -0
  40. package/dist/toolbar/FloatingToolbarContext.js.map +1 -0
  41. package/dist/toolbar/FloatingToolbarContext.mjs +6 -0
  42. package/dist/toolbar/FloatingToolbarContext.mjs.map +1 -0
  43. package/dist/toolbar/Toolbar.js +352 -0
  44. package/dist/toolbar/Toolbar.js.map +1 -0
  45. package/dist/toolbar/Toolbar.mjs +327 -0
  46. package/dist/toolbar/Toolbar.mjs.map +1 -0
  47. package/dist/types.js +7 -3
  48. package/dist/types.js.map +1 -1
  49. package/dist/types.mjs +6 -3
  50. package/dist/types.mjs.map +1 -1
  51. package/dist/utils.js +17 -0
  52. package/dist/utils.js.map +1 -1
  53. package/dist/utils.mjs +16 -1
  54. package/dist/utils.mjs.map +1 -1
  55. package/dist/version-history/HistoryVersionPreview.js +79 -79
  56. package/dist/version-history/HistoryVersionPreview.js.map +1 -1
  57. package/dist/version-history/HistoryVersionPreview.mjs +79 -79
  58. package/dist/version-history/HistoryVersionPreview.mjs.map +1 -1
  59. package/dist/version.js +1 -1
  60. package/dist/version.js.map +1 -1
  61. package/dist/version.mjs +1 -1
  62. package/dist/version.mjs.map +1 -1
  63. package/package.json +11 -8
  64. package/src/styles/constants.css +2 -1
  65. package/src/styles/index.css +58 -6
  66. package/src/styles/utils.css +11 -0
  67. package/styles.css +1 -1
  68. package/styles.css.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"MentionsList.js","sources":["../../src/mentions/MentionsList.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { createInboxNotificationId } from \"@liveblocks/core\";\nimport { useRoom, useUser } from \"@liveblocks/react\";\nimport { useMentionSuggestions } from \"@liveblocks/react/_private\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport type { HTMLAttributes, MouseEvent } from \"react\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useState,\n} from \"react\";\n\nimport { Avatar } from \"./Avatar\";\n\nexport interface UserProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n userId: string;\n}\n\nexport const User = forwardRef<HTMLSpanElement, UserProps>(\n function User(props, forwardedRef) {\n const { userId, className, ...spanProps } = props;\n\n const { user, isLoading } = useUser(userId);\n const $ = useOverrides();\n\n const name =\n user === undefined || user === null ? $.USER_UNKNOWN : user.name;\n\n return (\n <span\n className={className}\n data-loading={isLoading ? \"\" : undefined}\n ref={forwardedRef}\n {...spanProps}\n >\n {isLoading ? null : name}\n </span>\n );\n }\n);\n\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nexport interface MentionsListProps extends HTMLAttributes<HTMLDivElement> {\n query: string,\n command: (otps: { id: string, notificationId: string }) => void,\n clientRect: () => DOMRect,\n hide: boolean\n}\n\nexport type MentionsListHandle = {\n onKeyDown: ({ event }: { event: KeyboardEvent }) => boolean,\n};\n\nexport const MentionsList = forwardRef<MentionsListHandle, MentionsListProps>((props, ref) => {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const room = useRoom();\n const suggestions = useMentionSuggestions(room.id, props.query);\n const { onMouseEnter, onClick } = props;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"top-start\",\n middleware: [\n flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: SUGGESTIONS_COLLISION_PADDING }),\n shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: limitShift() }),\n size({ padding: SUGGESTIONS_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: props.clientRect,\n });\n }, [setReference, props.clientRect]);\n\n const selectItem = (index: number) => {\n const item = (suggestions ?? [])[index];\n if (item) {\n props.command({ id: item, notificationId: createInboxNotificationId() });\n }\n }\n\n const upHandler = () => {\n setSelectedIndex((selectedIndex + (suggestions?.length ?? 0) - 1) % (suggestions?.length ?? 0))\n }\n\n const downHandler = () => {\n setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0))\n }\n\n const enterHandler = () => {\n selectItem(selectedIndex)\n }\n\n useEffect(() => setSelectedIndex(0), [suggestions])\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"ArrowUp\") {\n upHandler()\n return true\n }\n\n if (event.key === \"ArrowDown\") {\n downHandler()\n return true\n }\n\n if (event.key === \"Enter\") {\n enterHandler()\n return true\n }\n\n return false\n },\n }))\n\n const handleClick = (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n selectItem(index)\n }\n const handleMouseEnter = (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n setSelectedIndex(index);\n }\n\n if (suggestions === undefined || suggestions.length === 0) {\n return null\n }\n\n return (\n <div className=\"lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions\" ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n display: props.hide ? \"none\" : \"block\"\n }}>\n <div className=\"lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list\">\n {suggestions.map((item, index) => (\n <div className=\"lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion\"\n key={index}\n role=\"option\"\n data-highlighted={index === selectedIndex || undefined}\n\n onMouseEnter={handleMouseEnter(index)}\n onClick={handleClick(index)}>\n <Avatar\n userId={item}\n className=\"lb-tiptap-mention-suggestion-avatar\"\n />\n <User\n userId={item}\n className=\"lb-tiptap-mention-suggestion-user\"\n />\n </div>\n ))\n }\n </div>\n </div>\n )\n})"],"names":["forwardRef","User","useUser","useOverrides","jsx","useState","useRoom","useMentionSuggestions","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createInboxNotificationId","useEffect","useImperativeHandle","jsxs","Avatar"],"mappings":"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"}
1
+ {"version":3,"file":"MentionsList.js","sources":["../../src/mentions/MentionsList.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { createInboxNotificationId } from \"@liveblocks/core\";\nimport { useRoom, useUser } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useMentionSuggestions,\n} from \"@liveblocks/react/_private\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport type { HTMLAttributes, MouseEvent } from \"react\";\nimport { forwardRef, useEffect, useImperativeHandle, useState } from \"react\";\n\nimport { Avatar } from \"./Avatar\";\n\nexport interface UserProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n userId: string;\n}\n\nexport const User = forwardRef<HTMLSpanElement, UserProps>(\n function User(props, forwardedRef) {\n const { userId, className, ...spanProps } = props;\n\n const { user, isLoading } = useUser(userId);\n const $ = useOverrides();\n\n const name =\n user === undefined || user === null ? $.USER_UNKNOWN : user.name;\n\n return (\n <span\n className={className}\n data-loading={isLoading ? \"\" : undefined}\n ref={forwardedRef}\n {...spanProps}\n >\n {isLoading ? null : name}\n </span>\n );\n }\n);\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nexport interface MentionsListProps extends HTMLAttributes<HTMLDivElement> {\n query: string;\n command: (otps: { id: string; notificationId: string }) => void;\n clientRect: () => DOMRect;\n hide: boolean;\n}\n\nexport type MentionsListHandle = {\n onKeyDown: ({ event }: { event: KeyboardEvent }) => boolean;\n};\n\nexport const MentionsList = forwardRef<MentionsListHandle, MentionsListProps>(\n (props, ref) => {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const room = useRoom();\n const suggestions = useMentionSuggestions(room.id, props.query);\n const { onMouseEnter, onClick } = props;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"top-start\",\n middleware: [\n flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: SUGGESTIONS_COLLISION_PADDING }),\n shift({\n padding: SUGGESTIONS_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: SUGGESTIONS_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: props.clientRect,\n });\n }, [setReference, props.clientRect]);\n\n const selectItem = (index: number) => {\n const item = (suggestions ?? [])[index];\n if (item) {\n props.command({\n id: item,\n notificationId: createInboxNotificationId(),\n });\n }\n };\n\n const upHandler = () => {\n setSelectedIndex(\n (selectedIndex + (suggestions?.length ?? 0) - 1) %\n (suggestions?.length ?? 0)\n );\n };\n\n const downHandler = () => {\n setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0));\n };\n\n const enterHandler = () => {\n selectItem(selectedIndex);\n };\n\n useEffect(() => setSelectedIndex(0), [suggestions]);\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"ArrowUp\") {\n upHandler();\n return true;\n }\n\n if (event.key === \"ArrowDown\") {\n downHandler();\n return true;\n }\n\n if (event.key === \"Enter\") {\n enterHandler();\n return true;\n }\n\n return false;\n },\n }));\n\n const handleClick =\n (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n selectItem(index);\n };\n const handleMouseEnter =\n (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n setSelectedIndex(index);\n };\n\n if (suggestions === undefined || suggestions.length === 0) {\n return null;\n }\n\n return (\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n display: props.hide ? \"none\" : \"block\",\n }}\n >\n <div className=\"lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list\">\n {suggestions.map((item, index) => (\n <div\n className=\"lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion\"\n key={index}\n role=\"option\"\n data-highlighted={index === selectedIndex || undefined}\n onMouseEnter={handleMouseEnter(index)}\n onClick={handleClick(index)}\n >\n <Avatar\n userId={item}\n className=\"lb-tiptap-mention-suggestion-avatar\"\n />\n <User\n userId={item}\n className=\"lb-tiptap-mention-suggestion-user\"\n />\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n"],"names":["forwardRef","User","useUser","useOverrides","jsx","useState","useRoom","useMentionSuggestions","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createInboxNotificationId","useEffect","useImperativeHandle","jsxs","Avatar"],"mappings":"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"}
@@ -2,9 +2,9 @@ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { useFloating, flip, offset, hide, shift, limitShift, size, autoUpdate } from '@floating-ui/react-dom';
3
3
  import { createInboxNotificationId } from '@liveblocks/core';
4
4
  import { useUser, useRoom } from '@liveblocks/react';
5
- import { useMentionSuggestions } from '@liveblocks/react/_private';
5
+ import { useMentionSuggestions, useLayoutEffect } from '@liveblocks/react/_private';
6
6
  import { useOverrides } from '@liveblocks/react-ui';
7
- import { forwardRef, useState, useLayoutEffect, useEffect, useImperativeHandle } from 'react';
7
+ import { forwardRef, useState, useEffect, useImperativeHandle } from 'react';
8
8
  import { Avatar } from './Avatar.mjs';
9
9
 
10
10
  const User = forwardRef(
@@ -23,118 +23,128 @@ const User = forwardRef(
23
23
  }
24
24
  );
25
25
  const SUGGESTIONS_COLLISION_PADDING = 10;
26
- const MentionsList = forwardRef((props, ref) => {
27
- const [selectedIndex, setSelectedIndex] = useState(0);
28
- const room = useRoom();
29
- const suggestions = useMentionSuggestions(room.id, props.query);
30
- const { onMouseEnter, onClick } = props;
31
- const {
32
- refs: { setReference, setFloating },
33
- strategy,
34
- x,
35
- y
36
- } = useFloating({
37
- strategy: "fixed",
38
- placement: "top-start",
39
- middleware: [
40
- flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),
41
- offset(10),
42
- hide({ padding: SUGGESTIONS_COLLISION_PADDING }),
43
- shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: limitShift() }),
44
- size({ padding: SUGGESTIONS_COLLISION_PADDING })
45
- ],
46
- whileElementsMounted: (...args) => {
47
- return autoUpdate(...args, {
48
- animationFrame: true
49
- });
50
- }
51
- });
52
- useLayoutEffect(() => {
53
- setReference({
54
- getBoundingClientRect: props.clientRect
55
- });
56
- }, [setReference, props.clientRect]);
57
- const selectItem = (index) => {
58
- const item = (suggestions ?? [])[index];
59
- if (item) {
60
- props.command({ id: item, notificationId: createInboxNotificationId() });
61
- }
62
- };
63
- const upHandler = () => {
64
- setSelectedIndex((selectedIndex + (suggestions?.length ?? 0) - 1) % (suggestions?.length ?? 0));
65
- };
66
- const downHandler = () => {
67
- setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0));
68
- };
69
- const enterHandler = () => {
70
- selectItem(selectedIndex);
71
- };
72
- useEffect(() => setSelectedIndex(0), [suggestions]);
73
- useImperativeHandle(ref, () => ({
74
- onKeyDown: ({ event }) => {
75
- if (event.key === "ArrowUp") {
76
- upHandler();
77
- return true;
26
+ const MentionsList = forwardRef(
27
+ (props, ref) => {
28
+ const [selectedIndex, setSelectedIndex] = useState(0);
29
+ const room = useRoom();
30
+ const suggestions = useMentionSuggestions(room.id, props.query);
31
+ const { onMouseEnter, onClick } = props;
32
+ const {
33
+ refs: { setReference, setFloating },
34
+ strategy,
35
+ x,
36
+ y
37
+ } = useFloating({
38
+ strategy: "fixed",
39
+ placement: "top-start",
40
+ middleware: [
41
+ flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),
42
+ offset(10),
43
+ hide({ padding: SUGGESTIONS_COLLISION_PADDING }),
44
+ shift({
45
+ padding: SUGGESTIONS_COLLISION_PADDING,
46
+ limiter: limitShift()
47
+ }),
48
+ size({ padding: SUGGESTIONS_COLLISION_PADDING })
49
+ ],
50
+ whileElementsMounted: (...args) => {
51
+ return autoUpdate(...args, {
52
+ animationFrame: true
53
+ });
78
54
  }
79
- if (event.key === "ArrowDown") {
80
- downHandler();
81
- return true;
55
+ });
56
+ useLayoutEffect(() => {
57
+ setReference({
58
+ getBoundingClientRect: props.clientRect
59
+ });
60
+ }, [setReference, props.clientRect]);
61
+ const selectItem = (index) => {
62
+ const item = (suggestions ?? [])[index];
63
+ if (item) {
64
+ props.command({
65
+ id: item,
66
+ notificationId: createInboxNotificationId()
67
+ });
82
68
  }
83
- if (event.key === "Enter") {
84
- enterHandler();
85
- return true;
69
+ };
70
+ const upHandler = () => {
71
+ setSelectedIndex(
72
+ (selectedIndex + (suggestions?.length ?? 0) - 1) % (suggestions?.length ?? 0)
73
+ );
74
+ };
75
+ const downHandler = () => {
76
+ setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0));
77
+ };
78
+ const enterHandler = () => {
79
+ selectItem(selectedIndex);
80
+ };
81
+ useEffect(() => setSelectedIndex(0), [suggestions]);
82
+ useImperativeHandle(ref, () => ({
83
+ onKeyDown: ({ event }) => {
84
+ if (event.key === "ArrowUp") {
85
+ upHandler();
86
+ return true;
87
+ }
88
+ if (event.key === "ArrowDown") {
89
+ downHandler();
90
+ return true;
91
+ }
92
+ if (event.key === "Enter") {
93
+ enterHandler();
94
+ return true;
95
+ }
96
+ return false;
86
97
  }
87
- return false;
98
+ }));
99
+ const handleClick = (index) => (event) => {
100
+ onClick?.(event);
101
+ if (event.isDefaultPrevented())
102
+ return;
103
+ selectItem(index);
104
+ };
105
+ const handleMouseEnter = (index) => (event) => {
106
+ onMouseEnter?.(event);
107
+ if (event.isDefaultPrevented())
108
+ return;
109
+ setSelectedIndex(index);
110
+ };
111
+ if (suggestions === void 0 || suggestions.length === 0) {
112
+ return null;
88
113
  }
89
- }));
90
- const handleClick = (index) => (event) => {
91
- onClick?.(event);
92
- if (event.isDefaultPrevented())
93
- return;
94
- selectItem(index);
95
- };
96
- const handleMouseEnter = (index) => (event) => {
97
- onMouseEnter?.(event);
98
- if (event.isDefaultPrevented())
99
- return;
100
- setSelectedIndex(index);
101
- };
102
- if (suggestions === void 0 || suggestions.length === 0) {
103
- return null;
114
+ return /* @__PURE__ */ jsx("div", {
115
+ className: "lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions",
116
+ ref: setFloating,
117
+ style: {
118
+ position: strategy,
119
+ top: 0,
120
+ left: 0,
121
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
122
+ minWidth: "max-content",
123
+ display: props.hide ? "none" : "block"
124
+ },
125
+ children: /* @__PURE__ */ jsx("div", {
126
+ className: "lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list",
127
+ children: suggestions.map((item, index) => /* @__PURE__ */ jsxs("div", {
128
+ className: "lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion",
129
+ role: "option",
130
+ "data-highlighted": index === selectedIndex || void 0,
131
+ onMouseEnter: handleMouseEnter(index),
132
+ onClick: handleClick(index),
133
+ children: [
134
+ /* @__PURE__ */ jsx(Avatar, {
135
+ userId: item,
136
+ className: "lb-tiptap-mention-suggestion-avatar"
137
+ }),
138
+ /* @__PURE__ */ jsx(User, {
139
+ userId: item,
140
+ className: "lb-tiptap-mention-suggestion-user"
141
+ })
142
+ ]
143
+ }, index))
144
+ })
145
+ });
104
146
  }
105
- return /* @__PURE__ */ jsx("div", {
106
- className: "lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions",
107
- ref: setFloating,
108
- style: {
109
- position: strategy,
110
- top: 0,
111
- left: 0,
112
- transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
113
- minWidth: "max-content",
114
- display: props.hide ? "none" : "block"
115
- },
116
- children: /* @__PURE__ */ jsx("div", {
117
- className: "lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list",
118
- children: suggestions.map((item, index) => /* @__PURE__ */ jsxs("div", {
119
- className: "lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion",
120
- role: "option",
121
- "data-highlighted": index === selectedIndex || void 0,
122
- onMouseEnter: handleMouseEnter(index),
123
- onClick: handleClick(index),
124
- children: [
125
- /* @__PURE__ */ jsx(Avatar, {
126
- userId: item,
127
- className: "lb-tiptap-mention-suggestion-avatar"
128
- }),
129
- /* @__PURE__ */ jsx(User, {
130
- userId: item,
131
- className: "lb-tiptap-mention-suggestion-user"
132
- })
133
- ]
134
- }, index))
135
- })
136
- });
137
- });
147
+ );
138
148
 
139
149
  export { MentionsList, SUGGESTIONS_COLLISION_PADDING, User };
140
150
  //# sourceMappingURL=MentionsList.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MentionsList.mjs","sources":["../../src/mentions/MentionsList.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { createInboxNotificationId } from \"@liveblocks/core\";\nimport { useRoom, useUser } from \"@liveblocks/react\";\nimport { useMentionSuggestions } from \"@liveblocks/react/_private\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport type { HTMLAttributes, MouseEvent } from \"react\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useState,\n} from \"react\";\n\nimport { Avatar } from \"./Avatar\";\n\nexport interface UserProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n userId: string;\n}\n\nexport const User = forwardRef<HTMLSpanElement, UserProps>(\n function User(props, forwardedRef) {\n const { userId, className, ...spanProps } = props;\n\n const { user, isLoading } = useUser(userId);\n const $ = useOverrides();\n\n const name =\n user === undefined || user === null ? $.USER_UNKNOWN : user.name;\n\n return (\n <span\n className={className}\n data-loading={isLoading ? \"\" : undefined}\n ref={forwardedRef}\n {...spanProps}\n >\n {isLoading ? null : name}\n </span>\n );\n }\n);\n\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nexport interface MentionsListProps extends HTMLAttributes<HTMLDivElement> {\n query: string,\n command: (otps: { id: string, notificationId: string }) => void,\n clientRect: () => DOMRect,\n hide: boolean\n}\n\nexport type MentionsListHandle = {\n onKeyDown: ({ event }: { event: KeyboardEvent }) => boolean,\n};\n\nexport const MentionsList = forwardRef<MentionsListHandle, MentionsListProps>((props, ref) => {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const room = useRoom();\n const suggestions = useMentionSuggestions(room.id, props.query);\n const { onMouseEnter, onClick } = props;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"top-start\",\n middleware: [\n flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: SUGGESTIONS_COLLISION_PADDING }),\n shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: limitShift() }),\n size({ padding: SUGGESTIONS_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: props.clientRect,\n });\n }, [setReference, props.clientRect]);\n\n const selectItem = (index: number) => {\n const item = (suggestions ?? [])[index];\n if (item) {\n props.command({ id: item, notificationId: createInboxNotificationId() });\n }\n }\n\n const upHandler = () => {\n setSelectedIndex((selectedIndex + (suggestions?.length ?? 0) - 1) % (suggestions?.length ?? 0))\n }\n\n const downHandler = () => {\n setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0))\n }\n\n const enterHandler = () => {\n selectItem(selectedIndex)\n }\n\n useEffect(() => setSelectedIndex(0), [suggestions])\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"ArrowUp\") {\n upHandler()\n return true\n }\n\n if (event.key === \"ArrowDown\") {\n downHandler()\n return true\n }\n\n if (event.key === \"Enter\") {\n enterHandler()\n return true\n }\n\n return false\n },\n }))\n\n const handleClick = (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n selectItem(index)\n }\n const handleMouseEnter = (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n setSelectedIndex(index);\n }\n\n if (suggestions === undefined || suggestions.length === 0) {\n return null\n }\n\n return (\n <div className=\"lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions\" ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n display: props.hide ? \"none\" : \"block\"\n }}>\n <div className=\"lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list\">\n {suggestions.map((item, index) => (\n <div className=\"lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion\"\n key={index}\n role=\"option\"\n data-highlighted={index === selectedIndex || undefined}\n\n onMouseEnter={handleMouseEnter(index)}\n onClick={handleClick(index)}>\n <Avatar\n userId={item}\n className=\"lb-tiptap-mention-suggestion-avatar\"\n />\n <User\n userId={item}\n className=\"lb-tiptap-mention-suggestion-user\"\n />\n </div>\n ))\n }\n </div>\n </div>\n )\n})"],"names":["User"],"mappings":"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"}
1
+ {"version":3,"file":"MentionsList.mjs","sources":["../../src/mentions/MentionsList.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { createInboxNotificationId } from \"@liveblocks/core\";\nimport { useRoom, useUser } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useMentionSuggestions,\n} from \"@liveblocks/react/_private\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport type { HTMLAttributes, MouseEvent } from \"react\";\nimport { forwardRef, useEffect, useImperativeHandle, useState } from \"react\";\n\nimport { Avatar } from \"./Avatar\";\n\nexport interface UserProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n userId: string;\n}\n\nexport const User = forwardRef<HTMLSpanElement, UserProps>(\n function User(props, forwardedRef) {\n const { userId, className, ...spanProps } = props;\n\n const { user, isLoading } = useUser(userId);\n const $ = useOverrides();\n\n const name =\n user === undefined || user === null ? $.USER_UNKNOWN : user.name;\n\n return (\n <span\n className={className}\n data-loading={isLoading ? \"\" : undefined}\n ref={forwardedRef}\n {...spanProps}\n >\n {isLoading ? null : name}\n </span>\n );\n }\n);\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nexport interface MentionsListProps extends HTMLAttributes<HTMLDivElement> {\n query: string;\n command: (otps: { id: string; notificationId: string }) => void;\n clientRect: () => DOMRect;\n hide: boolean;\n}\n\nexport type MentionsListHandle = {\n onKeyDown: ({ event }: { event: KeyboardEvent }) => boolean;\n};\n\nexport const MentionsList = forwardRef<MentionsListHandle, MentionsListProps>(\n (props, ref) => {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const room = useRoom();\n const suggestions = useMentionSuggestions(room.id, props.query);\n const { onMouseEnter, onClick } = props;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"top-start\",\n middleware: [\n flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: SUGGESTIONS_COLLISION_PADDING }),\n shift({\n padding: SUGGESTIONS_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: SUGGESTIONS_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: props.clientRect,\n });\n }, [setReference, props.clientRect]);\n\n const selectItem = (index: number) => {\n const item = (suggestions ?? [])[index];\n if (item) {\n props.command({\n id: item,\n notificationId: createInboxNotificationId(),\n });\n }\n };\n\n const upHandler = () => {\n setSelectedIndex(\n (selectedIndex + (suggestions?.length ?? 0) - 1) %\n (suggestions?.length ?? 0)\n );\n };\n\n const downHandler = () => {\n setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0));\n };\n\n const enterHandler = () => {\n selectItem(selectedIndex);\n };\n\n useEffect(() => setSelectedIndex(0), [suggestions]);\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"ArrowUp\") {\n upHandler();\n return true;\n }\n\n if (event.key === \"ArrowDown\") {\n downHandler();\n return true;\n }\n\n if (event.key === \"Enter\") {\n enterHandler();\n return true;\n }\n\n return false;\n },\n }));\n\n const handleClick =\n (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n selectItem(index);\n };\n const handleMouseEnter =\n (index: number) => (event: MouseEvent<HTMLDivElement>) => {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n setSelectedIndex(index);\n };\n\n if (suggestions === undefined || suggestions.length === 0) {\n return null;\n }\n\n return (\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n display: props.hide ? \"none\" : \"block\",\n }}\n >\n <div className=\"lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list\">\n {suggestions.map((item, index) => (\n <div\n className=\"lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion\"\n key={index}\n role=\"option\"\n data-highlighted={index === selectedIndex || undefined}\n onMouseEnter={handleMouseEnter(index)}\n onClick={handleClick(index)}\n >\n <Avatar\n userId={item}\n className=\"lb-tiptap-mention-suggestion-avatar\"\n />\n <User\n userId={item}\n className=\"lb-tiptap-mention-suggestion-user\"\n />\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n"],"names":["User"],"mappings":"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"}
@@ -0,0 +1,301 @@
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 react = require('react');
9
+ var reactDom$1 = require('react-dom');
10
+ var classnames = require('../classnames.js');
11
+ var context = require('../context.js');
12
+ var FloatingToolbarContext = require('./FloatingToolbarContext.js');
13
+ var Toolbar = require('./Toolbar.js');
14
+
15
+ const FLOATING_TOOLBAR_COLLISION_PADDING = 10;
16
+ const FLOATING_TOOLBAR_OPEN_DELAY = 50;
17
+ function DefaultFloatingToolbarContent({ editor }) {
18
+ const supportsThread = "addPendingComment" in editor.commands;
19
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
20
+ children: [
21
+ /* @__PURE__ */ jsxRuntime.jsx(Toolbar.Toolbar.BlockSelector, {}),
22
+ /* @__PURE__ */ jsxRuntime.jsx(Toolbar.Toolbar.SectionInline, {}),
23
+ supportsThread ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
24
+ children: [
25
+ /* @__PURE__ */ jsxRuntime.jsx(Toolbar.Toolbar.Separator, {}),
26
+ /* @__PURE__ */ jsxRuntime.jsx(Toolbar.Toolbar.SectionCollaboration, {})
27
+ ]
28
+ }) : null
29
+ ]
30
+ });
31
+ }
32
+ const FloatingToolbar = react.forwardRef(
33
+ ({
34
+ children = DefaultFloatingToolbarContent,
35
+ before,
36
+ after,
37
+ position = "top",
38
+ offset: sideOffset = 6,
39
+ editor,
40
+ onPointerDown,
41
+ onFocus,
42
+ onBlur,
43
+ className,
44
+ ...props
45
+ }, forwardedRef) => {
46
+ const toolbarRef = react.useRef(null);
47
+ const [isPointerDown, setPointerDown] = react.useState(false);
48
+ const [isFocused, setFocused] = react.useState(false);
49
+ const [isManuallyClosed, setManuallyClosed] = react.useState(false);
50
+ const isEditable = react$1.useEditorState({
51
+ editor,
52
+ equalityFn: Object.is,
53
+ selector: (ctx) => ctx.editor?.isEditable ?? false
54
+ }) ?? false;
55
+ const hasSelectionRange = react$1.useEditorState({
56
+ editor,
57
+ equalityFn: Object.is,
58
+ selector: (ctx) => {
59
+ const editor2 = ctx.editor;
60
+ if (!editor2) {
61
+ return false;
62
+ }
63
+ const { doc, selection } = editor2.state;
64
+ const { empty, ranges } = selection;
65
+ const from = Math.min(...ranges.map((range) => range.$from.pos));
66
+ const to = Math.max(...ranges.map((range) => range.$to.pos));
67
+ if (empty) {
68
+ return false;
69
+ }
70
+ return react$1.isTextSelection(selection) && doc.textBetween(from, to).length > 0;
71
+ }
72
+ }) ?? false;
73
+ const isOpen = isFocused && !isPointerDown && hasSelectionRange && !isManuallyClosed;
74
+ const [delayedIsOpen, setDelayedIsOpen] = react.useState(isOpen);
75
+ const delayedIsOpenTimeoutRef = react.useRef();
76
+ react.useEffect(() => {
77
+ if (!editor) {
78
+ return;
79
+ }
80
+ setManuallyClosed(false);
81
+ const handleSelectionChange = () => {
82
+ setManuallyClosed(false);
83
+ };
84
+ editor.on("selectionUpdate", handleSelectionChange);
85
+ return () => {
86
+ editor.off("selectionUpdate", handleSelectionChange);
87
+ };
88
+ }, [isFocused, hasSelectionRange, editor]);
89
+ react.useEffect(() => {
90
+ if (!editor) {
91
+ return;
92
+ }
93
+ const handleFocus2 = () => {
94
+ setFocused(true);
95
+ };
96
+ const handleBlur2 = (event) => {
97
+ if (event.relatedTarget && toolbarRef.current?.contains(event.relatedTarget)) {
98
+ return;
99
+ }
100
+ if (event.relatedTarget === editor.view.dom) {
101
+ return;
102
+ }
103
+ setFocused(false);
104
+ };
105
+ editor.view.dom.addEventListener("focus", handleFocus2);
106
+ editor.view.dom.addEventListener("blur", handleBlur2);
107
+ return () => {
108
+ editor.view.dom.removeEventListener("focus", handleFocus2);
109
+ editor.view.dom.removeEventListener("blur", handleBlur2);
110
+ };
111
+ }, [editor]);
112
+ const handleFocus = react.useCallback(
113
+ (event) => {
114
+ onFocus?.(event);
115
+ if (!event.isDefaultPrevented()) {
116
+ setFocused(true);
117
+ }
118
+ },
119
+ [onFocus]
120
+ );
121
+ const handleBlur = react.useCallback(
122
+ (event) => {
123
+ onBlur?.(event);
124
+ if (!event.isDefaultPrevented()) {
125
+ if (event.relatedTarget && toolbarRef.current?.contains(event.relatedTarget)) {
126
+ return;
127
+ }
128
+ if (event.relatedTarget === editor?.view.dom) {
129
+ return;
130
+ }
131
+ setFocused(false);
132
+ }
133
+ },
134
+ [onBlur, editor]
135
+ );
136
+ react.useEffect(() => {
137
+ if (isOpen) {
138
+ delayedIsOpenTimeoutRef.current = window.setTimeout(() => {
139
+ setDelayedIsOpen(true);
140
+ }, FLOATING_TOOLBAR_OPEN_DELAY);
141
+ } else {
142
+ setDelayedIsOpen(false);
143
+ }
144
+ return () => {
145
+ window.clearTimeout(delayedIsOpenTimeoutRef.current);
146
+ };
147
+ }, [isOpen]);
148
+ const floatingOptions = react.useMemo(() => {
149
+ const detectOverflowOptions = {
150
+ padding: FLOATING_TOOLBAR_COLLISION_PADDING
151
+ };
152
+ return {
153
+ strategy: "fixed",
154
+ placement: position,
155
+ middleware: [
156
+ reactDom.inline(detectOverflowOptions),
157
+ reactDom.flip({ ...detectOverflowOptions, crossAxis: false }),
158
+ reactDom.hide(detectOverflowOptions),
159
+ reactDom.shift({
160
+ ...detectOverflowOptions,
161
+ limiter: reactDom.limitShift()
162
+ }),
163
+ reactDom.offset(sideOffset),
164
+ reactDom.size(detectOverflowOptions)
165
+ ],
166
+ whileElementsMounted: (...args) => {
167
+ return reactDom.autoUpdate(...args, {
168
+ animationFrame: true
169
+ });
170
+ }
171
+ };
172
+ }, [position, sideOffset]);
173
+ const {
174
+ refs: { setReference, setFloating },
175
+ strategy,
176
+ x,
177
+ y,
178
+ isPositioned
179
+ } = reactDom.useFloating({
180
+ ...floatingOptions,
181
+ open: delayedIsOpen
182
+ });
183
+ const mergedRefs = _private.useRefs(forwardedRef, toolbarRef, setFloating);
184
+ const handlePointerDown = react.useCallback(
185
+ (event) => {
186
+ onPointerDown?.(event);
187
+ event.stopPropagation();
188
+ if (event.target === toolbarRef.current) {
189
+ event.preventDefault();
190
+ }
191
+ },
192
+ [onPointerDown]
193
+ );
194
+ react.useEffect(() => {
195
+ if (!editor || !isEditable) {
196
+ return;
197
+ }
198
+ const handlePointerDown2 = () => {
199
+ setPointerDown(true);
200
+ };
201
+ const handlePointerUp = () => {
202
+ setPointerDown(false);
203
+ };
204
+ document.addEventListener("pointerdown", handlePointerDown2);
205
+ document.addEventListener("pointercancel", handlePointerUp);
206
+ document.addEventListener("pointerup", handlePointerUp);
207
+ return () => {
208
+ document.removeEventListener("pointerdown", handlePointerDown2);
209
+ document.removeEventListener("pointercancel", handlePointerUp);
210
+ document.removeEventListener("pointerup", handlePointerUp);
211
+ };
212
+ }, [editor, isEditable]);
213
+ _private$1.useLayoutEffect(() => {
214
+ if (!editor || !delayedIsOpen) {
215
+ return;
216
+ }
217
+ const updateSelectionReference = () => {
218
+ const domSelection = window.getSelection();
219
+ if (editor.state.selection.empty || !domSelection || !domSelection.rangeCount) {
220
+ setReference(null);
221
+ } else {
222
+ const domRange = domSelection.getRangeAt(0);
223
+ setReference(domRange);
224
+ }
225
+ };
226
+ editor.on("transaction", updateSelectionReference);
227
+ updateSelectionReference();
228
+ return () => {
229
+ editor.off("transaction", updateSelectionReference);
230
+ };
231
+ }, [editor, delayedIsOpen, setReference]);
232
+ react.useEffect(() => {
233
+ if (!editor || !delayedIsOpen) {
234
+ return;
235
+ }
236
+ const handleKeyDown = (event) => {
237
+ if (event.target !== editor.view.dom && event.defaultPrevented) {
238
+ return;
239
+ }
240
+ if (event.key === "Escape") {
241
+ event.preventDefault();
242
+ event.stopPropagation();
243
+ editor.commands.focus();
244
+ setManuallyClosed(true);
245
+ }
246
+ };
247
+ editor.view.dom.addEventListener("keydown", handleKeyDown);
248
+ return () => {
249
+ editor.view.dom.removeEventListener("keydown", handleKeyDown);
250
+ };
251
+ }, [editor, delayedIsOpen]);
252
+ const close = react.useCallback(() => {
253
+ setManuallyClosed(true);
254
+ }, [setManuallyClosed]);
255
+ if (!editor || !delayedIsOpen) {
256
+ return null;
257
+ }
258
+ const slotProps = { editor };
259
+ return reactDom$1.createPortal(
260
+ /* @__PURE__ */ jsxRuntime.jsx(_private.TooltipProvider, {
261
+ children: /* @__PURE__ */ jsxRuntime.jsx(context.EditorProvider, {
262
+ editor,
263
+ children: /* @__PURE__ */ jsxRuntime.jsx(FloatingToolbarContext.FloatingToolbarContext.Provider, {
264
+ value: { close },
265
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", {
266
+ role: "toolbar",
267
+ "aria-label": "Floating toolbar",
268
+ "aria-orientation": "horizontal",
269
+ className: classnames.classNames(
270
+ "lb-root lb-portal lb-elevation lb-tiptap-floating-toolbar lb-tiptap-toolbar",
271
+ className
272
+ ),
273
+ ref: mergedRefs,
274
+ style: {
275
+ position: strategy,
276
+ top: 0,
277
+ left: 0,
278
+ transform: isPositioned ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)` : "translate3d(0, -200%, 0)",
279
+ minWidth: "max-content"
280
+ },
281
+ onPointerDown: handlePointerDown,
282
+ onFocus: handleFocus,
283
+ onBlur: handleBlur,
284
+ ...props,
285
+ children: [
286
+ Toolbar.applyToolbarSlot(before, slotProps),
287
+ Toolbar.applyToolbarSlot(children, slotProps),
288
+ Toolbar.applyToolbarSlot(after, slotProps)
289
+ ]
290
+ })
291
+ })
292
+ })
293
+ }),
294
+ document.body
295
+ );
296
+ }
297
+ );
298
+
299
+ exports.FLOATING_TOOLBAR_COLLISION_PADDING = FLOATING_TOOLBAR_COLLISION_PADDING;
300
+ exports.FloatingToolbar = FloatingToolbar;
301
+ //# sourceMappingURL=FloatingToolbar.js.map