Hide nav button in react-material-ui-carousel - css

I've just implemented the react material ui carousel, and it was pretty straightforward, the only thing i didn't catch, is how to hide buttons and show them only on over.
I noticed the props navButtonsAlwaysVisible and set it to false but it isn't enough.
Should i implement my own logic for that, or maybe I'm just missing something?
here's the component code:
import styles from '../../styles/Testimonial.module.scss'
import Image from 'next/image'
import Carousel from 'react-material-ui-carousel'
const Testimonial = _ => {
const items = [
{
imageUrl: "/png/image0.webp",
feedback: "feedback0",
name: "name0",
location: "location0"
},
{
imageUrl: "/png/image1.jpeg",
feedback: "feedback1",
name: "name1",
location: "location1"
}
]
return (
<div id="customers" className={`section ${styles.testimonial}`}>
<h2 className={`title ${styles.title}`}>Clientes Felizes</h2>
<span className={"separator"}> </span>
<Carousel
className={styles.carousel}
autoPlay={true}
stopAutoPlayOnHover={true}
interval={5000}
animation={"slide"}
swipe={true}
navButtonsAlwaysVisible={false}
navButtonsProps={{
style: {
backgroundColor: "#8f34eb",
opacity: 0.4
}
}}
>
{
items.map( (item, i) => <Item key={i} item={item} /> )
}
</Carousel>
</div>
)
}
function Item(props)
{
return (
<article className={styles.testimonial__card}>
<div className={styles.testimonial__photo_container}>
<Image
className={styles.testimonial__photo}
src={props.item.imageUrl}
alt="Testimonial"
width={312}
height={300}
/>
</div>
<p className={styles.testimonial__copy}>{props.item.feedback}</p>
<span className={styles.testimonial__name}>{props.item.name}</span>
<span className={styles.testimonial__city}>{props.item.location}</span>
</article>
)
}
export default Testimonial;

there's a prop called navButtonsAlwaysInvisible
navButtonsAlwaysInvisible={true}

You can try using Custom CSS for your purpose. Based on the current rendered markup,
.jss6 {
opacity: 0;
transition: all ease 1000ms; /* So that it does not disappear quickly */
}
You can define the hover for the parent so that it displays only when the parent container is hovered on:
.jss1.Testimonial_carousel__3rny3:hover .jss6 {
opacity: 1;
}
This is how it works now:

Related

Grid Layout for Tweets inside TwitterTimelineEmbed

I'm using react-twitter-embed to display a timeline in a home page. But I would like to add a custom CSS grid (the tweets, limited by six, must appear horizontally and not vertically):
import { useTranslation } from "react-i18next";
import { TwitterTimelineEmbed } from "react-twitter-embed";
import { FollowUsOn } from "../Footer/SubModules/FollowUs/follow-us-on.component";
import { BlockTwitterBtn } from "./SubModules/block-twitter-btn.component";
export const BlockTwitter = () => {
const { t } = useTranslation();
return (
<div className="container blockTwitter">
<div className="blockTwitter__firstCard">
<h3 className="blockTwitter__title">{t("common:blockTwitterTitle")}</h3>
<BlockTwitterBtn />
<FollowUsOn />
</div>
<section className="twitterContainer">
<div className="twitter-embed">
<TwitterTimelineEmbed
sourceType="profile"
screenName="Quebecor"
options={{
tweetLimit: "6",
width: "100%",
height: "100%"
}}
noHeader="true"
noFooter="true"
></TwitterTimelineEmbed>
</div>
</section>
</div>
);
};
I read I could use the option onLoad={function with custom CSS}, but I don't know exactly how to do this on React...

React Modals visible for a split-second on page load

