feat: specifies component names for arrays/collapsibles, simplifies threaded data
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
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>
|
||||
);
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Data } from '../Form/types';
|
||||
|
||||
export type CollapsibleLabel = (props: {
|
||||
formData: Data,
|
||||
collapsibleData: Data,
|
||||
index?: number,
|
||||
fallback: string,
|
||||
}) => React.ReactNode;
|
||||
|
||||
export type Props = {
|
||||
fallback: string;
|
||||
path: string;
|
||||
label?: CollapsibleLabel;
|
||||
rowNumber?: number;
|
||||
}
|
||||
60
src/admin/components/forms/RowLabel/index.tsx
Normal file
60
src/admin/components/forms/RowLabel/index.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import React from 'react';
|
||||
import { isComponent, Props } from './types';
|
||||
import { useWatchForm } from '../Form/context';
|
||||
|
||||
const baseClass = 'row-label';
|
||||
|
||||
export const RowLabel: React.FC<Props> = (props) => {
|
||||
const {
|
||||
path,
|
||||
fallback,
|
||||
label,
|
||||
rowNumber,
|
||||
className,
|
||||
} = props;
|
||||
|
||||
const { getDataByPath, getSiblingData } = useWatchForm();
|
||||
const collapsibleData = getSiblingData(path);
|
||||
const arrayData = getDataByPath(path);
|
||||
const data = arrayData || collapsibleData;
|
||||
|
||||
if (isComponent(label)) {
|
||||
const Label = label;
|
||||
return (
|
||||
<Label
|
||||
data={data}
|
||||
path={path}
|
||||
fallback={fallback}
|
||||
index={rowNumber}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (label) {
|
||||
return (
|
||||
<span
|
||||
className={[
|
||||
baseClass,
|
||||
className,
|
||||
].filter(Boolean).join(' ')}
|
||||
>
|
||||
{typeof label === 'function' ? label({
|
||||
data,
|
||||
path,
|
||||
fallback,
|
||||
index: rowNumber,
|
||||
}) : label}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (fallback) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{fallback}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
27
src/admin/components/forms/RowLabel/types.ts
Normal file
27
src/admin/components/forms/RowLabel/types.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { Data } from '../Form/types';
|
||||
|
||||
export type Props = {
|
||||
fallback: string;
|
||||
path: string;
|
||||
label?: RowLabel;
|
||||
rowNumber?: number;
|
||||
className?: string,
|
||||
}
|
||||
|
||||
export type RowLabelArgs = {
|
||||
data: Data,
|
||||
path: string,
|
||||
index: number,
|
||||
fallback: string
|
||||
}
|
||||
|
||||
export type RowLabelFunction = (args: RowLabelArgs) => string
|
||||
|
||||
export type RowLabelComponent = React.ComponentType<RowLabelArgs>
|
||||
|
||||
export type RowLabel = string | RowLabelFunction | RowLabelComponent
|
||||
|
||||
export function isComponent(label: RowLabel): label is RowLabelComponent {
|
||||
return React.isValidElement(label);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import { usePreferences } from '../../../utilities/Preferences';
|
||||
import { ArrayAction } from '../../../elements/ArrayAction';
|
||||
import { scrollToID } from '../../../../utilities/scrollToID';
|
||||
import HiddenInput from '../HiddenInput';
|
||||
import { CollapsibleLabel } from '../../CollapsibleLabel';
|
||||
import { RowLabel } from '../../RowLabel';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -49,7 +49,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
},
|
||||
} = props;
|
||||
|
||||
const CollapsibleLabelFromProps = components?.CollapsibleLabel || undefined;
|
||||
const RowLabelFromProps = components?.RowLabel || undefined;
|
||||
|
||||
const path = pathFromProps || name;
|
||||
|
||||
@@ -287,9 +287,9 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
key={row.id}
|
||||
dragHandleProps={providedDrag.dragHandleProps}
|
||||
header={(
|
||||
<CollapsibleLabel
|
||||
<RowLabel
|
||||
path={`${path}.${i}`}
|
||||
label={CollapsibleLabelFromProps}
|
||||
label={RowLabelFromProps}
|
||||
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 { CollapsibleLabel } from '../../CollapsibleLabel';
|
||||
import { RowLabel } from '../../RowLabel';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -74,7 +74,7 @@ const CollapsibleField: React.FC<Props> = (props) => {
|
||||
className,
|
||||
].filter(Boolean).join(' ')}
|
||||
header={(
|
||||
<CollapsibleLabel
|
||||
<RowLabel
|
||||
path={path}
|
||||
fallback={label}
|
||||
label={CollapsibleLabelFromProps}
|
||||
|
||||
Reference in New Issue
Block a user