How to animate parent width depending on its content? - css

I have a modal whose content can be toggled between two different components. It works, but the transition is brutal since the wrapper immediately takes the width of its content.
How to animate this properly? I thought about transform:scale but it did not work.
Here is the code, as well as a sandbox:
import React, {useState} from "react";
import styled from "styled-components"
const Wrapper = styled.div`
background:gainsboro;
width:100%;
height:100%;
border:1px solid lightgrey;
`
const Content1 = () => (
<div>
Lorizzle ipsizzle dolor sit amet, ass adipiscing elizzle. Ass
izzle velizzle, volutpizzle, suscipit quizzle, we gonna chung
vizzle, arcu. Pellentesque egizzle boom shackalack. Fo shizzle
my nizzle erizzle. Pimpin' crunk dolor dapibus rizzle tempizzle
sizzle. Maurizzle fo shizzle mah nizzle fo rizzle, mah home
g-dizzle nibh daahng dawg go to hizzle. Shizznit izzle tortor.
Pellentesque sizzle rhoncizzle shizzlin dizzle. In hizzle
habitasse platea dictumst. For sure fo. Break it down izzle
urna, pretizzle eu, mattis go to hizzle, eleifend black, nunc.
Daahng dawg suscipit. Tellivizzle yo mamma velit sed check
out this.
</div>
)
const Content2 = () => (
<div>
very short content
</div>
)
export default function App() {
const [toggle, setToggle] = useState(false)
return (
<Wrapper>
{toggle ? <Content1 /> : <Content2/>}
<button onClick={()=> setToggle(!toggle)}>toggle content</button>
</Wrapper>
);
}
https://codesandbox.io/s/still-smoke-5ikkg?file=/src/App.js
Thanks!

you can use react-fade-in, not the best, but a fast solution
https://www.npmjs.com/package/react-fade-in

Related

Responsive slider timeline (NextJs project) with Swiper

I am new to NextJs/ReactJs and I was trying to implement the Responsive slide with Swiperjs which is available in codepen.io
Here is the link to codepen.
Responsive slider timeline with Swiper
Below are my steps I carried out;
Installed JQuery (npm install)
Imported both swiper.min.css and swiper.min.js CDNs to my _Document.js file
Added the css files to Globals.css for time being
Created a TimelineComponent.js to have the swiper component separately.
imported TimelineComponent.js in the index.js
When I run the project it nicely shows you the expected output as below.
But when I resize my browser it behaves abnormally like below
import React, { useEffect } from 'react';
import $ from 'jquery';
function TimeLineComponent() {
function operateTimeline() {
var timelineSwiper = new Swiper('.timeline .swiper-container', {
direction: 'vertical',
loop: false,
speed: 1600,
pagination: '.swiper-pagination',
paginationBulletRender: function (swiper, index, className) {
var year = document
.querySelectorAll('.swiper-slide')
[index].getAttribute('data-year');
return '<span class="' + className + '">' + year + '</span>';
},
paginationClickable: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
breakpoints: {
768: {
direction: 'horizontal',
},
},
});
}
useEffect(() => {
$(window).on('load resize', operateTimeline);
operateTimeline();
return () => {
$(window).off('load resize');
};
}, []);
return (
<div className="timeline-container">
<div className="timeline">
<div className="swiper-container">
<div className="swiper-wrapper">
<div
className="swiper-slide"
style={{
backgroundImage: "url('https://unsplash.it/1920/500?image=11')",
}}
data-year="2011"
>
<div className="swiper-slide-content">
<span className="timeline-year">2011</span>
<h4 className="timeline-title">Our nice super title</h4>
<p className="timeline-text">
Lorem ipsum dolor site amet, consectetur adipscing elit, sed
do eisumod tempor incididut ut labore et dolore magna aliqua.
Ut enim ad mimim venjam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
<div
className="swiper-slide"
style={{
backgroundImage: "url('https://unsplash.it/1920/500?image=12')",
}}
data-year="2012"
>
<div className="swiper-slide-content">
<span className="timeline-year">2012</span>
<h4 className="timeline-title">Our nice super title</h4>
<p className="timeline-text">
Lorem ipsum dolor site amet, consectetur adipscing elit, sed
do eisumod tempor incididut ut labore et dolore magna aliqua.
Ut enim ad mimim venjam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
</div>
<div className="swiper-button-prev"></div>
<div className="swiper-button-next"></div>
<div className="swiper-pagination"></div>
</div>
</div>
</div>
);
}
export default TimeLineComponent;
Error can be replicated in the above codepen example as well. Most probably this is with the styling
Your help is much appreciated.

How to make React Material-UI Accordion fill entire height?

