DataForm: support registering 3rd party controls#74942
DataForm: support registering 3rd party controls#74942
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Flaky tests detected in 394688b. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/21358235925
|
| }; | ||
|
|
||
| export interface DataFormControls { | ||
| [ key: string ]: ComponentType< DataFormControlProps< any > >; |
There was a problem hiding this comment.
Should we just reuse this interface in FormControls in dataform-controls/index.tsx:30-32 and CustomControls in field-types/index.tsx:72-74?
| customControls?: FormControls | ||
| ) { | ||
| // Check custom controls first (they take precedence) | ||
| if ( customControls && Object.keys( customControls ).includes( type ) ) { |
There was a problem hiding this comment.
Could we just do customControls && type in customControls to avoid creating a keys array just to check existence?
| () => normalizeFields( fields ), | ||
| [ fields ] | ||
| () => normalizeFields( fields, settings?.controls ), | ||
| [ fields, settings?.controls ] |
There was a problem hiding this comment.
This memoization is useless if consumers just do:
settings={ {
controls: {
starRating: StarRatingControl,
},
} }
As we did on our story packages/dataviews/src/dataform/stories/register-controls.tsx. Not sure about what the correct solution should be but I guess we shgould update our story to use an object reference that does not chnages on rerender. We may also document that because of performance settings should not change on every rerender.
| * Allows any control name and additional configuration properties. | ||
| */ | ||
| export type EditConfigCustom = { | ||
| control: string; |
There was a problem hiding this comment.
This should probably be: control: Exclude<string, FieldTypeName | 'textarea' | 'text'>;
So on "config.control === 'textarea'", TypeScript narrows to EditConfigTextarea instead of EditConfigTextarea | EditConfigCustom.
| control: string; | |
| control: Exclude<string, FieldTypeName | 'textarea' | 'text'>; |
| config, | ||
| hideLabelFromVision, | ||
| validity, | ||
| }: DataFormControlProps< Item > & { validity?: FieldValidity } ) { |
There was a problem hiding this comment.
Do we need & { validity?: FieldValidity } here? It seems DataFormControlProps already includes it.
Closes #74856
What?
Adds support for registering custom controls in DataForm via a new settings prop.
Custom controls can be referenced by string name:
Or with additional configuration via EditConfig:
Why?
Field authors can already declare custom Edit controls:
However, this is not serializable as so cannot be used in places like JSON or PHP. By allowing 3rd parties to register their own custom controls as if they were core ones, we unlock serialization for them.
How?
settingsprop to DataForm with a controls object that maps control names to React components.Testing Instructions