Unable to change MUI table padding - css

I am using the Table component from the react library material-ui.
For some reason, each row, including the header, has a 24px padding, top and bottom, which I can't override.
I already tried changing the style on all the underlying components with no success. Here is the code:
<Table>
<TableHeader adjustForCheckbox={false} displaySelectAll={false} fixedHeader={true}>
<TableRow>
<TableHeaderColumn>id</TableHeaderColumn>
<TableHeaderColumn>name</TableHeaderColumn>
<TableHeaderColumn>number</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody showRowHover={true} displayRowCheckbox={false}>
{data.map(item => {
return (
<TableRow key={item.id}>
<TableRowColumn>{item.id}</TableRowColumn>
<TableRowColumn>{item.name}</TableRowColumn>
<TableRowColumn>{item.number}</TableRowColumn>
</TableRow>
);
})}
</TableBody>
</Table>
Any idea how which component's style needs to be changed in order to override this styling?

This kind of requirements can be handled with overrides in Material UI as per below example:
Step 1: include following dependencies
import { ThemeProvider } from '#material-ui/core'
import { createMuiTheme } from '#material-ui/core/styles';
Step 2: Define custom css related changes as
const theme = createMuiTheme({
overrides: {
MuiTableCell: {
root: { //This can be referred from Material UI API documentation.
padding: '4px 8px',
backgroundColor: "#eaeaea",
},
},
},
});
Step 3: Wrap your component or your code block with
<ThemeProvider theme={theme}>
<Table>
<TableRow>
<TableCell component="td" scope="row">
</TableCell>
</TableRow>
</Table>
</ThemeProvider>
This is how we can override the Material UI style from our custom style.
Happy Coding :)

The issue was with the height property of both the TableRow and TableHeaderColumn/TableRowColumn. For some reason this property manifested itself as padding-top/bottom.
To make a long story short, set the height property on the row and columns.

you can set size and paading props in material ui table
import {Table,} from '#material-ui/core';
<Table size="small" aria-label="a dense table"></Table>
refer this for more details : https://material-ui.com/api/table/
and make sure that elements inside the table row has small sizes .

Indeed, there is a padding added in the Table component, as seen here in the code of that component.
It cannot be overridden in material-ui API, and the context Theme variable desktopGutter is used in many places so I suggest not to change it.
What you can do is override that with a custom CSS item, that you will bundle with the rest of your CSS, either classic stylesheets or "react stye" with Radium or similar.
For example:
<Table id="mytable">...your material-ui JSX...</Table>
In the CSS:
#mytable .table {
padding: 0 !important;
}
Edit: my mistake, this is for the main table component, not the rows, but you can do something similar with the other components by watching in the developper tools which CSS path needs to be overriden.

Related

How to use components in different ways (React)

I want to use simple components in different way and different ui rendering
For example a dropdown rendering a list may have several ui according to the page or context (=> padding, margins, font size and other css properties might change)
should I:
implement it by overwriting in the parent component (target css properties of the child component and apply them my css needs - at cost that if change happens in the child component like change in classname or what might break the parent design)
Pass flags to the component to handle those design and at cost that each component handle the design of each parent
There are different approaches to this and everybody has his own preferences.
I usually solve this by supporting the className property. The class is accepted as a prop and applied to the root. So it is easy to change things like outer margins or the background-color. I usually discourage modifications of deeply nested elements.
Example:
import classnames from 'clsx';
import style from './button.module.scss';
export const Button = ({ content, onClick, className }) => {
return (
<div
className={classnames(style.buttonRoot, className)}
onClick={onClick}>
{content}
</div>
);
};
and if I want to modify it anywhere I can do it thus:
import { Button } from './Button';
import style from './productView.module.scss';
// ...
<Button content={'Show products'} className={style.showProdButton} onClick={showProd} />
and
.show-prod-button {
background-color: #562873;
margin-left: 32px;
}

Material UI 5 problems with emotion

I migrated from Material UI 4 to 5 Beta in my react app. From the documentation (docs style library) I can see that now I can use emotion, but when I use it I receive a message in the css attribute of the element where I use it.
My code:
import { jsx, css } from '#emotion/react';
//Other code.....
return (
<IconButton
css={css`
margin-left: 10px;
`}
//css={css({ marginLeft: 10 })}
aria-label='show 4 new mails'
color='inherit'
>
<Badge badgeContent={1} color='secondary'>
<MailIcon />
</Badge>
</IconButton>
)
If i inspect HTML, inside thebutton that is rendered i can see the attribute css like this css="You have tried to stringify object returned from 'css' function. It isn't supposed to be used directly (e.g. as value of the 'className' prop), but rather handed to emotion so it can handle it (e.g. as value of 'css' prop)."
I tried css prop with backtick and css function but none is working.
EDIT:
Changed marginleft into margin-left (this was an error while copiyng the code form my project)
I solved this ussues by adding /** #jsxImportSource #emotion/react */ in top of my import

Applying CSS stylesheet only to active component

I'm working on a ReactJS app that has a header at the top, a menu on the left, and the "frame" in the middle is where routes and their corresponding components are loaded. I want to be able to apply a CSS stylesheet to specific components only when they are loaded. I also don't want them applied all the time or to the top header or left menu.
My expectation was that adding import 'custom.css'; to a specific component would only apply the stylesheet's styles to that component and it's children when the route is active. Instead, it applies it to the entire page even when the route/component are not loaded.
I understand that an alternative approach is styled components, but, for my use-case, a design company is supplying a stylesheet (which should remain unchanged) that we need to consume only for the sub-module I'm working on and I don't want its styles to affect the rest of the app.
How can I have a stylesheet only applied to my active route/component?
Use simple CSS technique. Suppose you have two components with different css files (say about.css and contact.css). Now consider your both CSS file have one common class with different style properties, like:
about.css
.container{
max-width: 400px;
}
contact.css
.container{
max-width: 500px;
}
Yes in ReactJS both the CSS files will load at the same time and will override any one of the style. so to solve this problem add class to differentiate this styles, like:
about.css
.about-component.container{
max-width: 400px;
}
contact.css
.contact-component.container{
max-width: 500px;
}
If you want apply only when the component is mounted, you can use the lifecycle.
The follow example is based in the idea you are using sass, React, sass-node and have the loaders into webpack.
<pre>
import React from 'react';
import './styles.scss';
class MyComponent {
constructor(props) {
super(props);
this.state = { className: '' }
}
componentDidMount() {
this.setState({
className: 'myOwnClass'
});
}
render(){
return (
<div className={this.state.className}>This is a example</div>
);
}
}
export default myComponent;
</pre>
To be able to only call that specific CSS when you need it you can use CSS Modules. You may need to update your version of react.
When saving your CSS file save it with a ".module.css" eg. "styles.module.css". The CSS in these files can only be used and accessed by hte components where are they are imported. As stated in a tutorial from W3Schools.
Let's say this is your CSS code in styles.module.css:
.container {
color: white;
}
.cont-child {
background-color: red;
}
Then in your JS file you can import the CSS file like this if the JS and CSS files are in the same directory. Make sure you point to the correct path.
import styles from './styles.module.css'
Then in your HTML section you can use it like this:
class Home extends React.Component {
render() {
return(
<main className={ styles.container } >
<div className={ styles["cont-child"]} >
Some div text about something...
</div>
</main>
);
}
}
I currently use both ways to access the selectors, since the styles variable acts like an object. I placed both of them here because the second option is capable of fetching selectors named like "btn-active". Which comes in handy in some situations. Camelcasing is considered cleaner though.
Please note: I originally posted this answer as a reply to a similar question here React CSS - how to apply CSS to specific pages only
I want to be able to apply a CSS stylesheet to specific components
only when they are loaded.
Why not apply the styles inline via React.js?
Step 1. Create the style object for the component:
var componentOneStyle = {
color: 'white',
backgroundColor: 'red'
};
Step 2. Populate the component's style attribute with the style object:
ReactDOM.render(<div style={componentOneStyle}>This is Component One</div>, mountNode);

