In REACTJS, I am working with creating a simple App that contains Transitions. I have imported CSSTransitions and Group Transition in my file but when I am trying to apply CSSTransition for some of my news item but I am not getting the animation. It is as if it doesn't even exist.
I can see that my items are wrapped inside the component, but I cannot get them to animate.
Could someone please help me figure out what I'm doing wrong?
import React, { Component } from 'react';
import {CSSTransition, TransitionGroup} from 'react-transition-group';
import {Link} from 'react-router-dom';
import Axios from 'axios';
import {URL} from '../../../Config';
import styles from './NewsList.module.css';
export default class NewsList extends Component {
state={
items:[],
start: this.props.start,
end: this.props.start+this.props.amount,
amount: this.props.amount
}
componentWillMount(){
this.request(this.state.start,this.state.end)
}
request=(start,end)=>{
Axios.get(`${URL}/articles?_start=${start}&_end=${end}`)
.then(response=>{
this.setState({
items:[...this.state.items,...response.data]
})
})
}
loadMore=()=>{
let end = this.state.end + this.state.amount
this.request(this.state.end, end)
}
renderNews=(type)=>{
let template= null;
switch(type){
case('Card'):
template= this.state.items.map((item, i)=>(
<CSSTransition
classNames={{
enter: styles.newList_wrapper,
enterActive: styles.newList_wrapper_enter
}}
timeout= {500}
key={i}
>
<div>
<div className={styles.newslist_item}>
<Link to={`/articles/${item.id}`}>
<h2>{item.title}</h2>
</Link>
</div>
</div>
</CSSTransition>
)
);
break;
default:
template = null;
}
return template;
}
render() {
return (
<div>
<TransitionGroup
component="div"
className="list"
>
{this.renderNews(this.props.type)}
</TransitionGroup>
<div onClick={this.loadMore}>
Load More
</div>
</div>
);
}
}
.newslist_item{
border: 1px solid #f2f2f2;
background: #ffffff;
margin-top: 0px;
padding: 8px 5px 0 5px;
}
.newslist_item h2{
font-size: 13px;
line-height: 21px;
margin: 5px 0;
color: #525252
}
.newslist_item a {
text-decoration:none;
}
.newsList_wrapper{
box-sizing: border-box;
opacity: 0;
transform: translateX(-100%);
transition: all .5s ease-in;
}
.newsList_wrapper_enter{
opacity: 1;
transform: translateX(0%);
}
<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>
classNames={{
enter: **styles.newsList_wrapper**,
enterActive: **styles.newsList_wrapper_enter**
There was a typo with the classnames. An S was missing.
Related
I'm trying to set advanced usage Material UI v.4 Theme provider and StylesProvider
I can't use the "classes" prop of a component to override the styles.
I follow that instruction and some experience from past projects.
Advanced Material UI v 4.12.3
My App.js:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { ThemeProvider, StylesProvider } from "#material-ui/core/styles";
import theme from "./styles/theme";
import store from "./redux/store";
import AppRouter from "./routes/AppRouter";
import ErrorBoundary from "./ErrorBoundary";
ReactDOM.render(
<Provider store={store}>
<ErrorBoundary>
<StylesProvider injectFirst>
<ThemeProvider theme={theme}>
<AppRouter />
</ThemeProvider>
</StylesProvider>
</ErrorBoundary>
</Provider>,
document.getElementById("root"),
);
part of package.json:
"dependencies": {
"#material-ui/icons": "^4.9.1",
"#material-ui/lab": "^4.0.0-alpha.56",
}
"devDependencies": {
"#material-ui/core": "^4.9.12",
"#material-ui/pickers": "^3.2.10",
}
theme.js
import { createTheme } from "#material-ui/core/styles";
const theme = createTheme({
palette: {
primary: {
main: "#08718f",
},
secondary: {
main: "#604486",
},
},
});
export default theme;
image-preview.scss
.previewButton {
border-radius: 10px;
border: 1px solid #dcdcdc;
margin-right: 7px;
margin-bottom: 7px;
opacity: 0.6;
&:hover {
border: 1px solid #3f51b5;
opacity: 1;
}
}
SomeComponent.js
import { Button } from "#material-ui/core";
import "../../styles/common/image-preview.scss";
{imageObj?.map((el, index) => (
<Button
className='previewButton'
key={el.id}
onClick={() => setSelectedImage(index)}
>
<img className='imageButton' src={el.url} alt={el.imgName} />
</Button>
))}
This code above works great. I can easily rewrite Material UI components with the flag "injectFirst" from App.js .
Inside Button, I can change the style className=`previewButton' it works
But if I made these changes.
I can't use the "classes" prop of a component to override the styles.
className={classes.previewButton}
SomeComponent.js
import { Button } from "#material-ui/core";
import classes "../../styles/globalStyle.module.scss";
{imageObj?.map((el, index) => (
<Button
className={classes.previewButton}
key={el.id}
onClick={() => setSelectedImage(index)}
>
<img className='imageButton' src={el.url} alt={el.imgName} />
</Button>
))}
globalStyle.module.scss
.previewButton {
border-radius: 10px;
border: 1px solid #dcdcdc;
margin-right: 7px;
margin-bottom: 7px;
opacity: 0.6;
&:hover {
border: 1px solid #3f51b5;
opacity: 1;
}
}
Maybe I missed something? Any help will help!
NavStyles.js
import styled from 'styled-components';
export const Nav = styled.navwidth: 100%; ;
export const NavMenuMobile = styled.ul`
height: 80px;
.navbar_list_class {
font-size: 2rem;
background-color: red;
}
${props => props.navbar_list_props && `
font-size: 2rem;
background-color: gray;
`}
`;
Navbar.js
import React from 'react'
import {Nav, NavMenuMobile} from "./NavStyles";
const Navbar = () => {
return (
<Nav>
{/* work no problem */}
<NavMenuMobile navbar_list_props>Nav Bar props</NavMenuMobile>
{/* not work How to use..? */}
<NavMenuMobile className="navbar_list_class">Nav Bar class</NavMenuMobile>
</Nav>
)
}
export default Navbar
<Nav>
<NavMenuMobile className={navbar_list_props}>Nav Bar props</NavMenuMobile>
</Nav>
Try This
Looks like you are setting styles for the children within NavMenuMobile with the class "navbar_list_class".
Should work with &.navbar_list_class
export const NavMenuMobile = styled.ul`
height: 80px;
&.navbar_list_class {
font-size: 2rem;
background-color: red;
}
`;
I have a navbar component, as well as a Navbar.module.css file.
the navbar component file:
import styleNavbar from '../../../styles/Main/Navbar.module.css'
It's supposed to make the navigation bar look nice, but what's happening instead is that everything but the buttons gets styled. The buttons have changed back to the standard ones after I started using next-auth for social login.
the app file:
import React from 'react';
import { SessionProvider } from "next-auth/react"
import styles from '../styles/tstyles.css'
export default function App({Component,pageProps: { session, ...pageProps },}) {
return (
<SessionProvider className={styles} session={session}>
<div className={styles} >
<Component className={styles} {...pageProps} />
</div>
</SessionProvider>
)
};
The app file imports a tailwind css file that simply consists of the following:
#tailwind base;
#tailwind components;
#tailwind utilities;
that's all the css i have in my app. i'm very unfamiliar with how this works - but the styles on the nav bar were definitely showing before.
the full navbar.js
import styleNavbar from "../../../styles/Main/Navbar.module.css";
import React, { useState, useEffect, useRef } from "react";
import { signOut } from "next-auth/react";
const NavButtonCreator = (props) => {
const { mainprops, userprops, navbar, navprops, ...styleprops } = props;
return (
<button
href="#"
className={`${styleNavbar.menu__link} ${styleNavbar.r_link} ${styleNavbar.text_underlined}`}
{...props}
onClick={() => {
navbar.makeButtonClick(!navbar.buttonClick);
navbar.setButtonChoice(navprops.navbutton);
}}
>
{navprops.navbutton}
</button>
);
};
const NavButtonStyler = (props) => {
const { mainprops, userprops, navbar, ...navprops } = props;
return (
<>
{props.place == "left" && (
<div className="">
<NavButtonCreator
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
navprops={navprops}
/>
</div>
)}
{props.place == "center" && (
<div className="absolute left-1/2 transform -translate-x-1/2 ">
<NavButtonCreator
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
navprops={navprops}
/>
</div>
)}
{props.place == "right" && (
<div className="absolute right-0">
<NavButtonCreator
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
navprops={navprops}
/>
</div>
)}
</>
);
};
const Navbar = (props) => {
const { mainprops, ...userprops } = props;
const [buttonClick, makeButtonClick] = useState(false);
const [buttonChoice, setButtonChoice] = useState(userprops.pageId);
const navbar = {
buttonClick,
makeButtonClick,
setButtonChoice,
};
useEffect(() => {
if (buttonChoice == "log out") {
signOut();
}
userprops.makeRefresh(!userprops.refresh);
userprops.setPageId(buttonChoice);
}, [buttonClick]);
if (userprops.visitorType == "viewer") {
return (
<div>
<nav
className={`${styleNavbar.page__menu} ${styleNavbar.page__custom_settings} ${styleNavbar.menu}`}
>
<ul className={`${styleNavbar.menu__list} ${styleNavbar.r_list}`}>
<NavButtonStyler
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
place="left"
navbutton="uno"
/>
<NavButtonStyler
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
place="left"
navbutton="dos"
/>
<NavButtonStyler
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
place="left"
navbutton="tres"
/>
<NavButtonStyler
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
place="center"
navbutton="four"
/>
<NavButtonStyler
mainprops={mainprops}
userprops={userprops}
navbar={navbar}
place="right"
navbutton="i dont speak spanish"
/>
</ul>
</nav>
</div>
);
}
};
export default Navbar;
Navbar.module.css file:
/*
=====
DEPENDENCES
=====
*/
.r_link{
display: var(--rLinkDisplay, inline-flex) !important;
}
.r_link[href]{
color: var(--rLinkColor) !important;
text-decoration: var(--rLinkTextDecoration, none) !important;
}
.r_list{
padding-left: var(--rListPaddingLeft, 0) !important;
margin-top: var(--rListMarginTop, 0) !important;
margin-bottom: var(--rListMarginBottom, 0) !important;
list-style: var(--rListListStyle, none) !important;
}
/*
=====
CORE STYLES
=====
*/
.menu{
--rLinkColor: var(--menuLinkColor, currentColor);
}
.menu__link{
display: var(--menuLinkDisplay, block);
}
/*
focus state
*/
.menu__link:focus{
outline: var(--menuLinkOutlineWidth, 2px) solid var(--menuLinkOutlineColor, currentColor);
outline-offset: var(--menuLinkOutlineOffset);
}
/*
fading siblings
*/
.menu:hover .menu__link:not(:hover){
--rLinkColor: var(--menuLinkColorUnactive, #2e354b);
}
/*
=====
PRESENTATION STYLES
=====
*/
.menu{
background-color: var(--menuBackgroundColor, #2e354b);
box-shadow: var(--menuBoxShadow, 0 1px 3px 0 rgba(0, 0, 0, .12), 0 1px 2px 0 rgba(0, 0, 0, .24));
}
.menu__list{
display: flex;
}
.menu__link{
padding: var(--menuLinkPadding, 1.5rem 2.5rem);
font-weight: 700;
text-transform: uppercase;
}
/*
=====
TEXT UNDERLINED
=====
*/
.text_underlined{
position: relative;
overflow: hidden;
will-change: color;
transition: color .25s ease-out;
}
.text_underlined::before,
.text_underlined::after{
content: "";
width: 0;
height: 3px;
background-color: var(--textUnderlinedLineColor, currentColor);
will-change: width;
transition: width .1s ease-out;
position: absolute;
bottom: 0;
}
.text_underlined::before{
left: 50%;
transform: translateX(-50%);
}
.text_underlined::after{
right: 50%;
transform: translateX(50%);
}
.text_underlined:hover::before,
.text_underlined:hover::after{
width: 100%;
transition-duration: .2s;
}
/*
=====
SETTINGS
=====
*/
.page__custom_settings{
--menuBackgroundColor: #2e354b;
--menuLinkColor: #eed994;
--menuLinkColorUnactive: #2e354b;
--menuLinkOutlineOffset: -.5rem;
}
/*
=====
DEMO
=====
*/
.body{
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Open Sans, Ubuntu, Fira Sans, Helvetica Neue, sans-serif;
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.page{
box-sizing: border-box;
max-width: 640px;
padding-left: .75rem;
padding-right: .75rem;
margin: auto;
}
.page__menu:nth-child(n+2){
margin-top: 3rem;
}
.substack{
border:1px solid #EEE;
background-color: #fff;
width: 100%;
max-width: 480px;
height: 280px;
margin: 1rem auto;;
}
PS - i didnt write that css code
i installed autoprefixer
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
npm install autoprefixer
now the styles all look great....but the social auth doesn't work!!
TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined.
This error happened while generating the page. Any console logs will be displayed in the terminal window.
It looks like your using NextJS, and If your using Tailwind why are you using CSS Modules?
npx create-next-app -e with-tailwindcss my-project will create a working NextJS + TailwindCSS project for you.
I am a beginner of React.
I'm practicing using React to pass props from parent to child.
but.I can't pass props.
I just want to pass simple props from parent to child.
My code is here.
https://codesandbox.io/s/props-test-3bgjy?file=/src/Child.js
My code is not showing the error.
But my code doesn't display correctly.
import React, { Component } from "react";
import styled from "styled-components";
import Child from "./Child";
const Button = styled.button`
font-size: 16px;
padding: 16px;
`;
class App extends Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
msg: "state(msg)initial",
flg: true
};
this.doAction = this.doAction.bind(this);
}
doAction() {
this.setState((state) => ({
counter: state.counter + 1,
msg: state.counter,
flg: !state.flg
}));
}
render() {
return (
<div>
<Child msg={this.state.message} flag={this.state.flag} />
<Button onClick={this.doAction}>Click</Button>
</div>
);
}
}
export default App;
import React, { Component } from "react";
import styled from "styled-components";
const Message = styled.p`
font-size: 24pt;
color: #900;
margin: 20px 0px;
padding: 5px;
border-bottom: 2px solid #900;
&[data-primary="true"] {
font-size: 24pt;
color: white;
background-color: #900;
margin: 20px 0px;
padding: 5px;
border-bottom: 2px solid #900;
}
`;
class Child extends Component {
render() {
return (
<div>
<Message data-primary={this.props.flag}>
count: {this.props.msg}
</Message>
</div>
);
}
}
export default Child;
You are have mistake in line <Child msg={this.state.message} flag={this.state.flag} />
Need use state param msg
<Child msg={this.state.msg} flag={this.state.flag} />
https://codesandbox.io/s/props-test-forked-gw69r?file=/src/Parent.js
It looks like you have a typo; change this line:
<Child msg={this.state.message} flag={this.state.flag} />
to
<Child msg={this.state.msg} flag={this.state.flg} />
I'm facing an issue with material-ui drawer. I've changed the width of the drawer container which causes a a problem . The drawer remains a little inside the page and visible but I don't want to make it visible on the page while I haven't clicked the button. It might be having an issue with the transform attribute now.
So I changed it to transform: translate(350px, 0px) but then I'm getting another issue, that is if I am clicking the button the drawer is not showing up. Any help on this thing ??
I have got the solution and edited the code.
I've created a Demo here => Have a look
Also shared the code below:
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import Drawer from 'material-ui/Drawer';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
class App extends Component {
constructor() {
super();
this.state = {
openDrawer: false
};
}
toggleDrawer() {
this.setState({
openDrawer: !this.state.openDrawer
});
}
render() {
return (
<MuiThemeProvider>
<div>
<button onClick={this.toggleDrawer.bind(this)}> Toggle Drawer</button>
<Drawer
open={this.state.openDrawer}
containerClassName={!this.state.openDrawer? "hide-drawer": "show-drawer" }
openSecondary={true}
docked={true}
>
<div className="drawer-title-div">
<h4 className="drawer-title-text">It's my drawer</h4>
</div>
</Drawer>
</div>
</MuiThemeProvider>
);
}
}
render(<App />, document.getElementById('root'));
style.css
h1, p {
font-family: Lato;
}
.show-drawer {
top: 47px !important;
text-align: left !important;
width: 80% !important;
transform: translate(0%, 0px) !important;
}
.hide-drawer {
top: 47px !important;
text-align: left !important;
width: 80% !important;
transform: translate(100%, 0px) !important;
}
/* .drawer-side-drawer:focus {
top: 47px !important;
text-align: left !important;
width: 350px !important;
transform: translate(0px, 0px) !important;
} */
.drawer-title-div {
display: inline-block;
width: 100%;
background: #F2F8FB;
box-shadow: 0 1px 3px 0 rgba(0,0,0,0.24);
}
.drawer-title-text {
display: inline-block;
margin-left: 16px;
margin-top: 16px;
margin-bottom: 16px;
color: #484848;
font-family: Muli;
font-size: 16px;
font-weight: 600;
}
For mui version 5, you have to use the PaperProps prop like so:
<Drawer
PaperProps={{
sx: { width: "90%" },
}}
>{...Child elements here}</Drawer>
you can simply add this to index.css
.MuiDrawer-paper {
width: 60% !important;
}
#media (max-width: 1200px) {
.MuiDrawer-paper {
width: 100% !important;
}
}
Just add PaperProps={{ style: { width: '25%' } }} to your MUI Drawer.
Most Probably it will work for everyone.
You can try adding a toggle class and you can get rid of the transform.
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import Drawer from 'material-ui/Drawer';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
class App extends Component {
constructor() {
super();
this.state = {
openDrawer: false
};
}
toggleDrawer() {
this.setState({
openDrawer: !this.state.openDrawer
});
}
render() {
return (
<MuiThemeProvider>
<div>
<button onClick={this.toggleDrawer.bind(this)}> Toggle Drawer</button>
<Drawer containerClassName={!this.state.openDrawer ? "hide-drawer": "show-drawer"}
open={this.state.openDrawer}
openSecondary={true}
docked={true}
>
<div className="drawer-title-div">
<h4 className="drawer-title-text">It's my drawer</h4>
</div>
</Drawer>
</div>
</MuiThemeProvider>
);
}
}
render(<App />, document.getElementById('root'));
You can use window.innerWidth as width: 100%:
<Drawer ...>
<div style={{width: window.innerWidth * 0.25}}>
...
</div>
</Drawer>
One way to solve this issue is by getting the parent width:
const parentRef = useRef<HTMLDivElement>(null);
<Box
ref={parentRef}
>
<Drawer
PaperProps={{
sx: {
width: parentRef?.current?.clientWidth || 0,
},
}}
// .... etc
</Drawer>
</Box>
One way to solve this issue is by getting the parent width:
const parentRef = useRef<HTMLDivElement>(null);
<Box
ref={parentRef}
>
<Drawer
PaperProps={{
sx: {
width: parentRef?.current?.clientWidth || 0,
},
}}
>
// content goes here
</Drawer>
</Box>
Drawer-Material-UI If you look at the link.. you will find Drawer properties..
width (union: string number) [default : null] The width of the Drawer in pixels or
percentage in string format ex. 50% to fill half of the window or 100%
and so on. Defaults to using the values from theme.
so just update the tag with width and you are good to go,
<Drawer width="50%"></Drawer>
Check it here..
The drawer width is not matching the theme drawer width which was causing the problem.. not the transform CSS attribute.
Just a different approach ^^
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import Drawer from 'material-ui/Drawer';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Responsive from 'react-responsive-decorator'; // This decorator allows using the library as a decorator.
#Responsive
class App extends Component {
constructor() {
super();
this.state = {
openDrawer: false,
width:350
};
}
// Update for kinda media query thing
componentDidMount() {
this.props.media({ minWidth: 768 }, () => {
this.setState({
width: 350
});
});
this.props.media({ maxWidth: 768 }, () => {
this.setState({
width: 150
});
});
}
toggleDrawer() {
this.setState({
openDrawer: !this.state.openDrawer
});
}
render() {
return (
<MuiThemeProvider>
<div>
<button onClick={this.toggleDrawer.bind(this)}> Toggle Drawer</button>
<Drawer width={this.state.width} //<- Update
open={this.state.openDrawer}
containerClassName="drawer-side-drawer"
openSecondary={true}
docked={true}
>
<div className="drawer-title-div">
<h4 className="drawer-title-text">It's my drawer</h4>
</div>
</Drawer>
</div>
</MuiThemeProvider>
);
}
}
render(<App />, document.getElementById('root'));
I had the same problem.
you just have to add the PaperProps to your drawer