Selector in css file for reactstrap component - css

What do I want to achieve
So there is a gap between my jumbotron and my footer. I want to remove that gap. I did it already successfully by setting the margin-bottom to 0px; But at that moment, I had to pass an ID to the Jumbotron element. Now I want to achieve that same effect without passing an ID, but with classes.
I don't want to use inline styles. I want it in a separate css file.
In an old library (react-bootstrap not reactstrap) I could select for example all components from a certain type, like I did in the css provided below.
So the mistake is probably the selector in the css file. I couldn't find anything online which specifically shows it in a seperate "css file" way. Only with inline styling.
MainContent.js
import React from 'react';
import './MainContent.css';
import { Jumbotron, Button, Form, FormGroup, Label, Input, Container } from 'reactstrap';
const MainContent = () => {
return (
<Container>
<Jumbotron>
<Form>
<FormGroup>
<Label for="exampleEmail">Email</Label>
<Input type="email" name="email" id="exampleEmail" placeholder="with a placeholder" />
</FormGroup>
<FormGroup>
<Label for="examplePassword">Password</Label>
<Input type="text" name="password" id="examplePassword" placeholder="password placeholder" />
</FormGroup>
<Button>Submit</Button>
</Form>
</Jumbotron>
</Container>
);
}
export default MainContent;
MainContent.css
.Container {
margin-bottom: 0px;
}
.Jumbotron {
margin-bottom: 0px;
}

If you don't want to do it with IDs or with inline-styling, there is a way I would call a hack.
In MainContent.js add className attribute to the component as follows:
<Jumbotron className="jumbotron">
And in MainContent.css add !important in the statement you want to override other stylings:
.Container {
margin-bottom: 0px;
}
.Jumbotron {
margin-bottom: 0px !important;
}
Unless you override like this, margin-bottom: 2rem from node_modules/bootstrap/dist/css/bootstrap.css is used.

Related

CSS if first element is a dropdown then do something

i have CSS issue, i'm looking for some help please :)
so here my page :
There is notification icon at left bottom of the page, some time it can be disabled, so the icon and switch button can disapear. If that disapear, my "Langage" dropdown is moving to left like this :
My problem is i don't know in CSS how to say if "Langage" Dropdown is the first element of my line, then do something (like adding padding for example).
There is a way in CSS to do this ?
I tried something like this :
&:first-child {
margin-left: ${spacings.medium_2};
}
but not working :/
My code (react code):
{projectNotification
&& (
<UserFormLine id="notifications_switch" xs={6}>
<Icon>notifications</Icon>
<SwitchNotifications
id="notification"
checked={user.notify}
onChange={() => handleChangeUserAttribute('notify', !user.notify)}
/>
</UserFormLine>
)
}
<ProjectFormLine id="languageId_formLine" xs={6}>
<DropDown
id="languageId"
source={appLocalesData}
label={formatMessage({ ...messages.user.language })}
value={user.language}
onChange={(value) => handleChangeUserAttribute('language', value)}
/>
</ProjectFormLine>
first-child should be working fine, if you'd like to have some more control on the specificity of the rule, you could try using another attribute to make sure that the style applies to an element that matches that attribute.
In this example, the rule will apply to an element that is the first child of the container, but also has a name attribute with a testinput1 value.
.container {
margin-bottom: 10px;
}
.container input[name="testinput1"]:first-child {
border: 1px solid red;
}
<div class="container">
Container 1
<input class="input" name="testinput1" />
<input class="input" name="testinput2" />
</div>
<div class="container">
Container 2
<input class="input" name="testinput2" />
<input class="input" name="testinput1" />
</div>
<div class="container">
Container 3
<input class="input" name="testinput1" />
<input class="input" name="testinput2" />
</div>
However, looking at your scenario, maybe you want to look into CSS Grid to build your layout, you could set it up so there's always an "empty" column where the notification control should be, so it keeps the other element aligned.
Or use the visibility: hidden property on the notification control as suggested in the comments as well.

Changing a css variable in styled components from a React props

I am using CSS grid to create a dynamic table. The number of columns and rows are dynamic and are based on props I get from an higher component in React.
How can I change a css variable inside a styled component (emotion) to the data I get from a React props?
Here it is in their documentation:
https://www.styled-components.com/docs/basics#passed-props
// Create an Input component that'll render an <input> tag with some styles
const Input = styled.input`
padding: 0.5em;
margin: 0.5em;
color: ${props => props.inputColor || "palevioletred"};
background: papayawhip;
border: none;
border-radius: 3px;
`;
// Render a styled text input with the standard input color, and one with a custom input color
render(
<div>
<Input defaultValue="#probablyup" type="text" />
<Input defaultValue="#geelen" type="text" inputColor="rebeccapurple" />
</div>
);

