How to override one page over other in Reactjs? - javascript

I want to create pages which can override over another pages in React. Like see for an example here in Youtube: https://youtu.be/n5kr99DAjDk?t=441. The 'Post' page is opened with full height and a 'Back' button. This was easily possible in React Native. How could it be done in React for web.
Below is the code for reference:
App.js
const Routing = () => {
return (
<Router>
<TopNavbar />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/newPage" component={NewPage} />
</Switch>
<BottomNavbar />
</Router>
);
};
Home.js
const Home = () => {
return (
<div style={{ marginTop: "80px", position:'relative' }}>
<h2>Home Page</h2>
<Link to="/newPage">
<button>Click Here</button>
</Link>
</div>
);
};
export default Home;
NewPage.js
const NewPage = () => {
return (
<div className="newPageCSS">
<h2>New Page</h2>
</div>
);
};
export default NewPage;
NewPage.css
.newPageCSS {
margin-top: 80px;
position: absolute;
top:0;
left: 0;
}
I have tried position:absolute in NewPage but, no use. What could be best possible solution?
Please have a look at the given below codesandbox link for clarity of code.
Here is the codesandbox link: https://codesandbox.io/s/react-material-forked-9dodd

It sounds like you'd like your new page component to take up all the room of the page except for top and bottom navigation.
The solution is entirely CSS, however you'll need to tinker with styles to get margins/padding correct. It looks like you're using a UI library which can clash with your style sheet.
Here are the changes:
Update your main container to use flexbox instead of trying to control for top/bottom navs with pixels
#root {
display: flex;
min-height: 100vh;
flex-direction: column;
}
Then, get your new page component to expand by adding a flex 1. Added red border to easily visualize change.
.newPageCSS {
margin-top: 80px;
border: 2px solid red;
flex: 1;
}
Update your home page so bottom nav sticks to bottom and you can scroll home content
.homePageCSS {
margin-top: 80px;
max-height: 50%;
/* position: relative; */
flex: 1;
max-height: 70vh;
overflow: auto;
}
Position fixed is now unnecessary for bottom nav
.makeStyles-gridList-2 {
width: 100%;
border: 1px solid grey;
/* bottom: 0px; */
/* position: fixed; */
padding: 0;
flex-wrap: nowrap;
background: white;
}

Related

Why is my Swiper render buggy at the first time render using React

