React Create a Horizontal Divider with Text In between - reactjs

I need to create a React component that is a Horizontal Divider with a content like text In between. All the resources I have online is unable to help me get this done. I tried a material-ui divider by creating a Divider component and placing my text in-between like the example below:
<Divider>Or</Divider>
But I get the error:
hr is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.
I need to achieve this in the image below:
Any help will be appreciated.
These are my codes below:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import List from '#material-ui/core/List';
import Divider from '#material-ui/core/Divider';
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
}));
export default function ListDividers() {
const classes = useStyles();
return (
<List component="nav" className={classes.root} aria-label="mailbox
folders">
<Divider>Or</Divider>
</List>
);
}

Using Material UI.
import React from "react";
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles(theme => ({
container: {
display: "flex",
alignItems: "center"
},
border: {
borderBottom: "2px solid lightgray",
width: "100%"
},
content: {
paddingTop: theme.spacing(0.5),
paddingBottom: theme.spacing(0.5),
paddingRight: theme.spacing(2),
paddingLeft: theme.spacing(2),
fontWeight: 500,
fontSize: 22,
color: "lightgray"
}
}));
const DividerWithText = ({ children }) => {
const classes = useStyles();
return (
<div className={classes.container}>
<div className={classes.border} />
<span className={classes.content}>{children}</span>
<div className={classes.border} />
</div>
);
};
export default DividerWithText;
You can import and use it like the below
<DividerWithText>Or</DividerWithText>
Result

Here a custom example of what you could do : repro on stackblitz
import React, { Component } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";
const App = () => {
return <Divider>Or</Divider>;
};
const Divider = ({ children }) => {
return (
<div className="container">
<div className="border" />
<span className="content">
{children}
</span>
<div className="border" />
</div>
);
};
render(<App />, document.getElementById("root"));
And the CSS:
.container{
display: flex;
align-items: center;
}
.border{
border-bottom: 1px solid black;
width: 100%;
}
.content {
padding: 0 10px 0 10px;
}

Update 29/03/2022
That's now possible with Material UI đŸ”¥
https://mui.com/components/dividers/#dividers-with-text
You may want different spacing sometime
<Divider spacing={1}>Hello World</Divider>
Or
<Divider spacing={2}>Hello World</Divider>
For a configurable spacing here a Github Gist
Or a playground in codesandbox if you prefer

The current answer causes any text with spaces in-between to wrap:
If that happens, changing width: 100% to flexGrow: 1 should solve it:
border: {
borderBottom: "2px solid lightgray",
flexGrow: 1,
}

Unfortunately for now, having Divider with text on it in MUI is only available in v5, which is still in alpha stage. If you would like to try, you can download the alpha package, but be warned that it is still highly unstable and a lot of changes might be needed to migrate to v5, which is not very worth it.
GitHub discussion: https://github.com/mui-org/material-ui/issues/24036

Related

How to change icon size in MUI breakpoints?

