How to put one div onto another with transition? - javascript

I want to create something such that, depending on the state, a given div appears overlapping another div from the right side, here is my code:
const [loggedIn, setLoggedIn] = useState<boolean>(false);
const [hasConfirmedAccount, setHasConfirmedAccount] = useState<boolean>(false);
return (
<>
<div style={{ width: "100%" }}>
<div style={{ float: "left", width: "50%" }}>
<div
style={{ width: "100%", height: "100vh", backgroundColor: "#fafafafa" }}
></div>
</div>
<div id='notLoggedIn' style={{ float: "right", width: "50%" }}>
{!loggedIn && (
<div>
WHEN LOGGED IN === TRUE
</div>
)}
<div
style={
loggedIn && !hasConfirmedAccount
? { width: "100%", transition: "ease-in-out 5s" }
: { display: "none" }
}
>
<div id="notConfirmedAccount">WHENE LOGGED IN === TRUE AND hasConfirmedAccount === FALSE</div>
</div>
</div>
</div>
</>
);
The code works fine, when loggedIn === true and hasConfirmedAccount === false div with id = notConfirmedAccount has been displayed instead of div with id=notLoggedIn, but displaying this div does not work flowing, I want a slow leaving effect of the div on the right side that would overlap the previous div
can someone tell me what to do this?
thanks for any help!

install animate.css => $ npm install animate.css --save
animate.css
2.import "./animate.css" at top your component or project
3.just put the name of aniamte on className like this pattern in your div
<div className={style.forgot} className='animate__animated animate__fadeInDown'>
also you should control your showing div with state

Use React animation Add-Ons ReactTransitionGroup and ReactCSSTransitionGroup
The ReactTransitionGroup add-on component is a low-level API for animation, and ReactCSSTransitionGroup is an add-on component for easily implementing basic CSS animations and transitions.
https://reactjs.org/docs/animation.html

Related

MUI x-data-grid documentation example never works as expected

I am implementing the exact same code shown in the material-ui library documentation here
https://mui.com/x/react-data-grid/layout/#flex-layout
I am trying to implement the flex layout,
I just did the exact same steps and the console shows the error all the time:
Sandbox:
https://stackblitz.com/edit/react-8ahs3n?file=src/App.js
Please help, appreciated.
In the documentation example you linked to there is one additional div wrapping what you have in your code: <div style={{ height: 400, width: '100%' }}>. Including that wrapper element (which gives the element an intrinsic height as mentioned in the console warning) gets rid of the console error. Here's a modified version of your stackblitz that does not have the error: https://stackblitz.com/edit/react-m2uoq1?file=src%2FApp.js.
The 400px height in the documentation example can be replaced by whatever height you want -- it just can't be percent-based. If you want the DataGrid to be the full height of the browser, you can use 100vh instead of 100%.
Here's an example:
import * as React from "react";
import { DataGrid } from "#mui/x-data-grid";
import { useDemoData } from "#mui/x-data-grid-generator";
import CssBaseline from "#mui/material/CssBaseline";
export default function FlexLayoutGrid() {
const { data } = useDemoData({
dataSet: "Commodity",
rowLength: 50,
maxColumns: 6
});
return (
<>
<CssBaseline />
<div style={{ height: "100vh", width: "100%" }}>
<div style={{ display: "flex", height: "100%" }}>
<div style={{ flexGrow: 1 }}>
<DataGrid {...data} />
</div>
</div>
</div>
</>
);
}
In my example I included the CssBaseline component in order to get rid of the default 8px margin on the <body> element -- otherwise using 100vh will cause a scroll bar to appear; however the default margin (or a custom margin in your app) can be accounted for in other ways by using calc (e.g. height: "calc(100vh - 16px)").
Use a wrapper component such as Box from Material UI with flex display and height:
<div style={{ height: 400, width: '100%' }}>
<Box style={{
display: "flex",
height:400,
justifyContent: "center",
alignItems: "center"
}}
>
<Datagrid/>
</Box>
</div>

