From 3e151e2e45fd766abf63d4640681de930d29eb77 Mon Sep 17 00:00:00 2001 From: louwie17 Date: Wed, 30 Oct 2024 12:51:42 -0300 Subject: [PATCH] Add `isVisible` option to fields within DataForm (#65826) Co-authored-by: louwie17 Co-authored-by: oandregal Co-authored-by: youknowriad --- .../dataform-combined-edit/index.tsx | 17 ++++++---- .../dataform/stories/index.story.tsx | 22 +++++++++++-- .../form-field-visibility/index.tsx | 32 +++++++++++++++++++ .../src/dataforms-layouts/panel/index.tsx | 12 +++++-- .../src/dataforms-layouts/regular/index.tsx | 12 +++++-- packages/dataviews/src/types.ts | 5 +++ 6 files changed, 84 insertions(+), 16 deletions(-) create mode 100644 packages/dataviews/src/components/form-field-visibility/index.tsx diff --git a/packages/dataviews/src/components/dataform-combined-edit/index.tsx b/packages/dataviews/src/components/dataform-combined-edit/index.tsx index 6b2a752fa8de5..90a92ac861bdd 100644 --- a/packages/dataviews/src/components/dataform-combined-edit/index.tsx +++ b/packages/dataviews/src/components/dataform-combined-edit/index.tsx @@ -12,6 +12,7 @@ import { * Internal dependencies */ import type { DataFormCombinedEditProps, NormalizedField } from '../../types'; +import FormFieldVisibility from '../form-field-visibility'; function Header( { title }: { title: string } ) { return ( @@ -41,13 +42,15 @@ function DataFormCombinedEdit< Item >( { ); const children = visibleChildren.map( ( child ) => { return ( -
- -
+ +
+ +
+
); } ); diff --git a/packages/dataviews/src/components/dataform/stories/index.story.tsx b/packages/dataviews/src/components/dataform/stories/index.story.tsx index c929c21f1c21a..b59d79063200b 100644 --- a/packages/dataviews/src/components/dataform/stories/index.story.tsx +++ b/packages/dataviews/src/components/dataform/stories/index.story.tsx @@ -7,7 +7,18 @@ import { useState } from '@wordpress/element'; * Internal dependencies */ import DataForm from '../index'; -import type { CombinedFormField } from '../../../types'; +import type { CombinedFormField, Field } from '../../../types'; + +type SamplePost = { + title: string; + order: number; + author: number; + status: string; + reviewer: string; + date: string; + birthdate: string; + password?: string; +}; const meta = { title: 'DataViews/DataForm', @@ -75,14 +86,18 @@ const fields = [ elements: [ { value: 'draft', label: 'Draft' }, { value: 'published', label: 'Published' }, + { value: 'private', label: 'Private' }, ], }, { id: 'password', label: 'Password', type: 'text' as const, + isVisible: ( item: SamplePost ) => { + return item.status !== 'private'; + }, }, -]; +] as Field< SamplePost >[]; export const Default = ( { type }: { type: 'panel' | 'regular' } ) => { const [ post, setPost ] = useState( { @@ -102,13 +117,14 @@ export const Default = ( { type }: { type: 'panel' | 'regular' } ) => { 'author', 'reviewer', 'status', + 'password', 'date', 'birthdate', ], }; return ( - data={ post } fields={ fields } form={ { diff --git a/packages/dataviews/src/components/form-field-visibility/index.tsx b/packages/dataviews/src/components/form-field-visibility/index.tsx new file mode 100644 index 0000000000000..8cea59f11b7ae --- /dev/null +++ b/packages/dataviews/src/components/form-field-visibility/index.tsx @@ -0,0 +1,32 @@ +/** + * WordPress dependencies + */ +import { useMemo } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import type { NormalizedField } from '../../types'; + +type FormFieldVisibilityProps< Item > = React.PropsWithChildren< { + field: NormalizedField< Item >; + data: Item; +} >; + +export default function FormFieldVisibility< Item >( { + data, + field, + children, +}: FormFieldVisibilityProps< Item > ) { + const isVisible = useMemo( () => { + if ( field.isVisible ) { + return field.isVisible( data ); + } + return true; + }, [ field.isVisible, data ] ); + + if ( ! isVisible ) { + return null; + } + return children; +} diff --git a/packages/dataviews/src/dataforms-layouts/panel/index.tsx b/packages/dataviews/src/dataforms-layouts/panel/index.tsx index 4a43d25436fe7..b74e5e4667d4b 100644 --- a/packages/dataviews/src/dataforms-layouts/panel/index.tsx +++ b/packages/dataviews/src/dataforms-layouts/panel/index.tsx @@ -19,6 +19,7 @@ import { closeSmall } from '@wordpress/icons'; import { normalizeFields } from '../../normalize-fields'; import { getVisibleFields } from '../get-visible-fields'; import type { DataFormProps, NormalizedField } from '../../types'; +import FormFieldVisibility from '../../components/form-field-visibility'; interface FormFieldProps< Item > { data: Item; @@ -156,12 +157,17 @@ export default function FormPanel< Item >( { { visibleFields.map( ( field ) => { return ( - + > + + ); } ) } diff --git a/packages/dataviews/src/dataforms-layouts/regular/index.tsx b/packages/dataviews/src/dataforms-layouts/regular/index.tsx index 57aa163b890e5..6a340a50584df 100644 --- a/packages/dataviews/src/dataforms-layouts/regular/index.tsx +++ b/packages/dataviews/src/dataforms-layouts/regular/index.tsx @@ -10,6 +10,7 @@ import { useMemo } from '@wordpress/element'; import { normalizeFields } from '../../normalize-fields'; import { getVisibleFields } from '../get-visible-fields'; import type { DataFormProps } from '../../types'; +import FormFieldVisibility from '../../components/form-field-visibility'; export default function FormRegular< Item >( { data, @@ -33,12 +34,17 @@ export default function FormRegular< Item >( { { visibleFields.map( ( field ) => { return ( - + > + + ); } ) } diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index 2a335dce3af32..0ea0965704d18 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -123,6 +123,11 @@ export type Field< Item > = { */ isValid?: ( item: Item, context?: ValidationContext ) => boolean; + /** + * Callback used to decide if a field should be displayed. + */ + isVisible?: ( item: Item ) => boolean; + /** * Whether the field is sortable. */