Styled components interpolation - javascript

I am wondering why everybody use styled components like this
export const Title = styled.div`
margin-top: 48px;
font-family: ${({ theme }) => theme.font};
font-size: ${({ theme }) => theme.sizeBig};
color: ${({ theme }) => theme.dark};
font-weight: ${({ theme }) => theme.fontWeight}
`
Rather than something like
export const Title = styled.div`
margin-top: 48px;
${({ theme }) => css`
font-family: ${theme.font};
font-size: ${theme.sizeBig};
color: ${theme.dark};
font-weight: ${theme.fontWeight}
`}
`
Is there any reason to create arrow function on every line?

Comes down to personal preference. I actually go a little bit further in my apps:
export const Title = styled.div(({ theme }) => css`
margin-top: 48px;
font-family: ${theme.font};
font-size: ${theme.sizeBig};
color: ${theme.dark};
font-weight: ${theme.fontWeight}
`)
I like it this way since each style is defined in a single template literal.
Styled Components marks some components as static as an optimisation step, if there's nothing to interpolate. Reading this, it seems like this approach would have no performance impact, since having just one property being interpolated marks the whole styled component as not static.

Related

Next JS styled components dark mode themeing

This probably has answer, but I was unable to find it
I am using styled components with next js and use-dark-mode hook to trigger theme change/detect
global styles switch before loading
import { createGlobalStyle } from "styled-components";
export const GlobalStyles = createGlobalStyle`
body {
background: ${props => props.theme.background};
color: ${props => props.theme.color};
font-family: Roboto, sans-serif;
margin: 0;
padding: 0;
}
`
but having simple styled component like this one
const BackgroundTopAppBar = styled.header`
background-color: ${props => props.theme.appBarHeaderBackground};
`;
doesnt change upon page loading and remains light theme colored
also inside _document.js is implemented next-js team example of how to use styled components for SSR and it works well, but for styled components that are not global dark mode is not activated after page is refreshed
thank you
For anybody looking for a solution, use GlobalStyles and in there modify current color of element because GlobalStyles will apply it before loading
export const GlobalStyles = createGlobalStyle`
body {
background: ${props => props.theme.background};
color: ${props => props.theme.color};
font-family: Roboto, sans-serif;
margin: 0;
padding: 0;
}
${BackgroundTopAppBar} {
background-color: ${props => props.theme.appBarHeaderBackground};
}
`

How to change the style of a single component within an other component with styled-components?

