jsx: ReactJS if condition - reactjs

How to use if condition in jsx: ReactJS? I just want that if the
if user == "author" or "supervisor":
<IconButton
aria-label="delete"
onClick={() => props.pressHandler(props.id)}
>
<DeleteIcon style={{ color: 'red' }} />
</IconButton>
else
no delete button

Just put them in braces,
{ ["author", "supervisor"].includes(user) &&
<IconButton
aria-label="delete"
onClick={() => props.pressHandler(props.id)}
>
<DeleteIcon style={{ color: 'red' }} />
</IconButton> || null }
Reference: https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator

To elaborate on what Stark wrote:
You can use the js operator as such:
{(
(user === "author" || user === "supervisor") &&
<IconButton
aria-label="delete"
onClick={() => props.pressHandler(props.id)}
>
<DeleteIcon style={{ color: 'red' }} />
</IconButton>
) || undefined
}
Same above with ternary operator and React Fragment:
{
(user === "author" || user === "supervisor") ?
<IconButton
aria-label="delete"
onClick={() => props.pressHandler(props.id)}
>
<DeleteIcon style={{ color: 'red' }} />
</IconButton> : <></>
}
In false case, Undefined or React.Fragment wont be rendered.

{
["author", "supervisor"].includes(user) ? (
<IconButton
aria-label="delete"
onClick={() => props.pressHandler(props.id)}
>
<DeleteIcon style={{ color: "red" }} />
</IconButton>
) : null;
}
When you use "&&" operator sometimes you can see "false" text on your app. null will be great option to display nothing or use can put something differrent than delete button for regular user as null.

Related

How to swap MUI icon on IconButton when hovering

I have these tabs that have a close button on them, if the content in them has edits then the close icon turns to a circle, similar to visual code.
{tabs.map((tab, index) => {
const child = (
<StyledTab
label={
<span>
{tab.label + ':' + tab.hasEdit}
<IconButton size="small" component="span" onClick={() => closeClickHandler(tab.value)}>
{tab.hasEdit ? (
<CircleIcon style={{ fontSize: "12px" }} />
) : (
<CloseIcon style={{ fontSize: "18px" }} />
)}
</IconButton>
</span>
}
value={tab.value}
key={index}
/>
);
return (
<DraggableTab
label={
<span>
{tab.label}
<IconButton size="small" component="span" onClick={() => {
closeClickHandler(tab.value);
}}>
{tab.hasEdit ? (
<CircleIcon style={{ fontSize: "12px" }} />
) : (
<CloseIcon style={{ fontSize: "18px" }} />
)}
</IconButton>
</span>
}
value={tab.value}
index={index}
key={index}
child={child}
/>
);
})}
What I'm having trouble with is getting the icon to change from a circle to a close icon while hovering over the button.
Could someone give me a hand on a good way to implement this please?!
You could do this by adding a state for the items. Then add a onMouseEnter and onMouseLeave events on the IconButton. When hovering we can add the index to the array and finally remove when we're leaving. To determine if a icon needs to change we can check if the index in in the hoveringItems.
const [hoveringItems, setHoveringItems] = useState([]);
function handleHover(index, isLeaving) {
setHoveringItems((prevItems) => {
if (isLeaving) return prevItems.filter((item) => item !== index);
return [...prevItems, index];
});
}
return (
<IconButton
size="small"
component="span"
onClick={() => {
closeClickHandler(tab.value);
}}
onMouseEnter={() => handleHover(index, false)}
onMouseLeave={() => handleHover(index, true)}
>
{tab.hasEdit || hoveringItems.includes(index) ? (
<CircleIcon style={{ fontSize: "12px" }} />
) : (
<CloseIcon style={{ fontSize: "18px" }} />
)}
</IconButton>
);

How to add popconfirm to upload in antd react?

i need to add popconfirm element to upload element. i've tried to do this:
<Popconfirm
title="Add file to CDS?"
onConfirm={() => this.cleanGroup(group.key)}
okText="Да"
cancelText="Отмена"
disabled={group.items.length === 0}
open={this.state.open}
>
<Upload
style={{ width: '100%' }}
name="fileManager"
action={uploadUrl}
headers={headers}
data={{
group: group.key,
}}
showUploadList={false}
onChange={(info => this.uploadHandler(info))}
}}
>
<Tooltip title="Add file">
<Button icon={<PlusOutlined />} type="primary" />
</Tooltip>
</Upload>
</Popconfirm>
But in such case it ignore popconfirm. then i hsve tired manual download in upload element:
title="Вы хотите добавить файл в анкету ЦДС?"
onConfirm={() => this.cleanGroup(group.key)}
okText="Да"
cancelText="Отмена"
disabled={group.items.length === 0}
open={this.state.open}
>
<Upload
style={{ width: '100%' }}
name="fileManager"
beforeUpload={(file) => {
console.log("fgfd");
this.setState({
fileList: [...this.state.fileList, file],
});
this.setState({
open: true,
})
return false;
}}
>
<Tooltip title="Добавить файл">
<Button icon={<PlusOutlined />} type="primary" />
</Tooltip>
</Upload>
</Popconfirm>
this solution works, but the problem is that popconfirm and upload components are being rendered in array, so i get 5 popconfirms modals insteasd of one. i don't understand how to render popconfirm only for this upload element, not for all elements. any help will be appreciated!

