@liveblocks/react-tiptap 0.0.1 → 2.8.3-tiptap1

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 (69) hide show
  1. package/dist/LiveblocksExtension.js +144 -0
  2. package/dist/LiveblocksExtension.js.map +1 -0
  3. package/dist/LiveblocksExtension.mjs +142 -0
  4. package/dist/LiveblocksExtension.mjs.map +1 -0
  5. package/dist/classnames.js +8 -0
  6. package/dist/classnames.js.map +1 -0
  7. package/dist/classnames.mjs +6 -0
  8. package/dist/classnames.mjs.map +1 -0
  9. package/dist/comments/AnchoredThreads.js +178 -0
  10. package/dist/comments/AnchoredThreads.js.map +1 -0
  11. package/dist/comments/AnchoredThreads.mjs +176 -0
  12. package/dist/comments/AnchoredThreads.mjs.map +1 -0
  13. package/dist/comments/CommentsExtension.js +207 -0
  14. package/dist/comments/CommentsExtension.js.map +1 -0
  15. package/dist/comments/CommentsExtension.mjs +205 -0
  16. package/dist/comments/CommentsExtension.mjs.map +1 -0
  17. package/dist/comments/FloatingComposer.js +103 -0
  18. package/dist/comments/FloatingComposer.js.map +1 -0
  19. package/dist/comments/FloatingComposer.mjs +100 -0
  20. package/dist/comments/FloatingComposer.mjs.map +1 -0
  21. package/dist/comments/FloatingThreads.js +154 -0
  22. package/dist/comments/FloatingThreads.js.map +1 -0
  23. package/dist/comments/FloatingThreads.mjs +151 -0
  24. package/dist/comments/FloatingThreads.mjs.map +1 -0
  25. package/dist/index.d.mts +65 -0
  26. package/dist/index.d.ts +65 -0
  27. package/dist/index.js +18 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/index.mjs +10 -0
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/mentions/Avatar.js +53 -0
  32. package/dist/mentions/Avatar.js.map +1 -0
  33. package/dist/mentions/Avatar.mjs +51 -0
  34. package/dist/mentions/Avatar.mjs.map +1 -0
  35. package/dist/mentions/Mention.js +24 -0
  36. package/dist/mentions/Mention.js.map +1 -0
  37. package/dist/mentions/Mention.mjs +22 -0
  38. package/dist/mentions/Mention.mjs.map +1 -0
  39. package/dist/mentions/MentionExtension.js +221 -0
  40. package/dist/mentions/MentionExtension.js.map +1 -0
  41. package/dist/mentions/MentionExtension.mjs +219 -0
  42. package/dist/mentions/MentionExtension.mjs.map +1 -0
  43. package/dist/mentions/MentionsList.js +123 -0
  44. package/dist/mentions/MentionsList.js.map +1 -0
  45. package/dist/mentions/MentionsList.mjs +119 -0
  46. package/dist/mentions/MentionsList.mjs.map +1 -0
  47. package/dist/types.js +33 -0
  48. package/dist/types.js.map +1 -0
  49. package/dist/types.mjs +24 -0
  50. package/dist/types.mjs.map +1 -0
  51. package/dist/utils.js +47 -0
  52. package/dist/utils.js.map +1 -0
  53. package/dist/utils.mjs +43 -0
  54. package/dist/utils.mjs.map +1 -0
  55. package/dist/version-history/HistoryVersionPreview.js +79 -0
  56. package/dist/version-history/HistoryVersionPreview.js.map +1 -0
  57. package/dist/version-history/HistoryVersionPreview.mjs +77 -0
  58. package/dist/version-history/HistoryVersionPreview.mjs.map +1 -0
  59. package/dist/version.js +10 -0
  60. package/dist/version.js.map +1 -0
  61. package/dist/version.mjs +6 -0
  62. package/dist/version.mjs.map +1 -0
  63. package/package.json +77 -1
  64. package/src/styles/constants.css +9 -0
  65. package/src/styles/index.css +247 -0
  66. package/src/styles/utils.css +6 -0
  67. package/styles.css +1 -0
  68. package/styles.css.d.ts +1 -0
  69. package/styles.css.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["import type { ClientRectObject } from \"@floating-ui/react-dom\";\nimport type { Range } from \"@tiptap/core\";\nimport type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport { Fragment } from \"@tiptap/pm/model\";\n\nimport { LIVEBLOCKS_MENTION_TYPE } from \"./types\";\n\nexport const getRectFromCoords = (coords: {\n top: number;\n left: number;\n right: number;\n bottom: number;\n}): ClientRectObject => {\n return {\n ...coords,\n x: coords.left,\n y: coords.top,\n width: coords.right - coords.left,\n height: coords.bottom - coords.top,\n };\n};\n\nexport const getMentionsFromNode = (\n node: ProseMirrorNode,\n range: Range\n): { notificationId: string; userId: string }[] => {\n const result: { notificationId: string; userId: string }[] = [];\n node.nodesBetween(range.from, range.to, (child) => {\n if (child.type.name === LIVEBLOCKS_MENTION_TYPE) {\n const mention = child.attrs as { id?: string; notificationId?: string };\n if (mention.id && mention.notificationId) {\n result.push({\n notificationId: mention.notificationId,\n userId: mention.id,\n });\n }\n }\n });\n return result;\n};\n\n// How to modify data in transformPasted, inspired by: https://discuss.prosemirror.net/t/modify-specific-node-on-copy-and-paste-in-clipboard/4901/4\nexport const mapFragment = (\n fragment: Fragment,\n callback: (\n node: ProseMirrorNode\n ) => ProseMirrorNode | ProseMirrorNode[] | Fragment | null\n): Fragment => {\n const content: ProseMirrorNode[] = [];\n fragment.forEach((node) => {\n if (node.content.childCount > 0) {\n content.push(\n node.type.create(node.attrs, mapFragment(node.content, callback))\n );\n return;\n }\n content.push(callback(node) as ProseMirrorNode);\n });\n\n return Fragment.from(content);\n};\n"],"names":["LIVEBLOCKS_MENTION_TYPE","Fragment"],"mappings":";;;;;AAOa,MAAA,iBAAA,GAAoB,CAAC,MAKV,KAAA;AACtB,EAAO,OAAA;AAAA,IACL,GAAG,MAAA;AAAA,IACH,GAAG,MAAO,CAAA,IAAA;AAAA,IACV,GAAG,MAAO,CAAA,GAAA;AAAA,IACV,KAAA,EAAO,MAAO,CAAA,KAAA,GAAQ,MAAO,CAAA,IAAA;AAAA,IAC7B,MAAA,EAAQ,MAAO,CAAA,MAAA,GAAS,MAAO,CAAA,GAAA;AAAA,GACjC,CAAA;AACF,EAAA;AAEa,MAAA,mBAAA,GAAsB,CACjC,IAAA,EACA,KACiD,KAAA;AACjD,EAAA,MAAM,SAAuD,EAAC,CAAA;AAC9D,EAAA,IAAA,CAAK,aAAa,KAAM,CAAA,IAAA,EAAM,KAAM,CAAA,EAAA,EAAI,CAAC,KAAU,KAAA;AACjD,IAAI,IAAA,KAAA,CAAM,IAAK,CAAA,IAAA,KAASA,6BAAyB,EAAA;AAC/C,MAAA,MAAM,UAAU,KAAM,CAAA,KAAA,CAAA;AACtB,MAAI,IAAA,OAAA,CAAQ,EAAM,IAAA,OAAA,CAAQ,cAAgB,EAAA;AACxC,QAAA,MAAA,CAAO,IAAK,CAAA;AAAA,UACV,gBAAgB,OAAQ,CAAA,cAAA;AAAA,UACxB,QAAQ,OAAQ,CAAA,EAAA;AAAA,SACjB,CAAA,CAAA;AAAA,OACH;AAAA,KACF;AAAA,GACD,CAAA,CAAA;AACD,EAAO,OAAA,MAAA,CAAA;AACT,EAAA;AAGa,MAAA,WAAA,GAAc,CACzB,QAAA,EACA,QAGa,KAAA;AACb,EAAA,MAAM,UAA6B,EAAC,CAAA;AACpC,EAAS,QAAA,CAAA,OAAA,CAAQ,CAAC,IAAS,KAAA;AACzB,IAAI,IAAA,IAAA,CAAK,OAAQ,CAAA,UAAA,GAAa,CAAG,EAAA;AAC/B,MAAQ,OAAA,CAAA,IAAA;AAAA,QACN,IAAA,CAAK,KAAK,MAAO,CAAA,IAAA,CAAK,OAAO,WAAY,CAAA,IAAA,CAAK,OAAS,EAAA,QAAQ,CAAC,CAAA;AAAA,OAClE,CAAA;AACA,MAAA,OAAA;AAAA,KACF;AACA,IAAQ,OAAA,CAAA,IAAA,CAAK,QAAS,CAAA,IAAI,CAAoB,CAAA,CAAA;AAAA,GAC/C,CAAA,CAAA;AAED,EAAO,OAAAC,cAAA,CAAS,KAAK,OAAO,CAAA,CAAA;AAC9B;;;;;;"}
