Styled Components: nesting and referring to other components at the same time - javascript

<FooterLight transparent={true}/>
Is it possible to have a nested rule in definition of FooterLight for which the props value transparent is evaluated. Then it assigns 'color: white' to its children ChangelogVersion and CopyRight?
Next two questions:
Since color: white !important is the same for ChangelogVersion and CopyRight. Can these be merged together in one statement?
Does &&& work to not use !important?
export const FooterLight = styled(Navbar).attrs({fixed: 'bottom'})`
background-color: ${props => props.transparent
? 'transparent'
: 'white'};
${props => props.transparent && ChangelogVersion} {
color: white !important;
}
${props => props.transparent && CopyRight} {
color: white !important;
}
`
export const ChangelogVersion = styled(NavLink)`
&&& {
font-size: 14px !important;
padding-right: .5rem;
}
`
export const CopyRight = styled.div `
padding: .5rem 0;
color: '#777777';
font-size: 14px;
}

Sure can... You could do something like this:
export const FooterLight = styled(Navbar).attrs({fixed: 'bottom'})`
background-color: ${props => props.transparent
? 'transparent'
: 'white'};
${ChangelogVersion}, ${CopyRight} {
${props => props.transparent && "color: white !important;"}
}
`
As for your second statement, &&& might work but you're better off structuring the CSS better so it doesn't need to be !important in the first place... In you're example there's no reason for any of the importants to be there, so it's hard to offer a suggestion.

Related

Reducing Repetitive Code Within Styled-components

I'm using styled-components in a react project, and wondering if there's a way to reduce these 3 blocks that are repeating, with the only difference being the color of the border.
Initially, I'm thinking of creating an object that maps out the possible alert values (success, warning, danger), and add appropriate color as their keys, however I'm not sure where it to put that object.
const customStyles = {
${({ alert }) =>
alert === "success" &&
css`
border: 1px solid green;
`}
${({ alert }) =>
alert === "warning" &&
css`
border: 1px solid orange;
`}
${({ alert }) =>
alert === "danger" &&
css`
border: 1px solid red;
`}
}
const Input = styled.input`
${customStyles}
`;
How about a function you can reuse that returns the right color based on the value?
Something like this:
function getAlertColor(alert){
switch (alert) {
case "success":
return "green"
case "warning":
return "orange"
case "danger":
return "red"
}
}
const Input = styled.input`
border: ${props => `1px solid ${getAlertColor(props.alert)};`};
`;

React Styled Component doesn't show correct output

I've changed my style in StyledButton tag but it doesn't reflect on webpage. Can you help what is wrong in this code
import React, { Component } from 'react';
import './App.css';
//import Radium, {StyleRoot} from 'radium';
import Person from './Person/Person';
import { render } from 'react-dom';
import styled from 'styled-components'
const StyledButton = styled.button `
background-color: ${props => props.alt ? 'red' : 'green'}; //Here I have define these property which is not reflecting in output
color: white;
font: inherit;
border: 1px solid blue;
padding: 8px;
cursor:pointer;
&:hover:{
background-color:${props => props.alt ? 'salmon' : 'green'}; //Hover Function is also not working
color:black;
}`;
class App extends Component {
state ={
persons : [
{id:'12', name: 'Max', age: 28},
{id:'21', name: 'Manu', age:29},
{id:'33', name: 'Nikhil', age:23}
]};
nameChangeHandler = (event, id) => {
const personIndex = this.state.persons.findIndex(p=>{
return p.id===id;
});
const person = {
... this.state.persons[personIndex]
};
person.name = event.target.value;
const persons =[...this.state.persons];
persons[personIndex]=person;
this.setState({ persons: persons
});
}
deletePersonHandler = (personIndex) =>{
//const persons = this.state.persons.slice();
//const persons = this.state.persons
const persons = [... this.state.persons];
persons.splice(personIndex,1);
this.setState({persons: persons})
}
togglePersonsHandler = ()=> {
const doesShow = this.state.showPersons;
this.setState({showPersons: !doesShow});
}
render()
{
let persons = null;
if(this.state.showPersons)
{
persons = (
<div>
{ this.state.persons.map((person, index) =>{
return <Person
click = { () => this.deletePersonHandler(index) }
name={person.name}
age={person.age}
key= {person.id}
changed={(event)=> this.nameChangeHandler(event, person.id)}/>
})}
</div>
);
//StyledButton.backgroundColor= 'red';
}
let classes = []
if(this.state.persons.length<=2)
{
classes.push('red');
}
if(this.state.persons.length<=1)
{
classes.push('bold');
}
return (
<div className = "App">
<h1>Hi there this is my first react application</h1>
<p className= {classes.join(' ')}>Hi this is really working</p>
<StyledButton
alt ={ this.state.showPersons }
onClick = {this.togglePersonsHandler}>Toggle Persons</StyledButton>
{ persons }
</div>
);
}
}
export default App;
Code just toggle the names and ages when user click on button and delete the names when click on the paragraph and adding certain classes these are all works fine.
I'm using styled component package on toggle button and it is not working properly, I don't why Please let me know if you understand
You've defined alt to be a transient prop, i.e. $alt, but you don't pass that prop to the StyledButton.
You've also a typo in your hover selector, there's a trailing colon (:): &:hover: should be :hover (the leading parent node selector & is also unnecessary).
const StyledButton = styled.button `
background-color: ${props => props.$alt ? 'red' : 'green'};
color: white;
font: inherit;
border: 1px solid blue;
padding: 8px;
cursor: pointer;
:hover {
background-color:${props => props.$alt ? 'salmon' : 'green'};
color:black;
}
`;
...
<StyledButton
$alt={this.state.showPersons} // <-- pass transient prop
onClick={this.togglePersonsHandler}
>
Toggle Persons
</StyledButton>
This was introduced in v5.1. If you didn't intend to declare a transient prop or you aren't on v5.1 or newer, then simply remove the $ and use the alt prop.
const StyledButton = styled.button `
background-color: ${props => props.alt ? 'red' : 'green'};
color: white;
font: inherit;
border: 1px solid blue;
padding: 8px;
cursor: pointer;
:hover {
background-color:${props => props.alt ? 'salmon' : 'green'};
color:black;
}
}`;
...
<StyledButton
alt={this.state.showPersons} // <-- use alt prop
onClick={this.togglePersonsHandler}
>
Toggle Persons
</StyledButton>
Demo

how can i display round dot for active status in react

In older code of react it just display the text active or in active for an user. Now I want to replace it to red or green small dot how can I do it.
CSS
div .colored-circle {
display: inline-block;
margin-left: 5px;
margin-right: 5px;
margin-bottom: -2px;
border-radius: 50%;
border-style: solid;
border-width: 0.5px;
border-color: black;
height: 20px;
width: 20px;
}
Component:
const ColoredCircle = ({ color }) => {
const styles = { backgroundColor: color };
return color ? (
<Fragment>
<span className="colored-circle" style={styles} />
</Fragment>
) : null;
};
export default ColoredCircle;
Use the same logic you used to show 'active' or 'inactive' and instead of text add a div with css or img of the desired color.
If you happen to use material UI, you can do like this:
import React, { Fragment } from "react";
import { makeStyles } from "#material-ui/core";
const RADIUS_DOT = 1.5;
const useStyles = makeStyles((theme) => ({
circle: {
borderRadius: RADIUS_DOT,
height: RADIUS_DOT * 2,
width: RADIUS_DOT * 2,
padding: 0,
},
}));
const ColoredCircle = ({ color }) => {
const styles = { backgroundColor: color };
const classes = useStyles();
return color ? (
<Fragment>
<span className={classes.circle} style={styles} />
</Fragment>
) : null;
};
export default ColoredCircle;
you can use this package, can be helpful
npm i react-color-circle
import Circle from '#uiw/react-color-circle';
return (
<Circle
colors={[ '#F44E3B' ]}
/>);

Reusable parametric css with styled components

I'm using styled-components library in my react app and I've come across an interesting problem I wasn't able to find an elegant solution to online. What I want to achieve is to have a reusable piece of code, maybe similar to sass mixins, that would allow me to extend all my buttons with code that animates background darken on hover.
const DarkenHover = css<{ active?: boolean; normalColor: string; activeColor: string }>`
background-color: ${p => (p.active ? p.normalColor : p.activeColor)};
&:hover {
background-color: ${p => darken(0.1)(p.active ? p.normalColor : p.activeColor)};
}
transition: background-color .1s ease-in;
`;
const FooButton = styled.div<{ active?: boolean }>`
${p => DarkenHover({
active: p.active,
normalColor: "red",
activeColor: "blue",
})}
`;
const FooButton = styled.div<{ active?: boolean }>`
${p => DarkenHover({
active: p.active,
normalColor: "white",
activeColor: "green",
})}
`;
This obviously is not valid syntax but it demonstrates my use case. How can I use this DarkenHover css object with attributes?
You can save the styles in a var and reuse later.
const animation = css`
background-color: ${p => p.active ? ThemeColors.backgroundDark : "white"};
&:hover {
background-color: ${p => darken(0.1)(p.active ? p.normalColor : p.activeColor)};
}
transition: background-color .1s ease-in;
}
`;
The when you use it in another component, it should be able to access its props:
const FooButton = styled.div`
${animation};
`
Also to be able to have separate props per each styled components, those can be passed via attrs method:
const FooButton = styled.div.attrs({normalColor: '#000000' })`
${animation}
`;

Conditional styled-components in object notation

Styled components documentation doesn't mention this case and I can't figure out the syntax.
How would I turn this styled component:
const StyledButton = styled.button`
color: red;
${props => props.disabled && css`
color: grey;
background-color: grey;
`}
`
into object notation:
const StyledButton = styled.button(props => ({
color: 'red',
------
}))
I know the following would solve this question, but for my use case I need to keep the logic from the first exemple. So this won't make it for me:
const StyledButton = styled.button(props => ({
color: props.disabled ? 'grey' : 'red',
backgroundColor: props.disabled ? 'grey' : transparent,
}))
Maybe this would be what you're after (or similar)
const StyledButton = styled.button((props) => {
const disabledStyles = {
color: 'grey',
'background-color': 'grey',
};
return {
color: 'red',
...(props.disabled && disabledStyles)
};
})
I definitely don't understand why you can't use the ternary approach you have above but I've had some weird reqs on projects too. Good luck

Categories