Providing a title for a MUI Data Grid - reactjs

I'm learning how to use the MUI Data Grid React Component (MIT licensed version).
Is it possible to add a title to a Data Grid? Just some simple centered text above the column headers but below the Data Grid border would be great, though having custom components in a title would be ideal.
Is there a built in way to do this?
edit: Here is an example of what I'm trying to do. In this screenshot, I did it by wrapping the DataGrid in a div and giving that div a border, and removing the DataGrid border.
Is there some way to do this natively with the Data Grid interface?

Solved! When constructing the Data Grid, you can use the components prop, which accepts a ToolBar component.
<DataGrid
{...}
components={{Toolbar: DataGridTitle}}
/>
Where DataGridTitle is your own component that can have a title in it. In this case, I'm using:
function DataGridTitle() {
return(
<Box style={{width: "100%", display: "flex", justifyContent: "center", alignItems: "center"}}>
<Typography variant="h5">Users</Typography>
</Box>
)
}
And it works perfectly:

Related

Half page image on MUI v5

I'm trying to create a landing page in MUI v5 where half of the page is an image and the second part of the page is a form to login. I want the image and form to always fill the page completely with no scroll.
However, when doing so, it seems that MUI root is always affecting the margin so that the view has a horizontal scroll and there is white space on the left-hand side (See example below - and ignore the silly image):
How the page should look (and what it looks like if I scroll to the right):
How the page should look when I load it before scrolling:
I've spent hours trying to edit the CSS and figuring out where this is coming from with no luck. There is probably a better way to format this but I am using Grid and have tried Box with no luck.
My source code looks something like:
import React from "react";
import PropTypes from "prop-types";
import Grid from "#mui/material/Grid/Grid";
import Box from "#mui/material/Box";
import Paper from "#mui/material/Paper";
import SomeComponent from "...{some_path}...";
import SomeFormComponent from "...{some_path}...";
const SomeComponent = ({children, title, width}) => {
return (
<Grid container disableGutters sx={{height: "100vh", width: "100vw"}}>
<Grid
item
xs={false}
sm={4}
md={7}
sx={{
backgroundImage: `url(${SomeImage})`,
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
backgroundPosition: "center",
}}
/>
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<Box
sx={{
my: 8,
mx: 4,
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<SomeFormComponent width={width} title={title}>
{children}
</SomeFormComponent>
</Box>
</Grid>
</Grid>
);
};
Also, inspecting the page elements, I've identified the padding and margin come from a class called css-ayh9c9-MuiGrid-root which seems to be causing this because if I remove the class from the parent, everything works as expected. However, this is being added by MUI behind the scenes because it is nowhere in my source code.
Any help would be greatly appreciated!
I prefer Box whenever possible because Grid does some funky stuff with margins. In this case you can use the flex attribute on the children to get the right proportions. here is a working example https://codesandbox.io/s/material-demo-forked-rur3t?file=/App.tsx

Bring up scrollbar when <TextareaAutosize> is shrunk

I am using a <TextareaAutosize> component from the Material UI Library in my React app, as such:
<TextareaAutosize
minRows="2"
style={{resize: "vertical"}}
/>
This creates a textarea that autosizes based on the size of the content. I have styled it so that the user is only able to manually expand vertically.
The current behavior is that, when the user shrinks the textbox, there is no way to view the content out of sight. My goal is to bring up the scroll bar when the user shrinks the text area.
View CodeSandbox to test.
Simply add overflow: 'auto' to the style attribute.
<TextareaAutosize
minRows="2"
style={{ width: '50%', resize: 'vertical', overflow: 'auto' }}
/>
Codesandbox

How can I make a background image repeat using React gatsby-background-image?

Following the instructions in the gatsby-background-image documentation, I'm able to add a full width background image to a component by including the following in my component
<BackgroundImage fluid={backgroundImage.node.childImageSharp.fluid}>
{children}
</BackgroundImage>
This results in the following "stretched" background:
However, I do not want my image to be the full width of the component. Instead, I would like my background image to repeat within my component to achieve the following:
I see that styling of the background image is supported, but I'm not sure how correctly style the background image to make it repeat. Any help would be much appreciated!
Just add the style object as shown in the Styling & Passed Through Styles section.
<BackgroundImage fluid={backgroundImage.node.childImageSharp.fluid}
style={{ backgroundRepeat: 'repeat', backgroundSize: '200' }}>
{children}
</BackgroundImage>

What is the MUI Box component for?

Try as I might, I cannot wrap my head around the description given here.
The Box component serves as a wrapper component for most of the CSS utility needs.
What are 'the' CSS utility needs?
What is the use case for this component? What problem does it solve? How do you use it?
I find the MUI docs very limited and hard to understand. I have googled, but generally only found fairly lightweight blog posts on how to use material UI. In addition to help understanding this component, I would really appreciate any good resources (something like a better version of their own documentation, if such a thing exists).
(Background, I generally understand React, JS, CSS, HTML etc, with less strength in the latter two).
EDIT: This was written in the MUI v4 days. In MUI v5, all MUI components allow you to define CSS styles via the sx prop, not just Box; but Box also accepts styling props at top-level, as well as within sx.
The other answers don't really explain the motivation for using Box.
Box renders a <div> you can apply CSS styles to directly via React props, for the sake of convenience, since alternatives like separate CSS files, CSS-in-JS, or inline styles can be more typing and hassle to use.
For example, consider this component that uses JSS:
import * as React from 'react'
import { makeStyles } from '#material-ui/styles'
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: theme.spacing(1),
}
}))
const Example = ({children, ...props}) => {
const classes = useStyles(props);
return (
<div className={classes.root}>
{children}
</div>
)
}
It's much shorter to do this with Box by passing the props you want to it:
import * as React from 'react'
import Box from '#material-ui/core/Box'
const Example = ({children}) => (
<Box display="flex" flexDirection="column" alignItems="stretch" padding={1}>
{children}
</Box>
)
Notice also how padding={1} is a shorthand for theme.spacing(1). Box provides various conveniences for working with Material-UI themes like this.
In larger files it can be more of a hassle to jump back and forth from the rendered elements to the styles than if the styles are right there on the element.
Cases where you wouldn't want to use Box (MUI v4):
You want the enclosing component to be able to override styles by passing classes (makeStyles enables this. <Example classNames={{ root: 'alert' }} /> would work in the makeStyles example, but not the Box example.)
You need to use nontrivial selectors (example JSS selectors: $root > li > a, $root .third-party-class-name)
A Box is basically a div* on steroid. Box allows you to apply dynamic styles to an otherwise normal div very quickly like inline styles (but it's not inline styles). Besides that, it also has a first-class integration with MUI theme:
<Box
sx={{
bgcolor: 'primary.main',
color: 'text.secondary',
border: 4,
borderRadius: 2,
px: 2,
fontWeight: 'fontWeightBold',
zIndex: 'tooltip',
boxShadow: 8,
}}
>
Box
</Box>
If you need to do the above with a normal div, you have to get the theme object using useTheme hook and create an inline styles which is not a good practice if abused everywhere:
<div
style={{
backgroundColor: theme.palette.primary.main,
color: theme.palette.text.secondary,
border: '4px solid black',
borderRadius: theme.shape.borderRadius * 2,
padding: `0 ${theme.spacing(2)}`,
fontWeight: theme.typography.fontWeightBold,
zIndex: theme.zIndex.tooltip,
boxShadow: theme.shadows[8],
}}
>
div
</div>
Box among other components like Typography or Stack also supports system properties that lets you pass the style values to the top-level props, which resulted in even shorter code. Internally, the system properties are gathered and merged with the sx prop so they are the same thing (See this answer for more detail)
<Box
bgcolor="primary.main"
color="text.secondary"
border={4}
borderRadius={2}
px={2}
fontWeight="fontWeightBold"
zIndex="tooltip"
boxShadow={8}
>
Box
</Box>
Because Box leverages sx prop, you can also use sx features like adding responsive values:
<Box
display={{
xs: 'none',
sm: 'block',
}}
width={{
sm: 30,
md: 50,
lg: 100,
}}
>
Or creating nested styles:
<Box
display='flex'
sx={{
'& > :not(:last-child)': {
mr: 2 // maginRight: theme.spacing(2)
},
':hover': {
bgcolor: 'green'
}
}}
>
When to use Box?
When you want to create a styled div quickly when prototyping.
When you want to create a one-off inline styles that is not really reusable anywhere else. This is convenient when you want to fix something that is a bit off in a specific part of your layout.
When you want to add dynamic or responsive styles and make your code easier to understand at the same time because everything is defined in one place, plus the fact that sx syntax is highly compact.
When you want to reference multiple MUI theme properties because many sx properties are theme-aware out-of-the-box.
When not to use Box?
When you don't need to styles anything. Just use a normal div then.
When you are using it in a highly reusable components like list item, grid item or table cell. This is because sx prop has the slowest performance (2x slower than the second slowest approach)
When you're using other MUI components. In v5, all components from MUI has sx support so using Box as a wrapper or root component is unnecessary if you just want to style other MUI components.
*: By default a Box is a div, but you can override the root component of it. For example: <Box component='span'>
A Box is just that, a box. It's an element wrapped around its content which by itself contains no styling rules nor has any default effects on the visual output. But it's a place to put styling rules as needed. It doesn't offer any real functionality, just a placeholder for controlling the styles in the hierarchical markup structure.
Structurally it results in a <div>.
I often think of it as semantically similar to the JSX empty element:
<>
Some elements here
</>
In that it's used to group things. But it results in a <div> and can include some Material UI capabilities:
<Box className={classes.someStyling}>
Some elements here
</Box>
The Box component in Material UI it has a lot of useful stuff
The most important thing is that box element has been built in with material-ui/system functionalities by default that mean you can apply system functionalities to what you need if you use it as wrapper
Like this example:
<Box bgcolor="primary.main" color="primary.contrastText" p={2}>
primary.main
</Box>
and of course you can add css class to it as you like or not
the other good useful thing that it offer it can be warp in other components and be very helpful to apply system functionalities to it
Like this example:
<Typography component="div" variant="body1">
<Box color="primary.main">primary.main</Box>
</Typography>
Both of examples above i took them from documentation
you can find them in this link :here
and you can find what i mean by material ui system functionalities:here
Note: you can add any of material ui system functionalities to any component like docs here but i recommend you to warp what u need with box component it make life a lot easier

TouchableOpacity breaks styling

I'm attempting to create navigation in React Native. I've made a custom component that consists of an image and some text. Before applying TouchableOpacity the styling works fine. But after I apply it to one of the components, this happens.
All of the code can be found here, ready to run.
I'd like that the component titles MojQR doesn't deform, but stays like the rest of them. Currently, as seen in the code, the TouchableOpacity is only applied to MojQR
You have a problem with the styling you are using. When you set the dimensions (width, height) to take a percentage, it will take the percentage from the component that is wrapping it. That's why when you added TouchableOpacity it mess all the styling. You have 2 options, change the styling pattern you are using or make a simple change that can change the width dynamically from MenuItem like so:
//App.js
<TouchableOpacity style={styles.touchableContainer} onPress={() => navigation.navigate('Details')}>
<MenuItem itemImage={require('./app/img/QR_code_for_mobile_English_Wikipedia.svg.png')} children='Moj QR' isWrapped={true} />
</TouchableOpacity>
...
//And the styling inside your style object
touchableContainer: {
width: '50%'
}
In the code above, you add that prop that will be used to change the styles in
//MenuItem.js
//change the wrapper for this one:
<View style={this.props.isWrapped ? {...styles.menuItem, width: '100%'} : styles.menuItem}>
...
//And add the flexGrow property to your styles.menuItem
menuItem: {
width: '50%',
height: '33.3333%',
padding: 10,
flexGrow: 1,
},

Resources