Styled Components, createGlobalStyle from multiple files - styled-components

I'm using styled components and the createGlobalStyles to create global styles.
I want to have the styles in the createGlobalStyles to come from different styled component files and then have one file to create the createGlobalStyle. I'm havoing problems including the separate styled components into one file to create the creatGlobalStyle.
Here is a simpified example
//fonts.ts
export const Fonts = `
h1, h2, h3, h4, h5{
color: #aaa;
}
`
=
//fontFamily.ts
export const FontFamily = `
h1, h2, h3, h4, h5{
font-family: Arial;
}
`
=
//globalStyle.ts
import {createGlobalStyle} from 'styled-components';
import {Fonts} from './fonts'
import {Fonts} from './fontFamily'
export default createGlobalStyle`
Fonts
Fonts
`
How can I include the styles from the separate files in the createGlobalStyle

You can do it this way:
import { createGlobalStyle } from "styled-components";
import { Fonts } from "./fonts";
import { FontFamily } from "./fontFamily";
const GlobalStyle = createGlobalStyle`
${Fonts}
${FontFamily}
`;

If you have a lot of global styles like we did, you can use styled-components css method to leverage styled-components (css) IDE syntax highlighting & linting you can also do the following:
import React from 'react'
import { createGlobalStyle, css } from 'styled-components'
const Reset = css`
* {
box-sizing: border-box;
}
`
const Accessibility = css`
.hidden {
display: none !important;
visibility: hidden;
}
`
const BaseStyles = createGlobalStyle`
${Reset};
${Accessibility};
`
export const GlobalStyles = () => (
<>
<BaseStyles />
</>
)
Import GlobalStyles and render as sibling to {children}

Related

With styled components how to pass theme color from Global Style to React Icons Context Provider?

