diff --git a/examples/simple/src/comments/CommentEdit.tsx b/examples/simple/src/comments/CommentEdit.tsx index 31cf7849131..079c0a36477 100644 --- a/examples/simple/src/comments/CommentEdit.tsx +++ b/examples/simple/src/comments/CommentEdit.tsx @@ -1,3 +1,4 @@ +import * as React from 'react'; import { Card, Typography, @@ -8,7 +9,6 @@ import { Button, } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import * as React from 'react'; import { AutocompleteInput, DateInput, @@ -114,6 +114,7 @@ const CommentEdit = props => { basePath, version, } = controllerProps; + return (
@@ -154,7 +155,9 @@ const CommentEdit = props => { ) => true} optionText={} inputText={inputText} - options={{ fullWidth: true }} + options={{ + fullWidth: true, + }} /> diff --git a/packages/ra-core/src/util/index.ts b/packages/ra-core/src/util/index.ts index 5b43891e3c6..fd9c8c5c6d5 100644 --- a/packages/ra-core/src/util/index.ts +++ b/packages/ra-core/src/util/index.ts @@ -13,6 +13,7 @@ import useWhyDidYouUpdate from './useWhyDidYouUpdate'; import { useSafeSetState, useTimeout } from './hooks'; import { getMutationMode } from './getMutationMode'; export * from './indexById'; +export * from './mergeRefs'; export { escapePath, diff --git a/packages/ra-core/src/util/mergeRefs.ts b/packages/ra-core/src/util/mergeRefs.ts new file mode 100644 index 00000000000..543685562de --- /dev/null +++ b/packages/ra-core/src/util/mergeRefs.ts @@ -0,0 +1,16 @@ +import { LegacyRef, MutableRefObject, RefCallback } from 'react'; + +// https://github.com/gregberge/react-merge-refs +export function mergeRefs( + refs: Array | LegacyRef> +): RefCallback { + return value => { + refs.forEach(ref => { + if (typeof ref === 'function') { + ref(value); + } else if (ref != null) { + (ref as React.MutableRefObject).current = value; + } + }); + }; +} diff --git a/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx b/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx index 076bd922955..41b2159338d 100644 --- a/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx +++ b/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx @@ -8,7 +8,7 @@ import React, { import Downshift, { DownshiftProps } from 'downshift'; import classNames from 'classnames'; import get from 'lodash/get'; -import { TextField, Chip } from '@material-ui/core'; +import { TextField, Chip, InputProps } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import { TextFieldProps } from '@material-ui/core/TextField'; import { @@ -17,6 +17,7 @@ import { ChoicesInputProps, useSuggestions, warning, + mergeRefs, } from 'ra-core'; import debounce from 'lodash/debounce'; @@ -367,6 +368,8 @@ const AutocompleteArrayInput = (props: AutocompleteArrayInputProps) => { return true; }; + const { inputRef, ...InputPropsWithoutInputRef } = InputProps || {}; + return ( <> { id={id} fullWidth={fullWidth} InputProps={{ - inputRef: storeInputRef, + inputRef: mergeRefs([ + storeInputRef, + inputRef, + ]), classes: { root: classNames(classes.inputRoot, { [classes.inputRootFilled]: @@ -461,6 +467,7 @@ const AutocompleteArrayInput = (props: AutocompleteArrayInputProps) => { ); }, onFocus, + ...InputPropsWithoutInputRef, }} error={!!(touched && (error || submitError))} label={ @@ -580,13 +587,16 @@ const useStyles = makeStyles( const DefaultSetFilter = () => {}; interface Options { - suggestionsContainerProps?: any; + InputProps?: InputProps; labelProps?: any; + suggestionsContainerProps?: any; } export interface AutocompleteArrayInputProps - extends ChoicesInputProps, + extends ChoicesInputProps, Omit, - Omit, 'onChange'> {} + Omit, 'onChange'> { + options?: Options; +} export default AutocompleteArrayInput; diff --git a/packages/ra-ui-materialui/src/input/AutocompleteInput.tsx b/packages/ra-ui-materialui/src/input/AutocompleteInput.tsx index ad147ef78b3..461ea78bf19 100644 --- a/packages/ra-ui-materialui/src/input/AutocompleteInput.tsx +++ b/packages/ra-ui-materialui/src/input/AutocompleteInput.tsx @@ -9,7 +9,12 @@ import React, { import Downshift, { DownshiftProps } from 'downshift'; import get from 'lodash/get'; import classNames from 'classnames'; -import { TextField, InputAdornment, IconButton } from '@material-ui/core'; +import { + TextField, + InputAdornment, + IconButton, + InputProps, +} from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import ClearIcon from '@material-ui/icons/Clear'; import { TextFieldProps } from '@material-ui/core/TextField'; @@ -17,6 +22,7 @@ import { useInput, FieldTitle, ChoicesInputProps, + mergeRefs, useSuggestions, useTranslate, warning, @@ -364,7 +370,8 @@ export const AutocompleteInput = (props: AutocompleteInputProps) => { return true; }; - const { endAdornment, ...InputPropsWithoutEndAdornment } = InputProps || {}; + const { endAdornment, inputRef, ...InputPropsWithoutEndAdornment } = + InputProps || {}; const handleClickClearButton = useCallback( openMenu => event => { @@ -494,7 +501,10 @@ export const AutocompleteInput = (props: AutocompleteInputProps) => { id={id} name={input.name} InputProps={{ - inputRef: storeInputRef, + inputRef: mergeRefs([ + storeInputRef, + inputRef, + ]), endAdornment: getEndAdornment(openMenu), onBlur, onChange: event => { @@ -623,16 +633,18 @@ const useStyles = makeStyles( ); interface Options { - suggestionsContainerProps?: any; + InputProps?: InputProps; labelProps?: any; + suggestionsContainerProps?: any; } export interface AutocompleteInputProps - extends ChoicesInputProps, + extends ChoicesInputProps, Omit, Omit, 'onChange'> { clearAlwaysVisible?: boolean; resettable?: boolean; loaded?: boolean; loading?: boolean; + options?: Options; }