Skip to content

Commit 55cd324

Browse files
committed
add render props to CreateBase component
1 parent fe6d1d9 commit 55cd324

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

docs/CreateBase.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export const BookCreate = () => (
4646
You can customize the `<CreateBase>` component using the following props, documented in the `<Create>` component:
4747

4848
* `children`: the components that renders the form
49+
* `render`: alternative to children, a function that takes the EditController context and renders the form
4950
* [`disableAuthentication`](./Create.md#disableauthentication): disable the authentication check
5051
* [`mutationMode`](./Create.md#mutationmode): Switch to optimistic or undoable mutations (pessimistic by default)
5152
* [`mutationOptions`](./Create.md#mutationoptions): options for the `dataProvider.create()` call

packages/ra-core/src/controller/create/CreateBase.spec.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
DefaultTitle,
99
NoAuthProvider,
1010
WithAuthProviderNoAccessControl,
11+
WithRenderProp,
1112
} from './CreateBase.stories';
1213

1314
describe('CreateBase', () => {
@@ -283,4 +284,22 @@ describe('CreateBase', () => {
283284
fireEvent.click(screen.getByText('FR'));
284285
await screen.findByText('Créer un article (fr)');
285286
});
287+
288+
it('should allow render props', async () => {
289+
const dataProvider = testDataProvider({
290+
// @ts-ignore
291+
create: jest.fn((_, { data }) =>
292+
Promise.resolve({ data: { id: 1, ...data } })
293+
),
294+
});
295+
296+
render(<WithRenderProp dataProvider={dataProvider} />);
297+
fireEvent.click(screen.getByText('save'));
298+
299+
await waitFor(() => {
300+
expect(dataProvider.create).toHaveBeenCalledWith('posts', {
301+
data: { test: 'test' },
302+
});
303+
});
304+
});
286305
});

packages/ra-core/src/controller/create/CreateBase.stories.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,29 @@ export const AccessControl = ({
148148
</CoreAdminContext>
149149
);
150150

151+
export const WithRenderProp = ({
152+
dataProvider = defaultDataProvider,
153+
callTimeOptions,
154+
...props
155+
}: {
156+
dataProvider?: DataProvider;
157+
callTimeOptions?: SaveHandlerCallbacks;
158+
} & Partial<CreateBaseProps>) => (
159+
<CoreAdminContext dataProvider={dataProvider}>
160+
<CreateBase
161+
{...defaultProps}
162+
render={({ save }) => {
163+
const handleClick = () => {
164+
if (!save) return;
165+
save({ test: 'test' }, callTimeOptions);
166+
};
167+
168+
return <button onClick={handleClick}>save</button>;
169+
}}
170+
/>
171+
</CoreAdminContext>
172+
);
173+
151174
const defaultDataProvider = testDataProvider({
152175
// @ts-ignore
153176
create: (_, { data }) => Promise.resolve({ data: { id: 1, ...data } }),

packages/ra-core/src/controller/create/CreateBase.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ReactNode } from 'react';
33
import {
44
useCreateController,
55
CreateControllerProps,
6+
CreateControllerResult,
67
} from './useCreateController';
78
import { CreateContextProvider } from './CreateContextProvider';
89
import { Identifier, RaRecord } from '../../types';
@@ -44,6 +45,7 @@ export const CreateBase = <
4445
MutationOptionsError = Error,
4546
>({
4647
children,
48+
render,
4749
loading = null,
4850
...props
4951
}: CreateBaseProps<RecordType, ResultRecordType, MutationOptionsError>) => {
@@ -62,11 +64,17 @@ export const CreateBase = <
6264
return loading;
6365
}
6466

67+
if (!render && !children) {
68+
throw new Error(
69+
'<CreateBase> requires either a `render` prop or `children` prop'
70+
);
71+
}
72+
6573
return (
6674
// We pass props.resource here as we don't need to create a new ResourceContext if the props is not provided
6775
<OptionalResourceContextProvider value={props.resource}>
6876
<CreateContextProvider value={controllerProps}>
69-
{children}
77+
{render ? render(controllerProps) : children}
7078
</CreateContextProvider>
7179
</OptionalResourceContextProvider>
7280
);
@@ -81,6 +89,7 @@ export interface CreateBaseProps<
8189
MutationOptionsError,
8290
ResultRecordType
8391
> {
84-
children: ReactNode;
92+
children?: ReactNode;
93+
render?: (props: CreateControllerResult<RecordType>) => ReactNode;
8594
loading?: ReactNode;
8695
}

0 commit comments

Comments
 (0)