|
1 | | -import * as React from 'react'; |
2 | | -import { |
3 | | - isValidElement, |
4 | | - useCallback, |
5 | | - useEffect, |
6 | | - useMemo, |
7 | | - useRef, |
8 | | - useState, |
9 | | - type ReactNode, |
10 | | -} from 'react'; |
11 | | -import debounce from 'lodash/debounce.js'; |
12 | | -import get from 'lodash/get.js'; |
13 | | -import isEqual from 'lodash/isEqual.js'; |
14 | | -import clsx from 'clsx'; |
15 | 1 | import { |
16 | 2 | Autocomplete, |
17 | 3 | type AutocompleteChangeReason, |
| 4 | + type AutocompleteCloseReason, |
18 | 5 | type AutocompleteProps, |
19 | 6 | Chip, |
| 7 | + createFilterOptions, |
20 | 8 | TextField, |
21 | 9 | type TextFieldProps, |
22 | | - createFilterOptions, |
23 | 10 | useForkRef, |
24 | 11 | } from '@mui/material'; |
25 | 12 | import { |
26 | 13 | type ComponentsOverrides, |
27 | 14 | styled, |
28 | 15 | useThemeProps, |
29 | 16 | } from '@mui/material/styles'; |
| 17 | +import clsx from 'clsx'; |
| 18 | +import debounce from 'lodash/debounce.js'; |
| 19 | +import get from 'lodash/get.js'; |
| 20 | +import isEqual from 'lodash/isEqual.js'; |
30 | 21 | import { |
31 | 22 | type ChoicesProps, |
32 | 23 | FieldTitle, |
33 | 24 | type RaRecord, |
| 25 | + type SupportCreateSuggestionOptions, |
34 | 26 | useChoicesContext, |
| 27 | + useEvent, |
| 28 | + useGetRecordRepresentation, |
35 | 29 | useInput, |
36 | 30 | useSuggestions, |
37 | 31 | type UseSuggestionsOptions, |
| 32 | + useSupportCreateSuggestion, |
38 | 33 | useTimeout, |
39 | 34 | useTranslate, |
40 | 35 | warning, |
41 | | - useGetRecordRepresentation, |
42 | | - useEvent, |
43 | | - type SupportCreateSuggestionOptions, |
44 | | - useSupportCreateSuggestion, |
45 | 36 | } from 'ra-core'; |
| 37 | +import * as React from 'react'; |
| 38 | +import { |
| 39 | + isValidElement, |
| 40 | + type ReactNode, |
| 41 | + useCallback, |
| 42 | + useEffect, |
| 43 | + useMemo, |
| 44 | + useRef, |
| 45 | + useState, |
| 46 | +} from 'react'; |
| 47 | +import { Offline } from '../Offline'; |
46 | 48 | import type { CommonInputProps } from './CommonInputProps'; |
47 | 49 | import { InputHelperText } from './InputHelperText'; |
48 | 50 | import { sanitizeInputRestProps } from './sanitizeInputRestProps'; |
49 | | -import { Offline } from '../Offline'; |
50 | 51 |
|
51 | 52 | const defaultFilterOptions = createFilterOptions(); |
52 | 53 |
|
@@ -171,7 +172,9 @@ export const AutocompleteInput = < |
171 | 172 | offline = defaultOffline, |
172 | 173 | onBlur, |
173 | 174 | onChange, |
| 175 | + onClose: onCloseProp, |
174 | 176 | onCreate, |
| 177 | + onOpen: onOpenProp, |
175 | 178 | openText = 'ra.action.open', |
176 | 179 | optionText, |
177 | 180 | optionValue, |
@@ -338,6 +341,23 @@ If you provided a React element for the optionText prop, you must also provide t |
338 | 341 |
|
339 | 342 | const [filterValue, setFilterValue] = useState(''); |
340 | 343 |
|
| 344 | + const [isOpen, setIsOpen] = useState(false); |
| 345 | + const canRenderSuggestions = |
| 346 | + shouldRenderSuggestions == undefined || // eslint-disable-line eqeqeq |
| 347 | + shouldRenderSuggestions(filterValue); |
| 348 | + |
| 349 | + const handleOpen = useEvent((event: React.SyntheticEvent) => { |
| 350 | + setIsOpen(true); |
| 351 | + onOpenProp?.(event); |
| 352 | + }); |
| 353 | + |
| 354 | + const handleClose = useEvent( |
| 355 | + (event: React.SyntheticEvent, reason: AutocompleteCloseReason) => { |
| 356 | + setIsOpen(false); |
| 357 | + onCloseProp?.(event, reason); |
| 358 | + } |
| 359 | + ); |
| 360 | + |
341 | 361 | const handleChange = useEvent((newValue: any) => { |
342 | 362 | if (multiple) { |
343 | 363 | if (Array.isArray(newValue)) { |
@@ -755,13 +775,15 @@ If you provided a React element for the optionText prop, you must also provide t |
755 | 775 | clearOnBlur={clearOnBlur} |
756 | 776 | {...sanitizeInputRestProps(rest)} |
757 | 777 | freeSolo={!!create || !!onCreate} |
| 778 | + open={isOpen && canRenderSuggestions} |
| 779 | + onOpen={handleOpen} |
| 780 | + onClose={handleClose} |
758 | 781 | handleHomeEndKeys={!!create || !!onCreate} |
759 | 782 | filterOptions={filterOptions} |
760 | 783 | options={ |
761 | 784 | isPaused && isPlaceholderData |
762 | 785 | ? [] |
763 | | - : shouldRenderSuggestions == undefined || // eslint-disable-line eqeqeq |
764 | | - shouldRenderSuggestions(filterValue) |
| 786 | + : canRenderSuggestions |
765 | 787 | ? suggestions |
766 | 788 | : [] |
767 | 789 | } |
|
0 commit comments