Skip to content

Version Packages - #3076

Merged
christianhg merged 1 commit into
mainfrom
changeset-release/main
Aug 17, 2026
Merged

Version Packages#3076
christianhg merged 1 commit into
mainfrom
changeset-release/main

Conversation

@ecoscript

@ecoscript ecoscript Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@portabletext/block-tools@5.2.0

Minor Changes

  • #3074 d4d11e5 Thanks @christianhg! - feat: re-export createTableRule from @portabletext/html

    @portabletext/block-tools/rules already re-exports createFlattenTableRule; it now also re-exports createTableRule, @portabletext/html's deserializer rule for converting <table> HTML into a nested table shape.

Patch Changes

@portabletext/editor@7.11.0

Minor Changes

  • #3087 2f5c148 Thanks @christianhg! - feat: promote the Behavior API from beta to public

    The Behavior API is no longer beta. defineBehavior, the action creators (execute, forward, raise, effect), editor.registerBehavior, and BehaviorPlugin are stable. Their types are stable too: Behavior, BehaviorAction, BehaviorActionSet, BehaviorEvent, SyntheticBehaviorEvent, NativeBehaviorEvent, CustomBehaviorEvent, BehaviorGuard, and InsertPlacement.

    import {defineBehavior, raise} from '@portabletext/editor/behaviors'
    import {getFocusTextBlock} from '@portabletext/editor/selectors'
    
    const noBreakInTitles = defineBehavior({
      on: 'insert.break',
      guard: ({snapshot}) =>
        snapshot.context.selection !== null &&
        getFocusTextBlock(snapshot)?.node.style === 'title',
      actions: [() => [raise({type: 'insert.soft break'})]],
    })

    The alpha primitive event forms stay alpha: insert, remove.text, set, unset, and the explicit at/offset form of insert.text.

  • #3084 e7df9b8 Thanks @christianhg! - feat: promote the containers introspection map from alpha to public

    snapshot.context.containers is no longer alpha. Its types are stable too: Containers, RegisteredContainer, RegisteredSpan, RegisteredBlockObject, RegisteredInlineObject, and RegisteredPositional. OfDefinition is now re-exported from the package root; it appears in RegisteredContainer['field'], whose shape is named via indexed access rather than a dedicated export.

    The map is the read side of node registration: entries keyed by container _type, each carrying the array field that holds the container's editable children and any position-scoped child registrations.

    import {useEditorSelector} from '@portabletext/editor'
    
    const tableRegistration = useEditorSelector(editor, (snapshot) =>
      snapshot.context.containers.get('table'),
    )
  • #3081 eb8cb6c Thanks @christianhg! - feat: promote node registration from alpha to public

    defineContainer, defineTextBlock, defineSpan, defineBlockObject, defineInlineObject, editor.registerNode, and NodePlugin are no longer alpha. Their types are stable too: Container, TextBlock, Span, BlockObject, InlineObject, RegistrableNode, and the ContainerRender/ContainerRenderProps, SpanRender/SpanRenderProps, BlockObjectRender/BlockObjectRenderProps, InlineObjectRender/InlineObjectRenderProps, and TextBlockRender/TextBlockRenderProps pairs.

    This is the supported replacement for the deprecated renderBlock, renderChild, renderStyle, and renderListItem render props:

    import {defineTextBlock} from '@portabletext/editor'
    import {NodePlugin} from '@portabletext/editor/plugins'
    
    const textBlock = defineTextBlock({
      type: 'block',
      render: ({attributes, children}) => <div {...attributes}>{children}</div>,
    })
    
    function App() {
      return (
        <EditorProvider initialConfig={{schemaDefinition}}>
          <NodePlugin nodes={[textBlock]} />
          <PortableTextEditable />
        </EditorProvider>
      )
    }
  • #3091 75d2dc4 Thanks @christianhg! - feat: promote the surviving render-prop types from beta to public

    RenderPlaceholderFunction, RenderEditableFunction, and ScrollSelectionIntoViewFunction are now @public: editor-chrome hooks with no replacement on the horizon.

    The content-rendering props stay @beta: RenderAnnotationFunction, RenderDecoratorFunction, and their prop types alongside the already-deprecated RenderBlockFunction, RenderChildFunction, RenderStyleFunction, and RenderListItemFunction.

  • #3090 45fd070 Thanks @christianhg! - feat: promote the config, offset, and editor-ref surface from beta to public

    EditorConfig.keyGenerator, InvalidValueResolution, BlockOffset, and EditorRefPlugin move from @beta to @public. Their shapes and behavior are unchanged; they now follow the package's normal semver guarantees.

  • #3089 bfd7058 Thanks @christianhg! - feat: promote the applicable-schema and mark-state selectors from beta to public

    ApplicableSchema, getApplicableSchema, compareApplicableSchema, MarkState, and getMarkState are now stable, public API. Their behavior is unchanged; only the stability guarantee changes.

    import {useEditorSelector} from '@portabletext/editor'
    import {
      getApplicableSchema,
      compareApplicableSchema,
    } from '@portabletext/editor/selectors'
    
    const applicableSchema = useEditorSelector(
      editor,
      getApplicableSchema,
      compareApplicableSchema,
    )
  • #3088 8c72f76 Thanks @christianhg! - feat: promote the traversal utils from beta to public

    The traversal utilities are no longer beta: getNode, getChildren, getParent, getSibling, getAncestor, getAncestors, getContainer, getFirstChild, getLastChild, getLeaf, getSpan, getText, getTextBlock, getAnnotation, getEnclosingBlock, getPathSubSchema, getUnionSchema, getBlock, isBlock, isInline, isLeafObject, isObject, hasNode, comparePoints, pathContains, and rangeIntersects are all @public now and follow the package's normal semver guarantees.

    import {getEnclosingBlock, getNode} from '@portabletext/editor/traversal'
    
    const entry = getNode(snapshot, selection.anchor.path)
    const block = entry ? getEnclosingBlock(snapshot, entry.path) : undefined

    getContainerChildren stays @beta.

  • #3082 db10bb7 Thanks @christianhg! - feat: promote RangeDecoration and RangeDecorationOnMovedDetails to public API

    RangeDecoration and RangeDecorationOnMovedDetails are no longer alpha. The rangeDecorations prop on PortableTextEditable was already public; the types it takes are now stable too:

    <PortableTextEditable
      rangeDecorations={[
        {
          component: (props) => <SearchResultHighlight {...props} />,
          selection: {
            anchor: {path: [{_key: 'b1'}, 'children', {_key: 's1'}], offset: 0},
            focus: {path: [{_key: 'b1'}, 'children', {_key: 's1'}], offset: 3},
          },
          onMoved: (details) => {
            rememberSelection(details.newSelection)
          },
        },
      ]}
    />