package/dist/utils.mjs ADDED
@@ -0,0 +1,43 @@
1
+ import { Fragment } from '@tiptap/pm/model';
2
+ import { LIVEBLOCKS_MENTION_TYPE } from './types.mjs';
3
+
4
+ const getRectFromCoords = (coords) => {
5
+ return {
6
+ ...coords,
7
+ x: coords.left,
8
+ y: coords.top,
9
+ width: coords.right - coords.left,
10
+ height: coords.bottom - coords.top
11
+ };
12
+ };
13
+ const getMentionsFromNode = (node, range) => {
14
+ const result = [];
15
+ node.nodesBetween(range.from, range.to, (child) => {
16
+ if (child.type.name === LIVEBLOCKS_MENTION_TYPE) {
17
+ const mention = child.attrs;
18
+ if (mention.id && mention.notificationId) {
19
+ result.push({
20
+ notificationId: mention.notificationId,
21
+ userId: mention.id
22
+ });
23
+ }
24
+ }
25
+ });
26
+ return result;
27
+ };
28
+ const mapFragment = (fragment, callback) => {
29
+ const content = [];
30
+ fragment.forEach((node) => {
31
+ if (node.content.childCount > 0) {
32
+ content.push(
33
+ node.type.create(node.attrs, mapFragment(node.content, callback))
34
+ );
35
+ return;
36
+ }
37
+ content.push(callback(node));
38
+ });
39
+ return Fragment.from(content);
40
+ };
41
+
42
+ export { getMentionsFromNode, getRectFromCoords, mapFragment };
43
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","sources":["../src/utils.ts"],"sourcesContent":["import type { ClientRectObject } from \"@floating-ui/react-dom\";\nimport type { Range } from \"@tiptap/core\";\nimport type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport { Fragment } from \"@tiptap/pm/model\";\n\nimport { LIVEBLOCKS_MENTION_TYPE } from \"./types\";\n\nexport const getRectFromCoords = (coords: {\n top: number;\n left: number;\n right: number;\n bottom: number;\n}): ClientRectObject => {\n return {\n ...coords,\n x: coords.left,\n y: coords.top,\n width: coords.right - coords.left,\n height: coords.bottom - coords.top,\n };\n};\n\nexport const getMentionsFromNode = (\n node: ProseMirrorNode,\n range: Range\n): { notificationId: string; userId: string }[] => {\n const result: { notificationId: string; userId: string }[] = [];\n node.nodesBetween(range.from, range.to, (child) => {\n if (child.type.name === LIVEBLOCKS_MENTION_TYPE) {\n const mention = child.attrs as { id?: string; notificationId?: string };\n if (mention.id && mention.notificationId) {\n result.push({\n notificationId: mention.notificationId,\n userId: mention.id,\n });\n }\n }\n });\n return result;\n};\n\n// How to modify data in transformPasted, inspired by: https://discuss.prosemirror.net/t/modify-specific-node-on-copy-and-paste-in-clipboard/4901/4\nexport const mapFragment = (\n fragment: Fragment,\n callback: (\n node: ProseMirrorNode\n ) => ProseMirrorNode | ProseMirrorNode[] | Fragment | null\n): Fragment => {\n const content: ProseMirrorNode[] = [];\n fragment.forEach((node) => {\n if (node.content.childCount > 0) {\n content.push(\n node.type.create(node.attrs, mapFragment(node.content, callback))\n );\n return;\n }\n content.push(callback(node) as ProseMirrorNode);\n });\n\n return Fragment.from(content);\n};\n"],"names":[],"mappings":";;;AAOa,MAAA,iBAAA,GAAoB,CAAC,MAKV,KAAA;AACtB,EAAO,OAAA;AAAA,IACL,GAAG,MAAA;AAAA,IACH,GAAG,MAAO,CAAA,IAAA;AAAA,IACV,GAAG,MAAO,CAAA,GAAA;AAAA,IACV,KAAA,EAAO,MAAO,CAAA,KAAA,GAAQ,MAAO,CAAA,IAAA;AAAA,IAC7B,MAAA,EAAQ,MAAO,CAAA,MAAA,GAAS,MAAO,CAAA,GAAA;AAAA,GACjC,CAAA;AACF,EAAA;AAEa,MAAA,mBAAA,GAAsB,CACjC,IAAA,EACA,KACiD,KAAA;AACjD,EAAA,MAAM,SAAuD,EAAC,CAAA;AAC9D,EAAA,IAAA,CAAK,aAAa,KAAM,CAAA,IAAA,EAAM,KAAM,CAAA,EAAA,EAAI,CAAC,KAAU,KAAA;AACjD,IAAI,IAAA,KAAA,CAAM,IAAK,CAAA,IAAA,KAAS,uBAAyB,EAAA;AAC/C,MAAA,MAAM,UAAU,KAAM,CAAA,KAAA,CAAA;AACtB,MAAI,IAAA,OAAA,CAAQ,EAAM,IAAA,OAAA,CAAQ,cAAgB,EAAA;AACxC,QAAA,MAAA,CAAO,IAAK,CAAA;AAAA,UACV,gBAAgB,OAAQ,CAAA,cAAA;AAAA,UACxB,QAAQ,OAAQ,CAAA,EAAA;AAAA,SACjB,CAAA,CAAA;AAAA,OACH;AAAA,KACF;AAAA,GACD,CAAA,CAAA;AACD,EAAO,OAAA,MAAA,CAAA;AACT,EAAA;AAGa,MAAA,WAAA,GAAc,CACzB,QAAA,EACA,QAGa,KAAA;AACb,EAAA,MAAM,UAA6B,EAAC,CAAA;AACpC,EAAS,QAAA,CAAA,OAAA,CAAQ,CAAC,IAAS,KAAA;AACzB,IAAI,IAAA,IAAA,CAAK,OAAQ,CAAA,UAAA,GAAa,CAAG,EAAA;AAC/B,MAAQ,OAAA,CAAA,IAAA;AAAA,QACN,IAAA,CAAK,KAAK,MAAO,CAAA,IAAA,CAAK,OAAO,WAAY,CAAA,IAAA,CAAK,OAAS,EAAA,QAAQ,CAAC,CAAA;AAAA,OAClE,CAAA;AACA,MAAA,OAAA;AAAA,KACF;AACA,IAAQ,OAAA,CAAA,IAAA,CAAK,QAAS,CAAA,IAAI,CAAoB,CAAA,CAAA;AAAA,GAC/C,CAAA,CAAA;AAED,EAAO,OAAA,QAAA,CAAS,KAAK,OAAO,CAAA,CAAA;AAC9B;;;;"}
@@ -0,0 +1,79 @@
1
+ 'use strict';
2
+
3
+ var react = require('@liveblocks/react');
4
+ var reactUi = require('@liveblocks/react-ui');
5
+ var _private = require('@liveblocks/react-ui/_private');
6
+ var react$1 = require('@tiptap/react');
7
+ var React = require('react');
8
+ var yProsemirror = require('y-prosemirror');
9
+ var yjs = require('yjs');
10
+ var classnames = require('../classnames.js');
11
+
12
+ const AUTHORS_TRUNCATE = 3;
13
+ const HistoryVersionPreview = React.forwardRef(({ version, editor: parentEditor, onVersionRestore, className, ...props }, forwardedRef) => {
14
+ const $ = reactUi.useOverrides();
15
+ const { isLoading, data, error } = react.useHistoryVersionData(version.id);
16
+ const previewEditor = react$1.useEditor({
17
+ editable: false,
18
+ extensions: parentEditor.extensionManager.extensions.filter((e) => e.type !== "extension")
19
+ });
20
+ React.useEffect(() => {
21
+ if (data && previewEditor) {
22
+ const doc = new yjs.Doc();
23
+ yjs.applyUpdate(doc, data);
24
+ const root = doc.getXmlFragment("default");
25
+ const node = yProsemirror.yXmlFragmentToProseMirrorRootNode(root, parentEditor.schema);
26
+ previewEditor.commands.setContent(node.toJSON());
27
+ }
28
+ }, [data, previewEditor, parentEditor]);
29
+ const restore = React.useCallback(() => {
30
+ parentEditor.commands.setContent(previewEditor?.getJSON() ?? "");
31
+ onVersionRestore?.(version);
32
+ }, [onVersionRestore, parentEditor, previewEditor, version]);
33
+ return /* @__PURE__ */ React.createElement("div", {
34
+ ...props,
35
+ className: classnames.classNames(
36
+ "lb-root lb-history-version-preview lb-tiptap-version-preview",
37
+ className
38
+ ),
39
+ ref: forwardedRef
40
+ }, isLoading ? /* @__PURE__ */ React.createElement("div", {
41
+ className: "lb-loading lb-history-version-preview-loading"
42
+ }, /* @__PURE__ */ React.createElement(_private.SpinnerIcon, null)) : error ? /* @__PURE__ */ React.createElement("div", {
43
+ className: "lb-error lb-history-version-preview-error"
44
+ }, $.HISTORY_VERSION_PREVIEW_ERROR(error)) : /* @__PURE__ */ React.createElement("div", {
45
+ className: "lb-history-version-preview-content lb-tiptap-editor-container lb-tiptap-version-preview-editor-container"
46
+ }, /* @__PURE__ */ React.createElement(react$1.EditorContent, {
47
+ editor: previewEditor
48
+ })), /* @__PURE__ */ React.createElement("div", {
49
+ className: "lb-history-version-preview-footer"
50
+ }, /* @__PURE__ */ React.createElement("span", {
51
+ className: "lb-history-version-preview-authors"
52
+ }, $.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(
53
+ /* @__PURE__ */ React.createElement(_private.List, {
54
+ values: version.authors.map((author) => /* @__PURE__ */ React.createElement(_private.User, {
55
+ key: author.id,
56
+ userId: author.id,
57
+ replaceSelf: true
58
+ })),
59
+ formatRemaining: $.LIST_REMAINING_USERS,
60
+ truncate: AUTHORS_TRUNCATE,
61
+ locale: $.locale
62
+ })
63
+ )), /* @__PURE__ */ React.createElement("div", {
64
+ className: "lb-history-version-preview-actions"
65
+ }, /* @__PURE__ */ React.createElement(_private.Button, {
66
+ onClick: restore,
67
+ disabled: !data,
68
+ variant: "primary",
69
+ size: "large",
70
+ className: "lb-history-version-preview-action"
71
+ }, /* @__PURE__ */ React.createElement(_private.RestoreIcon, {
72
+ className: "lb-button-icon"
73
+ }), /* @__PURE__ */ React.createElement("span", {
74
+ className: "lb-button-label"
75
+ }, $.HISTORY_VERSION_PREVIEW_RESTORE)))));
76
+ });
77
+
78
+ exports.HistoryVersionPreview = HistoryVersionPreview;
79
+ //# sourceMappingURL=HistoryVersionPreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistoryVersionPreview.js","sources":["../../src/version-history/HistoryVersionPreview.tsx"],"sourcesContent":["import type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { Content, Editor } from \"@tiptap/react\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n} from \"react\";\nimport { yXmlFragmentToProseMirrorRootNode } from \"y-prosemirror\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n editor: Editor;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\n/**\n * Displays a specific version of the current TipTap document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, editor: parentEditor, onVersionRestore, className, ...props }, forwardedRef) => {\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const previewEditor = useEditor({\n // ignore extensions, only get marks/nodes\n editable: false,\n extensions: parentEditor.extensionManager.extensions.filter((e) => e.type !== \"extension\"),\n });\n useEffect(() => {\n if (data && previewEditor) {\n const doc = new Doc();\n applyUpdate(doc, data);\n const root = doc.getXmlFragment(\"default\") // TODO: lookup field\n const node = yXmlFragmentToProseMirrorRootNode(root, parentEditor.schema);\n previewEditor.commands.setContent(node.toJSON() as Content)\n }\n }, [data, previewEditor, parentEditor]);\n const restore = useCallback(() => {\n parentEditor.commands.setContent(previewEditor?.getJSON() ?? \"\");\n onVersionRestore?.(version);\n }, [onVersionRestore, parentEditor, previewEditor, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-tiptap-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-tiptap-editor-container lb-tiptap-version-preview-editor-container\">\n\n <EditorContent editor={previewEditor} />\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n >\n <RestoreIcon className=\"lb-button-icon\" />\n <span className=\"lb-button-label\">\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </span>\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["forwardRef","useOverrides","useHistoryVersionData","useEditor","useEffect","Doc","applyUpdate","yXmlFragmentToProseMirrorRootNode","useCallback","classNames","SpinnerIcon","EditorContent","List","User","Button","RestoreIcon"],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { useHistoryVersionData } from '@liveblocks/react';
2
+ import { useOverrides } from '@liveblocks/react-ui';
3
+ import { SpinnerIcon, List, User, Button, RestoreIcon } from '@liveblocks/react-ui/_private';
4
+ import { useEditor, EditorContent } from '@tiptap/react';
5
+ import React, { forwardRef, useEffect, useCallback } from 'react';
6
+ import { yXmlFragmentToProseMirrorRootNode } from 'y-prosemirror';
7
+ import { Doc, applyUpdate } from 'yjs';
8
+ import { classNames } from '../classnames.mjs';
9
+
10
+ const AUTHORS_TRUNCATE = 3;
11
+ const HistoryVersionPreview = forwardRef(({ version, editor: parentEditor, onVersionRestore, className, ...props }, forwardedRef) => {
12
+ const $ = useOverrides();
13
+ const { isLoading, data, error } = useHistoryVersionData(version.id);
14
+ const previewEditor = useEditor({
15
+ editable: false,
16
+ extensions: parentEditor.extensionManager.extensions.filter((e) => e.type !== "extension")
17
+ });
18
+ useEffect(() => {
19
+ if (data && previewEditor) {
20
+ const doc = new Doc();
21
+ applyUpdate(doc, data);
22
+ const root = doc.getXmlFragment("default");
23
+ const node = yXmlFragmentToProseMirrorRootNode(root, parentEditor.schema);
24
+ previewEditor.commands.setContent(node.toJSON());
25
+ }
26
+ }, [data, previewEditor, parentEditor]);
27
+ const restore = useCallback(() => {
28
+ parentEditor.commands.setContent(previewEditor?.getJSON() ?? "");
29
+ onVersionRestore?.(version);
30
+ }, [onVersionRestore, parentEditor, previewEditor, version]);
31
+ return /* @__PURE__ */ React.createElement("div", {
32
+ ...props,
33
+ className: classNames(
34
+ "lb-root lb-history-version-preview lb-tiptap-version-preview",
35
+ className
36
+ ),
37
+ ref: forwardedRef
38
+ }, isLoading ? /* @__PURE__ */ React.createElement("div", {
39
+ className: "lb-loading lb-history-version-preview-loading"
40
+ }, /* @__PURE__ */ React.createElement(SpinnerIcon, null)) : error ? /* @__PURE__ */ React.createElement("div", {
41
+ className: "lb-error lb-history-version-preview-error"
42
+ }, $.HISTORY_VERSION_PREVIEW_ERROR(error)) : /* @__PURE__ */ React.createElement("div", {
43
+ className: "lb-history-version-preview-content lb-tiptap-editor-container lb-tiptap-version-preview-editor-container"
44
+ }, /* @__PURE__ */ React.createElement(EditorContent, {
45
+ editor: previewEditor
46
+ })), /* @__PURE__ */ React.createElement("div", {
47
+ className: "lb-history-version-preview-footer"
48
+ }, /* @__PURE__ */ React.createElement("span", {
49
+ className: "lb-history-version-preview-authors"
50
+ }, $.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(
51
+ /* @__PURE__ */ React.createElement(List, {
52
+ values: version.authors.map((author) => /* @__PURE__ */ React.createElement(User, {
53
+ key: author.id,
54
+ userId: author.id,
55
+ replaceSelf: true
56
+ })),
57
+ formatRemaining: $.LIST_REMAINING_USERS,
58
+ truncate: AUTHORS_TRUNCATE,
59
+ locale: $.locale
60
+ })
61
+ )), /* @__PURE__ */ React.createElement("div", {
62
+ className: "lb-history-version-preview-actions"
63
+ }, /* @__PURE__ */ React.createElement(Button, {
64
+ onClick: restore,
65
+ disabled: !data,
66
+ variant: "primary",
67
+ size: "large",
68
+ className: "lb-history-version-preview-action"
69
+ }, /* @__PURE__ */ React.createElement(RestoreIcon, {
70
+ className: "lb-button-icon"
71
+ }), /* @__PURE__ */ React.createElement("span", {
72
+ className: "lb-button-label"
73
+ }, $.HISTORY_VERSION_PREVIEW_RESTORE)))));
74
+ });
75
+
76
+ export { HistoryVersionPreview };
77
+ //# sourceMappingURL=HistoryVersionPreview.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistoryVersionPreview.mjs","sources":["../../src/version-history/HistoryVersionPreview.tsx"],"sourcesContent":["import type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { Content, Editor } from \"@tiptap/react\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n} from \"react\";\nimport { yXmlFragmentToProseMirrorRootNode } from \"y-prosemirror\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n editor: Editor;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\n/**\n * Displays a specific version of the current TipTap document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, editor: parentEditor, onVersionRestore, className, ...props }, forwardedRef) => {\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const previewEditor = useEditor({\n // ignore extensions, only get marks/nodes\n editable: false,\n extensions: parentEditor.extensionManager.extensions.filter((e) => e.type !== \"extension\"),\n });\n useEffect(() => {\n if (data && previewEditor) {\n const doc = new Doc();\n applyUpdate(doc, data);\n const root = doc.getXmlFragment(\"default\") // TODO: lookup field\n const node = yXmlFragmentToProseMirrorRootNode(root, parentEditor.schema);\n previewEditor.commands.setContent(node.toJSON() as Content)\n }\n }, [data, previewEditor, parentEditor]);\n const restore = useCallback(() => {\n parentEditor.commands.setContent(previewEditor?.getJSON() ?? \"\");\n onVersionRestore?.(version);\n }, [onVersionRestore, parentEditor, previewEditor, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-tiptap-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-tiptap-editor-container lb-tiptap-version-preview-editor-container\">\n\n <EditorContent editor={previewEditor} />\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n >\n <RestoreIcon className=\"lb-button-icon\" />\n <span className=\"lb-button-label\">\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </span>\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ const PKG_NAME = "@liveblocks/react-tiptap";
4
+ const PKG_VERSION = typeof "2.8.3-tiptap1" === "string" && "2.8.3-tiptap1";
5
+ const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
6
+
7
+ exports.PKG_FORMAT = PKG_FORMAT;
8
+ exports.PKG_NAME = PKG_NAME;
9
+ exports.PKG_VERSION = PKG_VERSION;
10
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,eAAA,KAAgB,QAAY,IAAA,gBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"}
@@ -0,0 +1,6 @@
1
+ const PKG_NAME = "@liveblocks/react-tiptap";
2
+ const PKG_VERSION = typeof "2.8.3-tiptap1" === "string" && "2.8.3-tiptap1";
3
+ const PKG_FORMAT = typeof "esm" === "string" && "esm";
4
+
5
+ export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
6
+ //# sourceMappingURL=version.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.mjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,eAAA,KAAgB,QAAY,IAAA,gBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"}
package/package.json CHANGED
@@ -1,12 +1,88 @@
1
1
  {
2
2
  "name": "@liveblocks/react-tiptap",
3
- "version": "0.0.1",
3
+ "version": "2.8.3-tiptap1",
4
4
  "description": "A tiptap react plugin to enable collaboration, comments, live cursors, and more.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.mts",
13
+ "default": "./dist/index.mjs"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.ts",
17
+ "module": "./dist/index.mjs",
18
+ "default": "./dist/index.js"
19
+ }
20
+ },
21
+ "./styles.css": {
22
+ "types": "./styles.css.d.ts",
23
+ "default": "./styles.css"
24
+ }
25
+ },
7
26
  "files": [
27
+ "dist/**",
28
+ "**/*.css",
29
+ "**/*.css.d.ts",
30
+ "**/*.css.map",
8
31
  "README.md"
9
32
  ],
