React CSS Transitions - reactjs

I'm learning React CSS Transitions. So I decided to make a sliding sidebar navigation. The sidebar slides in from right just fine. But I can't get leave animations working. I'm not sure what's going on.
The jsx:
render: function() {
return(
<div className="_Sidebar">
<div className="top">
<i
className="menuIcon fa fa-bars"
onClick={() => this.handleClick()}>
</i>
<UserName />
</div>
{this.state.show ?
<ReactCSSTransitionGroup
transitionName="example"
transitionAppear={true}
transitionLeave={true} >
<div key={"slidebar"} className="sidebar">
{this.handleItems()}
</div>
</ReactCSSTransitionGroup>
: null}
</div>
);
}
And the css:
.example-appear {
left: -230px;
transition: left .9s ease-in;
}
.example-appear.example-appear-active {
left: 0px;
}
.example-leave {
left: 0px;
transition: left .9s ease-out;
}
.example-leave.example-leave-active {
left: -230px;
}

really I tried in your code there is a thing not right in putting ReactCSSTransitionGroup tag, so I attached my code , its woke correct, you can use it directly and put your data,
import React from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
var Test = React.createClass({
getInitialState: function () {
return { active: true };
},
onToggle: function () {
this.setState({active: !this.state.active});
},
render: function() {
return (
<div>
<ReactCSSTransitionGroup
transitionName="fade"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{!this.state.active && ( <h2> Test Asmaa Almadhoun </h2>)}
</ReactCSSTransitionGroup>
<div className="chatBTN" onClick={this.onToggle}>
<img src="../src/contents/images/svg/chat.svg"/>
</div>
</div>
);
}
});
export default Test;
CSS File
.chatBar{
position: fixed;
height: 320px;
z-index: 0;
right: 0;
top: 40px;
width: 150px;
text-align: center;
display: block;
transform: translateY(-40px);
}
.fade-enter {
transform: translateY(-88%);
}
.fade-enter-active {
top: 0;
transform:translateY(-40px);
transition: .5s ease-in all;
}
.fade-leave {
transform: translateY(-40px);
}
.fade-leave-active {
transform: translateY(-88%);
transition: 0.3s ease-out all;
}

Related

Why CSS(sass) calc() method doesn't work in React?

At first look at my codes:
JSX:
import React from "react";
import "./styles.scss";
export default function App() {
return (
<div className="App">
<h1> This is a Portfolio Item </h1>
<div className="item-container">
<div className="img-container">
<img
src="https://tf-react-chester.now.sh/images/portfolio-image-5.jpg"
alt="Portfolio 1"
/>
</div>
<h3>This is the Title of Item </h3>
<h4>
This is the description of Item. This is the description of Item.{" "}
</h4>
</div>
</div>
);
}
And CSS(SASS):
.App {
.item-container {
width: 100%;
height:auto;
.img-container {
position: relative;
$margin: 20px;
&::before{
position: absolute;
content: '';
**width: calc(100%-20px);
height: calc(100%-20px);** /* These two line don't work. */
left: 10px;
top: 10px;
background-color: #fff;
transition: all 0.5s ease-in-out;
transform: scaleX(0);
transform-origin: 0;
}
&:hover {
transform: scaleX(1);
}
img{
max-width: 100%;
}
}
}
}
I am trying to create a ::before animated content over the image. But when I am using calc() method it doesn't work at all.
What's the reason?
Note: I have tried some solution to the same problem from StackOverflow but those don't work for me.
This is the codesandbox link:CodeSandBox
Try with spaces ;)
width: calc(100% - 20px);
height: calc(100% - 20px);

How to make sidenav mobile link in react js about this situation?

