Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/fields/collapsible.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ export const MyCollapsibleField: Field = {

The Collapsible Field inherits all of the default admin options from the base [Field Admin Config](./overview#admin-options), plus the following additional options:

| Option | Description |
| ------------------- | ------------------------------- |
| **`initCollapsed`** | Set the initial collapsed state |
| Option | Description |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **`initCollapsed`** | Set the initial collapsed state |
| **`persistCollapsedState`** | When `true` (default), the Admin Panel remembers the collapsed state per document. Set to `false` to always use `initCollapsed` on mount |

## Example

Expand Down
3 changes: 3 additions & 0 deletions packages/payload/src/fields/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,7 @@ export type CollapsibleField = {
>
} & FieldAdmin['components']
initCollapsed?: boolean
persistCollapsedState?: boolean
} & FieldAdmin
label?: Required<FieldBase['label']>
}
Expand All @@ -839,6 +840,7 @@ export type CollapsibleField = {
>
} & FieldAdmin['components']
initCollapsed?: boolean
persistCollapsedState?: boolean
} & FieldAdmin
label: Required<FieldBase['label']>
}
Expand All @@ -848,6 +850,7 @@ export type CollapsibleField = {
export type CollapsibleFieldClient = {
admin?: {
initCollapsed?: boolean
persistCollapsedState?: boolean
} & AdminClient
fields: ClientField[]
label: StaticLabel
Expand Down
30 changes: 26 additions & 4 deletions packages/ui/src/fields/Collapsible/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ const baseClass = 'collapsible-field'
const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {
const {
field,
field: { admin: { className, description, initCollapsed = false } = {}, fields, label } = {},
field: {
admin: { className, description, initCollapsed = false, persistCollapsedState = true } = {},
fields,
label,
} = {},
indexPath,
parentPath,
parentSchemaPath,
Expand All @@ -49,6 +53,10 @@ const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {

const onToggle = useCallback(
async (newCollapsedState: boolean): Promise<void> => {
if (!persistCollapsedState) {
return
}

const existingPreferences: DocumentPreferences = await getPreference(preferencesKey)

if (preferencesKey) {
Expand Down Expand Up @@ -76,12 +84,19 @@ const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {
})
}
},
[preferencesKey, fieldPreferencesKey, getPreference, setPreference, path],
[
preferencesKey,
fieldPreferencesKey,
getPreference,
setPreference,
path,
persistCollapsedState,
],
)

useEffect(() => {
const fetchInitialState = async () => {
if (preferencesKey) {
if (preferencesKey && persistCollapsedState) {
const preferences = await getPreference(preferencesKey)
const specificPreference = path
? preferences?.fields?.[path]?.collapsed
Expand All @@ -98,7 +113,14 @@ const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {
}

void fetchInitialState()
}, [getPreference, preferencesKey, fieldPreferencesKey, initCollapsed, path])
}, [
getPreference,
preferencesKey,
fieldPreferencesKey,
initCollapsed,
path,
persistCollapsedState,
])

const styles = useMemo(() => mergeFieldStyles(field), [field])

Expand Down
45 changes: 45 additions & 0 deletions test/fields/collections/Collapsible/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,51 @@ describe('Collapsibles', () => {
await expect(collapsedCollapsible).toBeVisible()
})

test('should persist collapsed state by default when revisiting a document', async () => {
const doc = await payload.create({
collection: collapsibleFieldsSlug,
data: {
text: 'test',
},
})

await page.goto(url.edit(doc.id))

const collapsibleToggle = page.locator('#field-collapsible-_index-0 .collapsible__toggle')

await expect(collapsibleToggle).toHaveClass(/collapsible__toggle--open/)
await collapsibleToggle.click()
await expect(collapsibleToggle).toHaveClass(/collapsible__toggle--collapsed/)

await page.goto(url.list)
await page.goto(url.edit(doc.id))

await expect(collapsibleToggle).toHaveClass(/collapsible__toggle--collapsed/)
})

test('should reset collapsed state when persistCollapsedState is false', async () => {
const doc = await payload.create({
collection: collapsibleFieldsSlug,
data: {
noPersistText: 'test',
text: 'test',
},
})

await page.goto(url.edit(doc.id))

const collapsibleToggle = page.locator('#field-collapsible-_index-5 .collapsible__toggle')

await expect(collapsibleToggle).toHaveClass(/collapsible__toggle--open/)
await collapsibleToggle.click()
await expect(collapsibleToggle).toHaveClass(/collapsible__toggle--collapsed/)

await page.goto(url.list)
await page.goto(url.edit(doc.id))

await expect(collapsibleToggle).toHaveClass(/collapsible__toggle--open/)
})

test('should render CollapsibleLabel using a function', async () => {
const label = 'custom row label'
await page.goto(url.create)
Expand Down
17 changes: 16 additions & 1 deletion test/fields/collections/Collapsible/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,22 @@ const CollapsibleFields: CollectionConfig = {
},
],
},
]
{
label: 'Collapsible Field - Do Not Persist State',
type: 'collapsible',
admin: {
description: 'This collapsible does not persist collapsed state via document preferences.',
initCollapsed: false,
persistCollapsedState: false,
},
fields: [
{
name: 'noPersistText',
type: 'text',
},
],
},
],
}

export default CollapsibleFields
2 changes: 2 additions & 0 deletions test/fields/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,7 @@ export interface CollapsibleField {
id?: string | null;
}[]
| null;
noPersistText?: string | null;
updatedAt: string;
createdAt: string;
}
Expand Down Expand Up @@ -2946,6 +2947,7 @@ export interface CollapsibleFieldsSelect<T extends boolean = true> {
innerCollapsible?: T;
id?: T;
};
noPersistText?: T;
updatedAt?: T;
createdAt?: T;
}
Expand Down
Loading