@liveblocks/react-ui 3.3.4 → 3.4.0

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 (67) hide show
  1. package/dist/_private/index.d.cts +3 -4
  2. package/dist/_private/index.d.ts +3 -4
  3. package/dist/components/AiChat.cjs +3 -2
  4. package/dist/components/AiChat.cjs.map +1 -1
  5. package/dist/components/AiChat.js +3 -2
  6. package/dist/components/AiChat.js.map +1 -1
  7. package/dist/components/AiTool.cjs +15 -6
  8. package/dist/components/AiTool.cjs.map +1 -1
  9. package/dist/components/AiTool.js +15 -6
  10. package/dist/components/AiTool.js.map +1 -1
  11. package/dist/components/Comment.cjs +5 -2
  12. package/dist/components/Comment.cjs.map +1 -1
  13. package/dist/components/Comment.js +5 -2
  14. package/dist/components/Comment.js.map +1 -1
  15. package/dist/components/Composer.cjs +5 -2
  16. package/dist/components/Composer.cjs.map +1 -1
  17. package/dist/components/Composer.js +5 -2
  18. package/dist/components/Composer.js.map +1 -1
  19. package/dist/components/Thread.cjs +1 -2
  20. package/dist/components/Thread.cjs.map +1 -1
  21. package/dist/components/Thread.js +2 -3
  22. package/dist/components/Thread.js.map +1 -1
  23. package/dist/components/internal/AiChatAssistantMessage.cjs +1 -0
  24. package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
  25. package/dist/components/internal/AiChatAssistantMessage.js +1 -0
  26. package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
  27. package/dist/components/internal/AiChatUserMessage.cjs +16 -14
  28. package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
  29. package/dist/components/internal/AiChatUserMessage.js +16 -14
  30. package/dist/components/internal/AiChatUserMessage.js.map +1 -1
  31. package/dist/components/internal/CodeBlock.cjs +1 -1
  32. package/dist/components/internal/CodeBlock.cjs.map +1 -1
  33. package/dist/components/internal/CodeBlock.js +1 -1
  34. package/dist/components/internal/CodeBlock.js.map +1 -1
  35. package/dist/components/internal/Prose.cjs +3 -1
  36. package/dist/components/internal/Prose.cjs.map +1 -1
  37. package/dist/components/internal/Prose.js +3 -1
  38. package/dist/components/internal/Prose.js.map +1 -1
  39. package/dist/index.d.cts +4 -3
  40. package/dist/index.d.ts +4 -3
  41. package/dist/primitives/AiMessage/tool-invocation.cjs +5 -2
  42. package/dist/primitives/AiMessage/tool-invocation.cjs.map +1 -1
  43. package/dist/primitives/AiMessage/tool-invocation.js +5 -2
  44. package/dist/primitives/AiMessage/tool-invocation.js.map +1 -1
  45. package/dist/primitives/Composer/slate/plugins/custom-links.cjs +2 -9
  46. package/dist/primitives/Composer/slate/plugins/custom-links.cjs.map +1 -1
  47. package/dist/primitives/Composer/slate/plugins/custom-links.js +1 -8
  48. package/dist/primitives/Composer/slate/plugins/custom-links.js.map +1 -1
  49. package/dist/primitives/Markdown.cjs +409 -61
  50. package/dist/primitives/Markdown.cjs.map +1 -1
  51. package/dist/primitives/Markdown.js +410 -62
  52. package/dist/primitives/Markdown.js.map +1 -1
  53. package/dist/version.cjs +1 -1
  54. package/dist/version.js +1 -1
  55. package/package.json +4 -4
  56. package/src/styles/dark/index.css +26 -0
  57. package/src/styles/index.css +178 -45
  58. package/styles/dark/attributes.css +1 -1
  59. package/styles/dark/attributes.css.map +1 -1
  60. package/styles/dark/media-query.css +1 -1
  61. package/styles/dark/media-query.css.map +1 -1
  62. package/styles.css +1 -1
  63. package/styles.css.map +1 -1
  64. package/dist/utils/find-last-index.cjs +0 -16
  65. package/dist/utils/find-last-index.cjs.map +0 -1
  66. package/dist/utils/find-last-index.js +0 -14
  67. package/dist/utils/find-last-index.js.map +0 -1
@@ -1,18 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var core = require('@liveblocks/core');
3
4
  var slate = require('slate');
4
5
  var isText = require('../../../slate/utils/is-text.cjs');
5
6
  var marks = require('../../../slate/utils/marks.cjs');
6
7
  var selectionContainsInlines = require('../../../slate/utils/selection-contains-inlines.cjs');
7
8
 
8
- function isUrl(string) {
9
- try {
10
- new URL(string);
11
- return true;
12
- } catch (_) {
13
- return false;
14
- }
15
- }
16
9
  function withCustomLinks(editor) {
17
10
  const { isInline, normalizeNode, insertData } = editor;
18
11
  editor.isInline = (element) => {
@@ -42,7 +35,7 @@ function withCustomLinks(editor) {
42
35
  let shouldInvokeDefaultBehavior = true;
43
36
  if (selection && !slate.Range.isCollapsed(selection)) {
44
37
  if (selection.anchor.path[0] === selection.focus.path[0]) {
45
- if (isUrl(pastedText)) {
38
+ if (core.isUrl(pastedText)) {
46
39
  if (!selectionContainsInlines.selectionContainsInlines(editor, (node) => !isText.isText(node))) {
47
40
  slate.Transforms.wrapNodes(
48
41
  editor,
@@ -1 +1 @@
1
- {"version":3,"file":"custom-links.cjs","sources":["../../../../../src/primitives/Composer/slate/plugins/custom-links.ts"],"sourcesContent":["import type { Editor as SlateEditor } from \"slate\";\nimport {\n Element as SlateElement,\n Node as SlateNode,\n Range as SlateRange,\n Transforms as SlateTransforms,\n} from \"slate\";\n\nimport type { ComposerBodyCustomLink } from \"../../../../types\";\nimport { isPlainText, isText } from \"../../../slate/utils/is-text\";\nimport { filterActiveMarks } from \"../../../slate/utils/marks\";\nimport { selectionContainsInlines } from \"../../../slate/utils/selection-contains-inlines\";\n\nfunction isUrl(string: string) {\n try {\n new URL(string);\n return true;\n } catch (_) {\n return false;\n }\n}\n\nexport function withCustomLinks(editor: SlateEditor): SlateEditor {\n const { isInline, normalizeNode, insertData } = editor;\n\n editor.isInline = (element) => {\n return element.type === \"custom-link\" ? true : isInline(element);\n };\n\n editor.normalizeNode = (entry) => {\n const [node, path] = entry;\n\n // Prevent nested or empty custom links\n if (SlateElement.isElement(node) && node.type === \"custom-link\") {\n if (\n node.children.length === 0 ||\n (node.children.length === 1 && node.children[0]?.text === \"\")\n ) {\n SlateTransforms.removeNodes(editor, { at: path });\n }\n }\n\n if (isText(node)) {\n const parentNode = SlateNode.parent(editor, path);\n\n // Prevent rich text within custom links by removing all marks of inner text nodes\n if (isComposerBodyCustomLink(parentNode)) {\n if (!isPlainText(node)) {\n const marks = filterActiveMarks(node);\n\n SlateTransforms.unsetNodes(editor, marks, { at: path });\n }\n }\n }\n\n normalizeNode(entry);\n };\n\n // Create custom links when pasting URLs while some text is selected\n editor.insertData = (data) => {\n const { selection } = editor;\n const pastedText = data.getData(\"text/plain\");\n\n // Keep track of whether the default behavior should be invoked\n // This allows us to sequence multiple conditions in a performant way,\n // ordering them by likelihood/cost and stopping early whenever possible\n let shouldInvokeDefaultBehavior = true;\n\n // Check if the selection is a range\n if (selection && !SlateRange.isCollapsed(selection)) {\n // Check if the selection is contained in a single block\n if (selection.anchor.path[0] === selection.focus.path[0]) {\n // Check if the pasted text is a valid URL\n if (isUrl(pastedText)) {\n // Check if the selection only contains (rich and/or plain) text nodes\n if (!selectionContainsInlines(editor, (node) => !isText(node))) {\n // If all conditions are met, wrap the selected nodes in a custom link\n SlateTransforms.wrapNodes<ComposerBodyCustomLink>(\n editor,\n {\n type: \"custom-link\",\n url: pastedText,\n children: [],\n },\n {\n at: selection,\n split: true,\n match: isPlainText,\n }\n );\n shouldInvokeDefaultBehavior = false;\n }\n }\n }\n }\n\n if (shouldInvokeDefaultBehavior) {\n insertData(data);\n }\n };\n\n return editor;\n}\n\nexport function isComposerBodyCustomLink(\n node: SlateNode\n): node is ComposerBodyCustomLink {\n return SlateElement.isElement(node) && node.type === \"custom-link\";\n}\n"],"names":["SlateElement","SlateTransforms","isText","SlateNode","isPlainText","marks","filterActiveMarks","SlateRange","selectionContainsInlines"],"mappings":"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"}
1
+ {"version":3,"file":"custom-links.cjs","sources":["../../../../../src/primitives/Composer/slate/plugins/custom-links.ts"],"sourcesContent":["import { isUrl } from \"@liveblocks/core\";\nimport type { Editor as SlateEditor } from \"slate\";\nimport {\n Element as SlateElement,\n Node as SlateNode,\n Range as SlateRange,\n Transforms as SlateTransforms,\n} from \"slate\";\n\nimport type { ComposerBodyCustomLink } from \"../../../../types\";\nimport { isPlainText, isText } from \"../../../slate/utils/is-text\";\nimport { filterActiveMarks } from \"../../../slate/utils/marks\";\nimport { selectionContainsInlines } from \"../../../slate/utils/selection-contains-inlines\";\n\nexport function withCustomLinks(editor: SlateEditor): SlateEditor {\n const { isInline, normalizeNode, insertData } = editor;\n\n editor.isInline = (element) => {\n return element.type === \"custom-link\" ? true : isInline(element);\n };\n\n editor.normalizeNode = (entry) => {\n const [node, path] = entry;\n\n // Prevent nested or empty custom links\n if (SlateElement.isElement(node) && node.type === \"custom-link\") {\n if (\n node.children.length === 0 ||\n (node.children.length === 1 && node.children[0]?.text === \"\")\n ) {\n SlateTransforms.removeNodes(editor, { at: path });\n }\n }\n\n if (isText(node)) {\n const parentNode = SlateNode.parent(editor, path);\n\n // Prevent rich text within custom links by removing all marks of inner text nodes\n if (isComposerBodyCustomLink(parentNode)) {\n if (!isPlainText(node)) {\n const marks = filterActiveMarks(node);\n\n SlateTransforms.unsetNodes(editor, marks, { at: path });\n }\n }\n }\n\n normalizeNode(entry);\n };\n\n // Create custom links when pasting URLs while some text is selected\n editor.insertData = (data) => {\n const { selection } = editor;\n const pastedText = data.getData(\"text/plain\");\n\n // Keep track of whether the default behavior should be invoked\n // This allows us to sequence multiple conditions in a performant way,\n // ordering them by likelihood/cost and stopping early whenever possible\n let shouldInvokeDefaultBehavior = true;\n\n // Check if the selection is a range\n if (selection && !SlateRange.isCollapsed(selection)) {\n // Check if the selection is contained in a single block\n if (selection.anchor.path[0] === selection.focus.path[0]) {\n // Check if the pasted text is a valid URL\n if (isUrl(pastedText)) {\n // Check if the selection only contains (rich and/or plain) text nodes\n if (!selectionContainsInlines(editor, (node) => !isText(node))) {\n // If all conditions are met, wrap the selected nodes in a custom link\n SlateTransforms.wrapNodes<ComposerBodyCustomLink>(\n editor,\n {\n type: \"custom-link\",\n url: pastedText,\n children: [],\n },\n {\n at: selection,\n split: true,\n match: isPlainText,\n }\n );\n shouldInvokeDefaultBehavior = false;\n }\n }\n }\n }\n\n if (shouldInvokeDefaultBehavior) {\n insertData(data);\n }\n };\n\n return editor;\n}\n\nexport function isComposerBodyCustomLink(\n node: SlateNode\n): node is ComposerBodyCustomLink {\n return SlateElement.isElement(node) && node.type === \"custom-link\";\n}\n"],"names":["SlateElement","SlateTransforms","isText","SlateNode","isPlainText","marks","filterActiveMarks","SlateRange","isUrl","selectionContainsInlines"],"mappings":"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"}
@@ -1,16 +1,9 @@
1
+ import { isUrl } from '@liveblocks/core';
1
2
  import { Element, Transforms, Node, Range } from 'slate';
2
3
  import { isText, isPlainText } from '../../../slate/utils/is-text.js';
3
4
  import { filterActiveMarks } from '../../../slate/utils/marks.js';
4
5
  import { selectionContainsInlines } from '../../../slate/utils/selection-contains-inlines.js';
5
6
 
6
- function isUrl(string) {
7
- try {
8
- new URL(string);
9
- return true;
10
- } catch (_) {
11
- return false;
12
- }
13
- }
14
7
  function withCustomLinks(editor) {
15
8
  const { isInline, normalizeNode, insertData } = editor;
16
9
  editor.isInline = (element) => {
@@ -1 +1 @@
1
- {"version":3,"file":"custom-links.js","sources":["../../../../../src/primitives/Composer/slate/plugins/custom-links.ts"],"sourcesContent":["import type { Editor as SlateEditor } from \"slate\";\nimport {\n Element as SlateElement,\n Node as SlateNode,\n Range as SlateRange,\n Transforms as SlateTransforms,\n} from \"slate\";\n\nimport type { ComposerBodyCustomLink } from \"../../../../types\";\nimport { isPlainText, isText } from \"../../../slate/utils/is-text\";\nimport { filterActiveMarks } from \"../../../slate/utils/marks\";\nimport { selectionContainsInlines } from \"../../../slate/utils/selection-contains-inlines\";\n\nfunction isUrl(string: string) {\n try {\n new URL(string);\n return true;\n } catch (_) {\n return false;\n }\n}\n\nexport function withCustomLinks(editor: SlateEditor): SlateEditor {\n const { isInline, normalizeNode, insertData } = editor;\n\n editor.isInline = (element) => {\n return element.type === \"custom-link\" ? true : isInline(element);\n };\n\n editor.normalizeNode = (entry) => {\n const [node, path] = entry;\n\n // Prevent nested or empty custom links\n if (SlateElement.isElement(node) && node.type === \"custom-link\") {\n if (\n node.children.length === 0 ||\n (node.children.length === 1 && node.children[0]?.text === \"\")\n ) {\n SlateTransforms.removeNodes(editor, { at: path });\n }\n }\n\n if (isText(node)) {\n const parentNode = SlateNode.parent(editor, path);\n\n // Prevent rich text within custom links by removing all marks of inner text nodes\n if (isComposerBodyCustomLink(parentNode)) {\n if (!isPlainText(node)) {\n const marks = filterActiveMarks(node);\n\n SlateTransforms.unsetNodes(editor, marks, { at: path });\n }\n }\n }\n\n normalizeNode(entry);\n };\n\n // Create custom links when pasting URLs while some text is selected\n editor.insertData = (data) => {\n const { selection } = editor;\n const pastedText = data.getData(\"text/plain\");\n\n // Keep track of whether the default behavior should be invoked\n // This allows us to sequence multiple conditions in a performant way,\n // ordering them by likelihood/cost and stopping early whenever possible\n let shouldInvokeDefaultBehavior = true;\n\n // Check if the selection is a range\n if (selection && !SlateRange.isCollapsed(selection)) {\n // Check if the selection is contained in a single block\n if (selection.anchor.path[0] === selection.focus.path[0]) {\n // Check if the pasted text is a valid URL\n if (isUrl(pastedText)) {\n // Check if the selection only contains (rich and/or plain) text nodes\n if (!selectionContainsInlines(editor, (node) => !isText(node))) {\n // If all conditions are met, wrap the selected nodes in a custom link\n SlateTransforms.wrapNodes<ComposerBodyCustomLink>(\n editor,\n {\n type: \"custom-link\",\n url: pastedText,\n children: [],\n },\n {\n at: selection,\n split: true,\n match: isPlainText,\n }\n );\n shouldInvokeDefaultBehavior = false;\n }\n }\n }\n }\n\n if (shouldInvokeDefaultBehavior) {\n insertData(data);\n }\n };\n\n return editor;\n}\n\nexport function isComposerBodyCustomLink(\n node: SlateNode\n): node is ComposerBodyCustomLink {\n return SlateElement.isElement(node) && node.type === \"custom-link\";\n}\n"],"names":["SlateElement","SlateTransforms","SlateNode","SlateRange"],"mappings":"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"}
1
+ {"version":3,"file":"custom-links.js","sources":["../../../../../src/primitives/Composer/slate/plugins/custom-links.ts"],"sourcesContent":["import { isUrl } from \"@liveblocks/core\";\nimport type { Editor as SlateEditor } from \"slate\";\nimport {\n Element as SlateElement,\n Node as SlateNode,\n Range as SlateRange,\n Transforms as SlateTransforms,\n} from \"slate\";\n\nimport type { ComposerBodyCustomLink } from \"../../../../types\";\nimport { isPlainText, isText } from \"../../../slate/utils/is-text\";\nimport { filterActiveMarks } from \"../../../slate/utils/marks\";\nimport { selectionContainsInlines } from \"../../../slate/utils/selection-contains-inlines\";\n\nexport function withCustomLinks(editor: SlateEditor): SlateEditor {\n const { isInline, normalizeNode, insertData } = editor;\n\n editor.isInline = (element) => {\n return element.type === \"custom-link\" ? true : isInline(element);\n };\n\n editor.normalizeNode = (entry) => {\n const [node, path] = entry;\n\n // Prevent nested or empty custom links\n if (SlateElement.isElement(node) && node.type === \"custom-link\") {\n if (\n node.children.length === 0 ||\n (node.children.length === 1 && node.children[0]?.text === \"\")\n ) {\n SlateTransforms.removeNodes(editor, { at: path });\n }\n }\n\n if (isText(node)) {\n const parentNode = SlateNode.parent(editor, path);\n\n // Prevent rich text within custom links by removing all marks of inner text nodes\n if (isComposerBodyCustomLink(parentNode)) {\n if (!isPlainText(node)) {\n const marks = filterActiveMarks(node);\n\n SlateTransforms.unsetNodes(editor, marks, { at: path });\n }\n }\n }\n\n normalizeNode(entry);\n };\n\n // Create custom links when pasting URLs while some text is selected\n editor.insertData = (data) => {\n const { selection } = editor;\n const pastedText = data.getData(\"text/plain\");\n\n // Keep track of whether the default behavior should be invoked\n // This allows us to sequence multiple conditions in a performant way,\n // ordering them by likelihood/cost and stopping early whenever possible\n let shouldInvokeDefaultBehavior = true;\n\n // Check if the selection is a range\n if (selection && !SlateRange.isCollapsed(selection)) {\n // Check if the selection is contained in a single block\n if (selection.anchor.path[0] === selection.focus.path[0]) {\n // Check if the pasted text is a valid URL\n if (isUrl(pastedText)) {\n // Check if the selection only contains (rich and/or plain) text nodes\n if (!selectionContainsInlines(editor, (node) => !isText(node))) {\n // If all conditions are met, wrap the selected nodes in a custom link\n SlateTransforms.wrapNodes<ComposerBodyCustomLink>(\n editor,\n {\n type: \"custom-link\",\n url: pastedText,\n children: [],\n },\n {\n at: selection,\n split: true,\n match: isPlainText,\n }\n );\n shouldInvokeDefaultBehavior = false;\n }\n }\n }\n }\n\n if (shouldInvokeDefaultBehavior) {\n insertData(data);\n }\n };\n\n return editor;\n}\n\nexport function isComposerBodyCustomLink(\n node: SlateNode\n): node is ComposerBodyCustomLink {\n return SlateElement.isElement(node) && node.type === \"custom-link\";\n}\n"],"names":["SlateElement","SlateTransforms","SlateNode","SlateRange"],"mappings":"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"}