diff --git a/packages/dataviews/src/dataform-controls/datetime.tsx b/packages/dataviews/src/dataform-controls/datetime.tsx new file mode 100644 index 0000000000000..3ba22dc0c1b08 --- /dev/null +++ b/packages/dataviews/src/dataform-controls/datetime.tsx @@ -0,0 +1,37 @@ +/** + * WordPress dependencies + */ +import { BaseControl, TimePicker } from '@wordpress/components'; +import { useCallback } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import type { DataFormControlProps } from '../types'; + +export default function DateTime< Item >( { + data, + field, + onChange, +}: DataFormControlProps< Item > ) { + const { id, label } = field; + const value = field.getValue( { item: data } ); + + const onChangeControl = useCallback( + ( newValue: string | null ) => onChange( { [ id ]: newValue } ), + [ id, onChange ] + ); + + return ( +
+ + { label } + + +
+ ); +} diff --git a/packages/dataviews/src/components/dataform-controls/index.tsx b/packages/dataviews/src/dataform-controls/index.tsx similarity index 60% rename from packages/dataviews/src/components/dataform-controls/index.tsx rename to packages/dataviews/src/dataform-controls/index.tsx index dd913269cd09e..297e73c28f837 100644 --- a/packages/dataviews/src/components/dataform-controls/index.tsx +++ b/packages/dataviews/src/dataform-controls/index.tsx @@ -10,15 +10,23 @@ import type { DataFormControlProps, Field, FieldTypeDefinition, -} from '../../types'; +} from '../types'; +import datetime from './datetime'; +import integer from './integer'; import radio from './radio'; +import select from './select'; +import text from './text'; interface FormControls { [ key: string ]: ComponentType< DataFormControlProps< any > >; } const FORM_CONTROLS: FormControls = { + datetime, + integer, radio, + select, + text, }; export function getControl< Item >( @@ -29,12 +37,19 @@ export function getControl< Item >( return field.Edit; } - let control; if ( typeof field.Edit === 'string' ) { - control = getControlByType( field.Edit ); + return getControlByType( field.Edit ); } - return control || fieldTypeDefinition.Edit; + if ( field.elements ) { + return getControlByType( 'select' ); + } + + if ( typeof fieldTypeDefinition.Edit === 'string' ) { + return getControlByType( fieldTypeDefinition.Edit ); + } + + return fieldTypeDefinition.Edit; } export function getControlByType( type: string ) { @@ -42,5 +57,5 @@ export function getControlByType( type: string ) { return FORM_CONTROLS[ type ]; } - return null; + throw 'Control ' + type + ' not found'; } diff --git a/packages/dataviews/src/dataform-controls/integer.tsx b/packages/dataviews/src/dataform-controls/integer.tsx new file mode 100644 index 0000000000000..f70a90ffe1523 --- /dev/null +++ b/packages/dataviews/src/dataform-controls/integer.tsx @@ -0,0 +1,38 @@ +/** + * WordPress dependencies + */ +import { __experimentalNumberControl as NumberControl } from '@wordpress/components'; +import { useCallback } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import type { DataFormControlProps } from '../types'; + +export default function Integer< Item >( { + data, + field, + onChange, + hideLabelFromVision, +}: DataFormControlProps< Item > ) { + const { id, label, description } = field; + const value = field.getValue( { item: data } ) ?? ''; + const onChangeControl = useCallback( + ( newValue: string | undefined ) => + onChange( { + [ id ]: Number( newValue ), + } ), + [ id, onChange ] + ); + + return ( + + ); +} diff --git a/packages/dataviews/src/components/dataform-controls/radio.tsx b/packages/dataviews/src/dataform-controls/radio.tsx similarity index 80% rename from packages/dataviews/src/components/dataform-controls/radio.tsx rename to packages/dataviews/src/dataform-controls/radio.tsx index d264aa6c24b7f..3d616404e0c05 100644 --- a/packages/dataviews/src/components/dataform-controls/radio.tsx +++ b/packages/dataviews/src/dataform-controls/radio.tsx @@ -7,9 +7,9 @@ import { useCallback } from '@wordpress/element'; /** * Internal dependencies */ -import type { DataFormControlProps } from '../../types'; +import type { DataFormControlProps } from '../types'; -export default function Edit< Item >( { +export default function Radio< Item >( { data, field, onChange, @@ -20,10 +20,9 @@ export default function Edit< Item >( { const onChangeControl = useCallback( ( newValue: string ) => - onChange( ( prevItem: Item ) => ( { - ...prevItem, + onChange( { [ id ]: newValue, - } ) ), + } ), [ id, onChange ] ); diff --git a/packages/dataviews/src/dataform-controls/select.tsx b/packages/dataviews/src/dataform-controls/select.tsx new file mode 100644 index 0000000000000..2b3bd9373fc15 --- /dev/null +++ b/packages/dataviews/src/dataform-controls/select.tsx @@ -0,0 +1,52 @@ +/** + * WordPress dependencies + */ +import { SelectControl } from '@wordpress/components'; +import { useCallback } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import type { DataFormControlProps } from '../types'; + +export default function Select< Item >( { + data, + field, + onChange, + hideLabelFromVision, +}: DataFormControlProps< Item > ) { + const { id, label } = field; + const value = field.getValue( { item: data } ) ?? ''; + const onChangeControl = useCallback( + ( newValue: any ) => + onChange( { + [ id ]: newValue, + } ), + [ id, onChange ] + ); + + const elements = [ + /* + * Value can be undefined when: + * + * - the field is not required + * - in bulk editing + * + */ + { label: __( 'Select item' ), value: '' }, + ...( field?.elements ?? [] ), + ]; + + return ( + + ); +} diff --git a/packages/dataviews/src/dataform-controls/text.tsx b/packages/dataviews/src/dataform-controls/text.tsx new file mode 100644 index 0000000000000..7ac095f4abede --- /dev/null +++ b/packages/dataviews/src/dataform-controls/text.tsx @@ -0,0 +1,40 @@ +/** + * WordPress dependencies + */ +import { TextControl } from '@wordpress/components'; +import { useCallback } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import type { DataFormControlProps } from '../types'; + +export default function Text< Item >( { + data, + field, + onChange, + hideLabelFromVision, +}: DataFormControlProps< Item > ) { + const { id, label, placeholder } = field; + const value = field.getValue( { item: data } ); + + const onChangeControl = useCallback( + ( newValue: string ) => + onChange( { + [ id ]: newValue, + } ), + [ id, onChange ] + ); + + return ( + + ); +} diff --git a/packages/dataviews/src/field-types/datetime.tsx b/packages/dataviews/src/field-types/datetime.tsx index c6b69048efe13..aa97fc86c318c 100644 --- a/packages/dataviews/src/field-types/datetime.tsx +++ b/packages/dataviews/src/field-types/datetime.tsx @@ -1,18 +1,7 @@ -/** - * WordPress dependencies - */ -import { BaseControl, TimePicker, SelectControl } from '@wordpress/components'; -import { useCallback } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ -import type { - SortDirection, - ValidationContext, - DataFormControlProps, -} from '../types'; +import type { SortDirection, ValidationContext } from '../types'; function sort( a: any, b: any, direction: SortDirection ) { const timeA = new Date( a ).getTime(); @@ -32,60 +21,8 @@ function isValid( value: any, context?: ValidationContext ) { return true; } -function Edit< Item >( { - data, - field, - onChange, -}: DataFormControlProps< Item > ) { - const { id, label } = field; - const value = field.getValue( { item: data } ); - - const onChangeControl = useCallback( - ( newValue: string | null ) => onChange( { [ id ]: newValue } ), - [ id, onChange ] - ); - - if ( field.elements ) { - const elements = [ - /* - * Value can be undefined when: - * - * - the field is not required - * - in bulk editing - * - */ - { label: __( 'Select item' ), value: '' }, - ...field.elements, - ]; - - return ( - - ); - } - - return ( -
- - { label } - - -
- ); -} - export default { sort, isValid, - Edit, + Edit: 'datetime', }; diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 38570ea6fec1a..f57c8e382db81 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -1,21 +1,7 @@ -/** - * WordPress dependencies - */ -import { - __experimentalNumberControl as NumberControl, - SelectControl, -} from '@wordpress/components'; -import { useCallback } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ -import type { - SortDirection, - ValidationContext, - DataFormControlProps, -} from '../types'; +import type { SortDirection, ValidationContext } from '../types'; function sort( a: any, b: any, direction: SortDirection ) { return direction === 'asc' ? a - b : b - a; @@ -41,62 +27,8 @@ function isValid( value: any, context?: ValidationContext ) { return true; } -function Edit< Item >( { - data, - field, - onChange, - hideLabelFromVision, -}: DataFormControlProps< Item > ) { - const { id, label, description } = field; - const value = field.getValue( { item: data } ) ?? ''; - const onChangeControl = useCallback( - ( newValue: string | undefined ) => - onChange( { - [ id ]: Number( newValue ), - } ), - [ id, onChange ] - ); - - if ( field.elements ) { - const elements = [ - /* - * Value can be undefined when: - * - * - the field is not required - * - in bulk editing - * - */ - { label: __( 'Select item' ), value: '' }, - ...field.elements, - ]; - - return ( - - ); - } - - return ( - - ); -} - export default { sort, isValid, - Edit, + Edit: 'integer', }; diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index 5364017c629b0..76ff699d0848c 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,18 +1,7 @@ -/** - * WordPress dependencies - */ -import { SelectControl, TextControl } from '@wordpress/components'; -import { useCallback } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ -import type { - SortDirection, - ValidationContext, - DataFormControlProps, -} from '../types'; +import type { SortDirection, ValidationContext } from '../types'; function sort( valueA: any, valueB: any, direction: SortDirection ) { return direction === 'asc' @@ -31,64 +20,8 @@ function isValid( value: any, context?: ValidationContext ) { return true; } -function Edit< Item >( { - data, - field, - onChange, - hideLabelFromVision, -}: DataFormControlProps< Item > ) { - const { id, label, placeholder } = field; - const value = field.getValue( { item: data } ); - - const onChangeControl = useCallback( - ( newValue: string ) => - onChange( { - [ id ]: newValue, - } ), - [ id, onChange ] - ); - - if ( field.elements ) { - const elements = [ - /* - * Value can be undefined when: - * - * - the field is not required - * - in bulk editing - * - */ - { label: __( 'Select item' ), value: '' }, - ...field.elements, - ]; - - return ( - - ); - } - - return ( - - ); -} - export default { sort, isValid, - Edit, + Edit: 'text', }; diff --git a/packages/dataviews/src/normalize-fields.ts b/packages/dataviews/src/normalize-fields.ts index 2cdde5b334379..f9f95b5b8140d 100644 --- a/packages/dataviews/src/normalize-fields.ts +++ b/packages/dataviews/src/normalize-fields.ts @@ -3,7 +3,7 @@ */ import getFieldTypeDefinition from './field-types'; import type { Field, NormalizedField } from './types'; -import { getControl } from './components/dataform-controls'; +import { getControl } from './dataform-controls'; /** * Apply default values and normalize the fields config. diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index 34e74eabd7c7d..7bbbc8cb863c0 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -63,9 +63,9 @@ export type FieldTypeDefinition< Item > = { isValid: ( item: Item, context?: ValidationContext ) => boolean; /** - * Callback used to render an edit control for the field. + * Callback used to render an edit control for the field or control name. */ - Edit: ComponentType< DataFormControlProps< Item > >; + Edit: ComponentType< DataFormControlProps< Item > > | string; }; /** @@ -105,7 +105,7 @@ export type Field< Item > = { /** * Callback used to render an edit control for the field. */ - Edit?: ComponentType< DataFormControlProps< Item > > | 'radio'; + Edit?: ComponentType< DataFormControlProps< Item > > | string; /** * Callback used to sort the field.