Passing props from react-cosmos to styled-components - javascript

I have the following component where I have applied the css using styled-components:
import styled from 'styled-components'
// square-block css can be re-written as a styled-component(???)
const SquareBlock = styled.div`
width: 100%;
height: 100%;
background-color: ${props => props.color};
`
export default SquareBlock
I would like to use the following fixture with react-cosmos to adapt the background-color of the component based on the props:
import { COLORS } from '../../../constants/tetronimo'
export default {
color: COLORS.I
}
In the React developer tools I noticed that the component PropsProxy had a fixture prop which has the color property:
JSON.stringify($r.props.fixture, null, 2)
{
"color": "#3cc7d6"
}
How can I ensure that props are passed correctly to react-cosmos?

Props need to be placed under fixture.props in the latest version of React Cosmos, but you seem to have already figured this out. Does this solve your problem?

Related

Change TextareaAutosize color in React with mui

I'm new at React and using mui components.
While I'm trying to set color to TextareaAutosize mui component with code like this:
import * as React from 'react';
import TextareaAutosize from '#mui/material/TextareaAutosize';
import { blue } from '#mui/material/colors';
export default function EmptyTextarea() {
return (
<TextareaAutosize
aria-label="empty textarea"
placeholder="Empty"
style={{ width: 200, color: blue, background: blue}}
//Also not works: color="{blue}"
/>
);
}
the color of the component not changed.
Thanks a lot!
<TextareaAutosize /> renders a plain HTMLTextAreaElement.
Which means this CSS will work:
textarea {
background-color: #222;
color: #BADA55;
}
Working demo: https://codesandbox.io/s/maxheighttextarea-material-demo-forked-5hc8nv?file=/index.css
If you want to scope the CSS to your particular instance, give it an id and use it in the CSS selector.

Unable to apply styles to styled-component element in Reactjs

I'm trying to wrap a component with a styled-component div and apply some styles. However, for some reason, the styles aren't being applied, even though the ostensibly correct wrapper that is expected to be rendered is being rendred.
CodeSandbox
What am I doing wrong here?
You just forgot to pass the className props, see here:
const Component = ({ className }) => (
<div className={className}>Hello World!</div>
);
https://codesandbox.io/s/optimistic-lumiere-cq8gt?file=/src/App.js
I hope I helped you. Have a good day.
EDIT: Check the docs here
You need to container Component with styled.{tag} or styled(Component)
And then use that Container component to wrap main component.
import React from "react";
import "./styles.css";
import styled from "styled-components";
export default () => <Component />;
const Component = () => <StyledDiv>Hello World!</StyledDiv>;
const StyledDiv = styled.div`
font-size: 10rem;
color: red;
display: flex;
justify-content: center;
align-items: center;
`;
Check here: https://codesandbox.io/s/dank-hill-h8rbc?file=/src/App.js:128-189

Using a styled component's rules within `createGlobalStyle`

New to styled components and am wondering if someone might have some advice on how to use a styled component's rules within a call to createGlobalStyle?
The below example is working, but I feel that it is not a great solution as componentStyle.rules is not in the official api docs.
// A styled component
import Modal from '../Modal'
import styled, { createGlobalStyle } from 'styled-components'
const StyledComponent = styled(Modal)`
background-color: pink;
`
createGlobalStyle`
// this div is mounted outside of the React root
.modal-from-external-library {
${StyledComponent.componentStyle.rules}
}
`
Not sure if what I was trying to do was possible, but I ended up solving the problem by exporting the css from the Modal using the css function of styled components.
// Modal.js
const styles = css`
// styles here
`
export default styled.div`
${styles}
`
// ... later
const GlobalStyles = createGlobalStyle`${styles}`
render() { return (<GlobalStyles {...props} />) }

Styled-component object can't observe mobx changes

I would like an HOC generated by styled-components to re-render when one of its properties get changed. I'm using MobX for change detection.
This doesn't respond to changes, I think I understand why. The question is if there is a simple workaround to make it work.
const DemoComponent = observer(styled.div`
background-color: ${props => props.myObject.myObservableIsTrue ? 'red' :
'green'};
`);
It's hard to tell by this little snippet, but one of my guesses would be you are not injecting any store, so currently, no store is being connected to your component.
here's a simple example of how I used styled-components with mobx if it helps:
EDITED:
I've updated the code example.
Do you know the Container / Presentational pattern?
This was the missing link.
In order to keep your renders as little as possible
you need to separate your stateful component from each other.
Spread them across a Container component (aka Dumb Components)
This way you separate state concerns and render only the component with the changed state.
UPDATED:
https://codesandbox.io/s/zxx6o2pq3l
Sorry!!! A bit of a hack job, but attempt to bring your entire code inside the #inject("store") class:
import React from "react";
import { observer, inject } from "mobx-react";
import styled, { css } from "styled-components";
#inject("store")
#observer
export default class OtherComponent extends React.Component {
render() {
const MyWrapper = (store) => {
const Wrapper = styled.div`
border: 1px solid black;
display: flex;
justify-content: space-between;
color: ${({ color }) => color};
border: 2px solid ${({ color }) => color || "black"};
padding: 10px;
margin-bottom: 10px;
`;
return (
<Wrapper {...store}>
styled-component
<button onClick={store.changeColor}>change color</button>
</Wrapper>
);
}
const { store } = this.props;
return (
<div>
{
MyWrapper(store)
}
</div>
);
}
}
Mobx is actually read like this: #inject("store") #observer export default class...
So it really an extension of an extended component; only wrapped variables will apply!

idiomatic way to share styles in styled-components?

trying to port some code from jss to styled-components,
jss code looks something like:
//...
const styles = {
myStyles: {
color: 'green'
}
}
const {classes} = jss.createStyleSheet(styles).attach()
export default function(props) {
return (
<div>
<Widget1 className={classes.myStyles}/>
<Widget2 className={classes.myStyles}/>
</div>
)
}
my question is what would be the idiomatic way to accomplish this sharing of the same styles across multiple components?
You can either share actual CSS strings or share styled-components components:
Share CSS strings:
import {css} from 'styled-components'
const sharedStyle = css`
color: green
`
// then later
const ComponentOne = styled.div`
${sharedStyle}
/* some non-shared styles */
`
const ComponentTwo = styled.div`
${sharedStyle}
/* some non-shared styles */
`
Share actual styled-components:
const Shared = styled.div`
color: green;
`
// ... then later
const ComponentOne = styled(Shared)`
/* some non-shared styles */
`
const ComponentTwo = styled(Shared)`
/* some non-shared styles */
`
Update: Based on questions in the comments, I created an example to show that passing props to styled-components's css function works the same way as passing props to the components themselves: https://codesandbox.io/s/2488xq91qj?fontsize=14. The official recommendation from styled-components is to always wrap strings you will pass to styled-components in the css tag function. In this example, the Test component receives it background and foreground colors through passed-in props embedded in the cssString variable created by invoking the css function.
In addition to the posted answer, you can also create a function that accepts props / theme and returns the css``.
styled-components will check the type of the value provided eg: ${shared} and if its a function it will invoke it with the relevant props / theme.
import styled, {css} from 'styled-components';
const shared = ({theme, myProp}) => css`
color: ${theme.color};
`
/* ------------ */
const Component1 = styled.div`
${shared};
/* more styles ... */
`
const Component2 = styled.div`
${shared};
/* more styles ... */
`
In addition to the 2 answers above, you can also share style between tags as such:
const MyText = styled.div`
color: orange;
`
const MyLink = MyText.withComponent("a")

Categories

Resources