This is the documentation of how to create a basic SearchBox
element from just an input field in Algolia. The problem is, Algolia's ends up looking pretty ugly
That's where material-ui comes in. I have used AppBar
before which contains a search element, so my thinking was to instantiate SearchBox
within my AppBar.js
component, but with material-ui's proprietary InputBase
(instead of boring html input
).
I'll paste the code I have so far below but it's refusing to compile with InputBase
(and more specifically it's associated props) being used to create a custom SearchBox
element.
If anyone has any experience with meshing different API's like this or think you might know what's going on, don't hesitate to let me know!
import React from 'react';
import PropTypes from 'prop-types';
import AppBar from '@material-ui/core/Appbar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import InputBase from '@material-ui/core/InputBase';
import {fade} from '@material-ui/core/styles/colorManipulator';
import {withStyles} from "@material-ui/core/styles";
import SearchIcon from '@material-ui/icons/Search';
import { connectSearchBox } from 'react-instantsearch-dom';
const styles = theme => ({
root:{
width: '100%',
},
grow:{
flexGrow: 1,
},
menuButton:{
marginLeft: -12,
marginRight: 20,
},
title:{
display: 'none',
[theme.breakpoints.up('sm')]:{
display: 'block',
},
},
search:{
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover':{
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]:{
marginLeft: theme.spacing.unit,
width: 'auto',
},
},
searchIcon:{
width: theme.spacing.unit * 9,
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot:{
color: 'inherit',
width: '100%',
},
inputInput:{
paddingTop: theme.spacing.unit,
paddingRight: theme.spacing.unit,
paddingBottom: theme.spacing.unit,
paddingLeft: theme.spacing.unit * 10,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]:{
width: 120,
'&:focus':{
width: 200,
},
},
},
});
function SearchBox({currentRefinement, refine}, props){
const {classes} = props;
return(
<InputBase
type='search'
value={currentRefinement}
onChange={event => refine(event.currentTarget.value)}
placeholder="Search for Destination by Name, State, and keywords..."
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
);
}
const CustomSearchBox = connectSearchBox(SearchBox);
function SearchAppBar(props){
const {classes} = props;
return(
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<Typography className={classes.title} variant="h6" color='inherit' noWrap>
title
</Typography>
<div className={classes.grow}/>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon/>
</div>
<CustomSearchBox/>
</div>
</Toolbar>
</AppBar>
</div>
);
}
SearchAppBar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SearchAppBar);
(as you can probably tell, I have gone very by the book with respect to documentation - I haven't tried anything special)
If you want to use the material ui search box component instead of Algolia's, you can use connectSearchBox();
to sync the material ui search box and Algolia search box API.
import { InstantSearch, connectSearchBox } from "react-instantsearch-dom";
const CustomSearchBox = connectSearchBox(MaterialUISearchBox);
Inside MaterialUISearchBox component, you will use the props Algolia provides: currentRefinement
and refine()
.
<InputBase
placeholder="Search…"
inputProps={{ "aria-label": "search" }}
value={this.props.currentRefinement}
onChange={(e) => this.props.refine(this.currentTarget.value)}
searchAsYouType={false}
/>
Please check the url for further details about Algolia's custom components.
https://www.algolia.com/doc/api-reference/widgets/search-box/react/