Material-ui Snackbar pop up out of Screen - reactjs

Hi!
I go on toy project with React, Material-ui.
when snack bar or react-toastify pop up.
It's not harboring in screen. (RED: scroll up/down then snackbar is there)
I changed pop up position top/bottom. but, It can't cover every case.
How can it make pop up in screen. (GREEN is showing in screen)
I want to SnackBar pop up in "BLUE" position and harboring with scroll.
thanks
<Grid item>
<Grid container direction="row" justify="space-evenly">
<Grid item>
<Button variant="outlined" onClick={() => {
toast.success("Update!")
}}>Update!</Button>
</Grid>
</Grid>
</Grid>
<ToastContainer position="top-center" autoClose={2500} />

I solved it..
I move <ToastContainer/> to top component from sub-component
(from 'Content' to 'Header')
export const App = observer(() => {
const classes = kpopStyle();
return (
<React.Fragment>
<BrowserRouter>
<Header /> // <-- to Here
{storeUiHandler.checkMobile() ?
<div className={classes.contentLayoutMobile}>
<Content /> // <-- from Here
<Footer />
</div> :
<div className={classes.contentLayoutPC}>
<Content />
<Footer />
</div>}
</BrowserRouter>
</React.Fragment>
);
});
now, It works as I expected.

Related

Pass icon button as props using react

I have a common grid component where I define the structure of the grid and also structure of a button bar that goes on top of the grid.
Common-grid.js
<Box height='100%' width='100%' position='absolute'>
<div className="common-grid">
<div className="button-bar">
</div>
<div className="ag-grid">
</div>
</div>
</Box>
I pass data to the grid from my other component based to fill in the grid.
MyComponent.js
{gridData.length > 0 && <Grid tableData={gridData} columnData={activeListColumnDef} {...props}/>}
Along with the data, I would also like to pass icon buttons that I would like to see in button bar.
<IconButton
icon={<AddIcon />}
onClick={onClickOpenActiveListEditor}
/>
<IconButton
icon={<EditIcon />}
/>
I do not want to define icon buttons in the common component but pass it as props. Is it possible to pass such html elements along with its event listeners as props? Please help!
Sure, it's called a render prop. Just directly pass the node like this:
// in the parent component
<Grid
tableData={gridData}
columnData={activeListColumnDef}
icon={<AddIcon onClick={onClickOpenActiveListEditor} />}
{...props}
/>
// in the Grid component
function Grid({tableData, columnData, icon}){
return (
<>
// grid stuff
{icon && icon}
</>
)
}
If you need typescript support, the node would typed as such:
interface GridProps{
// stuff
icon?: React.ReactNode;
}
You could do something like:
const renderIcon = (onClick) => {
return <Icon onClick={onClick} />
}
...
<IconButton renderIcon={renderIcon} />
Then, inside IconButton:
{renderIcon()}

How to use <br/> in string to put string in new line?

I was creating React project and here is the component that I want to ensure that is put inside a string.
<InfoIcon
tooltip={`${hints.todoHint} <br/> ${hints.inProgressHint} <br/> ${hints.doneHint}`}
/>
but it is not working since br/ is literally rendered like br/
One option is to convert tooltip in to three props and add <br /> in the InfoIcon component. For example InfoIcon component can be
const InfoIcon = ({ todoHint, inProgressHint, doneHint }) => (
<div>
{todoHint}
<br />
{inProgressHint}
<br />
{doneHint}
</div>
);
// Using Info Icon
<InfoIcon todoHint={todoHint} inProgressHint={inProgressHint} doneHint={doneHint} />
Other option is to send tooltip as follows
const tooltip = (
<div>
{hints.todoHint}
<br />
{hints.inProgressHint}
<br />
{hints.doneHint}
</div>
)
<InfoIcon tooltip={tooltip} />
Well, material-ui tooltip allows you to use ANY kind of HTML content. => refer to official document customized tooltiops
This means you can use normal <div> and <Typography />, and any other styled elements to handle multi-line content.
The only thing you need to do is pass the content to props title => refer to document of tooltip api
import {
Tooltip,
Typography
} from '#material-ui/core';
<Tooltip
title={ // customized content here via props `title`
<>
<div>Seperate line</div>
<Typography>Seperate line</Typography>
</>
}
>
<IconButton aria-label="delete">
<InfoIcon /> // You can use your original icon here
</IconButton>
</Tooltip>
Watch it online: https://stackblitz.com/run
You can find related question here: How to make line break for ToolTip titles in Material-UI

