-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
/
ReferenceInput.tsx
126 lines (118 loc) · 3.7 KB
/
ReferenceInput.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import React, { ReactElement } from 'react';
import PropTypes from 'prop-types';
import {
ChoicesContextProvider,
useReferenceInputController,
InputProps,
ResourceContextProvider,
UseReferenceInputControllerParams,
} from 'ra-core';
import { AutocompleteInput } from './AutocompleteInput';
/**
* An Input component for choosing a reference record. Useful for foreign keys.
*
* This component fetches the possible values in the reference resource
* (using `dataProvider.getList()`), then renders an `<AutocompleteInput>`,
* to which it passes the possible choices via a `ChoicesContext`.
*
* You can pass a child select component to customize the way the reference
* selector is displayed (e.g. using `<SelectInput>` or `<RadioButtonGroupInput>`
* instead of `<AutocompleteInput>`).
*
* @example // default selector: AutocompleteInput
* export const CommentEdit = () => (
* <Edit>
* <SimpleForm>
* <ReferenceInput label="Post" source="post_id" reference="posts" />
* </SimpleForm>
* </Edit>
* );
*
* @example // using a SelectInput as selector
* export const CommentEdit = () => (
* <Edit>
* <SimpleForm>
* <ReferenceInput label="Post" source="post_id" reference="posts">
* <SelectInput optionText="title" />
* </ReferenceInput>
* </SimpleForm>
* </Edit>
* );
*
* By default, restricts the possible values to 25. You can extend this limit
* by setting the `perPage` prop.
*
* @example
* <ReferenceInput source="post_id" reference="posts" perPage={100}/>
*
* By default, orders the possible values by id desc. You can change this order
* by setting the `sort` prop (an object with `field` and `order` properties).
*
* @example
* <ReferenceInput
* source="post_id"
* reference="posts"
* sort={{ field: 'title', order: 'ASC' }}
* />
*
* Also, you can filter the query used to populate the possible values. Use the
* `filter` prop for that.
*
* @example
* <ReferenceInput
* source="post_id"
* reference="posts"
* filter={{ is_published: true }}
* />
*
* The enclosed component may filter results. ReferenceInput create a ChoicesContext which provides
* a `setFilters` function. You can call this function to filter the results.
*/
export const ReferenceInput = (props: ReferenceInputProps) => {
const {
children = defaultChildren,
reference,
sort = { field: 'id', order: 'DESC' },
filter = {},
} = props;
const controllerProps = useReferenceInputController({
...props,
sort,
filter,
});
if (props.validate && process.env.NODE_ENV !== 'production') {
throw new Error(
'<ReferenceInput> does not accept a validate prop. Set the validate prop on the child instead.'
);
}
return (
<ResourceContextProvider value={reference}>
<ChoicesContextProvider value={controllerProps}>
{children}
</ChoicesContextProvider>
</ResourceContextProvider>
);
};
ReferenceInput.propTypes = {
children: PropTypes.element,
filter: PropTypes.object,
label: PropTypes.string,
page: PropTypes.number,
perPage: PropTypes.number,
record: PropTypes.object,
reference: PropTypes.string.isRequired,
resource: PropTypes.string,
sort: PropTypes.shape({
field: PropTypes.string,
order: PropTypes.oneOf(['ASC', 'DESC']),
}),
source: PropTypes.string,
};
const defaultChildren = <AutocompleteInput />;
export interface ReferenceInputProps
extends InputProps,
UseReferenceInputControllerParams {
children?: ReactElement;
label?: string;
[key: string]: any;
}