I have 2 Material-ui Accordions which I want to expand to their full height in the following way:
Both of them collapsed.
One collapsed (take the maximum height possible)
Both expanded (each take 50% of the full height)
Can I achieve this with the following code simply with CSS? (thought it should be possible with flex-grow and flex-direction:column but I can't get it to work.
https://codesandbox.io/s/upbeat-tesla-uchsb?file=/accordionFullHeight
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Accordion from '#material-ui/core/Accordion';
import AccordionSummary from '#material-ui/core/AccordionSummary';
import AccordionDetails from '#material-ui/core/AccordionDetails';
import Typography from '#material-ui/core/Typography';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
background: 'green',
height: '90vh'
},
heading: {
fontSize: theme.typography.pxToRem(15),
fontWeight: theme.typography.fontWeightRegular,
},
}));
export default function SimpleAccordion() {
const classes = useStyles();
return (
<div className={classes.root}>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography className={classes.heading}>Accordion 1</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</Typography>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel2a-content"
id="panel2a-header"
>
<Typography className={classes.heading}>Accordion 2</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</Typography>
</AccordionDetails>
</Accordion>
</div>
);
}
Solved it using a controlled Accordion that uses flex-grow:1 only when its expanded:
https://codesandbox.io/s/upbeat-tesla-uchsb?file=/src/MyAccordion.js
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Accordion from "#material-ui/core/Accordion";
import AccordionDetails from "#material-ui/core/AccordionDetails";
import AccordionSummary from "#material-ui/core/AccordionSummary";
import Typography from "#material-ui/core/Typography";
import ExpandMoreIcon from "#material-ui/icons/ExpandMore";
const useStyles = makeStyles((theme) => ({
root: {
width: "100%",
background: "red",
color: "blue"
},
rootExpanded: {
background: "blue",
flexGrow: 1
}
}));
export default function MyAccordion(props) {
const classes = useStyles();
const { name } = props;
const [expanded, setExpanded] = React.useState(false);
const rootClass = expanded ? classes.rootExpanded : classes.root;
const handleChange = (panel) => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
return (
<Accordion
className={rootClass}
expanded={expanded === name}
onChange={handleChange(name)}
>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1bh-content"
id={`${name}-header`}
>
<Typography className={classes.heading}>General settings</Typography>
<Typography className={classes.secondaryHeading}>
I am an accordion
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat.
Aliquam eget maximus est, id dignissim quam.
</Typography>
</AccordionDetails>
</Accordion>
);
}

Specifying alternate background image using ngStyle

I am trying to specify an alternate background image for a DIV like so:
<div [ngStyle]="{'background-image':'url(1.jpg), url(2.jpg)'}"></div>
Neither of the images are displaying (it works if I don't specify an alternate image).
Is it possible to specify multiple background images using ngStyle?
Working demo
Template file
<div [ngStyle]='styles'>
<h1>Lorem Ipsum Dolor</h1>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
</div>
Ts file
export class AppComponent {
name = 'Angular';
img1 = 'https://www.w3schools.com/css/img_flwr.gif';
img2 = 'https://www.w3schools.com/css/paper.gif'
isSelected: boolean = true;
styles = {};
setCurrentStyles() {
this.styles = {
backgroundImage: this.isSelected ?
`url(${this.img1})`:`url(${this.img2})`
};
}
toogleImage() {
this.isSelected = !this.isSelected;
this.setCurrentStyles();
}
}
Try like this
template.html
<div class="image" [ngStyle]="{background: !isActive ? 'url(https://www.fonewalls.com/wp-content/uploads/Aqua-Solid-Color-Background-Wallpaper-for-Mobile-Phone.png)' : 'url(https://www.fonewalls.com/wp-content/uploads/Midnight-Blue-Solid-Color-Background-Wallpaper-for-Mobile-Phone.png)'}"></div>
cmponent.ts
isActive: boolean = true;
You can also keep your HTML clean with moving all the logic into the component.ts.
In the end you would have something like this:
<div class="image" [ngStyle]="{
'background-image': 'url(' + backgroundImageString + ')'
}"></div>
Then in your component:
private defineBackImage(someArg) {
if (stuff) {
this.backgroundImageString = url1;
} else {
this.backgroundImageString = url2;
}
}
You can trigger this function on init of according to specific events, also you can extend this logic to display much more than 2 backgrounds

Does deep nesting flexbox layout cause performance issue?

