Trying to get react-perfect-scrollbar working in React app - reactjs

So i'm new to React and trying to add a scroll bar to app. I've installed react-perfect-scrollbar and imported it to my app. After following instructions as specified I can't get a scroll bar to show... I imagine i'm making a very basic mistake but I can't work it out. I'm not fiddling with custom options or anything yet, i'm simply trying to display a scroll bar
import PerfectScrollbar from 'react-perfect-scrollbar';
import 'react-perfect-scrollbar/dist/css/styles.css';
<PerfectScrollbar>
<p> test 1 </p>
<p> test 2 </p>
</PerfectScrollbar>

You are not providing correct css for scrollbar to be shown.
Working codesandbox code here
Example.js
import React, { Component } from "react";
import ScrollBar from "react-perfect-scrollbar";
import "react-perfect-scrollbar/dist/css/styles.css";
import "./example.scss";
class Example extends Component {
render() {
return (
<div className="example">
<ScrollBar component="div">
<div className="content" />
</ScrollBar>
</div>
);
}
}
export default Example;
example.scss
.example {
width: 400px;
height: 400px;
.content {
background: green;
width: 800px;
height: 480px;
}
}
Hope that helps!!!

Have you tried to put your items inside DIV?
import PerfectScrollbar from 'react-perfect-scrollbar';
import 'react-perfect-scrollbar/dist/css/styles.css';
<PerfectScrollbar>
<div>
<p> test 1 </p>
<p> test 2 </p>
</div>
</PerfectScrollbar>

Related

Unable to toggle expanded nav menu

I want to create an expandable side menu which is toggled by clicking the hamburger menu inside "MobileNav". I'm having issues selecting the elements since they're inside seperate documents. How would I go about doing this?
The idea is to add and remove the "hidden" class to hide and show the expanded menu.
App
import React from "react";
import ExpandedNav from "./components/ExpandedNav";
import MobileNav from "./components/MobileNav";
import Navbar from "./components/Navbar";
import "./styles/styles.css";
function App() {
return (
<div className="app-wrapper">
{/* Mobile Nav */}
<MobileNav />
<ExpandedNav />
{/* Main Nav */}
<Navbar />
{/* Routing */}
</div>
);
}
export default App;
Expanded Nav
import React from "react";
function ExpandedNav() {
return <div className="expanded-nav" id="expanded-nav"></div>;
}
export default ExpandedNav;
Mobile Nav
import React from "react";
import { AiOutlineMenu } from "react-icons/ai";
function MobileNav() {
return (
<div className="app-mobile-nav">
<div className="mobile-nav-brand">
<span>Chicken</span>
<div className="mobile-nav-divider" />
<span>Little</span>
</div>
<AiOutlineMenu className="nav-icon" id="mobile-hb-nav" />
</div>
);
}
export default MobileNav;
Expanded Nav SCSS
.expanded-nav {
display: flex;
position: absolute;
top: 0;
right: 0;
bottom: 0;
margin: 15px 20px 15px 0px;
width: 300px;
border-radius: $border-radius;
box-shadow: $box-shadow;
border: $thin-light-border;
background-color: $block-color;
}
.hidden {
display: none; /* responds to click event */
}
There is a better way then toggling CSS classes. Add state in the App file and then forward function for changing state via props to the MobileNav component. Based on the state show or hide expanded component. Something like this:
import React from "react";
import ExpandedNav from "./components/ExpandedNav";
import MobileNav from "./components/MobileNav";
import Navbar from "./components/Navbar";
import "./styles/styles.css";
function App() {
const [isVisible, setIsVisible] = useState(false);
return (
<div className="app-wrapper">
{/* Mobile Nav */}
<MobileNav toggleNav={() => setIsVisible(!visible)}/>
{isVisible && <ExpandedNav />}
{/* Main Nav */}
<Navbar />
{/* Routing */}
</div>
);
}
export default App;
import React from "react";
import { AiOutlineMenu } from "react-icons/ai";
function MobileNav({toggleNav}) {
return (
// Add onClick function to the element that you need, this is only
// for example
<div className="app-mobile-nav" onClick={toggleNav}>
<div className="mobile-nav-brand">
<span>Chicken</span>
<div className="mobile-nav-divider" />
<span>Little</span>
</div>
<AiOutlineMenu className="nav-icon" id="mobile-hb-nav" />
</div>
);
}
export default MobileNav;

FontAwesome spinner won't spin in React

