feat: converts rowHeader to collapsibleLabel, extends data passed to functions/components
This commit is contained in:
23
src/admin/components/forms/CollapsibleLabel/index.tsx
Normal file
23
src/admin/components/forms/CollapsibleLabel/index.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { Props } from './types';
|
||||
import { useWatchForm } from '../Form/context';
|
||||
|
||||
export const CollapsibleLabel: React.FC<Props> = (props) => {
|
||||
const {
|
||||
path,
|
||||
fallback,
|
||||
label,
|
||||
rowNumber,
|
||||
} = props;
|
||||
const { getDataByPath, getSiblingData, getData } = useWatchForm();
|
||||
const formData = getData();
|
||||
const collapsibleData = getDataByPath(path) || getSiblingData(path);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{(typeof label === 'function')
|
||||
? label({ collapsibleData, index: rowNumber, formData, fallback })
|
||||
: (label || fallback)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
16
src/admin/components/forms/CollapsibleLabel/types.ts
Normal file
16
src/admin/components/forms/CollapsibleLabel/types.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import { Data } from '../Form/types';
|
||||
|
||||
export type CollapsibleHeader = (props: {
|
||||
formData: Data,
|
||||
collapsibleData: Data,
|
||||
index?: number,
|
||||
fallback: string,
|
||||
}) => React.ReactNode;
|
||||
|
||||
export type Props = {
|
||||
fallback: string;
|
||||
path: string;
|
||||
header?: CollapsibleHeader;
|
||||
rowNumber?: number;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { Props } from './types';
|
||||
import { useWatchForm } from '../Form/context';
|
||||
|
||||
const RowHeader: React.FC<Props> = (props) => {
|
||||
const {
|
||||
path,
|
||||
fallback,
|
||||
header,
|
||||
rowNumber,
|
||||
} = props;
|
||||
const { getSiblingData } = useWatchForm();
|
||||
const siblingData = getSiblingData(`${path}`);
|
||||
|
||||
/* if (isComponent(header)) {
|
||||
const Header = header;
|
||||
return (
|
||||
<Header
|
||||
value={siblingData}
|
||||
index={rowNumber}
|
||||
/>
|
||||
);
|
||||
} */
|
||||
|
||||
if (header) {
|
||||
return (
|
||||
<Fragment>
|
||||
{
|
||||
typeof header === 'function'
|
||||
? header({ value: siblingData, index: rowNumber })
|
||||
: header
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
return <Fragment>{fallback}</Fragment>;
|
||||
};
|
||||
|
||||
export default RowHeader;
|
||||
@@ -1,13 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Data } from '../Form/types';
|
||||
|
||||
export type RowHeaderComponent = (props: {value: Data, index?: number}) => React.ReactNode;
|
||||
|
||||
export type RowHeader = string | RowHeaderComponent;
|
||||
|
||||
export type Props = {
|
||||
fallback: string | React.ReactElement;
|
||||
path: string;
|
||||
header?: RowHeader;
|
||||
rowNumber?: number;
|
||||
}
|
||||
@@ -22,9 +22,9 @@ import { usePreferences } from '../../../utilities/Preferences';
|
||||
import { ArrayAction } from '../../../elements/ArrayAction';
|
||||
import { scrollToID } from '../../../../utilities/scrollToID';
|
||||
import HiddenInput from '../HiddenInput';
|
||||
import { CollapsibleLabel } from '../../CollapsibleLabel';
|
||||
|
||||
import './index.scss';
|
||||
import RowHeader from '../../RowHeader';
|
||||
|
||||
const baseClass = 'array-field';
|
||||
|
||||
@@ -49,7 +49,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
},
|
||||
} = props;
|
||||
|
||||
const RowHeaderFromProps = components?.RowHeader || undefined;
|
||||
const CollapsibleLabelFromProps = components?.CollapsibleLabel || undefined;
|
||||
|
||||
const path = pathFromProps || name;
|
||||
|
||||
@@ -287,10 +287,10 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
key={row.id}
|
||||
dragHandleProps={providedDrag.dragHandleProps}
|
||||
header={(
|
||||
<RowHeader
|
||||
path={`${path}.${i}.0`}
|
||||
header={RowHeaderFromProps}
|
||||
fallback={`${labels.singular} ${rowNumber >= 10 ? rowNumber : `0${rowNumber}`}`}
|
||||
<CollapsibleLabel
|
||||
path={`${path}.${i}`}
|
||||
label={CollapsibleLabelFromProps}
|
||||
fallback={`${labels.singular} ${String(rowNumber).padStart(2, '0')}`}
|
||||
rowNumber={rowNumber}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { DocumentPreferences } from '../../../../../preferences/types';
|
||||
import { useDocumentInfo } from '../../../utilities/DocumentInfo';
|
||||
import FieldDescription from '../../FieldDescription';
|
||||
import { getFieldPath } from '../getFieldPath';
|
||||
import RowHeader from '../../RowHeader';
|
||||
import { CollapsibleLabel } from '../../CollapsibleLabel';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -31,7 +31,7 @@ const CollapsibleField: React.FC<Props> = (props) => {
|
||||
},
|
||||
} = props;
|
||||
|
||||
const RowHeaderFromProps = components?.RowHeader || undefined;
|
||||
const CollapsibleLabelFromProps = components?.CollapsibleLabel || undefined;
|
||||
|
||||
const { getPreference, setPreference } = usePreferences();
|
||||
const { preferencesKey } = useDocumentInfo();
|
||||
@@ -74,10 +74,10 @@ const CollapsibleField: React.FC<Props> = (props) => {
|
||||
className,
|
||||
].filter(Boolean).join(' ')}
|
||||
header={(
|
||||
<RowHeader
|
||||
<CollapsibleLabel
|
||||
path={path}
|
||||
fallback={<div className={`${baseClass}__label`}>{label}</div>}
|
||||
header={RowHeaderFromProps}
|
||||
fallback={label}
|
||||
label={CollapsibleLabelFromProps}
|
||||
/>
|
||||
)}
|
||||
onToggle={onToggle}
|
||||
|
||||
@@ -186,7 +186,7 @@ export const collapsible = baseField.keys({
|
||||
fields: joi.array().items(joi.link('#field')),
|
||||
admin: baseAdminFields.keys({
|
||||
components: joi.object().keys({
|
||||
RowHeader: componentSchema,
|
||||
CollapsibleLabel: componentSchema,
|
||||
}).default({}),
|
||||
}).default({}),
|
||||
});
|
||||
@@ -242,7 +242,7 @@ export const array = baseField.keys({
|
||||
),
|
||||
admin: baseAdminFields.keys({
|
||||
components: joi.object().keys({
|
||||
RowHeader: componentSchema,
|
||||
CollapsibleLabel: componentSchema,
|
||||
}).default({}),
|
||||
}).default({}),
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ConditionalDateProps } from '../../admin/components/elements/DatePicker
|
||||
import { Description } from '../../admin/components/forms/FieldDescription/types';
|
||||
import { User } from '../../auth';
|
||||
import { Payload } from '../..';
|
||||
import { RowHeader } from '../../admin/components/forms/RowHeader/types';
|
||||
import { CollapsibleLabel } from '../../admin/components/forms/CollapsibleLabel/types';
|
||||
|
||||
export type FieldHookArgs<T extends TypeWithID = any, P = any, S = any> = {
|
||||
/** The data passed to update the document within create and update operations, and the full document itself in the afterRead hook. */
|
||||
@@ -193,7 +193,7 @@ export type CollapsibleField = Omit<FieldBase, 'name'> & {
|
||||
admin?: Admin & {
|
||||
initCollapsed?: boolean | false;
|
||||
components?: {
|
||||
RowHeader?: RowHeader
|
||||
CollapsibleLabel?: CollapsibleLabel
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,7 +342,7 @@ export type ArrayField = FieldBase & {
|
||||
admin?: Admin & {
|
||||
initCollapsed?: boolean | false;
|
||||
components?: {
|
||||
RowHeader?: RowHeader
|
||||
CollapsibleLabel?: CollapsibleLabel
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import React from 'react';
|
||||
import { RowHeaderComponent } from '../../../../src/admin/components/forms/RowHeader/types';
|
||||
import { CollapsibleLabel } from '../../../../src/admin/components/forms/CollapsibleLabel/types';
|
||||
|
||||
const ArrayRowHeader: RowHeaderComponent = (props) => {
|
||||
const { value, index } = props;
|
||||
return <React.Fragment>{value.title || `array_${index}`}</React.Fragment>;
|
||||
export const ArrayCollapsibleLabel: CollapsibleLabel = (props) => {
|
||||
const { collapsibleData, fallback } = props;
|
||||
return <span style={{ color: 'hotpink' }}>{collapsibleData.title || fallback}</span>;
|
||||
};
|
||||
|
||||
export default ArrayRowHeader;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { RowHeaderFunction } from '../../../../src/admin/components/forms/RowHeader/types';
|
||||
import type { CollectionConfig } from '../../../../src/collections/config/types';
|
||||
import HeaderComponent from './HeaderComponent';
|
||||
import { ArrayCollapsibleLabel } from './HeaderComponent';
|
||||
|
||||
export const arrayDefaultValue = [
|
||||
{ text: 'row one' },
|
||||
@@ -86,7 +85,7 @@ const ArrayFields: CollectionConfig = {
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'arrayWithRowHeaderFunction',
|
||||
name: 'collapsibleLabelAsFunction',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
@@ -94,14 +93,15 @@ const ArrayFields: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
admin: {
|
||||
description: 'Collapsible labels rendered from a function.',
|
||||
components: {
|
||||
RowHeader: ({ value, index }) => value.title || `item ${index}`,
|
||||
CollapsibleLabel: ({ collapsibleData, fallback }) => collapsibleData.title || fallback,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
name: 'arrayWithRowHeaderComponent',
|
||||
name: 'rowHeaderAsComponent',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
@@ -109,8 +109,9 @@ const ArrayFields: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
admin: {
|
||||
description: 'Collapsible labels rendered as components.',
|
||||
components: {
|
||||
RowHeader: HeaderComponent,
|
||||
CollapsibleLabel: ArrayCollapsibleLabel,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import React from 'react';
|
||||
import { RowHeaderComponent } from '../../../../src/admin/components/forms/RowHeader/types';
|
||||
import { CollapsibleLabel } from '../../../../src/admin/components/forms/CollapsibleLabel/types';
|
||||
|
||||
const ArrayRowHeader: RowHeaderComponent = (props) => {
|
||||
const { value } = props;
|
||||
return <React.Fragment>{value.title || 'enter title'}</React.Fragment>;
|
||||
export const CollapsibleLabelComponent: CollapsibleLabel = (props) => {
|
||||
const { collapsibleData, fallback } = props;
|
||||
return <span style={{ color: 'coral' }}>{collapsibleData.componentTitleField || fallback}</span>;
|
||||
};
|
||||
|
||||
export default ArrayRowHeader;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CollectionConfig } from '../../../../src/collections/config/types';
|
||||
import { CollapsibleLabelComponent } from './HeaderComponent';
|
||||
|
||||
const CollapsibleFields: CollectionConfig = {
|
||||
slug: 'collapsible-fields',
|
||||
@@ -74,35 +75,35 @@ const CollapsibleFields: CollectionConfig = {
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Collapsible Field - RowHeaderFunction',
|
||||
label: 'Collapsible Header Function',
|
||||
type: 'collapsible',
|
||||
admin: {
|
||||
description: 'This is a collapsible field.',
|
||||
description: 'Collapsible label rendered from a function.',
|
||||
initCollapsed: true,
|
||||
components: {
|
||||
RowHeader: ({ value }) => value.title1 || 'untitled',
|
||||
CollapsibleLabel: ({ collapsibleData }) => collapsibleData.functionTitleField || 'Untitled',
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title1',
|
||||
name: 'functionTitleField',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Collapsible Field - RowHeaderComponent',
|
||||
label: 'Collapsible Header Component',
|
||||
type: 'collapsible',
|
||||
admin: {
|
||||
description: 'This is a collapsible field.',
|
||||
description: 'Collapsible label rendered as a react component.',
|
||||
initCollapsed: true,
|
||||
components: {
|
||||
RowHeader: ({ value }) => value.title2 || 'untitled',
|
||||
CollapsibleLabel: CollapsibleLabelComponent,
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title2',
|
||||
name: 'componentTitleField',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user