I am rendering modals in React.
My index.html looks like this:
<div id="root"></div>
<div id="modal"></div>
And all my modals are rendered (through a portal) as a child of .modal.
Each modal element has the following form:
<div class="modal-background open">
<!-- children -->
</div>
Where the class can be modal-background open or modal-background closed. The entire component is:
interface OwnProps {
children: React.ReactNode
isOpen: boolean
onExit: () => void
}
export class Modal extends React.Component<OwnProps, any> {
_exit = () => this.props.onExit();
_renderModal = () => (
<div className={`modal-background ${this.props.isOpen ? "open" : "closed"}`} onClick={this._exit}>
{this.props.children}
</div>
);
render() {
if (this.props.isOpen) {
document.body.className += " no-scroll";
} else {
document.body.classList.remove("no-scroll");
}
let elem = document.querySelector("#modal");
if (elem == null) {
console.log("Could not render modal.");
return null;
}
return ReactDOM.createPortal(this._renderModal(), elem);
}
}
And the CSS looks like:
.modal-background {
/* Other styling - this a dark backdrop for a modal child */
background-color: rgba(0,0,0,0.2);
transition: opacity 150ms ease-out;
&.closed {
opacity: 0;
pointer-events: none;
}
&.open {
pointer-events: all;
opacity: 1;
&:hover {
cursor: pointer;
}
}
}
So my modal is used like <Modal><CustomModalElement/></Modal>.
When I load the page, my modal elements briefly flash, indicating that they are not hidden on load (but a split-second afterwards).
I can fix this by adding display: none and display: inherit into the css, but then I miss the nice transitions.
Is there a better way to do this?
Not sure you need to do anything else inside your index.html file except
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="modal"></div>
And for your Modal.js, you could try something along these lines:
import React from "react";
import ReactDOM from "react-dom";
const Modal = props => {
return ReactDOM.createPortal(
<div className="ui dimmer modals visible active">
<div className="ui standard modal visible active">
<div className="header">Delete Object</div>
<div className="content">
Are you sure you want to delete this?
</div>
<div className="actions">
<button className="ui primary button">Delete</button>
<button className="ui button">Cancel</button>
</div>
</div>
</div>,
document.querySelector("#modal")
);
};
export default Modal;
and then inside your other component where the user will execute the modal:
import React from "react";
import Modal from "../Modal"; // or wherever your Modal is in the file tree
const ObjectDelete = () => {
return (
<div>
ObjectDelete
<Modal />
</div>
);
};
export default ObjectDelete;
Keep in mind that the example of modal I offer here is not a reusable component.

CSS Help - Remove blank space between Images (<img>)

Right now I am trying to make images stack side by side, vertically and horizontally, so that there is no white spaces between them. This is what my view currently looks like.
Ideally, there would be none of that blank, white space. I have inserted the ReactJS code below with my GifViewer component that holds the . Any ideas on how I can get this to work? And the code will not run due to the axios request, so it's just for visual effect right now.
img {
display: inline !important;
width: 20%;
vertical-align: top;
height: auto;
top: 0;
left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
class GifViewer extends Component {
render() {
return (
<img
key={this.props.keyyer}
src={`https://i.giphy.com/${this.props.id}.gif`}
/>
);
}
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchTerm: "",
counter: 0,
pastSearches: [],
data: null
};
this.handleChange = this.handleChange.bind(this);
}
componentDidUpdate() {
console.log("this.state.data", this.state.data);
}
componentDidMount() {
console.log("Mounted");
}
handleChange(event) {
this.setState({ searchTerm: event.target.value });
axios
.get(
`${BASE_URL}${config.apiKey}${QUERY}${this.state.searchTerm}${LIMITS}`
)
.then(result => {
this.setState({ data: result.data.data });
});
}
render() {
if (this.state.data) {
var GIFS = this.state.data.map(d => (
<GifViewer keyyer={d.embed_url} id={d.id} />
));
}
return (
<div className="container-fluid">
<div className="row py-5 bg-success">
<div className="col-8 offset-2">
<h3 className="text-center">LET'S BREAK THE INTER-WEBZ</h3>
<input
type="text"
className="form-control"
value={this.state.searchTerm}
onChange={this.handleChange}
placeholder="Search"
/>
</div>
</div>
{this.state.data ? GIFS : "Nothing yet"}
</div>
);
}
}
export default App;
My personal favorite way to resolve this is the css property object-fit: cover; (applied to your img rule).
There's a great article on the property here, but the gist (for your purpose) is that you can zoom the image to cover the whole space without stretching or distorting the image.

