prettier formatting inside styled-component - styled-components

In our code base we use styled-components, with a theme. To use the theme one must do something like this
const StyledComp = styled.div`
margin: ${theme.spacing.sm};
`
However, because our theme is nested for organization purposes this can be quite verbose. So what we do is
const StyledComp = styled.div(({theme: { spacing, fontSize, etc }}) => `
margin: ${spacing.sm};
font-size: ${fontSize._14};
`);
I'm not sure where I picked up this pattern, but it really helps and we use it everywhere. However. prettier, and actually most styled-component vscode plugins don't seem to recognize it. That is they don't format the code inside or provide intellisense or whatever.
Is there anyway to fix this or could someone explain to me the issue so that I have more information for searching for a solution?

Related

Jest - how to test if a component does not exist?

How do I check if a component is not present, i.e. that a specific component has not been rendered?
.contains receives a React Node or array of Nodes as an argument. Instead, use .find:
expect(wrapper.find('selector').exists()).toBeTruthy()
You can use enzymes contains to check if the component was rendered:
expect(component.contains(<ComponentName />)).toBe(false)
If you're using react-testing-library (I know the OP wasn't but I found this question via web search) then this will work:
expect(component.queryByText("Text I care about")).not.toBeInTheDocument();
You can query by Text, Role, and several others. See docs for more info.
Note: queryBy* will return null if it is not found. If you use getBy* then it will error out for elements not found.
Providing a slightly updated answer based on the documentation for enzyme-matchers's toExist. This will require you to install the enzyme-matchers package.
function Fixture() {
return (
<div>
<span className="foo" />
<span className="bar baz" />
</div>
);
}
const wrapper = mount(<Fixture />); // mount/render/shallow when applicable
expect(wrapper.find('span')).toExist();
expect(wrapper.find('ul')).not.toExist();
.contains does not expect a selector, unlike find. You can look at the length attribute of the ShallowWrapper
expect(wrapper.find('...')).toHaveLength(0)
I found I needed to use this syntax with Enzyme and Jest to test if a Connected Component existed in the rendered output.
We use Jest and Enzyme, and I've found the only good test is to import the sub-component and test this way:
expect(component.find(SubComponent).length).toEqual(0); // or (1) for exists, obvs
I tried all the other answers and none worked reliably.
If you are using react-testing-library, then this also will work:
expect(component.queryByText("Text I care about").toBeNull());
expect(within(component).queryByText("Text I care about")).toBeNull();
Note: In my case, I needed to use queryBy* because it doesn´t error out when the text element (that contains the text: Text I care about) does not exist. Therefore, I could evaluate whether there is an existence of a text component or not.

How to easily inspect styled-components using dev tools?

I am using styled-components in a React project. When the components are rendered in the browser they are assigned a randomly generated classname, for example:
<div class="sc-KSdffgy oPwefl">
This class name does not help me identify from which component the <div> came from, so is there a way to do this easily?
P.s. currently I am adding attrs to my styled components so that I can recognise them in dev tools, for example:
const Foo = styled.div.attrs({
'data-id': 'foo'
})`
...
`;
That's exactly why we created our Babel plugin, when using it you'll get class names that include the name you gave your component:
<div class="Sidebar__Button-KSdffgy oPwefl">
On top of that we set the displayName of the generated component too, which means in your React DevTools you'll see the actual component name rather than just <div> or <Styled(Component)>.
To use the Babel plugin install it with npm install --save-dev babel-plugin-styled-components and then add it to your Babel configuration: (e.g. in your .babelrc)
plugins: ["styled-components"]
That's it! Happy debugging 😊
Note that if you're using create-react-app you cannot change the Babel configuration. I use and would recommend react-app-rewired to be able to change configurations without having to eject. We've also built react-app-rewire-styled-components which automatically integrates the styled-components Babel plugin for you!
For anyone using create-react-app, just substitute
import styled from "styled-components";
to
import styled from "styled-components/macro";
this will make your styled-component classes have the name of their component in them. And you'll be able to know which classes refer to which components just by looking at their class name ;)
For anyone using create-react-app, another option is to use the styled components babel macro
npm install --save babel-plugin-macros
Inside your component use import styled from 'styled-components/macro'; instead of import styled from 'styled-components';
You should now see the component name in your dev tools:
I was looking at doing the same and stumbled on the following as an alternative to attrs:
const Section = styled.div`
background-color: #06183d;
color: white;
padding: 16px;
margin-top: 16px;
${breakpoint("md")`
border-radius: 5px;
`}
`
Section.defaultProps = {
"data-id": "Section"
}
Use React.Component's defaultProps. It keeps the call to styled.div cleaner and should be easier to remove if needed.
Results in:
If you use ts-loader or awesome-typescript-loader there is typescript-plugin-styled-components.

Problems with variables inside styles using pug

I'm building a little app with NodeJS and Pug as engine.
I just want to insert a variable inside an element style, but can't find the way to make it work. Here is the code:
- var grados = 45;
span.glyphicon.glyphicon-arrow-up(style={transform:'rotate(#{grados}deg)'})
I think the problem is the parenthesis from the transform attribute, I tried it with another simpler approach like color:grados (- var grados = 'red') and it worked fine. Any ideas?
I'm afraid you've stumbled upon a common issue in Pug: Support for attribute interpolation has been dropped, so that syntax is no longer supported. See the page in the Pug docs relating to this. There is no 'clean' solution to fix this, other than simply building the attribute string with string concatenation:
- var grados = 45;
span.glyphicon.glyphicon-arrow-up(style={transform:'rotate(' + grados + 'deg)'})

How does React Native require(moduleName) work?

I saw code like var Animated = require('Animated') in react-native source code. But how can this be resolved without a path ?
My guess is that will be preprocessed by the packager by something like registering and I would like to do this in my own project. But there seems to be no document for react-native's packager , and I can't find the source code where this "registering" happen.
I think I find it! Just add #providesModule moduleName in the file's comment in the header , look into issue 896 for detail.
import {
Animated,
View,
Text,
} from 'react-native';
i can't catch what you said.but i post the above snippet how i used.

Is it possible to pass a value of 0 to span(0)?

Long tried to create a responsive navigation. But still turned out.
But I'm still not sure I did the right thing. Because I passed a value of 0 in the span. Or so it is still possible to do? It works :)
$big: (columns: 24, gutters: 1/2,math: fluid,gutter-position: split )
#include susy-breakpoint(700px, $big)
.nav-item // is ui>li.nav-item
#include span(0 border-box)
No, this is not a proper way to use Susy. If you look at the output, you will see that you get width: -1.38889%; which is not valid CSS. It works because browsers ignore invalid code - but it's not a good idea, and it's not a meaningful use of Susy.
The only grid-output you need is gutters, so that's all you should ask Susy for. The rest you can do with plain css:
.nav-item {
#include gutters;
box-sizing: border-box;
float: left;
}

Resources