-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat: conditional blocks #13801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: conditional blocks #13801
Changes from 8 commits
6b6e639
7090774
31d29cc
c9e0677
2decaec
53b357a
4900d75
054a37a
7a9d129
87d9c2a
261b15e
0e59f8e
de75960
25ca34e
3c5bcbc
23a4719
02c78d2
faa1dca
2b3151e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,24 +104,6 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { | |
return true | ||
})() | ||
|
||
const clientBlocks = useMemo(() => { | ||
if (!blockReferences) { | ||
return blocks | ||
} | ||
|
||
const resolvedBlocks: ClientBlock[] = [] | ||
|
||
for (const blockReference of blockReferences) { | ||
const block = | ||
typeof blockReference === 'string' ? config.blocksMap[blockReference] : blockReference | ||
if (block) { | ||
resolvedBlocks.push(block) | ||
} | ||
} | ||
|
||
return resolvedBlocks | ||
}, [blockReferences, blocks, config.blocksMap]) | ||
|
||
const memoizedValidate = useCallback( | ||
(value, options) => { | ||
// alternative locales can be null | ||
|
@@ -136,6 +118,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { | |
) | ||
|
||
const { | ||
blocksFilterOptions, | ||
customComponents: { AfterInput, BeforeInput, Description, Error, Label } = {}, | ||
disabled, | ||
errorPaths, | ||
|
@@ -150,6 +133,38 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { | |
validate: memoizedValidate, | ||
}) | ||
|
||
const { clientBlocks, clientBlocksAfterFilter } = useMemo(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the same as the previous We need both the filtered and unfiltered client blocks. The filtered ones are only used for the drawer. We still need the ability to display existing blocks that no longer match the filter and fail validation. |
||
let resolvedBlocks: ClientBlock[] = [] | ||
|
||
if (!blockReferences) { | ||
resolvedBlocks = blocks | ||
} else { | ||
for (const blockReference of blockReferences) { | ||
const block = | ||
typeof blockReference === 'string' ? config.blocksMap[blockReference] : blockReference | ||
if (block) { | ||
resolvedBlocks.push(block) | ||
} | ||
} | ||
} | ||
|
||
if (Array.isArray(blocksFilterOptions)) { | ||
const clientBlocksAfterFilter = resolvedBlocks.filter((block) => { | ||
const blockSlug = typeof block === 'string' ? block : block.slug | ||
return blocksFilterOptions.includes(blockSlug) | ||
}) | ||
|
||
return { | ||
clientBlocks: resolvedBlocks, | ||
clientBlocksAfterFilter, | ||
} | ||
} | ||
return { | ||
clientBlocks: resolvedBlocks, | ||
clientBlocksAfterFilter: resolvedBlocks, | ||
} | ||
}, [blockReferences, blocks, blocksFilterOptions, config.blocksMap]) | ||
|
||
const addRow = useCallback( | ||
(rowIndex: number, blockType: string) => { | ||
addFieldRow({ | ||
|
@@ -404,10 +419,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { | |
const { blockType, isLoading } = row | ||
|
||
const blockConfig: ClientBlock = | ||
config.blocksMap[blockType] ?? | ||
((blockReferences ?? blocks).find( | ||
(block) => typeof block !== 'string' && block.slug === blockType, | ||
) as ClientBlock) | ||
config.blocksMap[blockType] ?? clientBlocks.find((block) => block.slug === blockType) | ||
|
||
if (blockConfig) { | ||
const rowPath = `${path}.${i}` | ||
|
@@ -427,7 +439,8 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { | |
{...draggableSortableItemProps} | ||
addRow={addRow} | ||
block={blockConfig} | ||
blocks={blockReferences ?? blocks} | ||
// Pass all blocks, not just clientBlocksAfterFilter, as existing blocks should still be displayed even if they don't match the new filter | ||
blocks={clientBlocks} | ||
copyRow={copyRow} | ||
duplicateRow={duplicateRow} | ||
errorCount={rowErrorCount} | ||
|
@@ -499,7 +512,8 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { | |
<BlocksDrawer | ||
addRow={addRow} | ||
addRowIndex={rows?.length || 0} | ||
blocks={blockReferences ?? blocks} | ||
// Only allow choosing filtered blocks | ||
blocks={clientBlocksAfterFilter} | ||
drawerSlug={drawerSlug} | ||
labels={labels} | ||
/> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for keeping name
filterOptions
despite different type is in PR description