Skip to content

Commit 672d88f

Browse files
committed
Add useRenderAppenderWithLimit hook for controlling inner block limits
1 parent d87106f commit 672d88f

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ export { usePostMetaValue } from './use-post-meta-value';
1818
export { useTaxonomy } from './use-taxonomy';
1919
export { useIsSupportedMetaField } from './use-is-supported-meta-value';
2020
export { useFlatInnerBlocks } from './use-flat-inner-blocks';
21+
export { useRenderAppenderWithLimit } from './use-render-appender-with-limit';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useSelect } from '@wordpress/data';
2+
import {
3+
store as blockEditorStore,
4+
useBlockEditContext,
5+
InnerBlocks,
6+
} from '@wordpress/block-editor';
7+
8+
export function useRenderAppenderWithLimit(limit: number, buttonAppender = false) {
9+
const { clientId } = useBlockEditContext();
10+
const appenderType = buttonAppender
11+
? InnerBlocks.ButtonBlockAppender
12+
: InnerBlocks.DefaultBlockAppender;
13+
14+
return useSelect(
15+
(select) => {
16+
// @ts-expect-error - TS doesn't know about the block editor store
17+
const { innerBlocks } = select(blockEditorStore).getBlock(clientId);
18+
const numberOfInnerBlocks = innerBlocks.length;
19+
const shouldRenderAppender = numberOfInnerBlocks < limit;
20+
return shouldRenderAppender ? appenderType : false;
21+
},
22+
[clientId, limit],
23+
);
24+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# `useRenderAppenderWithLimit`
2+
3+
There are times when we need more granular control over how many blocks can be added to a block that supports inner blocks. That’s where the `useRenderAppenderWithLimit` custom hook comes in. With a single line of code, it gives us an easy way to enforce a maximum number of inner blocks.
4+
5+
The hook will return either false or the block appender, depending on the maximum limit you pass in. Behind the scenes, it handles the heavy lifting by fetching and counting the inner blocks for your block, then conditionally returning the appender only when allowed.
6+
7+
## Usage
8+
9+
```js
10+
import { useBlockProps, useInnerBlockProps } from '@wordpress/block-editor';
11+
import { useRenderAppenderWithLimit } from '@10up/block-components';
12+
13+
function BlockEdit() {
14+
const renderAppender = useRenderAppenderWithLimit(4);
15+
16+
const blockProps = useBlockProps();
17+
const innerBlocksProps = useInnerBlocksProps(
18+
{},
19+
{
20+
...
21+
renderAppender,
22+
},
23+
);
24+
25+
return (
26+
<div {...useBlockProps}>
27+
<div {...innerBlocksProps}>
28+
</div>
29+
);
30+
}
31+
```

0 commit comments

Comments
 (0)