@@ -4,22 +4,31 @@ import PropTypes from 'prop-types'
44import React , { forwardRef , useState , useMemo } from 'react'
55
66import withOnlyLocales from './locales/withOnlyLocales'
7+ import ButtonBase from '../ButtonBase'
78import Icon from '../Icon'
9+ import { iconPropType } from '../Icon'
810import IconButton from '../IconButton'
911import CrossCircleIcon from '../Icons/CrossCircle'
1012import MagnifierIcon from '../Icons/Magnifier'
1113import InputBase from '../InputBase'
1214import Paper from '../Paper'
15+ import Typography from '../Typography'
1316import { useI18n } from '../providers/I18n'
1417import { makeStyles } from '../styles'
1518
19+ const sizeToPixel = {
20+ small : 40 ,
21+ medium : 48 ,
22+ large : 56
23+ }
24+
1625const useStyles = makeStyles ( theme => ( {
1726 root : {
1827 display : 'flex' ,
1928 boxSizing : 'border-box' ,
2029 position : 'relative' ,
2130 alignItems : 'center' ,
22- height : 40 ,
31+ height : ( { size } ) => sizeToPixel [ size ] ,
2332 flex : 1 ,
2433 borderRadius : 99 ,
2534 borderStyle : 'solid' ,
@@ -37,7 +46,19 @@ const useStyles = makeStyles(theme => ({
3746 backgroundColor : theme . palette . background . contrast
3847 } ,
3948 inputBase : {
40- flex : 1
49+ flex : 1 ,
50+ paddingLeft : ( { icon } ) => ! icon && '1rem'
51+ } ,
52+ buttonBase : {
53+ flex : 1 ,
54+ justifyContent : 'start' ,
55+ height : '100%' ,
56+ borderRadius : 99
57+ } ,
58+ typography : {
59+ color : 'currentColor' ,
60+ opacity : 0.42 ,
61+ paddingLeft : ( { icon } ) => ! icon && '1rem'
4162 } ,
4263 icon : {
4364 color : theme . palette . text . secondary ,
@@ -81,6 +102,12 @@ const SearchBar = forwardRef(
81102 (
82103 {
83104 placeholder : placeholderProp ,
105+ icon,
106+ size,
107+ type,
108+ label : labelProp ,
109+ componentsProps,
110+ disabledClear,
84111 className,
85112 defaultValue,
86113 elevation,
@@ -93,11 +120,12 @@ const SearchBar = forwardRef(
93120 ref
94121 ) => {
95122 const { t } = useI18n ( )
96- const classes = useStyles ( )
123+ const classes = useStyles ( { size , type , icon } )
97124 const [ currentValue , setCurrentValue ] = useState ( defaultValue )
98125 const [ isFocused , setIsFocused ] = useState ( false )
99126
100127 const placeholder = placeholderProp || t ( 'search.placeholder' )
128+ const label = labelProp || t ( 'search.placeholder' )
101129
102130 const delayedOnChange = useMemo (
103131 ( ) => debounce ( event => onChange ( event ) , 375 ) ,
@@ -143,18 +171,32 @@ const SearchBar = forwardRef(
143171 ref = { ref }
144172 { ...props }
145173 >
146- < Icon className = { classes . icon } icon = { MagnifierIcon } />
147- < InputBase
148- className = { classes . inputBase }
149- placeholder = { disabled ? null : placeholder }
150- value = { disabled ? placeholder : currentValue }
151- disabled = { disabled }
152- aria-label = { placeholder }
153- onChange = { handleChange }
154- onFocus = { handleFocus }
155- onBlur = { handleBlur }
156- />
157- { currentValue && (
174+ { type === 'button' ? (
175+ < ButtonBase className = { classes . buttonBase } >
176+ { icon && < Icon className = { classes . icon } icon = { icon } /> }
177+ { typeof label === 'string' ? (
178+ < Typography className = { classes . typography } > { label } </ Typography >
179+ ) : (
180+ label
181+ ) }
182+ </ ButtonBase >
183+ ) : (
184+ < >
185+ { icon && < Icon className = { classes . icon } icon = { icon } /> }
186+ < InputBase
187+ { ...componentsProps ?. inputBase }
188+ className = { classes . inputBase }
189+ placeholder = { disabled ? null : placeholder }
190+ value = { disabled ? placeholder : currentValue }
191+ disabled = { disabled }
192+ aria-label = { placeholder }
193+ onChange = { handleChange }
194+ onFocus = { handleFocus }
195+ onBlur = { handleBlur }
196+ />
197+ </ >
198+ ) }
199+ { currentValue && ! disabledClear && (
158200 < IconButton size = "medium" onClick = { handleClear } >
159201 < Icon icon = { CrossCircleIcon } />
160202 </ IconButton >
@@ -174,6 +216,10 @@ SearchBar.displayName = 'SearchBar'
174216
175217SearchBar . defaultProps = {
176218 elevation : true ,
219+ icon : MagnifierIcon ,
220+ size : 'small' ,
221+ type : 'search' ,
222+ disabledClear : false ,
177223 defaultValue : '' ,
178224 onChange : ( ) => { } ,
179225 onFocus : ( ) => { } ,
@@ -182,9 +228,22 @@ SearchBar.defaultProps = {
182228
183229SearchBar . propTypes = {
184230 className : PropTypes . string ,
231+ type : PropTypes . oneOf ( [ 'button' , 'search' ] ) ,
232+ icon : iconPropType ,
233+ size : PropTypes . oneOf ( [ 'small' , 'medium' , 'large' ] ) ,
234+ componentsProps : PropTypes . shape ( {
235+ /** Props spread to InputBase component */
236+ inputBase : PropTypes . object
237+ } ) ,
185238 defaultValue : PropTypes . string ,
239+ disabledClear : PropTypes . bool ,
186240 elevation : PropTypes . bool ,
187241 placeholder : PropTypes . string ,
242+ label : PropTypes . oneOfType ( [
243+ PropTypes . string ,
244+ PropTypes . func ,
245+ PropTypes . object
246+ ] ) ,
188247 disabled : PropTypes . bool ,
189248 onChange : PropTypes . func ,
190249 onFocus : PropTypes . func ,
0 commit comments