I'm working on an react app with styled-components and I have a component 'Navigation'. In this component are more components like , , etc.
Header for example is declared like this:
const Header = styled.div`
height: 48px;
width: 100%;
transition: all 0.5s ease-in;
Thing is that I have this Navigation component in different files and for all of them the styling is good but now I want to change the background color of the Header component in just one of those files, which is within(?) the Navigation component. How can I do that?
I know that it's possible to change the styling from the Navigation component with something like const NewNav = styled(Navigation)`` but what about the Header?
Thank you in advance.
You can pass props through your navigation component to your header.
<NavigationExample secondary />
import styled, { css } from 'styled-components';
function NavigationExample(props) {
const { secondary } = props;
return (
<Navigation>
<Header secondary={secondary}>
...
</Header>
<Profile>
username
<Profile>
</Navigation>
);
}
const Navigation = styled.nav;
const Header = styled.header`
/* Base styles */
width: 100%;
height: 60px;
background: #222;
color: #fff;
${props => props.secondary && css`
background: #fff;
color: #000;
`;
`;
const Profile = styled.div``;
export default NavigationExample;
Alternatively, you can inline props in your css.
<NavigationExample backgroundColor="#222" />
const Header = styled.header`
/* Base styles */
width: 100%;
height: 60px;
background: ${props => props.backgroundColor || '#222'};
color: ${props => props.backgroundColor ? '#000' : '#fff'}; /* Adjusting text so it's legible like the previous example */
`;

How to use the :first-of-type rule inside a styled-components/emotion partial?

I'm trying to replicate some CSS in Emotion using Partials but I don't see how it's possible to replicate a rule like :first-of-type in a situation where I'm using a partial. Is there some way to achieve this?
Starting CSS:
li.item {
background: white;
border: 1px solid;
}
li.item.isResult:first-of-type {
background: pink; /* Don't know how to port this rule */
}
Best attempt at porting this rule to Emotion:
import styled from '#emotion/styled';
import { css } from '#emotion/core';
const Item = styled.li`
background: white;
border: 1px solid;
${resultPartial}
`
const resultPartial = props => props.isResult && css`
&:first-of-type {
background: pink; // Has no effect
}
`
PS: Although partials don't seem to be mentioned in Emotion's docs, they are supported and do work. I'm specifically wondering about how to go about recreating a :first-of-type rule inside a partial.
Not a solution, but an explanation why it doesn't work.
const Div = styled.div`
color: black;
&:first-of-type {
color: red;
}
`;
Generates CSS like this:
.HaSh{color: black}
.HaSh:first-of-type{color: red}
However, the CSS spec only allows "type" to be a tag name for first/nth/last/only-of-type. Yet, styled-components relies and must rely on class names to distinguish differently styled div's. Thus, a dead end.
I believe you can work around the limitation (in general) by setting the style on any "parent's child", e.g.:
const Comp = () => <Container><p>1</p><p>2</p></Container>;
const Container = styled.div`
& > *:first-of-type {
color: red;
}
`;

styled components / react

Im working on a simple button example which i plan to extend. I have added a new button and included some constants as well. so far so good. In case i want to use more button versions like version1, version2, version3 of the same button with some styles changed like the background color. How should i do that? And how should they be exported?
const PrimaryButton = styled.button`
font: inherit;
padding: 0.5em 1em;
border: 1px solid;
background-color: ${buttonBackgroundColor};
color: ${buttonColor};
border-radius: 0.25em;
border-color: ${colors.blueLight};
margin-right: 0.5em;
cursor: pointer;
outline:none;
:hover {
background-color: ${colors.blueLight};
}
`;
Maybe it is possible to extend the button (how?) or does it make more sense to add different components for each button? For my typography i have use "extend". That works. How would that be for the different button versions? Is there a similar way?
export const H1 = styled.h1`
font-size: 30px;
color: red;
`
export const H2 = H1.withComponent('h2').extend`
font-size: 24px;
`
It was working as i added a new component. I imported the PrimaryButton into the new defined component called "Version2".
import PrimaryButton from './primary';
From here i updated the PrimaryButton like this:
const Version2 = PrimaryButton.extend`background-color: red;`
This has the advantage that we have a master component for a button. Now we are able to extend the master with diversity of additional styles. In my case background-color.
With the help of
export default Version2;
we are now able to add this button called "Version2" into our render function like:
<PrimaryButton>ClickMe!</PrimaryButton>
<Version2>ClickMe!</Version2>
and now we get the different buttons. And it´s very modular and clean as well.

How to prevent outside CSS from adding and overriding ReactJS component styles

I have a custom ReactJS component that I want to style in a certain way and provide as a plugin to many different web sites. But when web sites use global styles (Twitter bootstrap or another css framework) it adds and overrides styles of my component. For example:
global.css:
label {
color: red;
font-weight: bold;
}
component.js:
class HelloMessage extends React.Component {
render() {
let style = {
color: "green"
};
return (<label style={style}>Hello</label>);
}
}
result:
Above I didn't use "font-weight: bold" in my component's style but in result my component is using it.
I'd like to be able to encapsulate my custom components's styles in a way that makes them look the same across all the web sites.
The best approach in my view is to define some kind of reset class for your component and put in a set of css resets you can find out there
(e.g. http://meyerweb.com/eric/tools/css/reset/)
The definition in a sass file could look like this:
.your-component-reset {
div, span, object, iframe {
margin: 0;
padding: 0;
border: 0;
font-weight: normal;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
// add some more reset styles
}
To avoid writing a lot when you don't want to use sass just use the universal selector *:
.your-component-reset * {
margin: 0;
padding: 0;
font-weight: normal;
// other reset styles ...
}

Categories

Resources