Skip to content

Commit db381d1

Browse files
committed
refactor(editor): remove in-editor heading drag handle
Section reorder remains available from the TOC via moveSection. AGENTS.md notes TOC-only reorder and expands migration safety and CLI guidance. Made-with: Cursor
1 parent 4830f92 commit db381d1

10 files changed

Lines changed: 2 additions & 642 deletions

File tree

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525

2626
## Learned Workspace Facts
2727

28-
- docs.plus / docsy — Bun monorepo (packages/\*); main app @docs.plus/webapp (Next.js Pages Router), backend @docs.plus/hocuspocus; editor code under packages/webapp/src/components/TipTap/ (extensions, nodes, plugins); `src/lib/` removed — all shared utilities in `src/utils/`, feature-local helpers stay colocated; server-side `TiptapTransformer.toYdoc` / nested→flat migration must use an extension set that covers **every** node/mark in stored docs (e.g. **TaskList** / **TaskItem** from `@tiptap/extension-list` aligned with the webapp), not StarterKit alone — missing types fail encode, not flatten logic
29-
- Editor uses flat heading schema (`heading block*`) with decoration-based sections; `attrs['toc-id']` renders as `data-toc-id`; shared heading utilities (computeSection, moveSection, canMapDecorations, transactionAffectsNodeType, matchSections) in TipTap/extensions/shared/
28+
- docs.plus / docsy — Bun monorepo (packages/\*); main app @docs.plus/webapp (Next.js Pages Router), backend @docs.plus/hocuspocus; editor code under packages/webapp/src/components/TipTap/ (extensions, nodes, plugins); `src/lib/` removed — all shared utilities in `src/utils/`, feature-local helpers stay colocated; server-side `TiptapTransformer.toYdoc` / nested→flat migration must use an extension set that covers **every** node/mark in stored docs (e.g. **TaskList** / **TaskItem** from `@tiptap/extension-list` aligned with the webapp), not StarterKit alone — missing types fail encode, not flatten logic; **batch migrations must fail closed** (do not overwrite stored Yjs for a doc when transform/encode fails — keep prior bytes and surface the doc id); **run migration CLI** via `bun run migrate:nested-to-flat` from `packages/hocuspocus.server` after root `bun install` — invoking the script path alone from an arbitrary cwd can break Bun resolution of `yjs` for `@hocuspocus/transformer`
29+
- Editor uses flat heading schema (`heading block*`) with decoration-based sections; `attrs['toc-id']` renders as `data-toc-id`; shared heading utilities (computeSection, moveSection, canMapDecorations, transactionAffectsNodeType, matchSections) in TipTap/extensions/shared/; **section reorder is TOC-only** (`useTocDrag` / `moveHeading` + `moveSection`) — there is no in-editor heading drag handle extension
3030
- **HeadingScale (mandatory spec):** `extensions/heading-scale/heading-scale.ts`**dynamic** heading **font size by rank within a section**, **not** fixed per HTML level or a Google-style ladder. **Each H1 starts a new section**; within a section, **distinct** heading levels are sorted and sizes are **interpolated evenly between 20pt (max) and 12pt (min)**; same level twice in one section → **same visual size**; **one distinct level in a section → 20pt**. Title (first top-level H1) is included as part of section 1. **Decorations only** (`--hd-size`, `--hd-rank`, `--hd-total`); never write sizes into the document. Plugin state `{ fingerprint, decorations }` with fingerprint = top-level heading **levels in order** (e.g. `1,2,4,1,3`); **full rebuild when fingerprint changes** or `y-sync$` meta; else **map** the decoration set. **Do not** replace this with fixed per-level pt maps — that breaks the agreed behavior.
3131
- Editor perf: jank is React/Zustand re-renders, not ProseMirror; never put UI flags in `useEditor` deps; `shouldRerenderOnTransaction: false` on collab; decoration plugins should avoid full rebuilds on every keystroke — use `transactionAffectsNodeType(tr, 'heading')` **or** a cheaper structural check (HeadingScale uses **heading-level fingerprint**, not only `transactionAffectsNodeType`); placeholder uses `@docs.plus/extension-placeholder` (O(1) via state.init/apply) — do NOT replace with TipTap's built-in (O(N) doc.descendants)
3232
- Zustand: monolithic 7-slice store; all `useStore` calls must use leaf selectors — never `(state) => state` or `(state) => state.settings`

packages/webapp/src/components/TipTap/TipTap.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ import ShortUniqueId from 'short-unique-id'
4444
import { IndexeddbPersistence } from 'y-indexeddb'
4545
import * as Y from 'yjs'
4646

47-
import { HeadingDrag } from './extensions/heading-drag'
4847
import { HeadingFilter } from './extensions/heading-filter'
4948
import { HeadingFold, headingFoldPluginKey } from './extensions/heading-fold'
5049
import { HeadingScale } from './extensions/heading-scale'
@@ -157,7 +156,6 @@ const Editor = ({
157156
HeadingFold.configure({
158157
documentId: docName
159158
}),
160-
HeadingDrag,
161159
HeadingFilter.configure({
162160
foldAdapter: {
163161
getFoldedIds: (state) => {

packages/webapp/src/components/TipTap/extensions/heading-drag/heading-drag-plugin.ts

Lines changed: 0 additions & 298 deletions
This file was deleted.

packages/webapp/src/components/TipTap/extensions/heading-drag/heading-drag.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)