Get ID of fully visible component - javascript

I tried to make code showing the number of component which is currently fully visible.
I used Intersection Observer API and to make it, used callback entry.intersectionRatio === 1.0.
I want to remark currently fully visible component at state currentView but it doesn't show anything.
I think currentView is not changed, althought I use useEffect
May I know which part is wrong and how to fix it??
code :
import styled from "styled-components";
import { useState, useEffect } from "react";
export default function App() {
const [currentView, setCurrentView] = useState();
useEffect(() => {
const components = document.querySelectorAll(".comp");
const componentObserver = new IntersectionObserver(function (
entries,
observer
) {
entries.forEach(function (entry) {
if (entry.isIntersecting && entry.intersectionRatio === 1.0) {
setCurrentView(entry.target.id);
}
});
});
components.forEach((comp) => {
componentObserver.observe(comp);
});
}, [currentView, setCurrentView]);
return (
<Wrap>
<div className="fixed">currentcomponent : {currentView}</div>
<div id="part-1" className="compo1 comp">
components 1
</div>
<div id="part-2" className="compo2 comp">
components 2
</div>
<div id="part-3" className="compo3 comp">
components 3
</div>
</Wrap>
);
}
const Wrap = styled.div`
border: 3px solid black;
width: 100vw;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
.fixed {
position: sticky;
top: 0;
}
.compo1 {
border: 3px solid red;
display: flex;
justify-content: center;
align-items: center;
width: 90vw;
height: 90vh;
}
.compo2 {
border: 3px solid blue;
display: flex;
justify-content: center;
align-items: center;
width: 90vw;
height: 90vh;
}
.compo3 {
border: 3px solid green;
display: flex;
justify-content: center;
align-items: center;
width: 90vw;
height: 90vh;
}
`;
CodeSandBox :
CodeSandBox

Related

React Redux Image Wont load

So this could honestly be as simple as just over looking it and staring for so long and being new to react but on my section component I'm loading in my backgroundImg prop wont load the image and I cant figure it out. My pictures are in the public folder and my code is in the src components folder
Also, I can get images to load in the file just not when I'm calling them through prop
Home.js This is where I am calling my component and trying to load the file in through the prop type
import React from 'react'
import styled from 'styled-components'
import Section from './Section'
function Home() {
return (
<Container>
<Section
title="Model S"
description="Order Online for Touchless Delivery"
backgroundImg='/public/pictures/model-s.jpg'
leftBtnText="Custom Order"
rightBtnText="Existing Inventory"
/>
<Section
title="Model E"
description="Order Online for Touchless Delivery"
backgroundImg=".\Pictures\model-e.jpg"
leftBtnText="Custom Order"
rightBtnText="Existing Inventory"
/>
<Section />
<Section />
</Container>
)
}
export default Home
//Home and styled help you stlye the component without using css
const Container = styled.div`
height: 100vh;
`
Section.js The component for the Screen
import React from 'react'
import styled from 'styled-components'
//props are just parameters you can set when calling the component
function Section(props) {
return (
<Wrap bgImg={props.backgroundImg}>
<ItemText>
<h1>{props.title}</h1>
<p>{props.description}</p>
</ItemText>
<Buttons>
<ButtonGroup>
<LeftButton>
{props.leftBtnText}
</LeftButton>
<RightButton>
{props.rightBtnText}
</RightButton>
</ButtonGroup>
<DownArrow src='/Pictures/down-arrow.svg' />
</Buttons>
</Wrap>
)
}
export default Section
const Wrap = styled.div`
width: 100vw;
height: 100vh;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
`
const ItemText = styled.div`
padding-top: 15vh;
text-align: center;
`
const ButtonGroup = styled.div`
display: flex;
margin-bottom: 30px;
#media (max-width: 786px){
flex-direction: column;
}
`
const LeftButton = styled.div`
background-color: rgba(23, 26, 32, 0.8);
height: 40px;
width: 256px;
color: white;
display: flex;
justify-content: center;
align-items: center;
border-radius: 100px;
opacity: 0.85;
text-transform: uppercase;
font-size: 12px;
cursor: pointer;
margin: 8px;
`
const RightButton = styled(LeftButton)`
background: white;
opacity: 0.65;
color: black;
`
const DownArrow = styled.img`
margin-top: 20px;
height: 40px;
overflow-x: hidden;
animation: animateDown infinite 1.5s;
`
const Buttons = styled.div`
`
Thanks for the help.
I haven't tested this, but it looks like you didn't use the Wrap bgImg prop in the styled component. There is background-size, background-position, background-repeat, but not background-image using the prop.
Example:
background-image: ${props => props.bgImg || ''};
https://styled-components.com/docs/basics#passed-props