Patch Changes

  • #3092 5c61867 Thanks @christianhg! - fix: deprecate EditableAPIDeleteOptions in favor of behavior events

    EditableAPIDeleteOptions is deprecated together with the PortableTextEditor.delete static it serves. Send a delete behavior event (with an optional unit) or a delete.block event via editor.send instead.

  • #3075 9e3b7be Thanks @christianhg! - fix: deprecate the block-level render props on <PortableTextEditable>

    renderBlock, renderChild, renderStyle, and renderListItem are deprecated, along with their function types. They keep working, but node registrations (defineTextBlock, defineBlockObject, defineInlineObject, defineSpan mounted through NodePlugin) are the supported way to render nodes, and list numbering comes from @portabletext/plugin-list-index. The migration guide walks through each prop: https://www.portabletext.org/editor/guides/migrate-render-props/

    The span-level props (renderDecorator, renderAnnotation, renderPlaceholder) and rangeDecorations are not deprecated.

  • #3093 fbb9a98 Thanks @christianhg! - fix: deprecate the legacy render-prop payload types

    BlockRenderProps, BlockChildRenderProps, BlockStyleRenderProps, and BlockListItemRenderProps are deprecated together with the render props they serve (renderBlock, renderChild, renderStyle, renderListItem). Type against the node registration API instead: BlockObjectRenderProps / TextBlockRenderProps for blocks, InlineObjectRenderProps / SpanRenderProps for children, and defineTextBlock render props for styles and list items. See the migration guide: https://www.portabletext.org/editor/guides/migrate-render-props/

  • #3086 2c97777 Thanks @christianhg! - fix: keep the drag source when a drop fits no blocks

    Dropping blocks that the destination rejects entirely (a table cell whose schema accepts none of them, for example) deleted the drag source with nothing inserted. That drop is now a no-op.

  • Updated dependencies [b7610ec, b7050a7, 0e3505b, 8ed2d1f]:

    • @portabletext/html@1.2.0
    • @portabletext/markdown@1.5.0

@portabletext/html@1.2.0

Minor Changes

  • #3074 b7610ec Thanks @christianhg! - feat: add createTableRule for deserializing <table> HTML into a nested table shape

    createFlattenTableRule was the only table deserializer, and it flattens a table into a list of standalone text blocks, losing the row/column structure. createTableRule keeps it: it turns a <table> into one block carrying rows, each row carrying cells, each cell carrying a Portable Text value array, the shape @portabletext/plugin-table's defineTable produces.

    import {htmlToPortableText} from '@portabletext/html'
    import {createTableRule} from '@portabletext/html/rules'
    
    const blocks = htmlToPortableText(html, {
      schema,
      rules: [createTableRule({schema})],
    })

    headerRows is set from leading <thead> rows or an all-<th> first row, and omitted when there are none. Ragged rows are padded to the widest row with empty cells, and colspan/rowspan are ignored: a spanning cell contributes one cell, and the padding fills the rest. The containers option matches a defineTable call whose container names were renamed. It is role-keyed like defineTable's own option and reads only type and arrayField, so the same container definitions can be passed to both.

Patch Changes

  • #3078 0e3505b Thanks @christianhg! - fix: scope createFlattenTableRule's row and cell lookup to its own table

    A table containing another table in one of its cells was not flattened at all: its cells came through as separate blocks, as if the rule had not been passed. Rows and cells are now read from the table's own rows and cells collections, so a nested table stays inside the cell that holds it.

@portabletext/markdown@1.5.0

Minor Changes

  • #3073 b7050a7 Thanks @christianhg! - feat: convert GFM tables by default

    markdownToPortableText now converts GFM pipe tables to a table block object out of the box, matching the shape @portabletext/plugin-table expects: headerRows, an optional alignment array, and rows of row objects holding cell objects with a value array of Portable Text blocks. This only kicks in when the schema declares a table block object with a rows field; a schema without that keeps flattening table cells into plain blocks, as before. A consumer-supplied types.table matcher still wins over the default.

    portableTextToMarkdown now renders table block objects back to GFM by default too, instead of a fenced JSON block. A value that isn't table-shaped falls back to the fenced JSON rendering. A consumer-supplied types.table renderer still wins over the default.

    DefaultTableRenderer now treats a missing or non-positive headerRows as headerless, rather than promoting the first row to a header. markdownToPortableText always sets headerRows explicitly, so converting GFM to Portable Text and back is unaffected.

  • #3079 8ed2d1f Thanks @christianhg! - feat: render code, image, horizontal rule, HTML, and callout blocks to markdown by default

    portableTextToMarkdown now renders code, image, horizontal-rule, html, and callout block objects back to Markdown by default, instead of a fenced JSON block. This matches table, which already rendered as GFM by default.

    code, image, html, and callout fall back to the fenced JSON rendering when a value doesn't match the shape its renderer expects, for example a consumer's own differently-shaped code type reaching the renderer via the same _type name; horizontal-rule always renders ---. A consumer-supplied types renderer still wins over any of the defaults.

    @portabletext/editor's markdown clipboard picks this up via the automatic dependency bump: copying a code block, image, horizontal rule, HTML block, or callout out of the editor now produces real Markdown instead of a fenced JSON block.

    One narrow behavioral fix rides along: when a callout or DefaultBlockquoteObjectRenderer content entry falls back to fenced JSON, the JSON is the original value; previously it carried a style: 'normal' field injected by the renderer.

@portabletext/plugin-character-pair-decorator@8.0.48

Patch Changes

@portabletext/plugin-dnd@1.0.32

Patch Changes

@portabletext/plugin-emoji-picker@7.0.48

Patch Changes

@portabletext/plugin-input-rule@6.0.17

