diff --git a/docs/src/demos/Examples/CodeBlockLanguage/React/CodeBlockComponent.jsx b/docs/src/demos/Examples/CodeBlockLanguage/React/CodeBlockComponent.jsx new file mode 100644 index 00000000..486b7428 --- /dev/null +++ b/docs/src/demos/Examples/CodeBlockLanguage/React/CodeBlockComponent.jsx @@ -0,0 +1,24 @@ +import React from 'react' +import { NodeViewWrapper, NodeViewContent } from '@tiptap/react' +import './CodeBlockComponent.scss' + +export default ({ node: { attrs: { language: defaultLanguage } }, updateAttributes, extension }) => ( + + +
+      
+    
+
+) diff --git a/docs/src/demos/Examples/CodeBlockLanguage/React/CodeBlockComponent.scss b/docs/src/demos/Examples/CodeBlockLanguage/React/CodeBlockComponent.scss new file mode 100644 index 00000000..d0b00f23 --- /dev/null +++ b/docs/src/demos/Examples/CodeBlockLanguage/React/CodeBlockComponent.scss @@ -0,0 +1,9 @@ +.code-block { + position: relative; + + select { + position: absolute; + right: 0.5rem; + top: 0.5rem; + } +} \ No newline at end of file diff --git a/docs/src/demos/Examples/CodeBlockLanguage/React/index.jsx b/docs/src/demos/Examples/CodeBlockLanguage/React/index.jsx new file mode 100644 index 00000000..561c97b9 --- /dev/null +++ b/docs/src/demos/Examples/CodeBlockLanguage/React/index.jsx @@ -0,0 +1,71 @@ +import React from 'react' +import { useEditor, EditorContent, ReactNodeViewRenderer } from '@tiptap/react' +import Document from '@tiptap/extension-document' +import Paragraph from '@tiptap/extension-paragraph' +import Text from '@tiptap/extension-text' +import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight' +import CodeBlockComponent from './CodeBlockComponent' + +// load all highlight.js languages +import lowlight from 'lowlight' + +// load specific languages only +// import lowlight from 'lowlight/lib/core' +// import javascript from 'highlight.js/lib/languages/javascript' +// lowlight.registerLanguage('javascript', javascript) +import './styles.scss' + +const MenuBar = ({ editor }) => { + if (!editor) { + return null + } + + return ( + + ) +} + +export default () => { + const editor = useEditor({ + extensions: [ + Document, + Paragraph, + Text, + CodeBlockLowlight + .extend({ + addNodeView() { + return ReactNodeViewRenderer(CodeBlockComponent) + }, + }) + .configure({ lowlight }), + ], + content: ` +

+ That’s a boring paragraph followed by a fenced code block: +

+
for (var i=1; i <= 20; i++)
+{
+  if (i % 15 == 0)
+    console.log("FizzBuzz");
+  else if (i % 3 == 0)
+    console.log("Fizz");
+  else if (i % 5 == 0)
+    console.log("Buzz");
+  else
+    console.log(i);
+}
+

+ Press Command/Ctrl + Enter to leave the fenced code block and continue typing in boring paragraphs. +

+ `, + }) + + return ( +
+ + +
+ ) +} diff --git a/docs/src/demos/Examples/CodeBlockLanguage/React/styles.scss b/docs/src/demos/Examples/CodeBlockLanguage/React/styles.scss new file mode 100644 index 00000000..9b4a4c44 --- /dev/null +++ b/docs/src/demos/Examples/CodeBlockLanguage/React/styles.scss @@ -0,0 +1,73 @@ +/* Basic editor styles */ +.ProseMirror { + > * + * { + margin-top: 0.75em; + } + + pre { + background: #0d0d0d; + color: #fff; + font-family: "JetBrainsMono", monospace; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + + code { + color: inherit; + padding: 0; + background: none; + font-size: 0.8rem; + } + + .hljs-comment, + .hljs-quote { + color: #616161; + } + + .hljs-variable, + .hljs-template-variable, + .hljs-attribute, + .hljs-tag, + .hljs-name, + .hljs-regexp, + .hljs-link, + .hljs-name, + .hljs-selector-id, + .hljs-selector-class { + color: #f98181; + } + + .hljs-number, + .hljs-meta, + .hljs-built_in, + .hljs-builtin-name, + .hljs-literal, + .hljs-type, + .hljs-params { + color: #fbbc88; + } + + .hljs-string, + .hljs-symbol, + .hljs-bullet { + color: #b9f18d; + } + + .hljs-title, + .hljs-section { + color: #faf594; + } + + .hljs-keyword, + .hljs-selector-tag { + color: #70cff8; + } + + .hljs-emphasis { + font-style: italic; + } + + .hljs-strong { + font-weight: 700; + } + } +} diff --git a/docs/src/demos/Examples/CodeBlockLanguage/CodeBlockComponent.vue b/docs/src/demos/Examples/CodeBlockLanguage/Vue/CodeBlockComponent.vue similarity index 100% rename from docs/src/demos/Examples/CodeBlockLanguage/CodeBlockComponent.vue rename to docs/src/demos/Examples/CodeBlockLanguage/Vue/CodeBlockComponent.vue diff --git a/docs/src/demos/Examples/CodeBlockLanguage/index.vue b/docs/src/demos/Examples/CodeBlockLanguage/Vue/index.vue similarity index 100% rename from docs/src/demos/Examples/CodeBlockLanguage/index.vue rename to docs/src/demos/Examples/CodeBlockLanguage/Vue/index.vue diff --git a/docs/src/docPages/examples/syntax-highlighting.md b/docs/src/docPages/examples/syntax-highlighting.md index 03b9598a..54d9eef1 100644 --- a/docs/src/docPages/examples/syntax-highlighting.md +++ b/docs/src/docPages/examples/syntax-highlighting.md @@ -1,3 +1,6 @@ # Syntax highlighting - + diff --git a/packages/core/src/commands/focus.ts b/packages/core/src/commands/focus.ts index dd3aee21..cf374a41 100644 --- a/packages/core/src/commands/focus.ts +++ b/packages/core/src/commands/focus.ts @@ -73,7 +73,13 @@ export const focus: RawCommands['focus'] = (position = null) => ({ tr.setStoredMarks(storedMarks) } - view.focus() + // focus async because in some situations weird things happen + // see: https://github.com/ueberdosis/tiptap/issues/1520 + setTimeout(() => { + if (!editor.isDestroyed) { + view.focus() + } + }, 0) } return true