Last active
July 17, 2024 10:11
-
-
Save fubits1/f2e27c6fa8f5c2850689d8585a68c5e0 to your computer and use it in GitHub Desktop.
Svelte 5 and tiptap editor default example (REPL backup just in case)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script> | |
| /** my REPL link: | |
| * https://svelte-5-preview.vercel.app/#H4sIAAAAAAAACr1Z624buRV-lbNKYckLSaOLx2vLsra2YzdpN22xTtEfqwChZiiJMDWcJTl2FEFA3qAo0D_91X99sDxBH6GHnLsuGwuyLUiaGfJc-H08h-SQi8qYcaoqvV8WlYDMaKVXuQjDSr2i56F5UPeUa4rPSkTSMyV95UkW6sEwGGrneyA-CTX1YSzFDKZah6rnOBOmp9Go6YmZE9ERlb5QTDka1UjoaEmpMyMscHw6E8pR0nOuP5FZiO1wXtMxibh2bq1f-N4ZBgBsFgqpYQFXggsJy9hZ9feJQfpJ00AxETQ8U18tqPzElH6r6WyrBkeBBkOJotZ7rL_Vc063qmm8bSgjUtS71URqKv_EdKw4rKSaKq5p3DE9rJyVMF37TOegchVPSLoqK4J3Igp0Lhx3jxUzgpxqoJzOKMqcw-_Qq6a1w7OsKnZVqjF1idla7RDOB7AwRZALB_QhaWQtqYLUSS-9qWcVKUWqB7-khRB3HMZDMGaTSNLaAkx8GZmM66YJv3rWY_bxAywP67mVXHaTpd_SzHsmK_yQ3aExbcF8zBXMpz_tDMolAG8Y6CmVtL4i6qzJ9sM1ZT1lCvBLoE9ngxFRzOs7eIes2fAHMYa-0lIEk8F7GwV9J3lswi2ircfOgZgf53DHAt8oWVNgghJsUCqYi-jrl3_7EEoxIiM-Rxch9ZK4JLFo3MNNuIw0PBAMWowBxo0qKEqNKzDpoXqrWFeR9SO-hrXP2VoZ9uCUaGyXoWAUcROTxgM84HiBUUjh65f_rhlyNljabB21AUNWP4jYrMlr1XyEwb6zhmBD971VAbZdIzFEw0RSon-EC-wA0xPYCbYYe9fQipTTnNik2yzwGaZ1E36iMQ1azpEKT_gURlx4d9-mOpR00LcKHidKnQ8rnASTiExow1NqWBmMhD-Pc9hnKuRk3oMAqcVUX_YdozhAq2jk23DhLhAP9eyaRi-ORpIqxe4Rx9sYhggwwky84NgVU0GBeWbkn-C9iCbTJvwBFbBHTPAZ0Mibx5l3h8-caY3BPzKVEgcivwmvRUz1WMgJBokW4E0pChvDwpCZpgxSKETzm6xZcn-NhF7FDfD3GFsalzPymQUTbK4QPjwIeVeHkZh_B__7zz__sRZJIwnOmsGvX_4F78RstU1bmvAxG0lE8F6SQBFP4_DZg9JgbD6OY-jwKEjakDTwkQQl4GOSxUxdoOI9_WgbjUBUkvLUz01kY3p8c5bWLJNGLOO5wl5w6Mkm-mDxio0TpaWZ-Ps-u88C0IyfUvDGBDsvxAg0Aisio0hrnDbLEigTl6ePQ7y3QXG-iNGjZSUwk7iYwMFBOmB5U1w81A6bY-FFCq9aTCacXgru44OMsGqZW8QkMMnony--S9WJUd7JSAxjsUJ1DXGh_LByCD_iXMxUg9jyYQV6-DysZBYGuSnjIYPvxPgfzcdvEvBWE5Tdm4KtZraSwKzGbjTEXp6HiFst2R3dm4itZrYSoazGbkTEXp6HiCsc7femYYuRrSSYKWY3CoyHbxEAj8MdBYrqC87fERwDs1YPrjglEmamcE8HnrH0Z2zwmvXAFD5V_yGKvxJJJpKE013ID1Ol3Xog8_U8cfiGEh8nVVyrc4ovLD1o4xTzeFDTWH1YqUPJwg4A37RfCFlnb2SdHZF1XghZd29k3R2RdV8I2dHeyI52RHb0QsjcvZG5OyJzXwjZ8d7IjndEdvw8yC7ta7DZu9hp3Zlp7bj6zF-6nwfOXyS-l1B_VzwiV9sNUOLvGRGZ1cmleXfbdRFklXZfCcUbAc8UbNk76E7BlmntGGy53tOs7nBV9EZI9hnfNwn_OeI5imKiZhIgUeQJXRPpX0pK8kAYmCIYmbKn6qco8MUeS_aN6gVy_ob1Tx1amH77NHmjeqHJP9OnbzL2pt2RrlVfnbonr2_a1UenQ1Wnm9BVM5nYE4ceZHbiSaWaJUgV86Na3bjmjmS4NTz7js_u7X16t3DYGM3YXZURC_ye2Y7D5sX778tBphH07RZwej5zabeGk42fZHPYnKr0JlyMCF-AkWvGZw5mt2moARqNhynTtAevbm5u7I5QozHixLvDks5157JzWixs2P0fojTWttutm9Z1UotvFPNGuwdyMiK143Yduj_UodOqQ6vZcg-LQp3NQicloe5GoXanJHSUCLldFDpBoRMj1G2VhNxEyFR2XPx1jdBxQYjSwGDtXLluiia0_YWlxxet1o1bKi1S4J60WldX5WrOJlOdOD1Bp8an65aJmFPOxUPR0s3F1VXbLVWnDXdbBv8R_rWNlaMVI4k_030X16kFTDRb5F51u3lRQfb6MpNVU-Ibb63wE7Q7-Nft4p95sv4N8_G32To-rNuKbvO4fYLX0-bp0ek2YdtQDHB0cgC9MZNKN7wp43660Ynv6BMWNLQI0Xm8GTm0Z1QYymZ1UAxhYyPidbBHWDy1EBLfrPVQHdqSzs6KdvG9sdlxsdRWZQ9IYC4Z_x_gigLCfPu11C5Uy8SzqpHA_J2t1C7LCJJl7CqIaTsGMe0k125yPUqubnI9ThvEWUAbUxp3XbvZPltnr9N0c1D2vPIB3_B7EEqq9bxIbbEBm_qhW7S0grad1xWswSKhcYzR3FDsMzWSlmQoi3Y2i3Y2iHY3i7Y3iG7gbYPqqiJ2kF2AmbMJZGks5Ixoc7ZdPFhL-8wewSRkjXAUnNiTi0YyH9wTWStn_2HC38gudRsSAyFSvXLolZTLY2uqXmh_q3lS6Jc87G38mUFvtV8Q03qLS-62NtLd0kg7T5TaNiYzxuc46f2R6kuJ0656JwKBc-UMLyokHl3LyDgH13H8kGVqck69ynsZR3LKFVckrWTBlEqms-IyfbKQxbnfDal7APkaOKMw5ojTMaagGR2V4MxPeIknrMNHQU1MtNfzSJZ9lSAm7m2Ctjd576x67-S-0UX8NefLZrFQqVdmwmdjRv1KT8uILj8s_w8G-ms8GyIAAA== | |
| */ | |
| /** | |
| * Svelte 5 with the tiptap editor default editor example | |
| * GitHub gist backup: https://gist.github.com/fubits1/f2e27c6fa8f5c2850689d8585a68c5e0 | |
| * runed version of: https://svelte.dev/repl/c5cae550c2f4418e95c4dbecf832e6f5?version=4.2.18 | |
| * adapted from: https://github.com/ueberdosis/tiptap/tree/main/demos/src/Examples/Default/Svelte | |
| */ | |
| import { Color } from '@tiptap/extension-color' | |
| import ListItem from '@tiptap/extension-list-item' | |
| import TextStyle from '@tiptap/extension-text-style' | |
| import StarterKit from "@tiptap/starter-kit"; | |
| import { Editor } from "@tiptap/core"; | |
| import { onMount } from "svelte"; | |
| let element = $state(); | |
| let editor = $state(); | |
| onMount(() => { | |
| editor = new Editor({ | |
| element: element, | |
| extensions: [ | |
| Color.configure({ types: [TextStyle.name, ListItem.name] }), | |
| TextStyle.configure({ types: [ListItem.name] }), | |
| StarterKit, | |
| ], | |
| content: ` | |
| <h2> | |
| Hi there, | |
| </h2> | |
| <p> | |
| this is a <em>basic</em> example of <strong>Tiptap</strong>. Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists: | |
| </p> | |
| <ul> | |
| <li> | |
| That’s a bullet list with one … | |
| </li> | |
| <li> | |
| … or two list items. | |
| </li> | |
| </ul> | |
| <p> | |
| Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block: | |
| </p> | |
| <pre><code class="language-css">body { | |
| display: none; | |
| }</code></pre> | |
| <p> | |
| I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too. | |
| </p> | |
| <blockquote> | |
| Wow, that’s amazing. Good work, boy! 👏 | |
| <br /> | |
| — Mom | |
| </blockquote> | |
| `, | |
| onTransaction: () => { | |
| // force re-render so `editor.isActive` works as expected | |
| editor = editor; | |
| }, | |
| }); | |
| }); | |
| </script> | |
| {#if editor} | |
| <div class="control-group"> | |
| <div class="button-group"> | |
| <button | |
| onclick={() => console.log && editor.chain().focus().toggleBold().run()} | |
| disabled={!editor.can().chain().focus().toggleBold().run()} | |
| class={editor.isActive("bold") ? "is-active" : ""} | |
| > | |
| Bold | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleItalic().run()} | |
| disabled={!editor.can().chain().focus().toggleItalic().run()} | |
| class={editor.isActive("italic") ? "is-active" : ""} | |
| > | |
| Italic | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleStrike().run()} | |
| disabled={!editor.can().chain().focus().toggleStrike().run()} | |
| class={editor.isActive("strike") ? "is-active" : ""} | |
| > | |
| Strike | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleCode().run()} | |
| disabled={!editor.can().chain().focus().toggleCode().run()} | |
| class={editor.isActive("code") ? "is-active" : ""} | |
| > | |
| Code | |
| </button> | |
| <button onclick={() => editor.chain().focus().unsetAllMarks().run()}>Clear marks</button> | |
| <button onclick={() => editor.chain().focus().clearNodes().run()}>Clear nodes</button> | |
| <button | |
| onclick={() => editor.chain().focus().setParagraph().run()} | |
| class={editor.isActive("paragraph") ? "is-active" : ""} | |
| > | |
| Paragraph | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()} | |
| class={editor.isActive("heading", { level: 1 }) ? "is-active" : ""} | |
| > | |
| H1 | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()} | |
| class={editor.isActive("heading", { level: 2 }) ? "is-active" : ""} | |
| > | |
| H2 | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()} | |
| class={editor.isActive("heading", { level: 3 }) ? "is-active" : ""} | |
| > | |
| H3 | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleHeading({ level: 4 }).run()} | |
| class={editor.isActive("heading", { level: 4 }) ? "is-active" : ""} | |
| > | |
| H4 | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleHeading({ level: 5 }).run()} | |
| class={editor.isActive("heading", { level: 5 }) ? "is-active" : ""} | |
| > | |
| H5 | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleHeading({ level: 6 }).run()} | |
| class={editor.isActive("heading", { level: 6 }) ? "is-active" : ""} | |
| > | |
| H6 | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleBulletList().run()} | |
| class={editor.isActive("bulletList") ? "is-active" : ""} | |
| > | |
| Bullet list | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleOrderedList().run()} | |
| class={editor.isActive("orderedList") ? "is-active" : ""} | |
| > | |
| Ordered list | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleCodeBlock().run()} | |
| class={editor.isActive("codeBlock") ? "is-active" : ""} | |
| > | |
| Code block | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().toggleBlockquote().run()} | |
| class={editor.isActive("blockquote") ? "is-active" : ""} | |
| > | |
| Blockquote | |
| </button> | |
| <button onclick={() => editor.chain().focus().setHorizontalRule().run()}> | |
| Horizontal rule | |
| </button> | |
| <button onclick={() => editor.chain().focus().setHardBreak().run()}>Hard break</button> | |
| <button | |
| onclick={() => editor.chain().focus().undo().run()} | |
| disabled={!editor.can().chain().focus().undo().run()} | |
| > | |
| Undo | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().redo().run()} | |
| disabled={!editor.can().chain().focus().redo().run()} | |
| > | |
| Redo | |
| </button> | |
| <button | |
| onclick={() => editor.chain().focus().setColor('#958DF1').run()} | |
| class={editor.isActive('textStyle', { color: '#958DF1' }) ? 'is-active' : ''} | |
| > | |
| Purple | |
| </button> | |
| </div> | |
| </div> | |
| {/if} | |
| <div bind:this={element}></div> | |
| <style> | |
| /* Basic editor styles */ | |
| :global{ | |
| .tiptap { | |
| --white: #FFF; | |
| --black: #2E2B29; | |
| --black-contrast: #110F0E; | |
| --gray-1: rgba(61, 37, 20, 0.05); | |
| --gray-2: rgba(61, 37, 20, 0.08); | |
| --gray-3: rgba(61, 37, 20, 0.12); | |
| --gray-4: rgba(53, 38, 28, 0.30); | |
| --gray-5: rgba(28, 25, 23, 0.60); | |
| --green: #22C55E; | |
| --purple: #6A00F5; | |
| --purple-contrast: #5800CC; | |
| --purple-light: rgba(88, 5, 255, 0.05); | |
| --yellow-contrast: #FACC15; | |
| --yellow: rgba(250, 204, 21, 0.4); | |
| --yellow-light: #FFFAE5; | |
| --red: #FF5C33; | |
| --red-light: #FFEBE5; | |
| --shadow: 0px 12px 33px 0px rgba(0, 0, 0, 0.06), 0px 3.618px 9.949px 0px rgba(0, 0, 0, 0.04); | |
| & :first-child { | |
| margin-top: 0; | |
| } | |
| /* List styles */ | |
| & ul, | |
| ol { | |
| padding: 0 1rem; | |
| margin: 1.25rem 1rem 1.25rem 0.4rem; | |
| & li p { | |
| margin-top: 0.25em; | |
| margin-bottom: 0.25em; | |
| } | |
| } | |
| /* Heading styles */ | |
| & h1, | |
| h2, | |
| h3, | |
| h4, | |
| h5, | |
| h6 { | |
| line-height: 1.1; | |
| margin-top: 2.5rem; | |
| text-wrap: pretty; | |
| } | |
| & h1, | |
| h2 { | |
| margin-top: 3.5rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| & h1 { | |
| font-size: 1.4rem; | |
| } | |
| & h2 { | |
| font-size: 1.2rem; | |
| } | |
| & h3 { | |
| font-size: 1.1rem; | |
| } | |
| & h4, | |
| h5, | |
| h6 { | |
| font-size: 1rem; | |
| } | |
| /* Code and preformatted text styles */ | |
| & code { | |
| background-color: var(--purple-light); | |
| border-radius: 0.4rem; | |
| color: var(--black-contrast); | |
| font-size: 0.85rem; | |
| padding: 0.25em 0.3em; | |
| } | |
| & pre { | |
| background: var(--black); | |
| border-radius: 0.5rem; | |
| color: var(--white); | |
| font-family: 'JetBrainsMono', monospace; | |
| margin: 1.5rem 0; | |
| padding: 0.75rem 1rem; | |
| & code { | |
| background: none; | |
| color: inherit; | |
| font-size: 0.8rem; | |
| padding: 0; | |
| } | |
| } | |
| & blockquote { | |
| border-left: 3px solid var(--gray-3); | |
| margin: 1.5rem 0; | |
| padding-left: 1rem; | |
| } | |
| & hr { | |
| border: none; | |
| border-top: 1px solid var(--gray-2); | |
| margin: 2rem 0; | |
| } | |
| } | |
| } | |
| </style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment