Material UI linked buttons with MUI's styled component api - reactjs

I like the look of the Material UI Styled Component api (not the styled-component library), but I'm having trouble turning my simple button component into a linked button.
How do I insert a react-router-dom link into a MUI Styled Component button?
Previously, the typical Material UI HOC api approach let me add a linked "reports" button as follows. It works great, but requires a lot more boilerplate (not shown here):
<Button
variant="contained"
color="primary"
className={classes.button}
component={Link}
to="/reports"
>
<ShowChartIcon className={classes.buttonIcon} />
Reports
</Button>
#1 Obvious Approach: When I follow this pattern and include the component and to properties my own MUI Styled Component called <MyButton>, I get a typescript error saying those properties don't exist.
#2 Different Approach: Following the pattern proposed in this material ui github issue, the button does indeed link to the reports screen, but the mui variant and color are lost:
<MyButton
variant="contained"
color="primary"
{...{
component: Link,
to: `/reports`
} as any}
>
<MyShowChartIcon />
Reports
</MyButton>
#3 Workaround Approach: A less desirable option is to wrap the button in a <Link>. That does create a working link, but it also brings in a little bit of unintended styling.
<Link to="/reports">
<MyButton
variant="contained"
color="primary"
>
<MyShowChartIcon />
Reports
</MyButton>
</Link>

Using the latest version of material-ui (v4.0.2) you can use the HOC component created with withStyles, but you will have to manually cast the custom component back to its original type:
const MyButton = withStyles(
createStyles({
root: {
color: 'red'
}
})
)(Button) as typeof Button
then you can use your custom component like you would the original one:
<MyButton component={Link} to="/blank-page">
my button
</MyButton>
Here is a working example: https://codesandbox.io/s/createreactappwithtypescript-n6wih
I found this solution from this comment: https://github.com/mui-org/material-ui/issues/15695#issuecomment-498242520.

Related

MUI Badge is not showing in the DOM, in inspector the span is in tact

I've created a React RTK application with mainly MUI Components.
Suddenly (and I can' reconstruct where when or why) the Mui <Badge> is not showing in my app, although it is in plain sight in the DevTools, elements.
The code that leads to this example page is:
import { Badge, Button } from "#mui/material";
import React from "react";
export default () => (
<div>
<Badge variant="dot" badgevalue={10}>
<Button variant="outlined">test</Button>
</Badge>
</div>
);
I've tried a lot, but with no succes. Can anyone help me out what the problem is here?
you have not added color props to badge. thats why its not displaying. also I checked the badge API. there is no badgeValue props. but there is badgeContent props. https://mui.com/api/badge/
<div>
<Badge variant="dot" badgevalue={10} color="primary">
<Button variant="outlined">test</Button>
</Badge>
<Badge variant="dot" badgeContent={10} color="primary">
<Button variant="outlined">test</Button>
</Badge>
</div>

Material UI button missing styles after being linked

I'm using a standard Material UI button that looks fine if I refresh the page that I am on. However, if I get to the page through a link from another page (I'm using react-router-dom) then the styling from the button is missing.
import {Link} from "react-router-dom";
<Link
color="inherit"
style={{textDecoration: 'none'}}
to={link}>
<Button variant="contained" color="primary">
test
</Button>
</Link>

React / Material UI complex styling

I have an issue related with styling in React / Material UI. I think is an issue related with TouchRipple from Material-UI
<div key={indexP}>
<Link className={classes.link} to={parent.link}>
<ListItem button selected={this.state.treeParentOpen[indexP] === true} onClick={this.handleClick(indexP)}>
<ListItemIcon>
<ParentIcon />
</ListItemIcon>
<ListItemText primary={parent.title} />
</ListItem>
</Link>
<Divider />
</div>
I have the above code inside a Drawer component (this is a small extract just to exemplify), for a Sidebar menu.
The issue i am having is related with the styling interaction of the ListItem and Link Components.
If i take the Link out of the code i have a normal ListItemripple behaviour (onclick and offclick), everything is pretty and in grey shades.
When i had the Link to the code (as is), the ripple behaviour of the ListItem changes and onClick is Blue and offClick purple. How should i address the styling of the ripple effect associated with buttonBase used in ListItem.
Thanks!

in Material UI Icon doesn't work as expected

I am using Material UI. In the doc it shows that I can use:
import Icon from "#material-ui/core/Icon";
...
<Button variant="contained" color="primary" className={classes.button}>
blabla
<Icon className={classes.rightIcon}>send</Icon>
</Button>
but what it shows is a button with a text "BLABLA SE" which is wrong.
But when I use:
import SendIcon from "#material-ui/icons/Send";
....
<Button variant="contained" color="primary" className={classes.button}>
Blabla
<SendIcon className={classes.rightIcon} />
</Button>
It works just fine, with a text BLABLA and a send icon on the left side of it.
In the sandBox provided in the doc both work. So why the first case doesn't
work for me?
I think there is an error in this documentation example : https://material-ui.com/demos/buttons/#buttons-with-icons-and-label
import Icon from '#material-ui/core/Icon';
shoud be
import SendIcon from '#material-ui/icons/Send';
Here is a working version with this replacement : https://codesandbox.io/s/k3rjyoq32v
The module imported with this path #material-ui/core/Icon is not an svg icon itself, it is the Icon component documented here : https://material-ui.com/api/icon/
There are basically three ways of working with Icons in material-ui :
#material-ui/core/Icon : Component useful for displaying font icons. See https://material-ui.com/style/icons/#font-icons
#material-ui/icons : package with a set of Material Icons converted to SVG icons usable as React components. See https://material-ui.com/style/icons/#svg-material-icons
#material-ui/core/SvgIcon : Component to use any SVG as an icon. See https://material-ui.com/style/icons/#svg-icons
I think you've solved your own problem since I've seen you have got the icon to show in your codesandbox.
Had the same problem and found out that I didn't import the material icons font family in the index.html.
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
Only with the above import will the component work.

Open DatePicker or DatePickerDialog using custom button

Is there any way to trigger the DatePickerDialog to open using an external control / button other than the built in input that comes out of the box with the DatePicker?
We are using the material-ui library.
Since the dialog open state is handled internally by material-ui components, the only way to do it would be using ref in the DatePicker and calling focus(). Kind of a hack - but it works..
Example:
<DatePicker
ref='datePickerStartDate'
errorStyle={componentSyles.error}
textFieldStyle={componentSyles.textField}
DateTimeFormat={Intl.DateTimeFormat}
cancelLabel={cancelLabel}
autoOk={true}
{...this.props}
/>
<FontIcon
onClick={(e) => { this.refs.datePickerStartDate.focus() }}
className="material-icons" style={componentSyles.icon}>
date_range
</FontIcon>

Resources