First time using React-Transition-Group

I have a image viewer component that as one large image and 3 smaller ones below it. When you hover over one of the bottom images it changes the large image to the corresponding image. I would like to add a fade-in/fade-out transition when the larger image changes. So far I can get a fade-in and a fade-out on the mouse completely leaving the smaller image but, not hovering between the images. Here is my code:
import React, { Component } from 'react';
import Transition from 'react-transition-group/Transition'
import Image0 from './Image1.jpg'
import Image1 from './Image2.jpg'
import Image2 from './Image3.jpg'
import './ImageViewer.css';
const duration = 300;
const Images = [Image0, Image1, Image2]
const defaultStyle = {
transition: `opacity ${duration}ms ease-in-out`,
opacity: 0,
}
const transitionStyles = {
entering: { opacity: 1 },
entered: { opacity: 1 },
exiting: { opacity: .9 },
exited: { opacity: 0.01 }
};
const Fade = ({ in: inProp, currentImage }) => (
<Transition in={inProp} timeout={duration}>
{(state) => (
<div style={{
...defaultStyle,
...transitionStyles[state]
}}>
<img src={currentImage}/>
</div>
)}
</Transition>
);
class App extends Component {
state = { show: false, currentImg: Images[0] }
handleClick = e => {
this.setState({
show: !this.state.show,
currentImg: Images[Number(e.currentTarget.dataset.id)]
})
}
render() {
return (
<div className="App">
<Fade in={this.state.show} currentImage={this.state.currentImg}/>
<div className="small_image_wrapper">
<img className="small_image"
src={Image0}
alt="A wonderful bed"
data-id={0}
onMouseOver={this.handleClick}
onMouseOut={this.handleClick}
/>
<img className="small_image"
src={Image1}
alt="A wonderful bed"
data-id={1}
onMouseOver={this.handleClick}
onMouseOut={this.handleClick}
/>
<img className="small_image"
src={Image2}
alt="A wonderful bed"
data-id={2}
onMouseOver={this.handleClick}
onMouseOut={this.handleClick}
/>
</div>
</div>
);
}
}
export default App;
Also here's a link to what I have so far with transitions:
https://peaceful-jones-ee2ca2.netlify.com/
And without transitions:
https://practical-lamport-9cc94e.netlify.com/
I am not sure but you have to wrap all your images into TransitionGroup
import {TransitionGroup}, {Transition} from 'react-transition-group';
...
render() {
return (
<div className="App">
<TransitionGroup>
<Fade in={this.state.show} currentImage={this.state.currentImg}/>
</TransitionGroup>
<div className="small_image_wrapper">
/* here comes small images */
</div>
</div>
)};

Add a State property to an Inline Style in React

I have a react element that has an inline style like this: (Shortened version)
<div className='progress-bar'
role='progressbar'
style={{width: '30%'}}>
</div>
I want to replace the width with a property from my state, although I'm not quite sure how to do it.
I tried:
<div className='progress-bar'
role='progressbar'
style={{{width: this.state.percentage}}}>
</div>
Is this even possible?
You can do it like this
style={ { width: `${ this.state.percentage }%` } }
Example
yes its possible check below
class App extends React.Component {
constructor(props){
super(props)
this.state = {
width:30; //default
};
}
render(){
//when state changes the width changes
const style = {
width: this.state.width
}
return(
<div>
//when button is clicked the style value of width increases
<button onClick={() => this.setState({width + 1})}></button>
<div className='progress-bar'
role='progressbar'
style={style}>
</div>
</div>
);
}
:-)

Resources