import * as React from 'react' ; import { useCallback } from 'react' ; import PropTypes from 'prop-types' ; import classNames from 'classnames' ; import { InputAdornment , IconButton , TextField as MuiTextField , TextFieldProps , Theme , } from '@material-ui/core' ; import { makeStyles } from '@material-ui/core/styles' ; import ClearIcon from '@material-ui/icons/Clear' ; import { InputProps , useTranslate } from 'ra-core' ; import { ClassesOverride } from '../types' ; import { Styles } from '@material-ui/styles' ; /**
 * An override of the default Material-UI TextField which is resettable
 */ const ResettableTextField = ( props ) => { const { classes : classesOverride , clearAlwaysVisible , InputProps , value , resettable , disabled , variant = 'filled' , margin = 'dense' , ... rest } = props ; const classes = useStyles ( props ) ; const translate = useTranslate ( ) ; const { onChange , onFocus , onBlur } = props ; const handleClickClearButton = useCallback ( event => { event . preventDefault ( ) ; onChange ( '' ) ; } , [ onChange ] ) ; const handleFocus = useCallback ( event => { onFocus && onFocus ( event ) ; } , [ onFocus ] ) ; const handleBlur = useCallback ( event => { onBlur && onBlur ( event ) ; } , [ onBlur ] ) ; const { clearButton , clearIcon , inputAdornedEnd , selectAdornment , visibleClearIcon , ... restClasses } = classes ; const { endAdornment , ... InputPropsWithoutEndAdornment } = InputProps || { } ; if ( clearAlwaysVisible && endAdornment ) { throw new Error ( 'ResettableTextField cannot display both an endAdornment and a clear button always visible' ) ; } const getEndAdornment = ( ) => { if ( ! resettable ) { return endAdornment ; } else if ( ! value ) { if ( clearAlwaysVisible ) { return ( < InputAdornment position = "end" classes = { { root : props . select ? selectAdornment : null , } } > < IconButton className = { clearButton } aria - label = { translate ( 'ra.action.clear_input_value' ) } title = { translate ( 'ra.action.clear_input_value' ) } disableRipple disabled = { true } > < ClearIcon className = { classNames ( clearIcon , visibleClearIcon ) } /> < /IconButton> < /InputAdornment>); } else { if ( endAdornment ) { return endAdornment ; } else { return ( < InputAdornment position = "end" classes = { { root : props . select ? selectAdornment : null , } } > < span className = { clearButton } > & nbsp ; < /span> < /InputAdornment>); } } } else { return ( < InputAdornment position = "end" classes = { { root : props . select ? selectAdornment : null , } } > < IconButton className = { clearButton } aria - label = { translate ( 'ra.action.clear_input_value' ) } title = { translate ( 'ra.action.clear_input_value' ) } disableRipple onClick = { handleClickClearButton } onMouseDown = { handleMouseDownClearButton } disabled = { disabled } > < ClearIcon className = { classNames ( clearIcon , { [ visibleClearIcon ] : clearAlwaysVisible || value , } ) } /> < /IconButton> < /InputAdornment>); } } ; return ( < MuiTextField classes = { restClasses } value = { value } InputProps = { { classes : props . select && variant === 'filled' ? { adornedEnd : inputAdornedEnd } : { } , endAdornment : getEndAdornment ( ) , ... InputPropsWithoutEndAdornment , } } disabled = { disabled } variant = { variant } margin = { margin } { ... rest } onFocus = { handleFocus } onBlur = { handleBlur } / > ) ; } ; export const resettableStyles = { clearIcon : { height : 16 , width : 0 , } , visibleClearIcon : { width : 16 , } , clearButton : { height : 24 , width : 24 , padding : 0 , } , selectAdornment : { position : 'absolute' , right : 24 , } , inputAdornedEnd : { paddingRight : 0 , } , } ; const useStyles = makeStyles ( resettableStyles , { name : 'RaResettableTextField' , } ) ; const handleMouseDownClearButton = event => { event . preventDefault ( ) ; } ; ResettableTextField . propTypes = { classes : PropTypes . object , clearAlwaysVisible : PropTypes . bool , disabled : PropTypes . bool , InputProps : PropTypes . object , onBlur : PropTypes . func , onChange : PropTypes . func . isRequired , onFocus : PropTypes . func , resettable : PropTypes . bool , value : PropTypes . any . isRequired , } ; interface Props { classes ? : ClassesOverride < typeof useStyles > ; clearAlwaysVisible ? : boolean ; resettable ? : boolean ; } export type ResettableTextFieldProps = InputProps < Props & TextFieldProps > ; export default ResettableTextField ;