scrolling for overflow-x not working properly - css

I can scroll on the x axis only by moving the laptop touchpad right to left or by pressing in the scroll button and then moving right to left.Not with normal scroll.
the css is the following:
.row {
color: white;
margin-left: 20px;
}
.row__posters {
display: flex;
overflow-y: hidden;
overflow-x: scroll;
padding: 20px;
}
.row__posters::-webkit-scrollbar {
display: none;
}
.row__poster {
object-fit: contain;
width : 100%;
max-height: 100px;
margin-right: 10px;
transition: transform 450ms;
}
.row__poster:hover {
transform: scale(1.08);
}
.row__posterLarge {
max-height: 250px;
}
.row__posterLarge:hover {
transform: scale(1.09);
}
the Javascipt file is:
import React,{ useState , useEffect} from 'react'
import axios from './axios';
import './Row.css';
const base_url = "https://image.tmdb.org/t/p/original/";
function Row({ title ,fetchUrl,isLargeRow }) {
const [movies, setMovies] = useState([]);
// A snippet of code which runs based on a specific condition
useEffect(() => {
// if we leave the brackets blank [] ,run once when the row loads
and dont run again
async function fetchData() {
const request = await axios.get(fetchUrl);
setMovies(request.data.results);
return request;
}
fetchData();
}, [fetchUrl]);
return (
<div className="row">
<h2>{title}</h2>
<div className="row__posters">
{/* several row_posters */}
{movies.map(movie => (
<img
key={movie.id}
className={`row__poster ${isLargeRow && "row__posterLarge"}`}
src={`${base_url}${
isLargeRow ? movie.poster_path : movie.backdrop_path
}`}
alt={movie.name}
/>
))}
</div>
</div>
)
}
export default Row
I tried alot of solutions but I must be doing something wrong because nothing worked .it could be that I used the proposed code in the wrong department.
Thank you for the help in advance!!

Related

How to make dropdown animation?

I am implementing drop-down list using styled-component in react. In the process, I have two questions.
First, when dropDownVisible changes from true to false, why doesn't the animation effect apply and it disappears immediately? How can I improve the animation effect? Like when this list goes down, I want to make it gradually when it goes up.
Second, when StyledDropdown is dropped down, I want it to drop down behind the StyledHead, so I set the z-index property like that. I want the StyledHead to be always on top, so I'm curious why the StyledHead is hidden as the StyledDropdown drops down, even though I gave the z-index property bigger.
The source code is roughly structured like this:
// AApage.jsx
import { useEffect, useState, useRef } from 'react';
import { MdArrowDropDown, MdArrowDropUp } from 'react-icons/md';
import styled, { keyframes } from 'styled-components';
const dropAnimation = keyframes`
0% {
transform : translateY(-300px);
display : none;
}
100% {
transform : translateY(0);
}
`;
const StyledHead = styled.div`
width: 100px;
height: 100px;
background-color: red;
z-index: 11;
`;
const StyledDropdown = styled.div`
width: 100px;
height: 300px;
background-color: #d9d9d9;
border-radius: 0px 0px 10px 10px;
z-index: 3;
animation: ${dropAnimation} 1s alternate;
`;
const AApage = () => {
const [dropDownVisible, setDropDownVisible] = useState<boolean>(false);
const toggleDropDownVisible = () => {
setDropDownVisible((prev) => !prev);
};
return (
<>
<StyledHead>
<div>Dropdown</div>
<span>{`${dropDownVisible}`}</span>
{dropDownVisible ? (
<MdArrowDropUp
onClick={() => {
toggleDropDownVisible();
}}
></MdArrowDropUp>
) : (
<MdArrowDropDown
onClick={() => {
toggleDropDownVisible();
}}
></MdArrowDropDown>
)}
</StyledHead>
{dropDownVisible ? (
<StyledDropdown>
<div>temp data</div>
<div>temp data</div>
<div>temp data</div>
</StyledDropdown>
) : (
<></>
)}
</>
);
};
export default AApage;

Change state in function component react

