I am using react-toolbox menu for my website. Based on the example given in the documentation React-toolbox menu, I can only use icon as my menu. How can I use text for the menu instead?
Example of what I want to do:
When I click the blog text which is a menu, the menuItem will be shown.
Is it possible to do this?
just remove icon property from MenuItem component
<IconMenu icon={<div>blog</div>} position='topLeft' menuRipple>
<MenuItem value='download' caption='Download' />
<MenuItem value='help' caption='Favorite' />
<MenuItem value='settings' caption='Open in app' />
<MenuDivider />
<MenuItem value='signout' icon='delete' caption='Delete' disabled />
</IconMenu>
You can pass an element to the icon property like that:
<IconMenu icon={<div>Menu</div>} position='topLeft' menuRipple>
In case someone else has the problem, the solution is to use Menu component instead of IconMenu. Like this :
const [menuActive, setMenuActive] = useState(false);
return (
<div style={{ position: 'relative' }}>
<Button label='Actions' onClick={() => setMenuActive(!menuActive)} />
<Menu position='topRight' active={menuActive} onHide={() => setMenuActive(false)}>
<MenuItem value='download' caption='Download' />
<MenuItem value='action' caption='Action' />
</Menu>
</div>
);
Related
As per the demo, the label for a MUI outlined select input should sit on top of the top border of the select box.
However, in my application, the z-index of the label seems to be placing it behind the top border and thus it looks like a line is cutting through the label.
I have pretty much taken the code exactly from the documentation, and as far as I know, do not have any styles conflicting with this input element. I have compared the styles in the debugger to what I have and what is present in the documentation, and I do not see any of my first party CSS files causing a different style to be set on the element.
Any idea what might be going wrong here?
Here is the source code:
<FormControl variant='outlined' style={{ width: '100%' }} margin={'1'}>
<InputLabel id='test-select-label'>Label</InputLabel>
<Select
labelId='test-select-label'
id='test-select'
value={'test1'}
onChange={e => setTest(e.target.value)}
size='small'
>
<MenuItem key={1} value={'test'} >Test 1</MenuItem>
<MenuItem key={2} value={'test2'} >Test 2</MenuItem>
</Select>
</FormControl>
Solution 1: Use TextField
This is what TextField is for. It uses FormControl and InputLabel internally and make sure they work well together. You can tell TextField to render select instead input by overriding the select props:
<TextField
value={value}
onChange={(e) => setValue(e.target.value)}
select // tell TextField to render select
label="Label"
>
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</TextField>
For more detail about how TextField works, see this answer.
Solution 2: Use Select
If you decide to use Select, you need to write more code to do the same amount of work:
Pass the label text as InputLabel children
<InputLabel id="test-select-label">Label</InputLabel>
This label text will be rendered on the screen as the Select label when put inside FormControl and next to the Select component.
Pass the label text to the label props of the Select component
This label text is hidden and used to override and remove the part of the border-top where the real label is occupied when the Select label is shrinked.
<Select labelId="test-select-label" label="Label">
Putting it together we'll have something like below, note that with this approach we need to set the label in 2 different places which is not very DRY, so I'd prefer the first approach.
<FormControl>
<InputLabel id="test-select-label">Label</InputLabel>
<Select
value={value}
onChange={(e) => setValue(e.target.value)}
labelId="test-select-label"
label="Label"
>
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</Select>
</FormControl>
Live Demo
If you add the label property to your select component your problem should disappear.
...
<Select
value={value}
onChange={(e) => setValue(e.target.value)}
label="Label" // add this
>
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</Select>
...
Here is a live demo where you can see the difference:
Try this method, it worked for me.
JSX:
<TextField select variant={"outlined"} style={{width: "100%"}} label="Label">
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</TextField>
CSS:
.MuiSelect-outlined.MuiSelect-outlined, .MuiSelect-outlined.MuiSelect-outlined:active, .MuiSelect-outlined.MuiSelect-outlined:focus {
background-color: transparent;
text-align: left;
font-family: sans-serif !important;
font-size: 14px !important;
font-weight: 400 !important;
}
I had a similar issue when I tried to set padding on the FormControl component. I had the proper id and label, but it was still an issue. CSS is not my strong suit, but I noticed that if I could replicate the layout I wanted using margin on the FormControl component, the label aligned appropriately. See image with padding instead of margin:
I have created a React component using Material UI as below
<Popper
open={open}
anchorEl={anchorRef.current}
onBlur={handleToggle}
transition
disablePortal
>
<MenuList autoFocusItem={open}>
<MenuItem>Tom</MenuItem>
<MenuItem>Patt</MenuItem>
</MenuList>
<input type="text" name="Student" onChange={getStudent}></input>
</Popper>
In the above component i have MenuList and TextField. I tried to add onBlur={handleToggle} thinking that, it will close the component if clicked outside of it but its closing even when i am trying to add text in TextField using onChange={getStudent}, Why is it happening and how to close Component only if clicked outside of it? Thanks.
You can use ClickAwayListener component to detect whether the user is clicking outside of the Popover area.
<ClickAwayListener onClickAway={() => setOpen(false)}>
<span>
<Popper
open={open}
anchorEl={ref.current}
transition
disablePortal
>
<MenuList autoFocusItem={open}>
<MenuItem>Tom</MenuItem>
<MenuItem>Patt</MenuItem>
</MenuList>
<input
type="text"
name="Student"
/>
</Popper>
<Button variant="outlined" onClick={() => setOpen((o) => !o)} ref={ref}>
Nothing
</Button>
</span>
</ClickAwayListener>
Live Demo
i know that disabled item doesn't trigger any event and the possible workaround is to wrap my elements in another which i tried but it didn't work. I can't think of another solution to hover over a disabled tooltip. Here's the sandbox i have
import React from "react";
import "./styles.css";
import MenuItem from "#material-ui/core/MenuItem";
import Tooltip from "#material-ui/core/Tooltip";
export default function App() {
const content = (
<Tooltip title="hover over">
<p>Hey</p>
</Tooltip>
);
return (
<MenuItem disabled component="div">
{content}
</MenuItem>
);
}
https://codesandbox.io/s/beautiful-wing-mgowh?fontsize=14&hidenavigation=1&theme=dark
In order to get the tooltip to show you need to wrap the disabled MenuItem with a <div> and then wrap it with the Tooltip:
export default function App() {
const content = (
<span title="lol">
<p title="lol">Hey</p>
</span>
);
return (
<Tooltip
title="hover over"
>
<div style={{ display: "inline-block" }}>
<MenuItem disabled component="div">
{content}
</MenuItem>
</div>
</Tooltip>
);
}
Checkout this sandbox in which I also used PopperProps on the Tooltip in order to get it to show next to the MenuItem. You can play around with the marginTop and marginLeft values in order to adjust it to your use-case.
I am trying to place two icons one is related to wordDocument and other is related to download icon on and button but one icon is overriding another icon, this is the code:
import { FileWordOutlined, DownloadOutlined } from '#ant-design/icons';
return (
<Fragment>
<Button
type="primary"
style={{ width: '30%' }}
onClick={() => {
authProvider.getIdToken().then(token => {
downloadFile(
`${process.env.REACT_APP_API_URL}/api/Projects/${projectNumber}`,
token.idToken.rawIdToken
);
});
}}
icon={((<FileWordOutlined />), (<DownloadOutlined />))}
size="small"
>
Basis of Design
</Button>
</Fragment>
);
and the button image is looking like this right now
I am looking to place icon <FileWordOutlined /> on the right side of the text Basis of Design and <DownloadOutlined /> is on the left side of the text.
Could anyone please let me know is there any way to achieve this?
The icon props take only one component. So you won't be able to pass two-component there.
There are two ways to get 2 icons.
Remove the icon prop and use the 2 icon Component,for ex,<FileWordOutlined />, <DownloadOutlined /> as children to the Button prop.
<Button type="primary">
<FileWordOutlined />
Basis of Design
<DownloadOutlined />
</Button>
If you want to use the icon prop you use it like this:
<Button
type="primary"
icon={<FileWordOutlined />}
size="small"
>
Basis of Design
<DownloadOutlined />
</Button>
What you are doing isn't working because you are setting icon to the returned value of ((<FileWordOutlined />), (<DownloadOutlined />)), which is <DownloadOutlined />.
You can omit icon and put the icons and the button text inside Button instead:
<Button
type="primary"
size="small"
>
<DownloadOutlined />
Basis of Design
<FileWordOutlined />
</Button>
demo
If you want to get 2 icons then create icon prop like this:
<Button icon={your primary icon}>
{text}
{extra icon}
</Button>
So the Element would look like
<My Button
icon={<icon name/>}
text={text}
extra icon={<extra icon name/>}
/>
I need to do this transformation because the dropdown from Material UI looks bad.
Beside of that, the code is working fine. It is a dropdown with multiple choices, it loads a list of strings and their corresponding images and when they are filtered by that category/categories are shown in the table.
This is the working code with Material UI:
import {
Select,
MenuItem,
FormControl,
InputLabel,
} from '#material-ui/core';
const platforms = ['a', 'b', 'c', 'd'];
<FormControl className='searchPlatform'>
<InputLabel id='platforLabel'>Platform</InputLabel>
<Select
labelId='platforLabel'
id='platforLabel'
value={this.props.platformFilter}
renderValue={this.getSelectedPlatformFilter}
onChange={this.handleChangePlatform}
multiple
>
{platforms.map((platform) => (
<MenuItem key={platform} value={platform}>
<div>
<img
src={this.showicon(platform)}
alt=''
height={17}
width={17}
/>
{platform}
</div>
</MenuItem>
))}
</Select>
</FormControl>
And the next one is what I've tried with Bootstrap. I don't know how to trigger the dropdown on onChange. I've tried to put onClick on Dropdown.Item in order to call the same trigger as in onChange from Dropdown.Menu
import { Dropdown } from 'react-bootstrap';
<Dropdown>
<Dropdown.Toggle variant='success' id='dropdown-basic'>
Dropdown Button
</Dropdown.Toggle>
<Dropdown.Menu
value={this.props.platformFilter}
renderValue={this.getSelectedPlatformFilter}
onChange={this.handleChangePlatform}
>
{platforms.map((platform) => (
<Dropdown.Item
eventKey={platform}
value={platform}
onClick={this.handleChangePlatform}
>
<div>
<img
src={this.showicon(platform)}
alt=''
height={17}
width={17}
/>
{platform}
</div>
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
Try onSelect prop on <Dropdown> component, as it's a callback fired when a menu item is selected.
(eventKey: any, event: Object) => any
It would be something like:
<Dropdown onSelect={handleChangePlatform}>
<Dropdown.Toggle variant='success' id='dropdown-basic'>
Dropdown Button
</Dropdown.Toggle>
<Dropdown.Menu>
// ... rest of code
</Dropdown.Menu>
</Dropdown>