Skip to content

Commit 90fd4d9

Browse files
committed
Support render prop
1 parent a30cc3f commit 90fd4d9

File tree

2 files changed

+73
-7
lines changed

2 files changed

+73
-7
lines changed

packages/ra-core/src/controller/input/ReferenceArrayInputBase.stories.tsx

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import {
1515
ReferenceArrayInputBase,
1616
ReferenceArrayInputBaseProps,
1717
} from './ReferenceArrayInputBase';
18-
import { ChoicesProps, useChoicesContext } from '../../form';
18+
import {
19+
ChoicesContextValue,
20+
ChoicesProps,
21+
useChoicesContext,
22+
} from '../../form';
1923
import { useGetRecordRepresentation } from '../..';
2024

2125
export default { title: 'ra-core/controller/ReferenceArrayInputBase' };
@@ -51,8 +55,15 @@ const i18nProvider = polyglotI18nProvider(() => englishMessages);
5155
const CheckboxGroupInput = (
5256
props: Omit<InputProps, 'source'> & ChoicesProps
5357
) => {
54-
const { allChoices, isPending, error, resource, source, total } =
55-
useChoicesContext(props);
58+
const choicesContext = useChoicesContext(props);
59+
60+
return <CheckboxGroupInputBase {...props} {...choicesContext} />;
61+
};
62+
63+
const CheckboxGroupInputBase = (
64+
props: Omit<InputProps, 'source'> & ChoicesProps & ChoicesContextValue
65+
) => {
66+
const { allChoices, isPending, error, resource, source, total } = props;
5667
const input = useInput({ ...props, source });
5768
const getRecordRepresentation = useGetRecordRepresentation(resource);
5869

@@ -141,6 +152,53 @@ Basic.argTypes = {
141152
meta: { control: 'boolean' },
142153
};
143154

155+
export const WithRender = ({
156+
dataProvider = defaultDataProvider,
157+
meta,
158+
...props
159+
}: Partial<ReferenceArrayInputBaseProps> & {
160+
dataProvider?: DataProvider;
161+
meta?: boolean;
162+
}) => (
163+
<TestMemoryRouter initialEntries={['/posts/create']}>
164+
<CoreAdmin dataProvider={dataProvider} i18nProvider={i18nProvider}>
165+
<Resource
166+
name="posts"
167+
create={
168+
<CreateBase resource="posts" record={{ tags_ids: [1, 3] }}>
169+
<h1>Create Post</h1>
170+
<Form>
171+
<ReferenceArrayInputBase
172+
reference="tags"
173+
resource="posts"
174+
source="tags_ids"
175+
queryOptions={
176+
meta ? { meta: { foo: 'bar' } } : {}
177+
}
178+
{...props}
179+
render={context => (
180+
<CheckboxGroupInputBase
181+
{...context}
182+
source="tags_ids"
183+
/>
184+
)}
185+
/>
186+
</Form>
187+
</CreateBase>
188+
}
189+
/>
190+
</CoreAdmin>
191+
</TestMemoryRouter>
192+
);
193+
194+
WithRender.args = {
195+
meta: false,
196+
};
197+
198+
WithRender.argTypes = {
199+
meta: { control: 'boolean' },
200+
};
201+
144202
export const WithError = () => (
145203
<TestMemoryRouter initialEntries={['/posts/create']}>
146204
<CoreAdmin

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import { ResourceContextProvider } from '../../core/ResourceContextProvider';
88
import { ChoicesContextProvider } from '../../form/choices/ChoicesContextProvider';
99
import { RaRecord } from '../../types';
10+
import { ChoicesContextValue } from '../../form';
1011

1112
/**
1213
* An Input component for fields containing a list of references to another resource.
@@ -78,13 +79,19 @@ import { RaRecord } from '../../types';
7879
export const ReferenceArrayInputBase = <RecordType extends RaRecord = any>(
7980
props: ReferenceArrayInputBaseProps<RecordType>
8081
) => {
81-
const { children, reference, sort, filter = defaultFilter } = props;
82-
if (React.Children.count(children) !== 1) {
82+
const { children, filter = defaultFilter, reference, render, sort } = props;
83+
if (children && React.Children.count(children) !== 1) {
8384
throw new Error(
8485
'<ReferenceArrayInputBase> only accepts a single child (like <Datagrid>)'
8586
);
8687
}
8788

89+
if (!render && !children) {
90+
throw new Error(
91+
"<EditBase> requires either a 'render' prop or 'children' prop"
92+
);
93+
}
94+
8895
const controllerProps = useReferenceArrayInputController({
8996
...props,
9097
sort,
@@ -94,7 +101,7 @@ export const ReferenceArrayInputBase = <RecordType extends RaRecord = any>(
94101
return (
95102
<ResourceContextProvider value={reference}>
96103
<ChoicesContextProvider value={controllerProps}>
97-
{children}
104+
{render ? render(controllerProps) : children}
98105
</ChoicesContextProvider>
99106
</ResourceContextProvider>
100107
);
@@ -105,5 +112,6 @@ const defaultFilter = {};
105112
export interface ReferenceArrayInputBaseProps<RecordType extends RaRecord = any>
106113
extends InputProps,
107114
UseReferenceArrayInputParams<RecordType> {
108-
children: React.ReactNode;
115+
children?: React.ReactNode;
116+
render?: (context: ChoicesContextValue<RecordType>) => React.ReactNode;
109117
}

0 commit comments

Comments
 (0)