How to align Icon with select control using Material design? - reactjs

I am new to Material design UI components and struggling with real basic alignment question.
I have a select control that uses an Icon for the drop down and then right next to this, another Icon to cancel the action.
Here is all that is in render() part of page:
<div style={{display:'flex', alignContent:'center'}}>
<Select IconComponent={ArrowDropDownCircleOutlined} disableUnderline={true}
renderValue={() => { return ('') }}>
<MenuItem value={'contains'}>Contains</MenuItem>
<MenuItem value={'startswith'}>Starts with</MenuItem>
<MenuItem value={'EqualTo'}>Equal to</MenuItem>
<MenuItem value={'isNull'}>is Null</MenuItem></Select>
<CancelOutlined onClick={() => console.log('hello world')} />
</div>
this is what's displayed:
I have tried various style changes, verticalAlign:'middle", 'top', 'buttom', etc..but nothing aligns them.
If I change the select component to just an Icon, the two icons are aligned correctly however.
What am I missing?

Instead of alignContent: 'center' use alignItems: 'center'.
Here's a demo where it works:

Related

how to add a clear icon in Material-UI pickers inside of input

I use Date picker
inside of picker is an option to set it clearable, but this option is only when the picker is open
maybe is possible to add custom button like this:
Or maybe instead of doing something custom, to use another picker with option of clear inside of input?
You can add InputProps with endAdornment key to your DatePicker component in order to customize the input element and add a custom icon like this:
InputProps={{
endAdornment: (
<div
onClick={handleClear}
style={{ marginRight: 20, cursor: "pointer" }}
>
<ClearIcon />
</div>
)
}}
You can take a look at this sandbox for a live working example.

how to set MenuItem be <a> inside <li>

I'm new to Material-UI.
I want to make some popover and saw Menu and MenuItem in Menu Demo. They are perfect except for one thing. I want the menu item to be link.
By default MenuItem is li, (I think) because Menu is ul. But it is not so hard that make an item link by setting component="a" or component={RouterLink}. But in this case, they lose li.
For Screen Reader like program, I heard that using an appropriate Html tag is important. (It is called Semantic Web. Right?)
In this perspective, I want to menu items to be a inside li.
-- Trial --
<MenuItem>
<a>link text</a>
</MenuItem>
a is inside li. But it looks different from the case below.
<MenuItem component="a" href="/">
link text
</MenuItem>
Then, I try
<MenuItem>
<a style={{all: "inherit"}}>
link text
</a>
</MenuItem>
It looks satisfactory, but the color changes after clicking it, (I think) because a:visited { color: ...; } is not inherited.
Finally I tried
<li>
<MenuItem component="a" href"/">
link text
</MenuItem>
</li>
Yeah. It solves all problems. But, what if I forget to add li?
My menu contains many items. Some of them are link and others are not. Then should I add li directly by distinguishing only the cases of link?
-- Question --
Is my solution is best? How about you? Please share your way.
Semantically, MenuItem is more suitable for li because it represents an item in a list. The component props's default value of MenuItem is 'li' after all. So I'd go for:
<MenuItem>
<a style={{all: "inherit"}}>
link text
</a>
</MenuItem>
But, what if I forget to add li?
That's one reason to use React, you can easily de-duplicate part of your components by creating another component and reuse it:
const useStyles = makeStyles((theme) => ({
root: {
"& a:visited": {
color: theme.palette.primary.main
}
}
}));
function MenuItemLink({ children, href, onClick }) {
const classes = useStyles();
return (
<MenuItem onClick={onClick} className={classes.root}>
<a href={href}>{children}</a>
</MenuItem>
);
}
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItemLink href="/" onClick={handleClose}>
Profile
</MenuItemLink>
<MenuItemLink href="/" onClick={handleClose}>
My account
</MenuItemLink>
<MenuItemLink href="/" onClick={handleClose}>
Logout
</MenuItemLink>
</Menu>
Live Demo

Trying to select menuItems in a seperate component - how to solve 'function components cannot be given refs' error?