Component is briefly rendering without styles on first render

When I open my react app, the component below flashes with width:100%, probably because it inherits it from the material-ui card.
In my react app there are a lot of these components being rendered, each with their own width which are based on the parent component's data. I set the width with an inline style based on the props.
As I understand, the component has the inline style as it is created and there should be no delay to apply it. However I see all the SceneThumb components with 100% width for a a fraction of a second, before they apply the given inline style.
If I change the css of scene-thumb-parent to include some width, say 10% for example, then I'll see them all with 10% for a fraction of a second, before the inline style is applied. That makes me think there is a delay in applying inline css, but it really puzzles me..
Is this to be expected of react? Or of html in general? Is there any way to reduce this inline style application delay? Maybe it's something to do with the dev hot reloading setup I get from create-react-app?
SceneThumb.js (code that is irrelevant to the question has been omitted):
import React, { Component } from 'react';
import './scene-thumb.css';
import Card from 'material-ui/Card';
class SceneThumb extends Component {
render() {
return (
<div
className='scene-thumb-parent'
style={{width:this.props.width, left:this.props.left}}
>
<Card
className={this.props.selected?'scene-thumb-selected':'scene-thumb'}
>
<span>
Hello world!
</span>
</Card>
</div>
);
}
}
export default SceneThumb;
scene-thumb.css:
.scene-thumb-parent {
position:relative;
text-overflow:clip;
white-space:nowrap;
overflow:hidden;
min-width: 12px;
}
.scene-thumb-selected {
border: 2px solid red;
border-radius: 5px;
}
.scene-thumb,.scene-thumb-selected {
padding: 2px;
margin:2px;
position:relative;
}
The width prop is initially null or some other value. A moment later, the prop is updated which triggers another render. This is why you're seeing the flash you're talking about.
You can test this by adding the following to your render() function:
console.log(this.props.width)
You'll probably see it logging at least twice with different values.
There are many ways you can fix this. What makes most sense would depend on the rest of the application, and your personal preference. Regardless, here's one way:
render() {
if(!this.props.width) return null; //if it's null, render nothing.
return (
<div className='scene-thumb-parent' style={{width:this.props.width, left:this.props.left}}>
<Card className={this.props.selected?'scene-thumb-selected':'scene-thumb'}>
<span>Hello world!</span>
</Card>
</div>
);
}

material-ui change the height of the drawer

I'm using react and material-ui in my project and I have come across a simple issue that I just dont't know how to solve.
I want to create a drawer and set its height in a way that when it will open, it wont open over the app bar.
There is no parameter in the Drawer component for the height, I also tried to override its style and setting up the height on the style object like this :
<Drawer style={{height:'90%'}} />
But it didn't work.
The only way I can think of, is editing the code of the Drawer component, but ofcourse I want to avoid that.
Any idea on how I can define the height?
Here you go:
<Drawer open={this.state.open} containerStyle={{height: 'calc(100% - 64px)', top: 64}}>
<MenuItem>Menu Item</MenuItem>
<MenuItem>Menu Item 2</MenuItem>
</Drawer>
containerStyle is prohibited in version 1.0 and above
So you need to use props classes instead
Here is an example to this nontrivial case
import {withStyles, createStyleSheet} from 'material-ui/styles'
const styleSheet = createStyleSheet({
paper: {
height: 'calc(100% - 64px)',
top: 64
}
})
class CustomDrawer extends Component {
...
render () {
const classes = this.props.classes
return (
<Drawer
classes={{paper: classes.paper}}
>
...
)
}
CustomDrawer.propTypes = {
classes: PropTypes.object.isRequired
}
export default withStyles(styleSheet)(CustomDrawer)

Resources