33
+ "scripts": {
34
+ "dev": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript --watch",
35
+ "build": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
36
+ "format": "eslint --fix src/; stylelint --fix src/styles/; prettier --write src/",
37
+ "lint": "eslint src/; stylelint src/styles/",
38
+ "lint:package": "publint --strict && attw --pack",
39
+ "start": "npm run dev",
40
+ "test": "jest --silent --verbose --color=always",
41
+ "test:watch": "jest --silent --verbose --color=always --watch"
42
+ },
43
+ "dependencies": {
44
+ "@floating-ui/react-dom": "^2.1.2",
45
+ "@liveblocks/client": "2.8.3-tiptap1",
46
+ "@liveblocks/core": "2.8.3-tiptap1",
47
+ "@liveblocks/react": "2.8.3-tiptap1",
48
+ "@liveblocks/react-ui": "2.8.3-tiptap1",
49
+ "@liveblocks/yjs": "2.8.3-tiptap1",
50
+ "@tiptap/core": "^2.7.2",
51
+ "@tiptap/react": "^2.7.2",
52
+ "@tiptap/suggestion": "^2.7.2",
53
+ "use-sync-external-store": "^1.2.2",
54
+ "y-prosemirror": "^1.2.12",
55
+ "yjs": "^13.6.18"
56
+ },
57
+ "peerDependencies": {
58
+ "@tiptap/extension-collaboration": "^2.7.2",
59
+ "@tiptap/extension-collaboration-cursor": "^2.7.2",
60
+ "@tiptap/pm": "^2.7.2",
61
+ "@tiptap/react": "^2.7.2",
62
+ "@tiptap/suggestion": "^2.7.2",
63
+ "react": "^16.14.0 || ^17 || ^18",
64
+ "react-dom": "^16.14.0 || ^17 || ^18"
65
+ },
66
+ "devDependencies": {
67
+ "@liveblocks/eslint-config": "*",
68
+ "@liveblocks/jest-config": "*",
69
+ "@rollup/plugin-node-resolve": "^15.2.3",
70
+ "@rollup/plugin-replace": "^5.0.5",
71
+ "@rollup/plugin-typescript": "^11.1.2",
72
+ "@testing-library/jest-dom": "^5.16.5",
73
+ "@types/use-sync-external-store": "^0.0.6",
74
+ "eslint-plugin-react": "^7.33.2",
75
+ "eslint-plugin-react-hooks": "^4.6.0",
76
+ "msw": "^0.27.1",
77
+ "rollup": "^3.28.0",
78
+ "rollup-plugin-dts": "^5.3.1",
79
+ "rollup-plugin-esbuild": "^5.0.0",
80
+ "rollup-plugin-preserve-directives": "^0.2.0",
81
+ "stylelint": "^15.10.2",
82
+ "stylelint-config-standard": "^34.0.0",
83
+ "stylelint-order": "^6.0.3",
84
+ "stylelint-plugin-logical-css": "^0.13.2"
85
+ },
10
86
  "sideEffects": false,