Patch Changes

@portabletext/plugin-list-index@1.0.32

Patch Changes

@portabletext/plugin-markdown-shortcuts@8.0.48

Patch Changes

@portabletext/plugin-one-line@7.0.47

Patch Changes

@portabletext/plugin-paste-link@4.0.47

Patch Changes

@portabletext/plugin-sdk-value@7.2.5

Patch Changes

@portabletext/plugin-table@1.3.17

Patch Changes

@portabletext/plugin-typeahead-picker@6.0.48

Patch Changes

@portabletext/plugin-typography@8.0.48

Patch Changes

@portabletext/toolbar@8.0.47

Patch Changes

@vercel

vercel Bot commented Aug 14, 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 Ready Ready Preview Aug 17, 2026 1:01pm
portable-text-example-basic Ready Ready Preview Aug 17, 2026 1:01pm
portable-text-playground Ready Ready Preview Aug 17, 2026 1:01pm

Request Review

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @portabletext/editor

Compared against main (fbb9a982)

@portabletext/editor

Metric Value vs main (fbb9a98)
Internal (raw) 807.2 KB -
Internal (gzip) 179.6 KB -
Bundled (raw) 1.42 MB -
Bundled (gzip) 347.4 KB -
Import time 99ms +1ms, +0.9%

@portabletext/editor/behaviors

Metric Value vs main (fbb9a98)
Internal (raw) 4.2 KB -
Internal (gzip) 1.4 KB -
Bundled (raw) 3.9 KB -
Bundled (gzip) 1.3 KB -
Import time 2ms -0ms, -1.0%

@portabletext/editor/plugins

Metric Value vs main (fbb9a98)
Internal (raw) 5.2 KB -
Internal (gzip) 1.8 KB -
Bundled (raw) 5.0 KB -
Bundled (gzip) 1.7 KB -
Import time 7ms -0ms, -3.1%

@portabletext/editor/selectors

Metric Value vs main (fbb9a98)
Internal (raw) 96.4 KB -
Internal (gzip) 22.3 KB -
Bundled (raw) 92.5 KB -
Bundled (gzip) 21.0 KB -
Import time 8ms -0ms, -0.4%

@portabletext/editor/traversal

Metric Value vs main (fbb9a98)
Internal (raw) 40.7 KB -
Internal (gzip) 10.6 KB -
Bundled (raw) 41.1 KB -
Bundled (gzip) 10.6 KB -
Import time 6ms +0ms, +1.0%

@portabletext/editor/utils

Metric Value vs main (fbb9a98)
Internal (raw) 34.1 KB -
Internal (gzip) 8.7 KB -
Bundled (raw) 32.5 KB -
Bundled (gzip) 8.5 KB -
Import time 6ms +0ms, +3.4%

🗺️ . · ./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 main (fbb9a982)

Metric Value vs main (fbb9a98)
Internal (raw) 53.0 KB -
Internal (gzip) 11.6 KB -
Bundled (raw) 348.0 KB -
Bundled (gzip) 98.2 KB -
Import time 38ms -0ms, -0.4%

🗺️ 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.

@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from a3bf46f to 31fb1c5 Compare August 14, 2026 10:35
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 31fb1c5 to aa3be6d Compare August 14, 2026 10:37
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from aa3be6d to 3b85cde Compare August 14, 2026 11:06
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 3b85cde to 2e3bfe6 Compare August 14, 2026 12:23
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 2e3bfe6 to f4c46d3 Compare August 14, 2026 13:39
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from f4c46d3 to 6693dd9 Compare August 17, 2026 07:27
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 6693dd9 to 3293ae8 Compare August 17, 2026 07:29
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 3ce8f0a to b4f6ec1 Compare August 17, 2026 10:43
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from b4f6ec1 to a1f1c8d Compare August 17, 2026 11:45
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from a1f1c8d to 977a5db Compare August 17, 2026 11:48
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 977a5db to 58e642f Compare August 17, 2026 11:49
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 58e642f to 1d726a2 Compare August 17, 2026 12:00
@ecoscript
ecoscript Bot force-pushed the changeset-release/main branch from 1d726a2 to 4b92f8e Compare August 17, 2026 12:01
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