diff --git a/demos/src/Examples/Default/React/index.spec.js b/demos/src/Examples/Default/React/index.spec.js index 005560dee..d78f4ba34 100644 --- a/demos/src/Examples/Default/React/index.spec.js +++ b/demos/src/Examples/Default/React/index.spec.js @@ -12,7 +12,6 @@ context('/src/Examples/Default/React/', () => { it('should apply the paragraph style when the keyboard shortcut is pressed', () => { cy.get('.tiptap h1').should('exist') - cy.get('.tiptap p').should('not.exist') cy.get('.tiptap') .trigger('keydown', { modKey: true, altKey: true, key: '0' }) @@ -79,7 +78,7 @@ context('/src/Examples/Default/React/', () => { cy.get('.tiptap').type('{enter}A second item{enter}A third item{selectall}') cy.get('button').contains('Clear nodes').click() cy.get('.tiptap ul').should('not.exist') - cy.get('.tiptap p').should('have.length', 3) + cy.get('.tiptap p').should('have.length', 4) }) const buttonNodes = [ @@ -124,20 +123,20 @@ context('/src/Examples/Default/React/', () => { it('should add a br', () => { cy.get('.tiptap').type('{rightArrow}') cy.get('button').contains('Hard break').click() - cy.get('.tiptap h1 br').should('exist') + cy.get('.tiptap br').should('exist') }) it('should undo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') }) it('should redo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') cy.get('button').contains('Redo').click() - cy.get('.tiptap').should('not.contain', 'Hello world') + cy.get('.tiptap').should('not.contain', 'Example Text') }) }) diff --git a/demos/src/Examples/Default/Svelte/index.spec.js b/demos/src/Examples/Default/Svelte/index.spec.js index dc0e1c0a5..45bee0132 100644 --- a/demos/src/Examples/Default/Svelte/index.spec.js +++ b/demos/src/Examples/Default/Svelte/index.spec.js @@ -12,7 +12,6 @@ context('/src/Examples/Default/React/', () => { it('should apply the paragraph style when the keyboard shortcut is pressed', () => { cy.get('.tiptap h1').should('exist') - cy.get('.tiptap p').should('not.exist') cy.get('.tiptap') .trigger('keydown', { modKey: true, altKey: true, key: '0' }) @@ -53,7 +52,7 @@ context('/src/Examples/Default/React/', () => { cy.get('.tiptap').type('{enter}A second item{enter}A third item{selectall}') cy.get('button').contains('Clear nodes').click() cy.get('.tiptap ul').should('not.exist') - cy.get('.tiptap p').should('have.length', 3) + cy.get('.tiptap p').should('have.length', 4) }) const buttonNodes = [ @@ -98,20 +97,20 @@ context('/src/Examples/Default/React/', () => { it('should add a br', () => { cy.get('.tiptap').type('{rightArrow}') cy.get('button').contains('Hard break').click() - cy.get('.tiptap h1 br').should('exist') + cy.get('.tiptap br').should('exist') }) it('should undo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') }) it('should redo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') cy.get('button').contains('Redo').click() - cy.get('.tiptap').should('not.contain', 'Hello world') + cy.get('.tiptap').should('not.contain', 'Example Text') }) }) diff --git a/demos/src/Examples/Default/Vue/index.spec.js b/demos/src/Examples/Default/Vue/index.spec.js index c777d2660..8dd31af4f 100644 --- a/demos/src/Examples/Default/Vue/index.spec.js +++ b/demos/src/Examples/Default/Vue/index.spec.js @@ -12,7 +12,6 @@ context('/src/Examples/Default/Vue/', () => { it('should apply the paragraph style when the keyboard shortcut is pressed', () => { cy.get('.tiptap h1').should('exist') - cy.get('.tiptap p').should('not.exist') cy.get('.tiptap') .trigger('keydown', { modKey: true, altKey: true, key: '0' }) @@ -53,7 +52,7 @@ context('/src/Examples/Default/Vue/', () => { cy.get('.tiptap').type('{enter}A second item{enter}A third item{selectall}') cy.get('button').contains('Clear nodes').click() cy.get('.tiptap ul').should('not.exist') - cy.get('.tiptap p').should('have.length', 3) + cy.get('.tiptap p').should('have.length', 4) }) const buttonNodes = [ @@ -98,20 +97,20 @@ context('/src/Examples/Default/Vue/', () => { it('should add a br', () => { cy.get('.tiptap').type('{rightArrow}') cy.get('button').contains('Hard break').click() - cy.get('.tiptap h1 br').should('exist') + cy.get('.tiptap br').should('exist') }) it('should undo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') }) it('should redo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') cy.get('button').contains('Redo').click() - cy.get('.tiptap').should('not.contain', 'Hello world') + cy.get('.tiptap').should('not.contain', 'Example Text') }) }) diff --git a/demos/src/Examples/NodePos/React/index.jsx b/demos/src/Examples/NodePos/React/index.jsx index 358f9eae0..3bf7d05b5 100644 --- a/demos/src/Examples/NodePos/React/index.jsx +++ b/demos/src/Examples/NodePos/React/index.jsx @@ -10,7 +10,9 @@ const mapNodePosToString = nodePos => `[${nodePos.node.type.name} ${nodePos.rang export default () => { const editor = useEditor({ extensions: [ - StarterKit, + StarterKit.configure({ + trailingNode: false, + }), Image, ], content: ` diff --git a/demos/src/Experiments/IsolatingClear/React/index.spec.js b/demos/src/Experiments/IsolatingClear/React/index.spec.js index 005560dee..d78f4ba34 100644 --- a/demos/src/Experiments/IsolatingClear/React/index.spec.js +++ b/demos/src/Experiments/IsolatingClear/React/index.spec.js @@ -12,7 +12,6 @@ context('/src/Examples/Default/React/', () => { it('should apply the paragraph style when the keyboard shortcut is pressed', () => { cy.get('.tiptap h1').should('exist') - cy.get('.tiptap p').should('not.exist') cy.get('.tiptap') .trigger('keydown', { modKey: true, altKey: true, key: '0' }) @@ -79,7 +78,7 @@ context('/src/Examples/Default/React/', () => { cy.get('.tiptap').type('{enter}A second item{enter}A third item{selectall}') cy.get('button').contains('Clear nodes').click() cy.get('.tiptap ul').should('not.exist') - cy.get('.tiptap p').should('have.length', 3) + cy.get('.tiptap p').should('have.length', 4) }) const buttonNodes = [ @@ -124,20 +123,20 @@ context('/src/Examples/Default/React/', () => { it('should add a br', () => { cy.get('.tiptap').type('{rightArrow}') cy.get('button').contains('Hard break').click() - cy.get('.tiptap h1 br').should('exist') + cy.get('.tiptap br').should('exist') }) it('should undo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') }) it('should redo', () => { cy.get('.tiptap').type('{selectall}{backspace}') cy.get('button').contains('Undo').click() - cy.get('.tiptap').should('contain', 'Hello world') + cy.get('.tiptap').should('contain', 'Example Text') cy.get('button').contains('Redo').click() - cy.get('.tiptap').should('not.contain', 'Hello world') + cy.get('.tiptap').should('not.contain', 'Example Text') }) }) diff --git a/package-lock.json b/package-lock.json index 15864cdbc..9aa5442a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5144,6 +5144,10 @@ "resolved": "packages/extension-underline", "link": true }, + "node_modules/@tiptap/extension-utils": { + "resolved": "packages/extension-utils", + "link": true + }, "node_modules/@tiptap/extension-youtube": { "resolved": "packages/extension-youtube", "link": true @@ -19213,16 +19217,14 @@ "version": "3.0.0-next.3", "license": "MIT", "devDependencies": { - "@tiptap/core": "^3.0.0-next.3", - "@tiptap/pm": "^3.0.0-next.3" + "@tiptap/extension-utils": "^3.0.0-next.3" }, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.0.0-next.1", - "@tiptap/pm": "^3.0.0-next.1" + "@tiptap/extension-utils": "^3.0.0-next.3" } }, "packages/extension-floating-menu": { @@ -19249,16 +19251,14 @@ "version": "3.0.0-next.3", "license": "MIT", "devDependencies": { - "@tiptap/core": "^3.0.0-next.3", - "@tiptap/pm": "^3.0.0-next.3" + "@tiptap/extension-utils": "3.0.0-next.3" }, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.0.0-next.1", - "@tiptap/pm": "^3.0.0-next.1" + "@tiptap/extension-utils": "3.0.0-next.3" } }, "packages/extension-font-family": { @@ -19283,16 +19283,14 @@ "version": "3.0.0-next.3", "license": "MIT", "devDependencies": { - "@tiptap/core": "^3.0.0-next.3", - "@tiptap/pm": "^3.0.0-next.3" + "@tiptap/extension-utils": "^3.0.0-next.3" }, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.0.0-next.1", - "@tiptap/pm": "^3.0.0-next.1" + "@tiptap/extension-utils": "^3.0.0-next.3" } }, "packages/extension-hard-break": { @@ -19734,6 +19732,23 @@ "@tiptap/core": "^3.0.0-next.1" } }, + "packages/extension-utils": { + "name": "@tiptap/extension-utils", + "version": "3.0.0-next.3", + "license": "MIT", + "devDependencies": { + "@tiptap/core": "^3.0.0-next.3", + "@tiptap/pm": "^3.0.0-next.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.0.0-next.3", + "@tiptap/pm": "^3.0.0-next.3" + } + }, "packages/extension-youtube": { "name": "@tiptap/extension-youtube", "version": "3.0.0-next.3", @@ -19855,6 +19870,7 @@ "@tiptap/extension-strike": "^3.0.0-next.3", "@tiptap/extension-text": "^3.0.0-next.3", "@tiptap/extension-underline": "^3.0.0-next.3", + "@tiptap/extension-utils": "^3.0.0-next.3", "@tiptap/pm": "^3.0.0-next.3" }, "funding": { diff --git a/packages/extension-dropcursor/package.json b/packages/extension-dropcursor/package.json index e1d531ffb..cbabef3e3 100644 --- a/packages/extension-dropcursor/package.json +++ b/packages/extension-dropcursor/package.json @@ -28,12 +28,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^3.0.0-next.3", - "@tiptap/pm": "^3.0.0-next.3" + "@tiptap/extension-utils": "^3.0.0-next.3" }, "peerDependencies": { - "@tiptap/core": "^3.0.0-next.1", - "@tiptap/pm": "^3.0.0-next.1" + "@tiptap/extension-utils": "^3.0.0-next.3" }, "repository": { "type": "git", diff --git a/packages/extension-dropcursor/src/index.ts b/packages/extension-dropcursor/src/index.ts index dcbb962f9..2fc6d31c8 100644 --- a/packages/extension-dropcursor/src/index.ts +++ b/packages/extension-dropcursor/src/index.ts @@ -1,5 +1,5 @@ -import { Dropcursor } from './dropcursor.js' +import { Dropcursor } from '@tiptap/extension-utils' -export * from './dropcursor.js' +export { Dropcursor, DropcursorOptions } from '@tiptap/extension-utils' export default Dropcursor diff --git a/packages/extension-focus/package.json b/packages/extension-focus/package.json index cf6ad1bcc..c5100ad39 100644 --- a/packages/extension-focus/package.json +++ b/packages/extension-focus/package.json @@ -28,12 +28,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^3.0.0-next.3", - "@tiptap/pm": "^3.0.0-next.3" + "@tiptap/extension-utils": "3.0.0-next.3" }, "peerDependencies": { - "@tiptap/core": "^3.0.0-next.1", - "@tiptap/pm": "^3.0.0-next.1" + "@tiptap/extension-utils": "3.0.0-next.3" }, "repository": { "type": "git", diff --git a/packages/extension-focus/src/index.ts b/packages/extension-focus/src/index.ts index a1dfee566..41bacfb32 100644 --- a/packages/extension-focus/src/index.ts +++ b/packages/extension-focus/src/index.ts @@ -1,5 +1,5 @@ -import { FocusClasses } from './focus.js' +import { Focus } from '@tiptap/extension-utils' -export * from './focus.js' +export { Focus, FocusOptions } from '@tiptap/extension-utils' -export default FocusClasses +export default Focus diff --git a/packages/extension-gapcursor/package.json b/packages/extension-gapcursor/package.json index 5c0cb057c..0e786bc3e 100644 --- a/packages/extension-gapcursor/package.json +++ b/packages/extension-gapcursor/package.json @@ -28,12 +28,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^3.0.0-next.3", - "@tiptap/pm": "^3.0.0-next.3" + "@tiptap/extension-utils": "^3.0.0-next.3" }, "peerDependencies": { - "@tiptap/core": "^3.0.0-next.1", - "@tiptap/pm": "^3.0.0-next.1" + "@tiptap/extension-utils": "^3.0.0-next.3" }, "repository": { "type": "git", diff --git a/packages/extension-gapcursor/src/index.ts b/packages/extension-gapcursor/src/index.ts index 352b84713..372da023e 100644 --- a/packages/extension-gapcursor/src/index.ts +++ b/packages/extension-gapcursor/src/index.ts @@ -1,5 +1,5 @@ -import { Gapcursor } from './gapcursor.js' +import { Gapcursor } from '@tiptap/extension-utils' -export * from './gapcursor.js' +export { Gapcursor } from '@tiptap/extension-utils' export default Gapcursor diff --git a/packages/extension-utils/CHANGELOG.md b/packages/extension-utils/CHANGELOG.md new file mode 100644 index 000000000..293c5681a --- /dev/null +++ b/packages/extension-utils/CHANGELOG.md @@ -0,0 +1,2 @@ +# Change Log + diff --git a/packages/extension-utils/README.md b/packages/extension-utils/README.md new file mode 100644 index 000000000..ca8cb8479 --- /dev/null +++ b/packages/extension-utils/README.md @@ -0,0 +1,18 @@ +# @tiptap/extension-utils + +[![Version](https://img.shields.io/npm/v/@tiptap/extension-focus.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-focus) +[![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-focus.svg)](https://npmcharts.com/compare/tiptap?minimal=true) +[![License](https://img.shields.io/npm/l/@tiptap/extension-focus.svg)](https://www.npmjs.com/package/@tiptap/extension-focus) +[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis) + +## Introduction + +Tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. + +## Official Documentation + +Documentation can be found on the [Tiptap website](https://tiptap.dev). + +## License + +Tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md). diff --git a/packages/extension-utils/package.json b/packages/extension-utils/package.json new file mode 100644 index 000000000..73fb46b9f --- /dev/null +++ b/packages/extension-utils/package.json @@ -0,0 +1,46 @@ +{ + "name": "@tiptap/extension-utils", + "description": "various utils extension for tiptap", + "version": "3.0.0-next.3", + "homepage": "https://tiptap.dev", + "keywords": [ + "tiptap", + "tiptap extension" + ], + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + } + }, + "main": "dist/index.cjs", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "src", + "dist" + ], + "devDependencies": { + "@tiptap/core": "^3.0.0-next.3", + "@tiptap/pm": "^3.0.0-next.3" + }, + "peerDependencies": { + "@tiptap/core": "^3.0.0-next.3", + "@tiptap/pm": "^3.0.0-next.3" + }, + "repository": { + "type": "git", + "url": "https://github.com/ueberdosis/tiptap", + "directory": "packages/extension-utils" + }, + "scripts": { + "build": "tsup" + } +} diff --git a/packages/extension-dropcursor/src/dropcursor.ts b/packages/extension-utils/src/drop-cursor.ts similarity index 97% rename from packages/extension-dropcursor/src/dropcursor.ts rename to packages/extension-utils/src/drop-cursor.ts index 7a8358ee0..8f6050284 100644 --- a/packages/extension-dropcursor/src/dropcursor.ts +++ b/packages/extension-utils/src/drop-cursor.ts @@ -27,7 +27,7 @@ export interface DropcursorOptions { /** * This extension allows you to add a drop cursor to your editor. * A drop cursor is a line that appears when you drag and drop content - * inbetween nodes. + * in-between nodes. * @see https://tiptap.dev/api/extensions/dropcursor */ export const Dropcursor = Extension.create({ diff --git a/packages/extension-focus/src/focus.ts b/packages/extension-utils/src/focus.ts similarity index 97% rename from packages/extension-focus/src/focus.ts rename to packages/extension-utils/src/focus.ts index 12c8a51ba..5810b7557 100644 --- a/packages/extension-focus/src/focus.ts +++ b/packages/extension-utils/src/focus.ts @@ -27,7 +27,7 @@ export interface FocusOptions { * This extension allows you to add a class to the focused node. * @see https://www.tiptap.dev/api/extensions/focus */ -export const FocusClasses = Extension.create({ +export const Focus = Extension.create({ name: 'focus', addOptions() { diff --git a/packages/extension-gapcursor/src/gapcursor.ts b/packages/extension-utils/src/gap-cursor.ts similarity index 100% rename from packages/extension-gapcursor/src/gapcursor.ts rename to packages/extension-utils/src/gap-cursor.ts diff --git a/packages/extension-utils/src/index.ts b/packages/extension-utils/src/index.ts new file mode 100644 index 000000000..77f355294 --- /dev/null +++ b/packages/extension-utils/src/index.ts @@ -0,0 +1,5 @@ +export * from './drop-cursor.js' +export * from './focus.js' +export * from './gap-cursor.js' +export * from './selection.js' +export * from './trailing-node.js' diff --git a/packages/extension-utils/src/selection.ts b/packages/extension-utils/src/selection.ts new file mode 100644 index 000000000..f5ff2375e --- /dev/null +++ b/packages/extension-utils/src/selection.ts @@ -0,0 +1,51 @@ +import { Extension } from '@tiptap/core' +import { Plugin, PluginKey } from '@tiptap/pm/state' +import { Decoration, DecorationSet } from '@tiptap/pm/view' + +export type SelectionOptions = { + /** + * The class name that should be added to the selected text. + * @default 'selection' + * @example 'is-selected' + */ + className: string +} + +/** + * This extension allows you to add a class to the selected text. + * @see https://www.tiptap.dev/api/extensions/selection + */ +export const Selection = Extension.create({ + name: 'selection', + + addOptions() { + return { + className: 'selection', + } + }, + + addProseMirrorPlugins() { + const { editor, options } = this + + return [ + new Plugin({ + key: new PluginKey('selection'), + props: { + decorations(state) { + if (state.selection.empty || editor.isFocused) { + return null + } + + return DecorationSet.create(state.doc, [ + Decoration.inline(state.selection.from, state.selection.to, { + class: options.className, + }), + ]) + }, + }, + }), + ] + }, +}) + +export default Selection diff --git a/packages/extension-utils/src/trailing-node.ts b/packages/extension-utils/src/trailing-node.ts new file mode 100644 index 000000000..51732cbfa --- /dev/null +++ b/packages/extension-utils/src/trailing-node.ts @@ -0,0 +1,84 @@ +import { Extension } from '@tiptap/core' +import { Node, NodeType } from '@tiptap/pm/model' +import { Plugin, PluginKey } from '@tiptap/pm/state' + +function nodeEqualsType({ types, node }: { types: NodeType | NodeType[]; node: Node | null | undefined }) { + return (node && Array.isArray(types) && types.includes(node.type)) || node?.type === types +} + +/** + * Extension based on: + * - https://github.com/ueberdosis/tiptap/blob/v1/packages/tiptap-extensions/src/extensions/TrailingNode.js + * - https://github.com/remirror/remirror/blob/e0f1bec4a1e8073ce8f5500d62193e52321155b9/packages/prosemirror-trailing-node/src/trailing-node-plugin.ts + */ + +export interface TrailingNodeOptions { + /** + * The node type that should be inserted at the end of the document. + * @note the node will always be added to the `notAfter` lists to + * prevent an infinite loop. + * @default 'paragraph' + */ + node: string; + /** + * The node types after which the trailing node should not be inserted. + * @default ['paragraph'] + */ + notAfter?: string | string[]; +} + +/** + * This extension allows you to add an extra node at the end of the document. + * @see https://www.tiptap.dev/api/extensions/trailing-node + */ +export const TrailingNode = Extension.create({ + name: 'trailingNode', + + addOptions() { + return { + node: 'paragraph', + notAfter: [], + } + }, + + addProseMirrorPlugins() { + const plugin = new PluginKey(this.name) + const disabledNodes = Object.entries(this.editor.schema.nodes) + .map(([, value]) => value) + .filter(node => (this.options.notAfter || []).concat(this.options.node).includes(node.name)) + + return [ + new Plugin({ + key: plugin, + appendTransaction: (_, __, state) => { + const { doc, tr, schema } = state + const shouldInsertNodeAtEnd = plugin.getState(state) + const endPosition = doc.content.size + const type = schema.nodes[this.options.node] + + if (!shouldInsertNodeAtEnd) { + return + } + + return tr.insert(endPosition, type.create()) + }, + state: { + init: (_, state) => { + const lastNode = state.tr.doc.lastChild + + return !nodeEqualsType({ node: lastNode, types: disabledNodes }) + }, + apply: (tr, value) => { + if (!tr.docChanged) { + return value + } + + const lastNode = tr.doc.lastChild + + return !nodeEqualsType({ node: lastNode, types: disabledNodes }) + }, + }, + }), + ] + }, +}) diff --git a/packages/extension-utils/tsup.config.ts b/packages/extension-utils/tsup.config.ts new file mode 100644 index 000000000..9a367d572 --- /dev/null +++ b/packages/extension-utils/tsup.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from 'tsup' + +export default defineConfig({ + entry: ['src/index.ts'], + tsconfig: '../../tsconfig.build.json', + outDir: 'dist', + dts: true, + clean: true, + sourcemap: true, + format: [ + 'esm', + 'cjs', + ], +}) diff --git a/packages/starter-kit/package.json b/packages/starter-kit/package.json index 35e39ce6d..c2ffdb8ae 100644 --- a/packages/starter-kit/package.json +++ b/packages/starter-kit/package.json @@ -50,6 +50,7 @@ "@tiptap/extension-strike": "^3.0.0-next.3", "@tiptap/extension-underline": "^3.0.0-next.3", "@tiptap/extension-text": "^3.0.0-next.3", + "@tiptap/extension-utils": "^3.0.0-next.3", "@tiptap/pm": "^3.0.0-next.3" }, "repository": { diff --git a/packages/starter-kit/src/starter-kit.ts b/packages/starter-kit/src/starter-kit.ts index 1291a4079..03a69f414 100644 --- a/packages/starter-kit/src/starter-kit.ts +++ b/packages/starter-kit/src/starter-kit.ts @@ -5,8 +5,6 @@ import { BulletList, BulletListOptions } from '@tiptap/extension-bullet-list' import { Code, CodeOptions } from '@tiptap/extension-code' import { CodeBlock, CodeBlockOptions } from '@tiptap/extension-code-block' import { Document } from '@tiptap/extension-document' -import { Dropcursor, DropcursorOptions } from '@tiptap/extension-dropcursor' -import { Gapcursor } from '@tiptap/extension-gapcursor' import { HardBreak, HardBreakOptions } from '@tiptap/extension-hard-break' import { Heading, HeadingOptions } from '@tiptap/extension-heading' import { History, HistoryOptions } from '@tiptap/extension-history' @@ -20,6 +18,9 @@ import { Paragraph, ParagraphOptions } from '@tiptap/extension-paragraph' import { Strike, StrikeOptions } from '@tiptap/extension-strike' import { Text } from '@tiptap/extension-text' import { Underline, UnderlineOptions } from '@tiptap/extension-underline' +import { + Dropcursor, DropcursorOptions, Gapcursor, TrailingNode, TrailingNodeOptions, +} from '@tiptap/extension-utils' export interface StarterKitOptions { /** @@ -147,6 +148,12 @@ export interface StarterKitOptions { * @example underline: false */ underline: Partial | false, + + /** + * If set to false, the trailingNode extension will not be registered + * @example trailingNode: false + */ + trailingNode: Partial | false, } /** @@ -244,6 +251,10 @@ export const StarterKit = Extension.create({ extensions.push(Underline.configure(this.options?.underline)) } + if (this.options.trailingNode !== false) { + extensions.push(TrailingNode.configure(this.options?.trailingNode)) + } + return extensions }, })