11
87
  "bugs": {
12
88
  "url": "https://github.com/liveblocks/liveblocks/issues"
@@ -0,0 +1,9 @@
1
+ $lb-elevation-list-padding: 4px;
2
+ $lb-tiptap-anchored-threads-shadow:
3
+ 0 0 0 1px rgb(0 0 0 / 4%),
4
+ 0 2px 6px rgb(0 0 0 / 4%),
5
+ 0 6px 20px rgb(0 0 0 / 6%);
6
+ $lb-tiptap-anchored-threads-active-shadow:
7
+ 0 0 0 1px rgb(0 0 0 / 4%),
8
+ 0 2px 6px rgb(0 0 0 / 8%),
9
+ 0 8px 26px rgb(0 0 0 / 12%);
@@ -0,0 +1,247 @@
1
+ @import "./utils";
2
+ @import "./constants";
3
+
4
+ /*************************************
5
+ * Suggestions *
6
+ *************************************/
7
+
8
+ .lb-tiptap-suggestions-list {
9
+ margin: 0;
10
+ padding: 0;
11
+ list-style: none;
12
+ }
13
+
14
+ /*************************************
15
+ * Mention suggestions *
16
+ *************************************/
17
+
18
+ .lb-tiptap-mention-suggestions {
19
+ --lb-tiptap-mention-suggestion-avatar-size: 1.25rem;
20
+ }
21
+
22
+ .lb-tiptap-mention-suggestion {
23
+ padding: calc(0.375 * var(--lb-spacing)) calc(0.625 * var(--lb-spacing));
24
+ }
25
+
26
+ .lb-tiptap-mention-suggestion-avatar {
27
+ inline-size: var(--lb-tiptap-mention-suggestion-avatar-size);
28
+ margin-inline-start: calc(-0.125 * var(--lb-spacing));
29
+ margin-inline-end: calc(0.5 * var(--lb-spacing));
30
+ margin-block: calc(0.125 * var(--lb-spacing));
31
+ background: var(--lb-foreground-subtle);
32
+ color: var(--lb-foreground-moderate);
33
+ }
34
+
35
+ /*************************************
36
+ * Elevation lists *
37
+ *************************************/
38
+
39
+ .lb-tiptap-suggestions {
40
+ padding: $lb-elevation-list-padding;
41
+ animation-duration: var(--lb-transition-duration);
42
+ animation-timing-function: var(--lb-transition-easing);
43
+ will-change: transform, opacity;
44
+ }
45
+
46
+ .lb-tiptap-suggestions-list-item {
47
+ display: flex;
48
+ align-items: center;
49
+ padding: calc(0.25 * var(--lb-spacing)) calc(0.5 * var(--lb-spacing));
50
+ border-radius: calc(var(--lb-radius) - 0.75 * $lb-elevation-list-padding);
51
+ color: var(--lb-foreground-secondary);
52
+ outline: none;
53
+ font-size: 0.875rem;
54
+ cursor: pointer;
55
+ user-select: none;
56
+ transition-property: background, color, opacity;
57
+ scroll-margin-block: $lb-elevation-list-padding;
58
+ }
59
+
60
+ :is(.lb-tiptap-suggestions-list-item) {
61
+ &:where([data-highlighted], [data-selected]) {
62
+ background: var(--lb-foreground-subtle);
63
+ transition-duration: calc(var(--lb-transition-duration) / 2);
64
+ }
65
+
66
+ &:where(:disabled, [data-disabled]) {
67
+ opacity: 0.5;
68
+ cursor: not-allowed;
69
+ }
70
+ }
71
+
72
+ /*************************************
73
+ * Floating animations *
74
+ *************************************/
75
+
76
+ :is(.lb-tiptap-suggestions) {
77
+ &:where([data-side="top"]) {
78
+ animation-name: lb-animation-slide-up;
79
+ }
80
+
81
+ &:where([data-side="bottom"]) {
82
+ animation-name: lb-animation-slide-down;
83
+ }
84
+
85
+ &:where([data-state="closed"]) {
86
+ animation-name: lb-animation-disappear;
87
+ }
88
+ }
89
+
90
+ @media (prefers-reduced-motion) {
91
+ .lb-tiptap-suggestions:where(:not([data-state="closed"])) {
92
+ animation-name: lb-animation-appear;
93
+ }
94
+ }
95
+
96
+ /*************************************
97
+ * Mention *
98
+ *************************************/
99
+
100
+ .lb-tiptap-mention {
101
+ padding: 0.1em 0.3em;
102
+ border-radius: calc(0.675 * var(--lb-radius));
103
+ background: var(--lb-accent-subtle);
104
+ color: var(--lb-accent);
105
+ box-decoration-break: clone;
106
+ font-weight: 500;
107
+
108
+ @include invisible-selection;
109
+ }
110
+
111
+ .lb-mention-selected {
112
+ background: var(--lb-accent);
113
+ color: var(--lb-accent-foreground);
114
+ }
115
+
116
+ /*************************************
117
+ * Thread mark *
118
+ *************************************/
119
+
120
+ .lb-tiptap-thread-mark {
121
+ background: var(--lb-accent-subtle);
122
+ color: var(--lb-foreground);
123
+ outline: none;
124
+ font-weight: 500;
125
+ transition-property: color, text-decoration-color;
126
+ text-decoration-line: underline;
127
+ text-decoration-color: var(--lb-foreground-moderate);
128
+ text-underline-offset: 2px;
129
+ }
130
+
131
+ .lb-tiptap-thread-mark-selected {
132
+ color: var(--lb-accent);
133
+ text-decoration-line: underline;
134
+ text-decoration-color: var(--lb-accent-moderate);
135
+ text-underline-offset: 2px;
136
+ }
137
+
138
+ /*************************************
139
+ * Anchored threads *
140
+ *************************************/
141
+
142
+ .lb-tiptap-anchored-threads {
143
+ --lb-tiptap-anchored-threads-gap: 1.25rem;
144
+ --lb-tiptap-anchored-threads-active-thread-offset: -0.75rem;
145
+ }
146
+
147
+ .lb-tiptap-anchored-threads-thread-container {
148
+ transition-duration: calc(var(--lb-transition-duration) * 2);
149
+ transition-property: transform;
150
+ }
151
+
152
+ @media (prefers-reduced-motion) {
153
+ .lb-tiptap-anchored-threads-thread-container {
154
+ transition-duration: 0s;
155
+ }
156
+ }
157
+
158
+ .lb-tiptap-anchored-threads-thread {
159
+ position: relative;
160
+ overflow: hidden;
161
+ border-radius: var(--lb-radius);
162
+ background: var(--lb-dynamic-background);
163
+ box-shadow: $lb-tiptap-anchored-threads-shadow;
164
+ transition-property: background, box-shadow;
165
+
166
+ &::after {
167
+ content: "";
168
+ position: absolute;
169
+ inset: 0;
170
+ z-index: 1;
171
+ border-radius: inherit;
172
+ box-shadow: var(--lb-inset-shadow);
173
+ pointer-events: none;
174
+ }
175
+
176
+ &:where([data-state="active"]) {
177
+ box-shadow: $lb-tiptap-anchored-threads-active-shadow;
178
+ }
179
+ }
180
+
181
+ /*************************************
182
+ * Floating components *
183
+ *************************************/
184
+
185
+ .lb-tiptap-floating {
186
+ --lb-tiptap-floating-size: 350px;
187
+ }
188
+
189
+ /*************************************
190
+ * Floating threads *
191
+ *************************************/
192
+
193
+ .lb-tiptap-floating-threads-thread {
194
+ inline-size: var(--lb-tiptap-floating-size);
195
+
196
+ &:where(:not(:last-of-type)) {
197
+ border-block-end: 1px solid var(--lb-foreground-subtle);
198
+ }
199
+ }
200
+
201
+ /*************************************
202
+ * Floating composer *
203
+ *************************************/
204
+
205
+ .lb-tiptap-floating-composer {
206
+ inline-size: var(--lb-tiptap-floating-size);
207
+ }
208
+
209
+ .lb-tiptap-active-selection {
210
+ background: var(--lb-selection, rgb(0 0 255 / 20%));
211
+ pointer-events: none;
212
+ }
213
+
214
+ /*************************************
215
+ * Collab Cursors *
216
+ *************************************/
217
+
218
+ /* Give a remote user a caret */
219
+ /* stylelint-disable-next-line selector-class-pattern */
220
+ .collaboration-cursor__caret {
221
+ position: relative;
222
+ margin-inline-start: -1px;
223
+ margin-inline-end: -1px;
224
+ border-inline-start: 1px solid #0d0d0d;
225
+ border-inline-end: 1px solid #0d0d0d;
226
+ word-break: normal;
227
+ pointer-events: none;
228
+ }
229
+
230
+ /* Render the username above the caret */
231
+ /* stylelint-disable-next-line selector-class-pattern */
232
+ .collaboration-cursor__label {
233
+ position: absolute;
234
+ inset-inline-start: -1px;
235
+ inset-block-start: -1.4em;
236
+ padding: 2px 6px;
237
+ border-radius: 6px;
238
+ border-end-start-radius: 0;
239
+ color: #fff;
240
+ font-weight: 600;
241
+ font-style: normal;
242
+ font-size: 14px;
243
+ line-height: normal;
244
+ white-space: nowrap;
245
+ pointer-events: none;
246
+ user-select: none;
247
+ }
@@ -0,0 +1,6 @@
1
+ @mixin invisible-selection {
2
+ &::selection,
3
+ *::selection {
4
+ background: transparent;
5
+ }
6
+ }
package/styles.css ADDED
@@ -0,0 +1 @@
1
+ .lb-tiptap-suggestions-list{margin:0;padding:0;list-style:none}.lb-tiptap-mention-suggestions{--lb-tiptap-mention-suggestion-avatar-size:1.25rem}.lb-tiptap-mention-suggestion{padding:calc(.375*var(--lb-spacing))calc(.625*var(--lb-spacing))}.lb-tiptap-mention-suggestion-avatar{inline-size:var(--lb-tiptap-mention-suggestion-avatar-size);margin-inline-start:calc(-.125*var(--lb-spacing));margin-inline-end:calc(.5*var(--lb-spacing));margin-block:calc(.125*var(--lb-spacing));background:var(--lb-foreground-subtle);color:var(--lb-foreground-moderate)}.lb-tiptap-suggestions{animation-duration:var(--lb-transition-duration);animation-timing-function:var(--lb-transition-easing);will-change:transform,opacity;padding:4px}.lb-tiptap-suggestions-list-item{padding:calc(.25*var(--lb-spacing))calc(.5*var(--lb-spacing));border-radius:calc(var(--lb-radius) - .75*4px);color:var(--lb-foreground-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;align-items:center;scroll-margin-block:4px;font-size:.875rem;transition-property:background,color,opacity;display:flex}.lb-tiptap-suggestions-list-item:where([data-highlighted],[data-selected]){background:var(--lb-foreground-subtle);transition-duration:calc(var(--lb-transition-duration)/2)}.lb-tiptap-suggestions-list-item:where(:disabled,[data-disabled]){opacity:.5;cursor:not-allowed}.lb-tiptap-suggestions:where([data-side=top]){animation-name:lb-animation-slide-up}.lb-tiptap-suggestions:where([data-side=bottom]){animation-name:lb-animation-slide-down}.lb-tiptap-suggestions:where([data-state=closed]){animation-name:lb-animation-disappear}.lb-tiptap-mention{border-radius:calc(.675*var(--lb-radius));background:var(--lb-accent-subtle);color:var(--lb-accent);-webkit-box-decoration-break:clone;box-decoration-break:clone;padding:.1em .3em;font-weight:500}.lb-tiptap-mention::selection{background:0 0}.lb-tiptap-mention ::selection{background:0 0}.lb-mention-selected{background:var(--lb-accent);color:var(--lb-accent-foreground)}.lb-tiptap-thread-mark{background:var(--lb-accent-subtle);color:var(--lb-foreground);text-decoration-line:underline;-webkit-text-decoration-color:var(--lb-foreground-moderate);text-decoration-color:var(--lb-foreground-moderate);text-underline-offset:2px;outline:none;font-weight:500;transition-property:color,text-decoration-color}.lb-tiptap-thread-mark-selected{color:var(--lb-accent);text-decoration-line:underline;-webkit-text-decoration-color:var(--lb-accent-moderate);text-decoration-color:var(--lb-accent-moderate);text-underline-offset:2px}.lb-tiptap-anchored-threads{--lb-tiptap-anchored-threads-gap:1.25rem;--lb-tiptap-anchored-threads-active-thread-offset:-.75rem}.lb-tiptap-anchored-threads-thread-container{transition-duration:calc(var(--lb-transition-duration)*2);transition-property:transform}.lb-tiptap-anchored-threads-thread{border-radius:var(--lb-radius);background:var(--lb-dynamic-background);transition-property:background,box-shadow;position:relative;overflow:hidden;box-shadow:0 0 0 1px #0000000a,0 2px 6px #0000000a,0 6px 20px #0000000f}.lb-tiptap-anchored-threads-thread:after{content:"";z-index:1;border-radius:inherit;box-shadow:var(--lb-inset-shadow);pointer-events:none;position:absolute;inset:0}.lb-tiptap-anchored-threads-thread:where([data-state=active]){box-shadow:0 0 0 1px #0000000a,0 2px 6px #00000014,0 8px 26px #0000001f}.lb-tiptap-floating{--lb-tiptap-floating-size:350px}.lb-tiptap-floating-threads-thread{inline-size:var(--lb-tiptap-floating-size)}.lb-tiptap-floating-threads-thread:where(:not(:last-of-type)){border-block-end:1px solid var(--lb-foreground-subtle)}.lb-tiptap-floating-composer{inline-size:var(--lb-tiptap-floating-size)}.lb-tiptap-active-selection{background:var(--lb-selection,#00f3);pointer-events:none}.collaboration-cursor__caret{word-break:normal;pointer-events:none;border-inline:1px solid #0d0d0d;margin-inline:-1px;position:relative}.collaboration-cursor__label{border-radius:6px;color:#fff;white-space:nowrap;pointer-events:none;-webkit-user-select:none;user-select:none;border-end-start-radius:0;padding:2px 6px;font-size:14px;font-style:normal;font-weight:600;line-height:normal;position:absolute;inset-block-start:-1.4em;inset-inline-start:-1px}@media (prefers-reduced-motion){.lb-tiptap-suggestions:where(:not([data-state=closed])){animation-name:lb-animation-appear}.lb-tiptap-anchored-threads-thread-container{transition-duration:0s}}
@@ -0,0 +1 @@
1
+ declare module "@liveblocks/react-tiptap/styles.css";