Skip to content
Merged
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
Revert "DataForm: Streamline validation behavior (#71345)"
This reverts commit 55d79f3.
  • Loading branch information
oandregal authored Aug 26, 2025
commit d8eb424cf4b9889bc2a20e93e00fa3764a1b41af
4 changes: 0 additions & 4 deletions packages/dataviews/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@

- DataViews: Fix incorrect documentation for `defaultLayouts` prop. [#71334](https://github.com/WordPress/gutenberg/pull/71334)

### Enhancements

- DataForm: Add second argument to the `onChange` callback that contains an `isValid` boolean property and remove `isItemValid` utility. [#71345](https://github.com/WordPress/gutenberg/pull/71345)

## 7.0.0 (2025-08-20)

### Breaking changes
Expand Down
4 changes: 2 additions & 2 deletions packages/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ const form = {

#### `onChange`: `function`

Callback function that receives an object with the edits done by the user. It also receives a second parameter that indicates whether the current item is valid or not according to the current fields and form configuration.
Callback function that receives an object with the edits done by the user.

Example:

Expand All @@ -598,7 +598,7 @@ const data = {
date: '2012-04-23T18:25:43.511Z',
};

const onChange = ( edits, { isValid } ) => {
const onChange = ( edits ) => {
/*
* edits will contain user edits.
* For example, if the user edited the title
Expand Down
23 changes: 1 addition & 22 deletions packages/dataviews/src/components/dataform/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import type { DataFormProps } from '../../types';
import { DataFormProvider } from '../dataform-context';
import { normalizeFields } from '../../normalize-fields';
import { DataFormLayout } from '../../dataforms-layouts/data-form-layout';
import { isItemValid } from '../../validation';

export default function DataForm< Item >( {
data,
Expand All @@ -23,33 +22,13 @@ export default function DataForm< Item >( {
[ fields ]
);

const onChangeWithValidation = ( updatedData: Partial< Item > ) => {
if ( ! onChange ) {
return;
}

const isValid = isItemValid(
{
...data,
...updatedData,
},
fields,
form
);
onChange( updatedData, { isValid } );
};

if ( ! form.fields ) {
return null;
}

return (
<DataFormProvider fields={ normalizedFields }>
<DataFormLayout
data={ data }
form={ form }
onChange={ onChangeWithValidation }
/>
<DataFormLayout data={ data } form={ form } onChange={ onChange } />
</DataFormProvider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
* Internal dependencies
*/
import DataForm from '../index';
import { isItemValid } from '../../../validation';
import type {
Field,
Form,
Expand Down Expand Up @@ -402,7 +403,6 @@ const ValidationComponent = ( {
boolean: true,
customEdit: 'custom control',
} );
const [ isPostValid, setIsValid ] = useState( true );

const customTextRule = ( value: ValidatedItem ) => {
if ( ! /^[a-zA-Z ]+$/.test( value.text ) ) {
Expand Down Expand Up @@ -483,26 +483,26 @@ const ValidationComponent = ( {
fields: [ 'text', 'email', 'integer', 'boolean', 'customEdit' ],
};

const canSave = isItemValid( post, _fields, form );

return (
<form>
<VStack alignment="left">
<DataForm< ValidatedItem >
data={ post }
fields={ _fields }
form={ form }
onChange={ ( edits, { isValid } ) => {
onChange={ ( edits ) =>
setPost( ( prev ) => ( {
...prev,
...edits,
} ) );

setIsValid( isValid );
} }
} ) )
}
/>
<Button
__next40pxDefaultSize
accessibleWhenDisabled
disabled={ ! isPostValid }
disabled={ ! canSave }
variant="primary"
>
Submit
Expand Down
25 changes: 7 additions & 18 deletions packages/dataviews/src/test/dataform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,9 @@ describe( 'DataForm component', () => {
await user.type( titleInput, newValue );
expect( onChange ).toHaveBeenCalledTimes( newValue.length );
for ( let i = 0; i < newValue.length; i++ ) {
expect( onChange ).toHaveBeenNthCalledWith(
i + 1,
{
title: newValue[ i ],
},
{ isValid: true }
);
expect( onChange ).toHaveBeenNthCalledWith( i + 1, {
title: newValue[ i ],
} );
}
} );

Expand Down Expand Up @@ -388,10 +384,7 @@ describe( 'DataForm component', () => {

// Modal should be closed and onChange should be called
expect( screen.queryByRole( 'dialog' ) ).not.toBeInTheDocument();
expect( onChange ).toHaveBeenCalledWith(
{ title: 'New Title' },
{ isValid: true }
);
expect( onChange ).toHaveBeenCalledWith( { title: 'New Title' } );
} );

it( 'should call onChange with the correct value for each typed character', async () => {
Expand All @@ -414,13 +407,9 @@ describe( 'DataForm component', () => {
await user.type( input, newValue );
expect( onChange ).toHaveBeenCalledTimes( newValue.length );
for ( let i = 0; i < newValue.length; i++ ) {
expect( onChange ).toHaveBeenNthCalledWith(
i + 1,
{
title: newValue[ i ],
},
{ isValid: true }
);
expect( onChange ).toHaveBeenNthCalledWith( i + 1, {
title: newValue[ i ],
} );
}
} );

Expand Down
5 changes: 1 addition & 4 deletions packages/dataviews/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -756,10 +756,7 @@ export interface DataFormProps< Item > {
data: Item;
fields: Field< Item >[];
form: Form;
onChange: (
value: Record< string, any >,
validation: { isValid: boolean }
) => void;
onChange: ( value: Record< string, any > ) => void;
}

export interface FieldLayoutProps< Item > {
Expand Down
15 changes: 7 additions & 8 deletions packages/fields/src/actions/reorder-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { store as coreStore } from '@wordpress/core-data';
import { __ } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { useState } from '@wordpress/element';
import { DataForm } from '@wordpress/dataviews';
import { DataForm, isItemValid } from '@wordpress/dataviews';
import {
Button,
__experimentalHStack as HStack,
Expand All @@ -31,7 +31,6 @@ function ReorderModal( {
onActionPerformed,
}: RenderModalProps< BasePost > ) {
const [ item, setItem ] = useState( items[ 0 ] );
const [ isItemValid, setIsValid ] = useState( true );
const orderInput = item.menu_order;
const { editEntityRecord, saveEditedEntityRecord } =
useDispatch( coreStore );
Expand All @@ -41,7 +40,7 @@ function ReorderModal( {
async function onOrder( event: React.FormEvent ) {
event.preventDefault();

if ( ! isItemValid ) {
if ( ! isItemValid( item, fields, formOrderAction ) ) {
return;
}

Expand Down Expand Up @@ -69,6 +68,7 @@ function ReorderModal( {
} );
}
}
const isSaveDisabled = ! isItemValid( item, fields, formOrderAction );
return (
<form onSubmit={ onOrder }>
<VStack spacing="5">
Expand All @@ -81,13 +81,12 @@ function ReorderModal( {
data={ item }
fields={ fields }
form={ formOrderAction }
onChange={ ( changes, { isValid } ) => {
onChange={ ( changes ) =>
setItem( {
...item,
...changes,
} );
setIsValid( isValid );
} }
} )
}
/>
<HStack justify="right">
<Button
Expand All @@ -104,7 +103,7 @@ function ReorderModal( {
variant="primary"
type="submit"
accessibleWhenDisabled
disabled={ ! isItemValid }
disabled={ isSaveDisabled }
>
{ __( 'Save' ) }
</Button>
Expand Down
Loading