I want tp use css to Material-UI component.
in MyCss.css
.trackTitle {
color:white;
}
in myComponent.js
import "./MyCss.css"
<Grid container item xs={1} className="trackTitle">
change color test
</Grid>
It doesn't change the color.
However the below works.
import "./MyCss.css"
<Grid container item xs={1} className="trackTitle">
<span className="trackTitle">
change color test
</span>
</Grid>
If I use basic tag span not Material-ui Grid
The class works.
See another case for component Slider
in MyCss.css
.mySlider {
height:"80px";
}
in myComponent.js
<Slider className="mySlider"
min={0} max={1} step={0.1}/>
not work.
<Slider className="mySlider" style={{height:"80px"}}
min={0} max={1} step={0.1}/>
works.
Now I understood className for component doesn't work.
Howeber, I want to use css to Material-UI component, how can I make it?
What you can do is to find the material-UI components CSS selector in the browser console, then override the css in your css file. Most likely this would work. Here is an example this is the root css for the slider
.MuiSlider-root {
color: #1976d2;
width: 100%;
cursor: pointer;
height: 2px;
display: inline-block;
padding: 13px 0;
/* position: relative; */
box-sizing: content-box;
touch-action: none;
-webkit-tap-highlight-color: transparent;
}
copy-paste it and then set your updates in the css
.MuiSlider-root {
/* update */
}
Material-ui is a css framework, if you want to use className for material-ui component
you have to injectFirst in root. example:
ReactDOM.render(
<StylesProvider injectFirst>
<App/>
</StylesProvider>
document.getElementById('root')
);
after this you will be able to use className anywhere on the app for any material-ui component
Related
So I have a component which is basically a custom button, with position: fixed, and I need it to render twice, one next to the other, but how can I achieve this if this component has position: fixed ? Basically, Is rendered twice in the same position.
Here is my code, where FloatingButton is the component with the issue above:
return (
<div className="details">
<Grid container spacing={3}>
<Grid item xs={12} md={12}>
<Header {...headerProps} />
</Grid>
<Grid container className="inner-container" justifyContent="flex-end">
<Grid item>
{floatingButtonProps ? <FloatingButton {...floatingButtonProps} /> : null}
</Grid>
<Grid item>
{floatingButtonProps ? <FloatingButton {...floatingButtonProps} /> : null}
</Grid>
</Grid>
</Grid>
</div>
);
and here is the CSS from the Button component:
min-width: 80px;
max-width: 80px;
height: 80px;
border-radius: 40px;
position: fixed;
bottom: 32px;
right: 32px;
display: inline-flex;
border-color: transparent;
color: #fff;
overflow: hidden;
cursor: pointer;
transition: max-width 0.5s;
position:fixed: An element with position: fixed is positioned relative to the viewport, which means it always stays in the same place even if the page is scrolled. SO technically your code is working just fine.
Now if you want to achieve two "fixed buttons" side by side. One of the ways is:- you should make the container of the button to be position:fixed and render the button without a fixed position
You can also pass the value for right in props to FloatingButton
like,
For first button <FloatingButton right='32px'/> and for second one <FloatingButton right='132px'/>
and in the Button component, you can assign it as CSS property
I am trying to add masked input to a styled component based on react-native-paper Text Input. Here is my styled component :
const StyledTextInput = styled.TextInput`
border-color: #68c25a;
border-width: 1px;
border-radius: 5px;
height: 50px;
margin-top: 5px;
padding: 12px;
`;
I am trying to add it as a render prop as per docs:
<StyledTextInput
render={(props) => (
<MaskInput {...props} mask={Masks.DATE_DDMMYYYY} />
)}
/>
But this doesn't work. The only way it works is if I add it directly to TextInput, not StyledTextInput. So I think the issue is in the styled component itself.
I'm using react-bootstrap v0.28.5 and trying to customise the background colour of the Dropdown.Toggle when the Dropdown component is open (see the toggle button with grey background in the 1st pic).
Any idea how I can achieve this?
I've been able to customise the Dropdown style as shown in the code below, but it seems that bootstrap has its own "open" class (see element tree in 2nd pic), which I can't figure out how to access using react className. I've looked in the source code for react-bootstrap/lib/Dropdown.js for some clues but no luck.
react component
<Dropdown className={styles.container}>
<Dropdown.Toggle className={styles.toggle} noCaret>
<div className={styles.title}>Title</div>
<div className={styles.placeholder}>Selection</div>
</Dropdown.Toggle>
<Dropdown.Menu>
<MenuItem eventKey="1" onSelect={(key, e) => onSelect(key, e)}>
Action
</MenuItem>
<MenuItem eventKey="2">Another action</MenuItem>
<MenuItem eventKey="3">Active Item</MenuItem>
</Dropdown.Menu>
</Dropdown>
styles.scss
.container {
display: block;
width: 100%;
height: 100%;
.toggle {
border: none;
text-align: start;
width: 100%;
padding: 0;
.title {
font-size: 13px;
font-weight: 700;
margin-bottom: 2px;
}
.placeholder {
font-size: 16px;
}
&:hover {
background: #e4e5e9;
}
}
I've tried looking at the source code but I don't see how to customise the "open" class.
Pic 1: Dropdown component
Pic 2: Page elements
Any help will be appreciated! Thanks a lot.
You may want to overwrite the styles for the toggle class by using the !important tag like this :
&:hover {
background: #e4e5e9 !important;
}
I was trying to follow the MUI guide on overriding MUI styles, but using styled-components instead of JSS. In particular, I could not get the first two approaches to work:
Using className
Using classes
I have made sure the injection order in head is correct, so that is not the issue. My problem is that the classes I need are not added to the DOM.
Also note: I managed to get normal styled-components to work well with MUI. I.e. the following works fine:
import React from 'react';
import Button from '#material-ui/core/Button';
import Typography from '#material-ui/core/Typography';
import styled from 'styled-components';
import { darken, fade } from '#material-ui/core/styles/colorManipulator';
const StyledButton = styled(Button)`
color: ${props => props.theme.palette.primary.contrastText };
background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
border-radius: ${props => props.theme.shape.borderRadius}px;
height: 48px;
padding: 0 30px;
box-shadow: 0 3px 5px 2px rgba(255, 105, 135, 0.3);
&:hover {
background: ${props => {
return `linear-gradient(45deg, ${darken(`#fe6b8b`, 0.2)} 30%, ${darken(`#ff8e53`, 0.2)} 90%)`;
}};
};
font-size: 1.2rem;
${props => props.theme.breakpoints.up('md')} {
font-size: 1rem;
}
`;
// In render:
<StyledButton>Hello World</StyledButton>
The following however, does not work:
styled(Typography)`
&.my-class {
margin-bottom: 5rem;
}
`;
// In render:
<Typography className="my-class" component="h2" variant="h2">
Dev Tools does show that my-class is indeed added, but, the class does not get added to the DOM. I followed this guide (Third Method).
Any idea why?
PS: I do not want to turn Typography into a StyledTypography component. I know that works (see first example above). Instead, I want to follow the override guide in the MUI docs.
Edit
Relevant installed packages:
"#material-ui/core": "^3.9.3"
"styled-components": "^4.2.0",
Edit 2:
I got it to work if I import an external style sheet:
// style.css
.my-class2 {
margin-bottom: 3rem;
}
// index.js
import React from 'react';
import Typography from '#material-ui/core/Typography';
import './style.css';
const IndexPage = () => (
<>
<Typography className="my-class2" component="h2" variant="h2">
Testing h2 (MUI)
</Typography>
</>
);
<Typography className="my-class2" component="h2" variant="h2">
Testing h2 (MUI)
</Typography>
However, I would like to keep it all inside the component.
Thus, my problem boils down to:
How can I add locally scoped styles to the DOM from within a component, without for instance creating a new component tag / variable with styled-components?
My component is a basic NavBar with different items. When Hovering over the item with the dopdiwn-items class, the NavBar should display those items in a block. Instead, only the first item can be seen, with the others being hidden. The same code, when put into plain HTML and CSS on code pen, works as expected. I discovered if I increase the size of the navbar then the items do show as a large block of text. I listed screenshots, and my code below.
CodePen link: http://codepen.io/anon/pen/dvNvmM
Parent Container:
/*Start dependencies*/
import React, { Component, PropTypes } from 'react';
import Picture from '../../components/picture.jsx';
import ShoppingCart from '../../components/shoppingcart.jsx';
import NavBar from '../../components/navbar.jsx';
import { browserHistory } from 'react-router';
import cart from '../../reducers/index.js';
/*Flag set to know if the client recieved and loaded
Will be set to True once the response from the server
Is loaded and parsed*/
var flag = true;
//Start React class
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {clothingData: 0}
}
render(){
/*if the flag variable is false, server is not done yet retriving
data from the DB and parsing it, thus nothing displayed
*/
if (!flag){
return (
<div>
</div>
);
}
//If flag is true (data is ready to be displayed)
else{
//console.log(this.state.clothingData[0].path);
//console.log(this.state.clothingData[0].fileName);
//console.log(this.state.clothingData);
return (
<div>
<NavBar />
<Picture className = "test" src = {this.state.clothingData} onClick = { () => {browserHistory.push('/Product'); }} name = {"joe"} />
</div>
);
}
}
}
JSX:
import React, { Component, PropTypes } from 'react';
export default class NavBar extends Component {
render(){
return(
<ul className="navbar">
<li className="dropdown">
Clothes
<div className="dropdown-items">
Item
Item
Item
Item
</div>
</li>
<li>About</li>
<li>Policies</li>
<li>How To Rent</li>
<li>Contact</li>
</ul>
);
}
}
CSS:
/*Main HTML Stylesheet*/
html{
font-family: sans-serif;
}
/*div{
background:white;
}*/
/********* NavBar Section **********/
.navbar {
overflow: hidden;
background-color:#B597C3;
}
/* links inside the navigation bar */
.navbar li {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: .625em 5em;
text-decoration: none;
font-size: 17px;
}
/* color of links on hover */
.navbar a:hover {
color:#ffffff;
text-decoration: underline;
}
.navbar a.active {
text-decoration:underline;
}
/* Drop Down Items */
.dropdown-btn {
float:left;
font-size: 1.0625em;
color:white;
border: none;
cursor: pointer;
overflow:hidden;
}
.dropdown{
display: inline-block;
}
.dropdown-items{
position:absolute;
display: none;
margin:0;
min-width: 10em;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-items a {
color:white;
padding: 12px 50px;
text-decoration: none;
display: block;
}
.dropdown:hover .dropdown-items {
display: block;
position: absolute;
width: 100%;
height: 100%;
}
/********* NavBar Section **********/
When Hovered:
When Hovered w/ increased size:
Okay, so I think you should not use CSS pseudo selectors with React. I've read questions like this one and my conclusion is in React you should handle the onMouseEnter and onMouseLeave events yourself and then keep a component state that indicates whether the dropdown should be shown or not.
That is the React way of usually doing things: hook up event handler functions and use the component state. When the handler functions are called, you change the state.
I don't know whether CSS pseudo selectors will work properly with React. You can take a look at this GitHub issue. My guess is that whatever you are trying to do doesn't work with the CSS selectors because React uses a virtual DOM and not the actual DOM. So the CSS would be changing the DOM directly kind of thing? It would be nice if other more knowledgeable people could comment on that.
For now, I think you should follow the React way of doing things. Here is the code for what you are trying to do:
import React, { Component, PropTypes } from 'react';
export default class NavBar extends Component {
state = {
showDropdown: false
}
renderDropdown() {
return (
<div className="dropdown-items">
Item
Item
Item
Item
</div>
);
}
render() {
return (
<ul className="navbar">
<li
className="dropdown"
onMouseEnter={() => this.setState({ showDropdown: true })}
onMouseLeave={() => this.setState({ showDropdown: false })}
>
Clothes
{this.state.showDropdown ? this.renderDropdown() : null}
</li>
<li>About</li>
<li>Policies</li>
<li>How To Rent</li>
<li>Contact</li>
</ul>
);
}
}
Keep in mind you should remove the CSS rule for the hover pseudo selector for the items div, as well as the display: none for the dropdown. After doing that, everything should be OK.
Note: I used a property initializer to set up the initial state for the component. Babel should take care of transpiling that. In case that doesn't work, set the initial state in the constructor.