Styled components cause react-dom.production.min.js:4482 Error: Minified React error #31;

Styled components cause build crash
Guys, I have a problem with styled components ;/.
I'm using create-react-app and everything works fine until I "npm run build" and deploy the app on my FTP.
I keep getting this weird error and have not found any solution online. My code is attached below. Should be plain and simple.
Any ideas?
import styled from 'styled-components';
import countriesJSON from './countries.json';
const Container = styled.div`
max-width: 1200px;
margin: 0 auto;
`;
const Wrapper = styled.div`
display: flex;
flex-direction: column;
height: 100vh;
justify-content: center;
align-items: center;
`;
const Button = styled.button`
background: whitesmoke;
border-radius: 3px;
height: 5vh;
width: 20vw;
border: 2px solid orange;
color: 'slategrey';
margin: 0 1em;
padding: 0.25em 1em;
&:hover {
background: whitesmoke;
transform: scale(1.2);
`;
const Text = styled.h1`
font-size: calc(2vw + 10px);
font-weight: bold;
text-align: center;
color: whitesmoke;
`;
const Paragraph = styled.p`
color: whitesmoke;
font-size: calc(1vw + 10px);
`;
const CountryWrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
#media (min-width: 600px) {
flex-direction: row;
}
`;
const CountryDetailsWrapper = styled.div`
margin: 10px;
text-align: center;
`;
const CountryImgWrapper = styled.div`
img {
height: 40vh;
margin: 0 auto;
width: 90vw;
padding: 10px;
}
#media (min-width: 596px) {
img {
width: 30vw;
height: 30vh;
}
}
`;
class Homepage extends Component {
constructor(props) {
super(props);
this.state = {
randomCountry: '',
isCountryWrapperVisible: false,
countryFlag: '',
countryRegion: '',
countryCurrency: '',
countryCapital: '',
countryPopulation: '',
countryTimezone: ''
}};
generateRandomCity = () => {
let num = Math.floor(Math.random() * countriesJSON.length);
this.setState({
randomCountry: countriesJSON[num].name
});
};
componentDidUpdate() {
this.fetchCountryInfo();
}
fetchCountryInfo = () => {
fetch(`https://restcountries.eu/rest/v2/name/${this.state.randomCountry}`)
.then(res => res.json())
.then(response =>
this.setState({
countryFlag: response[0].flag,
countryCapital: response[0].capital,
countryRegion: response[0].region,
countryCurrency: response[0].currency,
countryPopulation: response[0].population,
isCountryWrapperVisible: true
})
);
};
render() {
return (
<Container>
<Wrapper>
<Text> Test Your Knowledge of Flags </Text>
<Button onClick={this.generateRandomCity}> HIT ME! </Button>
{this.state.isCountryWrapperVisible && (
<CountryWrapper>
<CountryImgWrapper>
<img src={this.state.countryFlag} alt='flag' className='img-fluid'/>
</CountryImgWrapper>
<CountryDetailsWrapper>
<Paragraph> Name: {this.state.randomCountry} </Paragraph>
<Paragraph> Capital: {this.state.countryCapital} </Paragraph>
<Paragraph> Region: {this.state.countryRegion} </Paragraph>
<Paragraph> Population: {this.state.countryPopulation} </Paragraph>
</CountryDetailsWrapper>
</CountryWrapper>
) }
</Wrapper>
</Container>
)
}
}
export default Homepage;```
It turns out the problem lied in global-style object within parent component I had to recode.

How do I get Flex to work in my react app?

Basically I have two divs setup up and im trying to use flex box to easily size them so they both equally take up half the screen vertically using react. For some reason they are turning out looking like this.
Iv'e tried reinstalling npm but that didn't work at all, and i'm pretty sure my syntax is just fine.
This is my App.css
.wrapper,html,body {
height: 100%;
margin: 0;
}
.wrapper {
display: flex;
flex-direction: column;
}
.nav {
background-color: red;
flex: 1;
}
.main {
background-color: blue;
flex: 1;
}
This is my App.js
import {Row, Col } from "react-bootstrap";
import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import './App.css'
class App extends Component {
render() {
return (
<div className = 'wrapper'>
<div className = 'nav'>
<text>hey</text>
</div>
<div className = 'main'>
<text>hey</text>
</div>
</div>
);
}
}
export default App;
They should work if you remove flex-direction: column; - you actually want flex-direction: row;, which is the default.
You're missing the flex: 1 prop inside the .wrapper css definition. The definition should look like this:
.wrapper {
display: flex;
flex:1;
flex-direction: column;
}
With flex: 1 you're telling the wrapper to use all the available space. Otherwise, it just use what it needs no matter the height.
Here's the entire CSS:
.wrapper,
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
display: flex;
flex: 1;
flex-direction: column;
}
.nav {
background-color: red;
flex: 1;
}
.main {
background-color: blue;
flex: 1;
}
See the result:
Anyway, I totally recommend using Bootstrap v4 which is flexbox based by default.
Your code is all fine, just need add flex:1 to wrapper class.
you can read more about flex here : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
.wrapper,
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
display: flex;
flex-direction: column;
flex: 1;
}
.nav {
background-color: red;
flex: 1;
}
.main {
background-color: blue;
flex: 1;
}
<div class='wrapper'>
<div class='nav'>
<text>hey</text>
</div>
<div class='main'>
<text>hey</text>
</div>
</div>

Why touch methods can't receive the className's parameter?

Since I figured out that new className(param) does not refer directly to an instance(param){} when it passed a constructor function, I've been trying to pass a HTML class into the instance method without changing. but it keeps detecting pseudo class of the param.
This is my code:
class Slider {
'use strict';
istouchStart(e) {
console.log(e.target);
this.coordX = e.touches[0].clientX;
return this.coordX;
}
constructor(target) {
// Variables
var _ = this;
console.log(target);
$(target).stop(true, true).on({
touchstart:_.istouchStart,
touchmove:_.istouchMove,
touchend:_.istouchEnd
});
}
}
const image = new Slider('.inline-grid');
div {
position: relative;
}
.inline-grid {
margin: 0 auto;
width: 2560px;
border: 1px solid black;
display: flex;
flex-flow: row;
overflow: hidden;
}
.wrap {
width: 100%;
display: flex;
flex-flow: row;
}
.cell {
display: flex;
flex-flow: column;
flex-shrink: 0;
width: 100%;
height: 200px;
}
.orange {
background-color: orange;
}
<div class="inline-grid">
<div class="wrap">
<div class="cell orange"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
how would I get the .inline-grid from the istouchStart method?
this is a second try using return and arrow function, but this one just doesn't work without showing an error.:
static istouchStart() {
return (e) => {
console.log(e.target);
this.coordX = e.touches[0].clientX;
}
}

Extra pixels in CSS radiobutton group buttons that won't go away

EDIT: Changed the post name, which was incorrectly titled from another post !!
I have been building a sports app in React over the last several months, and I am struggling with a small cosmetic issue with my radio buttons. Immensely frustrating is the fact that despite my attempt at a reproducible example, the bug does not appear in my example below, although fortunately a variant of the issue is occurring. Here are my buttons:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
oneTwoFour: "1 Graph",
quarter: "All"
}
}
handleQuarterChange = (event) => {
this.setState({ quarter: event.target.value });
};
handleOneTwoFourChange = (event) => {
this.setState({ oneTwoFour: event.target.value });
};
render() {
const { oneTwoFour, quarter } = this.state;
const oneTwoFourOptions = ["1 Graph", "2 Graphs", "4 Graphs"];
const oneTwoFourButtons =
<form>
<div className="blg-buttons">
{oneTwoFourOptions.map((d, i) => {
return (
<label key={'onetwofour-' + i}>
<input
type={"radio"}
value={oneTwoFourOptions[i]}
checked={oneTwoFour === oneTwoFourOptions[i]}
onChange={this.handleOneTwoFourChange}
/>
<span>{oneTwoFourOptions[i]}</span>
</label>
)
})}
</div>
</form>;
const quarterOptions = ["All", "OT", "Half 1", "Half 2", "Q1", "Q2", "Q3", "Q4"];
const quarterButtons =
<form>
<div className="blg-buttons">
{quarterOptions.map((d, i) => {
return (
<label key={'quarter-' + i} style={{"width":"50%"}}>
<input
type={"radio"}
value={quarterOptions[i]}
checked={quarter === quarterOptions[i]}
onChange={this.handleQuarterChange}
/>
<span>{quarterOptions[i]}</span>
</label>
)
})}
</div>
</form>;
return(
<div>
<div style={{"width":"25%", "float":"left", "margin":"0 auto", "padding":"5px"}}>
{quarterButtons}
</div>
<div style={{"width":"25%", "float":"left", "margin":"0 auto", "padding":"5px"}}>
{oneTwoFourButtons}
</div>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
.blg-buttons {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.blg-buttons input[type=radio] {
visibility:hidden;
width:0px;
height:0px;
overflow:hidden;
}
.blg-buttons input[type=radio] + span {
cursor: pointer;
display: inline-block;
vertical-align: top;
line-height: 1;
font-size: 1.0vw;
padding: 0.5vw;
border-radius: 0.35vw;
border: 0.15vw solid #333;
width: 90%;
text-align: center;
color: #333;
background: #EEE;
}
.blg-buttons input[type=radio]:not(:checked) + span {
cursor: pointer;
background-color: #EEE;
color: #333;
}
.blg-buttons input[type=radio]:not(:checked) + span:hover{
cursor: pointer;
background: #888;
}
.blg-buttons input[type=radio]:checked + span{
cursor: pointer;
background-color: #333;
color: #EEE;
}
.blg-buttons label {
line-height: 0;
font-size: calc(0.85vw);
margin-bottom: 0.1vw;
width: 90%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<div id='root'>
Come On Work!
</div>
Also, here is a screenshot of an inspection of the buttons in my app (can be found at bigleaguegraphs.com/nba/shotcharts-pro as well), showing the true error that I am having:
The error is in this overhang of the buttons that is not due to padding or margin. I have seemingly gone through every single aspect of the CSS styling my radio buttons, and I have no idea why the element extends a few extra pixels outward to the right.
Amazingly / unfortunately, this is not occurring in the example above, although there is a different issue in the example above where the label element extends a few extra pixels upward (instead of rightward), that I cannot account for.
Any help with removing this extra couple of pixels on the button group would be very much appreciated!
.blg-buttons {
display: flex;
justify-content: center;
/* flex-wrap: wrap; you shouldn't need this */
flex-direction: column;
flex: 1;
}
.blg-buttons label {
display: flex;
line-height: 0;
font-size: 0.85vw;
flex: 1;
align-items: center;
margin-bottom: 5px; /* you don't need that 0.1vw */
font-weight: 700;
}
.blg-buttons input[type=radio]+span {
cursor: pointer;
display: flex;
flex: 1;
justify-content: center;
vertical-align: top;
line-height: 1;
font-size: 1vw;
padding: .5vw;
border-radius: .35vw;
border: .15vw solid #333;
width: 90%;
/* text-align: center; <-- you don't need this with flex */
color: #333;
background: #eee;
}
You should try and use flexbox where possible. I worked this out by playing with your site, so where i saw .nba_scp_cp_rbs i replaced with .blg-buttons (hope that's right). But yeh, avoid using stuff like width: 90%, with flex you rarely have to explicitly define widths, and you can size things based on padding & margins, leading to way less weird sizing bugs like yours :)
picture proof of it working

Categories