import { Container } from "#mui/material";
import * as React from "react";
import { Home } from "#mui/icons-material";
import PersonIcon from "#mui/icons-material/Person";
import FormatListBulletedIcon from "#mui/icons-material/FormatListBulleted";
import CameraAltIcon from "#mui/icons-material/CameraAlt";
import OndemandVideoIcon from "#mui/icons-material/OndemandVideo";
import PhoneAndroidIcon from "#mui/icons-material/PhoneAndroid";
import FeaturedPlayListIcon from "#mui/icons-material/FeaturedPlayList";
import StorefrontIcon from "#mui/icons-material/Storefront";
import SettingsIcon from "#mui/icons-material/Settings";
import LogoutIcon from "#mui/icons-material/Logout";
import Typography from "#mui/material/Typography";
import { styled } from "#mui/material/styles";
const StyledContainer = styled("div")(({ theme }) => ({
paddingTop: theme.spacing(10),
backgroundColor: theme.palette.primary.main,
height: "100vh",
color: "white",
[theme.breakpoints.up("sm")]: {
backgroundColor: "white",
color: "#555",
border: "1px solid #ece7e7",
},
}));
const Item = styled("div")(({ theme }) => ({
display: "flex",
alignItems: "center",
marginBottom: theme.spacing(4),
[theme.breakpoints.up("sm")]: {
marginBottom: theme.spacing(3),
cursor: "Pointer",
},
}));
const Icon = styled("div")(({ theme }) => ({
marginRight: theme.spacing(1),
[theme.breakpoints.up("sm")]: {
//I need to change the Icon size
//fontSize:"18px" but this not working
},
}));
const Text = styled("div")(({ theme }) => ({
fontWeight: 500,
fontSize: "300px",
[theme.breakpoints.down("sm")]: {
display: "none",
},
}));
function Leftbar() {
return (
<StyledContainer>
<Container>
<div>
<Item>
<Icon>
<Home />
</Icon>
<Text>
<Typography>Homepage</Typography>
</Text>
</Item>
</div>
<div>
<Item>
<Icon>
<PersonIcon />
</Icon>
<Text>
<Typography>Friends</Typography>
</Text>
</Item>
</div>
</Container>
</StyledContainer>
);
}
export default Leftbar;
This is my sidebar code. and this is the screenshot of the page.
Here I need to change the sidebar icon sizes. But the problem is I unable to change the Icon sizes in breakpoints. This is the code of that breakpoint.
const Icon = styled("div")(({ theme }) => ({
marginRight: theme.spacing(1),
[theme.breakpoints.up("sm")]: {
//I need to change the Icon size
//fontSize:"18px" but this not working
},
}));
I tried several times to solve this problem. But I didn't get a solution. So if anyone knows how to solve this problem, Please help me. Thank you
[![enter image description here][2]][2]
You need to select svg to apply font size.
Try this
[theme.breakpoints.up("sm")]: {
'& svg': {
fontSize: 18
}
},

How to remove default Button classes from material UI and use my own css class

