I am trying to display a large version of my post in the postDetail.jsx file but it shows blank when i Open it on my web browser. the application is being fetched properly as shown on my network tab in developer option and no form of error is printed on the console.
import React, { useEffect } from 'react';
import { Paper, Typography, CircularProgress, Divider } from '#material-ui/core/';
import { useDispatch, useSelector } from 'react-redux';
import moment from 'moment'; //js library for time
import { useParams, useHistory } from 'react-router-dom';
import { getPost } from '../../actions/posts';
import useStyles from './styles'
const PostDetails = () => {
const { post, posts, isLoading } = useSelector((state) => state.posts);
const dispatch = useDispatch();
const history = useHistory();
const classes = useStyles();
const { id } = useParams();
useEffect(() => {
dispatch(getPost(id));
}, [id]);
if(!post) return null;
//if this return this else return jsx
if(isLoading) {
return (
<Paper elevation={6} className={classes.loadingPaper}>
<CircularProgress size="7em" />
</Paper>
);
}
return (
<Paper style={{ padding: '20px', borderRadius: '15px' }} elevation={6}>
<div className= {classes.card}>
<div className={classes.section}>
<Typography variant="h3" component="h2">{post.title}</Typography>
<Typography gutterBottom variant="h6" color="textSecondary" component="h2">{ post.tags }</Typography>
<Typography gutterBottom variant="body 1" component="p"> {post.message} </Typography>
<Typography variant="h6"> Created by:{post.name} </Typography>
<Typography variant="body 1">{moment(post.createdAt).fromNow()}</Typography>
<Divider style={{ margin: "20px 0" }} />
<Typography variant="body1"><strong>Realtime Chat - coming soon !</strong></Typography>
<Divider style={{ margin: '20px 0px'}}/>
<Typography variant="body 1"><strong>Comments - coming soon !</strong></Typography>
<Divider style={{ margin: '20px 0px' }}/>
</div>
<div className={ classes.imageSection }>
<img className={ classes.media } src={post.selectedFile} alt={post.title} />
</div>
</div>
</Paper>
)
}
export default PostDetails;
This is the styles used for the code.. I used Material-Ui
import { makeStyles } from '#material-ui/core/styles';
export default makeStyles((theme) => ({
media: {
borderRadius: '20px',
objectFit: 'cover',
width: '100%',
maxHeight: '600px',
},
card: {
display: 'flex',
width: '100%',
[theme.breakpoints.down('sm')]: {
flexWrap: 'wrap',
flexDirection: 'column',
},
},
section: {
borderRadius: '20px',
margin: '10px',
flex: 1,
},
imageSection: {
marginLeft: '20px',
[theme.breakpoints.down('sm')]: {
marginLeft: 0,
},
},
recommendedPosts: {
display: 'flex',
[theme.breakpoints.down('sm')]: {
flexDirection: 'column',
},
},
loadingPaper: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: '20px',
borderRadius: '15px',
height: '39vh',
},
commentsOuterContainer: {
display: 'flex',
justifyContent: 'space-between',
},
commentsInnerContainer: {
height: '200px',
overflowY: 'auto',
marginRight: '30px',
},
}));
Original image Containing the post before a specific id is clicked
[Image of the postDetails when clicked on the original post which contains the specific id i.e /posts/:1d]
Related
I am creating a Appbar with material UI. When I use a custom hook. to control the child component it also controls the whole parent component...
My purpose is to use this hook to disappear the component whenever a click is made outside of the component
Here is my custom hook
useListener.js
import { useEffect, useState, useRef } from "react";
export const useListener = (active, ref) => {
ref = useRef();
const [open, setOpen] = useState((active = false));
useEffect(() => {
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
setOpen(!open);
return;
}
}
// Bind the event listener
document.body.addEventListener("click", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.body.removeEventListener("click", handleClickOutside);
};
}, [open, ref]);
return [open, ref];
};
when I use it in the component by destructing it with
const [open, ref] = useListener()
and use it inside the component, I set open to appear and disappear the component, with CSS..
display: open ? 'block' : 'none'
Now when I use this component in which this hook is being used, When I click on this component it appears, and when I click outside of the component (any where else in the body) it disappears, which is totally fine...
But the issue is when I click on the parent component in with this component is being used it also makes appear this child component...
Here is my child component...
Profile.js
import React from "react";
import Paper from "#mui/material/Paper";
import Box from "#mui/material/Box";
import cover from "../assets/cover.webp";
import profilepic from "../assets/profilepic.webp";
import Button from "#mui/material/Button";
import Typography from "#mui/material/Typography";
import { LogoutIcon } from "../assets/LogoutIcon";
import { ChangePasswordIcon } from "../assets/ChangePasswordIcon";
import { useListener } from "../../../hooks/useListener";
const logout = () => {
localStorage.removeItem("authorization");
localStorage.removeItem("user");
localStorage.removeItem("permissions");
window.location.reload(false);
};
const Profile = () => {
const [open, profileRef] = useListener();
console.log(profileRef.current);
return (
<Box
ref={profileRef}
sx={{
display: open ? "inline" : "none",
width: "190px",
}}
>
<Paper elevation={2}>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<img src={cover} alt="Cover" style={{ width: "190px" }}></img>
<img
src={profilepic}
alt="Profile"
style={{ height: "62px", width: "62px", borderRadius: "50%" }}
></img>
<Typography variant="button" display="block" gutterBottom>
Username
</Typography>
<Button>
<Box sx={{ display: "flex", flexDirection: "row" }}>
<ChangePasswordIcon sx={{ height: "18px", width: "18px" }} />
<Typography variant="body1" gutterBottom>
Change password
</Typography>
</Box>
</Button>
<Button onClick={logout}>
<Box sx={{ display: "flex", flexDirection: "row" }}>
<LogoutIcon sx={{ width: "16px", height: "16px" }} />
<Typography variant="body1" gutterBottom>
Logout
</Typography>
</Box>
</Button>
</Box>
</Paper>
</Box>
);
};
export default Profile;
And this is the parent component...
TopbarContents.js
import React, { useState } from "react";
import Box from "#mui/material/Box";
import Button from "#mui/material/Button";
import Typography from "#mui/material/Typography";
import profilepic from "../assets/profilepic.webp";
import Profile from "./Profile";
export const TopbarContents = () => {
const [profileActive, toggleProfile] = useState(false);
const openProfile = () => {
toggleProfile(true);
};
return (
<Box sx={{ width: "100%" }}>
<Box
sx={{
width: "100%",
display: "flex",
alignItems: "center",
}}
>
<Box sx={{ flexGrow: 1 }}>
<Typography
sx={{ color: "#494343" }}
variant="h6"
noWrap
component="div"
>
Dashboard
</Typography>
</Box>
<Box
sx={{
height: "45px",
width: "160px",
borderRadius: 2,
display: "flex",
flexDirection: "column",
justifyContent: "center",
border: "1px solid #e0e0e0",
pl: "8px",
}}
>
<Typography sx={{ color: "#2E4299", pt: 1 }} variant="caption">
Case study
</Typography>
<Typography sx={{ color: "#494343" }} variant="overline">
Trial ID: NC48023194
</Typography>
</Box>
<Button
color="guava"
variant="contained"
size="medium"
sx={{ fontFamily: "Poppins", mr: 6, ml: 3 }}
>
Case Study
</Button>
<Button onClick={openProfile}>
<img
src={profilepic}
alt="Profile"
style={{ height: "62px", width: "62px", borderRadius: "50%" }}
></img>
</Button>
</Box>
<Box
sx={{
display: profileActive ? "inline" : "none",
flexDirection: "column",
}}
>
<Profile />
</Box>
</Box>
);
};
Using ReactJS, I am trying to make a second (smaller) navbar the same way Airtable has done on their product page. My first navbar is at the top, and turns dark from transparent once I scroll. The second bar (colored purple in the screenshot to easily see) is currently behind the first navbar when I would like it to sit right underneath the header background image.
First (main) Navbar - "Header.js"
import React, { useEffect, useState } from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { AppBar, IconButton, Toolbar, Collapse } from '#material-ui/core';
import SortIcon from '#material-ui/icons/Sort';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
import { Link as Scroll } from 'react-scroll';
import ScrollToColor from './ColorChangeOnScroll';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
fontFamily: 'Nunito',
},
appbar: {
background: 'none',
},
appbarTitle:{
flexGrow: '1',
},
appbarWrapper:{
width: '80%',
margin: '0 auto',
},
icon: {
color: '#fff',
fontSize: '2rem',
},
colorText: {
color: '#34cbc2',
},
container: {
textAlign: 'center',
},
title: {
color: '#fff',
fontSize: '4rem',
},
goDown: {
color: '#34cbc2',
fontSize: '4rem',
},
}));
export default function Header() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
useEffect(() => {
setChecked(true);
}, []);
return (
<section>
<div className={classes.root} id="header">
<ScrollToColor>
<AppBar className={classes.appbar} elevation={0}>
<Toolbar className={classes.appbarWrapper}>
<h1 className={classes.appbarTitle}>
Logo <span className={classes.colorText}>Colored</span>
</h1>
<IconButton>
<SortIcon className={classes.icon} />
</IconButton>
</Toolbar>
</AppBar>
</ScrollToColor>
<Collapse
in={checked}
{...(checked ? { timeout: 1000 } : {})}
collapsedHeight={50}>
<div className={classes.container}>
<h1 className={classes.title}>
Main header <br />
at <span className={classes.colorText}>title.</span>
</h1>
<Scroll to="info-card" smooth={true}>
<IconButton>
<ExpandMoreIcon className={classes.goDown} />
</IconButton>
</Scroll>
</div>
</Collapse>
</div>
</section>
);
}
Second Navbar - "StickyHeader.js"
import React, { useEffect, useState } from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { AppBar, IconButton, Toolbar, Collapse } from '#material-ui/core';
import SortIcon from '#material-ui/icons/Sort';
const useStyles = makeStyles((theme) => ({
root: {
top: '1000px',
display: 'flex',
position: 'sticky',
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Nunito',
},
appbar: {
background: 'purple',
},
list: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
}));
export default function Header() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
useEffect(() => {
setChecked(true);
}, []);
return (
<section>
<div className={classes.root} style={{ top: "72px" }} id="stickyheader">
<AppBar className={classes.appbar} elevation={4}>
<Toolbar className={classes.appbarWrapper}>
<ul className={classes.list} style={{ listStyleType: "none" }}>
<li>
Database
</li>
</ul>
</Toolbar>
</AppBar>
</div>
</section>
);
}
Landing Page snippet
export default function Landing() {
const classes = useStyles();
return (
<div className={classes.root}>
<CssBaseline />
<Header />
<StickyHeader />
<InfoCards />
</div>
);
}
Tried adjusting:
Separating each component into their own files to act as 'sections,' so one would sit on top of the other
Adjusting margin, marginTop in useStyles with position: relative
Same as above with position: sticky
Added style={{ top: "##px" }} to the navbar's div to see if that pushed it downwards
Images
2nd navbar behind 1st at top
2nd navbar behind 1st, scrolled
Photoshopped view of the desired outcome (where 2nd navbar is sticky and 'joins' the 1st navbar when scrolled past)
I'm not sure if I am missing something simple in the styling for these navbars, or if this needs something more complex. Any advice is appreciated in advance.
Note
The logo and header titles are a part of the first navbar. The second (purple) navbar has a very small 'Database' clickable text that is difficult to see in the first couple screenshots, right on top of 'Logo colored.'
Update
Resulting screenshot from MB_'s answer
EDIT
This is the only solution I have found...
PS:
1/ Use position: "fixed" instead of position: "sticky"
2/ There are other modifications to do... (add scroll listener,...)
Header.js
import React, { useEffect, useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import { AppBar, IconButton, Toolbar, Collapse } from "#material-ui/core";
import SortIcon from "#material-ui/icons/Sort";
import ExpandMoreIcon from "#material-ui/icons/ExpandMore";
import { Link as Scroll } from "react-scroll";
const useStyles = makeStyles(theme => ({
root: {
fontFamily: "Nunito"
},
appbar: {
position: "fixed",
zIndex: "9999",
background: "black"
},
appbarTitle: {
flexGrow: "1"
},
appbarWrapper: {
width: "80%",
margin: "0 auto"
},
icon: {
color: "#fff",
fontSize: "2rem"
},
colorText: {
color: "#34cbc2"
},
container: {
textAlign: "center",
height: "100vh",
marginTop: "80px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
title: {
color: "#333",
fontSize: "4rem"
},
goDown: {
color: "#34cbc2",
fontSize: "4rem"
}
}));
export default function Header() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
useEffect(() => {
setChecked(true);
}, []);
return (
<div className={classes.root} id="header">
<AppBar className={classes.appbar} elevation={0}>
<Toolbar className={classes.appbarWrapper}>
<h1 className={classes.appbarTitle}>
Logo <span className={classes.colorText}>Colored</span>
</h1>
<IconButton>
<SortIcon className={classes.icon} />
</IconButton>
</Toolbar>
</AppBar>
<Collapse
in={checked}
{...(checked ? { timeout: 1000 } : {})}
collapsedHeight={50}
>
<div id="mainheader" className={classes.container}>
<h1 className={classes.title}>
Main header <br />
at <span className={classes.colorText}>title.</span>
</h1>
<Scroll to="info-card" smooth={true}>
<IconButton>
<ExpandMoreIcon className={classes.goDown} />
</IconButton>
</Scroll>
</div>
</Collapse>
</div>
);
}
StickyHeader.js
import React, { useEffect, useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import { AppBar, IconButton, Toolbar, Collapse } from "#material-ui/core";
const useStyles = makeStyles(theme => ({
root: {
fontFamily: "Nunito"
},
appbar: {
background: "purple"
},
list: {
display: "flex",
justifyContent: "center",
alignItems: "center"
}
}));
export default function StickyHeader() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
const [scrollY, setScrollY] = useState({ position: "relative" });
useEffect(() => {
window.addEventListener("scroll", () => {
const heightVh = document.querySelector("#mainheader").offsetHeight / 100;
if (window.scrollY > heightVh * 100) {
setScrollY({ position: "fixed", top: "80px" });
} else {
setScrollY({ position: "relative" });
}
});
return () => {
window.removeEventListener("scroll");
};
}, [scroll]);
useEffect(() => {
setChecked(true);
}, []);
return (
<>
{console.log(scrollY)}
<div className={classes.root} id="stickyheader">
<AppBar className={classes.appbar} style={scrollY} elevation={4}>
<Toolbar className={classes.appbarWrapper}>
<ul className={classes.list} style={{ listStyleType: "none" }}>
<li>
<a href="#product" data-id="product" data-is-active="true">
Database
</a>
</li>
</ul>
</Toolbar>
</AppBar>
</div>
</>
);
}
Demo : stackblitz
I have a toolbar where I am using 2 icons that appear on the left end. Currently, I am using this styling method:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
},
appBar: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
panelheaderRight: {
marginRight: 0,
right: 0,
},
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
// justifyContent: spaceBetween,
backgroundColor: theme.palette.background.default,
padding: theme.spacing(3),
},
}),
);
I want the icons to appear on the right end. If I add a separate css file with this, it works:
.toolbar-class{
justify-content:space-between;
}
but I want to use it inside the createStyles. There's no 'space-between' option in createStyles. This is how a portion of my component looks like:
<AppBar position="fixed" className={classes.appBar}>
<Toolbar className="toolbar-class">
<Typography variant="h6" noWrap>
Al
</Typography>
<div className="panelheaderRight">
<NotificationsIcon />
{/* <ExitToAppIcon onClick={() =>
<ExitToAppIcon onClick={logout}></ExitToAppIcon>
</div>
</Toolbar>
</AppBar>
Is there any way I can move the icons to the left using createStylesand without adding a separate css file?
Some notice points:
Change justify-content to justifyContent, and value as string.
No need to use createStyels for makeStyles
const useStyles = makeStyles((theme: Theme) => ({
toolBar: {
justifyContent: 'space-between'
},
...
...
<Toolbar className={classes.toolBar}>
I am trying to pass my API value to the Flippy card to dynamically render image and the word displayed on flip.
I am struggling with something I thought would be easy: I have an API where I call back an image link and a word to populate the flip cards. I want to dynamically render my flip cards to the page using that data, but right now my image link and the word are hard coded and I don't know to pass my API call values to the component. API works and correctly returns links and words; hard coded flip card also works with no issues and functions as intended. I believe I have to implement props and pass it somehow to the const DefaultCardContents- thanks so much for taking a stab at it.
I tried implemeneting props but I am unsure how to pass them to the constant
THIS IS MY FLASHCARD COMPONENT
import React, { Component } from 'react';
import Flippy, { FrontSide, BackSide } from './../lib';
import Button from 'react-bootstrap/Button';
import './style.css';
const FlippyStyle = {
width: '200px',
height: '200px',
textAlign: 'center',
color: '#FFF',
fontFamily: 'sans-serif',
fontSize: '30px',
justifyContent: 'center'
}
const DefaultCardContents = ({ children }) => (
<React.Fragment>
<FrontSide
style={{
backgroundColor: 'white',
display: 'flex',
alignItems: 'center',
flexDirection: 'column'
}}
>
<img
src="https://parent.guide/wp-content/uploads/2014/08/Banana-baby-food-recipes.jpg"
style={{ maxWidth: '100%', maxHeight: '100%' }}
/>
<span
style={{
fontSize: '12px',
position: 'absolute',
bottom: '10px',
width: '100%'
}}>
{children}<br />
Hover over to show key word
</span>
</FrontSide>
<BackSide
style={{
backgroundColor: '#EB6864',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column'
}}>
<h1>Banana</h1>
<span
style={{
fontSize: '12px',
position: 'absolute',
bottom: '10px',
width: '100%'
}}>
{children}<br />
<Button variant="success">Success</Button>
<Button variant="outline-warning">Warning</Button>
</span>
</BackSide>
</React.Fragment>);
const FlippyOnHover = ({ flipDirection = 'vertical' }) => (
<Flippy
flipOnHover={true}
flipDirection={flipDirection}
style={FlippyStyle}
>
<DefaultCardContents>
</DefaultCardContents>
</Flippy>
);
class Flashcard extends Component {
constructor(props) {
super(props);
this.state = {
isFlipped: false
}
}
render() {
return (
<div className="App">
<div style={{ display: 'flex', flex: '1 0 200px', justifyContent: 'space-around', 'flex-wrap': 'wrap' }}>
<FlippyOnHover flipDirection="horizontal" />
</div>
</div>
);
}
}
export default Flashcard;
THIS IS MY API CALL AND PAGE RENDER
import React, { Component } from "react";
import Flashcard from "../components/Flashcard";
import API from "../utils/API";
class Flashcards extends Component {
state = {
flashcards: [],
flashcardName: "",
flashcardImage: "",
flipped: false
};
componentDidMount() {
this.loadFlashcards();
};
loadFlashcards = () => {
API.getFlashcards()
.then(res => {
// console.log(res.data);
this.setState({ flashcards: res.data, flashcardName: "", flashcardImage: "" })
// console.log("flashhhhhhhhhh" + JSON.stringify(this.state.flashcards));
})
.catch(err => console.log(err));
};
flipped = () => {
console.log(this.state)
if (this.state.flipped === false) {
this.setState({ flipped: true })
}
}
render() {
return (
<div>
{this.state.flashcards.length ? (
<div>
{this.state.flashcards.map(flashcards => (
<div key={flashcards._id} >
<Flashcard/>
</div>
))}
</div>
) : (
<h3>No Results to Display</h3>
)}
</div>
)
}
}
export default Flashcards;
Expected result is a dynamically generated array of cards base don API
You need to modify your Flashcard component to accept props for the title and the URL for the image, assuming that is in the data returned from the API.
In your map, pass the values to the Flashcard, something like:
{this.state.flashcards.map(flashcard => (
<div key={flashcard._id}>
<Flashcard
title={flashcard.title}
imageUrl={flashcard.image}
/>
</div>
))}
Edit:
Looks like your are using the react-flippy library, so you don't need to manage what state the flash card is in.
Crudly, your FlashCard component could look something like:
import React, { Component } from "react";
import Flippy, { FrontSide, BackSide } from "./../lib";
import Button from "react-bootstrap/Button";
import "./style.css";
const FlippyStyle = {
width: "200px",
height: "200px",
textAlign: "center",
color: "#FFF",
fontFamily: "sans-serif",
fontSize: "30px",
justifyContent: "center"
};
const CardContents = ({ title, imageUrl }) => (
<React.Fragment>
<FrontSide
style={{
backgroundColor: "white",
display: "flex",
alignItems: "center",
flexDirection: "column"
}}
>
<img
src={imageUrl}
style={{ maxWidth: "100%", maxHeight: "100%" }}
/>
<span
style={{
fontSize: "12px",
position: "absolute",
bottom: "10px",
width: "100%"
}}
>
<br />
Hover over to show key word
</span>
</FrontSide>
<BackSide
style={{
backgroundColor: "#EB6864",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column"
}}
>
<h1>{title}</h1>
<span
style={{
fontSize: "12px",
position: "absolute",
bottom: "10px",
width: "100%"
}}
>
<br />
<Button variant="success">Success</Button>
<Button variant="outline-warning">Warning</Button>
</span>
</BackSide>
</React.Fragment>
);
class Flashcard extends Component {
render() {
return (
<div>
<div
style={{
display: "flex",
flex: "1 0 200px",
justifyContent: "space-around",
"flex-wrap": "wrap"
}}
>
<Flippy flipOnHover={true} flipDirection='horizontal' style={FlippyStyle}>
<CardContents imageUrl={this.props.imageUrl} title={this.props.title}/>
</Flippy>
</div>
</div>
);
}
}
export default Flashcard;
I'll show you exactly what I mean here. (it's a short video demonstrating exactly how this problem is reproduced and the missing css elements)
I also have screenshots of before:
and after:
Via inspect element it's clear that important css elements just straight up disappear, and it doesn't make any sense why that would happen specifically after clicking on a link, coming back, and refreshing.
Has anyone run into a similar problem with material-ui before or think you might know why the css is breaking?
EDIT: console is logging errors only when the search bar is in the wacky position as such:
unfortunately, I'm still not quite sure what to make of it.
I'll also include my appbar component which uses #material-ui/core/styles' makeStyles CSS rendering. If you want the entire repository to play around with I can make it available as well.
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import IconButton from '#material-ui/core/IconButton';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import { fade } from '#material-ui/core/styles/colorManipulator';
import { makeStyles } from '#material-ui/core/styles';
import MenuIcon from '#material-ui/icons/Menu';
import SearchIcon from '#material-ui/icons/Search';
import {connectSearchBox} from 'react-instantsearch-dom';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
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(1),
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('sm')]: {
width: 300,
'&:focus': {
width: 400,
},
},
}
}));
function SearchBox({currentRefinement, refine}){
const classes = useStyles();
return(
<InputBase
type="search"
value={currentRefinement}
onChange={event => refine(event.currentTarget.value)}
placeholder="Search by state, park name, keywords..."
classes = {{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
)
}
const CustomSearchBox = connectSearchBox(SearchBox);
function SearchAppBar() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="static" color="primary">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="Open drawer"
>
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
Title
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<CustomSearchBox/>
</div>
</Toolbar>
</AppBar>
</div>
);
}
export default SearchAppBar;