I want to make the sidenav mobile to show when clicking.
I tried to use jquery, but don't know how to configure in webpack.
const SignedOutLinks = () => {
return (
<div>
<NavLink to="#" className="sidenav-trigger nav-wrapper" data-target="mobile-links">
<i className="material-icons">menu</i>
</NavLink>
<ul className="right hide-on-med-and-down">
<li className="waves-effect waves-light">
<NavLink to="/signup">Signup</NavLink>
</li>
<li className="waves-effect waves-light">
<NavLink to="/signin">Login</NavLink>
</li>
</ul>
<ul className="sidenav" id="mobile-links">
<li className="waves-effect waves-light">
<NavLink to="/signup">Signup</NavLink>
</li>
<li className="waves-effect waves-light">
<NavLink to="/signin">Login</NavLink>
</li>
</ul>
</div>
);
};
if you want to write it, this is some code i make:
or this link
react:
class Drawer extends React.Component{
constructor(props){
super(props)
this.state = {
open: false,
}
}
handleDrawer(){
let currentState = this.state.open
this.setState({open: !currentState})
}
componentDidMount(){
if (this.state.open = true){
document.addEventListener("keydown", (event) => {
if (event.keyCode === 27){
this.setState({open: false})
}
})
}
}
handleClickOut(){
if(this.state.open === true){
this.setState({open: false})
}
}
render(){
console.log(this.state)
return (
<div>
<div
onClick={this.handleClickOut.bind(this)}
className={this.state.open ? "deactive" : "container"}>
<button onClick={this.handleDrawer.bind(this)}>Click on me to see the
drawer</button>
</div>
<div className={this.state.open ? "active" : "drawer"}>Hellllo i'm a
drawer</div>
</div>
)
}
}
export default Drawer
css:
.drawer {
display: none;
}
.active {
display: show;
position: absolute;
left: 0;
width: 25vw;
height: 100vh;
background-color: #C10E00;
transition: display 0.4s ease-in-out;
text-align: center;
padding: 10px;
}
.container {
position: relative;
text-align: center;
}
.deactive {
position: absolute;
text-align: center;
background-color: #FF5346;
width: 100vw;
height: 100vh;
transition: 0.4s ease-in-out;
opacity: 0.5;
}
button {
width: 300px;
height: 150px;
background-color: #910B00;
color: white;
box-shadow: 2px 5px grey;
margin: 25px;
}
or if you want to get it full coded you can use Material-UI framework

How to get a particular div into fullscreen(full window size) in reactjs

