-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DataForm: enable fields to declare a different layout #66531
Merged
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
2f49a88
Add DataFormProvider for fields
louwie17 7fc515a
Add dataform layout component and inline layout
louwie17 2190773
Fix label in panel view
louwie17 35fa64c
Remove unneeded line
louwie17 c848178
Update `field` to FormField as well
louwie17 7824f36
Remove combinedFields usage
louwie17 01da3c5
Remove old use of View
louwie17 6eae567
Add label and move field type check to 'getFieldDefinition'
louwie17 d22d764
Create types of each view
louwie17 9235f5e
Add sticky example
louwie17 d017417
Update combined fields story
louwie17 ecf42e8
Fix change I missed during rebase
louwie17 7cf260b
Remove old status_and_visibility field
louwie17 3ec2fd1
Rename fields to children for clarity
louwie17 8b96c7e
Add children support to regular layout
louwie17 b30b780
Replace inline with labelPosition
louwie17 f333902
Remove field type checking within dataform layouts
louwie17 40963fe
Update DataForm context to align more with DataViews context
louwie17 6c0a927
Add seperated combined form field type
louwie17 1b76afa
Simplify: use always id
oandregal bce9399
Use the new API for configuring feature image
oandregal ad94776
Remove unnecessary layout for field
oandregal 2b71c33
Feature image: default label position
oandregal b52ef79
Implement labelPosition none for panel layout
oandregal 53c84b4
Implement labelPosition none for regular layout
oandregal 0a4be12
Panel layout: improve button spacing when labelPosition is none or top
oandregal 0f6399b
Panel layout: do not style the label as a base control.
oandregal 7c1004f
Style for layout regular label
oandregal 2b27db1
Panel: better spacing
oandregal b201728
Destructure all props
oandregal 695b629
DataFormLayout: props are data, form, onChange, children
oandregal fa872ee
Extract FieldLayoutProps as a common interface for all layouts
oandregal 3f709f9
Introduce normalizeFormFields & form.labelPosition
oandregal a813725
Storybook: remove toFormField
oandregal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
69 changes: 0 additions & 69 deletions
69
packages/dataviews/src/components/dataform-combined-edit/index.tsx
This file was deleted.
Oops, something went wrong.
16 changes: 0 additions & 16 deletions
16
packages/dataviews/src/components/dataform-combined-edit/style.scss
This file was deleted.
Oops, something went wrong.
30 changes: 30 additions & 0 deletions
30
packages/dataviews/src/components/dataform-context/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { createContext } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { NormalizedField } from '../../types'; | ||
|
||
type DataFormContextType< Item > = { | ||
fields: NormalizedField< Item >[]; | ||
}; | ||
|
||
const DataFormContext = createContext< DataFormContextType< any > >( { | ||
fields: [], | ||
} ); | ||
|
||
export function DataFormProvider< Item >( { | ||
fields, | ||
children, | ||
}: React.PropsWithChildren< { fields: NormalizedField< Item >[] } > ) { | ||
return ( | ||
<DataFormContext.Provider value={ { fields } }> | ||
{ children } | ||
</DataFormContext.Provider> | ||
); | ||
} | ||
|
||
export default DataFormContext; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,34 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useMemo } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { DataFormProps } from '../../types'; | ||
import { getFormLayout } from '../../dataforms-layouts'; | ||
import { DataFormProvider } from '../dataform-context'; | ||
import { normalizeFields } from '../../normalize-fields'; | ||
import { DataFormLayout } from '../../dataforms-layouts/data-form-layout'; | ||
|
||
export default function DataForm< Item >( { | ||
data, | ||
form, | ||
...props | ||
fields, | ||
onChange, | ||
}: DataFormProps< Item > ) { | ||
const layout = getFormLayout( form.type ?? 'regular' ); | ||
if ( ! layout ) { | ||
const normalizedFields = useMemo( | ||
oandregal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
() => normalizeFields( fields ), | ||
[ fields ] | ||
); | ||
|
||
if ( ! form.fields ) { | ||
return null; | ||
} | ||
|
||
return <layout.component form={ form } { ...props } />; | ||
return ( | ||
<DataFormProvider fields={ normalizedFields }> | ||
<DataFormLayout data={ data } form={ form } onChange={ onChange } /> | ||
</DataFormProvider> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useState } from '@wordpress/element'; | ||
import { useMemo, useState } from '@wordpress/element'; | ||
import { ToggleControl } from '@wordpress/components'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import DataForm from '../index'; | ||
import type { CombinedFormField, Field } from '../../../types'; | ||
import type { Field, Form } from '../../../types'; | ||
|
||
type SamplePost = { | ||
title: string; | ||
|
@@ -27,8 +28,13 @@ const meta = { | |
type: { | ||
control: { type: 'select' }, | ||
description: | ||
'Chooses the layout of the form. "regular" is the default layout.', | ||
options: [ 'regular', 'panel' ], | ||
'Chooses the default layout of each field. "regular" is the default layout.', | ||
options: [ 'default', 'regular', 'panel' ], | ||
}, | ||
labelPosition: { | ||
control: { type: 'select' }, | ||
description: 'Chooses the label position of the layout.', | ||
options: [ 'default', 'top', 'side', 'none' ], | ||
}, | ||
}, | ||
}; | ||
|
@@ -97,9 +103,33 @@ const fields = [ | |
return item.status !== 'private'; | ||
}, | ||
}, | ||
{ | ||
id: 'sticky', | ||
label: 'Sticky', | ||
type: 'integer', | ||
Edit: ( { field, onChange, data, hideLabelFromVision } ) => { | ||
const { id, getValue } = field; | ||
return ( | ||
<ToggleControl | ||
__nextHasNoMarginBottom | ||
label={ hideLabelFromVision ? '' : field.label } | ||
checked={ getValue( { item: data } ) } | ||
onChange={ () => | ||
onChange( { [ id ]: ! getValue( { item: data } ) } ) | ||
} | ||
/> | ||
); | ||
}, | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added sticky example, which flows nicer for the inline example. |
||
] as Field< SamplePost >[]; | ||
|
||
export const Default = ( { type }: { type: 'panel' | 'regular' } ) => { | ||
export const Default = ( { | ||
type, | ||
labelPosition, | ||
}: { | ||
type: 'default' | 'regular' | 'panel'; | ||
labelPosition: 'default' | 'top' | 'side' | 'none'; | ||
} ) => { | ||
const [ post, setPost ] = useState( { | ||
title: 'Hello, World!', | ||
order: 2, | ||
|
@@ -108,29 +138,36 @@ export const Default = ( { type }: { type: 'panel' | 'regular' } ) => { | |
reviewer: 'fulano', | ||
date: '2021-01-01T12:00:00', | ||
birthdate: '1950-02-23T12:00:00', | ||
sticky: false, | ||
} ); | ||
|
||
const form = { | ||
fields: [ | ||
'title', | ||
'order', | ||
'author', | ||
'reviewer', | ||
'status', | ||
'password', | ||
'date', | ||
'birthdate', | ||
], | ||
}; | ||
const form = useMemo( | ||
() => ( { | ||
type, | ||
labelPosition, | ||
fields: [ | ||
'title', | ||
'order', | ||
{ | ||
id: 'sticky', | ||
layout: 'regular', | ||
labelPosition: 'side', | ||
}, | ||
'author', | ||
'reviewer', | ||
'password', | ||
'date', | ||
'birthdate', | ||
], | ||
} ), | ||
[ type, labelPosition ] | ||
) as Form; | ||
|
||
return ( | ||
<DataForm< SamplePost > | ||
data={ post } | ||
fields={ fields } | ||
form={ { | ||
...form, | ||
type, | ||
} } | ||
form={ form } | ||
onChange={ ( edits ) => | ||
setPost( ( prev ) => ( { | ||
...prev, | ||
|
@@ -142,40 +179,45 @@ export const Default = ( { type }: { type: 'panel' | 'regular' } ) => { | |
}; | ||
|
||
const CombinedFieldsComponent = ( { | ||
type = 'regular', | ||
combinedFieldDirection = 'vertical', | ||
type, | ||
labelPosition, | ||
}: { | ||
type: 'panel' | 'regular'; | ||
combinedFieldDirection: 'vertical' | 'horizontal'; | ||
type: 'default' | 'regular' | 'panel'; | ||
labelPosition: 'default' | 'top' | 'side' | 'none'; | ||
} ) => { | ||
const [ post, setPost ] = useState( { | ||
const [ post, setPost ] = useState< SamplePost >( { | ||
title: 'Hello, World!', | ||
order: 2, | ||
author: 1, | ||
status: 'draft', | ||
reviewer: 'fulano', | ||
date: '2021-01-01T12:00:00', | ||
birthdate: '1950-02-23T12:00:00', | ||
} ); | ||
|
||
const form = { | ||
fields: [ 'title', 'status_and_visibility', 'order', 'author' ], | ||
combinedFields: [ | ||
{ | ||
id: 'status_and_visibility', | ||
label: 'Status & Visibility', | ||
children: [ 'status', 'password' ], | ||
direction: combinedFieldDirection, | ||
render: ( { item } ) => item.status, | ||
}, | ||
] as CombinedFormField< any >[], | ||
}; | ||
const form = useMemo( | ||
() => ( { | ||
type, | ||
labelPosition, | ||
fields: [ | ||
'title', | ||
{ | ||
id: 'status', | ||
label: 'Status & Visibility', | ||
children: [ 'status', 'password' ], | ||
}, | ||
'order', | ||
'author', | ||
], | ||
} ), | ||
[ type, labelPosition ] | ||
) as Form; | ||
|
||
return ( | ||
<DataForm | ||
<DataForm< SamplePost > | ||
data={ post } | ||
fields={ fields } | ||
form={ { | ||
...form, | ||
type, | ||
} } | ||
form={ form } | ||
onChange={ ( edits ) => | ||
setPost( ( prev ) => ( { | ||
...prev, | ||
|
@@ -191,11 +233,8 @@ export const CombinedFields = { | |
render: CombinedFieldsComponent, | ||
argTypes: { | ||
...meta.argTypes, | ||
combinedFieldDirection: { | ||
control: { type: 'select' }, | ||
description: | ||
'Chooses the direction of the combined field. "vertical" is the default layout.', | ||
options: [ 'vertical', 'horizontal' ], | ||
}, | ||
}, | ||
args: { | ||
type: 'panel', | ||
}, | ||
}; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a DataForm context to store the field definitions. This way I can more easily manage the layout on a field level without having to make sure I drill down the field definitions.