feat: Tiptap V3 migration (#1854)

* Tiptap3 migration - WIP

* fix collaboration

* remove unused code

* fix flicker

* disable duplicate extensions

* update tiptap version

* Switch to useEditorState
- Set shouldRerenderOnTransaction to false

* fix editable state

* add tippyoptions for reference

* merge main

* tiptap 3.6.1

* fix bubble menu

* fix converter

* fix menus

* fix collaboration caret css

* fix: Set `isInitialized` to force immediate react node view rendering

* feat: Migrate tippy.js menus to Floating UI

* feat: Update collaboration connection for HocusPocus v3

* fix: Connect/disconnect websocketProvider

* cleanup

* cleanup

* feat: Improved placeholder and upload handling for images

* feat: Improved placeholder and upload handling for videos

* refactor: Image node and view clean-up

* feat: Improved placeholder and upload handling for attachments

* fix: Video view styles

* fix: Transaction handling on asset upload

* fix: Use imageDimensionsFromStream

* feat: Multiple file upload, improved placeholders, local previews

* fix: Drag & drop, paste upload

* fix: Allow media as attachment

* * add skeleton pulse animation
* add translation strings
* fix attachment view responsiveness

* fix collab connection status display

* Tiptap v3.17.0

* fix suggestion menu exit bug

* fix search shortcut

* fix history editor css

* tiptap 3.17.1

---------

Co-authored-by: Arek Nawo <areknawo@areknawo.com>
This commit is contained in:
Philip Okugbe
2026-01-24 20:41:08 +00:00
committed by GitHub
parent 98f71c95fe
commit 657fdf8cb7
74 changed files with 2532 additions and 2370 deletions
@@ -1,8 +1,9 @@
import '@/features/editor/styles/index.css';
import React, { useEffect } from 'react';
import { EditorContent, useEditor } from '@tiptap/react';
import { mainExtensions } from '@/features/editor/extensions/extensions';
import { Title } from '@mantine/core';
import "@/features/editor/styles/index.css";
import React, { useEffect } from "react";
import { EditorContent, useEditor } from "@tiptap/react";
import { mainExtensions } from "@/features/editor/extensions/extensions";
import { Title } from "@mantine/core";
import classes from "./history.module.css";
export interface HistoryEditorProps {
title: string;
@@ -26,7 +27,9 @@ export function HistoryEditor({ title, content }: HistoryEditorProps) {
<div>
<Title order={1}>{title}</Title>
{editor && <EditorContent editor={editor} />}
{editor && (
<EditorContent editor={editor} className={classes.historyEditor} />
)}
</div>
</>
);
@@ -67,7 +67,7 @@ function HistoryList({ pageId }: Props) {
mainEditorTitle
.chain()
.clearContent()
.setContent(activeHistoryData.title, true)
.setContent(activeHistoryData.title, { emitUpdate: true })
.run();
mainEditor
.chain()
@@ -1,37 +1,49 @@
.history {
display: block;
width: 100%;
padding: var(--mantine-spacing-md);
color: light-dark(var(--mantine-color-black), var(--mantine-color-dark-0));
display: block;
width: 100%;
padding: var(--mantine-spacing-md);
color: light-dark(var(--mantine-color-black), var(--mantine-color-dark-0));
@mixin hover {
background-color: light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-8));
}
@mixin hover {
background-color: light-dark(
var(--mantine-color-gray-2),
var(--mantine-color-dark-8)
);
}
}
.historyEditor {
:global(.ProseMirror) {
padding: 0 !important;
}
}
.active {
background-color: light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-8));
background-color: light-dark(
var(--mantine-color-gray-2),
var(--mantine-color-dark-8)
);
}
.sidebar {
max-height: rem(700px);
width: rem(250px);
padding: var(--mantine-spacing-sm);
display: flex;
flex-direction: column;
border-right: rem(1px) solid
max-height: rem(700px);
width: rem(250px);
padding: var(--mantine-spacing-sm);
display: flex;
flex-direction: column;
border-right: rem(1px) solid
light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
}
.sidebarFlex {
display: flex;
display: flex;
}
.sidebarMain {
flex: 1;
flex: 1;
}
.sidebarRightSection {
flex: 1;
padding: rem(16px) rem(40px);
flex: 1;
padding: rem(16px) rem(40px);
}