How to prevent button from losing focus when clicking elsewhere on screen? - reactjs

I am fairly new to React and I am using styled-components.
const Button = styled.button`
height: 35px;
width: 85px;
color: #0288d1;
border: 1px solid #0288d1;
background: white;
border-radius: 1px;
&:hover {
cursor: pointer;
background: #cfe8ef;
}
&:focus {
background: #0288d1;
color: white;
}
`;
I would like to prevent the button from losing focus when the user clicks somewhere else on the screen. Would I need to add additional JavaScript code to do this or is there a CSS property that can help me with this issue?

Try below:
const setFocus = e => {
e.target && e.target.focus();
};
return (
<button
onBlur={e => {
setFocus(e);
}}
>
My Button
</button>
);

You can add :active in global stylesheet.
button:active {
border: 2px solid #000;
}
So any time, button tags receive this style in active mode.

Related

How can i remove the Button hover color in Mui?

I need to disable the hover color but seems like its not working !
const ButtonWrapper = styled(Box)`
display: flex;
margin: 0 3% 0 auto;
& > button,
& > p,
& > div {
margin-right: 40px;
align-items: center;
font-size: 16px;
}
`;
const LoginButton = styled(Button)`
color: #2874f0;
cursor: pointer;
background: #fff;
border-radius: 2px;
margin-left: 45px;
box-shadow:none;
border:1px solid #DBDBDB;
padding: 5px 40px 5px 40px;
text-transform:none;
font-weight:500;
height:32px;
width:130px;
`;
const CustomButtons = () => {
return (
<ButtonWrapper>
<LoginButton variant="contained">Login</LoginButton>
</ButtonWrapper>
);
};
export default CustomButtons;
There is a blue hover effect coming that i dont want; I tried the inline style sx={{ "&:hover": { backgroundColor: "transparent" }} } but its not working.
How can i add the transparent style to the LoginButton using the &:hover?
i written like
const LoginButton = styled(Button)`
color: #2874f0;
cursor: pointer;
background: #fff;
border-radius: 2px;
margin-left: 45px;
box-shadow:none;
border:1px solid #DBDBDB;
padding:5px 40px 5px 40px;
text-transform:none;
font-weight:500;
height:32px;
width:130px;
//dont know the correct syntax
"&:hover": {
background-color: transparent;
}
`;
//its not working
It is the MuiButton-root class which is not letting you change the background color. You can target this class using sx prop or styled. Check the fix below, I'm using sx prop and targeting MuiButton-root class and setting the background to transparent.
<LoginButton variant="contained" sx={{ '&.MuiButton-root:hover':{bgcolor: 'transparent'} }}>
Login
</LoginButton>

onClick doesn't work on Button Style Component in Mobil View