I am new to React and material UI. I am using material UI button and I want to remove default button classes (MuiButtonBase-root MuiButton-root MuiButton-text makeStyles-buttonCss-3). I want to use only my class 'buttonCss'. Please can anyone help me to fix this.
My code is below -:
import { TextField } from '#material-ui/core';
import Button from '#material-ui/core/Button';
import { makeStyles } from '#material-ui/core/styles'
import { Form, Formik } from 'formik';
import * as React from 'react';`enter code here`
const useStyles = makeStyles((theme) => ({
container: {`enter code here`
maxWidth: "100vw",
maxHeight: "100vh",
display: "flex",
alignItems: "flex-start",
justifyContent: "space-evenly",
flexWrap: 'wrap'
},
mybox: {
width: 300,
backgroundColor: theme.palette.success.main,
color: "white",
padding: theme.spacing(1),
borderRadius: 4,
boxShadow: theme.shadows[10]
},
buttonCss : {
backgroundColor: theme.palette.success.dark
},
deafult: {
color: 'red'
}
}));
// implementing button this way
<Button className={classes.buttonCss} >Submit</Button>
You can't remove the default class and then continue using MaterialUi, now just use the default html button .
If you want only to customise, now just use
const useStyles = makeStyles({
root: {background: "red}
});
export default () => {
const classes = useStyles();
return <Button className={classes} >Submit</Button>
}

Typescript/React/MaterialUI/JSS project: override CSS for a single React component

I am trying to understand how to override the CSS/formatting/theme for just a single React component in a Typescript/React/MaterialUI/JSS project. Below is the code, however the {classes.gridStyle} within the JSX doesn't get processed (see screenshot below the code snippet). I can see it show up in the browser debugger as unmodified and the typescript editor is also giving me a warning that variable "classes" is never used.
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { Grid, createStyles } from '#material-ui/core';
const useStyles = makeStyles(() =>
createStyles({
gridStyle: {
display: 'inline-block',
padding: '0 20px',
height: '40px',
},
'& div': {
display: 'inline-block',
fontSize: '10px',
padding: '0 20px',
height: '40px',
},
})
);
export default function HomeHeader(): JSX.Element {
const classes = useStyles();
return (
<Grid item className="{classes.gridStyle}">
Row 1 completely override css experiment...
</Grid>
);
}
Issue inside browser debugger
className="{classes.gridStyle}">
should be
className={classes.gridStyle}>

How to 'justify-content: center' for MUI Pagination?

I am trying to center the contents of the Pagination. However, this does not work. On console, I need to justify the ul wrapper and I can not find any information on MUI site related to the pagination props or a guide on how to center the item.
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Pagination from '#material-ui/lab/Pagination';
const useStyles = makeStyles((theme) => ({
root: {
'& > *': {
marginTop: theme.spacing(2),
},
},
pagination: {
alignItems: 'center',
justify: 'center',
}
}));
const Paginated = (props) => {
const classes = useStyles();
return (
<div className={classes.root}>
<Pagination className={classes.pagination} count={props.totalPage} color='primary' />
</div>
);
};
export default Paginated;
and I have been trying on codesandbox as well. https://codesandbox.io/s/material-demo-zv1ps?file=/demo.js
Is there any way I can do this without having an additional box or Grid wrapper to wrap it out?
root: {
"& > *": {
marginTop: theme.spacing(2),
justifyContent:"center",
display:'flex'
}
}
We can also use Stack component:
import Stack from '#mui/material/Stack';
<Stack alignItems="center">
<Pagination className={classes.pagination} count={props.totalPage} color='primary' />
</Stack>
margin: "auto" worked for me
root: {
margin: "auto",
},
I got the idea from here: 4 ways to center a component in Material-UI

How to style MUI Tooltip?

How can I style MUI Tooltip text? The default tooltip on hover comes out black with no text-wrap. Is it possible to change the background, color etc? Is this option even available?
The other popular answer (by André Junges) on this question is for the 0.x versions of Material-UI. Below I've copied in my answer from Material UI's Tooltip - Customization Style which addresses this for v3 and v4. Further down, I have added a version of the example using v5.
Below are examples of how to override all tooltips via the theme, or to just customize a single tooltip using withStyles (two different examples). The second approach could also be used to create a custom tooltip component that you could reuse without forcing it to be used globally.
import React from "react";
import ReactDOM from "react-dom";
import {
createMuiTheme,
MuiThemeProvider,
withStyles
} from "#material-ui/core/styles";
import Tooltip from "#material-ui/core/Tooltip";
const defaultTheme = createMuiTheme();
const theme = createMuiTheme({
overrides: {
MuiTooltip: {
tooltip: {
fontSize: "2em",
color: "yellow",
backgroundColor: "red"
}
}
}
});
const BlueOnGreenTooltip = withStyles({
tooltip: {
color: "lightblue",
backgroundColor: "green"
}
})(Tooltip);
const TextOnlyTooltip = withStyles({
tooltip: {
color: "black",
backgroundColor: "transparent"
}
})(Tooltip);
function App(props) {
return (
<MuiThemeProvider theme={defaultTheme}>
<div className="App">
<MuiThemeProvider theme={theme}>
<Tooltip title="This tooltip is customized via overrides in the theme">
<div style={{ marginBottom: "20px" }}>
Hover to see tooltip customized via theme
</div>
</Tooltip>
</MuiThemeProvider>
<BlueOnGreenTooltip title="This tooltip is customized via withStyles">
<div style={{ marginBottom: "20px" }}>
Hover to see blue-on-green tooltip customized via withStyles
</div>
</BlueOnGreenTooltip>
<TextOnlyTooltip title="This tooltip is customized via withStyles">
<div>Hover to see text-only tooltip customized via withStyles</div>
</TextOnlyTooltip>
</div>
</MuiThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here is documentation on tooltip CSS classes available to control different aspects of tooltip behavior: https://material-ui.com/api/tooltip/#css
Here is documentation on overriding these classes in the theme: https://material-ui.com/customization/components/#global-theme-override
Here is a similar example, but updated to work with v5 of Material-UI (pay attention that it works in 5.0.3 and upper versions after some fixes). It includes customization via the theme, customization using styled, and customization using the sx prop. All of these customizations target the "tooltip slot" so that the CSS is applied to the element that controls the visual look of the tooltip.
import React from "react";
import ReactDOM from "react-dom";
import { createTheme, ThemeProvider, styled } from "#mui/material/styles";
import Tooltip from "#mui/material/Tooltip";
const defaultTheme = createTheme();
const theme = createTheme({
components: {
MuiTooltip: {
styleOverrides: {
tooltip: {
fontSize: "2em",
color: "yellow",
backgroundColor: "red"
}
}
}
}
});
const BlueOnGreenTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} componentsProps={{ tooltip: { className: className } }} />
))(`
color: lightblue;
background-color: green;
font-size: 1.5em;
`);
const TextOnlyTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} componentsProps={{ tooltip: { className: className } }} />
))(`
color: black;
background-color: transparent;
`);
function App(props) {
return (
<ThemeProvider theme={defaultTheme}>
<div className="App">
<ThemeProvider theme={theme}>
<Tooltip title="This tooltip is customized via overrides in the theme">
<div style={{ marginBottom: "20px" }}>
Hover to see tooltip customized via theme
</div>
</Tooltip>
</ThemeProvider>
<BlueOnGreenTooltip title="This tooltip is customized via styled">
<div style={{ marginBottom: "20px" }}>
Hover to see blue-on-green tooltip customized via styled
</div>
</BlueOnGreenTooltip>
<TextOnlyTooltip title="This tooltip is customized via styled">
<div style={{ marginBottom: "20px" }}>
Hover to see text-only tooltip customized via styled
</div>
</TextOnlyTooltip>
<Tooltip
title="This tooltip is customized via the sx prop"
componentsProps={{
tooltip: {
sx: {
color: "purple",
backgroundColor: "lightblue",
fontSize: "2em"
}
}
}}
>
<div>
Hover to see purple-on-blue tooltip customized via the sx prop
</div>
</Tooltip>
</div>
</ThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Documentation on changes to the theme structure between v4 and v5: https://mui.com/guides/migration-v4/#theme
Tooltip customization examples in the Material-UI documentation: https://mui.com/components/tooltips/#customization
MUI v5 Update
You can customize the Tooltip by overriding the styles in the tooltip slot. There are 3 ways to do that in v5. For reference, see the customization section of Tooltip. More examples of sx prop and createTheme can be seen here and here.
styled()
const ToBeStyledTooltip = ({ className, ...props }) => (
<Tooltip {...props} classes={{ tooltip: className }} />
);
const StyledTooltip = styled(ToBeStyledTooltip)(({ theme }) => ({
backgroundColor: '#f5f5f9',
color: 'rgba(0, 0, 0, 0.87)',
border: '1px solid #dadde9',
}));
sx prop
<Tooltip
title="Add"
arrow
componentsProps={{
tooltip: {
sx: {
bgcolor: 'common.black',
'& .MuiTooltip-arrow': {
color: 'common.black',
},
},
},
}}
>
<Button>SX</Button>
</Tooltip>
createTheme + ThemeProvider
const theme = createTheme({
components: {
MuiTooltip: {
styleOverrides: {
tooltip: {
backgroundColor: 'pink',
color: 'red',
border: '1px solid #dadde9',
},
},
},
},
});
If you want to change text color , font-size ... of Tooltip there is a simple way.
You can insert a Tag inside Title of Martial Ui Tooltip for example :
<Tooltip title={<span>YourText</span>}>
<Button>Grow</Button>
</Tooltip>
then you can style your tag anyhow you want.
check below Example :
This answer is out of date. This answer was written in 2016 for the 0.x versions of Material-UI. Please see this answer for an approach that works with versions 3 and 4.
well, you can change the text color and the element background customizing the mui theme.
color - is the text color
rippleBackgroundColor - is the tooltip bbackground
Example: Using IconButton - but you could you the Tooltip directly..
import React from 'react';
import IconButton from 'material-ui/IconButton';
import MuiThemeProvider from 'material-ui/lib/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
const muiTheme = getMuiTheme({
tooltip: {
color: '#f1f1f1',
rippleBackgroundColor: 'blue'
},
});
const Example = () => (
<div>
<MuiThemeProvider muiTheme={muiTheme}>
<IconButton iconClassName="muidocs-icon-custom-github" tooltip="test" />
</MuiThemeProvider>
</div>
);
You can also pass a style object for the Tooltip (in IconButton it's tooltipStyles) - but these styles will only be applied for the root element.
It's not possible yet to change the label style to make it wrap in multiple lines.
I ran into this issue as well, and want for anyone seeking to simply change the color of their tooltip to see this solution that worked for me:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Tooltip from '#material-ui/core/Tooltip';
import Button from '#material-ui/core/Button';
import DeleteIcon from '#material-ui/icons/Delete';
const useStyles = makeStyles(theme => ({
customTooltip: {
// I used the rgba color for the standard "secondary" color
backgroundColor: 'rgba(220, 0, 78, 0.8)',
},
customArrow: {
color: 'rgba(220, 0, 78, 0.8)',
},
}));
export default TooltipExample = () => {
const classes = useStyles();
return (
<>
<Tooltip
classes={{
tooltip: classes.customTooltip,
arrow: classes.customArrow
}}
title="Delete"
arrow
>
<Button color="secondary"><DeleteIcon /></Button>
</Tooltip>
</>
);
};
MUI v5 custom component
Building on NearHuscarl's answer using sx, the simplest approach for me was to create a custom component to include the styling plus any other properties you want repeated on each tooltip.
For example, the component could display the tooltips on the bottom with an arrow and a larger font size:
const StyledTooltip = ({ title, children, ...props }) => (
<Tooltip
{...props}
title={title}
placement="bottom"
arrow
componentsProps={{
tooltip: {
sx: {
fontSize: '1.125rem',
},
},
}}
>
{children}
</Tooltip>
);
const Buttons = () => (
<div>
<StyledTooltip title="This is one">
<Button>One</Button>
</StyledTooltip>
<StyledTooltip title="This is two">
<Button>Two</Button>
</StyledTooltip>
</div>
);
Another solution with HtmlTooltip
I Use HtmlTooltip and add arrow: {color: '#f5f5f9',}, for the arrow tooltip style.
And much more to the tooltip style itself.
So I use ValueLabelComponent to control the label and put there a Tooltip from MaterialUI.
Hopes it give another way to edit MaterialUI Tooltip :)
const HtmlTooltip = withStyles((theme) => ({
tooltip: {
backgroundColor: 'var(--blue)',
color: 'white',
maxWidth: 220,
fontSize: theme.typography.pxToRem(12),
border: '1px solid #dadde9',
},
arrow: {
color: '#f5f5f9',
},
}))(Tooltip);
function ValueLabelComponent({ children, open, value }) {
return (
<HtmlTooltip arrow open={open} enterTouchDelay={0} placement="top" title={value}>
{children}
</HtmlTooltip>
);
}
...
...
return (
<div className={classes.root}>
<Slider
value={value}
onChange={handleChange}
onChangeCommitted={handleChangeCommitted}
scale={(x) => convertRangeValueToOriginalValue(x, minMaxObj)}
valueLabelDisplay="auto"
valueLabelFormat={(x) => '$' + x}
ValueLabelComponent={ValueLabelComponent}
aria-labelledby="range-slider"
/>
</div>
);
I used makeStyles() and ended with that:
import React from 'react';
import Grid from '#mui/material/Grid';
import Typography from '#mui/material/Typography';
import Tooltip from '#mui/material/Tooltip';
import InfoOutlinedIcon from '#mui/icons-material/InfoOutlined';
import { makeStyles } from '#material-ui/core/styles';
const styles = makeStyles({
tooltip: {
backgroundColor: '#FFFFFF',
color: '#000000',
border: '.5px solid #999999',
fontSize: '.85rem',
fontWeight: '400'
}
});
const HeaderTooltip = ({ header, tooltip }) =>
<Grid container direction="row" alignItems="center" spacing={1}>
<Grid item>
<Typography variant='h5'>{header}</Typography>
</Grid>
<Grid item>
<Tooltip title={tooltip} classes={{ tooltip: styles().tooltip }}>
<InfoOutlinedIcon />
</Tooltip>
</Grid>
</Grid>
export default HeaderTooltip;
With styledComponent and MUI V5
import styled from 'styled-components';
....
....
<StyledTooltip title={tooltip}>
<IconTextStyle>
{icon}
<Label>{label}</Label>
</IconTextStyle>
</StyledTooltip>
const StyledTooltip = styled((props) => (
<Tooltip classes={{ popper: props.className }} {...props} />
))`
& .MuiTooltip-tooltip {
display: flex;
background-color: #191c28;
border-radius: 4px;
box-shadow: 0px 0px 24px #00000034;
}
`;
I'm created custom Tooltip in the following way
import React from 'react'
import Tooltip from '#material-ui/core/Tooltip'
import ErrorOutlineOutlinedIcon from '#material-ui/icons/ErrorOutlineOutlined'
import {
makeStyles,
createStyles,
withStyles,
} from '#material-ui/core/styles'
import Typography from '#material-ui/core/Typography'
import { Divider, Link, Paper } from '#material-ui/core'
const HtmlTooltip = withStyles(theme => ({
arrow: {
'&::before': {
color: 'white'
}
},
tooltip: {
backgroundColor: '#f5f5f9',
boxShadow: theme.shadows[8],
color: 'rgba(0, 0, 0, 0.87)',
fontSize: 14,
maxWidth: 800,
padding: 0,
},
tooltipPlacementTop: {
margin: '4px 0',
},
}))(Tooltip)
const imageStyles = { root: { color: 'deeppink', height: 20, marginBottom: 0, width: 20 } }
const Image = withStyles(imageStyles)(({ classes }) => (
<ErrorOutlineOutlinedIcon classes={classes} />
))
const useStyles = makeStyles(theme =>
createStyles({
content: {
border: `1px solid ${theme.palette.grey[300]}`,
margin: 0,
minWidth: 600,
padding: 0,
zIndex: 1,
},
contentInner: {
padding: theme.spacing(1)
},
header: {
backgroundColor: 'deeppink',
fontWeight: 'bold',
padding: theme.spacing(1),
}
})
)
export default function CustomTooltip(params) {
const classes = useStyles()
const labelDisplay = params.content
const textDispaly = params.text
return (
<>
{labelDisplay && labelDisplay.length > 20 ? (<HtmlTooltip arrow interactive title={
<Paper className={classes.content}>
<div className={classes.header}>
<Typography color='inherit' variant='body1' style={{color: 'white', fontSize: '20px'}}>
{params.title}
</Typography>
</div>
<Divider />
<div className={classes.contentInner}>
{textDispaly}
</div>
</Paper>}
placement='top'
>
<div style={{ alignItems: 'center', display: 'flex', fontSize: '12px', justifyContent: 'space-between' }}>
{labelDisplay}<Image/>
</div>
</HtmlTooltip>) : (labelDisplay)}
</>
)
}

Resources