Skip to content

Commit fb34fc0

Browse files
committed
Improve API
1 parent 2bd511d commit fb34fc0

File tree

3 files changed

+92
-98
lines changed

3 files changed

+92
-98
lines changed

packages/ra-core/src/controller/input/SimpleFormIteratorBase.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import * as React from 'react';
22
import { Children, type ReactNode, useMemo, useRef } from 'react';
3-
import get from 'lodash/get';
43
import { type UseFieldArrayReturn, useFormContext } from 'react-hook-form';
54
import { FormDataConsumer } from '../../form/FormDataConsumer';
65
import { useWrappedSource } from '../../core/useWrappedSource';
76
import type { RaRecord } from '../../types';
87
import { useEvent } from '../../util';
9-
import { useRecordContext } from '../record/useRecordContext';
108
import { useArrayInput } from './useArrayInput';
119
import { SimpleFormIteratorContext } from './SimpleFormIteratorContext';
1210

1311
export const SimpleFormIteratorBase = (props: SimpleFormIteratorBaseProps) => {
14-
const { inputs, render } = props;
12+
const { children, inputs } = props;
1513

1614
const finalSource = useWrappedSource('');
1715
if (!finalSource) {
@@ -22,7 +20,6 @@ export const SimpleFormIteratorBase = (props: SimpleFormIteratorBaseProps) => {
2220

2321
const { append, fields, move, remove, replace } = useArrayInput(props);
2422
const { trigger, getValues } = useFormContext();
25-
const record = useRecordContext(props);
2623
const initialDefaultValue = useRef({});
2724

2825
const removeField = useEvent((index: number) => {
@@ -87,8 +84,6 @@ export const SimpleFormIteratorBase = (props: SimpleFormIteratorBaseProps) => {
8784
replace([]);
8885
});
8986

90-
const records = get(record, finalSource);
91-
9287
const context = useMemo(
9388
() => ({
9489
total: fields.length,
@@ -113,24 +108,21 @@ export const SimpleFormIteratorBase = (props: SimpleFormIteratorBaseProps) => {
113108
}
114109
return (
115110
<SimpleFormIteratorContext.Provider value={context}>
116-
{render({ fields, records })}
111+
{children}
117112
</SimpleFormIteratorContext.Provider>
118113
);
119114
};
120115

121116
export interface SimpleFormIteratorBaseProps
122117
extends Partial<UseFieldArrayReturn> {
118+
children: ReactNode;
123119
inline?: boolean;
124120
inputs: ReactNode;
125121
meta?: {
126122
// the type defined in FieldArrayRenderProps says error is boolean, which is wrong.
127123
error?: any;
128124
submitFailed?: boolean;
129125
};
130-
render: (props: {
131-
fields: Record<'id', string>[];
132-
records: RaRecord[];
133-
}) => ReactNode;
134126
record?: RaRecord;
135127
resource?: string;
136128
source?: string;

packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIterator.tsx

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import {
1414
SimpleFormIteratorBase,
1515
type SimpleFormIteratorBaseProps,
1616
type SimpleFormIteratorDisableRemoveFunction,
17-
SimpleFormIteratorItemBase,
1817
RecordContextProvider,
18+
useArrayInput,
19+
useRecordContext,
1920
} from 'ra-core';
21+
import get from 'lodash/get';
2022

2123
import {
2224
SimpleFormIteratorClasses,
@@ -57,71 +59,67 @@ export const SimpleFormIterator = (inProps: SimpleFormIteratorProps) => {
5759
'SimpleFormIterator can only be called within an iterator input like ArrayInput'
5860
);
5961
}
62+
const { fields } = useArrayInput(props);
63+
const record = useRecordContext(props);
64+
const records = get(record, finalSource);
6065

6166
return (
62-
<SimpleFormIteratorBase
63-
inputs={children}
64-
render={({ fields, records }) => (
65-
<Root
66-
className={clsx(
67-
className,
68-
fullWidth && 'fullwidth',
69-
disabled && 'disabled'
70-
)}
71-
sx={sx}
72-
>
73-
<ul className={SimpleFormIteratorClasses.list}>
74-
{fields.map((member, index) => (
75-
<RecordContextProvider
76-
key={member.id}
77-
value={(records && records[index]) || {}}
67+
<SimpleFormIteratorBase inputs={children} {...props}>
68+
<Root
69+
className={clsx(
70+
className,
71+
fullWidth && 'fullwidth',
72+
disabled && 'disabled'
73+
)}
74+
sx={sx}
75+
>
76+
<ul className={SimpleFormIteratorClasses.list}>
77+
{fields.map((member, index) => (
78+
<RecordContextProvider
79+
key={member.id}
80+
value={(records && records[index]) || {}}
81+
>
82+
<SimpleFormIteratorItem
83+
index={index}
84+
fields={fields}
85+
resource={props.resource}
86+
disabled={disabled}
87+
disableRemove={disableRemove}
88+
disableReordering={disableReordering}
89+
getItemLabel={getItemLabel}
90+
removeButton={removeButton}
91+
reOrderButtons={reOrderButtons}
92+
inline={inline}
7893
>
79-
<SimpleFormIteratorItemBase
80-
index={index}
81-
fields={fields}
82-
resource={props.resource}
83-
>
84-
<SimpleFormIteratorItem
85-
disabled={disabled}
86-
disableRemove={disableRemove}
87-
disableReordering={disableReordering}
88-
getItemLabel={getItemLabel}
89-
removeButton={removeButton}
90-
reOrderButtons={reOrderButtons}
91-
inline={inline}
92-
>
93-
{children}
94-
</SimpleFormIteratorItem>
95-
</SimpleFormIteratorItemBase>
96-
</RecordContextProvider>
97-
))}
98-
</ul>
99-
{!disabled &&
100-
!(disableAdd && (disableClear || disableRemove)) && (
101-
<div className={SimpleFormIteratorClasses.buttons}>
102-
{!disableAdd && (
103-
<div
104-
className={
105-
SimpleFormIteratorClasses.add
106-
}
107-
>
108-
{addButton}
109-
</div>
110-
)}
111-
<SimpleFormIteratorClearButton
112-
disableClear={disableClear}
113-
disableRemove={disableRemove}
114-
/>
115-
</div>
116-
)}
117-
</Root>
118-
)}
119-
/>
94+
{children}
95+
</SimpleFormIteratorItem>
96+
</RecordContextProvider>
97+
))}
98+
</ul>
99+
{!disabled &&
100+
!(disableAdd && (disableClear || disableRemove)) && (
101+
<div className={SimpleFormIteratorClasses.buttons}>
102+
{!disableAdd && (
103+
<div className={SimpleFormIteratorClasses.add}>
104+
{addButton}
105+
</div>
106+
)}
107+
<SimpleFormIteratorClearButton
108+
disableClear={disableClear}
109+
disableRemove={disableRemove}
110+
/>
111+
</div>
112+
)}
113+
</Root>
114+
</SimpleFormIteratorBase>
120115
);
121116
};
122117

123118
export interface SimpleFormIteratorProps
124-
extends Omit<SimpleFormIteratorBaseProps, 'render' | 'inputs'> {
119+
extends Omit<
120+
SimpleFormIteratorBaseProps,
121+
'children' | 'render' | 'inputs'
122+
> {
125123
addButton?: ReactNode;
126124
children?: ReactNode;
127125
className?: string;

packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIteratorItem.tsx

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import type { ReactNode } from 'react';
33
import { Typography, Stack } from '@mui/material';
44
import clsx from 'clsx';
55
import {
6+
SimpleFormIteratorItemBase,
67
useRecordContext,
7-
useSimpleFormIteratorItem,
8-
type SimpleFormIteratorDisableRemoveFunction,
98
type RaRecord,
9+
type SimpleFormIteratorDisableRemoveFunction,
10+
type SimpleFormIteratorItemBaseProps,
1011
} from 'ra-core';
1112

1213
import { SimpleFormIteratorClasses } from './useSimpleFormIteratorStyles';
@@ -23,12 +24,12 @@ export const SimpleFormIteratorItem = React.forwardRef<
2324
disableReordering,
2425
disableRemove,
2526
getItemLabel,
27+
index,
2628
inline,
2729
removeButton = <DefaultRemoveItemButton />,
2830
reOrderButtons = <DefaultReOrderButtons />,
2931
} = props;
3032

31-
const { index } = useSimpleFormIteratorItem();
3233
const record = useRecordContext();
3334
if (!record) {
3435
throw new Error(
@@ -51,40 +52,43 @@ export const SimpleFormIteratorItem = React.forwardRef<
5152
typeof getItemLabel === 'function' ? getItemLabel(index) : getItemLabel;
5253

5354
return (
54-
<li className={SimpleFormIteratorClasses.line} ref={ref}>
55-
{label != null && label !== false && (
56-
<Typography
57-
variant="body2"
58-
className={SimpleFormIteratorClasses.index}
55+
<SimpleFormIteratorItemBase {...props}>
56+
<li className={SimpleFormIteratorClasses.line} ref={ref}>
57+
{label != null && label !== false && (
58+
<Typography
59+
variant="body2"
60+
className={SimpleFormIteratorClasses.index}
61+
>
62+
{label}
63+
</Typography>
64+
)}
65+
<Stack
66+
className={clsx(SimpleFormIteratorClasses.form)}
67+
direction={inline ? { xs: 'column', sm: 'row' } : 'column'}
68+
sx={{
69+
gap: inline ? 2 : 0,
70+
}}
5971
>
60-
{label}
61-
</Typography>
62-
)}
63-
<Stack
64-
className={clsx(SimpleFormIteratorClasses.form)}
65-
direction={inline ? { xs: 'column', sm: 'row' } : 'column'}
66-
sx={{
67-
gap: inline ? 2 : 0,
68-
}}
69-
>
70-
{children}
71-
</Stack>
72-
{!disabled && (
73-
<span className={SimpleFormIteratorClasses.action}>
74-
{!disableReordering && reOrderButtons}
72+
{children}
73+
</Stack>
74+
{!disabled && (
75+
<span className={SimpleFormIteratorClasses.action}>
76+
{!disableReordering && reOrderButtons}
7577

76-
{!disableRemoveField(record) && removeButton}
77-
</span>
78-
)}
79-
</li>
78+
{!disableRemoveField(record) && removeButton}
79+
</span>
80+
)}
81+
</li>
82+
</SimpleFormIteratorItemBase>
8083
);
8184
});
8285

8386
export type SimpleFormIteratorGetItemLabelFunc = (
8487
index: number
8588
) => string | ReactNode;
8689

87-
export interface SimpleFormIteratorItemProps {
90+
export interface SimpleFormIteratorItemProps
91+
extends SimpleFormIteratorItemBaseProps {
8892
children?: ReactNode;
8993
disabled?: boolean;
9094
disableRemove?: boolean | SimpleFormIteratorDisableRemoveFunction;

0 commit comments

Comments
 (0)