Add useMaxInnerBlocks hook#406
Conversation
Enforces an upper bound on a block's direct innerBlocks. Diffs clientIds against a snapshot to remove only the newest extras — existing children are preserved even when a duplicate lands between them. Fires a configurable notice (snackbar by default) when extras are removed. - hooks/use-max-inner-blocks: new hook + readme - example/src/blocks/max-inner-blocks-example: demo block with inspector toggles for max, notice type, icon, dismissibility, explicit dismiss, and action button
Resolves merge with develop, which introduced the TypeScript conversion, React 18 upgrade, @wordpress/icons ^11, and a parallel useRenderAppenderWithLimit hook (complementary, not redundant — that hook prevents the appender from rendering past the limit; useMaxInnerBlocks reactively removes blocks added through any path including paste and duplicate). - Convert hooks/use-max-inner-blocks to .tsx with proper types - Convert example block to .tsx - Move hook export from hooks/index.js (deleted on develop) to hooks/index.ts - Add useMaxInnerBlocks to project README hooks list - Take develop's example/src/index.js (entries are auto-discovered via webpack now)
|
🎉 A new testing version of this package has been published to NPM. You can install it with |
|
The CI failures here (Jest, Cypress, build, all dying at Tracking the fix in #407, which only updates the lockfile (no |
|
Update on the lockfile fix in #407: The regenerated lockfile is correctly fixing the
So the fix here unblocks the install step that was blocking every check. The remaining failures can be triaged separately and don't affect this PR's reviewability. |
|
Update on #407: confirmed green now (Jest, ESLint, Cypress with all 35 tests, release_testing, Analyze, CodeQL all passing). Once it merges to develop, this PR's checks will go green automatically (the lockfile fix gets merged in, and the only red check on #407 — |
Summary
useMaxInnerBlockshook (TypeScript) that enforces an upper bound on a block's directinnerBlocks. Over-limit additions are removed and a notice is fired.clientIds against a snapshot to remove only the newest extras — existing (potentially filled) children are preserved even when a duplicate lands between them (e.g.[A, A-copy, B]→ removes the copy, keeps[A, B]).noticeOptionspassthrough tocreateNotice— supports custom icon, action buttons, snackbar vs default type, sticky/dismissible behavior, etc. Default icon isinfofrom@wordpress/icons.API
See
hooks/use-max-inner-blocks/readme.mdfor full usage and customization examples.Files
hooks/use-max-inner-blocks/index.tsx— hook implementationhooks/use-max-inner-blocks/readme.md— usage andnoticeOptionsreferencehooks/index.ts— barrel exportREADME.md— added hook linkexample/src/blocks/max-inner-blocks-example/— TS example block (block.json + edit.tsx + index.tsx) demonstrating every customization pathTest plan
npm ci && npm run buildat the repo root succeeds;dist/index.jsexportsuseMaxInnerBlocksand types are emitted atdist/hooks/use-max-inner-blocks/index.d.tscd example && npm run build && npm run wp-env startboots cleanly (run via rootnpm cisince the project uses npm workspaces)maxremoves the new child and fires a snackbarmax, fires one noticemax(range 1–5), notice type (snackbar/default), icon (default/custom/none), dismissible, explicit dismiss (sticky), action buttonnoticeOptions.icononly renders on snackbar notices (default-type<Notice>ignores it — documented in readme)CI status
The
Cypress,Jest, andbuildchecks fail at thenpm cistep with apackage.json↔package-lock.jsonmismatch (Missing: stylelint@16.26.1 from lock fileplus ~40 transitive deps). This is a pre-existing failure ondevelopdating to #405 (2026-04-01) — every develop CI run since has hit the same error. Scope-wise it doesn't belong in this PR; tracking separately so the dep tree can be re-resolved with care (a freshnpm installon Node 20 pulledwebpackbarforward to a version incompatible withwebpack's ProgressPlugin schema).