How to apply styles to multiple components using styled components - javascript

I've created a icon.js file. It exports 3 SVG components to different files.
Like this :
export const MenuIcon = () => {
return (
<svg>
...
</svg>
);
};
export const ArrowLeftIcon = () => {
return (
<svg>
...
</svg>
);
};
export const SearchIcon = () => {
return (
<svg>
...
</svg>
);
};
And I would like to apply the same styles to all three of these components using styled components, not giving them a same className. Is there a solution for that? Thank you :)

I think the following steps could help you.
Steps
npm i styled-components#4.1.3
import styled from 'styled-components';
const StyledSvg = styled.svg` <---the html tag that you want to style
color: palevioletred; <---the css styles that you want to use
`;
Now use StyledSvg that you just created instead of the svg tags.
return(
<StyledSvg>
...
</StyledSvg>
);

Related

How to switch between global CSS onclick in Gatsby?

I'm building a portfolio site in Gatsby, and as I work more on the illustration and design side, would like to serve up multiple design options to showcase that work, based on a user selection via click. I've found some similar questions, but none that are specific to Gatsby.
I'm using styled components to create the layout, so It seems to me that just swapping between multiple Global stylesheets (with fonts, colors, etc) via a button would be the way to go, so the layout remains intact, but I'm honestly not sure how to go about this as I'm pretty beginner in Gatsby and Javascript in general.
Thanks in advance!
Given a simply <Layout> structure like:
import React from "react"
import { createGlobalStyle } from "styled-components"
const GlobalStyle = createGlobalStyle`
body {
color: ${props => (props.theme === "purple" ? "purple" : "white")};
}
`
export default function Layout({ children }) {
return (
<React.Fragment>
<GlobalStyle theme="purple" />
{children}
</React.Fragment>
)
}
You can easily attach an onClick event to the children by adding a boolean operator to switch your <GlobalStyle>, for example:
export default function somePage(){
const [defaultStyles, setDefaultStyles]=useState(false);
const handleChange=()=>setDefaultStyles(!defaultStyles)
return <Layout defaultStyles={defaultStyles}>
<h1 onClick={handleChange}> Click me to toggle the global styles</h1>
</Layout>
}
Basically, you are creating a boolean state (initially set as false) to change between default styles. The result of that state (toggled by clicking the <h1>) will be sent upwards to your <Layout> so, there:
import React from "react"
import { createGlobalStyle } from "styled-components"
const GlobalStyle = createGlobalStyle`
body {
color: ${props => (props.theme === "purple" ? "purple" : "white")};
}
`
export default function Layout({ children, defaultStyles }) {
return (
<React.Fragment>
{defaultStyles && <GlobalStyle theme="purple" />}
{children}
</React.Fragment>
)
}
The && operator will only render <GlobalStyle> if defaultStyles is true. Adapt it to your needs or add a ternary condition if needed.

ReactJS: Two different styles for one component

I have a component that I use twice in the same code, it looks like this:
import React from 'react';
import Container from 'Base/Grid/Container';
import styles from './index.css';
const Columns = props => <Container {...props} className={styles.root} block/>;
export default Columns;
How can i, when importing, apply another style class to the second used Columns?
thanks in advance
You can define another style beside of your styles.root that is passed from the props. Like below:
const Columns = props => <Container {...props} className={[styles.root,props.newStyles]} block/>;
So when you make a Columns component you can pass the specific styles. For example:
<Columns newStyles={{color: 'red'}} />
So you can customize the style for each component which you use.
or if you don't want to use the root style you can make it conditional that if there the newStyle was passed use it. If not just use the styles.root. And the code would be like this:
Columns = props => <Container {...props} className={props.newStyle || styles.root} block/>;
A clean solution is to use react composition. Declare the "base" component in one file, and then export in two different files with two different names the styled one.
// BaseComponent.jsx
export default Column = () => <div>Column</div>;
// RedColumn.jsx
import Column from './Column';
const RedColumn = () => <Column style={{color: "red"}} />;
export default RedColumn;
// BlueColumn.jsx
import Column from './Column';
const BlueColumn = () => <Column style={{color: "blue"}} />;
export default BlueColumn;

How to compose styled components in emotionjs with React?

