canvas: consolidate bubble + table toolbars into the fixed top toolbar (greyed-always) + add font-size #92

Closed
opened 2026-06-23 17:41:45 +00:00 by sameh-farouk · 1 comment
Member

Problem

The canvas (TipTap) editor has three separate toolbars:

  • #canvas-toolbar (fixed top) — block tools only (headings, lists, align, insert, undo).
  • #bubble-menu (floating, on selection) — the ONLY place for inline formatting (bold/italic/underline/strike/code/highlight/color/sub/sup/link).
  • #canvas-table-toolbar (floating, anchored to the active cell) — table row/col/merge/header/delete.

Issues:

  1. No font-size control (only font-family). The bundle already ships fontSize/setFontSize, so no rebuild needed — just register + add a dropdown.
  2. The two floating toolbars occlude content and the layout jumps (editor content shifts up/down) when entering/leaving a table.

Change (approved design)

Consolidate everything into the fixed top toolbar:

  • Move the inline-format group up from the bubble menu; delete #bubble-menu + its positioning JS.
  • Move the table group up; delete #canvas-table-toolbar + its positioning JS. Render it greyed-always — present but disabled when the cursor isn't in a table, enabled when it is. So the button set never changes → constant height → no vertical jump.
  • Add a font-size dropdown next to font-family (register the FontSize extension already in the bundle).
  • Toolbar may wrap to multiple rows (fixed/constant row count since the button set is stable) — no forced single row, no horizontal scroll.

Net: removes ~100 lines of floating-position logic; one stable toolbar; font-size added.

## Problem The canvas (TipTap) editor has three separate toolbars: - `#canvas-toolbar` (fixed top) — block tools only (headings, lists, align, insert, undo). - `#bubble-menu` (floating, on selection) — the ONLY place for inline formatting (bold/italic/underline/strike/code/highlight/color/sub/sup/link). - `#canvas-table-toolbar` (floating, anchored to the active cell) — table row/col/merge/header/delete. Issues: 1. **No font-size control** (only font-family). The bundle already ships `fontSize`/`setFontSize`, so no rebuild needed — just register + add a dropdown. 2. The two floating toolbars occlude content and the layout jumps (editor content shifts up/down) when entering/leaving a table. ## Change (approved design) Consolidate everything into the **fixed top toolbar**: - Move the inline-format group up from the bubble menu; **delete `#bubble-menu`** + its positioning JS. - Move the table group up; **delete `#canvas-table-toolbar`** + its positioning JS. Render it **greyed-always** — present but disabled when the cursor isn't in a table, enabled when it is. So the button set never changes → constant height → no vertical jump. - Add a **font-size** dropdown next to font-family (register the FontSize extension already in the bundle). - Toolbar may wrap to multiple rows (fixed/constant row count since the button set is stable) — no forced single row, no horizontal scroll. Net: removes ~100 lines of floating-position logic; one stable toolbar; font-size added.
Author
Member

Implemented and verified end-to-end on the box (build #23, served from web.sock via the router).

What shipped (branch development_sameh_collab_toolbar)

  • One fixed toolbar. The floating bubble (selection) menu and the in-table toolbar are gone; their controls now live in the single #canvas-toolbar, which stays a fixed height (71px) whether the cursor is inside or outside a table — no more editor content jumping up/down.
  • Table group greyed-always. The 11 table buttons are always present; they enable only when the cursor is inside a table and are greyed otherwise (verified: in-cell → 11 enabled, outside → 0 enabled).
  • Font-size control added to the toolbar (Size/12/14/16/18/24/32px); setFontSize emits <span style="font-size: …">.

Non-obvious root cause found while wiring font-size

Exporting FontSize forced a newer @tiptap/extension-text-style, which moved @tiptap/extension-collaboration onto the @tiptap/y-tiptap fork for its ySyncPlugin. The vendored editor still used the deprecated @tiptap/extension-collaboration-cursor@3.0.0, which resolves ySyncPluginKey from upstream y-prosemirror — a different key instance. The cursor plugin's init then read getState() === undefined and threw Cannot read properties of undefined (reading 'doc'), aborting editor construction (the canvas showed the generic "Canvas not found" error box).

Fix: replaced the deprecated cursor extension with its official v3 successor @tiptap/extension-collaboration-caret (shares the y-tiptap key with Collaboration). Also pinned the whole @tiptap family to exact 3.22.3 (deps + overrides) so the vendored bundle is deterministic and won't silently drift on rebuild, updated the remote-caret CSS classes (.collaboration-cursor__*.collaboration-carets__*), and restored the missing scripts/vendor-bundle/build.sh.

Verification

Browser (Playwright) against the running daemon, as canvas owner:

  • editor constructs (caret + FontSize + table), no error box, console clean
  • toolbar fixed at 71px in and out of tables
  • table group toggles enabled/greyed with cursor in/out of cell
  • setFontSize('24px') applies; floating menus absent
  • test edits cleaned up; canvas back to empty

Commits: e263fb5 (toolbar), 36da933 (FontSize export), 73e1d39 (cursor→caret fix). Ready to squash-merge to development.

Implemented and verified end-to-end on the box (build #23, served from web.sock via the router). ## What shipped (branch `development_sameh_collab_toolbar`) - **One fixed toolbar.** The floating bubble (selection) menu and the in-table toolbar are gone; their controls now live in the single `#canvas-toolbar`, which stays a **fixed height (71px)** whether the cursor is inside or outside a table — no more editor content jumping up/down. - **Table group greyed-always.** The 11 table buttons are always present; they enable only when the cursor is inside a table and are greyed otherwise (verified: in-cell → 11 enabled, outside → 0 enabled). - **Font-size control** added to the toolbar (Size/12/14/16/18/24/32px); `setFontSize` emits `<span style="font-size: …">`. ## Non-obvious root cause found while wiring font-size Exporting `FontSize` forced a newer `@tiptap/extension-text-style`, which moved `@tiptap/extension-collaboration` onto the `@tiptap/y-tiptap` fork for its `ySyncPlugin`. The vendored editor still used the **deprecated** `@tiptap/extension-collaboration-cursor@3.0.0`, which resolves `ySyncPluginKey` from **upstream `y-prosemirror`** — a different key instance. The cursor plugin's `init` then read `getState() === undefined` and threw `Cannot read properties of undefined (reading 'doc')`, aborting editor construction (the canvas showed the generic "Canvas not found" error box). **Fix:** replaced the deprecated cursor extension with its official v3 successor `@tiptap/extension-collaboration-caret` (shares the y-tiptap key with Collaboration). Also pinned the whole `@tiptap` family to exact `3.22.3` (deps + overrides) so the vendored bundle is deterministic and won't silently drift on rebuild, updated the remote-caret CSS classes (`.collaboration-cursor__*` → `.collaboration-carets__*`), and restored the missing `scripts/vendor-bundle/build.sh`. ## Verification Browser (Playwright) against the running daemon, as canvas owner: - editor constructs (caret + FontSize + table), no error box, console clean - toolbar fixed at 71px in and out of tables - table group toggles enabled/greyed with cursor in/out of cell - `setFontSize('24px')` applies; floating menus absent - test edits cleaned up; canvas back to empty Commits: `e263fb5` (toolbar), `36da933` (FontSize export), `73e1d39` (cursor→caret fix). Ready to squash-merge to `development`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_collab#92
No description provided.