I'm working on a react. The code below is an example. ArrayExample is mapped and returned to the div component. Whenever I click the mapped div component, I want to change the value of the top of div (position: 'absolute') and place it on the right side according to the mapped div topBorder. Is there a way? I want to move it smoothly like an animation.
import React from "react";
const sample = () => {
const arrayExample = ["AAAA", "BBBB", "CCCC"];
return (
<div
style={{
display: "flex",
flexDirection: "column",
width: "100%",
height: "500px",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f3f3f3",
}}
>
{arrayExample.map((v, i) => {
return (
<div
style={{
width: "50%",
padding: 50,
border: "1px solid black",
marginTop: 15,
}}
onClick={() => {
console.log("Event!")
}}
>
{v}
</div>
);
})}
<div style={{position: 'absolute', top: 70, right: '22%', backgroundColor: "#4285F4", width: 50, height: 150, borderRadius: 5}}>
moving screen(I want to Change top value)
</div>
</div>
);
};
export default sample;
On click of the item div, you need to figure out the distance of that div from the top, and then change the top css property of your right div according to that. To find this distance you can use offsetTop property. For animation you can use transition property. Here is the code:
import React, { useRef } from "react";
const Sample = () => {
const arrayExample = ["AAAA", "BBBB", "CCCC"];
const rightDiv = useRef();
const itemClickHandler = (i) => {
const newTopHeight = document.getElementById("container").children[i].offsetTop;
rightDiv.current.style.top = newTopHeight + 'px';
}
return (
<div
id="container"
style={{
display: "flex",
flexDirection: "column",
width: "100%",
height: "500px",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f3f3f3",
}}
>
{arrayExample.map((v, i) => {
return (
<div
key={i}
style={{
width: "50%",
padding: 50,
border: "1px solid black",
marginTop: 15,
}}
onClick={() => itemClickHandler(i)}
>
{v}
</div>
);
})}
<div
ref={rightDiv}
style={{
position: 'absolute',
top: 70,
right: '22%',
backgroundColor: "#4285F4",
width: 50,
height: 150,
borderRadius: 5,
transition: "top 0.5s ease-in-out"
}}>
moving screen(I want to Change top value)
</div>
</div>
);
};
export default Sample;
You can see this in action here: https://codesandbox.io/s/thirsty-curie-7mskj
In your click handler you can get the current position of the clicked div in px, you can easily google how to do this this (relative to the page, not the viewport). I would suggest storing this value in state, call it something like activeItemOffsetTop, then just set top to the current state
Related
I need to build horizontal progress bar with circle at the end in react js, as shown in picture. I am able to build progress bar with custom "%", now I want to add circle at the end with some text inside.
code for progress bar with custom "%":
codesandbox
Change progress bar component to:
<div style={containerStyles}>
<div style={fillerStyles}>
<div style={circleStyles}>{circleText}</div>
</div>
</div>
And add this styles to the component:
const circleStyles = {
display: "flex",
position: "absolute",
right: "0",
width: "50px",
height: "50px",
background: "blue",
top: "-60%",
borderRadius: "50px",
justifyContent: "center",
alignItems: "center",
color: "white"
};
And here's the App.js:
export default function App() {
return (
<div className="App">
<ProgressBar
bgcolor={item.bgcolor}
completed={item.completed}
circleText={"100%"}
/>
</div>
);
}
add a span under container div and put this style to it
<div style={containerStyles}>
<div style={fillerStyles}></div>
<span style={circleStyle}>{text}</span>
</div>
style
const circleStyle = {
height: 40,
width: 40,
position: "absolute",
right: 0,
backgroundColor: bgcolor,
borderRadius: "50%",
top: -10,
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "white"
};
and then put this to containerStyle
position: "relative",
I'm trying to position the FullWidthDiv component to span from the beginning of the MainDiv side, all the way to the end. I've tried giving in an absolute position and playing around with flex, but I can't get it to not start from the SubDiv component.
Is it possible to achieve this?
My CodeSandbox approach.
Here is what I'm trying to achieve
It is a little bit hacky, but you can center ChildDiv with align-items: center.
Also, shrink the FullWidthDiv to 280.
And last you have to add flex: 1, width: 100% to the div, that hold SubChildDiv inside App component.
export default function App() {
return (
<MainDiv>
<ChildDiv>
<div style={{flex: 1, width: '100%'}}>
<SubChildDiv />
<SubChildDiv />
</div>
<FullWidthDiv />
</ChildDiv>
</MainDiv>
);
}
const MainDiv = ({ children }) => (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: 250,
height: 250,
backgroundColor: "red",
padding: "1rem"
}}
>
{children}
</div>
);
const ChildDiv = ({ children }) => (
<div
style={{
width: 200,
height: 200,
backgroundColor: "blue",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "space-between"
}}
>
{children}
</div>
);
const SubChildDiv = () => (
<div
style={{
display: "flex",
width: "100%",
height: 30,
backgroundColor: "green",
border: "1px solid black"
}}
/>
);
const FullWidthDiv = () => (
<div
style={{
width: 280,
height: 30,
border: "1px solid black",
backgroundColor: "green"
}}
/>
);
If you want the FullWidthDiv to be with 100% width, you have to calculate the 100% width and add the padding from both sides of MainDiv it will look something like that: calc(100% + 2rem).
I have a div specified like this:
<button
style={{
padding: "0px",
background: "yellow",
position: "absolute",
left: `${seat.x}%`,
top: `${seat.y}%`,
width: `${squareSizePercentageX}%`,
paddingTop: `${squareSizePercentageX}%`
}}
key={index}
/>
seat.x and seat.y is always under 100. In spite of that div get outside of parent div.
This is how parent looks like:
<div
style={{
display: "flex",
maxWidth: `calc(calc(100vmin * ${aspectRatio})+200px)`
}}
>
<div style={{ width: `calc(100vmin * ${aspectRatio})` }}>
<div
style={{ paddingTop: `${100 / aspectRatio}%`, background: "pink" }} // <-- this is here the parent
>{listContent2}</div>
</div>
<div style={{ width: "200px", background: "yellow" }}>
</div>
</div>
Here all the code:
import React from "react";
import UPUjpestRendezvenyterLayout from "../assets/UPUjpestRendezvenyterLayout.json";
class SelectSeat extends React.Component {
render() {
const seats = UPUjpestRendezvenyterLayout.seats;
const squareSizePercentageX =
UPUjpestRendezvenyterLayout.squareSizePercentageX;
const aspectRatio = UPUjpestRendezvenyterLayout.aspectRatio;
let listContent2 = seats.map((seat, index) => {
return (
<button
style={{
padding: "0px",
background: "yellow",
position: "absolute",
left: `${seat.x}%`,
top: `${seat.y}%`,
width: `${squareSizePercentageX}%`,
paddingTop: `${squareSizePercentageX}%`
}}
key={index}
/>
);
});
return (
<div
style={{
display: "flex",
maxWidth: `calc(calc(100vmin * ${aspectRatio})+200px)`
}}
>
<div style={{ width: `calc(100vmin * ${aspectRatio})` }}>
<div
style={{ paddingTop: `${100 / aspectRatio}%`, background: "pink" }} // <-- this is here the parent
>{listContent2}</div>
</div>
<div style={{ width: "200px", background: "yellow" }}>
</div>
</div>
);
}
}
export default SelectSeat;
Here an image. Small yellow rectangle should be all inside pink area.
you need to set position: relative to parent div
try by giving Css flex-wrap: wrap; and position : relative and don't forget to set left and top to your parent div , these changes can fix your problem
On all but two pages of my site I would like the header to include two buttons. How can I make the header aware of this so it includes the buttons when needed and doesn't for the other two pages. I'm using React and Gatsby.
Could I accomplish this by adding if statements to my component? If so I'm not sure how to move beyond this step.
const isHomepage = pathname == `/`
const isContact = pathname == `/contact/`
let styles = {}
if (isHomepage) {
}
} else if (isContact) {
} else {
}
This is my code for the header:
import React from 'react'
import Link from 'gatsby-link'
import colors from '../utils/colors'
const Header = ({ siteTitle }) => (
<div
style={{
background: colors.white,
marginBottom: '1.45rem',
borderBottom: '1px solid',
borderBottomColor: colors.green,
height: '3rem',
top: 0,
left: 0,
width: '100%',
position: 'fixed',
}}
>
<div
style={{
paddingLeft: 20,
paddingRight: 20,
marginLeft: 'auto',
marginRight: 'auto',
maxWidth: 960,
}}
>
<div
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
height: 53,
}}>
<h3 style={{
margin: 0,
}}>
<Link
to="/"
style={{
color: colors.green,
textDecoration: 'none',
fontWeight: 450,
}}
>
{siteTitle}
</Link>
</h3>
</div>
</div>
</div>
)
export default Header
Use conditional rendering based on location.pathname
{['/path1', '/path2'].indexOf(location.pathname) === -1 && (
<button>1<button>
<button>2<button>
)}
import React from 'react'
import Link from 'gatsby-link'
import colors from '../utils/colors'
const Header = ({ siteTitle }) => (
<div
style={{
background: colors.white,
marginBottom: '1.45rem',
borderBottom: '1px solid',
borderBottomColor: colors.green,
height: '3rem',
top: 0,
left: 0,
width: '100%',
position: 'fixed',
}}
>
<div
style={{
paddingLeft: 20,
paddingRight: 20,
marginLeft: 'auto',
marginRight: 'auto',
maxWidth: 960,
}}
>
<div
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
height: 53,
}}>
<h3 style={{
margin: 0,
}}>
<Link
to="/"
style={{
color: colors.green,
textDecoration: 'none',
fontWeight: 450,
}}
>
{siteTitle}
</Link>
{['/path1', '/path2'].indexOf(location.pathname) === -1 && (
<button>1<button>
<button>2<button>
)}
</h3>
</div>
</div>
</div>
)
export default Header
I’m having trouble aligning two components within another div in React. I’m using relative positioning for the parent div (snippetButtonHolder) and absolute positioning for its children (snippet and button). I want snippet to be centered in the parent and button to be under snippet and to the right, but for some reason when I use these attributes they are positioned relative to the entire page, not to the parent div. Does anyone have a suggestion as to what I should do differently?
const styles = {
module: {
marginTop: '30px',
padding: '20px',
},
snippet: {
backgroundColor: '#f2f2f2',
border: 'solid 1px #ccc',
borderRadius: '4px',
margin: '0 auto',
padding: '10px',
width: '100%',
position: 'absolute',
left: '50%',
},
snippetButtonHolder: {
width: '95%',
position: 'relative',
},
button: {
float: 'right',
marginTop: '5px',
position: 'absolute',
left: '94%',
},
};
export default class CodeSnippet extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div style={styles.module}>
<div style={styles.snippetButtonHolder}>
<div style={styles.snippet}>
<div
{'text will go here'}
</div>
{this.state.showButton ?
<button
style={styles.button}>
Press me
</button>
: null}
</div>
</div>
</div>
);
}
}
Give this a try:
const styles = {
module: {
marginTop: '30px',
padding: '20px',
},
snippet: {
backgroundColor: '#f2f2f2',
border: 'solid 1px #ccc',
borderRadius: '4px',
display: 'inline-block',
overflow: 'hidden',
padding: '10px',
},
snippetButtonHolder: {
textAlign: 'center',
width: '95%',
},
button: {
float: 'right',
marginTop: '5px',
},
};