I'm new to Material-ui and react. What I'm trying to do is have my drawer stay in a persistent open state when the user clicks the hamburger menu on the AppBar. I want my main content 'pushed' to the right when the drawer opens, not the drawer laying on top of it. I'm stuck and don't know how to get this to work. Here's my code thus far. Thanks in advance for any tips or tricks! :)
Application.js
import React, {Component, PropTypes} from 'react'
import {connect} from 'react-redux'
import {ClassificationBanner} from './ClassificationBanner'
import TitleBar from './TitleBar'
import styles from './Application.css'
import injectTapEventPlugin from 'react-tap-event-plugin'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
injectTapEventPlugin();
class Application extends Component {
render() {
return (
<MuiThemeProvider>
<div className={styles.root}>
<ClassificationBanner />
<TitleBar />
{this.props.children}
</div>
</MuiThemeProvider>
)
}
}
Application.propTypes = {
children: PropTypes.object.isRequired,
bbox: React.PropTypes.arrayOf(React.PropTypes.number),
};
export default Application
TitleBar.js
import React, {Component} from 'react'
import logo from '../../images/logo.1.png'
import AppBar from 'material-ui/AppBar'
import Drawer from 'material-ui/Drawer'
import Subheader from 'material-ui/Subheader'
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import MenuItem from 'material-ui/MenuItem'
import { Link, IndexLink } from 'react-router';
import css from './TitleBar.css'
class TitleBar extends Component {
constructor(props){
super(props);
this.state = {drawerOpen:false};
}
getChildContext() {
return {muiTheme: getMuiTheme(baseTheme)};
}
handleToggle() {
this.setState({drawerOpen: !this.state.drawerOpen});
}
handleClose() { this.setState({drawerOpen: false}); }
render() {
const styles = {
appBar: {
backgroundColor: 'black',
height: '70px',
top: '25px'
},
img: {
position: 'absolute',
left: '50%',
marginLeft: '-127px',
marginTop: '10px',
height: '50px'
},
drawer: {
width: '200px',
marginTop: '95px',
backgroundColor: '#010101',
marginLeft: '0px',
padding: '0px'
},
mainMenu: {
color: '#3e3f3f',
display: 'inline-block',
marginRight: '40px',
fontSize: '20px',
align: 'left',
},
};
const img = <img style={styles.img} src={logo}/>
return (
<header className="header">
<AppBar style={styles.appBar} title={img} onLeftIconButtonTouchTap={this.handleToggle.bind(this)} />
<Drawer containerStyle={styles.drawer}
overlayStyle={styles.drawer}
docked={false}
open={this.state.drawerOpen}
onRequestChange={(open) => this.setState({open})}>
<Subheader inset={false}><span style={{width:'100%'}}><div style={styles.mainMenu}>MAIN MENU</div><div style={{display:'inline-block'}}><i className="fa fa-long-arrow-left fa-lg" style={{color: '#4498c0'}} onTouchTap={this.handleClose.bind(this)} aria-hidden="true"></i></div></span></Subheader>
<MenuItem className={css.menuItem} onTouchTap={this.handleClose.bind(this)}><IndexLink className={css.link} activeClassName={css.active} onlyActiveOnIndex={true} to="/exports"><i className="fa fa-book" aria-hidden="true"></i> DataPack Library</IndexLink></MenuItem>
<MenuItem className={css.menuItem} onTouchTap={this.handleClose.bind(this)}><Link className={css.link} activeClassName={css.active} to="/create" ><i className="fa fa-plus-square" aria-hidden="true"></i> Create Datapack</Link></MenuItem>
<MenuItem className={css.menuItem} onTouchTap={this.handleClose.bind(this)}><Link className={css.link} activeClassName={css.active} to="/about" ><i className="fa fa-info-circle" aria-hidden="true"></i> About EventKit</Link></MenuItem>
<MenuItem className={css.menuItem} onTouchTap={this.handleClose.bind(this)}><Link className={css.link} activeClassName={css.active} to="/account" ><i className="fa fa-user" aria-hidden="true"></i> Account Settings</Link></MenuItem>
<MenuItem className={css.menuItem} onTouchTap={this.handleClose.bind(this)}><Link className={css.link} activeClassName={css.active} to="/logout" ><i className="fa fa-sign-out" aria-hidden="true"></i> Log Out</Link></MenuItem>
</Drawer>
</header>
)
}
}
TitleBar.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
export default TitleBar
TitleBar.css
.menuItem > div > div{
margin-left: 0px !important;
padding: 0px !important;
}
.img {
width: 205px;
height: 40px;
}
/* =========================================================================
Link
========================================================================= */
.link {
position: relative;
display: block;
padding: 5px;
text-align: left;
text-decoration: none;
color: #4498c0;
}
.link:visited {
text-decoration:none;
}
.atHome .link {
line-height: 150px;
}
.link:hover {
background-color: #161e2e;
text-decoration: none;
}
.link:active {
text-decoration: none;
}
a:link {
text-decoration: none;
}
/* Link: State
========================================================================= */
.active,
.active:hover {
box-shadow: 0 2px rgba(0,0,0,.1);
background-color: #161e2e;
text-decoration: none;
}
.active:visited {
text-decoration: none;
}
.active .icon {
fill: #1675aa;
filter: none;
-webkit-filter: none;
box-shadow: 0 2px rgba(0,0,0,.1);
text-decoration: none;
}
Application.css
.root {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.body {
font-family: 'Roboto', sans-serif;
}
Related
I am new to React and am trying to create a mobile menu that I somehow created using several online resources. Now the problem is that my mobile menu is not closing after clicking on the Anchor links.
I have three different files (Burger, Navbar, and RightNav). Burger is just for icon transformation, Navbar is for main navigation, and RightNav is the mobile menu.
Can someone please specify how I can close the RightNav after clicking on any menu anchor link?
Burger.jsx file
import React, { useState } from 'react';
import styled from 'styled-components';
import RightNav from './RightNav';
const StyledBurger = styled.div`
width: 2rem;
height: 2rem;
position: fixed;
align-items:center;
right: 20px;
z-index: 20;
display: none;
top: 5%;
#media (max-width: 1000px) {
display: flex;
justify-content: space-around;
flex-flow: column nowrap;
align-items:flex-start;
}
div {
width: 2rem;
height: 0.25rem;
background-color: ${({ open }) => open ? '#00a993' : '#00a993'};
border-radius: 10px;
transform-origin: 1px;
transition: all 0.3s linear;
&:nth-child(1) {
transform: ${({ open }) => open ? 'rotate(45deg)' : 'rotate(0)' };
}
&:nth-child(2) {
transform: ${({ open }) => open ? 'translateX(100%)' : 'translateX(0)'};
opacity: ${({ open }) => open ? 0 : 1};
}
&:nth-child(3) {
transform: ${({ open }) => open ? 'rotate(-45deg)' : 'rotate(0)'};
width: ${({ open }) => open ? '20px':'16px'};
}
}
`;
const Burger = () => {
const [open, setOpen] = useState(false)
return (
<>
<StyledBurger open={open} onClick={() => setOpen(!open)} id="burger" className='burger'>
<div />
<div />
<div />
</StyledBurger>
<RightNav open={open}/>
</>
)
}
export default Burger
RightNav.jsx file
import React from 'react';
import styled from 'styled-components';
import { NavHashLink } from 'react-router-hash-link';
const Ul = styled.ul`
list-style: none;
display: flex;
flex-flow: row nowrap;
li {
padding: 18px 10px;
}
#media (max-width: 1000px) {
z-index: 1;
flex-flow: column nowrap;
background-color: #13161B;
position: fixed;
transform: ${({ open }) => open ? 'translateX(0)' : 'translateX(100%)'};
top: 10%;
right: 0;
width: 100%;
height:auto;
padding: 1.5rem;
align-items: center;
transition: transform 0.3s ease-in-out;
font-size: 16px;
font-family: 'Quicksand', sans-serif;
text-transform: uppercase;
font-weight: 600;
line-height: 7rem;
}
`;
const RightNav = ({ open, setOpen }) => {
return (
<Ul open={open} className="mobile-menu" id="mobile-menu">
<NavHashLink smooth to="/#welcome-section" activeClassName="selected" style={{ color: '#00a993' }}>
What
</NavHashLink>
<NavHashLink smooth to="/#how-section" activeClassName="selected" style={{ color: '#00a993' }}>
How
</NavHashLink>
<NavHashLink smooth to="/#IsItAThing-section" activeClassName="selected" style={{ color: '#00a993' }}>
Why
</NavHashLink>
<NavHashLink smooth to="/#team-section" activeClassName="selected" style={{ color: '#00a993' }}>
Who
</NavHashLink>
<NavHashLink smooth to="/#contact-section" activeClassName="selected" style={{ color: '#00a993' }}>
Where
</NavHashLink>
<a href='https://stories.therelevancehouse.com/' style={{ color: '#00a993' }}>
Stories
</a>
</Ul>
)
}
export default RightNav
Navbar.jsx file
import styled from 'styled-components';
import Burger from './Burger';
import React, { useEffect, useState } from 'react';
import '../App.css';
import logo from '../images/logomain.png'
import ln from '../images/LinkedIN_white.svg'
import medium from '../images/Medium_white.svg'
import twitter from '../images/Twitter_white.svg'
import fb from '../images/Facebook_white.svg'
import instagram from '../images/Instagram_white.svg'
import '../fonts/norwester.ttf'
import linkedinhover from '../images/LinkedinIconHover.svg'
import facebookhover from '../images/FacebookIconHover.svg'
import twitterhover from '../images/TwitterIconHover.svg'
import instagramhover from '../images/InstagramIconHover.svg'
import mediumhover from '../images/MediumIconHover.svg'
import { NavHashLink } from 'react-router-hash-link'
const Nav = styled.nav`
width: 100%;
border-bottom: 2px solid #f1f1f1;
padding: 20px 20px;
display: flex;
justify-content: space-between;
align-items: center;
.logo {
padding: 15px 0;
}
`
const Navbar = () => {
const [show, setShow] = useState(true);
const [lastScrollY, setLastScrollY] = useState(0);
useEffect(() => {
const controlNavbar = () => {
if (typeof window !== 'undefined') {
if ((window.scrollY > lastScrollY) && (window.scrollY > 200) && (window.innerWidth > 1000))
{
// document.getElementById("navbar").style.padding = "30px 10px";
document.getElementById("navtext").style.fontSize = "12px";
document.getElementById("navtext1").style.fontSize = "12px";
document.getElementById("navtext2").style.fontSize = "12px";
document.getElementById("navtext3").style.fontSize = "12px";
document.getElementById("navtext4").style.fontSize = "12px";
document.getElementById("navtext5").style.fontSize = "12px";
document.getElementById("nav-bar-logo1").style.height = "80px";
document.getElementById("nav").style.height = "90px";
// setShow(false);
} else {
setShow(true);
document.getElementById("navtext").style.fontSize = "14px";
document.getElementById("navtext1").style.fontSize = "14px";
document.getElementById("navtext2").style.fontSize = "14px";
document.getElementById("navtext3").style.fontSize = "14px";
document.getElementById("navtext4").style.fontSize = "14px";
document.getElementById("navtext5").style.fontSize = "14px";
document.getElementById("nav-bar-logo1").style.height = "105px";
document.getElementById("nav").style.height = "120px";
}
setLastScrollY(window.scrollY);
}
};
if (typeof window !== 'undefined') {
window.addEventListener('scroll', controlNavbar);
return () => {
window.removeEventListener('scroll', controlNavbar);
};
}
}, [lastScrollY]);
return (
<Nav >
<nav id='nav' className={ `${show && 'nav'}`} >
<a href="./" >
<img id='nav-bar-logo1' className='nav-bar-logo' alt="Marketing, Branding and Communications Agency"
src={logo} />
</a>
<div id='navigation-social'>
<a href='/'>
<img className='social-nav' src={ln} alt='linkedin' onMouseOver={e => e.currentTarget.src = linkedinhover} onMouseOut={e => e.currentTarget.src = ln} />
</a>
<a href='/'>
<img className='social-nav' src={medium} alt='medium' onMouseOver={e => e.currentTarget.src = mediumhover} onMouseOut={e => e.currentTarget.src = medium} />
</a>
<a href='/'>
<img className='social-nav' src={twitter} alt='twitter' onMouseOver={e => e.currentTarget.src = twitterhover} onMouseOut={e => e.currentTarget.src = twitter} />
</a>
<a href='/'>
<img className='social-nav' src={fb} alt='facebook' onMouseOver={e => e.currentTarget.src = facebookhover} onMouseOut={e => e.currentTarget.src = fb} />
</a>
<a href='/'>
<img className='social-nav' src={instagram} alt='instagram' onMouseOver={e => e.currentTarget.src = instagramhover} onMouseOut={e => e.currentTarget.src = instagram} />
</a>
</div>
<div id='navigation-items'>
<NavHashLink id="navtext" smooth to="/#welcome-section" activeClassName="selected" activeStyle={{ color: '#00a993' }}>
What
</NavHashLink>
<NavHashLink id="navtext1" smooth to="/#how-section" activeClassName="selected" activeStyle={{ color: '#00a993' }}>
How
</NavHashLink>
<NavHashLink id="navtext2" smooth to="/#IsItAThing-section" activeClassName="selected" activeStyle={{ color: '#00a993' }}>
Why
</NavHashLink>
<NavHashLink id="navtext3" smooth to="/#team-section" activeClassName="selected" activeStyle={{ color: '#00a993' }}>
Who
</NavHashLink>
<NavHashLink id="navtext4" smooth to="/#contact-section" activeClassName="selected" activeStyle={{ color: '#00a993' }}>
Where
</NavHashLink>
<a id="navtext5" href='https://stories.therelevancehouse.com/'>
Stories
</a>
</div>
</nav>
<Burger />
</Nav>
)
}
export default Navbar
I'm using the slider swiper in a project developed in Next.JS and I'm using Sass to do the styling. But when I'm going to use the swiper classes, as mandated by the documentation, to style the arrows, it doesn't work.
I need the arrows to be outside the component, not overlapping.
CSS
.swiper-button-next,
.swiper-button-prev {
background: red;
position: absolute;
top: 50%;
width: calc(var(--swiper-navigation-size) / 44 * 27);
height: var(--swiper-navigation-size);
margin-top: calc(0px - (var(--swiper-navigation-size) / 2));
z-index: 10;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--swiper-navigation-color, var(--swiper-theme-color));
}
.swiper-button-next.swiper-button-disabled,
.swiper-button-prev.swiper-button-disabled {
opacity: 0.35;
cursor: auto;
pointer-events: none;
}
.swiper-button-next:after,
.swiper-button-prev:after {
background: red;
font-family: swiper-icons;
font-size: var(--swiper-navigation-size);
text-transform: none !important;
letter-spacing: 0;
text-transform: none;
font-variant: initial;
line-height: 1;
}
.swiper-button-prev,
.swiper-container-rtl .swiper-button-next {
left: 10px;
right: auto;
}
.swiper-button-prev:after,
.swiper-container-rtl .swiper-button-next:after {
content: "prev";
color: #000;
}
.swiper-button-next,
.swiper-container-rtl .swiper-button-prev {
right: 10px;
left: auto;
}
.swiper-button-next:after,
.swiper-container-rtl .swiper-button-prev:after {
content: "next";
}
.swiper-button-next.swiper-button-white,
.swiper-button-prev.swiper-button-white {
--swiper-navigation-color: #ffffff;
}
.swiper-button-next.swiper-button-black,
.swiper-button-prev.swiper-button-black {
--swiper-navigation-color: #000000;
}
.swiper-button-lock {
display: none;
}
I've tried changing the styles, but nothing reflects on the component. If I change styles by browser it works normally.
Changing the basic arrows styles is pretty simple - take a look at the following codesandbox: https://codesandbox.io/s/stoic-shaw-q35wq?file=/src/styles.scss
.swiper-button-prev, .swiper-button-next {
top: 45%;
width: 40px;
height: 40px;
background: #fff;
border: 1px solid gray;
border-radius: 50%;
color: blue;
font-weight: 700;
outline: 0;
transition: background-color .2s ease, color .2s ease;
&::after {
font-size: 16px;
}
}
.swiper-button-prev {
&:after {
position: relative;
left: -1px;
}
}
.swiper-button-next {
&:after {
position: relative;
left: 1px;
}
}
.swiper-button-prev, .swiper-container-rtl .swiper-button-next {
left: 10px;
right: auto;
}
.swiper-button-next, .swiper-container-rtl .swiper-button-prev {
right: 10px;
left: auto;
}
.swiper-button-prev.swiper-button-disabled, .swiper-button-next.swiper-button-disabled {
opacity: 0;
cursor: auto;
pointer-events: none;
}
Moving the arrows outside, however, is a bit more tricky. In the example above I've used a little CSS tricks (negative margin and corresponding padding) and some overflows to get it working but it might not be enough for your use case.
You would have to create your own next/previous elements:
import React from "react";
import { Navigation, Pagination, Scrollbar, A11y, Controller } from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";
// Import Swiper styles
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "swiper/css/scrollbar";
import "./styles.scss";
const image = "https://source.unsplash.com/featured/300x201";
export default function App() {
const images = new Array(6).fill({ url: image });
const [swiper, setSwiper] = React.useState();
const prevRef = React.useRef();
const nextRef = React.useRef();
React.useEffect(() => {
if (swiper) {
console.log("Swiper instance:", swiper);
swiper.params.navigation.prevEl = prevRef.current;
swiper.params.navigation.nextEl = nextRef.current;
swiper.navigation.init();
swiper.navigation.update();
}
}, [swiper]);
return (
<div className="App">
<div className="carousel-container">
<div className="swiper-button" ref={prevRef}>
prev
</div>
<Swiper
modules={[Navigation, Pagination, Scrollbar, A11y, Controller]}
className="external-buttons"
spaceBetween={24}
slidesPerView={1}
navigation={{
prevEl: prevRef?.current,
nextEl: nextRef?.current
}}
updateOnWindowResize
observer
observeParents
initialSlide={2}
onSwiper={setSwiper}
>
{images.map((image, index) => (
<SwiperSlide key={index}>
<img
height="200"
width="300"
alt="img"
className="image"
src={image.url}
/>
</SwiperSlide>
))}
</Swiper>
<div className="swiper-button" ref={nextRef}>
next
</div>
</div>
</div>
);
}
Complete example - https://codesandbox.io/s/prod-darkness-o483y?file=/src/App.js
Important - the examples are using Swiper v7
Here is the best way to add custom arrows:
import React, { useRef } from "react";
// For Typescript
// import SwiperCore from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
const SliderComponent = () => {
const swiperRef = useRef();
// For Typescript!
// const swiperRef = useRef<SwiperCore>();
const sliderSettings = {
440: {
slidesPerView: 1,
spaceBetween: 30,
},
680: {
slidesPerView: 2,
spaceBetween: 30,
},
1024: {
slidesPerView: 3,
spaceBetween: 30,
},
};
return (
<div>
<button onClick={() => swiperRef.current?.slidePrev()}>Prev</button>
<Swiper
slidesPerView={3}
breakpoints={sliderSettings}
onBeforeInit={(swiper) => {
swiperRef.current = swiper;
}}
>
<SwiperSlide>
Slide 1
</SwiperSlide>
<SwiperSlide>
Slide 2
</SwiperSlide>
<SwiperSlide>
Slide 3
</SwiperSlide>
<SwiperSlide>
Slide 4
</SwiperSlide>
<SwiperSlide>
Slide 5
</SwiperSlide>
</Swiper>
<button onClick={() => swiperRef.current?.slideNext()}>Next</button>
</div>
);
};
export default SliderComponent;
hamza liaqat's answer is correct, but for typescript you need to add
import { Swiper as SwiperCore } from 'swiper/types';
I created a multi-items carousel and it's fetching all images from the database but only displaying 3 images. I need this carousel to display all images from the database when one click on side arrows. How can I make it work as "https://react-multi-carousel.now.sh/" this carousel? Can you help me with my custom carousel?
.home__wrapper {
.categoryslider__wrapper {
display: flex;
width: 100%;
margin-top: 15px;
visibility: visible;
opacity: 1;
transition: visibility 0s, opacity 0.05s, height 0.05s linear;
height: auto;
.category {
position: relative;
height: 14vh;
margin-bottom: 1em;
cursor: pointer;
& >img {
height: 100%;
width: 100%;
object-fit: cover;
}
p {
position: absolute;
top: 0.2em;
left: 1em;
color: rgb(255, 255, 255);
font-size: 2vh;
font-weight: 900;
letter-spacing: 0.5px;
line-height: 24px;
width: 80%;
text-align: left;
}
}
}
}
import React from 'react'
import {withRouter} from 'react-router'
import './index.scss'
import {times} from 'lodash'
import Carousel from 'react-bootstrap/Carousel'
import {Col} from 'react-bootstrap';
import {API} from '../../../constants';
class CategorySlider extends React.Component {
render() {
let {stores} = this.props;
return (
<>
<Carousel className='categoryslider__wrapper'>
{times(4, (index) => {
return (
<Carousel.Item key={index}>
{stores && stores.length && stores.map(store => {
if (store.featured_products.length){
return store.featured_products[0].image_url;
}
return stores[0].name;
}).filter(image=>image!==undefined).map((image_link, i )=> {
return (
<Col key={image_link + "" + i} className="col-4 category" >
<img src={API.files.detail.replace('/files/:fileUUID/', image_link)} alt=""></img>
<p>{stores[i].name}</p>
</Col>
)
})}
</Carousel.Item >
)
})}
</Carousel>
</>
);
}
}
export default withRouter(CategorySlider);
I am using react-bootstrap 1.0.0-beta.3, which is build for supporting bootstrap 4 update.
Before this I was using react-bootstrap 0.32.1 and created Accordion using Panels and Panel group.
But after bootstrap upgrade it was suggested to Card component. I tried to achieve the same behavior like this:
<CardGroup>
<Card eventKey={this.state.eventKey} className="border-0">
<Card.Header>
<div className="row">
<div className="col-xs-9 col-sm-9 col-md-9 col-lg-9">
<Card.Title>
This is test
</Card.Title>
</div>
<div className="col-xs-3 col-sm-3 col-md-3 col-lg-3">
Test Text 123
</div>
</div>
</Card.Header>
<Card.Body>
Test Text 456
</Card.Body>
</Card>
</CardGroup>
I am facing couple of issues here:
How to make one card to take the full width.
How to make this structure behave like accordion.
Something like this:
You'll need to create custom components and css classNames.
Working example: https://codesandbox.io/s/8zkrw9jw50
components/Accordian.js
import React from "react";
import Card from "../../components/Card";
const panels = [
"Add Edit Menus",
"Resource Management",
"Asset Management",
"User Management",
"Account Management"
];
export default () => (
<div className="app-container">
<div className="accordion-container">
{panels.map(title => (
<Card key={title} title={title} />
))}
</div>
</div>
);
components/Card.js
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Row, Col, Card } from "react-bootstrap";
import Collapse from "../Collapse";
import Button from "../Button";
const { Body, Header, Title } = Card;
class CardComponent extends Component {
state = { isActive: false };
toggleVisibility = () =>
this.setState(prevState => ({ isActive: !this.state.isActive }));
render = () => (
<div className={`${this.state.isActive ? "active" : "inactive"}`}>
<Card>
<Header style={{ padding: 0 }}>
<Row>
<Col xs={9}>
<Button onClick={this.toggleVisibility}>
{!this.state.isActive ? "+" : "-"}
</Button>
<Title style={{ display: "inline-block" }}>
{this.props.title}
</Title>
</Col>
<Col style={{ paddingTop: 7 }} xs={3}>
Test Text 123
</Col>
</Row>
</Header>
<Collapse>
<Body style={{ padding: 10 }}>Test Text 456</Body>
</Collapse>
</Card>
</div>
);
}
export default CardComponent;
CardComponent.propTypes = {
title: PropTypes.string.isRequired
};
components/Button.js
import styled from "styled-components";
const StyledButton = styled.button`
color: #909090;
background-color: transparent;
font-weight: bold;
outline: none;
border: 0;
cursor: pointer;
font-size: 22px;
transition: all 0.3s ease-in-out;
margin: 0 15px;
width: 25px;
&:hover {
color: #333333;
}
&:focus {
outline: none;
}
`;
export default StyledButton;
components/Collapse.js
import React from "react";
import PropTypes from "prop-types";
const Collapse = ({ children }) => (
<span className="folding-pannel">{children}</span>
);
export default Collapse;
Collapse.propTypes = {
children: PropTypes.node.isRequired
};
styles.css
.accordion-container {
width: 100%;
}
.app-container {
margin: 20px;
}
.active,
.inactive {
margin-bottom: 5px;
}
.active .folding-pannel {
transition: all 0.3s ease-in-out;
height: 42px;
}
.inactive .folding-pannel {
transform: perspective(0px) rotateX(90deg);
transition: all 0.3s ease-in-out;
height: 0;
}
I am trying to make use of react-modal for the first time. When I click on the sign-in button, the react-modal component is invoke but seems to be hiding behind the cover page which is a video landing page.
The React devtool displays the appropriate states before the sign-in button is clicked
before the sign-in button is clicked
When the sign-in button is now clicked, the react devtool now displays that the ModalPortal component is rendered showing the appropriate states
when the sign-in button is clicked
SignInModal.scss
.ReactModalPortal>div {
opacity: 0;
}
.ReactModalPortal .ReactModal__Overlay {
align-items: center;
display: flex;
justify-content: center;
transition: opacity 200ms ease-in-out;
}
.ReactModalPortal .ReactModal__Overlay--after-open {
opacity: 1;
}
.ReactModalPortal .ReactModal__Overlay--before-close {
opacity: 0;
}
.modal {
position: relative;
background: #464b5e;
color: white;
max-width: 90rem;
outline: none;
padding: 3.2rem;
text-align: center;
}
.modal__title {
margin: 0 0 1.6rem 0;
}
.modal__body {
font-size: 2rem;
font-weight: 300;
margin: 0 0 3.2rem 0;
word-break: break-all;
}
CoverPage.js Component
import Header from './Header';
import HeaderVideo from './HeaderVideo';
import SignInModal from './SignInModal';
import React, { Component } from 'react';
class CoverPage extends Component {
state = {
modalIsOpen: false
};
onOpenModal = () => {
this.setState(() => ({
modalIsOpen: true
}));
};
onCloseModal = () => {
this.setState(() => ({
modalIsOpen: false
}));
};
render() {
return (
<div>
<Header />
<HeaderVideo onOpenModal={this.onOpenModal} />
<SignInModal
modalIsOpen={this.state.modalIsOpen}
onOpenModal={this.onOpenModal}
onCloseModal={this.onCloseModal}
/>
</div>
);
}
}
export default CoverPage;
HeaderVideo.js Component
import React from 'react';
import Signup from './Signup';
import CoverInfo from './CoverInfo';
const HeaderVideo = props => {
return (
<div className="video-container">
<video preload="true" autoPlay loop volume="0" postoer="/images/1.jpg">
<source src="images/vine.mp4" type="video/mp4" />
<source src="images/vine1.webm" type="video/webm" />
</video>
<div className="video-content">
<div className="container content">
<div className="row">
<div className="col-md-9">
<CoverInfo onOpenModal={props.onOpenModal} />
</div>
<div className="col-md-3">
<Signup />
</div>
</div>
</div>
</div>
</div>
);
};
export default HeaderVideo;
CoverInfo.js Component
import React from 'react';
const CoverInfo = props => {
return (
<div className="info">
<div>
<h1>Welcome to EventCity!</h1>
</div>
<div>
<p>
At EventCity! we pride ourselves on the unrivalled personal {`event`} services,we provide
to our clientele. We guide you from the stressful decision making {`process`},ensuring you
are comfortable,whether it is a wedding, corporate {`function `}or even a kiddies party,we
create a buzz around you, taking you to the next level.
</p>
</div>
<div>
<h3>Innovation, {`Performance`} and Delivery</h3>
</div>
<button type="button" className="btn btn-success btn-lg" onClick={props.onOpenModal}>
Sign In here
</button>
</div>
);
};
export default CoverInfo;
video-cover.scss
video {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: 1;
}
.video-content {
z-index: 2;
position: absolute;
background: rgba(0, 0, 0, 0.6);
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.content {
padding-top: 120px;
}
You need to set the z-index property on the Modal's overlay, which normally has a z-index of 0. The CSS class is .ReactModal__Overlay
Here is the pure-React way of doing it:
const customStyles = {
content : {
...
},
overlay: {zIndex: 1000}
};
<Modal style={customStyles}>
...
</Modal>
.modal {
position: fixed;
z-index:9999;
top :0;
left:0;
right:0;
bottom:0;
background: #464b5e;
color: white;
outline: none;
padding: 3.2rem;
text-align: center;
}
Example of react-modal inline styles Set the styles in the react-modal inline styles. The z-index to 100 but make just like below
style={{
overlay: {
zIndex: 100,
backgroundColor: 'rgba(70, 70, 70, 0.5)',
},