Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add <Menu.Item>content</Menu.item> syntax #9242

Merged
merged 7 commits into from Sep 14, 2023
Merged

Add <Menu.Item>content</Menu.item> syntax #9242

merged 7 commits into from Sep 14, 2023

Conversation

fzaninotto
Copy link
Member

@fzaninotto fzaninotto commented Sep 4, 2023

Problem

The <Menu.Item primaryText> syntax isn't intuitive, especially for someone who already knows material-ui, where the menu label is expressed via children.

Solution

Support menu label is expressed via children in addition to primaryText for mobile

import { Menu } from 'react-admin';
import { ListItemIcon, ListItemText, Typography } from '@mui/material';

const CustomMenu = () => (
    <Menu>
        <Menu.Item to="/" leftIcon={<Dashboard />} primaryText="Dashboard" />
        <Menu.Item to="/sales" primaryText="Sales">
            <ListItemIcon>
               <PieChartOutlined />
             </ListItemIcon>
             <ListItemText>Sales</ListItemText>
             <Typography variant="body2" color="text.secondary">
                 ⌘S
             </Typography>
        </Menu.Item>
        <Menu.Item to="/customers" leftIcon={<PeopleOutlined />} primaryText="Customers" />
        <Menu.Item to="/products" leftIcon={<Inventory />} primaryText="Catalog" />
    </Menu>
);

The following is still supported:

const CustomMenu = () => (
    <Menu>
        <Menu.Item to="/" leftIcon={<Dashboard />} primaryText="Dashboard" />
        <Menu.Item to="/sales" leftIcon={<PieChartOutlined />} primaryText="Sales" />
        <Menu.Item to="/customers" leftIcon={<PeopleOutlined />} primaryText="Customers" />
        <Menu.Item to="/products" leftIcon={<Inventory />} primaryText="Catalog" />
    </Menu>
);

Copy link
Contributor

@djhi djhi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should deprecate primaryText to remove it in v5 IMO

docs/Menu.md Outdated Show resolved Hide resolved
@fzaninotto fzaninotto added the WIP Work In Progress label Sep 5, 2023
@fzaninotto fzaninotto changed the title Add <Menu.Item>title</Menu.item> syntax Add <Menu.Item>content</Menu.item> syntax Sep 5, 2023
Copy link
Contributor

@slax57 slax57 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very nice !

Just found a little issue: the Tooltip is still rendered on hover when providing children, and it's empty so it's a bit weird.

Capture d’écran du 2023-09-07 11-15-02

@fzaninotto
Copy link
Member Author

Because we have to show the menu label on hover on Mobile, we must always support primaryText, even when passing children. But then we end up with duplicated label, because we have to render both in the expanded menu for backwards compatibility reasons.

image

The only BC solution I can think of is to deprecate primaryText and replace it with label, and only render label in expanded menu if there is no children. But this is a much larger change:

image

So we should probably not move forward with this. Anyone willing to use custom menu content can still use their own component instead of <Menu.Item>.

WDYT?

@slax57
Copy link
Contributor

slax57 commented Sep 8, 2023

@fzaninotto You're right.

However, I don't understand why you are saying "we have to render both in the expanded menu for backwards compatibility reasons".

Unless I'm mistaken, <Menu.Item> did not accept children in the first place (or rather, ignored them). So why couldn't we implement a logic that says: render the children under <StyledMenuItem> when there are children provided, otherwise render primaryText ; and in any case, render primaryText as the <Tooltip title>?

The following seems to work according to my tests:

    const renderMenuItem = () => {
        return (
            <StyledMenuItem
                className={clsx(className, {
                    [MenuItemLinkClasses.active]: !!match,
                })}
                // @ts-ignore
                component={LinkRef}
                ref={ref}
                tabIndex={0}
                {...rest}
                onClick={handleMenuTap}
            >
                {leftIcon && (
                    <ListItemIcon className={MenuItemLinkClasses.icon}>
                        {leftIcon}
                    </ListItemIcon>
                )}
                {children
                    ? children
                    : typeof primaryText === 'string'
                    ? translate(primaryText, { _: primaryText })
                    : primaryText}
            </StyledMenuItem>
        );
    };

    return open ? (
        renderMenuItem()
    ) : (
        <Tooltip
            title={
                typeof primaryText === 'string'
                    ? translate(primaryText, { _: primaryText })
                    : null
            }
            placement="right"
            {...tooltipProps}
        >
            {renderMenuItem()}
        </Tooltip>
    );

@fzaninotto
Copy link
Member Author

You're right, it works! I've pushed the changes. Switching back to RFR.

docs/Menu.md Outdated Show resolved Hide resolved
docs/Menu.md Outdated Show resolved Hide resolved
</ListItemIcon>
<ListItemText>Customers</ListItemText>
</Menu.Item>
<Tooltip title="Catalog" placement="right">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this Tooltip displays all the time, not only when the side menu is collapsed. Not sure it's worth it to bother fixing it though, it's really minor...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw it. This is indeed minor, and it's on an internal story, so I though we could live with it.

packages/ra-ui-materialui/src/layout/MenuItemLink.tsx Outdated Show resolved Hide resolved
fzaninotto and others added 2 commits September 12, 2023 18:38
Co-authored-by: Jean-Baptiste Kaiser <jb@marmelab.com>
@djhi djhi requested a review from slax57 September 13, 2023 07:14
@slax57 slax57 added this to the 4.15.0 milestone Sep 14, 2023
@slax57 slax57 merged commit 1e056aa into next Sep 14, 2023
11 checks passed
@slax57 slax57 deleted the menu-item-children branch September 14, 2023 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFR Ready For Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants