Reputation: 903
I'm trying to have my component use dynamic styles in react-native using styled-components. The way to do this is shown here https://github.com/styled-components/styled-components/issues/940
const ColorAnimation = styled.div.attrs({
style: props => ({
color: props.color
})
})`
// static styles
It works in React Native as well, as shown here. https://snack.expo.io/ryIXsAe0M
import React, { Component } from 'react';
import { View } from 'react-native';
import styled from 'styled-components/native'; // 2.2.4
const StyledView = styled.View.attrs({
style: props => ({
backgroundColor: props.backgroundColor,
height: props.height,
}),
})`
background-color: papayawhip;
`;
const StyledText = styled.Text`
color: palevioletred;
`;
const RotatedBox = styled.View`
transform: rotate(90deg);
text-shadow-offset: 10px 5px;
font-variant: small-caps;
margin: 5px 7px 2px;
`;
export default class App extends Component {
render() {
return (
<View style={{ marginTop: 50 }}>
<StyledView height={100} backgroundColor="yellow">
<StyledText>Hello World!</StyledText>
</StyledView>
<RotatedBox />
</View>
);
}
}
However, I'd rather just pass in a customStyle prop that contains all the dynamic styles I want to use. Like this. . . https://snack.expo.io/BkpToRe0f
const StyledView = styled.View.attrs({
style: props => props.customStyles,
})`
background-color: papayawhip;
`;
<StyledView customStyles={{ height: 100, backgroundColor: 'yelllow' }}>
Unfortunately, this does not apply the styles. Does anyone know why this is? Also if there is an alternative solution?
Upvotes: 2
Views: 5293
Reputation: 11
How about trying this
const StyledView = styled(View).attrs(props => ({
backgroundColor: props.theme.backgroundColor,
height: props.theme.height,
})
)
Upvotes: 1
Reputation: 700
For anyone wanting a bit more detailed explanation of when to use additional props
in styled components I will make a quick example of how attrs
works. Also known as Attaching additional props. You can read about it here on styled components documentation.
Below is a simple example for a background image using CSS. I would need to apply a title and aria-label for accessibility purposes. One way of doing this would be to attach additional props.
// Component
getBackgroundImage = () => {
const { imageUrl, altTag } = this.props;
return (
<BackgroundImage
imageUrl={imageUrl}
altTag={altTag}
/>
);
};
// Styled component
export default styled.div.attrs({
title: props => props.altTag,
'aria-label': props => props.altTag,
role: 'img,
})`
background: url(${props => props.imageUrl}) center center/ cover no-repeat;
height: 400px;
width: 100%;
`;
I would then be able to find this component in the DOM and I would be able to see these attributes. I believe this is the correct usage of this, and separates your concerns regarding additional props and static styling.
In regard to the question:
Unfortunately, this does not apply the styles. Does anyone know why this is?
I believe it's not working as backgroundColor
is not an attribute. Height is an attribute that applies to certain HTML elements, which can be found with this link.
Other HTML attributes can be found here
So for your StyledComponent to display correct styles, attrs
is not needed.
const StyledView = styled.View`
background-color: ${props => props.backgroundColor};
height: ${props => props.height};
`;
<StyledView height={100} backgroundColor="yelllow" />
More information regarding attaching-additional-props and attrs API. They both contain very useful information and examples.
Upvotes: 2
Reputation: 2715
I think you're a bit confused as to how to use the styled components
This is the example you gave:
const StyledView = styled.View.attrs({
style: props => ({
backgroundColor: props.backgroundColor,
height: props.height,
}),
})`
background-color: papayawhip;
`;
And this is how it should be:
const StyledView = styled.View`
height: ${props => props.height},
background-color: ${props => props.backgroundColor ? "papayawhip"};
`;
While the first one works as you say, the second one is much cleaner and you can use the component without having to pass an extra customStyles prop. Styled components take care of that for you
<StyledView backgroundColor={"blue"} height="500" />
Upvotes: 0