Skip to content

Commit d1050e6

Browse files
committed
fix(ui): hide entire tabs field when admin.condition is false
Tabs field with `admin.condition` only hid child fields — tab buttons and description remained visible. Tabs branch in `addFieldStatePromise` never wrote `state[path]` for the container, so `WatchCondition` saw `passesCondition === undefined` and rendered the tabs UI regardless. Mirror row/collapsible pattern: write `state[path]` with `disableFormData` and `passesCondition: false` when the condition fails. Fixes #12761
1 parent ac6f86c commit d1050e6

4 files changed

Lines changed: 69 additions & 2 deletions

File tree

packages/ui/src/forms/fieldSchemasToFormState/addFieldStatePromise.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,16 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
947947
state,
948948
})
949949
} else if (field.type === 'tabs') {
950+
if (!filter || filter(args)) {
951+
state[path] = {
952+
disableFormData: true,
953+
}
954+
955+
if (passesCondition === false) {
956+
state[path].passesCondition = false
957+
}
958+
}
959+
950960
return iterateFields({
951961
id,
952962
addErrorPathToParent: addErrorPathToParentArg,

test/fields/collections/ConditionalLogic/e2e.spec.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import type { BrowserContext, Page } from '@playwright/test'
22

33
import { expect, test } from '@playwright/test'
4-
import { addArrayRow } from '../../../__helpers/e2e/fields/array/index.js'
5-
import { addBlock } from '../../../__helpers/e2e/fields/blocks/index.js'
64
import path from 'path'
75
import { fileURLToPath } from 'url'
86

97
import type { PayloadTestSDK } from '../../../__helpers/shared/sdk/index.js'
108
import type { Config } from '../../payload-types.js'
119

1210
import { assertNetworkRequests } from '../../../__helpers/e2e/assertNetworkRequests.js'
11+
import { addArrayRow } from '../../../__helpers/e2e/fields/array/index.js'
12+
import { addBlock } from '../../../__helpers/e2e/fields/blocks/index.js'
1313
import {
1414
ensureCompilationIsDone,
1515
initPageConsoleErrorCatch,
@@ -289,6 +289,25 @@ describe('Conditional Logic', () => {
289289
await expect(fieldWithOperationCondition).toBeHidden()
290290
})
291291

292+
test('should hide entire tabs field UI when admin.condition is false', async () => {
293+
await page.goto(url.create)
294+
295+
const tabsField = page.locator('.tabs-field').filter({
296+
has: page.locator('button:has-text("Tab With Condition 1")'),
297+
})
298+
299+
await expect(tabsField).toBeHidden()
300+
301+
const enableTabsToggle = page.locator('label[for=field-enableTabs]')
302+
await enableTabsToggle.click()
303+
304+
await expect(tabsField).toBeVisible()
305+
await expect(tabsField.locator('button:has-text("Tab With Condition 1")')).toBeVisible()
306+
307+
await enableTabsToggle.click()
308+
await expect(tabsField).toBeHidden()
309+
})
310+
292311
test('should toggle conditional field when radio changes inside a block', async () => {
293312
await page.goto(url.create)
294313

test/fields/collections/ConditionalLogic/index.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,38 @@ const ConditionalLogic: CollectionConfig = {
231231
},
232232
],
233233
},
234+
{
235+
name: 'enableTabs',
236+
type: 'checkbox',
237+
},
238+
{
239+
type: 'tabs',
240+
admin: {
241+
condition: ({ enableTabs }) => Boolean(enableTabs),
242+
},
243+
tabs: [
244+
{
245+
label: 'Tab With Condition 1',
246+
description: 'Description for conditional tab 1',
247+
fields: [
248+
{
249+
name: 'conditionalTabsField1',
250+
type: 'text',
251+
},
252+
],
253+
},
254+
{
255+
label: 'Tab With Condition 2',
256+
description: 'Description for conditional tab 2',
257+
fields: [
258+
{
259+
name: 'conditionalTabsField2',
260+
type: 'text',
261+
},
262+
],
263+
},
264+
],
265+
},
234266
{
235267
name: 'arrayOne',
236268
type: 'array',

test/fields/payload-types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,9 @@ export interface ConditionalLogic {
10041004
blockType: 'blockWithRadioCondition';
10051005
}[]
10061006
| null;
1007+
enableTabs?: boolean | null;
1008+
conditionalTabsField1?: string | null;
1009+
conditionalTabsField2?: string | null;
10071010
arrayOne?:
10081011
| {
10091012
title?: string | null;
@@ -2865,6 +2868,9 @@ export interface ConditionalLogicSelect<T extends boolean = true> {
28652868
blockName?: T;
28662869
};
28672870
};
2871+
enableTabs?: T;
2872+
conditionalTabsField1?: T;
2873+
conditionalTabsField2?: T;
28682874
arrayOne?:
28692875
| T
28702876
| {

0 commit comments

Comments
 (0)