diff --git a/apps/docs/guides/global-drag-handle.mdx b/apps/docs/guides/global-drag-handle.mdx new file mode 100644 index 000000000..a1781cb9e --- /dev/null +++ b/apps/docs/guides/global-drag-handle.mdx @@ -0,0 +1,83 @@ +--- +title: "Global Drag Handle (New)" +description: "Drag and drop blocks across the editor" +--- + + + + + Install the extension with a package manager of your choice. + + ```NPM + $ npm i tiptap-extension-global-drag-handle + ``` + ```Yarn + $ yarn add tiptap-extension-global-drag-handle + ``` + + In order to enjoy all the advantages of a drag handle, it is recommended to install the auto joiner extension as well, which allows you to automatically join various nodes such as 2 lists that are next to each other. + + ```NPM + $ npm i tiptap-extension-auto-joiner + ``` + ```Yarn + $ yarn add tiptap-extension-auto-joiner + ``` + + + + + ```tsx + // extensions.ts + import GlobalDragHandle from 'tiptap-extension-global-drag-handle' + import AutoJoiner from 'tiptap-extension-auto-joiner' // optional + + export const defaultExtensions = [ + GlobalDragHandle, + AutoJoiner, // optional + // other extensions + ]; + + // editor.tsx + const Editor = () => { + return + } + ``` + + + + ```tsx + //extensions.ts + import GlobalDragHandle from 'tiptap-extension-global-drag-handle' + import AutoJoiner from 'tiptap-extension-auto-joiner' // optional + + export const defaultExtensions = [ + GlobalDragHandle.configure({ + dragHandleWidth: 20, // default + + // The scrollTreshold specifies how close the user must drag an element to the edge of the lower/upper screen for automatic + // scrolling to take place. For example, scrollTreshold = 100 means that scrolling starts automatically when the user drags an + // element to a position that is max. 99px away from the edge of the screen + // You can set this to 0 to prevent auto scrolling caused by this extension + scrollTreshold: 100 // default + }), + AutoJoiner.configure({ + elementsToJoin: ["bulletList", "orderedList"] // default + }), + // other extensions + ]; + + // editor.tsx + const Editor = () => { + return + } + ``` + + + + By default the drag handle is headless, which means it doesn't contain any css. If you want to apply styling to the drag handle, use the class "drag-handle" in your css file. + + Take a look at [this](https://github.com/steven-tey/novel/blob/main/apps/web/styles/prosemirror.css#L131) to see an example of drag handle styling. + + + diff --git a/apps/docs/mint.json b/apps/docs/mint.json index 35d9ae858..9a60e5998 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -51,7 +51,8 @@ ] }, "guides/ai-command", - "guides/image-upload" + "guides/image-upload", + "guides/global-drag-handle" ] }, { diff --git a/packages/headless/package.json b/packages/headless/package.json index 3618cb228..b656219f1 100644 --- a/packages/headless/package.json +++ b/packages/headless/package.json @@ -54,6 +54,8 @@ "@tiptap/react": "^2.1.7", "@tiptap/starter-kit": "^2.1.7", "@tiptap/suggestion": "^2.1.7", + "tiptap-extension-auto-joiner": "^0.1.1", + "tiptap-extension-global-drag-handle": "^0.1.2", "@types/node": "18.15.3", "cmdk": "^0.2.1", "jotai": "^2.6.4", diff --git a/packages/headless/src/extensions/drag-and-drop.tsx b/packages/headless/src/extensions/drag-and-drop.tsx deleted file mode 100644 index eedd90bc1..000000000 --- a/packages/headless/src/extensions/drag-and-drop.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import { Extension } from "@tiptap/core"; - -import { NodeSelection, Plugin } from "@tiptap/pm/state"; -// @ts-ignore -import { __serializeForClipboard, EditorView } from "@tiptap/pm/view"; - -export interface DragHandleOptions { - /** - * The width of the drag handle - */ - dragHandleWidth: number; -} -function absoluteRect(node: Element) { - const data = node.getBoundingClientRect(); - const modal = node.closest('[role="dialog"]'); - - if (modal && window.getComputedStyle(modal).transform !== "none") { - const modalRect = modal.getBoundingClientRect(); - - return { - top: data.top - modalRect.top, - left: data.left - modalRect.left, - width: data.width, - }; - } - - return { - top: data.top, - left: data.left, - width: data.width, - }; -} - -function nodeDOMAtCoords(coords: { x: number; y: number }) { - return document - .elementsFromPoint(coords.x, coords.y) - .find( - (elem: Element) => - elem.parentElement?.matches?.(".ProseMirror") || - elem.matches( - [ - "li", - "p:not(:first-child)", - "pre", - "blockquote", - "h1, h2, h3, h4, h5, h6", - ].join(", ") - ) - ); -} - -function nodePosAtDOM( - node: Element, - view: EditorView, - options: DragHandleOptions -) { - const boundingRect = node.getBoundingClientRect(); - - return view.posAtCoords({ - left: boundingRect.left + 50 + options.dragHandleWidth, - top: boundingRect.top + 1, - })?.inside; -} - -function DragHandle(options: DragHandleOptions) { - function handleDragStart(event: DragEvent, view: EditorView) { - view.focus(); - - if (!event.dataTransfer) return; - - const node = nodeDOMAtCoords({ - x: event.clientX + 50 + options.dragHandleWidth, - y: event.clientY, - }); - - if (!(node instanceof Element)) return; - - const nodePos = nodePosAtDOM(node, view, options); - if (nodePos == null || nodePos < 0) return; - - view.dispatch( - view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)) - ); - - const slice = view.state.selection.content(); - const { dom, text } = __serializeForClipboard(view, slice); - - event.dataTransfer.clearData(); - event.dataTransfer.setData("text/html", dom.innerHTML); - event.dataTransfer.setData("text/plain", text); - event.dataTransfer.effectAllowed = "copyMove"; - - event.dataTransfer.setDragImage(node, 0, 0); - - view.dragging = { slice, move: event.ctrlKey }; - } - - function handleClick(event: MouseEvent, view: EditorView) { - view.focus(); - - view.dom.classList.remove("dragging"); - - const node = nodeDOMAtCoords({ - x: event.clientX + 50 + options.dragHandleWidth, - y: event.clientY, - }); - - if (!(node instanceof Element)) return; - - const nodePos = nodePosAtDOM(node, view, options); - if (!nodePos) return; - - view.dispatch( - view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)) - ); - } - - let dragHandleElement: HTMLElement | null = null; - - function hideDragHandle() { - if (dragHandleElement) { - dragHandleElement.classList.add("hide"); - } - } - - function showDragHandle() { - if (dragHandleElement) { - dragHandleElement.classList.remove("hide"); - } - } - - return new Plugin({ - view: (view) => { - dragHandleElement = document.createElement("div"); - dragHandleElement.draggable = true; - dragHandleElement.dataset.dragHandle = ""; - dragHandleElement.classList.add("drag-handle"); - dragHandleElement.addEventListener("dragstart", (e) => { - handleDragStart(e, view); - }); - dragHandleElement.addEventListener("click", (e) => { - handleClick(e, view); - }); - - hideDragHandle(); - - view?.dom?.parentElement?.appendChild(dragHandleElement); - - return { - destroy: () => { - dragHandleElement?.remove?.(); - dragHandleElement = null; - }, - }; - }, - props: { - handleDOMEvents: { - mousemove: (view, event) => { - if (!view.editable) { - return; - } - - const node = nodeDOMAtCoords({ - x: event.clientX + 50 + options.dragHandleWidth, - y: event.clientY, - }); - - if (!(node instanceof Element) || node.matches("ul, ol")) { - hideDragHandle(); - return; - } - - const compStyle = window.getComputedStyle(node); - const lineHeight = parseInt(compStyle.lineHeight, 10); - const paddingTop = parseInt(compStyle.paddingTop, 10); - - const rect = absoluteRect(node); - - rect.top += (lineHeight - 24) / 2; - rect.top += paddingTop; - // Li markers - if (node.matches("ul:not([data-type=taskList]) li, ol li")) { - rect.left -= options.dragHandleWidth; - } - rect.width = options.dragHandleWidth; - - if (!dragHandleElement) return; - - dragHandleElement.style.left = `${rect.left - rect.width}px`; - dragHandleElement.style.top = `${rect.top}px`; - showDragHandle(); - }, - keydown: () => { - hideDragHandle(); - }, - mousewheel: () => { - hideDragHandle(); - }, - // dragging class is used for CSS - dragstart: (view) => { - view.dom.classList.add("dragging"); - }, - drop: (view) => { - view.dom.classList.remove("dragging"); - hideDragHandle(); - }, - dragend: (view) => { - view.dom.classList.remove("dragging"); - }, - }, - }, - }); -} - -const DragAndDrop = Extension.create({ - name: "dragAndDrop", - - addProseMirrorPlugins() { - return [ - DragHandle({ - dragHandleWidth: 24, - }), - ]; - }, -}); - -export default DragAndDrop; diff --git a/packages/headless/src/extensions/index.ts b/packages/headless/src/extensions/index.ts index 4a495a021..03f7885cf 100644 --- a/packages/headless/src/extensions/index.ts +++ b/packages/headless/src/extensions/index.ts @@ -13,8 +13,10 @@ import { Markdown } from "tiptap-markdown"; import Highlight from "@tiptap/extension-highlight"; import UpdatedImage from "./updated-image"; import CustomKeymap from "./custom-keymap"; -import DragAndDrop from "./drag-and-drop"; import { ImageResizer } from "./image-resizer"; +import GlobalDragHandle from "tiptap-extension-global-drag-handle"; +import AutoJoiner from "tiptap-extension-auto-joiner"; + const PlaceholderExtension = Placeholder.configure({ placeholder: ({ node }) => { if (node.type.name === "heading") { @@ -38,7 +40,10 @@ const simpleExtensions = [ transformCopiedText: true, }), CustomKeymap, - DragAndDrop, + GlobalDragHandle.configure({ + scrollTreshold: 0, + }), + AutoJoiner, ] as const; const Horizontal = HorizontalRule.extend({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ce59cea1..e16a7e601 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -64,10 +64,10 @@ importers: version: 0.2.4 ai: specifier: ^2.2.33 - version: 2.2.35(react@18.2.0)(solid-js@1.8.14)(svelte@4.2.10)(vue@3.4.19) + version: 2.2.35(react@18.2.0)(solid-js@1.8.16)(svelte@4.2.12)(vue@3.4.21) autoprefixer: specifier: ^10.4.17 - version: 10.4.17(postcss@8.4.35) + version: 10.4.17(postcss@8.4.38) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -143,7 +143,7 @@ importers: version: 18.2.19 prettier-plugin-tailwindcss: specifier: ^0.3.0 - version: 0.3.0(prettier@2.8.8) + version: 0.3.0(prettier@3.2.5) tailwindcss: specifier: ^3.4.1 version: 3.4.1 @@ -225,6 +225,12 @@ importers: tippy.js: specifier: ^6.3.7 version: 6.3.7 + tiptap-extension-auto-joiner: + specifier: ^0.1.1 + version: 0.1.1 + tiptap-extension-global-drag-handle: + specifier: ^0.1.2 + version: 0.1.2 tiptap-markdown: specifier: ^0.8.9 version: 0.8.9(@tiptap/core@2.2.2) @@ -261,12 +267,12 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - /@ampproject/remapping@2.2.1: - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 dev: false /@babel/code-frame@7.23.5: @@ -277,8 +283,8 @@ packages: chalk: 2.4.2 dev: false - /@babel/helper-string-parser@7.23.4: - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + /@babel/helper-string-parser@7.24.1: + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} dev: false @@ -296,12 +302,12 @@ packages: js-tokens: 4.0.0 dev: false - /@babel/parser@7.23.9: - resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + /@babel/parser@7.24.1: + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: false /@babel/runtime@7.23.9: @@ -311,11 +317,11 @@ packages: regenerator-runtime: 0.14.1 dev: false - /@babel/types@7.23.9: - resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} + /@babel/types@7.24.0: + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.23.4 + '@babel/helper-string-parser': 7.24.1 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 dev: false @@ -902,14 +908,33 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.22 + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + dev: false + /@jridgewell/resolve-uri@3.1.1: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: false + /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + dev: false + /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} @@ -919,6 +944,13 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: @@ -2610,77 +2642,77 @@ packages: '@upstash/redis': 1.24.3 dev: false - /@vue/compiler-core@3.4.19: - resolution: {integrity: sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==} + /@vue/compiler-core@3.4.21: + resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==} dependencies: - '@babel/parser': 7.23.9 - '@vue/shared': 3.4.19 + '@babel/parser': 7.24.1 + '@vue/shared': 3.4.21 entities: 4.5.0 estree-walker: 2.0.2 - source-map-js: 1.0.2 + source-map-js: 1.2.0 dev: false - /@vue/compiler-dom@3.4.19: - resolution: {integrity: sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==} + /@vue/compiler-dom@3.4.21: + resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==} dependencies: - '@vue/compiler-core': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/compiler-core': 3.4.21 + '@vue/shared': 3.4.21 dev: false - /@vue/compiler-sfc@3.4.19: - resolution: {integrity: sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==} + /@vue/compiler-sfc@3.4.21: + resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==} dependencies: - '@babel/parser': 7.23.9 - '@vue/compiler-core': 3.4.19 - '@vue/compiler-dom': 3.4.19 - '@vue/compiler-ssr': 3.4.19 - '@vue/shared': 3.4.19 + '@babel/parser': 7.24.1 + '@vue/compiler-core': 3.4.21 + '@vue/compiler-dom': 3.4.21 + '@vue/compiler-ssr': 3.4.21 + '@vue/shared': 3.4.21 estree-walker: 2.0.2 - magic-string: 0.30.7 - postcss: 8.4.35 - source-map-js: 1.0.2 + magic-string: 0.30.8 + postcss: 8.4.38 + source-map-js: 1.2.0 dev: false - /@vue/compiler-ssr@3.4.19: - resolution: {integrity: sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==} + /@vue/compiler-ssr@3.4.21: + resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==} dependencies: - '@vue/compiler-dom': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/compiler-dom': 3.4.21 + '@vue/shared': 3.4.21 dev: false - /@vue/reactivity@3.4.19: - resolution: {integrity: sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==} + /@vue/reactivity@3.4.21: + resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==} dependencies: - '@vue/shared': 3.4.19 + '@vue/shared': 3.4.21 dev: false - /@vue/runtime-core@3.4.19: - resolution: {integrity: sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==} + /@vue/runtime-core@3.4.21: + resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==} dependencies: - '@vue/reactivity': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/reactivity': 3.4.21 + '@vue/shared': 3.4.21 dev: false - /@vue/runtime-dom@3.4.19: - resolution: {integrity: sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==} + /@vue/runtime-dom@3.4.21: + resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==} dependencies: - '@vue/runtime-core': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/runtime-core': 3.4.21 + '@vue/shared': 3.4.21 csstype: 3.1.3 dev: false - /@vue/server-renderer@3.4.19(vue@3.4.19): - resolution: {integrity: sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==} + /@vue/server-renderer@3.4.21(vue@3.4.21): + resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==} peerDependencies: - vue: 3.4.19 + vue: 3.4.21 dependencies: - '@vue/compiler-ssr': 3.4.19 - '@vue/shared': 3.4.19 - vue: 3.4.19(typescript@5.3.3) + '@vue/compiler-ssr': 3.4.21 + '@vue/shared': 3.4.21 + vue: 3.4.21(typescript@5.3.3) dev: false - /@vue/shared@3.4.19: - resolution: {integrity: sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==} + /@vue/shared@3.4.21: + resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==} dev: false /abab@2.0.6: @@ -2737,7 +2769,7 @@ packages: humanize-ms: 1.2.1 dev: false - /ai@2.2.35(react@18.2.0)(solid-js@1.8.14)(svelte@4.2.10)(vue@3.4.19): + /ai@2.2.35(react@18.2.0)(solid-js@1.8.16)(svelte@4.2.12)(vue@3.4.21): resolution: {integrity: sha512-YzR56VAMjqvGIVzMUFwH7jjo7K+Z3Old4nXcigiWsuqXnWQeQi3iPR8p2/xOZzmuZyMTOC+6jjbIJ8hoEOhfcQ==} engines: {node: '>=14.6'} peerDependencies: @@ -2758,14 +2790,14 @@ packages: eventsource-parser: 1.0.0 nanoid: 3.3.6 react: 18.2.0 - solid-js: 1.8.14 - solid-swr-store: 0.10.7(solid-js@1.8.14)(swr-store@0.10.6) - sswr: 2.0.0(svelte@4.2.10) - svelte: 4.2.10 + solid-js: 1.8.16 + solid-swr-store: 0.10.7(solid-js@1.8.16)(swr-store@0.10.6) + sswr: 2.0.0(svelte@4.2.12) + svelte: 4.2.12 swr: 2.2.0(react@18.2.0) swr-store: 0.10.6 - swrv: 1.0.4(vue@3.4.19) - vue: 3.4.19(typescript@5.3.3) + swrv: 1.0.4(vue@3.4.21) + vue: 3.4.21(typescript@5.3.3) dev: false /ajv@6.12.6: @@ -2956,7 +2988,7 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /autoprefixer@10.4.17(postcss@8.4.35): + /autoprefixer@10.4.17(postcss@8.4.38): resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -2968,7 +3000,7 @@ packages: fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.35 + postcss: 8.4.38 postcss-value-parser: 4.2.0 dev: false @@ -3313,7 +3345,7 @@ packages: engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} dependencies: mdn-data: 2.0.30 - source-map-js: 1.0.2 + source-map-js: 1.2.0 dev: false /cssesc@3.0.0: @@ -5148,8 +5180,8 @@ packages: react: 18.2.0 dev: false - /magic-string@0.30.7: - resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} + /magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -6017,6 +6049,15 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: false + /preferred-pm@3.1.3: resolution: {integrity: sha512-MkXsENfftWSRpzCzImcp4FRsCc3y1opwB73CfCNWyzMqArju2CrlMHlqB7VexKiPEOjGMbttv1r9fSCn5S610w==} engines: {node: '>=10'} @@ -6032,7 +6073,7 @@ packages: engines: {node: '>= 0.8.0'} dev: false - /prettier-plugin-tailwindcss@0.3.0(prettier@2.8.8): + /prettier-plugin-tailwindcss@0.3.0(prettier@3.2.5): resolution: {integrity: sha512-009/Xqdy7UmkcTBpwlq7jsViDqXAYSOMLDrHAdTMlVZOrKfM2o9Ci7EMWTMZ7SkKBFTG04UM9F9iM2+4i6boDA==} engines: {node: '>=12.17.0'} peerDependencies: @@ -6084,7 +6125,7 @@ packages: prettier-plugin-twig-melody: optional: true dependencies: - prettier: 2.8.8 + prettier: 3.2.5 dev: true /prettier@2.8.8: @@ -6092,6 +6133,12 @@ packages: engines: {node: '>=10.13.0'} hasBin: true + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + dev: true + /pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6695,17 +6742,17 @@ packages: lru-cache: 6.0.0 dev: false - /seroval-plugins@1.0.4(seroval@1.0.4): - resolution: {integrity: sha512-DQ2IK6oQVvy8k+c2V5x5YCtUa/GGGsUwUBNN9UqohrZ0rWdUapBFpNMYP1bCyRHoxOJjdKGl+dieacFIpU/i1A==} + /seroval-plugins@1.0.5(seroval@1.0.5): + resolution: {integrity: sha512-8+pDC1vOedPXjKG7oz8o+iiHrtF2WswaMQJ7CKFpccvSYfrzmvKY9zOJWCg+881722wIHfwkdnRmiiDm9ym+zQ==} engines: {node: '>=10'} peerDependencies: seroval: ^1.0 dependencies: - seroval: 1.0.4 + seroval: 1.0.5 dev: false - /seroval@1.0.4: - resolution: {integrity: sha512-qQs/N+KfJu83rmszFQaTxcoJoPn6KNUruX4KmnmyD0oZkUoiNvJ1rpdYKDf4YHM05k+HOgCxa3yvf15QbVijGg==} + /seroval@1.0.5: + resolution: {integrity: sha512-TM+Z11tHHvQVQKeNlOUonOWnsNM+2IBwZ4vwoi4j3zKzIpc5IDw8WPwCfcc8F17wy6cBcJGbZbFOR0UCuTZHQA==} engines: {node: '>=10'} dev: false @@ -6794,22 +6841,22 @@ packages: yargs: 15.4.1 dev: false - /solid-js@1.8.14: - resolution: {integrity: sha512-kDfgHBm+ROVLDVuqaXh/jYz0ZVJ29TYfVsKsgDPtNcjoyaPtOvDX2l0tVnthjLdEXr7vDTYeqEYFfMkZakDsOQ==} + /solid-js@1.8.16: + resolution: {integrity: sha512-rja94MNU9flF3qQRLNsu60QHKBDKBkVE1DldJZPIfn2ypIn3NV2WpSbGTQIvsyGPBo+9E2IMjwqnqpbgfWuzeg==} dependencies: csstype: 3.1.3 - seroval: 1.0.4 - seroval-plugins: 1.0.4(seroval@1.0.4) + seroval: 1.0.5 + seroval-plugins: 1.0.5(seroval@1.0.5) dev: false - /solid-swr-store@0.10.7(solid-js@1.8.14)(swr-store@0.10.6): + /solid-swr-store@0.10.7(solid-js@1.8.16)(swr-store@0.10.6): resolution: {integrity: sha512-A6d68aJmRP471aWqKKPE2tpgOiR5fH4qXQNfKIec+Vap+MGQm3tvXlT8n0I8UgJSlNAsSAUuw2VTviH2h3Vv5g==} engines: {node: '>=10'} peerDependencies: solid-js: ^1.2 swr-store: ^0.10 dependencies: - solid-js: 1.8.14 + solid-js: 1.8.16 swr-store: 0.10.6 dev: false @@ -6827,6 +6874,11 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + dev: false + /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -6878,12 +6930,12 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: false - /sswr@2.0.0(svelte@4.2.10): + /sswr@2.0.0(svelte@4.2.12): resolution: {integrity: sha512-mV0kkeBHcjcb0M5NqKtKVg/uTIYNlIIniyDfSGrSfxpEdM9C365jK0z55pl9K0xAkNTJi2OAOVFQpgMPUk+V0w==} peerDependencies: svelte: ^4.0.0 dependencies: - svelte: 4.2.10 + svelte: 4.2.12 swrev: 4.0.0 dev: false @@ -7048,13 +7100,13 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /svelte@4.2.10: - resolution: {integrity: sha512-Ep06yCaCdgG1Mafb/Rx8sJ1QS3RW2I2BxGp2Ui9LBHSZ2/tO/aGLc5WqPjgiAP6KAnLJGaIr/zzwQlOo1b8MxA==} + /svelte@4.2.12: + resolution: {integrity: sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==} engines: {node: '>=16'} dependencies: - '@ampproject/remapping': 2.2.1 + '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/trace-mapping': 0.3.25 '@types/estree': 1.0.5 acorn: 8.11.3 aria-query: 5.3.0 @@ -7064,7 +7116,7 @@ packages: estree-walker: 3.0.3 is-reference: 3.0.2 locate-character: 3.0.0 - magic-string: 0.30.7 + magic-string: 0.30.8 periscopic: 3.1.0 dev: false @@ -7088,12 +7140,12 @@ packages: resolution: {integrity: sha512-LqVcOHSB4cPGgitD1riJ1Hh4vdmITOp+BkmfmXRh4hSF/t7EnS4iD+SOTmq7w5pPm/SiPeto4ADbKS6dHUDWFA==} dev: false - /swrv@1.0.4(vue@3.4.19): + /swrv@1.0.4(vue@3.4.21): resolution: {integrity: sha512-zjEkcP8Ywmj+xOJW3lIT65ciY/4AL4e/Or7Gj0MzU3zBJNMdJiT8geVZhINavnlHRMMCcJLHhraLTAiDOTmQ9g==} peerDependencies: vue: '>=3.2.26 < 4' dependencies: - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false /symbol-tree@3.2.4: @@ -7178,6 +7230,14 @@ packages: '@popperjs/core': 2.11.8 dev: false + /tiptap-extension-auto-joiner@0.1.1: + resolution: {integrity: sha512-n38N7qWUL3Iz6XdwxZLacSuE1itIAp6lzcVUYgi0K/d/eLydgFl07ZixBJ6XHCDESjw4wrRgRQQE9nvMGvn3QA==} + dev: false + + /tiptap-extension-global-drag-handle@0.1.2: + resolution: {integrity: sha512-QrLIyVEbCKFFyz8RSaa4TjBbYKrmZ+Fl69GkgH2nrj8EE7pOkQkYXqaS7ommfnGMiZspcuwdp9n73oJ29wDKpA==} + dev: false + /tiptap-markdown@0.8.9(@tiptap/core@2.2.2): resolution: {integrity: sha512-TykSDcsb94VFCzPbSSTfB6Kh2HJi7x4B9J3Jm9uSOAMPy8App1YfrLW/rEJLajTxwMVhWBdOo4nidComSlLQsQ==} peerDependencies: @@ -7683,19 +7743,19 @@ packages: vfile-message: 3.1.4 dev: false - /vue@3.4.19(typescript@5.3.3): - resolution: {integrity: sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==} + /vue@3.4.21(typescript@5.3.3): + resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.4.19 - '@vue/compiler-sfc': 3.4.19 - '@vue/runtime-dom': 3.4.19 - '@vue/server-renderer': 3.4.19(vue@3.4.19) - '@vue/shared': 3.4.19 + '@vue/compiler-dom': 3.4.21 + '@vue/compiler-sfc': 3.4.21 + '@vue/runtime-dom': 3.4.21 + '@vue/server-renderer': 3.4.21(vue@3.4.21) + '@vue/shared': 3.4.21 typescript: 5.3.3 dev: false