I have been working on a ReactJS project where I create most of the components using flexbox layout. Since with react, we can have deeply nested components, so my layout is having nested flexbox layout.
Now my question is, does this have any issue with performance? On a single page, there are many components and each component have 3 to 4 level nested flexbox layout. Will that cause a performance issue?
Have done a little test. Rendered 100 components, each with 10 nested layout. With and without flexbox. Here are the code snippets:
Component/index.js
#CSSModules(styles, { allowMultiple: true })
export default class TheComponent extends Component {
render() {
const { deepNest, flex } = this.props
return (
<div>{ this.renderComp(deepNest, flex) }</div>
)
}
renderComp(deepNest, flex) {
const flexProperties = [
{ justifyContent: "center", alignItems: "center" },
{ justifyContent: "flex-start", alignItems: "flex-end" },
{ flexDirection: "row" }
]
const content = [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante."
]
if (deepNest > 0 && flex) {
return (
<div styleName="containerFlex" style={flexProperties[deepNest % 3]}>
<div styleName="contentFlex" style={flexProperties[deepNest % 3]}>
{ content[deepNest % 3] }
</div>
<div styleName="nestedFlex" style={flexProperties[deepNest % 3]}>
{ this.renderComp(deepNest - 1, flex) }
</div>
</div>
)
}
if (deepNest > 0 && !flex) {
return (
<div styleName="container">
<div styleName="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante.
</div>
<div styleName="nested">
{ this.renderComp(deepNest - 1, flex) }
</div>
</div>
)
}
}
}
WithFlex/index.js
import TheComponent from "../Component"
#CSSModules(styles, { allowMultiple: true })
export default class WithFlex extends Component {
constructor(props) {
super(props)
this.state = { render: false }
}
render() {
const {render} = this.state
// number of components to render
const arr = _.range(100)
return (
<div>
<div
style={{ display: "block", padding: 30, lineHeight: "60px" }}
onClick={() => this.setState({render: !render})}>
Start Render
</div>
{ render && arr.map((i) => <TheComponent key={i} deepNest={10} flex={true}/> ) }
</div>
)
}
}
WithoutFlex/index.js
import TheComponent from "../Component"
#CSSModules(styles, { allowMultiple: true })
export default class WithoutFlex extends Component {
constructor(props) {
super(props)
this.state = { render: false }
}
render() {
const {render} = this.state
// number of components to renders
const arr = _.range(100)
return (
<div>
<div
style={{ display: "block", padding: 30, lineHeight: "60px" }}
onClick={() => this.setState({render: !render})}>
Start Render
</div>
{ render && arr.map((i) => <TheComponent key={i} deepNest={10} flex={false}/> ) }
</div>
)
}
}
Results from Chrome dev-tool timeline.
WithFlex
WithoutFlex
Summary
The difference is not that much. Also in flexbox, I put random properties to choose from. So I think it's alright with the performance. Hope it will help other devs.
Old flexbox (display: box) is 2.3x slower than new flexbox (display: flex).
Regular block layout (non-float), will usually be as fast or faster than new flexbox since it’s always single-pass. But new flexbox should be faster than using tables or writing custom JS-base layout code.
For more info
Article1
Article2

how to do a wordpress link block?

does anyone have an idea on the css that would turn the following in to a linked block?
<div class="one_third">
<?php
//The Query
query_posts('posts_per_page=1&cat=15');
//The Loop
if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<h2><?php the_title(); ?></h2>
<small><?php the_time('F jS, Y') ?></small>
<?php if ( has_post_thumbnail()) the_post_thumbnail('medium-thumbnail'); ?>
<div class="entry">
<p><a style="display: block;" rel="bookmark" href="<?php the_permalink(); ?>"><?php echo strip_tags(get_the_excerpt());?></a></p>
Sorry, no posts matched your criteria.
Thanks
#Sotiris
Sorry for the late reply only get to work on this site after working hours.
<div class="one_third">
<h2>News Letters Suday test post</h2>
<small>May 15th, 2011</small>
<div class="thumbnail"><img width="190" height="140" src="http://localhost:8888/edinburghshiatsuclinic/wp-content/uploads/2011/05/front-page3-200x147.jpg" class="attachment-medium-thumbnail wp-post-image" alt="front-page3" title="front-page3" /></div> <div class="entry">
<p><a style="display: block;" rel="bookmark" href="http://localhost:8888/edinburghshiatsuclinic/news-offers/news-letters-suday-test-post/.">Suspendisse tempus semper dignissim. Pellentesque ac tempus ligula. Aenean eu nisi eu mi consequat vehicula venenatis et leo. Praesent ornare aliquam ultricies. Nunc justo tellus, varius quis viverra a, scelerisque non justo. Suspendisse leo turpis, elementum in dignissim sed, facilisis … Continue reading →</a></p>
</div>
</div>
Well, based on the code you posted, everything in the div is a link already. If you want clicking anywhere on the div to work like a link, you'll need to use Javascript--can't really wrap a block-level element (<div>) in an inline element (<a>).
Here is a jQuery way to do that:
$('#one_third').click(
function(){
$(this).find('h2 a').click();
});
It just says "when you click on the div with id 'one_third', look for the element 'h2 a' in it and trigger a click on that element. (I narrowed it down to just one of the links, if you didn't do that, if you just said ('a'), it would click all the links. Which could be interesting as well.)

Resources