-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
Implement DrawerMenuItem #15107
Comments
Do you think it should be an enhancenent of MenuItem/ListItem or a seperate implementation? |
This comment has been minimized.
This comment has been minimized.
We have a couple of different efforts and issue on the List component, I think that it would be great to align them, cc @mbrookes:
I have made a quick POC to get an idea on the options we have: Git diff--- a/docs/src/pages/demos/lists/SelectedListItem.js
+++ b/docs/src/pages/demos/lists/SelectedListItem.js
@@ -26,7 +26,7 @@ function SelectedListItem() {
return (
<div className={classes.root}>
- <List component="nav">
+ <List variant="nav" component="nav">
<ListItem
button
selected={selectedIndex === 0}
diff --git a/packages/material-ui/src/List/List.js b/packages/material-ui/src/List/List.js
index 0039c4c95..b85add49b 100644
--- a/packages/material-ui/src/List/List.js
+++ b/packages/material-ui/src/List/List.js
@@ -32,12 +32,13 @@ const List = React.forwardRef(function List(props, ref) {
className,
component: Component,
dense,
+ variant,
disablePadding,
subheader,
...other
} = props;
- const context = React.useMemo(() => ({ dense }), [dense]);
+ const context = React.useMemo(() => ({ dense, variant }), [dense, variant]);
return (
<ListContext.Provider value={context}>
@@ -94,10 +95,12 @@ List.propTypes = {
* The content of the subheader, normally `ListSubheader`.
*/
subheader: PropTypes.node,
+ variant: PropTypes.oneOf(['nav', 'ul']),
};
List.defaultProps = {
component: 'ul',
+ variant: 'ul',
dense: false,
disablePadding: false,
};
diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js
index daa06ec91..2be1632d3 100644
--- a/packages/material-ui/src/ListItem/ListItem.js
+++ b/packages/material-ui/src/ListItem/ListItem.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import clsx from 'clsx';
import { chainPropTypes } from '@material-ui/utils';
import withStyles from '../styles/withStyles';
+import { fade } from '../styles/colorManipulator';
import ButtonBase from '../ButtonBase';
import { isMuiElement } from '../utils/reactHelpers';
import ListContext from '../List/ListContext';
@@ -15,7 +16,7 @@ export const styles = theme => ({
alignItems: 'center',
position: 'relative',
textDecoration: 'none',
- width: '100%',
+ //width: '100%',
boxSizing: 'border-box',
textAlign: 'left',
paddingTop: 8,
@@ -24,6 +25,15 @@ export const styles = theme => ({
backgroundColor: theme.palette.action.selected,
},
},
+ variantNav: {
+ margin: 8,
+ overflow: 'hidden',
+ '&$selected, &$selected:hover': {
+ borderRadius: 4,
+ color: theme.palette.primary.dark,
+ backgroundColor: fade(theme.palette.primary.main, theme.palette.action.hoverOpacity),
+ },
+ },
/* Styles applied to the `container` element if `children` includes `ListItemSecondaryAction`. */
container: {
position: 'relative',
@@ -106,12 +116,15 @@ const ListItem = React.forwardRef(function ListItem(props, ref) {
const childContext = {
dense: dense || context.dense || false,
alignItems,
+ selected,
};
const children = React.Children.toArray(childrenProp);
const hasSecondaryAction =
children.length && isMuiElement(children[children.length - 1], ['ListItemSecondaryAction']);
+ console.log('context', context)
+
const componentProps = {
className: clsx(
classes.root,
@@ -120,6 +133,7 @@ const ListItem = React.forwardRef(function ListItem(props, ref) {
[classes.gutters]: !disableGutters,
[classes.divider]: divider,
[classes.disabled]: disabled,
+ [classes.variantNav]: context.variant === 'nav',
[classes.button]: button,
[classes.alignItemsFlexStart]: alignItems === 'flex-start',
[classes.secondaryAction]: hasSecondaryAction,
diff --git a/packages/material-ui/src/ListItemIcon/ListItemIcon.js b/packages/material-ui/src/ListItemIcon/ListItemIcon.js
index 89e61d727..41eed6824 100644
--- a/packages/material-ui/src/ListItemIcon/ListItemIcon.js
+++ b/packages/material-ui/src/ListItemIcon/ListItemIcon.js
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
+import ListContext from '../List/ListContext';
export const styles = theme => ({
/* Styles applied to the root element. */
@@ -11,6 +12,9 @@ export const styles = theme => ({
flexShrink: 0,
display: 'inline-flex',
},
+ selected: {
+ color: 'inherit',
+ },
});
/**
@@ -18,8 +22,15 @@ export const styles = theme => ({
*/
const ListItemIcon = React.forwardRef(function ListItemIcon(props, ref) {
const { classes, className, ...other } = props;
+ const context = React.useContext(ListContext);
- return <div className={clsx(classes.root, className)} ref={ref} {...other} />;
+ return (
+ <div
+ className={clsx(classes.root, { [classes.selected]: context.selected }, className)}
+ ref={ref}
+ {...other}
+ />
+ );
});
ListItemIcon.propTypes = { What about: We follow the MenuItem pattern, we introduce a new DrawerListItem component, it's a drop in replacement for the ListItem component. It has a custom handling of the selected property as shown in the previous git diff. If somebody wants its drawer list to be keyboard navigable, it replaces the List component with the MenuList component? |
Alternative strategy: Standardise on a single List and ListItem component. Add variants for Drawer and Menu. Add a We would need to wait for 4.1 for deprecation of MenuList and MenuListItem, however it could be implemented now, with MenuList and MenuListItem becoming a thin wrapper that sets the List variant, with deprecation added later. (Or, the wrappers could become permanent for API stability...) |
We explore this problem further in #22780 for the requirements of the documentation. This will be a great starting point to work on this issue. There is a decision to take between bundling the style inside ListItem (1), creating a new component that extends ListItem (2), or creating a new component without ListItem (3). With hindsight, I think that we should have used option 3 for the Menu: it helps customization (fewer layers of abstraction, style often different) and performance (fewer components, especially relevant with lists). |
Drawer MenuItem: https://material-components.github.io/material-components-web-catalog/#/component/drawer
Demo:
https://material-components.github.io/material-components-web-catalog/#/component/drawer
Shape: https://material.io/design/shape/about-shape.html#shape-customization-tool
Benchmark
The text was updated successfully, but these errors were encountered: