Skip to content

feat: expose useDropPosition, useListIndex, and DropIndicator from @portabletext/editor#2765

Closed
christianhg wants to merge 1 commit into
feat/editor-on-behavior-eventfrom
feat/delete-engine-drop-position
Closed

feat: expose useDropPosition, useListIndex, and DropIndicator from @portabletext/editor#2765
christianhg wants to merge 1 commit into
feat/editor-on-behavior-eventfrom
feat/delete-engine-drop-position

Conversation

@christianhg

@christianhg christianhg commented Jun 9, 2026

Copy link
Copy Markdown
Member

Companion to #2764. Promotes the engine's drop-position machinery and list-index map to a small public surface on @portabletext/editor.

import {useDropPosition, useListIndex, DropIndicator} from '@portabletext/editor'

function MyBlock(props: BlockRenderProps) {
  const dropPosition = useDropPosition(props.path)
  const listIndex = useListIndex(props.path)

  return (
    <>
      {dropPosition === 'start' ? <DropIndicator /> : null}
      <div data-list-index={listIndex}>{props.children}</div>
      {dropPosition === 'end' ? <DropIndicator /> : null}
    </>
  )
}

What's public

  • useDropPosition(path) — path-scoped, returns 'start' | 'end' | undefined. Drop into renderBlock or a container render callback to paint a drop indicator at the right edge.
  • useListIndex(path) — path-scoped, returns the 1-based numbered-list index or undefined. The same value the engine paints on data-list-index.
  • DropIndicator — the default drop-indicator visual. Export so consumers can paint it themselves while keeping the engine's visual identity.
  • DropPosition — the 'start' | 'end' type.

All four are @beta and ship from the main entry.

Built on editor.on

useDropPosition subscribes to editor.on('drag.dragover', …) from #2764 — the same publication surface any future drag-aware plugin would use. No add behavior send, no store primitive, no new context contract on the public editor type. The engine publishes the behavior-event stream; the plugin builds the React-context provider on top.

useListIndex reads from the engine's listIndexMap via the existing engine selector context. Same pattern: the engine maintains the map, the hook exposes a stable path-keyed read.

The engine's built-in renderBlock / renderListItem paths consume both useDropPosition(props.path) and useListIndex(props.path) directly. Drop position threading through RenderElement props is gone; resolve-element-drop-position is gone; the engine and external consumers read from the same context.

No breaking change

The engine continues to paint the default drop indicator and data-list-index via the built-in renderBlock and renderListItem paths. Consumers relying on the implicit affordances see no behavior change.

EditorProvider mounts an @internal DropPositionProvider so the context is always available to render callbacks.

Followups (not in this PR)

@changeset-bot

changeset-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 34ab20f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@portabletext/editor Minor
@portabletext/plugin-character-pair-decorator Patch
@portabletext/plugin-emoji-picker Patch
@portabletext/plugin-input-rule Patch
@portabletext/plugin-markdown-shortcuts Patch
@portabletext/plugin-one-line Patch
@portabletext/plugin-paste-link Patch
@portabletext/plugin-sdk-value Patch
@portabletext/plugin-table Patch
@portabletext/plugin-typeahead-picker Patch
@portabletext/plugin-typography Patch
@portabletext/toolbar Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
portable-text-editor-documentation Error Error Jun 10, 2026 3:10pm
portable-text-example-basic Ready Ready Preview, Comment Jun 10, 2026 3:10pm
portable-text-playground Ready Ready Preview, Comment Jun 10, 2026 3:10pm

Request Review

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @portabletext/editor

Compared against feat/editor-on-behavior-event (a8a17873)

@portabletext/editor

Metric Value vs feat/editor-on-behavior-event (a8a1787)
Internal (raw) 776.8 KB -959 B, -0.1%
Internal (gzip) 147.6 KB -213 B, -0.1%
Bundled (raw) 1.38 MB -988 B, -0.1%
Bundled (gzip) 309.5 KB -182 B, -0.1%
Import time 97ms -1ms, -0.9%

@portabletext/editor/behaviors

Metric Value vs feat/editor-on-behavior-event (a8a1787)
Internal (raw) 467 B -
Internal (gzip) 207 B -
Bundled (raw) 424 B -
Bundled (gzip) 171 B -
Import time 2ms +0ms, +0.3%

@portabletext/editor/plugins

Metric Value vs feat/editor-on-behavior-event (a8a1787)
Internal (raw) 2.7 KB -
Internal (gzip) 894 B -
Bundled (raw) 2.5 KB -
Bundled (gzip) 827 B -
Import time 7ms -0ms, -0.2%

@portabletext/editor/selectors

Metric Value vs feat/editor-on-behavior-event (a8a1787)
Internal (raw) 79.3 KB -6 B, -0.0%
Internal (gzip) 14.5 KB -6 B, -0.0%
Bundled (raw) 74.8 KB -6 B, -0.0%
Bundled (gzip) 13.4 KB -12 B, -0.1%
Import time 8ms -0ms, -0.5%

@portabletext/editor/traversal

Metric Value vs feat/editor-on-behavior-event (a8a1787)
Internal (raw) 25.4 KB -
Internal (gzip) 5.0 KB -
Bundled (raw) 25.4 KB -
Bundled (gzip) 5.0 KB -
Import time 6ms +0ms, +0.3%

@portabletext/editor/utils

Metric Value vs feat/editor-on-behavior-event (a8a1787)
Internal (raw) 28.7 KB -
Internal (gzip) 6.0 KB -
Bundled (raw) 26.7 KB -
Bundled (gzip) 5.7 KB -
Import time 6ms +0ms, +0.6%

🗺️ . · ./behaviors · ./plugins · ./selectors · ./traversal · ./utils · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @portabletext/markdown

Compared against feat/editor-on-behavior-event (a8a17873)

Metric Value vs feat/editor-on-behavior-event (a8a1787)
Internal (raw) 53.0 KB -
Internal (gzip) 9.6 KB -
Bundled (raw) 347.6 KB -
Bundled (gzip) 96.0 KB -
Import time 40ms +0ms, +0.1%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@christianhg christianhg force-pushed the feat/delete-engine-drop-position branch from 8b8d3dd to ae373ec Compare June 9, 2026 13:10
@christianhg christianhg changed the title feat: extract drop indicator into @portabletext/plugin-drop-position feat: expose useDropPosition and DropIndicator from @portabletext/editor/plugins Jun 9, 2026
@christianhg christianhg force-pushed the feat/delete-engine-drop-position branch from ae373ec to c1990db Compare June 9, 2026 13:18
@christianhg christianhg force-pushed the feat/delete-engine-drop-position branch from c1990db to 427747a Compare June 9, 2026 13:28
@christianhg christianhg force-pushed the feat/delete-engine-drop-position branch from 427747a to c7bce94 Compare June 9, 2026 14:04
@christianhg christianhg changed the title feat: expose useDropPosition and DropIndicator from @portabletext/editor/plugins feat: expose useDropPosition and DropIndicator from @portabletext/editor Jun 9, 2026
@christianhg christianhg force-pushed the feat/delete-engine-drop-position branch from c7bce94 to bf38f2a Compare June 9, 2026 14:16
@christianhg christianhg changed the title feat: expose useDropPosition and DropIndicator from @portabletext/editor feat: expose useDropPosition, useListIndex, and DropIndicator from @portabletext/editor Jun 9, 2026
@christianhg christianhg force-pushed the feat/delete-engine-drop-position branch from bf38f2a to a936758 Compare June 9, 2026 14:25
…tor/plugins

Promotes the engine's drop-position machinery to a small public surface
under @portabletext/editor/plugins:

- useDropPosition(path) — path-scoped, returns 'start' | 'end' | undefined.
  Used inside renderBlock or container render callbacks to know where to
  paint a drop indicator.
- DropIndicator — the default visual; export for consumers who want to
  paint it themselves while keeping the engine's visual identity.
- DropPosition — type.

The engine continues to paint the default indicator via the existing
renderBlock and renderListItem paths, so there's no breaking change for
consumers relying on the implicit affordance. The structural change is
small: state moves from a hook called inside Editable.tsx into a
DropPositionProvider mounted by EditorProvider; Editable.tsx reads the
context via useDropPosition() (no-arg overload).

The plugin is built on top of editor.on('drag.dragover', …) from #2764 —
same publication surface any future drag-aware plugin would use.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant