Skip to content

Comments

feat: add nested blocks schema support#2187

Open
christianhg wants to merge 2 commits intofeat-containersfrom
feat-nested-blocks-schema
Open

feat: add nested blocks schema support#2187
christianhg wants to merge 2 commits intofeat-containersfrom
feat-nested-blocks-schema

Conversation

@christianhg
Copy link
Member

Summary

Adds nested block support to @portabletext/schema and @portabletext/sanity-bridge, enabling block types that appear inside block objects (e.g. table cells containing PTE content).

Ref: task-schema-nested-blocks on the board (Phase 0.1 + 0.2)

Changes

@portabletext/schema (commit 1)

  • NestedBlockSchemaType / NestedBlockDefinition — new types for block types inside block objects
  • OfDefinition discriminated unionBlockOfDefinition | ObjectOfDefinition on FieldDefinition.of
    • BlockOfDefinition (type: 'block') carries PTE sub-schema: styles, decorators, annotations, lists
    • ObjectOfDefinition (type: string) carries fields for non-block types
  • compileSchema() processes nestedBlocks and of recursively
  • Existing schemas compile identically (plus nestedBlocks: [])
  • 8 tests

@portabletext/sanity-bridge (commit 2)

  • PortableTextMemberSchemaTypes.nestedBlocks — new field
  • createPortableTextMemberSchemaTypes() walks block object fields recursively to detect objects containing array-of-blocks fields
  • portableTextMemberSchemaTypesToSchema() emits nestedBlocks and carries of through on array fields
  • safeGetOf() handles Sanity schema getter edge cases
  • Table schema integration test
  • All existing tests updated with nestedBlocks: [] (additive)

Design note: bridge auto-detection scope

The bridge detects nested blocks by finding objects that directly contain an array-of-blocks field (e.g. tableCell with content: array of [block]). Intermediate containers like tableRow (which has cells: array of [tableCell] but no blocks directly) are not auto-classified.

The task spec example lists both tableRow and tableCell as nestedBlocks in defineSchema() — works fine on the schema side since users declare them explicitly. Question: should the bridge also auto-detect intermediate containers? Happy to adjust.

Test results

  • packages/schema: 8 tests ✅
  • packages/sanity-bridge: 18 tests ✅

@changeset-bot
Copy link

changeset-bot bot commented Feb 16, 2026

⚠️ No Changeset found

Latest commit: bdad5de

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel
Copy link

vercel bot commented Feb 16, 2026

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

Project Deployment Actions Updated (UTC)
portable-text-editor-documentation Ready Ready Preview, Comment Feb 16, 2026 9:19am
portable-text-example-basic Ready Ready Preview, Comment Feb 16, 2026 9:19am
portable-text-playground Ready Ready Preview, Comment Feb 16, 2026 9:19am

Request Review

… of on FieldDefinition

- Add NestedBlockSchemaType/NestedBlockDefinition for block types that
  appear inside block objects (e.g. table cells containing PTE content)
- Add OfDefinition = BlockOfDefinition | ObjectOfDefinition discriminated
  union on FieldDefinition.of for array field member types
- BlockOfDefinition (type: 'block') carries PTE sub-schema: styles,
  decorators, annotations, lists
- ObjectOfDefinition (type: string) carries fields for non-block types
- compileSchema() emits nestedBlocks: [] for existing schemas (additive)
- 8 tests: backwards compat, nested blocks, of with block/object types,
  full table schema example
…f on array fields

- Add nestedBlocks to PortableTextMemberSchemaTypes
- Walk block object fields recursively to detect objects containing
  array-of-blocks fields (nested block containers like table cells)
- Emit nestedBlocks in portableTextMemberSchemaTypesToSchema()
- Carry OfDefinition (block vs object) through on array fields via
  sanityFieldToFieldDefinition() and sanityFieldToOfDefinition()
- Use safeGetOf() to handle Sanity schema getter edge cases
- Add table schema integration test: table → tableRow → tableCell
  with nested block content correctly detected
- All existing tests updated with nestedBlocks: [] (additive)
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