React Menu is closing on element click - reactjs

I have a menu which applies filter to my list and when I click on an element inside the menu is closing and I can not set more filters. I should click the stepper or the selection box many times and the menu should close on click on submit or cancel and not on click of stepper or selection box
`
<Menu matchWidth={true} isOpen={isOpen} onOpen={handleOpen} onClose={handleCancel} closeOnBlur={false} closeOnSelect={false} >
<ChakraSelectButton headline={'Who?'} information={information} />
<MenuList p={4} onClick={e => e.stopPropagation()} >
<VStack
alignItems={'flex-start'}
// #ts-ignore
ref={ref}
<Stepper
title={'How many people?'}
handleChange={handleChange}
name={people}
value={numberOfPeople ? numberOfPeople : 0}
boxSize={10}
/>
{numberOfPeople > 0 && (
<VStack w={'100%'} onClick={e => e.preventDefault()}>
<Text
alignSelf={'flex-start'}
Please insert the age!
</Text>
{Array.from(Array(numberOfPeople)).map((a, idx) => {
return (
<Select
key={idx}
userSelect={'none'}>
<option value={24}>24</option>
<option value={25}>25</option>
<option value={26}>26</option>
<option value={27}>27</option>
</Select>
);
})}
</VStack>
)}
<Stepper
title={'Pets'}
handleChange={handleChange}
value={numberOfPets ? numberOfPets : 0}
boxSize={10}
/>
<Divider />
<CtaFilterButtons
size={'sm'}
handleCancel={handleCancel}
handleFilterChange={handleSubmit}
/>
</VStack>
</MenuList>
</Menu>
`
I only want to close the menu when I click on submit.

Related

stopPropogation not working consistently in React

