fix(ui): awaits form state before rendering conditional fields (#9933)
When a condition exists on a field and it resolves to `false`, it currently "blinks" in and out when rendered within an array or block row. This is because when add rows to form state, we iterate over the _fields_ of that row and render their respective components. Then when conditions are checked for that field, we're expecting `passesCondition` to be explicitly `false`, ultimately _rendering_ the field for a brief moment before form state returns with evaluated conditions. The fix is to set these fields into local form state with a new `isLoading: true` prop, then display a loader within the row until form state returns with its proper conditions.
This commit is contained in:
@@ -92,6 +92,49 @@ const ConditionalLogic: CollectionConfig = {
|
||||
condition: ({ groupSelection }) => groupSelection === 'group2',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'enableConditionalFields',
|
||||
type: 'checkbox',
|
||||
},
|
||||
{
|
||||
name: 'arrayWithConditionalField',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'textWithCondition',
|
||||
type: 'text',
|
||||
admin: {
|
||||
condition: (data) => data.enableConditionalFields,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'blocksWithConditionalField',
|
||||
type: 'blocks',
|
||||
blocks: [
|
||||
{
|
||||
slug: 'blockWithConditionalField',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'textWithCondition',
|
||||
type: 'text',
|
||||
admin: {
|
||||
condition: (data) => data.enableConditionalFields,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -541,6 +541,26 @@ describe('fields', () => {
|
||||
const fieldRelyingOnSiblingData = page.locator('input#field-reliesOnParentGroup')
|
||||
await expect(fieldRelyingOnSiblingData).toBeVisible()
|
||||
})
|
||||
|
||||
test('should not render conditional fields when adding array rows', async () => {
|
||||
await page.goto(url.create)
|
||||
const addRowButton = page.locator('.array-field__add-row')
|
||||
const fieldWithConditionSelector =
|
||||
'input#field-arrayWithConditionalField__0__textWithCondition'
|
||||
await addRowButton.click()
|
||||
|
||||
const wasFieldAttached = await page
|
||||
.waitForSelector(fieldWithConditionSelector, {
|
||||
state: 'attached',
|
||||
timeout: 100, // A small timeout to catch any transient rendering
|
||||
})
|
||||
.catch(() => false) // If it doesn't appear, this resolves to `false`
|
||||
|
||||
expect(wasFieldAttached).toBeFalsy()
|
||||
const fieldToToggle = page.locator('input#field-enableConditionalFields')
|
||||
await fieldToToggle.click()
|
||||
await expect(page.locator(fieldWithConditionSelector)).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
describe('tabs', () => {
|
||||
|
||||
Reference in New Issue
Block a user