I am trying to create a Dropdown which will have Menu items which would be, on hovered, deletable. I would like to insert an Icon as a children of my Menu Items, but when trying to render it with Storybook, I am getting an error : "Couldn't find story matching 'components-forms-buttons-newdropdown--new-dropdown'."
If I simply comment the Icon component, it's working fine.
Example :
<Box sx={sx} style={{ display: 'inline-block', position: 'relative' }}>
<Box
sx={{
cursor: disabled ? 'not-allowed' : undefined,
display: 'inline-block',
borderRadius: '15px',
}}
>
<StyledMuiButton
variant="outlined"
isdisabled={isdisabled}
onClick={handleClick}
endIcon={<KeyboardArrowDownIcon />}
>
<Typography variant="body1">
{defaultValue ? `${label} :` : label}
</Typography>
<Typography variant="h4">{activeOption}</Typography>
</StyledMuiButton>
</Box>
<StyledMenuContainer
isClicked={isClicked ? 1 : 0}
maxHeight={maxHeight}
>
{options?.map(option => {
return (
<StyledMenuItem
key={option.label}
value={option.value}
divider={option.divider}
disabled={option.disabled}
className={option.className}
onClick={() => handleOptionClick(option)}
>
<ListItemIcon>
{/* When uncommenting this, storybook trhows an error */}
{/* <Delete /> */}
</ListItemIcon>
<ListItemText
sx={{ color: 'grey.160' }}
primary={option.label}
/>
</StyledMenuItem>
);
})}
</StyledMenuContainer>
</Box>
I imported the Icon from MUI.
I do not get why it's not working, as I took inspiration from the documentation.
I upgraded my dependencies so it should not be related to MUI version.
storybook render
Related
In my react app, I would like to control open/close of a material ui v5 Datepicker by clicking an icon button:
function handleShowCalendar() {
setState({ showCalendar: true })
}
<TextField
{...params}
autoFocus={props.autoFocus}
fullWidth
placeholder="Enter a task..."
variant="outlined"
size="small"
InputProps={{
...params.InputProps,
onKeyUp: handleKeyUp,
endAdornment: addTodo.isLoading ? (
<Box position="absolute" top={10} right={10}>
<CircularProgress size={16} />
</Box>
) : (
<Box position="absolute" top={-4} right={0}>
<IconButton
onClick={handleShowCalendar}
disabled={state.text.length <= 0}
>
<CalendarToday />
</IconButton>
</Box>
),
}}
/>
...
<DatePicker
open={state.showCalendar}
value={state.due}
onChange={handleChangeDate}
onClose={() => setState({ showCalendar: false })}
disableHighlightToday
// DialogProps={{ sx: { postition: "inline" } }}
renderInput={(params) => <Fragment {...params} />}
showToolbar={true}
ToolbarComponent={() => (
<AppBar position="static">
<Toolbar>
<Typography variant="h6">Due Date</Typography>
</Toolbar>
</AppBar>
)}
/>
</Fragment>
The problem is the position of the Datepicker is always at the top left corner. Can anyone help why the Datepicker won't show like inline, what I am missing in above code? Thanks.
As an answer to the question in the title, it seems that the code you have posted does open and close the DatePicker.
It sounds like the second question is the one that needs answering, whether it will show "inline".
It seems that the "absolute" position of the Box surrounding the IconButton and the hardcoded top and right values are preventing the borders of the DatePicker from being inside of the TextField.
Here's a Code Sandbox illustrating a DatePicker within a TextField.
If you would like to clarify the positioning you prefer, please do so.
For the code below
import {
TextField,
Stack,
Button,
Box,
Grid,
SvgIcon,
Typography,
Divider,
Link
} from "#mui/material";
// import IconGoogle from "../client/images/google.svg";
export default function Home() {
return (
<Grid container justifyContent="center" padding={20}>
<Grid item>
<Stack spacing={2} width={320}>
<Typography component="label" variant="h5" alignSelf="center">
Sign In
</Typography>
<Button variant="outlined" fullwidth>
{/* <IconGoogle /> */}
Sign in to Google
</Button>
<Divider> OR </Divider>
<TextField variant="outlined" label="Email" fullwidth />
<Stack>
<TextField variant="outlined" label="Password" fullwidth />
<Typography
component="label"
variant="subtitle1"
sx={{ color: "gray", fontSize: 12 }}
>
Minimum 6 Character
</Typography>
</Stack>
<Button variant="contained">Sign In</Button>
<Link component="button" underline="none" sx={{ mt: 100 }}>
Forgot Password
</Link>
</Stack>
</Grid>
</Grid>
);
}
It gives the following screen
which I expect the red rectangle portion to be much larger, since I set sx={{ mt: 100 }}. Why it's not larger and how to rectify it?
If you use padding instead of margin, it does move the button down.
<Link component="button" underline="none" sx={{ pt: 100}}>
Forgot Password
</Link>
The size of the main area of the DataGrid changes with the window size but seems to ignore the size required for the page footer (so a scroll bar remains).
export default class DebugDisplay extends Component {
render = () => {
return <Box >
<DataAdapter localDbConnect="items" setAccessor={this.setAccessor}/>
<AppBar position="static">
<Toolbar>
<IconButton color="inherit" aria-label="Menu" onClick={this.toggleMenu}>
<MenuIcon />
</IconButton>
<Typography variant="h6" sx={{flexGrow:1, flexDirection: "row"}}>
POS Web Debug {this.state.timestamp}
</Typography>
</Toolbar>
</AppBar>
<Drawer type="temporary" open={this.state.debugMenuOpen} onClose={this.toggleMenu}>
<Box sx={{display: "flex", flexDirection: "column", flexGrow: 1}}>
<Button onClick={this.toggleMenu}>Close</Button>
<Divider />
<Button onClick={this.testEnter}>Test Enter</Button>
<Button onClick={this.testTotal}>Test Total</Button>
<Button onClick={this.testInvoice}>Test Invoice</Button>
</Box>
</Drawer>
<Paper >
<Button onClick={this.testEnter} variant="outlined">Test Enter</Button>
<Button onClick={this.testTotal} variant="outlined">Test Total</Button>
<Button onClick={this.testInvoice} variant="outlined">Test Invoice</Button>
<DataGrid sx={{display: "flex", flexGrow:1, flexDirection: "column"}} rows={this.state.rows} columns={itemColumns} autoPageSize pagination density="compact" onCellClick={this.onCellClick}/>;
</Paper>
</Box>;
}
What is wrong?
I am creating a navigation menu and part of it is having a Login link and "Try for Free" button on the right part of the webpage. But what is puzzling me is how to get the button aligned to the right of the Login link. Currently it looks like this:
What am I doing wrong?
<Grid item xs={4}>
{/* <Toolbar disableGutters> */}
<Tabs className={classes.tabContainer}>
<Tab className={classes.tab} component={Link} to="/analyze" label="Login" />
</Tabs>
{/* <Typography className={classes.root}>
<Link href="#" onClick={menuOptions}>
Link
</Link>
</Typography> */}
<Button
variant="contained"
color="default"
size="medium"
// style={{ marginTop: '1.1em' }}
// style={{ maxWidth: '108px', minWidth: '108px' }}
onClick={() => {
// handleClickImportPGN();
}}
>
Try for Free
</Button>
{/* </Toolbar> */}
</Grid>;
One of the handiest ways is to use CSS Flexbox
<Grid item style={{ display: "flex" }}>
<Tabs>
<Tab component={Link} label="Login" />
</Tabs>
<Button
variant="contained"
color="default"
size="medium"
// style={{ marginTop: '1.1em' }}
// style={{ maxWidth: '108px', minWidth: '108px' }}
onClick={() => {
// handleClickImportPGN();
}}
>
Try for Free
</Button>
{/* </Toolbar> */}
</Grid>;
But if you want to make use more of Material UI, you could try to have a few more Grid within each of the children elements.
Simplified Working Example:
Using Intersection Observer API I'm trying to render a Material-UI Component by visibility on the viewport.
export default function Index() {
const [onScreen, theRef] = useOnScreen({
rootMargin: "-300px",
ssr: true
});
const classes = useStyles();
return (
<Container maxWidth="sm">
<DummyContainer />
<div
ref={theRef}
style={{
height: "100vh",
padding: "20px",
backgroundColor: "green",
transition: "all .5s ease-in"
}}
>
{onScreen && (
<Box className={classes.rootBox} my={16}>
<Typography variant="h2" gutterBottom>
Content Lazy using Intersection Observer
</Typography>
<Copyright />
</Box>
)}
</div>
<Box className={classes.rootBox} my={4}>
<Typography variant="h2" gutterBottom>
Content no lazy, why this Box loses margin?
</Typography>
<Typography gutterBottom>
If you request this page with JavaScript disabled, you will notice
that has been properly rendered in SSR
</Typography>
</Box>
</Container>
);
}
Basic stuff, onScreen is a toggled boolean using Intersection Observer
In order to be "SEO friendly" I'm using NextJS and I wanted this component to always be visible in SSR and conditional visible in CSR.
The problem arises during rehydration in CSR, it's seems that some classnames after the lazy component are recreated and I'm losing styling in second Box component.
I've created this CodeSandbox to have a look : https://codesandbox.io/s/nextjsmaterialuiclassnamemismatch-1j4oi
Is this a bug in MaterialUI, JSS? Or most probably I'm doing something wrong?