I am working with 2 dropdown menus using stopPropogation to prevent the menu shifting up and down when items are checked and unchecked.
One menu works great but the other is still jumping up and down when checking and unchecking items, although I am confident that I'm using stopPropogation in the same way for both instances. I am wondering what I am doing wrong in the faulty dropdown menu that's causing this issue.
Working dropdown menu:
return (
<div onClick={(e) => {
e.stopPropagation();
}}>
<FormControl
variant="outlined"
size="small"
className={classes.formControl}
>
<InputLabel id="demo-mutiple-checkbox-label" align="left" margin="dense">
Select Models
</InputLabel>
<Select
multiple
labelId="demo-mutiple-checkbox-label"
label="SelectModels"
value={modelIds}
onChange={handleChange}
renderValue={(selected) =>
selected
.map(
(id) =>
deviceModelData.find((model) => model.alg_id === id).alg_name
)
.join(', ')
}
MenuProps={MenuProps}
className={classes.rootSelect}
>
{deviceModelData.map((model, index) => (
<MenuItem key={model.alg_id} value={model.alg_id}>
<Checkbox checked={modelIds.includes(model.alg_id)} />
<ListItemText primary={model.alg_name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
Problematic dropdown menu:
return (
<div
onClick={(e) => {
e.stopPropagation();
}}
>
<FormControl
variant="outlined"
size="small"
className={classes.formControl}
>
<InputLabel id="demo-mutiple-checkbox-label">Select Classes</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
label={label}
id="demo-mutiple-checkbox"
multiple
value={classIds}
onChange={handleClassIdsChange}
renderValue={(selected) =>
selected
.map((id) => marketplaceModelClasses[id].original_label)
.join(', ')
}
MenuProps={MenuProps}
>
{allClassIds.map((classId) => {
return (
<MenuItem key={classId} value={classId}>
<Checkbox
value={classId}
checked={classIds.indexOf(classId) > -1}
/>
<ListItemText
primary={marketplaceModelClasses[classId].original_label}
/>
</MenuItem>
);
})}
</Select>
</FormControl>
</div>
);
}

Open Select list from overriden input - material ui

<Select
value={text}
onChange={handleChange}
label={formatMessage(messages.dateFilter)}
input={
<Box display="flex" className={classes.input}>
<Calendar />
<Typography variant="caption">{text}</Typography>
</Box>
}
>
{items.map(entity => {
return (
<MenuItem value={entity.text}>
<Box display="flex" justifyContent="space-between">
<Typography variant="caption">{entity.text}</Typography>
{text === entity.text && <CheckMark />}
</Box>
</MenuItem>
)
})}
</Select>
As you can see I try to override input property in Select list , but now when I click on this field it doesn't open select list popup. I've also tried to use open property (set it to true), but it also doesn't work. How can I solve it ?
"#material-ui/core": "4.5.2",

Material UI select and autocomplete box not lined up

Screenshot of misaligned drop-down boxes
Hi! I'm a beginner ReactJS engineer. I added 2 drop-down boxes from material UI, the left box is the Autocomplete from materialui/labs and the right box is the Select from materialui/core. They're both placed in the same component with the same styling applied to it, but the Autocomplete is slightly off. Is there a simple fix to this misalignment?
<AutocompleteComponent
formStyle={{ width: 200 }}
label={'Build'}
options={builds}
value={selectedBuild}
handleChange={handleFilterSelectChange('selectedBuild')} />
<SelectComponent
formStyle={{ width: 120 }}
label={'Sheet Layout'}
options={sheetLayouts}
value={selectedSheetLayout}
handleChange={handleFilterSelectChange('selectedSheetLayout')} />
For select component:
const SelectComponent = props => {
return (
<FormControl
className={className}
required={required}
error={error}
margin={margin}
style={formStyle}
>
<InputLabel>{label}</InputLabel>
<Select
inputRef={inputRef}
value={value}
style={style}
onChange={handleChange}
disabled={disabled}
onClick={onClick}
onFocus={onFocus}
onBlur={onBlur}
>
{excludeNone ? null : (
<MenuItem value="">
<em>{noneLabel ? noneLabel : "None"}</em>
</MenuItem>
)}
{optionsExist(options)}
</Select>
{helperText ? <FormHelperText>{helperText}</FormHelperText> : null}
</FormControl>
);
};
For the autocomplete component:
class AutocompleteComponent extends React.Component {
render() {
return (
<FormControl
className={className}
required={required}
error={error}
margin={margin}
style={formStyle}
>
<Autocomplete
style={style}
disabled={disabled}
onClick={onClick}
onFocus={onFocus}
onBlur={onBlur}
options={options}
getOptionLabel= {option => option.label && option.label.toString()}
id="auto-complete"
autoComplete
includeInputInList
renderInput={params => (
<TextField
{...params}
label="Builds"
margin="normal"
fullWidth
position="center"
/>
)}
renderOption={(option, { inputValue }) => {
const matches = match(option.label, inputValue);
const parts = parse(option.label, matches);
return (
<div>
{parts.map((part, index) => (
<span
key={index}
style={{ fontWeight: part.highlight ? 700 : 400 }}
>
{part.text}
</span>
))}
</div>
);
}}
/>
{helperText ? <FormHelperText>{helperText}</FormHelperText> : null}
</FormControl>
);
}
}
Thanks!

How to fix shadow for menu material-ui

When I use a few icon menus than box-shadow looks very dark. How to fix that?
1:
Codesandbox example https://codesandbox.io/embed/flamboyant-tdd-r83u1
<div>
{items.map((item, index) => {
return (
<Fragment key={index}>
<IconButton
aria-owns={open ? "long-menu" : undefined}
onClick={this.handleClick}
>
<MoreVertIcon />
</IconButton>
<Menu anchorEl={anchorEl} open={open} onClose={this.handleClose}>
{options.map(option => (
<MenuItem key={option} onClick={this.handleClose}>
{option}
</MenuItem>
))}
</Menu>
</Fragment>
);
})}
</div>
Because, actually you are triggering multiple menus with the same flag at the same time. So shadow is dark because there are multiple menus one after the other.
Below code should fix this, You don't have to render Menu in items loop
render() {
const items = [...Array(10).keys()];
const { anchorEl } = this.state;
const open = Boolean(anchorEl);
return (
<div>
{items.map((item, index) => {
return (
<Fragment key={index}>
<IconButton
aria-owns={open ? "long-menu" : undefined}
onClick={this.handleClick}
>
<MoreVertIcon />
</IconButton>
</Fragment>
);
})}
<Menu anchorEl={anchorEl} open={open} onClose={this.handleClose}>
{options.map(option => (
<MenuItem key={option} onClick={this.handleClose}>
{option}
</MenuItem>
))}
</Menu>
</div>
);
}

How to show an inputlabel/placeholder/label permanently?

I'm using the multi-select with checkboxes from material ui v4. The provided default settings display an array of 'SELECTED' values. renderValue={selected => selected.join(', ')}. However, I would like to remove this function and only display a permanent label. It seems that the display value is being tied to the value of the component itself. Does anybody knows how to work around this?
<FormControl className={classes.formControl}>
<InputLabel htmlFor="select-multiple-checkbox">Tag</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-checkbox" />}
renderValue={selected => selected.join(', ')}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
Are you saying that you don't want any indication of what the selected values are?
If so, below is one way of doing that:
<FormControl className={classes.formControl}>
<InputLabel shrink={false} htmlFor="select-multiple-checkbox">
Tag
</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-checkbox" />}
renderValue={() => (
<span dangerouslySetInnerHTML={{ __html: "​" }} />
)}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<InputLabel shrink={false}
This prevents the label from shrinking and moving up when the Select is focused.
renderValue={() => (<span dangerouslySetInnerHTML={{ __html: "​" }} />)}
This causes a zero-width space to be rendered as the "selected values". This ensures that the height doesn't collapse (which is what happens if you just return empty string) while still allowing the label to be displayed.

Resources