Skip to content

Commit f80532e

Browse files
committed
[DOC] selectInput create example + storie
1 parent a60969a commit f80532e

File tree

2 files changed

+186
-86
lines changed

2 files changed

+186
-86
lines changed

docs/SelectInput.md

Lines changed: 77 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -158,66 +158,70 @@ To allow users to add new options, pass a React element as the `create` prop. `<
158158

159159
{% raw %}
160160
```jsx
161-
import { CreateCategory } from './CreateCategory';
161+
import { CreateAuthor } from './CreateAuthor';
162162

163-
const PostCreate = () => (
163+
const BookCreate = () => (
164164
<Create>
165165
<SimpleForm>
166-
<TextInput source="title" />
167-
<ReferenceInput source="category_id" reference="categories">
168-
<SelectInput create={<CreateCategory />} />
166+
<ReferenceInput reference="authors" source="author">
167+
<SelectInput
168+
create={<CreateAuthor />}
169+
/>
169170
</ReferenceInput>
170171
</SimpleForm>
171172
</Create>
172173
);
173174

174-
// in ./CreateCategory.js
175-
import { useCreate, useCreateSuggestionContext } from 'react-admin';
175+
// in ./CreateAuthor.js
176+
import React from 'react';
177+
import { CreateBase, SimpleForm, TextInput, useCreateSuggestionContext } from 'react-admin';
178+
import CloseIcon from '@mui/icons-material/Close';
176179
import {
177-
Box,
178-
BoxProps,
179180
Button,
180181
Dialog,
181-
DialogActions,
182182
DialogContent,
183-
TextField,
183+
DialogTitle,
184+
IconButton,
184185
} from '@mui/material';
185186

186-
const CreateCategory = () => {
187+
const CreateAuthor = () => {
187188
const { filter, onCancel, onCreate } = useCreateSuggestionContext();
188-
const [create] = useCreate();
189-
const [value, setValue] = React.useState(filter || '');
190-
191-
const handleSubmit = event => {
192-
event.preventDefault();
193-
create(
194-
'categories',
195-
{ data: { title: value } },
196-
{
197-
onSuccess: (data) => {
198-
setValue('');
199-
onCreate(data);
200-
},
201-
}
202-
);
189+
190+
const onAuthorCreate = author => {
191+
onCreate(author);
203192
};
204193

205194
return (
206195
<Dialog open onClose={onCancel}>
207-
<form onSubmit={handleSubmit}>
208-
<DialogContent>
209-
<TextField
210-
label="New category name"
211-
value={value}
212-
onChange={event => setValue(event.target.value)}
213-
autoFocus
214-
/>
215-
</DialogContent>
216-
<DialogActions>
217-
<Button type="submit">Save</Button>
218-
<Button onClick={onCancel}>Cancel</Button>
219-
</DialogActions>
220-
</form>
196+
<DialogTitle sx={{ m: 0, p: 2 }}>Create Author</DialogTitle>
197+
<IconButton
198+
aria-label="close"
199+
onClick={onCancel}
200+
sx={theme => ({
201+
position: 'absolute',
202+
right: 8,
203+
top: 8,
204+
color: theme.palette.grey[500],
205+
})}
206+
>
207+
<CloseIcon />
208+
</IconButton>
209+
<DialogContent sx={{ p: 0 }}>
210+
<CreateBase
211+
redirect={false}
212+
resource="authors"
213+
mutationOptions={{
214+
onSuccess: author => {
215+
onAuthorCreate(author);
216+
},
217+
}}
218+
>
219+
<SimpleForm defaultValues={{ name: filter }}>
220+
<TextInput source="name" helperText={false} />
221+
<TextInput source="language" helperText={false} autoFocus />
222+
</SimpleForm>
223+
</CreateBase>
224+
</DialogContent>
221225
</Dialog>
222226
);
223227
};
@@ -695,43 +699,42 @@ const PostCreate = () => {
695699

696700
const CreateCategory = () => {
697701
const { filter, onCancel, onCreate } = useCreateSuggestionContext();
698-
const [value, setValue] = React.useState(filter || '');
699-
const [create] = useCreate();
700-
701-
const handleSubmit = event => {
702-
event.preventDefault();
703-
create(
704-
'categories',
705-
{
706-
data: {
707-
title: value,
708-
},
709-
},
710-
{
711-
onSuccess: (data) => {
712-
setValue('');
713-
onCreate(data);
714-
},
715-
}
716-
);
702+
703+
const onCategoryCreate = category => {
704+
onCreate(category);
717705
};
718706

707+
719708
return (
720709
<Dialog open onClose={onCancel}>
721-
<form onSubmit={handleSubmit}>
722-
<DialogContent>
723-
<TextField
724-
label="New category name"
725-
value={value}
726-
onChange={event => setValue(event.target.value)}
727-
autoFocus
728-
/>
729-
</DialogContent>
730-
<DialogActions>
731-
<Button type="submit">Save</Button>
732-
<Button onClick={onCancel}>Cancel</Button>
733-
</DialogActions>
734-
</form>
710+
<DialogTitle sx={{ m: 0, p: 2 }}>Create Category</DialogTitle>
711+
<IconButton
712+
aria-label="close"
713+
onClick={onCancel}
714+
sx={theme => ({
715+
position: 'absolute',
716+
right: 8,
717+
top: 8,
718+
color: theme.palette.grey[500],
719+
})}
720+
>
721+
<CloseIcon />
722+
</IconButton>
723+
<DialogContent sx={{ p: 0 }}>
724+
<CreateBase
725+
redirect={false}
726+
resource="categories"
727+
mutationOptions={{
728+
onSuccess: category => {
729+
onCategoryCreate(category);
730+
},
731+
}}
732+
>
733+
<SimpleForm defaultValues={{ title: filter }}>
734+
<TextInput source="name" helperText={false} autoFocus/>
735+
</SimpleForm>
736+
</CreateBase>
737+
</DialogContent>
735738
</Dialog>
736739
);
737740
};

packages/ra-ui-materialui/src/input/SelectInput.stories.tsx

Lines changed: 109 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
1-
import * as React from 'react';
2-
import { Admin, AdminContext } from 'react-admin';
3-
import { Resource, required, useGetList, TestMemoryRouter } from 'ra-core';
4-
import polyglotI18nProvider from 'ra-i18n-polyglot';
5-
import englishMessages from 'ra-language-english';
1+
import CloseIcon from '@mui/icons-material/Close';
62
import {
3+
Button,
74
Dialog,
8-
DialogContent,
95
DialogActions,
6+
DialogContent,
7+
DialogTitle,
8+
IconButton,
109
TextField,
11-
Button,
1210
} from '@mui/material';
11+
import { Resource, TestMemoryRouter, required, useGetList } from 'ra-core';
12+
import polyglotI18nProvider from 'ra-i18n-polyglot';
13+
import englishMessages from 'ra-language-english';
14+
import * as React from 'react';
15+
import { Admin, AdminContext, CreateBase } from 'react-admin';
1316

14-
import { Create as RaCreate, Edit } from '../detail';
15-
import { SimpleForm } from '../form';
16-
import { SelectInput } from './SelectInput';
17-
import { TextInput } from './TextInput';
18-
import { ReferenceInput } from './ReferenceInput';
1917
import { SaveButton } from '../button/SaveButton';
18+
import { Edit, Create as RaCreate } from '../detail';
19+
import { SimpleForm } from '../form';
2020
import { Toolbar } from '../form/Toolbar';
2121
import { FormInspector } from './common';
22+
import { ReferenceInput } from './ReferenceInput';
23+
import { SelectInput } from './SelectInput';
24+
import { TextInput } from './TextInput';
2225
import { useCreateSuggestionContext } from './useSupportCreateSuggestion';
2326

2427
export default { title: 'ra-ui-materialui/input/SelectInput' };
@@ -602,6 +605,100 @@ export const InsideReferenceInputWithError = () => (
602605
</TestMemoryRouter>
603606
);
604607

608+
const CreateAuthor = () => {
609+
const { filter, onCancel, onCreate } = useCreateSuggestionContext();
610+
611+
const onAuthorCreate = author => {
612+
onCreate(author);
613+
};
614+
615+
return (
616+
<Dialog open onClose={onCancel}>
617+
<DialogTitle sx={{ m: 0, p: 2 }}>Create Author</DialogTitle>
618+
<IconButton
619+
aria-label="close"
620+
onClick={onCancel}
621+
sx={theme => ({
622+
position: 'absolute',
623+
right: 8,
624+
top: 8,
625+
color: theme.palette.grey[500],
626+
})}
627+
>
628+
<CloseIcon />
629+
</IconButton>
630+
<DialogContent sx={{ p: 0 }}>
631+
<CreateBase
632+
redirect={false}
633+
resource="authors"
634+
mutationOptions={{
635+
onSuccess: author => {
636+
onAuthorCreate(author);
637+
},
638+
}}
639+
>
640+
<SimpleForm defaultValues={{ name: filter }}>
641+
<TextInput source="name" helperText={false} />
642+
<TextInput
643+
source="language"
644+
helperText={false}
645+
autoFocus
646+
/>
647+
</SimpleForm>
648+
</CreateBase>
649+
</DialogContent>
650+
</Dialog>
651+
);
652+
};
653+
654+
export const InsideReferenceInputWithCreationSupport = () => {
655+
const optionRenderer = choice => {
656+
console.log(choice);
657+
return choice.first_name && choice.last_name
658+
? `${choice.first_name} ${choice.last_name}`
659+
: `${choice.name}`;
660+
};
661+
return (
662+
<TestMemoryRouter initialEntries={['/books/1']}>
663+
<Admin dataProvider={dataProviderWithAuthors}>
664+
<Resource
665+
name="authors"
666+
recordRepresentation={record =>
667+
`${record.first_name} ${record.last_name} toto`
668+
}
669+
/>
670+
<Resource
671+
name="books"
672+
edit={() => (
673+
<Edit
674+
mutationMode="pessimistic"
675+
mutationOptions={{
676+
onSuccess: data => {
677+
console.log(data);
678+
},
679+
}}
680+
>
681+
<SimpleForm>
682+
<ReferenceInput
683+
reference="authors"
684+
source="author"
685+
>
686+
<SelectInput
687+
create={<CreateAuthor />}
688+
createLabel="Create a new Author"
689+
optionText={optionRenderer}
690+
/>
691+
</ReferenceInput>
692+
<FormInspector name="author" />
693+
</SimpleForm>
694+
</Edit>
695+
)}
696+
/>
697+
</Admin>
698+
</TestMemoryRouter>
699+
);
700+
};
701+
605702
export const TranslateChoice = () => {
606703
const i18nProvider = polyglotI18nProvider(() => ({
607704
...englishMessages,

0 commit comments

Comments
 (0)