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
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- `ValidatedCheckboxControl`: Expose the component under private API's ([#71505](https://github.com/WordPress/gutenberg/pull/71505/)).
- Expose `ValidatedTextareaControl` via Private APIs ([#71495](https://github.com/WordPress/gutenberg/pull/71495))
- Add support for ValidatedFormTokenField [#71350](https://github.com/WordPress/gutenberg/pull/71350).
- Expose `ValidatedSelectControl` via Private APIs ([#71665](https://github.com/WordPress/gutenberg/pull/71665))

## 30.3.0 (2025-09-03)

Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/private-apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ValidatedCheckboxControl,
ValidatedInputControl,
ValidatedNumberControl,
ValidatedSelectControl,
ValidatedTextControl,
ValidatedTextareaControl,
ValidatedToggleControl,
Expand All @@ -40,6 +41,7 @@ lock( privateApis, {
ValidatedInputControl,
ValidatedCheckboxControl,
ValidatedNumberControl,
ValidatedSelectControl,
ValidatedTextControl,
ValidatedTextareaControl,
ValidatedToggleControl,
Expand Down
1 change: 1 addition & 0 deletions packages/dataviews/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Dataform: Add new `password` field type and field control. [#71545](https://github.com/WordPress/gutenberg/pull/71545)
- DataForm: Add a textarea control for use with the `text` field type ([#71495](https://github.com/WordPress/gutenberg/pull/71495))
- DataViews: support groupBy in the list layout. [#71548](https://github.com/WordPress/gutenberg/pull/71548)
- DataForm: support validation in select control [#71665](https://github.com/WordPress/gutenberg/pull/71665)

### Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ const ValidationComponent = ( {
} ) => {
type ValidatedItem = {
text: string;
select?: string;
textarea: string;
email: string;
telephone: string;
Expand All @@ -409,6 +410,7 @@ const ValidationComponent = ( {

const [ post, setPost ] = useState< ValidatedItem >( {
text: 'Can have letters and spaces',
select: undefined,
textarea: 'Can have letters and spaces',
email: '[email protected]',
telephone: '+306978241796',
Expand All @@ -427,6 +429,13 @@ const ValidationComponent = ( {

return null;
};
const customSelectRule = ( value: ValidatedItem ) => {
if ( value.select !== 'option1' ) {
return 'Value must be Option 1.';
}

return null;
};
const customTextareaRule = ( value: ValidatedItem ) => {
if ( ! /^[a-zA-Z ]+$/.test( value.textarea ) ) {
return 'Value must only contain letters and spaces.';
Expand Down Expand Up @@ -500,6 +509,19 @@ const ValidationComponent = ( {
custom: maybeCustomRule( customTextRule ),
},
},
{
id: 'select',
type: 'text',
label: 'Select',
elements: [
{ value: 'option1', label: 'Option 1' },
{ value: 'option2', label: 'Option 2' },
],
isValid: {
required,
custom: maybeCustomRule( customSelectRule ),
},
},
{
id: 'textarea',
type: 'text',
Expand Down Expand Up @@ -586,6 +608,7 @@ const ValidationComponent = ( {
layout: { type },
fields: [
'text',
'select',
'textarea',
'email',
'telephone',
Expand Down
41 changes: 36 additions & 5 deletions packages/dataviews/src/dataform-controls/select.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
/**
* WordPress dependencies
*/
import { SelectControl } from '@wordpress/components';
import { useCallback } from '@wordpress/element';
import { privateApis } from '@wordpress/components';
import { useCallback, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import type { DataFormControlProps } from '../types';
import { unlock } from '../lock-unlock';

const { ValidatedSelectControl } = unlock( privateApis );

export default function Select< Item >( {
data,
field,
onChange,
hideLabelFromVision,
}: DataFormControlProps< Item > ) {
const { id, label, type } = field;
const { id, type, label, description } = field;
const [ customValidity, setCustomValidity ] =
useState<
React.ComponentProps<
typeof ValidatedSelectControl
>[ 'customValidity' ]
>( undefined );

const isMultiple = type === 'array';
const value = field.getValue( { item: data } ) ?? ( isMultiple ? [] : '' );
const onChangeControl = useCallback(
Expand Down Expand Up @@ -48,10 +58,31 @@ export default function Select< Item >( {
];

return (
<SelectControl
<ValidatedSelectControl
required={ !! field.isValid?.required }
onValidate={ ( newValue: any ) => {
const message = field.isValid?.custom?.(
{
...data,
[ id ]: newValue,
},
field
);

if ( message ) {
setCustomValidity( {
type: 'invalid',
message,
} );
return;
}

setCustomValidity( undefined );
} }
customValidity={ customValidity }
label={ label }
value={ value }
help={ field.description }
help={ description }
options={ elements }
onChange={ onChangeControl }
__next40pxDefaultSize
Expand Down
Loading