Skip to content

feat(react)!: structure parts, block actions and typed child refs - #98

Merged
weepaho3 merged 3 commits into
mainfrom
cms-45-structure-parts
Aug 16, 2026
Merged

feat(react)!: structure parts, block actions and typed child refs#98
weepaho3 merged 3 commits into
mainfrom
cms-45-structure-parts

Conversation

@weepaho3

@weepaho3 weepaho3 commented Aug 16, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Adds the structure layer to @createcms/react/editor: child refs from useChildren, placement-gated block actions, a keyboard-operable outline row, and a palette insert button. Together they let a consumer build a stacked form (recurse useChildren + Editor.Form) and add, reorder, duplicate and delete blocks without a canvas.

  • useChildren(parentId) returns { id, type, index } in order (same array reference until ids or types change). The factory narrows type to the schema's block types (ChildRefOf<S>).
  • useBlockActions(id) returns BlockActions: canMoveUp / canMoveDown / canHaveChildren / allowedChildTypes, plus add / remove / duplicate / moveUp / moveDown (each returns the store's verdict). Root: only add applies. Unknown id: type is null and everything is inert. Factory: TypedBlockActions<S>.
  • Editor.OutlineItem blockId: div with role="treeitem", aria-selected / aria-level / aria-expanded, roving tabIndex, data-selected / data-depth / data-has-children / data-block-id / data-block-type. Click selects. ArrowUp/Down select and focus the previous/next tree item in DOM order inside the closest [role="tree"]. Alt+Arrow moves among siblings. Delete/Backspace run onDelete (return false to keep), then remove and land focus on the next item outside the subtree (else the previous). Escape clears the selection. Nested rows own their own events; keys inside an input are left alone. No drag and drop.
  • Editor.AddBlock type: button with the palette label as default children. Insert point when parentId is omitted: the selected block if it accepts type (append), else after the selected block in its parent, else the root (append). Disabled when the target cannot take type. Click inserts and selects the new id.
  • Editor namespace grows to Root, Field, FieldLabel, FieldControl, FieldDescription, FieldError, Form, OutlineItem, AddBlock.
  • README: parts rows, Structure parts subsection (keyboard table, insert-point rule), hooks, factory types, data attributes, tests.

Tests: structure/structure.test.tsx (happy-dom) covers roles/aria/data attributes, click, roving tabIndex, arrow navigation, Alt+arrow reorder, Delete/Backspace with onDelete veto and focus return, Escape, nested-row ownership, render prop, unknown id, AddBlock insert-point and disabled gating, stacked-form acceptance; plus structure/structure.type-check.ts, updated hooks.test.tsx / factory.test.tsx / editor.test.tsx.

Changeset: @createcms/react minor.

Checklist

  • bun run check-types passes
  • bun run test passes (packages/react: 384 tests; the cms suite is unaffected)
  • bun run lint passes
  • Added a changeset (bunx changeset) if this changes published behavior
  • Docs updated if needed (package README, BREAKING-CHANGES.md, docs breaking-changes page)

BREAKING CHANGE: useChildren(parentId) returns child refs ({ id, type, index })
instead of a string array. Read child.id where an id was used before; the
factory's useChildren narrows type to the schema's block types.

@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
createcms-docs Ready Ready Preview Aug 16, 2026 5:41pm

BREAKING CHANGE: useChildren(parentId) returns child refs ({ id, type, index })
instead of a string array. Read child.id where an id was used before; the
factory's useChildren narrows type to the schema's block types.
@weepaho3
weepaho3 force-pushed the cms-45-structure-parts branch from dc34974 to cb35dcc Compare August 16, 2026 17:41
Repository owner deleted a comment from cursor Bot Aug 16, 2026
@weepaho3
weepaho3 merged commit bea8451 into main Aug 16, 2026
15 checks passed
@weepaho3
weepaho3 deleted the cms-45-structure-parts branch August 16, 2026 17:45
@github-actions github-actions Bot mentioned this pull request Aug 16, 2026
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