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/
Related
I have created 5 components that are wrapped inside a component. I want all 5 of those cards to stay in one row whether the screen size increases or decreases. With my current code, the cards show up in one row, but they go over the screen. I would have to scroll to the right in order to see the fifth card.
I want to be able to see all five cards on the screen regardless of the screen size. At the very least, all of them together on a screen larger than an iPad. Please help.
Code Below:
"time-card" component
import * as React from 'react';
import {
Card,
CardHeader,
CardMedia,
CardContent,
Typography,
} from '#mui/material';
import Icon from './images/icon.png';
import { makeStyles } from '#mui/styles';
import { variables } from 'theme';
const useStyles = makeStyles({
card: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
textAlign: 'center',
minWidth: 400,
maxWidth: 500,
height: '100%',
position: 'relative',
backgroundColor: '#7b1f82',
backgroundImage: 'linear-gradient(#891f7e, #6d2386)',
minHeight: '600px',
maxHeight: '700px',
margin: 10,
padding: '30px',
flexGrow: 1,
flexShrink: 1,
},
mediaSize: {
width: 70,
display: 'flex',
alignSelf: 'center',
},
Icon: {
display: 'flex',
alignSelf: 'center',
marginTop: '20px',
boxShadow: `8px 7px 9px 2px #600562`,
borderRadius: '50%',
height: '400',
width: 90,
padding: 7,
},
cardHeader: {
marginBottom: 0,
padding: 0,
},
eventName: {
marginBottom: '15 0',
fontWeight: 600,
fontSize: 70,
align: 'center',
},
cardContent: {
marginTop: 0,
paddingTop: 0,
},
eventBeginTime: {
fontSize: 55,
fontWeight: 600,
},
eventEndTime: {
fontSize: 65,
fontWeight: 600,
},
});
const TimeCard = () => {
const classes = useStyles();
return (
<Card className={classes.card}>
<CardMedia
className={classes.Icon}
component="img"
image={Icon}
></CardMedia>
<CardHeader
flexGrow={1}
className={classes.cardHeader}
title={
<Typography className={classes.eventName} align="center">
Event
</Typography>
}
/>
<CardContent className={classes.cardContent}>
<Typography color={variables.primary.main} variant="h2">
Begins
<Typography className={classes.eventBeginTime}>5:00 AM</Typography>
</Typography>
<Typography color={variables.white} variant="h2">
Ends
<Typography className={classes.eventEndTime}>6:00 AM</Typography>
</Typography>
</CardContent>
</Card>
);
};
export default TimeCard;
"Time-card-grid" component
import * as React from 'react';
import Grid from '#mui/material/Grid';
import { makeStyles } from '#mui/styles';
import TimeCard from './time-card';
const useStyles = makeStyles({
timeCardGrid: {
margin: 0,
},
});
const TimesGrid = () => {
const classes = useStyles();
return (
<div style={{ maxWidth: '100%' }}>
<Grid container className={classes.timeCardGrid} wrap="nowrap">
<TimeCard />
<TimeCard />
<TimeCard />
<TimeCard />
<TimeCard />
</Grid>
</div>
);
};
export default PrayerTimesGrid;
The minWidth property on your card is what's causing the overflow. The card will never be narrower than 400px, which is wider than a lot of phone screens. If you want everything on the page the maxWidth of the card should be the width of the screen divided by 5. e.g maxWidth: '20vw' (20% of the viewport width) or even just width: '20vw' and forget about maximum and minimum.
To do what you want, you have to think about the screen size. For instance,
Each card can't be fixed at 400px. Because otherwise you'll have to run into the situation you got. Maybe remove this line:
minWidth: 400,
And then your TimesGrid can be a flex based. This way all cards can spread out in a row.
const useStyles = makeStyles({
timeCardGrid: {
margin: 0,
display: flex,
justifyContent: "space-between"
},
})
I was working on a footer for my project.
I am using material UI grid for the footer so I wanted to add the logo at the bottom but I don't understand why it is having right padding (I guess it is padding, not sure).
ScreenShot ->
It's something like this. (Have blurred the logo for privacy reasons)
Code Footer.js React Compoennt ->
import React from "react";
import CssBaseline from "#material-ui/core/CssBaseline";
import Typography from "#material-ui/core/Typography";
import { makeStyles } from "#material-ui/core/styles";
import Container from "#material-ui/core/Container";
import Link from "#material-ui/core/Link";
import Grid from "#material-ui/core/Grid";
import Box from "#material-ui/core/Box";
import logoWhite from "../logos/logoWhite.png";
function Copyright() {
return (
<Typography variant="body2" color="textSecondary">
{"Copyright © "}
<Link color="inherit" href="https://material-ui.com/">
Your Website
</Link>{" "}
{new Date().getFullYear()}
{"."}
</Typography>
);
}
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
flexDirection: "column",
minHeight: "100vh",
},
main: {
marginTop: theme.spacing(8),
marginBottom: theme.spacing(2),
},
footer: {
padding: theme.spacing(3, 2),
marginTop: "auto",
backgroundColor: "#312D2D",
color: "white",
height: 167,
},
footerGrid: {
width: "20%",
marginLeft: 40,
marginTop: 35,
pading:0,
border: "2px solid red"
},
footerLogo: {
minWidth: "50%",
maxWidth: "60%",
width: "auto",
margin: "0 auto",
backgroundColor: "pink"
},
footerGridLogo: {
width: "fit-content",
pading:0,
borderRight: "1px solid white",
margin:0,
border: "4px solid green"
}
}));
export default function Footer() {
const classes = useStyles();
return (
<div className={classes.root}>
<CssBaseline />
<footer className={classes.footer}>
<Grid spacing={0} className={classes.footerGrid}>
<Grid item className={classes.footerGridLogo}>
<img
src={logoWhite}
alt="brandlogo"
className=""
className={classes.footerLogo}
/>
</Grid>
</Grid>
</footer>
</div>
);
}
Wanted it to look something like this ->
add this inline styling inside the Grid item tag style={{display:'flex',justifyContent:'center',alignItems:'center'}}
I implementing TabsBar in my Appbar for my React Desktop Application.
But I really have a hard time stylizing the Tabs part. If anyone can help me with clear explanations, that would be great. I want to add Icons to the right of the text. Change the color of the tab indicator and put it on top as on the picture example. I'm a beginner. I searched for 4 days but the I ask because I block
We have two colors :(#738889) & (#006F85) for actived Tab.
AppBar with Tabs Designed
Voici Mon code actuel ci-dessous :
import React from 'react';
import PropTypes from 'prop-types';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import Button from '#material-ui/core/Button';
import IconButton from '#material-ui/core/IconButton';
import SearchIcon from '#material-ui/icons/Search';
import InputBase from '#material-ui/core/InputBase';
import Icon from '#material-ui/core/Icon';
import { fade, makeStyles } from '#material-ui/core/styles';
import { withStyles } from '#material-ui/core/styles';
import { ReactComponent as BrandLogo } from '../Assets//PriceWanted/BrandLogo.svg';
import { ReactComponent as Icon_MicroPhone } from '../Icons/Icon_MicroPhone.svg';
import { ReactComponent as Icon_Separation } from '../Icons/Icon_Separation.svg';
import { ReactComponent as Icon_Global } from '../Icons/Icon_Global.svg';
import { ReactComponent as Icon_Lightning } from '../Icons/Icon_Lightning.svg';
import { ReactComponent as Icon_Shipment_Boat } from '../Icons/Icon_Shipment_Boat.svg';
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
width: '100%',
backgroundColor: theme.palette.background.paper,
},
Tabs: {
marginLeft: 50,
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
transition: theme.transitions.create('backgroundColor'),
marginRight: 10,
width: '100%',
backgroundColor: fade(theme.palette.common.black, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.black, 0.70),
boxShadow: '0 3px 5px 2px rgba(25, 1, 12, .2)',
},
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(3),
width: 'auto',
},
},
inputRoot: {
color: '#2F6164',
'&:hover': {
color: '#b2ebf2',
},
},
inputInput: {
padding: theme.spacing(1),
paddingLeft: `calc(1em + ${theme.spacing(2.5)}px)`,
paddingRight: `calc(1em + ${theme.spacing(2.5)}px)`,
transition: theme.transitions.create('width'),
width: '90%',
flex: 1,
[theme.breakpoints.up('sm')]: {
borderColor: 'grey',
'&:focus': {
borderColor: 'green',
},
width: '35ch',
'&:focus': {
width: '50ch',
},
},
},
searchIcon: {
padding: theme.spacing(0, 1),
color: '#889FA0',
height: '100%',
position: 'absolute',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
iconButton: {
padding:5,
marginRight: 6,
marginLeft: 6,
},
Toolbar: {
alignItems:'center'
},
}));
TabPanel.propTypes = {children: PropTypes.node,index: PropTypes.any.isRequired,value: PropTypes.any.isRequired,};
function TabPanel(props) {const { children, value, index, ...other } = props;}
function a11yProps(index) {return{id: `simple-tab-${index}`,'aria-controls': `simple-tabpanel-${index}`,};}
export default function SimpleTabs() {
const classes = useStyles();
const StyledButton = withStyles({
root : {background: 'linear-gradient(270deg,#00DBFF 0%, #021118 61.57%, #000000 100%)',
'&:hover': {background:'linear-gradient(90deg, #00DBFF 0%, #000000 100%)',},
position: 'relative',
borderRadius: 4,
border: 1,
color: 'White',
height: 35,
padding: '10 5px',
boxShadow: '0 3px 5px 2px rgba(0px 4px 4px #CBCBCB)',
marginLeft: 1,
justifyContent:'center'},
textTransform: 'capitalize',})(Button);
const [value, setValue] = React.useState(0);
const handleChange = (event,newValue) => {setValue(newValue);};
return (
<div className={classes.grow}>
<AppBar position="static">
<AppBar style={{background: '#FFFFFF'}}>
<Toolbar>
<BrandLogo/>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase placeholder="Marque,Modèle..."classes={{ root: classes.inputRoot,input: classes.inputInput,}}
inputProps={{ 'aria-label': 'search' }}/>
<IconButton className={classes.iconButton} aria-label="menu">
<Icon_MicroPhone/>
</IconButton>
</div>
<Icon_Separation style={{ flex: 1 }}/>
<Tabs
value={value}
onChange={handleChange}
variant="fullWidth"
indicatorColor="secondary"
textColor="secondary"
aria-label="icon label tabs example">
<Tab label="LIVE DEALS" {...a11yProps(0)} icon={<Icon_Lightning />}/>
<Tab label="GLOBAL STOCK" {...a11yProps(1)} icon={<Icon_Global/>}/>
<Tab label="TRANSPORT" {...a11yProps(2)} icon={<Icon_Shipment_Boat/>}/>
</Tabs>
<StyledButton
variant="contained"
color="primary"
className={classes.StyledButton}
endIcon={<Icon>power_settings_new&style</Icon>}>
CONNEXION
</StyledButton>
</Toolbar>
</AppBar>
</AppBar>
</div>);}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I have a Search button, and some other button, but only Search button text font size not get reduced, do you have any idea why?
import React from "react";
import event1 from "../assets/images/event1.png";
import event2 from "../assets/images/event2.png";
import event3 from "../assets/images/event3.png";
import event4 from "../assets/images/event4.png";
import scene from "../assets/images/scene.png";
import styles from "../assets/styles/HomePage.module.css";
import { Container, Box, TextField, Button } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
const useStyle = makeStyles({
root: {
backgroundColor: "#f6d7dc",
fontFamily: "ASMBold",
height: "100%"
},
container: {
width: "80%",
paddingTop: "20px"
},
search: {
border: "5px solid #184cdf",
padding: "22px 0",
display: "flex",
justifyContent: "center",
alignItems: "center",
fontSize: "20px",
margin: 0
},
longInput: {
width: "400px"
},
searchButton: {
backgroundColor: "#184cdf",
color: "#ec8562",
textTransform: "uppercase",
fontWeight: "bold",
height: "55px",
width: "100px"
}
});
function HomePage(props) {
const classes = useStyle();
return (
<div className={classes.root}>
<Container maxWidth="xl" className={classes.container} disableGutters>
<Box className={classes.search}>
<TextField variant="outlined" placeholder="city or place" />
<TextField variant="outlined" placeholder="dates" />
<TextField
variant="outlined"
placeholder="artists / venues / events"
className={classes.longInput}
/>
<Button varian="contained" className={classes.searchButton}>
Search
</Button>
</Box>
</Container>
</div>
);
}
export default HomePage;
I used the example in Material-UI for an AppBar and I simply changed it from a function to a class component, after that I looked at how to use withStyles and I did the exact same thing, but no matter what I do, and what kind of changes I make no style is applied.
"react": "^16.8.6",
"#material-ui/core": "^4.1.2",
"#material-ui/icons": "^4.2.1",
import React, {Component} from 'react';
import styleClasses from './SideDrawer.module.css';
import { withStyles } from '#material-ui/styles';
import PropTypes from 'prop-types';
// import UIManager from '../../UIManager/UIManager';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import { fade, makeStyles } from '#material-ui/core/styles';
import IconButton from '#material-ui/core/IconButton';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import Badge from '#material-ui/core/Badge';
import MenuItem from '#material-ui/core/MenuItem';
import Menu from '#material-ui/core/Menu';
import MenuIcon from '#material-ui/icons/Menu';
import SearchIcon from '#material-ui/icons/Search';
import AccountCircle from '#material-ui/icons/AccountCircle';
import MailIcon from '#material-ui/icons/Mail';
import NotificationsIcon from '#material-ui/icons/Notifications';
import MoreIcon from '#material-ui/icons/MoreVert';
const useStyles = makeStyles(theme => ({
grow: {
flexGrow: 1,
zIndex: 1000,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
color: 'red'
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginRight: theme.spacing(2),
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(3),
width: 'auto',
},
},
searchIcon: {
width: theme.spacing(7),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 7),
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('md')]: {
width: 200,
},
}
}));
class SideDrawer extends Component {
render () {
const { classes } = this.props;
console.log('classes', classes)
return (
<div className={styleClasses.grow}>
<AppBar className={'SideDrawer-inputInput-14'}>
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="Open drawer"
>
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
Test
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder="search..."
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ 'aria-label': 'Search' }}
/>
</div>
<div className={classes.grow} />
</Toolbar>
</AppBar>
</div>
)
}
}
SideDrawer.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(useStyles)(SideDrawer);
The console.log('classes', classes) returns :
{grow: "SideDrawer-grow-8", menuButton: "SideDrawer-menuButton-9", title: "SideDrawer-title-10", search: "SideDrawer-search-11", searchIcon: "SideDrawer-searchIcon-12", …}
grow: "SideDrawer-grow-8"
inputInput: "SideDrawer-inputInput-14"
inputRoot: "SideDrawer-inputRoot-13"
menuButton: "SideDrawer-menuButton-9"
search: "SideDrawer-search-11"
searchIcon: "SideDrawer-searchIcon-12"
title: "SideDrawer-title-10"
But none of these styles is applied to the actual items or the AppBar. What am I doing wrong?
You should not be trying to use makeStyles along with withStyles. makeStyles returns a custom hook and passing this custom hook into withStyles will not work correctly.
Instead, you want the following:
const styles = theme => ({
grow: {
flexGrow: 1,
zIndex: 1000,
},
/* and all your other styles ... */
});
// other stuff (e.g. your SideDrawer component) ...
export default withStyles(styles)(SideDrawer);