I created a React application with npx create-react-app.
Then following these instructions
https://fontawesome.com/how-to-use/on-the-web/using-with/react
I installed the Font Awesome dependences:
npm i #fortawesome/fontawesome-svg-core
npm i #fortawesome/free-solid-svg-icons
npm i #fortawesome/react-fontawesome
Then I changed the App.js to this:
import logo from './logo.svg';
import './App.css';
import { FaSpinner } from 'react-icons/fa';
function App() {
return (
<div className="App">
<FaSpinner icon="spinner" spin /> This is a test.
</div>
);
}
export default App;
But it only displays a spinner icon that is not spinning:
How do I get the spinner to spin?
NOTE:
Outside of React, Font Awesome works fine without doing any extra work to animate the icons, e.g. this simple HTML code shows an animated icon:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet"
type="text/css"
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<title>testspin</title>
</head>
<body>
<i class="fa fa-spinner fa-spin"
aria-hidden="true"></i>
This is a test
</body>
</html>
What do I need to do in order to get the React version to work this easily?
By default, the spinner will not spin. But a simple way to trigger it to spin just like the logo of React after creating a new react app.
Add a className of spin to the icon and add a little css to trigger it spinning such like that below:
App.js
import react from 'react';
import './App.css';
import { FaSpinner } from 'react-icons/fa';
function App() {
return (
<div className="App">
<FaSpinner icon="spinner" className="spinner" /> This is a test.
</div>
);
}
export default App;
App.css
.spinner {
animation: spin infinite 5s linear;
/*You can increase or decrease the timer (5s) to
increase or decrease the speed of the spinner*/
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
Actually you just need to add the class fa-spin, no need to add any custom css, this is already included with React-Fontawesome for the class fa-spin. Here is an example from a project of mine:
import React, { useState } from 'react'
import { faCog, faFilePdf } from '#fortawesome/free-solid-svg-icons'
import { Button } from 'react-bootstrap'
const MyComponent = () => {
const [pdfCreatingState,setPdfCreatingState] = useState(false);
const handleClick = ev => {
setPdfCreatingState(true);
setTimeout(() => generatePDFDocument(docData,docName));
}
const generatePDFDocument = async (docData,docName) => {
...
}
return(
<Button className="mr-4" onClick={handleClick}>
<FontAwesomeIcon icon={pdfCreatingState ? faCog : faFilePdf} title={"Generate PDF report"} className={pdfCreatingState ? "fa-spin" : ""} />
</Button>
);
}
I had the same situation with Nextjs and noticed that the proper <style> tag for animation was not being generated. So I solved the problem by directly importing it. In my case, Adding import "#fortawesome/fontawesome-svg-core/styles.css" fixes the issue, and FontAwesome works as intended.
In my project I'm using react-icons/fa and the answer provided by #Qudusayo worked very well for smooth spinners. If anyone is trying to create a 'pulsed' or 'step' spinner, here's how you can do that:
CSS:
.icon_pulse {
animation: circle 1.2s steps(8) infinite;
}
#keyframes circle {
from {
transform: rotate(90deg);
}
to {
transform: rotate(450deg);
}
}
JSX:
<FaSpinner className="icon_pulse" />

React 16 - unable to make a modal render using createPortal

