Skip to content

Commit 078ba46

Browse files
committed
Simplify implementation
1 parent 15dd083 commit 078ba46

File tree

3 files changed

+44
-45
lines changed

3 files changed

+44
-45
lines changed

packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.Card.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import englishMessages from 'ra-language-english';
3232

3333
import { InPlaceEditor } from './InPlaceEditor';
3434
import { SelectInput } from '../SelectInput';
35-
import { ChipField, SelectField, TextField } from '../../field';
35+
import { ChipField, SelectField } from '../../field';
3636
import { Notification } from '../../layout';
3737

3838
export default {

packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,39 @@ import { Box, IconButton, type SxProps } from '@mui/material';
1414
import SaveIcon from '@mui/icons-material/Save';
1515
import CloseIcon from '@mui/icons-material/Close';
1616

17-
import {
18-
InPlaceEditorContext,
19-
type InPlaceEditorValue,
20-
type InPlaceEditorAction,
21-
} from './InPlaceEditorContext';
2217
import { TextInput } from '../TextInput';
2318
import { TextField } from '../../field';
2419

20+
export type InPlaceEditorAction =
21+
| { type: 'edit' }
22+
| { type: 'save'; values: any }
23+
| { type: 'cancel' }
24+
| { type: 'success' }
25+
| { type: 'error'; error: any };
26+
27+
export type InPlaceEditorValue =
28+
| { state: 'editing' }
29+
| { state: 'saving'; values: any }
30+
| { state: 'reading' };
31+
2532
export interface InPlaceEditorProps {
2633
source?: string;
2734
mutationMode?: 'optimistic' | 'pessimistic' | 'undoable';
2835
cancelOnBlur?: boolean;
2936
notifyOnSuccess?: boolean;
37+
resource?: string;
3038
showButtons?: boolean;
3139
children?: React.ReactNode;
3240
editor?: React.ReactNode;
3341
sx?: SxProps;
3442
}
3543

44+
/**
45+
* Renders a value, and on click it turns into an editable field.
46+
*
47+
* The editable field is rendered inside a Form component, so InPlaceEditor
48+
* cannot be used inside another Form component.
49+
*/
3650
export const InPlaceEditor = (props: InPlaceEditorProps) => {
3751
const {
3852
source,
@@ -97,10 +111,10 @@ export const InPlaceEditor = (props: InPlaceEditorProps) => {
97111
);
98112

99113
const record = useRecordContext();
100-
const resource = useResourceContext();
114+
const resource = useResourceContext(props);
101115
const notify = useNotify();
102-
const [update] = useUpdate();
103116
const translate = useTranslate();
117+
const [update] = useUpdate();
104118

105119
const handleSave = async values => {
106120
if (!record) {
@@ -151,6 +165,12 @@ export const InPlaceEditor = (props: InPlaceEditorProps) => {
151165
const handleCancel = () => {
152166
dispatch({ type: 'cancel' });
153167
};
168+
const handleKeyDown = (event: React.KeyboardEvent) => {
169+
if (event.key === 'Escape') {
170+
dispatch({ type: 'cancel' });
171+
}
172+
};
173+
154174
const handleBlur = (event: React.FocusEvent) => {
155175
if (event.relatedTarget) {
156176
return;
@@ -165,9 +185,9 @@ export const InPlaceEditor = (props: InPlaceEditorProps) => {
165185
}
166186
};
167187

168-
return (
169-
<InPlaceEditorContext.Provider value={{ state, dispatch }}>
170-
{state.state === 'reading' ? (
188+
switch (state.state) {
189+
case 'reading':
190+
return (
171191
<Box
172192
onClick={handleEdit}
173193
sx={{
@@ -179,14 +199,12 @@ export const InPlaceEditor = (props: InPlaceEditorProps) => {
179199
>
180200
{children}
181201
</Box>
182-
) : state.state === 'editing' ? (
202+
);
203+
case 'editing':
204+
return (
183205
<Form onSubmit={handleSave}>
184206
<Box
185-
onKeyDown={event => {
186-
if (event.key === 'Escape') {
187-
handleCancel();
188-
}
189-
}}
207+
onKeyDown={handleKeyDown}
190208
onBlur={handleBlur}
191209
sx={{
192210
display: 'flex',
@@ -222,13 +240,16 @@ export const InPlaceEditor = (props: InPlaceEditorProps) => {
222240
)}
223241
</Box>
224242
</Form>
225-
) : state.state === 'saving' ? (
243+
);
244+
case 'saving':
245+
// set a custom record context with the new values
246+
// to avoid flickering
247+
return (
226248
<RecordContextProvider value={state.values}>
227249
<Box sx={{ opacity: 0.5 }}>{children}</Box>
228250
</RecordContextProvider>
229-
) : (
230-
''
231-
)}
232-
</InPlaceEditorContext.Provider>
233-
);
251+
);
252+
default:
253+
throw new Error('Unhandled state');
254+
}
234255
};

packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditorContext.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)