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

[RFR] Custom User Menu icon #2391

Merged
merged 6 commits into from
Oct 11, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion docs/Theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,11 @@ const MyLayout = props => <Layout
export default MyLayout;
```

### UserMenu Customization

You can replace the default user menu by your own by setting the `userMenu` prop of the `<AppBar>` component. For instance, to add custom menu items, just decorate the default `<UserMenu>` by adding children to it:

```js
```jsx
import { AppBar, UserMenu, MenuItemLink } from 'react-admin';
import SettingsIcon from '@material-ui/icons/Settings';

Expand All @@ -407,6 +409,38 @@ const MyAppBar = props => <AppBar {...props} userMenu={<MyUserMenu />} />;
const MyLayout = props => <Layout {...props} appBar={MyAppBar} />;
```

You can also customize the default icon by setting the `icon` prop to the `<UserMenu />` component.

{% raw %}
``` jsx
import { AppBar, UserMenu } from 'react-admin';
import { withStyles } from '@material-ui/core/styles';
import Avatar from '@material-ui/core/Avatar';

const myCustomIconStyle = {
avatar: {
height: 30,
width: 30,
},
};

const MyCustomIcon = withStyles(myCustomIconStyle)(
({ classes }) => (
<Avatar
className={classes.avatar}
src="https://marmelab.com/images/avatars/adrien.jpg"
/>
)
);

const MyUserMenu = props => (<UserMenu {...props} icon={<MyCustomIcon />} />);

const MyAppBar = props => <AppBar {...props} userMenu={<MyUserMenu />} />;
```
{% endraw %}

### Sidebar Customization

You can specify the `Sidebar` size by setting the `size` property:

```jsx
Expand All @@ -420,6 +454,8 @@ const MyLayout = props => <Layout

```

### Layout From Scratch

For more custom layouts, write a component from scratch. It must contain a `{children}` placeholder, where react-admin will render the resources. Use the [default layout](https://github.com/marmelab/react-admin/blob/master/src/mui/layout/Layout.js) as a starting point. Here is a simplified version (with no responsive support):

```jsx
Expand Down
23 changes: 13 additions & 10 deletions packages/ra-ui-materialui/src/layout/UserMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ class UserMenu extends React.Component {
children: PropTypes.node,
label: PropTypes.string.isRequired,
logout: PropTypes.node,
icon: PropTypes.node,
translate: PropTypes.func.isRequired,
};

static defaultProps = {
label: 'ra.auth.user_menu',
icon: <AccountCircle />,
};

state = {
Expand All @@ -36,23 +38,24 @@ class UserMenu extends React.Component {
};

render() {
const { children, label, logout, translate } = this.props;
const { children, label, icon, logout, translate } = this.props;
if (!logout && !children) return null;
const { anchorEl } = this.state;
const open = Boolean(anchorEl);

const menuIconProps = {
Copy link
Member

Choose a reason for hiding this comment

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

I don't need you need to extract the props now that only the icon prop is accepted.

'arial-label': label && translate(label, { _: label }),
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should provide a default label too imo. Something like Profile ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently there is a default label used as default prop: ra.auth.user_menu.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh sorry missed it

'aria-owns': open ? 'menu-appbar' : null,
'aria-haspopup': true,
color: 'inherit',
onClick: this.handleMenu,
children: cloneElement(icon),
};

return (
<div>
<Tooltip title={label && translate(label, { _: label })}>
<IconButton
arial-label={label && translate(label, { _: label })}
aria-owns={open ? 'menu-appbar' : null}
aria-haspopup="true"
onClick={this.handleMenu}
color="inherit"
>
<AccountCircle />
</IconButton>
<IconButton {...menuIconProps} />
</Tooltip>
<Menu
id="menu-appbar"
Expand Down