I'm trying to rotate a chevronDown button in react.js but the button is static.
here is my code.
import React, { useState, useEffect, useRef } from 'react'
import { chevronDown } from '../assets';
import styles from '../styles';
import { useOnClickOutside } from '../utils';
const AmountIn = () => {
const [showList, setShowList] = useState(false);
return (
<div className={styles.amountContainer}>
<input
placeholder="0.0"
type="number"
value=""
disabled={false}
onChange={() => {}}
className={styles.amountInput}
/>
<div className="relative" onClick={() => setShowList((prevState) => !prevState)}>
<button className={styles.currencyButton}>
{"ETH"}
<img
src={chevronDown}
alt="chevron down"
className={'w-4 h-4 object-contain ml-2 ${showList ? 'rotate-180' : 'rotate-0'}'}
/>
</button>
</div>
</div>
)
}
export default AmountIn
I'm expecting the button to rotate when the cursor is pointed at the button.
You can do this with the CSS :hover selector using transform. In your CSS module, you would use something like this to flip a chevron around
.currencyButton {
// core styling
&:hover {
img {
transform: rotate(0.5turn);
}
}
}
To expand on that, you can animate the change using a CSS transition.
Related
I am working with React Bootstrap Modal. I'm trying to change the closeButton icon. But it didn't work.
<Modal.Header className='modal-head' closeButton>
<Modal.Title>Cart</Modal.Title>
</Modal.Header>
I don't think react-bootstrap library provides anything as such by itself. Although what you can do it add an icon right aligned in the modal header and add an onClick action which changes the modal's open state and closes it.
*You can take a look to this example, maybe it will be more clear to you.
You have just to import LoginButton.
Focus on
handleShow
export const LoginButton = () => {
const [fullscreen, setFullscreen] = useState(true);
const [show, setShow] = useState(false);
function handleShow(breakpoint) {
setShow(breakpoint);
setFullscreen(true);
}
return (
<div>
<Button className="me-2 mb-2" onClick={() => handleShow(true)}>
Login
</Button>
<Modal className="Modal_Login" show={show} fullscreen={fullscreen} onHide={() => setShow(false)} >
<Modal.Header className="Modal_Login_header" >
<Modal.Title className=" Modal_Login_header_title col-md-4" >Login</Modal.Title>
<Button className="col-md-2" onClick={() => handleShow(false)}> CLose </Button>
</Modal.Header>
<Modal.Body>Modal body content</Modal.Body>
</Modal>
</div>
)
};
CSS:
.Modal_Login{
display: flex;
flex-direction:row;
}
.Modal_Login_header{
display: flex;
flex-direction:row;
justify-content: flex-end;
}
Summary:
I have this logo in my website header, I want this logo (image [1]) to change to another one (image [2]) on scrolling down, and to change back to the original logo (image [1]) when I scroll back to the top.
What i tried:
I tried to make it with EventListener and useEffect in the header page, but I'm getting this error below:
ERROR in src\layouts\Navbar\index.jsx
Line 12:3: 'listenScrollEvent' is not defined no-undef
My code:
import React, { useState } from 'react'
import { useEffect } from "react";
export default () => {
useState = {
imageSrc: '',
imageAlt: ''
}
listenScrollEvent = e => {
if (window.scrollY > 400) {
this.setState({
imageSrc: './/img/Smartlogger_logo.png',
imageAlt: 'smartlogger white logo'
})
} else {
this.setState({
imageSrc: './../../views/Home/image/smartLoggerheader_logo.png',
imageAlt: 'smartlogger colored logo'
})
}
}
useEffect(() => {
window.addEventListener('scroll', this.listenScrollEvent)
}, []);
return (
<header className='header-area header-sticky'>
<div className='container'>
<div className='row'>
<div className='col-12'>
<nav className='main-nav'>
{/* ***** Logo Start ***** */}
<a href='/#' className='logo'>
<style>{css}</style>
<img
src={this.setState}
alt='Smartlogger logo'
/>
</a>
{/* ***** Logo End ***** */}
</nav>
</div>
</div>
</div>
</header>
)
}
You need to make the following changes in your code. It should fix the issue.
Inside render() - img src replace src={this.setState} with src={this.state.imageSrc}
Inside listenScrollEvent function replace window.scrollY with event.srcElement.body.scrollY
it will look like this (I have used random images here):
listenScrollEvent = event => {
if (event.srcElement.body.scrollY > 400) {
this.setState({
imageSrc: 'https://c.tenor.com/57w9du3NrV0AAAAS/css-html.gif',
imageAlt: 'smartlogger white logo'
})
} else {
this.setState({
imageSrc: 'https://c.tenor.com/57w9du3NrV0AAAAS/css-html.gif',
imageAlt: 'smartlogger colored logo'
})
}
}
Full working code : (I have added style={{height:'200vh'}} on container div just to test it on my local. You can remove it)
import React from 'react'
import { Link } from 'react-router-dom'
export default class App extends React.Component {
state = {
imageSrc: 'https://c.tenor.com/TReUojNlZ6wAAAAi/js-javascript.gif',
imageAlt: ''
}
listenScrollEvent = event => {
if (event.srcElement.body.scrollY > 400) {
this.setState({
imageSrc: 'https://c.tenor.com/57w9du3NrV0AAAAS/css-html.gif',
imageAlt: 'smartlogger white logo'
})
} else {
this.setState({
imageSrc: 'https://c.tenor.com/57w9du3NrV0AAAAS/css-html.gif',
imageAlt: 'smartlogger colored logo'
})
}
}
componentDidMount() {
window.addEventListener('scroll', this.listenScrollEvent)
}
render() {
return (
<header className='header-area header-sticky'>
<div className='container' style={{height:"200vh"}}>
<div className='row'>
<div className='col-12'>
<nav className='main-nav'>
{/* ***** Logo Start ***** */}
<a href='/#' className='logo'>
{/* <style>{css}</style> */}
<img
src={this.state.imageSrc}
alt='Smartlogger logo'
/>
</a>
{/* ***** Logo End ***** */}
</nav>
</div>
</div>
</div>
</header>
)
}
}
Hope that's how you wanted it to work. Try running it on your local and then you can modify it as per your requiremnets.
In your useState hook you want to have your src and your alt.
Remember useState return an array of 2 elements, the first is the value and the second is the setter for that value.
You can use the setter in your listenScrollEvent function and you can use the value in your jsx.
You are also using a css variable in you jsx that isn't defined anywhere.
It should look something like this:
import React, { useState, useEffect } from "react";
export default () => {
const [image, setImage] = useState({
src: "",
alt: "",
});
const listenScrollEvent = (e) => {
if (window.scrollY > 400) {
setImage({
src: "../img/Smartlogger_white_logo.png",
alt: "smartlogger white logo",
});
} else {
setImage({
src: "../img/Smartlogger_colored_logo.png",
alt: "smartlogger colored logo",
});
}
};
useEffect(() => {
window.addEventListener("scroll", listenScrollEvent);
}, []);
return (
<header className="header-area header-sticky">
<div className="container">
<div className="row">
<div className="col-12">
<nav className="main-nav">
{/* ***** Logo Start ***** */}
<a href="/#" className="logo">
<style>{css}</style>
<img src={require(image.src)} alt={image.alt} />
</a>
{/* ***** Logo End ***** */}
</nav>
</div>
</div>
</div>
</header>
);
};
An alternative solution that looks a little cleaner to me:
import React, { useState, useEffect } from "react";
import whiteLogo from "../img/Smartlogger_white_logo.png";
import coloredLogo from "../img/Smartlogger_colored_logo.png";
export default () => {
const [isScrolled, setIsScrolled] = useState(false);
const listenScrollEvent = (e) => setIsScrolled(window.scrollY > 400);
useEffect(() => {
window.addEventListener("scroll", listenScrollEvent);
}, []);
return (
<header className="header-area header-sticky">
<div className="container">
<div className="row">
<div className="col-12">
<nav className="main-nav">
{/* ***** Logo Start ***** */}
<a href="/#" className="logo">
<style>{css}</style>
<img
src={isScrolled ? whiteLogo : coloredLogo}
alt={
isScrolled
? "SmartLogger white logo"
: "SmartLogger colored logo"
}
/>
</a>
{/* ***** Logo End ***** */}
</nav>
</div>
</div>
</div>
</header>
);
};
EDIT: added note about css variable, fixed typo in code and formatted better
EDIT2: fixed image link and added the require in the img src attribute, this should fix the image loading
EDIT3: added alternative solution
I am trying to create a Bootstrap sidebar like this picture here.
I have looked at all the code on react-bootstrap and Twitter Bootstrap and I am yet to find a how-to code this. Basically, if they are viewing on a desktop, I want the sidebar to be visible, otherwise hidden.
The sidebar should stay still while the content on the page scrolls up and down.
Ok so for people who want to make a sidebar sadly the news is you gotta make it all yourself.
What I have done is the following.
See the example at https://github.com/StartBootstrap/startbootstrap-simple-sidebar
Create sidebar.js somewhere in your app.
import React from "react";
import {Nav} from "react-bootstrap";
import { withRouter } from "react-router";
import '../pages/style/Dashboard.css'
const Side = props => {
return (
<>
<Nav className="col-md-12 d-none d-md-block bg-light sidebar"
activeKey="/home"
onSelect={selectedKey => alert(`selected ${selectedKey}`)}
>
<div className="sidebar-sticky"></div>
<Nav.Item>
<Nav.Link href="/home">Active</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-1">Link</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-2">Link</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="disabled" disabled>
Disabled
</Nav.Link>
</Nav.Item>
</Nav>
</>
);
};
const Sidebar = withRouter(Side);
export default Sidebar
My Dashboard.css has the following in it.
.sidebar {
position: fixed;
top: 0;
bottom: 0;
left: 0;
min-height: 100vh !important;
z-index: 100;
padding: 48px 0 0;
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
}
#sidebar-wrapper{
min-height: 100vh !important;
width: 100vw;
margin-left: -1rem;
-webkit-transition: margin .25s ease-out;
-moz-transition: margin .25s ease-out;
-o-transition: margin .25s ease-out;
transition: margin .25s ease-out;
}
#sidebar-wrapper .sidebar-heading {
padding: 0.875rem 1.25rem;
font-size: 1.2rem;
}
#page-content-wrapper {
min-width: 0;
width: 100%;
}
Then final step
In the file you want it to be show in do the following
import React from "react";
import {Container, Row, Col, Card, Form, Button } from "react-bootstrap";
import { withRouter } from "react-router";
import Sidebar from "../moduls/sidebar.js";
import './style/Dashboard.css'
const Dash = props => {
return (
<>
<Container fluid>
<Row>
<Col xs={2} id="sidebar-wrapper">
<Sidebar />
</Col>
<Col xs={10} id="page-content-wrapper">
this is a test
</Col>
</Row>
</Container>
</>
);
};
const Dashboard = withRouter(Dash);
export default Dashboard
As of 2022 there is pure react-boostrap based component called react-boostrap-sidebar-menu . It is the cleanest solution so far and quite customizable.
https://www.npmjs.com/package/react-bootstrap-sidebar-menu
https://github.com/ivp-dev/react-bootstrap-sidebar-menu
import SidebarMenu from 'react-bootstrap-sidebar-menu';
<SidebarMenu>
<SidebarMenu.Header>
<SidebarMenu.Brand>
{/* Your brand icon */}
</SidebarMenu.Brand>
<SidebarMenu.Toggle />
</SidebarMenu.Header>
<SidebarMenu.Body>
<SidebarMenu.Nav>
<SidebarMenu.Nav.Link>
<SidebarMenu.Nav.Icon>
{/* Menu item icon */}
</SidebarMenu.Nav.Icon>
<SidebarMenu.Nav.Title>
{/* Menu item title */}
</SidebarMenu.Nav.Title>
</SidebarMenu.Nav.Link>
<SidebarMenu.Nav/>
<SidebarMenu.Sub>
<SidebarMenu.Sub.Toggle>
<SidebarMenu.Nav.Icon />
<SidebarMenu.Nav.Title>
{/* Submenu title */}
</SidebarMenu.Nav.Title>
</SidebarMenu.Sub.Toggle>
<SidebarMenu.Sub.Collapse>
<SidebarMenu.Nav>
<SidebarMenu.Nav.Link>
<SidebarMenu.Nav.Icon>
{/* Submenu item icon */}
</SidebarMenu.Nav.Icon>
<SidebarMenu.Nav.Title>
{/* Submenu item title */}
</SidebarMenu.Nav.Title>
</SidebarMenu.Nav.Link>
</SidebarMenu.Nav>
</SidebarMenu.Sub.Collapse>
</SidebarMenu.Sub>
<SidebarMenu.Body/>
</SidebarMenu>
One can now use a library, react-bootstrap-drawer, which provides a sidenav / drawer which was taken directly from the react-bootstrap documentation. Oddly, this is not a component provided by the library itself so one must use a third-party library:
import 'react-bootstrap-drawer/lib/style.css';
import React, { useState } from 'react';
import {
Col,
Collapse,
Container,
Row,
} from 'react-bootstrap';
import { Drawer, } from 'react-bootstrap-drawer';
const ApplicationDrawer = (props) => {
const [open, setOpen] = useState(false);
const handleToggle = () => setOpen(!open);
return (
<Drawer { ...props }>
<Drawer.Toggle onClick={ handleToggle } />
<Collapse in={ open }>
<Drawer.Overflow>
<Drawer.ToC>
<Drawer.Header href="/">Application</Drawer.Header>
<Drawer.Nav>
<Drawer.Item href="/settings">Settings</Drawer.Item>
</Drawer.Nav>
</Drawer.ToC>
</Drawer.Overflow>
</Collapse>
</Drawer>
);
};
const Application = (props) => {
return (
<Container fluid>
<Row className="flex-xl-nowrap">
<Col as={ ApplicationDrawer } xs={ 12 } md={ 3 } lg={ 2 } />
<Col xs={ 12 } md={ 9 } lg={ 10 }>{ props.children }</Col>
</Row>
</Container>
);
};
See: https://github.com/SimpleSigner/react-bootstrap-drawer
of course, you have to make the navbar yourself and the examples above are very valid, but cdbreact speeds up the process a lot faster. just add cdbreact using
npm I cdbreact
or
yarn add cdbreact
and then import CDBSidebar, CDBSidebarContent, CDBSidebarHeader, etc. with cdbreact, you don't need to bother about installing bootsrap in your react app.
cdbreact also comes with icons, and a lot more.
import React from 'react'
import {CDBSidebar,
CDBSidebarContent,
CDBSidebarHeader,
CDBSidebarFooter, CDBSidebarMenu,
CDBSidebarMenuItem} from 'cdbreact';
import {NavLink, Link} from 'react-router-dom';
import {} from 'react-router-dom';
const Sidebar=()=>{
return (
<div style={{display:'flex', height:'100%', overflow:'scroll initial'}}>
<CDBSidebar textColer="#fff" backgroundColor="rgb(37, 90, 122)">
<CDBSidebarHeader prefix={<i className="fa fa-bars fa-large"></i>}>
<Link to="/dashboard">Dashboard</Link>
</CDBSidebarHeader>
<CDBSidebarContent className="sidebar-content">
<CDBSidebarMenu>
<NavLink exact to="/dashboard" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="columns">
Transfer
</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/dashboard" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="columns">
Transfer
</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/dashboard" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="columns">
Transfer
</CDBSidebarMenuItem>
</NavLink>
<NavLink exact to="/dashboard" activeClassName="activeClicked">
<CDBSidebarMenuItem icon="columns">
Transfer
</CDBSidebarMenuItem>
</NavLink>
</CDBSidebarMenu>
</CDBSidebarContent>
<CDBSidebarFooter style={{textAlign:'center'}}>
<div className="sidebar-btn-wrapper" style={{ padding :'20px 5px' }}>
sidebar footer
</div>
</CDBSidebarFooter>
</CDBSidebar>
</div>
)
}
export default Sidebar;
you can also follow the guide here https://dev.to/devwares/how-to-create-a-responsive-sidebar-in-react-using-bootstrap-and-contrast-5gi2 follow this link to see
import React from "react";
import "./About.css";
import About_Main from "../components/About_Main";
import About_Data1 from "../components/About_Data1";
import About_Data2 from "../components/About_Data2";
class About extends React.Component {
state = {
main: {
display:"block",
opacity:1
},
data: {
display:"none",
opacity:0
}
};
changeSelect = id => {
if (id === "select1") {
this.setState({
main: {
display:"block",
opacity:1
},
data: {
display:"none",
opacity:0
}});
} else if (id === "select2") {
this.setState({
main: {
display:"none",
opacity:0
},
data: {
display:"block",
opacity:1
}});
}
};
clickHandler = event => {
event.preventDefault();
this.changeSelect(event.target.id);
};
render() {
return (
<div>
<section className="selects">
<div
id="select1"
className="select"
onClick={this.clickHandler}
></div>
<div
id="select2"
className="select"
onClick={this.clickHandler}
></div>
</section>
<section className="about">
<div
className="about_div"
style={{ display: this.state.main.display, opacity: this.state.main.opacity }}
>
<About_Main></About_Main>
</div>
<div
className="about_data"
style={{ display: this.state.data.display, opacity:this.state.data.opacity }}
>
<About_Data1></About_Data1>
<About_Data2></About_Data2>
</div>
</section>
</div>
);
}
}
export default About;
By clicking 2 different buttons, I want to show only one out of two.
Also, I like to give a transition effect so I used opacity. But it is not working!
Is this the only way to set style property using javascript in react?
Can't I use querySelector or something else?
I feel like javascript is much easier than react ðŸ˜ðŸ˜
What I want to do is have something like this:
<button class="addMore">+</button>
Do an effect like this:
https://i.gyazo.com/d353b657df39c0e6ff159bfdb713f6a4.mp4
when you hover over it.
I've been able to find a few different things for this but none that act as I want it to in the video.
Use title in order to display your message:
<button class="addMore" title="click here">+</button>
.addMore{
border: none;
width: 32px;
height: 32px;
background-color: #eee;
transition: all ease-in-out 0.2s;
cursor: pointer;
}
.addMore:hover{
border: 1px solid #888;
background-color: #ddd;
}
<button class="addMore" title="Hover on me!">+</button>
<button type='submit' title='Add New Item'>+</button>
You can set the background color change of button using css as follows,
.addMore:hover {
background-color: #545454; //desired color code
}
and set the tooltip as <button class="addMore" title="click here">+</button>
For all my React.JSers out there, (and for folks that come after), I was able to achieve this by doing (and using the reactstrap lib):
Usage of Tooltip component
import { Button } from 'reactstrap'
<Tooltip
tooltipContent={
'You cannot cancel invoices that were created automatically by memberships!'
}
component={
<span id={'cancelButton'}>
<Button
style={{ pointerEvents: 'none' }}
onClick={...}
disabled
>
Cancel
</Button>
</span>
}
/>
Tooltip.jsx
import React, { useState } from 'react'
import * as Reactstrap from 'reactstrap'
const Tooltip = props => {
const [tooltipOpen, setTooltipOpen] = useState(false)
const toggle = () => setTooltipOpen(!tooltipOpen)
// Warnings for component useage
if (!props.component) {
console.warn('Missing component for tooltip')
}
if (!props.tooltipContent) {
console.warn('Missing content for tooltip')
}
if (props.component && !props.component.props.id) {
console.warn('Component for tooltip has no id (must not have spaces)')
}
return (
<React.Fragment>
{props.component}
{props.tooltipContent && (
<Reactstrap.Tooltip
placement={props.placement ? props.placement : 'top'}
isOpen={tooltipOpen}
target={props.component.props.id}
toggle={toggle}
delay={props.delay ? props.delay : 750}
>
{props.tooltipContent && (
<div className="row p-2">
<div className="col-md-12">{props.tooltipContent}</div>
</div>
)}
</Reactstrap.Tooltip>
)}
</React.Fragment>
)
}
Tooltip.displayName = 'Tooltip'
export default Tooltip
The most important parts are the style={{ pointerEvents: 'none' }} on the <Button /> element and the nesting of the Button within a <span />