What I would like to do is to compose multiple styled components into one.
With plain css this is very easy:
<button class="btn large red"></button>
This is my attempt with emotion in React:
import styled from "#emotion/styled/macro";
const A = styled.button({
color: "red"
});
const B = styled.button({
fontSize: 32
});
// I know how to add single styled component. But how to also add B here?
const C = styled(A)({
// some additional styles
});
function App() {
return (
<div className="App">
<A>A</A>
<B>B</B>
<C>C</C>
</div>
);
}
Please check the demo:
Demo
It seems like styled is not capable of combining multiple styled components by default.
You might want to look at the css functionality of emotion here. This allows the composition of multiple defined css styles. Even though this required more lines of code for the extra definition of the css objects.
Using css your example could look like this:
import styled from "#emotion/styled/macro";
import { css } from "#emotion/core";
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const red = css({
color: "red"
});
const A = styled.button(red);
const bolt = css({
fontSize: 32
});
const B = styled.button(bolt);
const C = styled.button(red, bolt);
function App() {
return (
<div className="App">
<A>A</A>
<B>B</B>
<C>C</C>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Demo

unable to add classes in react using create react app

a bit new to react.
I used the create react app https://github.com/facebook/create-react-app
to start a new react project.
the full code is here. https://github.com/bryandellinger/reactswitch/tree/master/src
I am trying to get the background color of a selected element to change and the text to become bold but it appears the class is never added not sure what I am doing wrong.
Switch.js
import React, { PropTypes } from 'react';
import styles from './Switch.css';
const CREDITCARD = 'Creditcard';
const BTC = 'Bitcoin';
const Choice = function (props) {
const cssClasses = [];
if (props.active) {
// <-- check props, not state
cssClasses.push(styles.active);
}
return (
<div
onClick={props.onClick}
className={cssClasses}
>
{props.label} {/* <-- allow any label */}
</div>
);
};
class Switch extends React.Component {
state = {
payMethod: BTC,
};
select = (choice) => {
return (evt) => {
this.setState({
payMethod: choice,
});
};
};
render() {
return (
<div className='switch'>
<Choice
onClick={this.select(CREDITCARD)}
active={this.state.payMethod === CREDITCARD}
label='Pay with Creditcard'
/>
<Choice
onClick={this.select(BTC)}
active={this.state.payMethod === BTC}
label='Pay with Bitcoin'
/>
Paying with: {this.state.payMethod}
</div>
);
}
}
export default Switch;
and Switch.css
.active {
background-color: #4619eb;
font-weight: bold;
}
it appears the active class from switch.css never gets added on the onclick event. not sure what I am missing.
Because of the way webpack is configured in CRA, you need to write your css like this:
:local(.active) {
background-color: #4619eb;
font-weight: bold;
}
CRA only supports importing the whole CSS file directly out of the box. So instead of importing the CSS file as a component, you would do:
import './Switch.css';
CRA docs for adding a stylesheet: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-stylesheet
Also, the className property should be a string with class names separated with a while space. If you want to set the class name dynamically, check out classnames: https://github.com/JedWatson/classnames.

How to override styles in a react-chartist component?

I have a simple React JS component that wraps around the really cool react ChartistGraph component. The only issue is that the styling is seemingly overridden by the ChartistGraph default CSS. There is a lot of info on the regular Chartist js package but not much on the React JS package.
As you can see, I'm trying to change the fill color two ways: through style classes and through a prop that supported on the component.
import React from 'react';
import { Paper, withStyles } from 'material-ui';
import ChartistGraph from 'react-chartist';
const styles = theme => ({
graphStyle: {
fill: 'red',
},
});
const CustomChart = ({ classes, graph }) => {
return (
<Paper>
<ChartistGraph
className={classes.graphStyle}
data={graph.data}
options={graph.options}
type={graph.type}
style={{ fill: 'red' }}
/>
</Paper>
);
};
export default withStyles(styles)(CustomChart);
A picture of the styles of the chart
You can use jss's nested rules (included by default in material-ui):
const styles = theme => ({
graphStyle: {
'& .ct-label': { fill: 'red' },
},
});
Full code:
import React from 'react';
import { Paper, withStyles } from 'material-ui';
import ChartistGraph from 'react-chartist';
const styles = theme => ({
graphStyle: {
'& .ct-label': { fill: 'red' },
},
});
const CustomChart = ({ classes, graph }) => {
return (
<Paper>
<ChartistGraph
className={classes.graphStyle}
data={graph.data}
options={graph.options}
type={graph.type}
// style={{ fill: 'red' }} // omitted
/>
</Paper>
);
};
export default withStyles(styles)(CustomChart);
I got into similar issue recently.React-Chartist is built on top of react not material-ui.When you inspect,you found regular css class names,not "material ui-ish" class-names(like MuiTable-root,MuiTable-selectedRow,etc).So ,imho,it won't support material-ui methods (withStyle/makeStyle) and rules.
But what you can do is:-
create a css file and put your styles there
And import it where you want
.You can import it on the main file of your app(index.js or whatever it is) since every css in your app will bundle in one file.

Categories