React MAterial UI - How to add MoreVertIcon in DataGrid?

I am implementing a functionality as shown similarly in the link
https://mui.com/x/react-data-grid/#mit-version
My confusion now is how to add MoreVertIcon at the end column of each row as shown in the code https://mui.com/material-ui/react-menu/#max-height-menu
Each row in the grid should have last column with the MoreVertIcon. Since the data is loaded from the array or JSON data, where will be best place to add this?
I tried like this but I get error in the <DataGrid> tag.
<DataGrid
rows={customers}
columns={columns}
pageSize={16}
rowsPerPageOptions={[5]}
getRowId={(row: any) => row.name}
autoPageSize={true}
rowHeight={45}
onRowClick={handleCustomerClick}
hideFooterSelectedRowCount={true}>
<div>
<IconButton
aria-label="more"
id="long-button"
aria-controls={open ? 'long-menu' : undefined}
aria-expanded={open ? 'true' : undefined}
aria-haspopup="true"
onClick={handleClick}
>
<MoreVertIcon />
</IconButton>
<Menu
id="long-menu"
MenuListProps={{
'aria-labelledby': 'long-button',
}}
anchorEl={anchorEl}
open={open}
onClose={handleClose}
PaperProps={{
style: {
maxHeight: ITEM_HEIGHT * 4.5,
width: '20ch',
},
}}
>
{options.map((option) => (
<MenuItem key={option} selected={option === 'Pyxis'} onClick={handleClose}>
{option}
</MenuItem>
))}
</Menu>
</div>
</DataGrid>

React material UI split button align

I am trying to align to the left the dropdown menu list, whatever values I put in are not yielding this result can somone advise how to do this?
https://material-ui.com/components/button-group/#split-button
Here is what my template looks like:
<Grid container direction="column" alignItems="flex-start">
<Grid item xs={12}>
<ButtonGroup variant="contained" color="primary" ref={anchorRef} aria-label="split button">
<Button onClick={() => handleClick(options[selectedIndex])}>
{options[selectedIndex]}
</Button>
<Button
color="primary"
size="small"
aria-controls={open ? "split-button-menu" : undefined}
aria-expanded={open ? "true" : undefined}
aria-label="select mode type"
aria-haspopup="menu"
onClick={handleToggle}
>
<ArrowDropDownIcon />
</Button>
</ButtonGroup>
<Popper open={open} anchorEl={anchorRef.current} role={undefined} transition disablePortal>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin: placement === "bottom" ? "left top" : "left bottom",
}}
>
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList id="split-button-menu">
{options &&
options.map((option, index) => (
<MenuItem
key={option}
disabled={index === selectedIndex}
selected={index === selectedIndex}
onClick={(event) => handleMenuItemClick(event, index)}
>
{option}
</MenuItem>
))}
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</Grid>
</Grid>
Try this:
<Grow
{...TransitionProps}
anchorOrigin={{
horizontal: 'left',
vertical: 'bottom',
}}
transformOrigin={{
horizontal: 'left',
vertical: 'top',
}}
>
{insert children here}
</Grow>
UPDATE
This is what you want, i.e, add placement='bottom-start' to your Popper component. Thanks for giving me more context.
<Popper
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
placement='bottom-start'
>
{...children...}
</Popper>

React Conditional Rendering to check if something is an empty tag

I have the following code:
{item && item.description && (
<Link
style={{ display: 'block', paddingBottom: '2px' }}
title="View Details"
onClick={() => setIsOpen(!isOpen)}
{...aria}
>
View Details
<Icon icon={isOpen ? 'collapse_arrow' : 'expand_arrow'}
marginLeft="5px"
verticalAlign="bottom"
/>
</Link>
)}
The problem is that item.description could be an empty tag and therefore the condition is met and a Link component is rendered when it actually shouldn't be.
How is the best way I could avoid this case?
Thanks in advance!
You could use a regex to check for empty tags.
function checkForEmptyTags(tags) {
if (!tags) return false;
const EMPTY_TAGS_REGEX = RegExp('<[^>]*>\s*<\/[^>]*>');
return EMPTY_TAGS_REGEX.test(tags);
}
{item && !checkForEmptyTags(item.description) && (
<Link
style={{ display: 'block', paddingBottom: '2px' }}
title="View Details"
onClick={() => setIsOpen(!isOpen)}
{...aria}
>
View Details
<Icon icon={isOpen ? 'collapse_arrow' : 'expand_arrow'}
marginLeft="5px"
verticalAlign="bottom"
/>
</Link>
)}

Resources