disable react extra div wrapper

Is it possible to disable react disable react extra div wrapper?
I'm using ES2015.
The wrapper is making two of my style not centering my component in C#.
#First div
.default-content {
margin-right: auto;
margin-left: auto;
padding: 16px 16px 16px 16px;
}
#second div
.full-width {
width:100%;
}
The code looks like this when its rendered.:
<react-container params="component: MontelUI.React.CompactStory, args: {
newsId: 955888, userId: 1003465, bookmarkMainProp: false }">
<div>
<div>hei</div>
</div>
</react-container>
My render function looks like this:
render() {
return (
<div>hei</div>
)
The component is called through custom-tag.
There is an option for this situation. You are not clear about what you meant but as I understood, you have and component which has div and to be able to render multiple components you need to wrap with div. But instead of this you can use Fragments! Try to analyze this link and wrap your component with Fragment not div!
Fragments in React
Like this ->
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}

angular 5 material - form fields stuck at 180px

I've created a form in a dialog using material forms, but I can't seem to get the inputs to be wider than 180px despite following numerous examples including https://material.angular.io/components/input/example.
I'm sure this is a pretty standard CSS thing, but I don't have that sort of brain so I cant figure out the problem.
Does anyone have a serious / non-trivial example that works??
Here's mine:
<h1 mat-dialog-title>{{title}}</h1>
<mat-dialog-content>
<form novalidate #f="ngForm" class="form-full-width">
<mat-form-field class="input-full-width">
<input type="text" [(ngModel)]="data.name" name="name" matInput placeholder="Name">
<mat-hint>Enter a unique name.</mat-hint>
</mat-form-field>
<mat-form-field class="input-full-width">
<textarea [(ngModel)]="data.description" name="description" matInput placeholder="Description"></textarea>
<mat-hint>You should describe the purpose/use of this thing.</mat-hint>
</mat-form-field>
</form>
</mat-dialog-content>
CSS :
.form-full-width {
min-width: 150px;
max-width: 500px;
width:100%;
}
.input-full-width {
width:800px;
}
.mat-form-field.mat-form-field {
width: auto;
}
Thanks.
can you try using
mat-form-field {
width: 100%;
}
I had the same issue in a mat-card, this worked for me.
Seems like it's something to do with View Encapsulation. This thread explains it: https://github.com/angular/material2/issues/4034 but changing encapsulation for the component causes all sorts of compile failures.
This article gave me the correct solution:https://material.angular.io/guide/customizing-component-styles
I'll move my style to global scope...
.formFieldWidth480 .mat-form-field-infix {
width: 480px;
}
and in the component that opens the dialog:
this.newDialog = this.dialog.open(NewDialogComponent,
{
width: '650px', height: '550px',
data : newThing,
panelClass : "formFieldWidth480"
});
I hope this saves someone else the day I lost...
Just like Jonesie said, this behavior is related to View Encapsulation. In this context .mat-form-field-infix takes 180px as default value probably beacause of this. The auto value lets the browser calculates the width instead of puting hardcoded value. The !important declarations forces the style override for this.
I am using !important since it complies with the rules for the use of this property. See docs
::ng-deep .mat-form-field-infix {
width: auto !important;
}
It's that .mat-form-field.mat-form-field in the css that's causing an issue. As soon as I removed that, I could control the widths with .input-full-width width setting. I set up a demo here: StackBlitz.com
<h1 mat-dialog-title>{{title}}</h1>
<mat-dialog-content>
<form novalidate #f="ngForm" class="form-full-width">
<mat-form-field class="input-full-width">
<input type="text" [(ngModel)]="data.name" name="name" matInput placeholder="Name">
<mat-hint>Enter a unique name.</mat-hint>
</mat-form-field>
<mat-form-field class="input-full-width">
<textarea [(ngModel)]="data.description" name="description" matInput placeholder="Description"></textarea>
<mat-hint>You should describe the purpose/use of this thing.</mat-hint>
</mat-form-field>
</form>
</mat-dialog-content>
.form-full-width {
min-width: 150px;
max-width: 500px;
width:100%;
}
.input-full-width {
width:800px;
}
/* .mat-form-field.mat-form-field {
width: auto;
} */
The solution I found was this one into general style.css
mat-form-field {
margin-left: 2.5rem;
width: calc(100% - 2.5rem);
}
::ng-deep .mat-form-field-infix {
width:800px !important;
}
This should work fine.Not sure if it can be done without custom CSS.
I have the same issue, fixed it with.
But still no idea why this issue is happening...
.mat-form-field-infix {
width: 100%;
}

Target native dom element <input>...</input> with styled-components

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>
);}}
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.
Working Demo
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
Working Demo
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.
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

Resources