I'm using React and trying to fetch some of my anime into the home banner using Swiper
I don't know why when I refresh my page, it'll only render at half of the swiper.
Here's how it display:
However, if I press the next or back button, it'll display normally again.
Here's my code in my Home Component:
import { useState, useEffect } from "react"
import ReactHlsPlayer from 'react-hls-player';
import './home.css'
import { supabase } from '../../supabaseClient'
import { Swiper, SwiperSlide } from 'swiper/react'
import SwiperCore, { Pagination,Navigation } from 'swiper';
import 'swiper/css'
SwiperCore.use([Pagination,Navigation]);
function Home(){
useEffect(async ()=>{
fetchAnime()
}, [])
const [animeDetail, setAnimeDetail] = useState([])
async function fetchAnime() {
const { data } = await supabase
.from ('anime')
.select ()
setAnimeDetail(data)
}
return (
<>
<div className="spacer">
</div>
<div className="home-section">
<h2>Home Page</h2>
<Swiper
centeredSlides={true}
slidesPerView={7}
spaceBetween={10}
loop={true}
pagination={false}
navigation={true} className="mySwiper">
{animeDetail.map((element, i)=>
(
<SwiperSlide key = {i}><img src={element.anime_image}/></SwiperSlide>
)
)}
</Swiper>
</div>
</>
)
}
export default Home
And here's my Home CSS, sorry if it's a bit messy, I'm still trying it here and there, but I'm stuck.
.swiper {
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
}
.swiper-wrapper{
width: 100%
}
.swiper-slide {
text-align: center;
font-size: 18px;
display: flex;
justify-content: center;
align-items: center;
max-width: 280px;
}
.swiper-slide img {
display: block;
box-sizing: border-box;
border: none;
max-height: 350px;
min-height: 350px;
-o-object-fit: cover;
object-fit: cover;
transition: all .3s ease;
opacity: 0.5
}
.swiper-slide-active {
transform: scale(1.2);
z-index: 2
}
.swiper-slide-active img{
transition: all .3 ease;
opacity: 1
}
And if someone figures it out, please help me a bit, I tried to whenever the item in the middle is in active, it'll pop out bigger, but I can't do it with transform: scale(number) - I have tried it (It does get bigger when it's active but it doesn't display bigger at the height, I haven't figured it out some ways at the moment)
you have to set the initialSlide prop on the Swiper element to an index of the slide in the middle. so that the slider starts from there.
Also in this case, you can set the centeredSlides prop to true as the active slide remains in the middle.
Here's a possible fix for your issue and for everyone else that comes here looking for answers.
Use conditional rendering of the Swiper component, something like this:
{animeDetail.length>0 && <Swiper
centeredSlides={true}
slidesPerView={7}
spaceBetween={10}
loop={true}
pagination={false}
navigation={true} className="mySwiper">
{animeDetail.map((element, i)=>
(
<SwiperSlide key = {i}><img src={element.anime_image}/></SwiperSlide>
)
)}
</Swiper>}

How to fix position of one element in a flexbox?

I have 2 boxes: Panel and Sidebar, in a flexbox, with flex-direction: row and justify-content: space-between I am able to horizontally align them side by side with a gap in the middle.
Now I'd like to fix the right Sidebar position, i.e. when scrolling down, the Sidebar should always stay on top of the screen, regardless of the location of Panel. How can I do it with CSS?
Working example here: https://codesandbox.io/s/gallant-saha-zgmnw
Code here:
App.js:
import React from "react";
import "./App.scss";
import Panel from "./Panel";
import Sidebar from "./Sidebar";
export default function App() {
return (
<div className="App">
<Panel />
<Sidebar />
</div>
);
}
App.scss:
.App {
width: 1100px;
font-family: sans-serif;
text-align: center;
display: flex;
flex-direction: row;
justify-content: space-between;
}
Panel.js:
import React from "react";
import "./Panel.scss";
const Panel = () => {
return (
<>
<div className="panel">The main panel</div>
</>
);
};
export default Panel;
Sidebar.js:
import React from "react";
import "./Sidebar.scss";
const Sidebar = () => {
return (
<>
<div className="sidebar">The sidebar</div>
</>
);
};
export default Sidebar;
I modified your siderbar css.
I used position fixed as this will make the sidebar fixed in the viewport so as you scroll it will remain static.
.sidebar {
position: fixed; /* add this */
width: 200px;
height: 200px;
text-align: center;
border: 1px black solid;
left: 906px /* add this */
}
This produces the desired effect. Tested and works. Apologies, I have updated my answer.
add this css to .sidebar
position:fixed;
right: 10px;
also, you can add:
top: -- px
if you have Navbar.

How can I overlay an icon on the top right corner of image?

Stack:
React
Relevant Package: FontAwesome => 'fortawesome'
Relevant Package: React Bootstrap => 'react-bootstrap'
What I currently have:
I am building a profile page and I would like users to be able to remove social media links with an "x" button.
This is my current code:
<React.Fragment>
<a href={social_item.url} key={social_item.id}>
<Image
className='m-2 shadow-sm'
width='32px'
src={
'https://www.google.com/s2/favicons?sz=128&domain_url=' +
social_item.url
}
rounded
/>
<FontAwesomeIcon
color='grey'
className='fa-stack the-wrapper'
icon={faTimes}
/>
</a>
</React.Fragment>
I know that when you are using two FontAwesome images you can overlay them using fa-stack. In this case, I am trying to overlay the "x" to the top right corner of the social media image.
My ideal outcome is something along these lines:
I have tried fa-stack but it does not appear to work when using icons in conjunction with images.
Any advice would be appreciated!
import React from "react";
const Icon = () => (
<React.Fragment>
<a alt="" href="" className="block-icon">
<Image
className="m-2 shadow-sm"
width="32px"
src={
"https://www.google.com/s2/favicons?sz=64&domain_url=yahoo.com"
}
rounded
/>
<FontAwesomeIcon
color="grey"
className="fa-stack the-wrapper icon-tag"
icon={faTimes}
/>
</a>
</React.Fragment>
);
export default Icon;
/* css */
.block-icon {
position: relative;
display: inline-flex;
}
.icon-tag {
position: absolute;
position: absolute;
top: 0;
right: 0;
z-index: 1;
width: 12px !important;
height: 12px !important;
}
You may not make width with the !important option but then svg close will take all the heights of the Image component in which case you should change top and right.
It gives something like this.
Making the link a a relative positioned block with "x" absolute positioned will work, like so:
a {
display: inline-block;
position: relative;
}
a .image {
display: block;
width: 25px;
height: 25px;
background-color: #f0f;
}
a .icon {
position: absolute;
right: 0;
top: 0;
line-height: 0;
}
<a>
<span class="image"> </span>
<span class="icon">x</span>
</a>

Changing elements (like fixed logo) color, depending on the section in React

I want to achieve an effect like this one
in a React webpage but without using jQuery. I've looked for alternatives to that library, but without results. I've seen a lot of similar questions, but each of them are answered using jQuery.
The effect is basically changing the color of the logo (and other elements in the page) as I scroll down through different sections.
Does anyone know a way to achieve this?
A way this could be done is by centering the logo's to their own containers dynamically, kinda like simulating position fixed, but using position absolute, so each logo is contained in their own section, and not globally like position fixed would do.
This way when you scroll to the next section, the second section covers the first section making it look like its transitioning.
I created a proof of concept here:
https://codesandbox.io/s/9k4o3zoo
NOTE: this demo is a proof of concept, it could be improved in performance by using something like request animation frame, and throttling.
Code:
class App extends React.Component {
state = {};
handleScroll = e => {
if (!this.logo1) return;
const pageY = e.pageY;
// 600 is the height of each section
this.setState(prevState => ({
y: Math.abs(pageY),
y2: Math.abs(pageY) - 600
}));
};
componentDidMount() {
window.addEventListener("scroll", this.handleScroll);
}
render() {
const { y, y2 } = this.state;
return (
<div>
<section className="first">
<h1
className="logo"
style={{ transform: `translateY(${y}px)` }}
ref={logo => {
this.logo1 = logo;
}}
>
YOUR LOGO
</h1>
</section>
<section className="second">
<h1
className="logo"
style={{ transform: `translateY(${y2}px)` }}
ref={logo => {
this.logo2 = logo;
}}
>
YOUR LOGO
</h1>
</section>
</div>
);
}
}
CSS would be:
section {
height: 600px;
width: 100%;
position: relative;
font-family: helvetica, arial;
font-size: 25px;
overflow: hidden;
}
.first {
background: salmon;
z-index: 1;
}
.first .logo {
color: black;
}
.second {
background: royalBlue;
z-index: 2;
}
.second .logo {
color: red;
}
.logo {
position: absolute;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 230px;
height: 30px;
}

Resizing a React navigation bar component when width is reduced?

I have a navigation bar for my webapp with the following css setup:
.navigation {
background: white;
display: flex;
height: 5em;
align-items: center;
padding: 0px 2em;
color: blue;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.075em;
border-bottom: 1px solid #E6E6E6;}
My issue is on mobile, my tabs in the navigation bar get all squeezed together. Is there a way in React that I can detect the width of the page and collapse all my navigation tabs into a dropdown menu? Or is this a CSS thing?
You could handle this in CSS, using proper media queries.
But if you prefer to do it with React, here is how you can implement it, listening to the window "resize" event:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
layoutMode: this.getLayoutMode(),
};
this.onResize = this.onResize.bind(this);
}
componentDidMount() {
window.addEventListener('resize', this.onResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.onResize);
}
onResize() {
this.setState({
layoutMode: this.getLayoutMode(),
});
}
getLayoutMode() {
return window.innerWidth > 1000 ?
'desktop'
: 'mobile';
}
render() {
return this.state.layoutMode === 'desktop' ? (
<NavigationBar />
) : (
<DropdownMenu />
);
}
}
Seriously, your best option is css. Let react focus on the structure of your DOM and on the interaction. Let css take care of styling.
So you can keep your react code simple like this:
render() {
var myMenu = ['Home','Settings','About us', 'Other stuff'];
return (
<div>
<button className='hamburger'>m</button>
<ul className='menu'>
{myMenu.map(item => {
return <MenuItem key={item} text={item}/>
})}
</ul>
</div>
);
}
And do the styling stuff in css (code below with Sass):
ul.menu
position: absolute
display: flex
flex-direction: row
width: 100%
li.menu-item
flex: 1 0 auto
padding: 10px
margin: 2px
background-color: grey
text-align: center
li.menu-item:hover
background-color: blue
button.hamburger
display: none
padding: 10px
margin: 2px
background-color: grey
#media screen and (max-width : 760px)
ul.menu
flex-direction: column
display: none
li.menu-item
background-color: orange
button.hamburger
display: block
position: absolute
button.hamburger:focus + ul.menu
display: flex
You can find a working demo in codepen here.
If you want to render a drop-down menu on mobile, here's one strategy:
Listen for media query changes in React: http://krasimirtsonev.com/blog/article/Using-media-queries-in-JavaScript-AbsurdJS-edition.
Use that listener to update this.state on the component (ex: this.state.isMobile).
Render different Navigation components based on the media query conditional (ex: this.state.isMobile ? <Navigation type="mobile" /> : <Navigation type="desktop" />).

Categories