React Material UI Button component with hookrouter

I am trying to migrate a class component React app to functional components with hooks.
When using class components I use to pass a Link component to a Button component since I was using react-router-dom library.
But now I am trying to use Paratron/hookrouter library for routing but I get an error when passing an A component to the Button:
TypeError: props.href is undefined
My code now looks like this:
import React, { Fragment } from 'react';
import { Grid, Button } from '#material-ui/core';
import { A } from 'hookrouter';
import './styles.css';
const Home = props => {
return (
<Fragment>
<Grid container spacing={24} className="landing">
<Grid item xs={6}>
<Button
variant="contained"
color="primary"
size="large"
component={A}
to="/login"
>Login</Button>
</Grid>
<Grid item xs={6}>
<Button
variant="contained"
color="secondary"
size="large"
component={A}
to="/contact"
>Contact us</Button>
</Grid>
</Grid>
</Fragment>
);
}
export default Home;
I guess this A component does not contain an href property. Not sure how to proceed. Any comments will be appreciated.
You need to provide 'href' prop, not 'to' prop.
<Fragment>
<Grid container spacing={24} className="landing">
<Grid item xs={6}>
<Button
variant="contained"
color="primary"
size="large"
component={A}
href="/login" //href
>Login</Button>
</Grid>
<Grid item xs={6}>
<Button
variant="contained"
color="secondary"
size="large"
component={A}
href="/contact" //href
>Contact us</Button>
</Grid>
</Grid>
</Fragment>
I also had to wrap A with class component, since A is probably function component, and they can't hold a ref (which is required by button component prop)
You can refer to this working CodeSandbox demo

admin-on-rest toggle menu (show / hide)

I'm using admin-on-rest in my react application as admin interface.
My problem is the menu, I'm add a DashboardMenuItem to toggle (show/hide) the menu. But I have no idea what the onClick function should look like and I find no example of this in the documentary or somewhere else.
Can anyone help me by giving an example for this?
My Code:
const Menu = ({ hasDashboard, onMenuTap, resources, translate, logout }) => (
<div style={styles.main}>
<WithPermission value='ROLE_SA'>
{hasDashboard && <DashboardMenuItem onClick={onMenuTap} />}
</WithPermission>
{resources
.filter(r => r.list)
.map(resource => (
<MenuItemLink
key={resource.name}
to={`/${resource.name}`}
primaryText={translatedResourceName(resource, translate)}
leftIcon={<resource.icon />}
onClick={onMenuTap}
/>
))}
{/* <MenuItemLink primaryText='Reports' key='reports' to={`/reports`} leftIcon={<UserIcon />} onClick={onMenuTap} /> */}
<WithPermission value='ROLE_SA'>
<SelectField floatingLabelText='Language for Datasets' onChange={LocaleSwitcher}>
<MenuItem value={'de'} primaryText='DE' />
<MenuItem value={'en'} primaryText='EN' />
</SelectField>
</WithPermission>
{logout}
<img src={Logo} style={{maxWidth: '100%', margin: '0 auto'}} />
</div>
)

AppBar Material UI questions

I'm pretty new to the Material UI Library but I really like it so far! However, i am having an issue with the AppBar component overlaying over my other content. I currently have <AppBar /> and <myComponent /> in my App.js render method. Here is the code snippet for that:
render(){
return (
<div>
<AppBar />
<myComponent />
</div>
);
}
This is the code for the myComponent function:
function myComponent(){
return (
<h1>
Hello
</h1>
);
}
However, when I run this code, the "Hello" message is overlaid by the AppBar component. Is there some way to have my hello message (and corresponding code) be displayed under the AppBar? It's a simple question but I would love to figure this out!
You need to add the top margin from top to the component which you have created right below the app bar
I am posting this from mobile if you need code just let me know I will right it for you
You can add paddingTop to the containing div to compensate for the height of the AppBar (64px by default):
render() {
return (
<div style={{ paddingTop: 64 }}>
<AppBar>
<Toolbar>
<Typography variant="title" color="inherit">
Title
</Typography>
</Toolbar>
</AppBar>
<YourComponent />
</div>
);
}

Resources