Reputation: 2027
I am having trouble getting my styled component to make a change to an <input />
wrapped in a React component. In Dev Tools I can see the style I am trying to override here:
.ui.input input {...}
I think the wrapping component needs to pass className
to input i.e
<input className = {this.props.className} ..> ... </input>
but I cannot get the style to override with or without that. I will provide some snippets below.
//styled component
const StyledSearch = styled(Searchbar)`
&.ui.input input{
border: 0px !important;
}
`;
class SearchBar extends Component {
...
render() {
const style = {
display: this.state.showResults ? 'block' : 'none',
maxHeight: 500,
overflowY: 'scroll',
};
return (
<div className="ui search fluid" ref="container">
<div
className={`ui icon fluid input ${this.props.loading ? 'loading' : ''}`}>
<input type="text"
placeholder={this.props.placeholder}
onFocus={this.focus}
className = {this.props.className}
value={this.props.value}
onChange={this.props.onChange}/>
<i className="search icon"></i>
</div>
<div
className="results"
style={style}>
{
this.props.results.map((result, index) => (
<a
className="result"
key={index}
onClick={this.select.bind(this, result)}>
<div className="content">
{
result.get('image') ?
(
<div className="image">
<img src={result.get('image')} style={{ maxWidth: 50 }}/>
</div>
) : null
}
<div className="title">
{result.get('title')}
</div>
<div className="description">
{result.get('description')}
</div>
</div>
</a>
)
)
}
</div>
</div>
);}}
Upvotes: 1
Views: 1794
Reputation: 1862
Currently at version 4 you can do it as simple as
const Input = styled.input`
border:2px solid red !important;
`;
it will rendered as native input with SC className
Upvotes: 0
Reputation: 62851
From what I can tell, you need to apply the styles generated with styled-components
to the wrapper element. This is due to the specificity of the .ui.input input
external style. Meaning we can't simply target the input
element with a new style because the .ui.input input
selector is more specific and takes precedence. Here's a simple CSS example showing how the specificity of the .ui.input input
selector takes precedence over the input
styling:
.ui.input input {
border:2px solid red !important;
}
input {
border: 0px !important;
}
<div class="ui input">
<input />
</div>
This same issue is at play in your case. In the example below I've created a new Wrapper
component, which has a style of:
&.ui.input input {
border: 0px !important;
font-size: 24px;
}
defined on it. This targets the inner input
element, with more specificity, to override the external styles.
import React from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';
class InputWrapper extends React.Component {
render() {
const Wrapper = styled.div`
&.ui.input input {
border: 0px !important;
font-size: 24px;
}
`;
return(
<Wrapper className="ui input">
<input type="text" placeholder="Input" />
</Wrapper>
)
}
}
ReactDOM.render(
<InputWrapper />,
document.getElementById("app")
);
Here's a WebpackBin example.
Upvotes: 1
Reputation: 1562
Basically, styled-components
creates a new unique class name (in other words, a new namespace) for any DOM or React Components for which the styled
function is called.
That means, when you use styled(SearchBar)
, styled-components
wraps SearchBar
component and attaches a unique class name to its root DOM. Then it passes that unique class name to the descendent DOMs and components (in your cases, nested div
, input
, a
).
For this method to work, your root DOM must have a className
that can be configured from outside. That's why, styled-components
expects that, root DOM has the definition ${this.props.className}
as the value of its className
props. If your component lacks this, styled-components
will not be able to create a new namespace which it can use to apply styling specific to it.
So, for your technique to work, you must assign ${this.props.className}
as one of the values of className
prop defined at the root div
of SearchBar
.
If you don't have access to SearchBar
, you can wrap it with another component. Overhead of this process is that, you have to use an extra DOM level
Upvotes: 1