I am new to React and being held back by a seemingly simple task.
I've got a Header component nested within which is a HamburgerButton component. Clicking the latter should make a sidenav appear but for now I would like the icon to change from the 'hamburger' to the big 'X'.
Here is my parent component:
import { MyMoviesLogo } from 'components/Icons';
import HamburgerButton from 'components/HamburgerButton/HamburgerButton';
import styles from './Header.module.css';
const Header = (): JSX.Element => {
const [isActive, setIsActive] = useState(false);
return (
<header className={styles.header}>
<MyMoviesLogo className={styles.headerIcon} />
<HamburgerButton
isActive={false}
/>
</header>
);
};
export default Header;
And here is the HamburgerButton
import styles from './HamburgerButton.module.css';
type HamburgerButtonProps = {
isActive: boolean;
onClick?: () => void;
};
const addMultipleClassNames = (classNames: string[]): string => classNames.join(' ');
const HamburgerButton = ({ isActive, onClick }: HamburgerButtonProps): JSX.Element => {
return (
<div className={isActive ? addMultipleClassNames([styles.hamburger, styles.active]) : styles.hamburger} onClick={onClick}>
<div className={styles.bar}></div>
<div className={styles.bar}></div>
<div className={styles.bar}></div>
</div>
);
}
export default HamburgerButton;
Here's my HamburgerButton.module.css file:
.hamburger {
cursor: pointer;
display: block;
width: 25px;
}
.bar {
background-color: var(--hamburger-button-global);
display: block;
height: 3px;
margin: 5px auto;
transition: all 0.3s ease-in-out;
width: 25px;
}
.hamburger.active .bar:nth-child(2) {
opacity: 0;
}
.hamburger.active .bar:nth-child(1) {
transform: translateY(8px) rotate(45deg);
}
.hamburger.active .bar:nth-child(3) {
transform: translateY(-8px) rotate(-45deg);
}
Manually changing the isActive prop to false verifies that the styling is applied as required.
My question is, how could I make it so when I click the icon its state gets toggled? I am familiar with React hooks like useState but can't quite put something together.
Any help would be greatly appreciated.
Thank you.
P.S.: It's probably obvious but I am using TypeScript.
You should use your onClick prop from your <HamburgerButton /> to change the parent state.
<HamburgerButton isActive={isActive} onClick={() => { setIsActive(oldState => !oldState) } />

React - how to stop div onClick from changing sibling divs

I have 6 div elements that I want to be able to click one of and have the className change for just the div I've clicked on. Currently, when I click on one div, ALL the div classNames change. This idea came from a vanilla JS concept that I'm trying to convert into a React component. I'm not sure where/what is going wrong, if anyone can tell me how to prevent the sibling divs' onClicks from being fired or if what I have is wrong fundamentally, I would be eternally grateful. This is what I have so far:
import React, { useState} from "react";
import { Panels } from "../../components/index";
import { data } from "../../constants/index";
import "./gallery.css";
const Gallery = () => {
const [isOpen, setIsOpen] = useState(false);
const toggleOpen = () => {
setIsOpen(!isOpen);
};
return (
<div className="panels">
{data.restaurants.map((restaurant, index) => (
<div
className={`panel panel${index} ${isOpen ? "open open-active" : ""}`}
onClick={toggleOpen}
>
<Panels
key={restaurant.name + index}
description={restaurant.description}
name={restaurant.name}
website={restaurant.website}
/>
</div>
))}
</div>
);
};
export default Gallery;
This is my Panels Component code:
import React from "react";
const Panels = ({ name, description, website }) => {
return (
<div className="panel_text">
<p>{description}</p>
<p>{name}</p>
<a href={website}>
<p>Visit {name}</p>
</a>
</div>
)};
export default Panels;
Aaaand this is my CSS code:
*, *:before, *:after {
box-sizing: inherit;
}
.panels {
min-height: 100vh;
overflow: hidden;
display: flex;
}
.panel, .panel_text {
background: '#fff';
box-shadow: inse 0 0 0 5px rgba(255, 255, 255, 0.1);
color: var(--color-golden);
text-align: center;
align-items: center;
transition:
font-size 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11),
flex 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11);
font-size: 20px;
background-size: cover;
background-position: center;
flex: 1;
justify-content: center;
display: flex;
flex-direction: column;
}
.panel0 {background-image: url(../../assets/defuegocarousel.jpg);}
.panel1 {background-image: url(../../assets/HaydenslakeSz.jpg);}
.panel2 {background-image: url(../../assets/stonecliffSz.jpg);}
.panel3 {background-image: url(../../assets/shigezooutside.png);}
.panel4 {background-image: url(../../assets/southparkSz.jpeg);}
.panel5 {background-image: url(../../assets/lechonoutside.jpg);}
.panel > * {
margin: 0;
width: 100%;
transition: transform 0.5s;
flex: 1 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.panel > *:first-child {transform: translateY(-100%);}
.panel.open-active > *:first-child {transform: translateY(0); }
.panel > *:last-child { transform: translateY(100%); }
.panel.open-active > *:last-child {transform: translateY(0); }
.panel_text p, a {
text-transform: uppercase;
}
.panel p:nth-child(2) {
font-size: 4rem;
}
.panel.open {
flex: 5;
font-size: 40px;
}
#media only screen and (max-width: 600px) {
.panel p {
font-size: 1rem;
}
}
You're saving a boolean value as a div element is open or not. So this value is considered for all div element's because there is no identifier which div element is open. You need to save a div element value to identify the open div element.
So you can use a div element's index instead of a boolean value. For example, try the below code.
import React, { useState} from "react";
import { Panels } from "../../components/index";
import { data } from "../../constants/index";
import "./gallery.css";
const Gallery = () => {
const [isOpen, setIsOpen] = useState(null);
return (
<div className="panels">
{data.restaurants.map((restaurant, index) => (
<div
className={`panel panel${index} ${isOpen === index ? "open open-active" : ""}`}
onClick={() => setIsOpen(index)}
>
<Panels
key={restaurant.name + index}
description={restaurant.description}
name={restaurant.name}
website={restaurant.website}
/>
</div>
))}
</div>
);
};
export default Gallery;
your isOpen state is common between all your div's
you should specify a unique value for isOpen of each div
you can change your isOpen state to an object like this :
import React, { useState} from "react";
import { Panels } from "../../components/index";
import { data } from "../../constants/index";
import "./gallery.css";
const Gallery = () => {
const [isOpen, setIsOpen] = useState({});
const toggleOpen = (index) => {
setIsOpen(prevState => {...prevState ,[index]:!(!!prevState[index]) });
};
return (
<div className="panels">
{data.restaurants.map((restaurant, index) => (
<div
className={`panel panel${index} ${isOpen[index] ? "open open-active" : ""}`}
onClick={()=>toggleOpen(index)}
>
<Panels
key={restaurant.name + index}
description={restaurant.description}
name={restaurant.name}
website={restaurant.website}
/>
</div>
))}
</div>
);
};
export default Gallery;