(Some) buttons not working in initially hidden div

I'm building a wordpress block using react (in the frontend).
The block will initially fetch a list from a server, then display the list using map.
For each item, it will render a header, like so:
As you can see, you can click a header and the content shows up. This content is build in the same map and they have their max-height and opacity set to 0 to hide them. I'm using those properties instead of just display: none, because I can CSS-transition them and it looks smoother. I had to blur the content, but you get the idea.
However, in some of the content-divs, the buttons are not working. The links-stlyed-as-buttons (the music services on the left) do not behave as links, although they have their href set in the markup. The hover effects do not work either, the cursor does not become the pointy finger and they are not clickable.
A div styled as a play-button has the same issues: in eventListeners I can see the onClick being listened for, but the button is not clickable, has no hover, etc.
One noteable thing is: it's not all list entries behaving this way. And if one list entry with broken buttons is open, and you open another content section with working buttons, the broken buttons will magically start working. If you then close the content section with working buttons, the formerly broken ones are broken again.
Honestly, this feels like my code is haunted.
Please note: because the length and content of the list is not entirely known, I have to use generated IDs and generated getElementByID-queries to interact with the items and can't define states for them (at least I couldn't think of a way to dynamically create states).
React:
//...
//releases is useState([]) of an object with metadata of songs
//comes from a database query, so the columns are known
{releases.map(release => {return(
<div key={release.catalogue_index} style={{marginTop: "8px"}}>
{/*This is the "header", shown in the screenshot*/}
<div className="layout-row" style={{backgroundColor: "#111", padding: "8px", marginTop: "4px", position: "relative"}} onClick={(event) => {
document.getElementById(`${release.catalogue_index}-content`).classList.toggle('open');
}}>
<div stlye={{flexGrow: 1}} className="layout-stack">
{/* here the title and some information is displayed*/}
</div>
</div>
{/*The content you can show (second screenshot)*/}
<div className="release-content" id={`${release.catalogue_index}-content`}>
{/*layout-stack and layout-row are just flex containers with different directions*/}
<div className="layout-row">
<img loading="lazy" alt={`${release.title} cover`} src={/*cover.jpg*/}
className="release-cover" />
<div className="layout-stack">
<div>{/*some metadata*/}</div>
<hr />
{release.short_description}
<div style={{height: "16px"}} />
<div className="layout-row">
{/*those are the link buttons sometimes not working*/}
{/*the whole thing only gets displayed if any link got fetched from the database*/}
{(release.link_bandcamp || release.link_youtube || release.link_spotify || release.link_apple) ?
<div className="layout-row">
<p className="link-caret"><strong>></strong></p>
<ul className="is-content-justification-center is-layout-flex wp-container-9 wp-block-social-links has-icon-color has-icon-background-color featured-social-group" style={{margin: 0}}>
{release.link_bandcamp ?
<li style={{color: "#fff", backgroundColor: "#888"}} className="wp-social-link wp-social-link-bandcamp wp-block-social-link wp-custom-social">
<a target="_blank" href={release.link_bandcamp} className="wp-block-social-link-anchor" rel="noopener"><img className="svgbutton" src={/*some-logo.svg*/} />
<span className="wp-block-social-link-label screen-reader-text">Bandcamp</span></a></li>
: null}
{release.link_youtube ?
<li style={{color: "#fff", backgroundColor: "#888"}} className="wp-social-link wp-social-link-youtube wp-block-social-link wp-custom-social">
<a target="_blank" href={release.link_youtube} className="wp-block-social-link-anchor" rel="noopener"><img className="svgbutton" src={/*some-logo.svg*/} />
<span className="wp-block-social-link-label screen-reader-text">Youtube</span></a></li>
: null}
{release.link_spotify ?
<li style={{color: "#fff", backgroundColor: "#888"}} className="wp-social-link wp-social-link-spotify wp-block-social-link wp-custom-social">
<a target="_blank" href={release.link_spotify} className="wp-block-social-link-anchor" rel="noopener"><img className="svgbutton" src={/*some-logo.svg*/} />
<span className="wp-block-social-link-label screen-reader-text">Spotify</span></a></li>
: null}
{release.link_apple ?
<li style={{color: "#fff", backgroundColor: "#888"}} className="wp-social-link wp-social-link-chain wp-block-social-link wp-custom-social">
<a target="_blank" href={release.link_apple} className="wp-block-social-link-anchor" rel="noopener"><img className="svgbutton" src={/*some-logo.svg*/} />
<span className="wp-block-social-link-label screen-reader-text">Apple Music</span></a></li>
: null}
</ul>
</div> : null}
<audio id={`audio-${release.catalogue_index}`} preload="none"
onEnded={() => {document.getElementById(`audio-seek-${release.catalogue_index}`).value = 0}}
onLoadedMetadata={() => document.getElementById(`audio-seek-${release.catalogue_index}`).max = document.getElementById(`audio-${release.catalogue_index}`).duration}
onTimeUpdate={() => document.getElementById(`audio-seek-${release.catalogue_index}`).value = Math.floor(document.getElementById(`audio-${release.catalogue_index}`).currentTime)}>
<source src={/*REDACTED*/} type="audio/mpeg" />
Your browser does not support audio.
</audio>
<div className="layout-row" style={{alignItems: "center"}}>
{/*this is the play button sometimes acting up*/}
<div className="play-pause wp-block-button"
onClick={() => {togglePlayPause(release.catalogue_index)}}>
<img id={`audio-button-${release.catalogue_index}`} className="play-pause svgbutton wp-block-button__link wp-element-button" src={/*play-svg*/} />
</div>
<input type="range" id={`audio-seek-${release.catalogue_index}`} className="audio-seek" max={100} value={0} />
</div>
</div>
</div>
</div>
<div style={{height: "16px"}} />
<div className="layout-stack">
{/*some flavor text*/}
</div>
</div>
</div>
)})}
CSS:
//...
.release-content {
max-height: 0vh;
opacity: 0;
transition: max-height 0.3s;
transition: opacity 0.3s;
}
.release-content.open {
opacity: 1;
height: fit-content;
padding: 16px;
max-height: 100vh;
}
.svgbutton {
color: currentColor;
fill: currentColor;
width: 1em;
height: 1em;
}
div.play-pause {
margin-left: 36px !important;
height: 38px;
}
img.play-pause {
box-sizing: unset !important;
margin-top: 0 !important;
}
//...
The only thing I could think of was that maybe the wordpress-classes ("wp-...") would somehow break ... but that doesn't make much sense, as some of the the list entries work fine while others don't - all using those same classes.
Based on RubenSmn's comment, I had to realize that I did not plan my code well and built terrible anti-patterns.
I have refactored the code to not map into all that markup, but a separate <Release /> component, which in turn contains the markup.
{releases.map(release => {return(
<ReleaseComponent key={release.catalogue_index} release={release} />
)})}
The new component was then built to not use classList.toggle, but proper React states to show and hide the content panels. Also the document.getElementByID-queries are gone and replaced by proper React refs.
const ReleaseComponent = (props) => {
const contentDiv = useRef(null);
const audioElement = useRef(null);
const audioButton = useRef(null);
const audioSeek = useRef(null);
const [contentOpen, setContentOpen] = useState(false);
//...
return(
//...
<div className="release-content" ref={contentDiv} hidden={!contentOpen}>
//...
Turns out, if you do things right, they actually work... This was a pretty humbling experience. Thank you, #RubenSmn .

How can I position button dynamatically according to page components?

In React application I am displaying list of images. When individual book is removed Hide Books button takes the place to that component.
What I am trying to achieve is Hide Books button should remain at the same position and should dynamatically change its position on y axis if whole row of books is deleted
Initial state of application
When individual book is removed -
app.js
return(
<div style={{ position: "relative", minHeight: "100vh" }}>
<button
style={{
position: "absolute",
bottom: "",
}}
onClick={clearBooks}
>
Hide Books
</button>
</div>
)
could you share more of your code? maybe have a codesandox example? It seems to be a styling issue but it's hard to tell without more code.
-edit-
your button should be separated from your list of books, this is the reason why it essentially "follows" your last book card.
Try to do something like this
return (
<section className='wrapper'>
<div className='bookList'>
{booksData.map(book => {
//code your books here
}
</div>
//then put your button out of the div
<button onClick={function}>hide books</button>
</section>
)
your CSS for the wrapper div could be something like this
.wrapper{
display: flex;
flex-direction: column
}
this way you'll have the books first then the button will be displayed below the list
Place the button as the next sibling to the section of Books. Shown in the following. All I did was to move the button out of the section. You will have to style the button with padding and such for the updated layout.
// in index.js, BookList
return (
<>
<section className="booklist">
{booksData.map((book, index) => {
return (
<Book
key={index}
{...book}
removeIndividualBook={removeIndividualBook}
></Book>
);
})}
</section>
{booksData.length === 0 ? (
<button onClick={handleShowBook}>Show Books</button>
) : (
<div style={{ position: "relative", minHeight: "100vh" }}>
<button
style={{
// position: "absolute",
// marginTop: "2350px",
// marginLeft: "28px",
position: "absolute",
//left: "12%",
bottom: "",
}}
onClick={clearBooks}
>
Hide Books
</button>
</div>
)}
</>
);

How to implement react-particles-js with anchor links?

Using react-particles-js
as a background on a React project, I discover that disables the anchor tag, don't know if its my implementation
const App = () => {
return (
<div className="App" style={{ position: "relative", overflow: "hidden" }}>
<div style={{ position: "absolute" }}>
<Particles height="330vh" width="100vw" params={particlesConfig} />
</div>
<Home /> {/*this is the content */}
</div>
);
};
What it happens its that in this component with link like this
<a
href="https://tienda-de-garage.herokuapp.com/"
style={{ textDecoration: "none", color: "black" }}
>
<p>Tienda de Garage</p>
</a>
Don't work.
I wonder if its the implementation, maybe the use of the view port the increase the size of the area to encompass the background but i'm not sure.
here its a live version, with the 1 link not working to show the issue
You need to set interactivity.detectsOn to window (InteractivityDetect.window or "window")
You can see a working sample here
This sample uses react-tsparticles but it's the same as react-particles-js since they share the same core library tsparticles

Changing the order of Components in React depending on a variable?

I have a React Component which is rendered by this map function:
<div className="links-container">
{links.map((link, i) => (
<Links
key={link.text}
icon={link.icon}
text={link.text}
isRight={i % 2 === 0 ? true : false}
/>
))}
</div>
import React, { Component } from "react";
export default class Links extends Component {
render() {
const { icon, text, isRight } = this.props;
return (
<div style={{ alignSelf: isRight ? "flex-end" : "" }}>
<div className="link">
<img
className="link-img"
src={icon}
alt="link"
style={{ borderColor: isRight ? "#1689FC" : "#FD003A" }}
/>
<div className="link-text">{text}</div>
</div>
</div>
);
}
}
And what I want to do is, if the isRight is true, I want to render the text first and then the img, if isRight is false, I want to render the image and then the text. Now, I am aware that I could wrap this thing in a big if statement like this:
isRight ? <div><text/><img/></div> : <div><img/><text/></div>
But I am wondering if there's a better way to do this because my approach uses repetitive code, which is the reason why I have this Links Component in the first place.
You can use display:flex and flex-direction property on <div className="link">
flex-direction: row-reverse or flex-direction: column-reverse depending on your layout.
Try using this single line of code: flex-direction: row-reverse

Categories

Resources