Looking for a way to pass color from theme to React Icons. Theme is working correctly and I'm able to pass colors to my styled components. Here is the breakdown:
index.js:
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
// Theme
import { ThemeProvider } from 'styled-components'
import { GlobalStyles } from './theme/GlobalStyles'
import Theme from './theme/theme'
ReactDOM.render(
<ThemeProvider theme={Theme}>
<GlobalStyles />
<App />
</ThemeProvider>,
document.getElementById('root'),
)
app.js (stripped down):
<IconContext.Provider value={{ color: `${({ theme }) => theme.colors.white}` }}>
<FaTimes />
<FaBars />
</IconContext.Provider>
the equivalent of:
<IconContext.Provider value={{ color: `#fff` }}>
<FaTimes />
<FaBars />
</IconContext.Provider>
does work and I did try:
NavElements.js:
import { IconContext } from 'react-icons/lib'
export const NavProvider = styled(<IconContext.Provider>{children}</IconContext.Provider>)`
color: ${({ theme }) => theme.colors.color2};
`
app.js:
// <IconContext.Provider value={{ color: `#fff` }}>
<NavProvider>
// Further code
</NavProvider>
// </IconContext.Provider>
but I get a children error. Attempt came from reading Q&A Styled-components and react-icons <IconContext.Provider> component
Other Q&As I found with no luck:
How to Style React-Icons
react-icons apply a linear gradient
With a theme color in Styled Components how can I pass that color to React Icons Provider?
I haven't worked with react-icon but this might help
Take a look at getting the theme without styled components - there is also a hook
Your example
export const NavProvider = styled(<IconContext.Provider>{children}</IconContext.Provider>)`
color: ${({ theme }) => theme.colors.color2};
`
work because styled expects a HTML element or a React component
Your NavProvider could be something like (haven't tried this code but it should work)
import { useContext } from 'react';
import { ThemeContext } from 'styled-components';
export const NavProvider = ({children}) => {
const themeContext = useContext(ThemeContext);
return (
<IconContext.Provider value={{ color: themeContext.colors.color2 }}>
{children}
</IconContext.Provider>
);
};

Target another component on hover using emotion-js

I understand this is very similar to Target another styled component on hover
However I would like to achieve the same effect with emotion-js
More specifically I am trying to recreate this example using emotion styled components
Here is my code and what I have tried.
import React from 'react';
import styled from '#emotion/styled';
import { Link } from 'gatsby';
const Dropdown = styled.div`
postition: relative;
display: inline-block;
`;
const Button = styled.div`
background-color: green;
color: white;
&:hover {
${DropDownContent} {
display: block;
}
}
`;
const DropDownContent = styled.div`
display: none;
position: absolute;
`;
const DropDownMenu = () => {
return (
<Dropdown>
<Button>Dropdown</Button>
<DropDownContent>
<Link to="/">Link 1</Link>
</DropDownContent>
</Dropdown>
);
};
export default DropDownMenu;
I would like the link to show up when I hover the button, but that is not working and I cannot figure out why
There are three issues here.
You're referencing DropdownContent before you've defined it. Rearrange your code so that the DropdownContent declaration comes before the tagged template literals that use it and you should be good to go.
The resulting css selector (something like button:hover .DropDownContent) does not match your HTML document, where DropDownContent is a sibling of Button.
Your position property on Dropdown is misspelled.
With all three issues resolved, your code may look something like this:
import React from 'react';
import styled from '#emotion/styled';
import { Link } from 'gatsby';
const Dropdown = styled.div`
position: relative;
display: inline-block;
`;
const DropDownContent = styled.div`
display: none;
position: absolute;
`;
const Button = styled.div`
background-color: green;
color: white;
&:hover + ${DropDownContent} {
display: block;
}
`;
const DropDownMenu = () => {
return (
<Dropdown>
<Button>Dropdown</Button>
<DropDownContent>
<Link to="/">Link 1</Link>
</DropDownContent>
</Dropdown>
);
};
export default DropDownMenu;
as #coreyward mentioned, rearrange the code.... and the
import styled from "#emotion/styled/macro";
and this will do the trick
This solution was already posted at Component selectors can only be used in conjunction with babel-plugin-emotion error while using emotion by https://stackoverflow.com/users/165215/ijk

Styling is not applied to styled component using style(StyledComponent) syntax

Styling a div using style.div works just fine.
But styling a styled component using style(FlexItem) does nothing.
What might be the reason?
import * as React from 'react';
import OuterSectionContainer from './../../ui/OuterSectionContainer';
import InnerSectionContainer from './../../ui/OuterSectionContainer/InnerSectionContainer';
import FlexContainer from './../../ui/OuterSectionContainer/InnerSectionContainer/FlexContainer';
import FlexItem from './../../ui/OuterSectionContainer/InnerSectionContainer/FlexContainer/FlexItem';
import ScaledImage from './../../ui/ScaledImage';
import styled from 'styled-components';
const Testamonials = () => {
const FlexItemStyled = styled(FlexItem)`
padding: 10px;
background-color: red;
display: none;
`;
return (
<OuterSectionContainer>
<InnerSectionContainer>
<FlexContainer>
<FlexItemStyled>
<ScaledImage src={require('../../../images/logo.png')} />
</FlexItemStyled>
<FlexItemStyled>
<ScaledImage src={require('../../../images/logo.png')} />
</FlexItemStyled>
<FlexItemStyled>
<ScaledImage src={require('../../../images/logo.png')} />
</FlexItemStyled>
<FlexItemStyled>
<ScaledImage src={require('../../../images/logo.png')} />
</FlexItemStyled>
</FlexContainer>
</InnerSectionContainer>
</OuterSectionContainer>
);
};
export default Testamonials;
FlexItem should not be a styled-components, then you should pass className in props to use styled(FlexItem) syntax.
more info here : https://www.styled-components.com/docs/basics#styling-any-components

Reuse a 'mixin' with Styled Components across different files?

How can I reuse a collection of styles with Styled Components across different files?
With SASS I can define and use a mixin like so:
#mixin section( $radius:4px ) {
border-radius: $radius;
background: white;
}
.box { #include section(); }
With Styled Components you can extend a style, but this means I would need to import that component into every page. This is pretty cumbersome compared to how variables are available everywhere with the ThemeProvider.
https://www.styled-components.com/docs/basics#extending-styles
Just adding on to the answer by #Evanss
You can make the mixin a function (as in OP) by doing:
const theme = {
sectionMixin: (radius) => `border-radius: ${radius};`
}
and then use it like:
const Button = styled.button`
${props => props.theme.sectionMixin('3px')}
`
or simply:
const Button = styled.button`
${({ theme }) => theme.sectionMixin('3px')}
`
You can create a string with multiple CSS rules and pass that to the ThemeProvider.
const theme = {
sectionMixin:
'background: white; border-radius: 5px; border: 1px solid blue;',
}
<ThemeProvider theme={theme}>

Styling react-select with styled-components

I'm trying to change the color of the select-up-arrow and the color of the control when it's in focus, but without success. Have anyone done this using styled-components?
This applies to react-select#v2.*
The same ideas as #bamse answer can be applied to v2 of react-select. The problem is that in v2 they removed pre-determined class names unless you specify to add them in with the prop classNamePrefix. They also changed what the class names in general look like.
General solution is to make sure to add in the class names with the prop classNamePrefix, then use styled around ReactSelect and target classes within it.
import React from 'react';
import ReactSelect from 'react-select';
import styled from 'styled-components';
const ReactSelectElement = styled(ReactSelect)`
.react-select__indicator react-select__dropdown-indicator {
border-color: transparent transparent red;
}
`;
export (props) => <ReactSelectElement classNamePrefix="react-select" {...props} />
This applies to react-select#v3.*
I had the same problem and solved it like this:
CustomSelect.js file:
import ReactSelect from 'react-select';
import styled from 'styled-components';
export const CustomSelect = styled(ReactSelect)`
& .Select__indicator Select__dropdown-indicator {
border-color: transparent transparent red;
}
`;
TheComponent.js file:
import React from 'react';
import { CustomSelect } from './CustomSelect';
export function TheComponent () {
return <div>
<CustomSelect
classNamePrefix={'Select'}
{* props... *}
/>
Something awesome here...
</div>
}
`;
Note the classNamePrefix={'Select'} in TheComponent.js - that's important.
This applies to react-select#v1.*
Here you can find an example of styling react-select with styled-components.
To change to caret's colour when the select is opened you can use this
&.Select.is-open > .Select-control .Select-arrow {
border-color: transparent transparent red;
}
The component would look like
import React from 'react';
import ReactSelect from 'react-select';
import styled from 'styled-components';
const RedCaretWhenOpened = styled(ReactSelect)`
&.Select.is-open > .Select-control .Select-arrow {
border-color: transparent transparent red;
}
`;
export (props) => <RedCaretWhenOpened {...props} />

Resources