Choppy height CSSTransition in react with multiple items

Goal: I'm getting really frustrated and have been scavenging through posts for hours now and can't find any real solution. I'm trying to animation a table row's height to expand/collapse when clicked on. I figured there should be an easy enough solution... Boy was I wrong.
Ideally since each row is going to store quite a bit of extra data, I'd like to load in the data, expand that single row, then remove the data when it's collapsed.
Problem:
I managed to get the animation working great!! I was so excited, only to find out that when I have more than ~3 rows, it gets extremely choppy/laggy. I can't find any fix what so ever.
Here is a sandbox https://codesandbox.io/s/0ql5vp13qv or if you wanted to see the code that manages the animation my code now:
import React, { Component } from 'react'
import { CSSTransition } from 'react-transition-group';
import Icon2 from '../Icon';
import * as Styled from './styles'
export default class CourseRow extends Component {
state = {switched: false};
selectCourse = () => {
this.setState(({switched}) => ({switched: !switched}));
}
render() {
return (
<Styled.Row onClick={this.selectCourse}>
<Styled.InnerRow>
<Styled.Field light>CSCI 1000</Styled.Field>
<Styled.Field>Computer Science 1</Styled.Field>
<Styled.Field>Explore algorithms and data structures that...</Styled.Field>
<Styled.Field><Styled.DropdownButton ><Icon2 icon="up_arrow"/></Styled.DropdownButton></Styled.Field>
</Styled.InnerRow>
<CSSTransition
classNames="fade"
timeout={300}
key={this.props.Title}
in={this.state.switched}
unmountOnExit
>
<div>
test<br/>test<br/>test<br/>
</div>
</CSSTransition>
</Styled.Row>
);
}
}
import styled from 'styled-components';
import Button from 'components/Button';
const columns = "1.5fr 2.5fr 5fr 3fr";
export const DropdownButton = styled(Button)`
background-color: blue;
`;
export const InnerRow = styled.div`
display: grid;
grid-template-columns: ${columns};
grid-column-gap: 1rem;
grid-row-gap: 0;
padding-top: ${props => props.heading ? '2.25rem' : '1.5rem'};
padding-bottom: ${props => props.heading ? '2rem' : '1.5rem'};
padding-left: 0.75rem;
padding-right: 0.75rem;
border-top: ${props => props.heading ? 'none' : '1px solid #E8E8E8'};
cursor: ${props => props.heading ? 'default' : 'pointer'};
`;
export const Row = styled.div`
&:hover {
background-color: #f7faff;
color: #1873EA;
}
& .fade-enter {
overflow-y: hidden;
max-height: 0;
}
& .fade-enter-active {
max-height: 200px;
transition: all 200ms ease;
}
& .fade-exit {
max-height: 200px;
}
& .fade-exit-active {
max-height: 0;
overflow-y: hidden;
transition: all 200ms ease;
}
`;
export const Field = styled.span`
display: flex;
align-items: center;
font-size: 14px;
font-weight: ${props => props.light ? '400' : '300'};
&:last-of-type {
justify-content: flex-end;
}
`;
I thought maybe adding key's to the elements/transitions would help however still nothing...
I took videos of the comparisons so you can see what I'm talking about it.
This is with 1 row:
https://www.youtube.com/watch?v=E6Db7nuqlgk&feature=youtu.be
This is with ~6 rows:
https://www.youtube.com/watch?v=Troba8eIqKA&feature=youtu.be

