Skip to content

Commit

Permalink
Add combined fields option to DataForms
Browse files Browse the repository at this point in the history
  • Loading branch information
louwie17 committed Sep 17, 2024
1 parent f82bc32 commit c74e428
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 19 deletions.
72 changes: 72 additions & 0 deletions packages/dataviews/src/components/dataform-combined-edit/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* WordPress dependencies
*/
import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
__experimentalHeading as Heading,
__experimentalSpacer as Spacer,
} from '@wordpress/components';

/**
* Internal dependencies
*/
import type { DataFormCombinedEditProps, NormalizedField } from '../../types';

function FieldHeader( { title }: { title: string } ) {
return (
<VStack
className="dataforms-layouts-panel__dropdown-header"
spacing={ 4 }
>
<HStack alignment="center">
<Heading level={ 2 } size={ 13 }>
{ title }
</Heading>
<Spacer />
</HStack>
</VStack>
);
}

function DataFormCombinedEdit< Item >( {
field,
data,
onChange,
}: DataFormCombinedEditProps< Item > ) {
const className = 'dataforms-combined-edit';
const visibleChildren = ( field.children ?? [] )
.map( ( fieldId ) => field.fields.find( ( { id } ) => id === fieldId ) )
.filter(
( childField ): childField is NormalizedField< Item > =>
!! childField
);
const children = visibleChildren.map( ( child, index ) => {
return (
<div className="dataforms-combined-edit__field" key={ child.id }>
{ index !== 0 && <FieldHeader title={ child.label } /> }
<child.Edit
data={ data }
field={ child }
onChange={ onChange }
hideLabelFromVision
/>
</div>
);
} );

if ( field.direction === 'horizontal' ) {
return (
<HStack spacing={ 4 } className={ className }>
{ children }
</HStack>
);
}
return (
<VStack spacing={ 4 } className={ className }>
{ children }
</VStack>
);
}

export default DataFormCombinedEdit;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.dataforms-combined-edit {
&__field:not(:first-child) {
border-top: $border-width solid $gray-200;
padding-top: $grid-unit-20;
}
}
45 changes: 37 additions & 8 deletions packages/dataviews/src/dataforms-layouts/panel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,17 @@ import { closeSmall } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { normalizeFields } from '../../normalize-fields';
import type { DataFormProps, NormalizedField, Field } from '../../types';
import {
normalizeFields,
normalizeCombinedFields,
} from '../../normalize-fields';
import type {
DataFormProps,
NormalizedField,
Field,
CombinedFormField,
NormalizedCombinedFormField,
} from '../../types';

interface FormFieldProps< Item > {
data: Item;
Expand Down Expand Up @@ -135,6 +144,26 @@ function FormField< Item >( {
);
}

export function getVisibleFields(
fields: Field< any >[],
formFields: string[] = [],
combinedFields?: CombinedFormField< any >[]
): Field< any >[] {
const visibleFields: Array<
Field< any > | NormalizedCombinedFormField< any >
> = [ ...fields ];
if ( combinedFields ) {
visibleFields.push(
...normalizeCombinedFields( combinedFields, fields )
);
}
return formFields
.map( ( fieldId ) =>
visibleFields.find( ( { id } ) => id === fieldId )
)
.filter( ( field ): field is Field< any > => !! field );
}

export default function FormPanel< Item >( {
data,
fields,
Expand All @@ -144,13 +173,13 @@ export default function FormPanel< Item >( {
const visibleFields = useMemo(
() =>
normalizeFields(
( form.fields ?? [] )
.map( ( fieldId ) =>
fields.find( ( { id } ) => id === fieldId )
)
.filter( ( field ): field is Field< Item > => !! field )
getVisibleFields(
fields,
form.fields,
form.layout?.combinedFields
)
),
[ fields, form.fields ]
[ fields, form.fields, form.layout?.combinedFields ]
);

return (
Expand Down
34 changes: 33 additions & 1 deletion packages/dataviews/src/normalize-fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
* Internal dependencies
*/
import getFieldTypeDefinition from './field-types';
import type { Field, NormalizedField } from './types';
import type {
CombinedFormField,
Field,
NormalizedField,
NormalizedCombinedFormField,
} from './types';
import { getControl } from './dataform-controls';
import DataFormCombinedEdit from './components/dataform-combined-edit';

/**
* Apply default values and normalize the fields config.
Expand Down Expand Up @@ -66,3 +72,29 @@ export function normalizeFields< Item >(
};
} );
}

/**
* Apply default values and normalize the fields config.
*
* @param combinedFields combined field list.
* @param fields Fields config.
* @return Normalized fields config.
*/
export function normalizeCombinedFields< Item >(
combinedFields: CombinedFormField< Item >[],
fields: Field< Item >[]
): NormalizedCombinedFormField< Item >[] {
return combinedFields.map( ( combinedField ) => {
return {
...combinedField,
Edit: DataFormCombinedEdit,
fields: normalizeFields(
combinedField.children
.map( ( fieldId ) =>
fields.find( ( { id } ) => id === fieldId )
)
.filter( ( field ): field is Field< any > => !! field )
),
};
} );
}
1 change: 1 addition & 0 deletions packages/dataviews/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import "./components/dataviews-item-actions/style.scss";
@import "./components/dataviews-selection-checkbox/style.scss";
@import "./components/dataviews-view-config/style.scss";
@import "./components/dataform-combined-edit/style.scss";

@import "./dataviews-layouts/grid/style.scss";
@import "./dataviews-layouts/list/style.scss";
Expand Down
39 changes: 30 additions & 9 deletions packages/dataviews/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,6 @@ export type Fields< Item > = Field< Item >[];

export type Data< Item > = Item[];

/**
* The form configuration.
*/
export type Form = {
type?: 'regular' | 'panel';
fields?: string[];
};

export type DataFormControlProps< Item > = {
data: Item;
field: NormalizedField< Item >;
Expand Down Expand Up @@ -524,9 +516,38 @@ export interface SupportedLayouts {
table?: Omit< ViewTable, 'type' >;
}

export interface CombinedFormField< Item > extends CombinedField {
render?: ComponentType< { item: Item } >;
}

export interface DataFormCombinedEditProps< Item > {
field: NormalizedCombinedFormField< Item >;
data: Item;
onChange: ( value: Record< string, any > ) => void;
}

export type NormalizedCombinedFormField< Item > = CombinedFormField< Item > & {
fields: NormalizedField< Item >[];
Edit?: ComponentType< DataFormCombinedEditProps< Item > >;
};

/**
* The form configuration.
*/
export type Form< Item > = {
type?: 'regular' | 'panel';
fields?: string[];
layout?: {
/**
* The fields to combine.
*/
combinedFields?: CombinedFormField< Item >[];
};
};

export interface DataFormProps< Item > {
data: Item;
fields: Field< Item >[];
form: Form;
form: Form< Item >;
onChange: ( value: Record< string, any > ) => void;
}
2 changes: 1 addition & 1 deletion packages/dataviews/src/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Field, Form } from './types';
export function isItemValid< Item >(
item: Item,
fields: Field< Item >[],
form: Form
form: Form< Item >
): boolean {
const _fields = normalizeFields(
fields.filter( ( { id } ) => !! form.fields?.includes( id ) )
Expand Down

0 comments on commit c74e428

Please sign in to comment.