I am making a Image viewer in ReactJs as I am newbie in this so I stuck at a point. actually I have to add a full screen option. when user click on any particular image the image is open and there is a option like next,prev,close,rotate and fullscreen(that is takes height and width of browser) so when user click on full screen that particular image will get the full window size and user still have option like rotate,next.close and prev. I searched for so many solution but nothing worked.
I tried so many things but it only does the fullscreen whole body but I want .center-image to be full screen with options as I said. This is the gallary modal component.
class GalleryModal extends React.Component {
constructor(props) {
super(props);
this.state = {
rotation: 0
};
this.rotate = this.rotate.bind(this);
}
render() {
const { rotation } = this.state;
if (this.props.isOpen === false) {
return null;
}
return (
<div className="modal-overlay" name={this.props.name}>
<div className="modal-body">
<a href="#" className="button" onClick={() => this.rotate()}>
<i className="fas fa-sync-alt" />
</a>
<a href="#" className="button" onClick={this.props.onPrev}>
<i className="fas fa-angle-left" />
</a>
<img
className="center_image"
id="image"
src={this.props.src}
style={{ transform: `rotate(${rotation}deg)` }}
/>
<a href="#" className="button" onClick={this.props.onNext}>
<i className="fas fa-angle-right" />
</a>
<a
className="modal-close"
href="#"
onClick={this.props.onClick}
>
<span className="fa fa-times" />
</a>
</div>
</div>
);
}
rotate() {
let newRotation = this.state.rotation + 90;
if (newRotation >= 360) {
newRotation = -360;
}
this.setState({
rotation: newRotation
});
}
}
Full code
This is my code and I am confused how to add the fullscreen option and where to add it .
I recommend using css viewport units, setting a component to height: 100vh and width: 100vw will make it fullscreen. You then conditionally render the component based on when you want it to be fullscreen.
Had to use some css tricks, but I believe this is what you're looking to achieve. The image is centered and takes up the maximum amount of width that is available within the window; however, if you stretch the window, it'll adjust its width up until it hits its max width (not advised to stretch it beyond its max value, otherwise, you'll get pixelation).
I did simplify your code a bit by elevating state and class methods to a single container, as well as, used setState() callbacks to manage state more efficiently and the ternary operator (cond ? true : false) in replace of simple if/else conditional statements.
Working example: https://codesandbox.io/s/zr5k7v0zp3
containers/Gallery/Gallery.js
import React from "react";
import GalleryImages from "../../components/GalleryImages/galleryImages";
import GalleryModal from "../../components/GalleryModal/galleryModal";
const imgUrls = [
"https://source.unsplash.com/3Z70SDuYs5g/800x600",
"https://source.unsplash.com/01vFmYAOqQ0/800x600",
"https://source.unsplash.com/2Bjq3A7rGn4/800x600",
"https://source.unsplash.com/t20pc32VbrU/800x600",
"https://source.unsplash.com/pHANr-CpbYM/800x600",
"https://source.unsplash.com/3PmwYw2uErY/800x600",
"https://source.unsplash.com/uOi3lg8fGl4/800x600",
"https://source.unsplash.com/CwkiN6_qpDI/800x600",
"https://source.unsplash.com/9O1oQ9SzQZQ/800x600",
"https://source.unsplash.com/E4944K_4SvI/800x600",
"https://source.unsplash.com/-hI5dX2ObAs/800x600",
"https://source.unsplash.com/vZlTg_McCDo/800x600"
];
export default class Gallery extends React.Component {
constructor(props) {
super(props);
this.state = {
imgIndex: 0,
imgUrlLength: imgUrls.length,
showModal: false,
rotation: 0
};
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.nextClick = this.nextClick.bind(this);
this.prevClick = this.prevClick.bind(this);
this.rotateImage = this.rotateImage.bind(this);
}
openModal(index) {
this.setState({
showModal: true,
imgIndex: index
});
}
closeModal() {
this.setState({
showModal: false,
imgIndex: 0,
rotation: 0
});
}
nextClick() {
this.setState(prevState => {
return {
imgIndex:
prevState.imgIndex === prevState.imgUrlLength - 1
? 0
: prevState.imgIndex + 1
};
});
}
prevClick() {
this.setState(prevState => {
return {
imgIndex:
prevState.imgIndex === 0
? prevState.imgUrlLength - 1
: prevState.imgIndex - 1
};
});
}
rotateImage() {
this.setState(prevState => {
return {
rotation: prevState.rotation + 90 <= 270 ? prevState.rotation + 90 : 0
};
});
}
render() {
return (
<div className="container-fluid gallery-container">
<GalleryImages imgUrls={imgUrls} openModal={this.openModal} />
<GalleryModal
isOpen={this.state.showModal}
onClick={this.closeModal}
onNext={this.nextClick}
onPrev={this.prevClick}
rotateImage={this.rotateImage}
rotation={this.state.rotation}
src={imgUrls[this.state.imgIndex]}
/>
</div>
);
}
}
components/GalleryImages/galleryImages.js
import React from "react";
import PropTypes from "prop-types";
const GalleryImages = ({ imgUrls, openModal }) => {
return (
<div className="row">
{imgUrls.map((url, index) => {
return (
<div key={index} className="col-sm-6 col-md-3 col-xl-2">
<div className="gallery-card">
<img
key={index}
className="gallery-thumbnail"
src={url}
alt={`Image number ${index + 1}`}
/>
<span
className="card-icon-open fa fa-expand"
onClick={() => openModal(index)}
/>
</div>
</div>
);
})}
</div>
);
};
GalleryImages.propTypes = {
imgUrls: PropTypes.arrayOf(PropTypes.string).isRequired,
openModal: PropTypes.func.isRequired
};
export default GalleryImages;
components/GalleryModal/galleryModal.js
import React from "react";
import PropTypes from "prop-types";
const GalleryModal = ({
isOpen,
onClick,
onNext,
onPrev,
rotateImage,
rotation,
src
}) => {
return isOpen ? (
<div className="modal-overlay">
<div className="modal-body">
<div className="close-modal">
<a className="modal-close" href="#" onClick={onClick}>
<span className="fa fa-times" />
</a>
</div>
<div className="rotate-container">
<a href="#" className="button" onClick={rotateImage}>
<i style={{ fontSize: 44 }} className="fas fa-sync-alt" />
</a>
</div>
<div className="image-container">
<div>
<a href="#" className="button" onClick={onPrev}>
<i className="fas fa-angle-left" />
</a>
</div>
<div>
<img
src={src}
style={{ transform: `rotate(${rotation}deg)`, width: "100%" }}
/>
</div>
<div>
<a href="#" className="button" onClick={onNext}>
<i className="fas fa-angle-right" />
</a>
</div>
</div>
</div>
</div>
) : null;
};
GalleryModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
onNext: PropTypes.func.isRequired,
onPrev: PropTypes.func.isRequired,
rotateImage: PropTypes.func.isRequired,
rotation: PropTypes.number.isRequired,
src: PropTypes.string
};
export default GalleryModal;
styles.css
html,
body {
min-height: 100%;
height: 100%;
}
html {
font-size: 16px;
}
body {
position: relative;
font-size: 100%;
}
.button {
font-size: 50px;
color: #eee;
margin: 5px;
}
.card-icon-open {
display: block;
position: relative;
left: 45%;
top: 35px;
font-size: 30px;
width: 30px;
color: #fff;
cursor: pointer;
opacity: 0;
transform: translate(0%, -400%);
transition: all 0.25s ease-in-out;
}
.card-icon-open:focus,
.card-icon-open:hover {
color: #111;
}
.close-modal {
position: fixed;
top: 0;
right: 5px;
}
.fullscreen {
position: relative;
text-decoration: none;
font-size: 25px;
color: #eee;
z-index: 999;
}
.fullscreen:hover,
.fullscreen:focus,
.fullscreen:blur {
text-decoration: none;
color: red;
}
.gallery-container {
padding-top: 10px;
}
.gallery-card {
position: relative;
overflow: hidden;
margin-bottom: 10px;
}
.gallery-thumbnail {
max-width: 100%;
height: auto;
border-radius: 4px;
}
.gallery-thumbnail:focus ~ .card-icon-open,
.gallery-thumbnail:hover ~ .card-icon-open,
.gallery-thumbnail ~ .card-icon-open:focus,
.gallery-thumbnail ~ .card-icon-open:hover {
opacity: 1;
}
.image-container {
display: flex;
justify-content: center;
align-items: center;
}
.image-rotate {
font-size: 44px;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 100%;
background: rgba(21, 21, 21, 0.75);
}
.modal-body {
position: relative;
top: 15%;
z-index: 11;
padding: 0;
overflow: hidden;
max-width: 100%;
max-height: 100%;
}
.modal-close {
font-size: 44px;
z-index: 99;
color: #eee;
transition: all 0.25s ease-in-out;
}
.modal-close:focus,
.modal-close:hover {
color: red;
}
.rotate-container {
font-size: 44px;
position: fixed;
top: 0;
left: 5px;
}
Found this library which does exactly what you describe:
https://www.npmjs.com/package/react-fullscreen-image
You can use as is or look into the code for guidance

React-modal hides behind elements

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)',
},

React CSS transition not working

I have a tic tac toe board, and want to add a transition an element on a click.
For demo, I have a board with some cells filled. On click on the board, a new cell is filled. I wanted this new cell to come with a transition.
I have followed the React Transition Group doc. On click on any cell of the board, a circle appears on 2rd row 3rd col. This should appear with a Fade-in transition. I have added CSSTransition group, but transition is not happening. Something is amiss.
Following is the codesandbox:
Some sample code from the snippet
tic-tac-toe-board.js
import React from "react";
import "./tictactoe.css";
import { CSSTransition } from 'react-transition-group';
const Fade = ({ children, ...props }) => (
<CSSTransition {...props} timeout={1000} classNames="fade">
{children}
</CSSTransition>
);
class TicTacToeBoard extends React.Component {
constructor(props) {
super(props);
this.state = {
board: [
[0, 1, 0],
[2, 0, 0],
[0, 0, 0]
]
};
}
handleBoardClick = () => {
let newBoard = [
[...this.state.board[0]],
[...this.state.board[1]],
[...this.state.board[2]]
];
newBoard[1][2] = 1;
this.setState({board: newBoard});
}
render() {
return (
<div className="board" onClick={this.handleBoardClick}>
{this.state.board.map((row, rowIndex) =>
row.map((cell, colIndex) => {
return (
<div className="cell" key={`${rowIndex}-${colIndex}`}>
{cell === 1 && (
<Fade in={true}>
<img
src="https://image.ibb.co/nDDDuw/circle_outline.png"
alt=""
className="cell-content"
/>
</Fade>
)}
{cell === 2 && (
<Fade in={true}>
<img
src="https://image.ibb.co/jY0nMb/close.png"
alt=""
className="cell-content"
/>
</Fade>
)}
</div>
);
})
)}
</div>
);
}
}
export default TicTacToeBoard;
tictactoe.css
* {
box-sizing: border-box;
}
.board {
width: 90vmin;
height: 90vmin;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
margin-left: auto;
margin-right: auto;
box-shadow: 5px 5px 10px #aaa;
}
.cell {
width: 30vmin;
height: 30vmin;
border: 1px solid lightgrey;
}
.cell-content {
width: 80%;
height: 80%;
margin: 10%;
}
.fade-enter {
opacity: 0.01;
}
.fade-enter.fade-enter-active {
opacity: 1;
transition: opacity 1000ms ease-in;
}
I had a similar issue but solved when I enclosed the CSSTransition inside the TransitionGroup
const Fade = ({ children, ...props }) => (
<TransitionGroup>
<CSSTransition {...props} timeout={1000} classNames="fade">
{children}
</CSSTransition>
</TransitionGroup>);
And update the style something like this
.fade-enter {
opacity: 0.01;
}
.fade-enter-active {
opacity: 1;
transition: opacity 1000ms ease-in;
}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0.01;
transition: opacity 1s ease-out;
}

Resources