Can't get buttons to wrap to new line instead of overflowing container

I couldn't get a JSFiddle to work properly with React and some other dependencies, so I hope the link to this Github repo is sufficient for demonstrating the issue:
https://github.com/ishraqiyun77/button-issues/
Basically, a group of buttons is rendered and they should be auto-widened to fill white space and take up the whole row. This works in Chrome, Edge, Safari, and Firefox. It looks like this:
This isn't happening in IE. I've been messing with it for hours and haven't made much progress:
Here is the code, although could clone the repo I posted above:
// component.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
Button,
Col,
Modal,
ModalBody,
ModalHeader,
Row
} from 'reactstrap';
import styles from '../assets/scss/app.scss';
class TestPrint extends Component {
constructor(props) {
super(props);
this.state = {
modal: false,
}
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
})
}
renderContent() {
let buttons = [];
for (let i = 1; i < 50; i++) {
buttons.push(
<Col key={i}>
<Button
key={i}
className='cuts-btn'
>
{i} - Test
</Button>
</Col>
);
};
return buttons;
}
render() {
return (
<div>
<Button
style={
{
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
}
}
onClick={this.toggle}
>
Open Modal for Buttons
</Button>
<Modal
size='lg'
isOpen={this.state.modal}
toggle={this.toggle}
className='results-modal'
>
<ModalHeader toggle={this.toggle}>
Button Issues
</ModalHeader>
<ModalBody>
<div className='results-bq-cuts'>
<Row>
{this.renderContent()}
</Row>
</div>
</ModalBody>
</Modal>
</div>
)
}
}
ReactDOM.render(<TestPrint />, document.getElementById('app'));
.results-modal {
max-width: 1200px;
.modal-content {
.modal-body {
margin-left: 13px;
margin-right: 13px;
.results-bq-cuts {
width: 100%;
.col {
padding:2px;
}
.cuts-btn {
font-size: 11px;
padding: 3px;
width: 100%;
box-shadow: none;
}
// .col {
// padding: 2px;
// display: table-cell;
// flex-basis: 100%;
// flex: 1;
// }
// .cuts-btn {
// font-size: 11px;
// padding: 3px;
// width: 100%;
// box-shadow: none;
// }
}
}
}
}
I have all of the <Button> wrapped in <Col> because that should be what is filling the white space by increasing the size of the button.
Thanks for the help!
IE11 doesn't like working out the width of flex items. If you add flex-basis: calc( 100% / 24 ); to .col it works :) Obviously use any width you want, but what I've given replicates the 21 boxes on one line. But essentially flex-basis needs a defined width to work.
​
Or add an extra class to each element (such as col-1 ) This'll also achieve the same thing.

Resources