I have a styled.button that works perfectly on desktop view, but when on my desktop I toggle to mobile view it doesn't work at all.
Button:
const DateElement = styled.button`
background-color: ${(props) => (props.primary ? '#DEE2FF' : '#696B86')};
color: ${(props) => (props.primary ? 'black' : '#dedee4')};
box-shadow: none;
padding: 9px;
width: 90px;
text-align: center;
height: 90px;
user-select: none;
border: 1px solid rgba(20, 79, 118, 0.2);
& :hover {
cursor: pointer;
}
& :focus {
display: none;
}
${(theme) => theme.theme.breakpoints.down('sm')} {
padding: 3px;
width: 70px;
text-align: center;
height: 70px;
}
`;
render:
return (
<DateElement
key={date.getTime()}
primary={isSelected}
onClick={() => handleClick(date)}
className={clsx({
[classes.crossed]: date.getTime() + endTimeMilli < today.getTime(),
[classes.containerWidth]: dates.length > 4,
})}
>
<Typography className={classes.date}>{getWeekDay(date)}</Typography>
<Typography className={classes.month}>{getMonth(date)}</Typography>
<Typography className={classes.day}>{date.getDate()}</Typography>
</DateElement>
);
What is the issue?
How can I fix this?
I end up fixing it changing the styled component from button to div, I just changed it and it work, I still don't understand why or how but it worked.
const DateElement = styled.div`
Is it because you are using theme.theme?
${(theme) => theme.theme.breakpoints.down('sm')} {..
I could be wrong but not how it usually looks according to the docs: https://mui.com/customization/breakpoints/

How can I add custom CSS to my React component and override the default CSS value?

I have a component for my button with its own css file, but I'm trying to figure out how to add a className directly to the component and change the CSS for mobile view. Right now, the Button.css file overrides everything and my new className added to the component doesn't even show up in the html.
Here is the Button.js file
import React from 'react';
import './Button.css'
const STYLES = [
'btn--primary',
'btn--outline'
]
const SIZES = [
'btn--medium',
'btn--large'
]
export const Button = ({
children,
type,
onClick,
buttonStyle,
buttonSize
}) => {
const checkButtonStyle = STYLES.includes(buttonStyle) ? buttonStyle : STYLES[0]
const checkButtonSize = SIZES.includes(buttonSize) ? buttonSize : SIZES[0]
return (
<button className={`btn ${checkButtonStyle} ${checkButtonSize}`} onClick={onClick} type={type}>
{children}
</button>
)
}
Here is the Button.css
:root {
--primary: #3acbf7;
}
.btn {
padding: 8px 20px;
border-radius: 4px;
outline: none;
border: none;
cursor: pointer;
}
.btn:hover {
background-color: transparent;
color: #fff;
padding: 8px 20px;
border-radius: 4px;
border: solid 2px var(--primary);
transition: all 0.3s ease-out;
}
.btn--primary {
background-color: var(--primary);
}
.btn--outline {
background-color: transparent;
color: #fff;
padding: 8px 20px;
border-radius: 4px;
border: solid 1px var(--primary);
transition: all 0.3s ease-out;
}
.btn--medium {
padding: 8px 20px;
border-radius: 4px;
font-size: 18px;
color: #fff;
}
.btn--large {
padding: 12px 26px;
border-radius: 4px;
font-size: 20px;
color: #fff;
}
And here is the main component where I'm trying to add a custom className to override the code above. Note this code is inside of a Navbar component.
import React, { Component } from 'react';
import { MenuItems } from "./MenuItems"
import { Button } from "../Button"
import './Navbar.css'
class Navbar extends Component {
render() {
return (
<nav className="NavbarItems">
<Button className="btn-mobile">Sign Up</Button>
</nav>
)
}
}
If I try to add .btn-mobile to my Navbar.css, none of the properties show up in the html. I tried to add an id and still didn't work. Not sure how to custom the button since it's a component with preset properties
The way that I generally accomplish this is to accept className as a prop and spread it into the default classes of the element, like so:
const Button = ({className='', text, ...rest}) => (
<button className={`my-button-class ${className}`} {...rest}>{text}</button>
)
Then you could use it like so:
<Button className="my-custom-class" text="press me" id="my-id" />
and it will render as
<button class="my-button-class my-custom-class" id="my-id">press me</button>
By defaulting the className prop to an empty string, it won't be added as the string of "undefined" if the implementation doesn't pass a className. Note that we also spread in any other props that were passed.

Design Bootstrap dynamic nav tabs component

I want to design a dynamic nav tabs component. when the card is clicked relevant tab is shown, with the connection arrow and border-color green.
sample code or a suggestion would be much helpful
.
You can use accordion by bootstrap. Use css flexbox to horizontally align the tabs next to each other and bind a javascript method that changes css color properties (arrow, green color) on clicking.
Here is the link - https://getbootstrap.com/docs/4.0/components/collapse/
Here is how you can do :
.js :
import React, { Component } from "react";
import { render } from "react-dom";
import "./style.css";
const App = () => {
const selectBlock = (e) => {
e.target.classList.toggle('selected');
}
return (
<div className="block" onClick={(e) => {selectBlock(e)}}>
<div>Here is the block</div>
<div className="arrow">
<FakeArrow />
</div>
</div>
);
};
const FakeArrow = () => {
return (
<div>
<span className="arrow-down-border" />
<span className="arrow-down" />
</div>
);
};
render(<App />, document.getElementById("root"));
.css :
.block {
position: relative;
width: 150px;
height: 50px;
text-align: center;
border: 2px solid black;
}
.arrow {
display: none;
}
.block.selected {
border: 2px solid #99d32c;
}
.block.selected .arrow {
display: block;
}
/* You need to fake the arrow border with another arrow behind */
.arrow-down-border {
position: absolute;
bottom: -20px;
left: 55px; /* 150px (main block) / 2 -20px (size of the triangle)*/
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #99d32c;
}
.arrow-down{
position: absolute;
bottom: -17px;
left: 58px; /* 150px (main block) / 2 -17px (size of the triangle)*/
width: 0;
height: 0;
border-left: 17px solid transparent;
border-right: 17px solid transparent;
border-top: 17px solid #ffffff;
}
Here is the repro on Stackblitz.
Of course this is just an example, you have to set a color for the arrows so my advice would be to do it with constants or props. Same thing for the position and others functionality you can add to the FakeArrow component.
Now, it would be waaaayy easier to manage it with an image if you really need a border (this is the tricky part in your requirement), or a simple arrow without border.
You can take a look at this post, it's the same question actually, i used a slightly different way to do it with css, but the result seems to be the same.

React Sematic-UI Dropdown renderLabel popup / tooltip on mouse hover

I'm making a react Sematic-UI Dropdown with multiselect and custom renderLabel function, I want to add tooltip / popup to these labels which show additional details of the item that the label represents. I have some rough idea how I might be able to do this, but I'm asking here first if someone has already done this or something similar and wants to share the knowledge.
http://react.semantic-ui.com/modules/dropdown/
currently I have this code:
renderLabel = (label) => {
return({
color: 'teal',
content: `${label.value}`,
icon: 'user'
})}
and it looks like:
I imagine I would need to do something like:
renderLabel = (label) => {
return({
color: 'teal',
content: `${label.value}`,
icon: 'user'
description: 'this is tooltip text...'
})}
and make an oldschool css tooltip of the description prop, something like:
[description] {position: -ms-device-fixed;}
[description]:before {
content:'';
/* hides the tooltip when not hovered */
display:none;
content:'';
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid #fff;
position:absolute;
top:30px;
left:35px;
z-index: 2;
font-size:0;
line-height:0;
width: .71428571em;
height: .71428571em;}
[description]:after {
display:none;
content:attr(description);
position:absolute;
top:35px;
left:0px;
padding:5px 10px;
background: #fff;
color: rgba(0,0,0,.87);
z-index:9;
font-size: 14px;
line-height: 1.4285em;
white-space:nowrap;
word-wrap:normal;
-webkit-transform-origin: left bottom;
-ms-transform-origin: left bottom;
transform-origin: left bottom;}
[description]:hover:before,[description]:hover:after {
display:block;}
but this is unpractical and hard coded, sematic-ui has popup module already in it, but I can't figure how to implement that here.
renderLabel={(a, b, c) => {
return (
<Popup
content={<div>Whatever i want here</div>}
eventsEnabled={true}
on="click"
onClose={() => setOpen(false)}
onOpen={() => setOpen(true)}
open={open}
trigger={<Label content={a.text} {...c} />}
/>
);
}}
You will need to improve setOpen method to just open the popop you want to be opened, maybe passing some id

Resources