I am trying to move my menuitems in a select field to a separate component, since I have to use the same menuitems twice it seemed the best way to just move them to a separate component. But it doesn't work like I would expect it to.
this works fine (since its in the same component):
<TextField
select
variant="outlined"
fullWidth
label="local menuitems"
onChange={(e) => {
console.log("Local running");
setLocalValue(e.target.value);
}}
style={{ width: "100%" }}
value={localValue}
>
<MenuItem value="1">MenuItem 1</MenuItem>
<MenuItem value="2">MenuItem 2</MenuItem>
<MenuItem value="3">MenuItem 3</MenuItem>
</TextField>
This doesnt (since its a separate component):
<TextField
select
variant="outlined"
fullWidth
label="External menuitems"
onChange={(e) => {
console.log("External running");
setExternalValue(e.target.value);
}}
style={{ width: "100%" }}
value={externalValue}
>
<MenuItems />
</TextField>
and MenuItems returns:
<Fragment>
<MenuItem value="1">MenuItem 1</MenuItem>
<MenuItem value="2">MenuItem 2</MenuItem>
<MenuItem value="3">MenuItem 3</MenuItem>
</Fragment>
I made a CodePen https://codesandbox.io/s/infallible-wilson-u4so6?file=/src/App.js
The first example is using the menuitems locally, the second in a different component. The menuitems are shown correctly but they don't work, I also noticed that this error shows up
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
As Omer pointed out the menuItems need to be direct children, so i will need to use forwardRef, now I havent used forwardRef and ref's in general so how would i use this in my case? And if you happen to know how it would work if the MenuItems component is using redux connect() that would be awesome!
Use select as in Material-UI
we must send children:
Material-UI: `children` must be passed when using the `TextField` component with `select`.
in documentation we can see this - it's mean we can't use external items.
the solution for that is to use forwardRef(), but it's not a good one.

Unable to see the Tooltip while using Highlighter

Context: I have table cell which have ellipsis, so I want to have a tooltip over the title.
Currently I am using Material UI Tooltip. Also, since there is a search option and hence I am using the highlighter react-highlight-words to highlight the search term.
Problem: When wrapping the Highlighter component with the Tooltip, the tooltip is not popping up as it does usually. I have used react-tooltip instead and it works.
Below is the code snippet of what I am trying to render :-
<TableCell align="center">
<Tooltip title={title}>
<Highlighter highlightClassName="YourHighlightClass" searchWords={[searchValue]} autoEscape textToHighlight={title} />
</Tooltip>
Seeking some help how to utilise the MUI Tooltip along with the Highlighter.
Here is the code when using react-tooltip:
<TableCell align="center">
<span data-tip={title}>
<Highlighter highlightClassName="YourHighlightClass" searchWords={[searchValue]} autoEscape textToHighlight={title} />
<ReactTooltip delayShow={500} effect="solid" border={false}/>
</span>
</TableCell>
I went through the documentation for the Tooltip and the Highlighter and found that,
Tooltip requires only one direct child, and the Highlighter renders multiple child.
Hence, the simple solution was to wrap the Highlight Component with some <span> tag, etc.
<TableCell align="center">
<Tooltip title={title}>
<span>
<Highlighter highlightClassName="YourHighlightClass" searchWords={[searchValue]} autoEscape textToHighlight={title} />
</span>
</Tooltip>
</TableCell>
Live Demo
It doesn't work because you are using a custom component that doesn't support the API that let you pass the ref down to the DOM element. The <Tooltip/> needs the child reference to know where the DOM element is so it can position itself correctly.
You can fix it by using React.forwardRef() which allow <Tooltip/> to access the children ref
const HighlightedSentence = React.forwardRef((props, ref) => {
return (
<span ref={ref} style={{ backgroundColor: "pink" }}>
<Highlighter
highlightClassName="YourHighlightClass"
searchWords={["and", "or", "the"]}
autoEscape={true}
textToHighlight="The dog is chasing the cat. Or perhaps they're just playing?"
{...props}
/>
</span>
);
});
function App() {
return (
<Tooltip title={"my tooltip"} placement="bottom">
<HighlightedSentence />
</Tooltip>
);
}
Live Demo

How to left align the label in a button

How do I get a material UI button to left align the label? There are no props to directly change the inline-styles on the button element and the only way I can figure to do this is to add a class and write some gross css selector like thisClass > div > button.
http://www.material-ui.com/#/components/raised-button
I had a similar issue with buttons that have an icon. I fixed it by justifing the content:
<Button
startIcon={<AccountCircleIcon/>}
fullWidth={true}
style={{justifyContent: "flex-start"}}>
button text
</Button>
You can give the label absolute positioning by using the labelStyle property on the element.
This works:
<RaisedButton
label="Primary"
primary={true}
lableStyle={{position: 'absolute',top: 0,left: -10}} />
Edit: Updating my answer with better ways to do this
Using text align on the button:
<RaisedButton
style={{textAlign: 'left'}}
label="Primary"
primary={true}/>
Using float on the label:
<RaisedButton
lableStyle={{float: 'left'}}
label="Primary"
primary={true}/>

Resources