Skip to content

Commit a3acfeb

Browse files
authored
feat(ui): export FieldPathContext (#13806)
Fixes #12286. Supersedes #12290. As of [v3.35.0](https://github.com/payloadcms/payload/releases/tag/v3.35.0), you are no longer able to directly pass a `path` prop to a custom field component. For example: ```tsx 'use client' import React from 'react' import { TextField } from '@payloadcms/ui' import type { TextFieldClientComponent } from 'payload' export const MyCustomField: TextFieldClientComponent = (props) => { return ( <TextField {...props} path="path.to.some.other.field" // This will not be respected, because this field's context takes precedence /> ) } ``` This was introduced in #11973 where we began passing a new `potentiallyStalePath` arg to the `useField` hook that takes the path from context as priority. This change was necessary in order to fix stale paths during row manipulation while the server is processing. To ensure field components respect your custom path, you need to wrap your components with their own `FieldPathContext`: ```tsx 'use client' import React from 'react' import { TextField, FieldPathContext } from '@payloadcms/ui' import type { TextFieldClientComponent } from 'payload' export const MyCustomField: TextFieldClientComponent = (props) => { return ( <FieldPathContext path="path.to.some.other.field"> <TextField {...props} /> </FieldPathContext> ) } ``` It's possible we can remove this in the future. I explored this in #12290, but it may require some more substantial changes in architecture. These exports are labeled experimental to allow for any potential changes in behavior that we may need to make in the future. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210533177582945
1 parent a2c31fa commit a3acfeb

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

packages/ui/src/exports/client/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export { usePayloadAPI } from '../../hooks/usePayloadAPI.js'
1919
export { useResize } from '../../hooks/useResize.js'
2020
export { useThrottledEffect } from '../../hooks/useThrottledEffect.js'
2121
export { useEffectEvent } from '../../hooks/useEffectEvent.js'
22+
export { FieldPathContext, useFieldPath } from '../../forms/RenderFields/context.js'
2223

2324
export { useUseTitleField } from '../../hooks/useUseAsTitle.js'
2425

packages/ui/src/forms/RenderFields/context.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
11
import React from 'react'
22

3+
/**
4+
* All fields are wrapped in a `FieldPathContext` provider by default.
5+
* The `useFieldPath` hook will return this value if it exists, not the path the field was explicitly given.
6+
* This means if you render a field directly, you will need to wrap it with a new `FieldPathContext` provider.
7+
* Otherwise, it will return the parent's path, not the path it was explicitly given.
8+
* @example
9+
* ```tsx
10+
* 'use client'
11+
* import React from 'react'
12+
* import { TextField, FieldPathContext } from '@payloadcms/ui'
13+
* import type { TextFieldClientComponent } from 'payload'
14+
*
15+
* export const MyCustomField: TextFieldClientComponent = (props) => {
16+
* return (
17+
* <FieldPathContext path="path.to.some.other.field">
18+
* <TextField {...props} />
19+
* </FieldPathContext>
20+
* )
21+
* }
22+
* ```
23+
*
24+
* @experimental This is an experimental API and may change at any time. Use at your own discretion.
25+
*/
326
export const FieldPathContext = React.createContext<string>(undefined)
427

28+
/**
29+
* Gets the current field path from the nearest `FieldPathContext` provider.
30+
* All fields are wrapped in this context by default.
31+
*
32+
* @experimental This is an experimental API and may change at any time. Use at your own discretion.
33+
*/
534
export const useFieldPath = () => {
635
const context = React.useContext(FieldPathContext)
736

0 commit comments

Comments
 (0)