I'm trying to render a loading notification modal while a POST is processing.
It seems like it should be very simple using createPortal but the modal never displays.
I added a div in index with an id of modal:
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<div id="modal"></div>
</body>
Here is the react component. When the test button is clicked the state of showModal is set to true:
import React, { Component, Header } from 'react';
import { render } from "react-dom";
import { Row, Col, Button } from 'reactstrap'
import 'bootstrap/dist/css/bootstrap.css';
import ProcessingModal from '../Modals/ProcessingModal';
export class TestModal extends React.Component {
constructor(props) {
this.state = {
showModal: false,
}
this.handleShowModal = this.handleShowModal.bind(this);
}
handleShowModal() {
this.setState({ showModal: true });
}
render() {
return (
<div>
<div className='container-fluid'>
<h2 style={{ textAlign: 'center', border: 'none' }}>
Header Text
</h2>
<br />
{this.state.showModal ? <ProcessingModal /> : null }
<Row>
<Col md={6}>
<Button onClick={this.handleShowModal} type="button">test</Button>
</Col>
</Row>
</div>
</div>
);
}
This is the ProcessingModal js:
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
const ModalContent = (
<div className='modal text-center'>
<div className="spinner-border text-success"><br />
Loading...
</div>
</div>
);
function ProcessingModal(props) {
return ReactDOM.createPortal(ModalContent, document.querySelector("#modal"));
}
export default ProcessingModal;
Where am i going wrong?
I think first argument of createPortal expect a React Element, not React Component.
In ProcessingModal.js, wrap ModalContent into JSX Element:
return ReactDOM.createPortal(<ModalContent/>, document.querySelector("#modal"))
Styling was my issue. The modal style had display: none;
Once that was removed it worked.

Carousel in React.js

I am trying to implement this tutorial. My code is like below
import makeCarousel from 'react-reveal/makeCarousel';
import Slide from 'react-reveal/Slide';
import styled, { css } from 'styled-components';
export default class Slider extends Component {
Container = styled.div`
border: 1px solid red;
position: relative;
overflow: hidden;
width: 300px;
height: 150px;
`;
CarouselUI = ({ children }) => <Container>{children}</Container>;
Carousel = makeCarousel(CarouselUI);
render (
<Carousel defaultWait={1000} /*wait for 1000 milliseconds*/ >
<Slide right>
<div>
<h1>Slide 1</h1>
<p>Slide Description</p>
</div>
</Slide>
<Slide right>
<div>
<h1>Slide 2</h1>
<p>Slide Description</p>
</div>
</Slide>
</Carousel>
);
}
I am getting error like below
you forgot to write return. Also the render function needs () after it.
render() {
return (
<Carousel defaultWait={1000} /*wait for 1000 milliseconds*/ >
<Slide right>
<div>
<h1>Slide 1</h1>
<p>Slide Description</p>
</div>
</Slide>
<Slide right>
<div>
<h1>Slide 2</h1>
<p>Slide Description</p>
</div>
</Slide>
</Carousel>
);
}
You seem to be missing some code, also need to move some lines around. It is unfortunate the tutorial misses some code and makes it seem like everything is inside your default exported class.
you need the line import React from 'react' at the top of your file, it needs to be in every React component.
Also The Component composition lines, which inject your styles etc, need to be moved outside of your exported class. Also they need to be defined, i.e. use const.
const Container = styled.div`...`
const CarouselUI = ({ children }) => <Container>{children}</Container>;
const Carousel = makeCarousel(CarouselUI);
and then also missing a return statement in render function. Remember its a function of the class Slider, so you also need the () after.
See a codesandbox which works - https://codesandbox.io/s/agitated-browser-foxsb?fontsize=14&hidenavigation=1&theme=dark
you have to install:
npm install react-responsive-carousel
for more information about Carousel follow the below link:
Link:https://www.npmjs.com/package/react-responsive-carousel
and more over you forget to write
render{
return(......
)
}

how to scale (large) font-awesome icons from the react-icons package

I am using the marvelouse react-icons package (http://gorangajic.github.io/react-icons/fa.html), specifically the font awesome package.
If this was not react, then I would just add an attribute to the tag, such as:
<i class="fa fa-camera-retro fa-5x"></i>
However, if I add the fa-5x to the FaFolderOpen tag, it does not do anything. As you can see, I am using react-bootstrap, and placing the icon a button (should it be a block)?
I have to believe this has been asked before, but I did not find it via search.
Here is what it looks like, and I want it larger:
const React = require('react')
import { Form, FormControl, FormGroup, ControlLabel, Col, Button, Tooltip, OverlayTrigger } from 'react-bootstrap'
import FaFolderOpen from 'react-icons/lib/fa/folder-open'
import FaFileCodeO from 'react-icons/lib/fa/file-code-o'
import FaFolderOpen from 'react-icons/lib/fa/folder-open'
import FaFileCodeO from 'react-icons/lib/fa/file-code-o'
<Button type="button" bsStyle="success" block onClick={(e) => folderChooser(e)}>
<FaFolderOpen />
</Button>
if you want a 5x icon size you need to pass it to the react class as size
// Font awesome pixel sizes relative to the multiplier.
// 1x - 14px
// 2x - 28px
// 3x - 42px
// 4x - 56px
// 5x - 70px
<FaFolderOpen size={70} />
if you notice it jumps by 14 each time
from the github readme it shows everything is overridden inline. its rendering a svg so you cant use 5x you have to use a pixel size
Edit
Coming back to this a few years later, with newer versions of FontAwesome/ReactIcons the recommended way to handle different sizings is with their icon provider that utilizes the React Context API. This requires React v16.3+
import { IconContext } from "react-icons";
<IconContext.Provider value={{ className: "shared-class", size: 70 }}>
<>
<FaFolder />
<FaBeer />
</>
</IconContext.Provider>
In reactjs you can use size = 'with your preferred size which be from sm to lg or 1x to 10x'
this is example for font awesome 5 in react
<FontAwesomeIcon icon={faBars} size = '10x'/>
If you need to style several icons simultaneously, you can wrap them to IconContext.Provider.
<IconContext.Provider value={{color: 'navy', size: 42}}>
<FaFacebook />
<FaGithub />
<FaLinkedin />
</IconContext.Provider>
An approach that is not very explicitly comes from docs (close to #Raimo Haikari):
App.jsx
import {IconContext} from "react-icons";
import { FaBeer } from 'react-icons/fa';
import './App.css'
class App extends component {
return (
<div>
<IconContext.Provider value={{ className="myReact-icons"}}>
<FaBeer />
</IconContext.Provider>
</div>);
}
App.css
.myreact-icons {
color: red;
height: 2em;
}
The default size is 1em. You can change it like this:
import { FcSurvey } from 'react-icons/fc';
<FcSurvey size={'2em'} />
Just to complement, because I was able to do it differently, you can also use the CSS property font-size or fontSize in JSON notation.
Using CSS in external file :
/* style.css */
.bigIcon {
font-size: 25px;
}
// index.jsx
import { FiPackage } from 'react-icons/fi';
import './style.css';
(...)
<FiPackage className="bigIcon" />
or (JSON syntax)
// index.jsx
import { FiPackage } from 'react-icons/fi';
(...)
<FiPackage style={{fontSize:'25px'}} />
I have a designer giving me pixel sizes that don't always correspond to one of FontAwesome's size options. So I'm setting the CSS height.
<FontAwesomeIcon icon={faBars} style={{ height: "20px" }} />
React-Icons has a prop called size that can be used to set to any size you want.
after importing the react-icon from the react-icon library, you can easily do something like this.
<FaUsers size={'4rem'} />
You can use this:
<FaFolderOpen size="4x" />

Resources