From e4f684dcbc551842694876ea0b6ea0e8bddba54f Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 25 May 2021 15:20:09 +0700 Subject: [PATCH 01/61] add wip ListItemButton --- packages/material-ui/src/ListItem/ListItem.js | 54 ++++-- .../src/ListItemButton/ListItemButton.d.ts | 88 +++++++++ .../src/ListItemButton/ListItemButton.js | 178 ++++++++++++++++++ .../src/ListItemButton/ListItemButton.test.js | 69 +++++++ .../material-ui/src/ListItemButton/index.d.ts | 5 + .../material-ui/src/ListItemButton/index.js | 5 + .../ListItemButton/listItemButtonClasses.ts | 39 ++++ 7 files changed, 420 insertions(+), 18 deletions(-) create mode 100644 packages/material-ui/src/ListItemButton/ListItemButton.d.ts create mode 100644 packages/material-ui/src/ListItemButton/ListItemButton.js create mode 100644 packages/material-ui/src/ListItemButton/ListItemButton.test.js create mode 100644 packages/material-ui/src/ListItemButton/index.d.ts create mode 100644 packages/material-ui/src/ListItemButton/index.js create mode 100644 packages/material-ui/src/ListItemButton/listItemButtonClasses.ts diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 1938576b0d1507..7f74ee27548454 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -12,6 +12,11 @@ import useEnhancedEffect from '../utils/useEnhancedEffect'; import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; import listItemClasses, { getListItemUtilityClass } from './listItemClasses'; +import { listItemButtonClasses } from '../ListItemButton'; + +// TODO remove these in v6 +// - button related (styling and logic) like autoFocus, focusVisible, disabled +// - container export const overridesResolver = (props, styles) => { const { styleProps } = props; @@ -30,12 +35,12 @@ export const overridesResolver = (props, styles) => { const useUtilityClasses = (styleProps) => { const { alignItems, - button, classes, dense, - disabled, disableGutters, divider, + disabled, + button, hasSecondaryAction, selected, } = styleProps; @@ -46,9 +51,9 @@ const useUtilityClasses = (styleProps) => { dense && 'dense', !disableGutters && 'gutters', divider && 'divider', + alignItems === 'flex-start' && 'alignItemsFlexStart', disabled && 'disabled', button && 'button', - alignItems === 'flex-start' && 'alignItemsFlexStart', hasSecondaryAction && 'secondaryAction', selected && 'selected', ], @@ -71,8 +76,10 @@ export const ListItemRoot = experimentalStyled('div', { width: '100%', boxSizing: 'border-box', textAlign: 'left', - paddingTop: 8, - paddingBottom: 8, + ...(!styleProps.hasListItemButton && { + paddingTop: 8, + paddingBottom: 8, + }), [`&.${listItemClasses.focusVisible}`]: { backgroundColor: theme.palette.action.focus, }, @@ -89,10 +96,11 @@ export const ListItemRoot = experimentalStyled('div', { opacity: theme.palette.action.disabledOpacity, }, /* Styles applied to the component element if dense. */ - ...(styleProps.dense && { - paddingTop: 4, - paddingBottom: 4, - }), + ...(!styleProps.hasListItemButton && + styleProps.dense && { + paddingTop: 4, + paddingBottom: 4, + }), /* Styles applied to the component element if `alignItems="flex-start"`. */ ...(styleProps.alignItems === 'flex-start' && { alignItems: 'flex-start', @@ -103,10 +111,11 @@ export const ListItemRoot = experimentalStyled('div', { backgroundClip: 'padding-box', }), /* Styles applied to the inner `component` element unless `disableGutters={true}`. */ - ...(!styleProps.disableGutters && { - paddingLeft: 16, - paddingRight: 16, - }), + ...(!styleProps.hasListItemButton && + !styleProps.disableGutters && { + paddingLeft: 16, + paddingRight: 16, + }), /* Styles applied to the inner `component` element if `button={true}`. */ ...(styleProps.button && { transition: theme.transitions.create('background-color', { @@ -132,11 +141,18 @@ export const ListItemRoot = experimentalStyled('div', { }, }), /* Styles applied to the component element if `children` includes `ListItemSecondaryAction`. */ - ...(styleProps.hasSecondaryAction && { - // Add some space to avoid collision as `ListItemSecondaryAction` - // is absolutely positioned. - paddingRight: 48, - }), + ...(!styleProps.hasListItemButton && + styleProps.hasSecondaryAction && { + // Add some space to avoid collision as `ListItemSecondaryAction` + // is absolutely positioned. + paddingRight: 48, + }), + ...(styleProps.hasListItemButton && + styleProps.hasSecondaryAction && { + [`& > .${listItemButtonClasses.root}`]: { + paddingRight: 48, + }, + }), })); const ListItemContainer = experimentalStyled('li', { @@ -195,6 +211,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { const children = React.Children.toArray(childrenProp); const hasSecondaryAction = children.length && isMuiElement(children[children.length - 1], ['ListItemSecondaryAction']); + const hasListItemButton = children.some((child) => isMuiElement(child, ['ListItemButton'])); const styleProps = { ...props, @@ -206,6 +223,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { disableGutters, divider, hasSecondaryAction, + hasListItemButton, selected, }; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts new file mode 100644 index 00000000000000..843711695f37f1 --- /dev/null +++ b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts @@ -0,0 +1,88 @@ +import * as React from 'react'; +import { SxProps } from '@material-ui/system'; +import { Theme } from '@material-ui/core/styles'; +import { ExtendButtonBase, ExtendButtonBaseTypeMap } from '../ButtonBase'; +import { OverrideProps } from '../OverridableComponent'; +import { ListItemButtonClasses } from './listItemButtonClasses'; + +interface ListItemButtonBaseProps { + /** + * Defines the `align-items` style property. + * @default 'center' + */ + alignItems?: 'flex-start' | 'center'; + /** + * If `true`, the list item is focused during the first mount. + * Focus will also be triggered if the value changes from false to true. + * @default false + */ + autoFocus?: boolean; + /** + * The content of the component if a `ListItemSecondaryAction` is used it must + * be the last child. + */ + children?: React.ReactNode; + /** + * Override or extend the styles applied to the component. + */ + classes?: Partial; + /** + * If `true`, compact vertical padding designed for keyboard and mouse input is used. + * The prop defaults to the value inherited from the parent List component. + * @default false + */ + dense?: boolean; + /** + * If `true`, the component is disabled. + * @default false + */ + disabled?: boolean; + /** + * If `true`, the left and right padding is removed. + * @default false + */ + disableGutters?: boolean; + /** + * If `true`, a 1px light border is added to the bottom of the list item. + * @default false + */ + divider?: boolean; + /** + * Use to apply selected styling. + * @default false + */ + selected?: boolean; + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx?: SxProps; +} + +export type ListItemButtonTypeMap< + P = {}, + D extends React.ElementType = 'button' +> = ExtendButtonBaseTypeMap<{ + props: P & ListItemButtonBaseProps; + defaultComponent: D; +}>; + +/** + * Uses an additional container component if `ListItemSecondaryAction` is the last child. + * + * Demos: + * + * - [Lists](https://material-ui.com/components/lists/) + * - [Transfer List](https://material-ui.com/components/transfer-list/) + * + * API: + * + * - [ListItemButton API](https://material-ui.com/api/list-item/) + */ +declare const ListItemButton: ExtendButtonBase; + +export type ListItemButtonProps< + D extends React.ElementType = ListItemButtonTypeMap['defaultComponent'], + P = {} +> = OverrideProps, D>; + +export default ListItemButton; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js new file mode 100644 index 00000000000000..8a8971fe009bf1 --- /dev/null +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -0,0 +1,178 @@ +import * as React from 'react'; +import clsx from 'clsx'; +import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; +import { alpha } from '../styles/colorManipulator'; +import experimentalStyled from '../styles/experimentalStyled'; +import useThemeProps from '../styles/useThemeProps'; +import ButtonBase from '../ButtonBase'; +import useEnhancedEffect from '../utils/useEnhancedEffect'; +import useForkRef from '../utils/useForkRef'; +import ListContext from '../List/ListContext'; +import listItemButtonClasses, { getListItemButtonUtilityClass } from './listItemButtonClasses'; + +const overridesResolver = (props, styles) => { + const { styleProps } = props; + + return { + ...styles.root, + ...(styleProps.dense && styles.dense), + ...(styleProps.alignItems === 'flex-start' && styles.alignItemsFlexStart), + ...(styleProps.divider && styles.divider), + ...(!styleProps.disableGutters && styles.gutters), + }; +}; + +const useUtilityClasses = (styleProps) => { + const { alignItems, classes, dense, disabled, disableGutters, divider, selected } = styleProps; + + const slots = { + root: [ + 'root', + dense && 'dense', + !disableGutters && 'gutters', + divider && 'divider', + disabled && 'disabled', + alignItems === 'flex-start' && 'alignItemsFlexStart', + selected && 'selected', + ], + }; + + return composeClasses(slots, getListItemButtonUtilityClass, classes); +}; + +const ListItemButtonRoot = experimentalStyled( + ButtonBase, + {}, + { name: 'ListItemButtonRoot', slot: 'Root', overridesResolver }, +)(({ theme, styleProps }) => ({ + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + position: 'relative', + textDecoration: 'none', + width: '100%', + boxSizing: 'border-box', + textAlign: 'left', + paddingTop: 8, + paddingBottom: 8, + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shortest, + }), + '&:hover': { + textDecoration: 'none', + backgroundColor: theme.palette.action.hover, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + [`&.${listItemButtonClasses.selected}`]: { + backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + [`&.${listItemButtonClasses.focusVisible}`]: { + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), + }, + }, + [`&.${listItemButtonClasses.selected}:hover`]: { + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + }, + }, + [`&.${listItemButtonClasses.focusVisible}`]: { + backgroundColor: theme.palette.action.focus, + }, + [`&.${listItemButtonClasses.disabled}`]: { + opacity: theme.palette.action.disabledOpacity, + }, + /* Styles applied to the inner `component` element if `divider={true}`. */ + ...(styleProps.divider && { + borderBottom: `1px solid ${theme.palette.divider}`, + backgroundClip: 'padding-box', + }), + /* Styles applied to the component element if `alignItems="flex-start"`. */ + ...(styleProps.alignItems === 'flex-start' && { + alignItems: 'flex-start', + }), + /* Styles applied to the inner `component` element unless `disableGutters={true}`. */ + ...(!styleProps.disableGutters && { + paddingLeft: 16, + paddingRight: 16, + }), + /* Styles applied to the component element if dense. */ + ...(styleProps.dense && { + paddingTop: 4, + paddingBottom: 4, + }), +})); + +const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) { + const props = useThemeProps({ props: inProps, name: 'MuiListItemButton' }); + const { + autoFocus = false, + className, + component = 'div', + children, + alignItems = 'center', + dense = false, + disableGutters = false, + divider = false, + selected = false, + focusVisibleClassName, + ...other + } = props; + + const context = React.useContext(ListContext); + const childContext = { + dense: dense || context.dense || false, + alignItems, + disableGutters, + }; + + const listItemRef = React.useRef(null); + useEnhancedEffect(() => { + if (autoFocus) { + if (listItemRef.current) { + listItemRef.current.focus(); + } else if (process.env.NODE_ENV !== 'production') { + console.error( + 'Material-UI: Unable to set focus to a ListItem whose component has not been rendered.', + ); + } + } + }, [autoFocus]); + + const styleProps = { + ...props, + alignItems, + dense: childContext.dense, + disableGutters, + divider, + }; + + const classes = useUtilityClasses(styleProps); + + const handleRef = useForkRef(listItemRef, ref); + + return ( + + {children} + + ); +}); + +ListItemButton.muiName = 'ListItemButton'; + +export default ListItemButton; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.test.js b/packages/material-ui/src/ListItemButton/ListItemButton.test.js new file mode 100644 index 00000000000000..32c9c967823015 --- /dev/null +++ b/packages/material-ui/src/ListItemButton/ListItemButton.test.js @@ -0,0 +1,69 @@ +import * as React from 'react'; +import { expect } from 'chai'; +import { createMount, describeConformanceV5, act, createClientRender, fireEvent } from 'test/utils'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import ListItemButton, { listItemButtonClasses as classes } from '@material-ui/core/ListItemButton'; + +describe('', () => { + const render = createClientRender(); + const mount = createMount(); + + describeConformanceV5(, () => ({ + classes, + inheritComponent: 'div', + render, + mount, + refInstanceof: window.HTMLLIElement, + muiName: 'MuiListItemButton', + testVariantProps: { dense: true }, + skip: ['componentsProp'], + })); + + it('should render with gutters classes', () => { + const { getByRole } = render(); + expect(getByRole('button')).to.have.class(classes.gutters); + }); + + it('should render with the selected class', () => { + const { getByRole } = render(); + expect(getByRole('button')).to.have.class(classes.selected); + }); + + it('should disable the gutters', () => { + const { getByRole } = render(); + expect(getByRole('button')).not.to.have.class(classes.gutters); + }); + + describe('secondary action', () => { + it('should accept a component property', () => { + const { getByRole } = render( + + + + , + ); + const listItem = getByRole('button'); + + expect(listItem).to.have.class(classes.container); + expect(listItem.querySelector(`span.${classes.root}`)).not.to.equal(null); + }); + }); + + describe('prop: focusVisibleClassName', () => { + it('should merge the class names', () => { + const { getByRole } = render( + , + ); + const button = getByRole('button'); + + act(() => { + fireEvent.keyDown(document.activeElement || document.body, { key: 'Tab' }); + button.focus(); + }); + + expect(button).to.have.class('focusVisibleClassName'); + expect(button).to.have.class(classes.focusVisible); + }); + }); +}); diff --git a/packages/material-ui/src/ListItemButton/index.d.ts b/packages/material-ui/src/ListItemButton/index.d.ts new file mode 100644 index 00000000000000..57fdf7f3962ea2 --- /dev/null +++ b/packages/material-ui/src/ListItemButton/index.d.ts @@ -0,0 +1,5 @@ +export { default } from './ListItemButton'; +export * from './ListItemButton'; + +export { default as listItemButtonClasses } from './listItemButtonClasses'; +export * from './listItemButtonClasses'; diff --git a/packages/material-ui/src/ListItemButton/index.js b/packages/material-ui/src/ListItemButton/index.js new file mode 100644 index 00000000000000..57fdf7f3962ea2 --- /dev/null +++ b/packages/material-ui/src/ListItemButton/index.js @@ -0,0 +1,5 @@ +export { default } from './ListItemButton'; +export * from './ListItemButton'; + +export { default as listItemButtonClasses } from './listItemButtonClasses'; +export * from './listItemButtonClasses'; diff --git a/packages/material-ui/src/ListItemButton/listItemButtonClasses.ts b/packages/material-ui/src/ListItemButton/listItemButtonClasses.ts new file mode 100644 index 00000000000000..69e909c305af82 --- /dev/null +++ b/packages/material-ui/src/ListItemButton/listItemButtonClasses.ts @@ -0,0 +1,39 @@ +import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; + +export interface ListItemButtonClasses { + /** Styles applied to the (normally root) `component` element. May be wrapped by a `container`. */ + root: string; + /** Pseudo-class applied to the `component`'s `focusVisibleClassName` prop if `button={true}`. */ + focusVisible: string; + /** Styles applied to the component element if dense. */ + dense: string; + /** Styles applied to the component element if `alignItems="flex-start"`. */ + alignItemsFlexStart: string; + /** Pseudo-class applied to the inner `component` element if `disabled={true}`. */ + disabled: string; + /** Styles applied to the inner `component` element if `divider={true}`. */ + divider: string; + /** Styles applied to the inner `component` element unless `disableGutters={true}`. */ + gutters: string; + /** Pseudo-class applied to the root element if `selected={true}`. */ + selected: string; +} + +export type ListItemButtonClassKey = keyof ListItemButtonClasses; + +export function getListItemButtonUtilityClass(slot: string): string { + return generateUtilityClass('MuiListItemButton', slot); +} + +const listItemButtonClasses: ListItemButtonClasses = generateUtilityClasses('MuiListItemButton', [ + 'root', + 'focusVisible', + 'dense', + 'alignItemsFlexStart', + 'disabled', + 'divider', + 'gutters', + 'selected', +]); + +export default listItemButtonClasses; From a0d692896546eb00968accb1a29326a516e3e913 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 25 May 2021 15:55:53 +0700 Subject: [PATCH 02/61] update lists docs to use ListItemButton --- .../pages/components/lists/CheckboxList.js | 31 +++++++------- .../pages/components/lists/CheckboxList.tsx | 31 +++++++------- docs/src/pages/components/lists/InsetList.js | 19 +++++---- docs/src/pages/components/lists/InsetList.tsx | 19 +++++---- docs/src/pages/components/lists/NestedList.js | 18 ++++---- .../src/pages/components/lists/NestedList.tsx | 18 ++++---- .../components/lists/SelectedListItem.js | 22 ++++------ .../components/lists/SelectedListItem.tsx | 22 ++++------ docs/src/pages/components/lists/SimpleList.js | 22 ++++------ .../src/pages/components/lists/SimpleList.tsx | 22 ++++------ .../pages/components/lists/VirtualizedList.js | 7 +++- .../components/lists/VirtualizedList.tsx | 7 +++- docs/src/pages/components/lists/lists.md | 12 ++---- .../src/ListItemButton/ListItemButton.d.ts | 2 +- .../src/ListItemButton/ListItemButton.js | 42 +++++++++++-------- 15 files changed, 145 insertions(+), 149 deletions(-) diff --git a/docs/src/pages/components/lists/CheckboxList.js b/docs/src/pages/components/lists/CheckboxList.js index 314b8b14035935..bf81516335886e 100644 --- a/docs/src/pages/components/lists/CheckboxList.js +++ b/docs/src/pages/components/lists/CheckboxList.js @@ -1,6 +1,7 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; @@ -30,23 +31,19 @@ export default function CheckboxList() { const labelId = `checkbox-list-label-${value}`; return ( - - - - - + + + + + + + diff --git a/docs/src/pages/components/lists/CheckboxList.tsx b/docs/src/pages/components/lists/CheckboxList.tsx index 63eb9a60d4ae71..18c6b6acd64bdd 100644 --- a/docs/src/pages/components/lists/CheckboxList.tsx +++ b/docs/src/pages/components/lists/CheckboxList.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; @@ -30,23 +31,19 @@ export default function CheckboxList() { const labelId = `checkbox-list-label-${value}`; return ( - - - - - + + + + + + + diff --git a/docs/src/pages/components/lists/InsetList.js b/docs/src/pages/components/lists/InsetList.js index 3948a75af48d43..f23139f2e81953 100644 --- a/docs/src/pages/components/lists/InsetList.js +++ b/docs/src/pages/components/lists/InsetList.js @@ -1,6 +1,7 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import StarIcon from '@material-ui/icons/Star'; @@ -12,14 +13,18 @@ export default function InsetList() { component="nav" aria-label="contacts" > - - - - - + + + + + + + - - + + + + ); diff --git a/docs/src/pages/components/lists/InsetList.tsx b/docs/src/pages/components/lists/InsetList.tsx index 3948a75af48d43..f23139f2e81953 100644 --- a/docs/src/pages/components/lists/InsetList.tsx +++ b/docs/src/pages/components/lists/InsetList.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import StarIcon from '@material-ui/icons/Star'; @@ -12,14 +13,18 @@ export default function InsetList() { component="nav" aria-label="contacts" > - - - - - + + + + + + + - - + + + + ); diff --git a/docs/src/pages/components/lists/NestedList.js b/docs/src/pages/components/lists/NestedList.js index a4d7bfc9a1fb79..1f209027f34af7 100644 --- a/docs/src/pages/components/lists/NestedList.js +++ b/docs/src/pages/components/lists/NestedList.js @@ -1,7 +1,7 @@ import * as React from 'react'; import ListSubheader from '@material-ui/core/ListSubheader'; import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Collapse from '@material-ui/core/Collapse'; @@ -30,33 +30,33 @@ export default function NestedList() { } > - + - - + + - - + + {open ? : } - + - + - + diff --git a/docs/src/pages/components/lists/NestedList.tsx b/docs/src/pages/components/lists/NestedList.tsx index a4d7bfc9a1fb79..1f209027f34af7 100644 --- a/docs/src/pages/components/lists/NestedList.tsx +++ b/docs/src/pages/components/lists/NestedList.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import ListSubheader from '@material-ui/core/ListSubheader'; import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Collapse from '@material-ui/core/Collapse'; @@ -30,33 +30,33 @@ export default function NestedList() { } > - + - - + + - - + + {open ? : } - + - + - + diff --git a/docs/src/pages/components/lists/SelectedListItem.js b/docs/src/pages/components/lists/SelectedListItem.js index 83812ceb4eb2f4..5f4463bddbda55 100644 --- a/docs/src/pages/components/lists/SelectedListItem.js +++ b/docs/src/pages/components/lists/SelectedListItem.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Divider from '@material-ui/core/Divider'; @@ -18,8 +18,7 @@ export default function SelectedListItem() { return ( - handleListItemClick(event, 0)} > @@ -27,9 +26,8 @@ export default function SelectedListItem() { - - + handleListItemClick(event, 1)} > @@ -37,24 +35,22 @@ export default function SelectedListItem() { - + - handleListItemClick(event, 2)} > - - + handleListItemClick(event, 3)} > - + ); diff --git a/docs/src/pages/components/lists/SelectedListItem.tsx b/docs/src/pages/components/lists/SelectedListItem.tsx index 52a445fad79404..afa87e6a90e073 100644 --- a/docs/src/pages/components/lists/SelectedListItem.tsx +++ b/docs/src/pages/components/lists/SelectedListItem.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Divider from '@material-ui/core/Divider'; @@ -21,8 +21,7 @@ export default function SelectedListItem() { return ( - handleListItemClick(event, 0)} > @@ -30,9 +29,8 @@ export default function SelectedListItem() { - - + handleListItemClick(event, 1)} > @@ -40,24 +38,22 @@ export default function SelectedListItem() { - + - handleListItemClick(event, 2)} > - - + handleListItemClick(event, 3)} > - + ); diff --git a/docs/src/pages/components/lists/SimpleList.js b/docs/src/pages/components/lists/SimpleList.js index b90dc3a970396d..23ec831a6d0501 100644 --- a/docs/src/pages/components/lists/SimpleList.js +++ b/docs/src/pages/components/lists/SimpleList.js @@ -1,42 +1,38 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Divider from '@material-ui/core/Divider'; import InboxIcon from '@material-ui/icons/Inbox'; import DraftsIcon from '@material-ui/icons/Drafts'; -function ListItemLink(props) { - return ; -} - export default function SimpleList() { return ( - + - - + + - + - + - - + + - + ); diff --git a/docs/src/pages/components/lists/SimpleList.tsx b/docs/src/pages/components/lists/SimpleList.tsx index 6ee78a02a12626..23ec831a6d0501 100644 --- a/docs/src/pages/components/lists/SimpleList.tsx +++ b/docs/src/pages/components/lists/SimpleList.tsx @@ -1,42 +1,38 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; import List from '@material-ui/core/List'; -import ListItem, { ListItemProps } from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Divider from '@material-ui/core/Divider'; import InboxIcon from '@material-ui/icons/Inbox'; import DraftsIcon from '@material-ui/icons/Drafts'; -function ListItemLink(props: ListItemProps<'a', { button?: true }>) { - return ; -} - export default function SimpleList() { return ( - + - - + + - + - + - - + + - + ); diff --git a/docs/src/pages/components/lists/VirtualizedList.js b/docs/src/pages/components/lists/VirtualizedList.js index 5f3e6e68180c36..f966fd790c5e40 100644 --- a/docs/src/pages/components/lists/VirtualizedList.js +++ b/docs/src/pages/components/lists/VirtualizedList.js @@ -1,6 +1,7 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemText from '@material-ui/core/ListItemText'; import { FixedSizeList } from 'react-window'; @@ -8,8 +9,10 @@ function renderRow(props) { const { index, style } = props; return ( - - + + + + ); } diff --git a/docs/src/pages/components/lists/VirtualizedList.tsx b/docs/src/pages/components/lists/VirtualizedList.tsx index 2eae903741c8c4..4592e89b452fa6 100644 --- a/docs/src/pages/components/lists/VirtualizedList.tsx +++ b/docs/src/pages/components/lists/VirtualizedList.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemText from '@material-ui/core/ListItemText'; import { FixedSizeList, ListChildComponentProps } from 'react-window'; @@ -8,8 +9,10 @@ function renderRow(props: ListChildComponentProps) { const { index, style } = props; return ( - - + + + + ); } diff --git a/docs/src/pages/components/lists/lists.md b/docs/src/pages/components/lists/lists.md index b31a220cdba97e..a32168645697d9 100644 --- a/docs/src/pages/components/lists/lists.md +++ b/docs/src/pages/components/lists/lists.md @@ -1,6 +1,6 @@ --- title: React List component -components: Collapse, Divider, List, ListItem, ListItemAvatar, ListItemIcon, ListItemSecondaryAction, ListItemText, ListSubheader +components: Collapse, Divider, List, ListItem, ListItemButton, ListItemAvatar, ListItemIcon, ListItemSecondaryAction, ListItemText, ListSubheader githubLabel: 'component: List' materialDesign: https://material.io/components/lists --- @@ -20,15 +20,9 @@ Lists are a continuous group of text or images. They are composed of items conta The last item of the previous demo shows how you can render a link: ```jsx -function ListItemLink(props) { - return ; -} - -//... - - + -; +; ``` You can find a [demo with React Router following this section](/guides/routing/#list) of the documentation. diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts index 843711695f37f1..9e10eab6d03a6a 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts +++ b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts @@ -60,7 +60,7 @@ interface ListItemButtonBaseProps { export type ListItemButtonTypeMap< P = {}, - D extends React.ElementType = 'button' + D extends React.ElementType = 'div' > = ExtendButtonBaseTypeMap<{ props: P & ListItemButtonBaseProps; defaultComponent: D; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index 8a8971fe009bf1..666180df7b8503 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -2,7 +2,7 @@ import * as React from 'react'; import clsx from 'clsx'; import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; import { alpha } from '../styles/colorManipulator'; -import experimentalStyled from '../styles/experimentalStyled'; +import experimentalStyled, { rootShouldForwardProp } from '../styles/experimentalStyled'; import useThemeProps from '../styles/useThemeProps'; import ButtonBase from '../ButtonBase'; import useEnhancedEffect from '../utils/useEnhancedEffect'; @@ -37,14 +37,20 @@ const useUtilityClasses = (styleProps) => { ], }; - return composeClasses(slots, getListItemButtonUtilityClass, classes); + const composedClasses = composeClasses(slots, getListItemButtonUtilityClass, classes); + + return { + ...classes, + ...composedClasses, + }; }; -const ListItemButtonRoot = experimentalStyled( - ButtonBase, - {}, - { name: 'ListItemButtonRoot', slot: 'Root', overridesResolver }, -)(({ theme, styleProps }) => ({ +const ListItemButtonRoot = experimentalStyled(ButtonBase, { + shouldForwardProp: (prop) => rootShouldForwardProp(prop) || prop === 'classes', + name: 'ListItemButtonRoot', + slot: 'Root', + overridesResolver, +})(({ theme, styleProps }) => ({ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', @@ -116,7 +122,6 @@ const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiListItemButton' }); const { autoFocus = false, - className, component = 'div', children, alignItems = 'center', @@ -161,15 +166,18 @@ const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) { const handleRef = useForkRef(listItemRef, ref); return ( - - {children} - + + + {children} + + ); }); From 41b248ba34239c6cd82cd8cd2ad0db1b45773584 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 25 May 2021 16:13:50 +0700 Subject: [PATCH 03/61] run proptypes and docs --- docs/pages/api-docs/list-item-button.js | 23 ++++++ docs/pages/api-docs/list-item-button.json | 45 ++++++++++++ docs/src/pagesApi.js | 1 + .../list-item-button/list-item-button-de.json | 58 +++++++++++++++ .../list-item-button/list-item-button-es.json | 58 +++++++++++++++ .../list-item-button/list-item-button-fr.json | 58 +++++++++++++++ .../list-item-button/list-item-button-ja.json | 58 +++++++++++++++ .../list-item-button/list-item-button-pt.json | 58 +++++++++++++++ .../list-item-button/list-item-button-ru.json | 58 +++++++++++++++ .../list-item-button/list-item-button-zh.json | 58 +++++++++++++++ .../list-item-button/list-item-button.json | 58 +++++++++++++++ .../src/ListItemButton/ListItemButton.d.ts | 4 +- .../src/ListItemButton/ListItemButton.js | 72 +++++++++++++++++++ .../src/ListItemButton/ListItemButton.test.js | 28 ++++---- 14 files changed, 621 insertions(+), 16 deletions(-) create mode 100644 docs/pages/api-docs/list-item-button.js create mode 100644 docs/pages/api-docs/list-item-button.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button-de.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button-es.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button-fr.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button-ja.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button-pt.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button-ru.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button-zh.json create mode 100644 docs/translations/api-docs/list-item-button/list-item-button.json diff --git a/docs/pages/api-docs/list-item-button.js b/docs/pages/api-docs/list-item-button.js new file mode 100644 index 00000000000000..a9307d09e55004 --- /dev/null +++ b/docs/pages/api-docs/list-item-button.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './list-item-button.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docs/translations/api-docs/list-item-button', + false, + /list-item-button.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/api-docs/list-item-button.json b/docs/pages/api-docs/list-item-button.json new file mode 100644 index 00000000000000..f25ff8d3172ffc --- /dev/null +++ b/docs/pages/api-docs/list-item-button.json @@ -0,0 +1,45 @@ +{ + "props": { + "alignItems": { + "type": { "name": "enum", "description": "'center'
| 'flex-start'" }, + "default": "'center'" + }, + "autoFocus": { "type": { "name": "bool" } }, + "children": { "type": { "name": "node" } }, + "classes": { "type": { "name": "object" } }, + "component": { "type": { "name": "elementType" } }, + "dense": { "type": { "name": "bool" } }, + "disabled": { "type": { "name": "bool" } }, + "disableGutters": { "type": { "name": "bool" } }, + "divider": { "type": { "name": "bool" } }, + "focusVisibleClassName": { "type": { "name": "string" } }, + "selected": { "type": { "name": "bool" } }, + "sx": { "type": { "name": "object" } } + }, + "name": "ListItemButton", + "styles": { + "classes": [ + "root", + "focusVisible", + "dense", + "alignItemsFlexStart", + "disabled", + "divider", + "gutters", + "selected" + ], + "globalClasses": { + "focusVisible": "Mui-focusVisible", + "disabled": "Mui-disabled", + "selected": "Mui-selected" + }, + "name": "MuiListItemButton" + }, + "spread": true, + "forwardsRefTo": "HTMLDivElement", + "filename": "/packages/material-ui/src/ListItemButton/ListItemButton.js", + "inheritance": null, + "demos": "", + "styledComponent": true, + "cssComponent": false +} diff --git a/docs/src/pagesApi.js b/docs/src/pagesApi.js index d5a1875ce8398d..382f74b16219da 100644 --- a/docs/src/pagesApi.js +++ b/docs/src/pagesApi.js @@ -75,6 +75,7 @@ module.exports = [ { pathname: '/api-docs/list' }, { pathname: '/api-docs/list-item' }, { pathname: '/api-docs/list-item-avatar' }, + { pathname: '/api-docs/list-item-button' }, { pathname: '/api-docs/list-item-icon' }, { pathname: '/api-docs/list-item-secondary-action' }, { pathname: '/api-docs/list-item-text' }, diff --git a/docs/translations/api-docs/list-item-button/list-item-button-de.json b/docs/translations/api-docs/list-item-button/list-item-button-de.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button-de.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/docs/translations/api-docs/list-item-button/list-item-button-es.json b/docs/translations/api-docs/list-item-button/list-item-button-es.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button-es.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/docs/translations/api-docs/list-item-button/list-item-button-fr.json b/docs/translations/api-docs/list-item-button/list-item-button-fr.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button-fr.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/docs/translations/api-docs/list-item-button/list-item-button-ja.json b/docs/translations/api-docs/list-item-button/list-item-button-ja.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button-ja.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/docs/translations/api-docs/list-item-button/list-item-button-pt.json b/docs/translations/api-docs/list-item-button/list-item-button-pt.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button-pt.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/docs/translations/api-docs/list-item-button/list-item-button-ru.json b/docs/translations/api-docs/list-item-button/list-item-button-ru.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button-ru.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/docs/translations/api-docs/list-item-button/list-item-button-zh.json b/docs/translations/api-docs/list-item-button/list-item-button-zh.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button-zh.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/docs/translations/api-docs/list-item-button/list-item-button.json b/docs/translations/api-docs/list-item-button/list-item-button.json new file mode 100644 index 00000000000000..6c46781d58c9b1 --- /dev/null +++ b/docs/translations/api-docs/list-item-button/list-item-button.json @@ -0,0 +1,58 @@ +{ + "componentDescription": "", + "propDescriptions": { + "alignItems": "Defines the align-items style property.", + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", + "children": "The content of the component if a ListItemSecondaryAction is used it must be the last child.", + "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "component": "The component used for the root node. Either a string to use a HTML element or a component.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", + "disabled": "If true, the component is disabled.", + "disableGutters": "If true, the left and right padding is removed.", + "divider": "If true, a 1px light border is added to the bottom of the list item.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", + "selected": "Use to apply selected styling.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." + }, + "classDescriptions": { + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, + "selected": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "selected={true}" + } + } +} diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts index 9e10eab6d03a6a..3d7f0fbee26b89 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts +++ b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts @@ -67,16 +67,14 @@ export type ListItemButtonTypeMap< }>; /** - * Uses an additional container component if `ListItemSecondaryAction` is the last child. * * Demos: * * - [Lists](https://material-ui.com/components/lists/) - * - [Transfer List](https://material-ui.com/components/transfer-list/) * * API: * - * - [ListItemButton API](https://material-ui.com/api/list-item/) + * - [ListItemButton API](https://material-ui.com/api/list-item-button/) */ declare const ListItemButton: ExtendButtonBase; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index 666180df7b8503..d72fb9baba82d0 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -1,4 +1,5 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import clsx from 'clsx'; import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; import { alpha } from '../styles/colorManipulator'; @@ -181,6 +182,77 @@ const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) { ); }); +ListItemButton.propTypes /* remove-proptypes */ = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the d.ts file and run "yarn proptypes" | + // ---------------------------------------------------------------------- + /** + * Defines the `align-items` style property. + * @default 'center' + */ + alignItems: PropTypes.oneOf(['center', 'flex-start']), + /** + * If `true`, the list item is focused during the first mount. + * Focus will also be triggered if the value changes from false to true. + * @default false + */ + autoFocus: PropTypes.bool, + /** + * The content of the component if a `ListItemSecondaryAction` is used it must + * be the last child. + */ + children: PropTypes.node, + /** + * Override or extend the styles applied to the component. + */ + classes: PropTypes.object, + /** + * The component used for the root node. + * Either a string to use a HTML element or a component. + */ + component: PropTypes.elementType, + /** + * If `true`, compact vertical padding designed for keyboard and mouse input is used. + * The prop defaults to the value inherited from the parent List component. + * @default false + */ + dense: PropTypes.bool, + /** + * If `true`, the component is disabled. + * @default false + */ + disabled: PropTypes.bool, + /** + * If `true`, the left and right padding is removed. + * @default false + */ + disableGutters: PropTypes.bool, + /** + * If `true`, a 1px light border is added to the bottom of the list item. + * @default false + */ + divider: PropTypes.bool, + /** + * This prop can help identify which element has keyboard focus. + * The class name will be applied when the element gains the focus through keyboard interaction. + * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo). + * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/master/explainer.md). + * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `focus-visible` class to other components + * if needed. + */ + focusVisibleClassName: PropTypes.string, + /** + * Use to apply selected styling. + * @default false + */ + selected: PropTypes.bool, + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx: PropTypes.object, +}; + ListItemButton.muiName = 'ListItemButton'; export default ListItemButton; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.test.js b/packages/material-ui/src/ListItemButton/ListItemButton.test.js index 32c9c967823015..6e7161de3db096 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.test.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.test.js @@ -1,9 +1,8 @@ import * as React from 'react'; import { expect } from 'chai'; import { createMount, describeConformanceV5, act, createClientRender, fireEvent } from 'test/utils'; -import ListItemText from '@material-ui/core/ListItemText'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemButton, { listItemButtonClasses as classes } from '@material-ui/core/ListItemButton'; +import ListContext from '../List/ListContext'; describe('', () => { const render = createClientRender(); @@ -14,7 +13,7 @@ describe('', () => { inheritComponent: 'div', render, mount, - refInstanceof: window.HTMLLIElement, + refInstanceof: window.HTMLDivElement, muiName: 'MuiListItemButton', testVariantProps: { dense: true }, skip: ['componentsProp'], @@ -35,18 +34,21 @@ describe('', () => { expect(getByRole('button')).not.to.have.class(classes.gutters); }); - describe('secondary action', () => { - it('should accept a component property', () => { - const { getByRole } = render( - - - + describe('context: dense', () => { + it('should forward the context', () => { + let context = null; + const { setProps } = render( + + + {(options) => { + context = options; + }} + , ); - const listItem = getByRole('button'); - - expect(listItem).to.have.class(classes.container); - expect(listItem.querySelector(`span.${classes.root}`)).not.to.equal(null); + expect(context).to.have.property('dense', false); + setProps({ dense: true }); + expect(context).to.have.property('dense', true); }); }); From ae4db46622657032c86e019592f18723fe3359e1 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 25 May 2021 16:20:20 +0700 Subject: [PATCH 04/61] fix typo name --- packages/material-ui/src/ListItemButton/ListItemButton.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index d72fb9baba82d0..e27a4bfa031ef8 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -48,7 +48,7 @@ const useUtilityClasses = (styleProps) => { const ListItemButtonRoot = experimentalStyled(ButtonBase, { shouldForwardProp: (prop) => rootShouldForwardProp(prop) || prop === 'classes', - name: 'ListItemButtonRoot', + name: 'MuiListItemButton', slot: 'Root', overridesResolver, })(({ theme, styleProps }) => ({ From f047a2c31b5facce17b5bfce8e301f1e74ad9967 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 25 May 2021 16:40:10 +0700 Subject: [PATCH 05/61] minor fix --- docs/src/pages/components/lists/lists.md | 2 +- packages/material-ui/src/ListItem/ListItem.js | 6 +++--- .../src/ListItemButton/ListItemButton.d.ts | 14 ++++++-------- .../src/ListItemButton/ListItemButton.js | 1 + packages/material-ui/src/ListItemButton/index.js | 1 - 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/src/pages/components/lists/lists.md b/docs/src/pages/components/lists/lists.md index a32168645697d9..a8691067fea284 100644 --- a/docs/src/pages/components/lists/lists.md +++ b/docs/src/pages/components/lists/lists.md @@ -22,7 +22,7 @@ The last item of the previous demo shows how you can render a link: ```jsx -; + ``` You can find a [demo with React Router following this section](/guides/routing/#list) of the documentation. diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 7f74ee27548454..671e0a29c6bc17 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -35,12 +35,12 @@ export const overridesResolver = (props, styles) => { const useUtilityClasses = (styleProps) => { const { alignItems, + button, classes, dense, + disabled, disableGutters, divider, - disabled, - button, hasSecondaryAction, selected, } = styleProps; @@ -51,9 +51,9 @@ const useUtilityClasses = (styleProps) => { dense && 'dense', !disableGutters && 'gutters', divider && 'divider', - alignItems === 'flex-start' && 'alignItemsFlexStart', disabled && 'disabled', button && 'button', + alignItems === 'flex-start' && 'alignItemsFlexStart', hasSecondaryAction && 'secondaryAction', selected && 'selected', ], diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts index 3d7f0fbee26b89..5996855958dbe6 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts +++ b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts @@ -58,13 +58,11 @@ interface ListItemButtonBaseProps { sx?: SxProps; } -export type ListItemButtonTypeMap< - P = {}, - D extends React.ElementType = 'div' -> = ExtendButtonBaseTypeMap<{ - props: P & ListItemButtonBaseProps; - defaultComponent: D; -}>; +export type ListItemButtonTypeMap

= + ExtendButtonBaseTypeMap<{ + props: P & ListItemButtonBaseProps; + defaultComponent: D; + }>; /** * @@ -80,7 +78,7 @@ declare const ListItemButton: ExtendButtonBase; export type ListItemButtonProps< D extends React.ElementType = ListItemButtonTypeMap['defaultComponent'], - P = {} + P = {}, > = OverrideProps, D>; export default ListItemButton; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index e27a4bfa031ef8..60606eb58d753f 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -160,6 +160,7 @@ const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) { dense: childContext.dense, disableGutters, divider, + selected, }; const classes = useUtilityClasses(styleProps); diff --git a/packages/material-ui/src/ListItemButton/index.js b/packages/material-ui/src/ListItemButton/index.js index 57fdf7f3962ea2..feb9791f4194cc 100644 --- a/packages/material-ui/src/ListItemButton/index.js +++ b/packages/material-ui/src/ListItemButton/index.js @@ -1,5 +1,4 @@ export { default } from './ListItemButton'; -export * from './ListItemButton'; export { default as listItemButtonClasses } from './listItemButtonClasses'; export * from './listItemButtonClasses'; From 8fb85ca108637f47c6a02d08924f0e2729cc538a Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 26 May 2021 11:34:12 +0700 Subject: [PATCH 06/61] mark button related prop as deprecated --- packages/material-ui/src/ListItem/ListItem.d.ts | 8 ++++++++ packages/material-ui/src/ListItem/ListItem.js | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/packages/material-ui/src/ListItem/ListItem.d.ts b/packages/material-ui/src/ListItem/ListItem.d.ts index b28937c763698d..c8d8fbcd42b422 100644 --- a/packages/material-ui/src/ListItem/ListItem.d.ts +++ b/packages/material-ui/src/ListItem/ListItem.d.ts @@ -15,6 +15,7 @@ interface ListItemBaseProps { * If `true`, the list item is focused during the first mount. * Focus will also be triggered if the value changes from false to true. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ autoFocus?: boolean; /** @@ -29,11 +30,13 @@ interface ListItemBaseProps { /** * The container component used when a `ListItemSecondaryAction` is the last child. * @default 'li' + * @deprecated will be removed in v6 */ ContainerComponent?: React.ElementType>; /** * Props applied to the container component if used. * @default {} + * @deprecated will be removed in v6 */ ContainerProps?: React.HTMLAttributes; /** @@ -45,6 +48,7 @@ interface ListItemBaseProps { /** * If `true`, the component is disabled. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ disabled?: boolean; /** @@ -60,6 +64,7 @@ interface ListItemBaseProps { /** * Use to apply selected styling. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ selected?: boolean; /** @@ -114,6 +119,7 @@ declare const ListItem: OverridableComponent< * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ button?: false; }, @@ -127,6 +133,8 @@ declare const ListItem: OverridableComponent< * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false + * @depreacted will be removed in v6, checkout `ListItemButton` instead + * */ button: true; }, diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 671e0a29c6bc17..1de946eec8d8af 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -322,12 +322,14 @@ ListItem.propTypes /* remove-proptypes */ = { * If `true`, the list item is focused during the first mount. * Focus will also be triggered if the value changes from false to true. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ autoFocus: PropTypes.bool, /** * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ button: PropTypes.bool, /** @@ -387,11 +389,13 @@ ListItem.propTypes /* remove-proptypes */ = { /** * The container component used when a `ListItemSecondaryAction` is the last child. * @default 'li' + * @deprecated will be removed in v6 */ ContainerComponent: elementTypeAcceptingRef, /** * Props applied to the container component if used. * @default {} + * @deprecated will be removed in v6 */ ContainerProps: PropTypes.object, /** @@ -403,6 +407,7 @@ ListItem.propTypes /* remove-proptypes */ = { /** * If `true`, the component is disabled. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ disabled: PropTypes.bool, /** @@ -422,6 +427,7 @@ ListItem.propTypes /* remove-proptypes */ = { /** * Use to apply selected styling. * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ selected: PropTypes.bool, /** From 3f46f02dd7b2722d26977ce3fc204d3075b9f079 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 26 May 2021 11:49:50 +0700 Subject: [PATCH 07/61] fix description --- packages/material-ui/src/ListItemButton/ListItemButton.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index 60606eb58d753f..17a8bbf49a6d99 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -98,21 +98,21 @@ const ListItemButtonRoot = experimentalStyled(ButtonBase, { [`&.${listItemButtonClasses.disabled}`]: { opacity: theme.palette.action.disabledOpacity, }, - /* Styles applied to the inner `component` element if `divider={true}`. */ + /* Styles applied to the root element if `divider={true}`. */ ...(styleProps.divider && { borderBottom: `1px solid ${theme.palette.divider}`, backgroundClip: 'padding-box', }), - /* Styles applied to the component element if `alignItems="flex-start"`. */ + /* Styles applied to the root element if `alignItems="flex-start"`. */ ...(styleProps.alignItems === 'flex-start' && { alignItems: 'flex-start', }), - /* Styles applied to the inner `component` element unless `disableGutters={true}`. */ + /* Styles applied to the root element unless `disableGutters={true}`. */ ...(!styleProps.disableGutters && { paddingLeft: 16, paddingRight: 16, }), - /* Styles applied to the component element if dense. */ + /* Styles applied to the root element if dense. */ ...(styleProps.dense && { paddingTop: 4, paddingBottom: 4, From 4f385a9bfc690722308740fe2d35ea4f93c513d0 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 26 May 2021 11:50:09 +0700 Subject: [PATCH 08/61] add usage guide to docs --- .../pages/components/lists/UsageGuideList.js | 61 +++++++++++++++++++ .../pages/components/lists/UsageGuideList.tsx | 61 +++++++++++++++++++ docs/src/pages/components/lists/lists.md | 17 ++++++ 3 files changed, 139 insertions(+) create mode 100644 docs/src/pages/components/lists/UsageGuideList.js create mode 100644 docs/src/pages/components/lists/UsageGuideList.tsx diff --git a/docs/src/pages/components/lists/UsageGuideList.js b/docs/src/pages/components/lists/UsageGuideList.js new file mode 100644 index 00000000000000..3791d980b87368 --- /dev/null +++ b/docs/src/pages/components/lists/UsageGuideList.js @@ -0,0 +1,61 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import IconButton from '@material-ui/core/IconButton'; +import Divider from '@material-ui/core/Divider'; +import InboxIcon from '@material-ui/icons/Inbox'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight'; + +export default function UsageGuideList() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/docs/src/pages/components/lists/UsageGuideList.tsx b/docs/src/pages/components/lists/UsageGuideList.tsx new file mode 100644 index 00000000000000..3791d980b87368 --- /dev/null +++ b/docs/src/pages/components/lists/UsageGuideList.tsx @@ -0,0 +1,61 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import IconButton from '@material-ui/core/IconButton'; +import Divider from '@material-ui/core/Divider'; +import InboxIcon from '@material-ui/icons/Inbox'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight'; + +export default function UsageGuideList() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/docs/src/pages/components/lists/lists.md b/docs/src/pages/components/lists/lists.md index a8691067fea284..9d977c0d5569cc 100644 --- a/docs/src/pages/components/lists/lists.md +++ b/docs/src/pages/components/lists/lists.md @@ -13,6 +13,23 @@ Lists are a continuous group of text or images. They are composed of items conta {{"component": "modules/components/ComponentLinkHeader.js"}} +## Usage Guide + +To have good HTML list markup, always start with `` (render `ul`) and use `` (render `li`) as children for static text. + +If the item needs to be actionable (the whole area of the item), use ``. Take a look at the sample code below about how to insert icon, primary and secondary text, and secondary action. + +For the case of button item + secondary action, wrap `` inside `` + +```jsx + + + + +``` + +{{"demo": "pages/components/lists/UsageGuideList.js", "bg": true}} + ## Simple List {{"demo": "pages/components/lists/SimpleList.js", "bg": true}} From 83eadf9e0c137ba632dc3f457d635de6ee276289 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 26 May 2021 12:31:50 +0700 Subject: [PATCH 09/61] add dense note --- docs/src/pages/components/lists/lists.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/src/pages/components/lists/lists.md b/docs/src/pages/components/lists/lists.md index 9d977c0d5569cc..d671b63b1835cc 100644 --- a/docs/src/pages/components/lists/lists.md +++ b/docs/src/pages/components/lists/lists.md @@ -30,6 +30,21 @@ For the case of button item + secondary action, wrap `` inside ` {{"demo": "pages/components/lists/UsageGuideList.js", "bg": true}} +💡 `List`, `ListItem`, `ListItemButton` accept `dense` prop that reduce the gap and text size. `dense` also inherit from the top level without needing to define in every element. + +```jsx + + // dense applied + // dense applied + + + + + // dense applied + + +``` + ## Simple List {{"demo": "pages/components/lists/SimpleList.js", "bg": true}} From 1678d5308d54fef01bdbd5eee2c02044ba2001a8 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Thu, 27 May 2021 10:45:18 +0700 Subject: [PATCH 10/61] Update docs/src/pages/components/lists/lists.md Co-authored-by: Olivier Tassinari --- docs/src/pages/components/lists/lists.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/components/lists/lists.md b/docs/src/pages/components/lists/lists.md index d671b63b1835cc..1668b4819803d7 100644 --- a/docs/src/pages/components/lists/lists.md +++ b/docs/src/pages/components/lists/lists.md @@ -13,7 +13,7 @@ Lists are a continuous group of text or images. They are composed of items conta {{"component": "modules/components/ComponentLinkHeader.js"}} -## Usage Guide +## Usage guide To have good HTML list markup, always start with `` (render `ul`) and use `` (render `li`) as children for static text. From 43a0f75e67c503f76b2f5520c1fcd53cd66eed0c Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 10:59:07 +0700 Subject: [PATCH 11/61] add `action` prop and update demos --- .../pages/components/lists/CheckboxList.tsx | 16 ++++++----- .../lists/CheckboxListSecondary.tsx | 26 ++++++++++-------- .../pages/components/lists/GutterlessList.tsx | 12 +++++---- .../components/lists/InteractiveList.tsx | 14 +++++----- .../pages/components/lists/UsageGuideList.tsx | 27 ++++++++++--------- .../transitions/TransitionGroupExample.tsx | 10 +++---- .../material-ui/src/ListItem/ListItem.d.ts | 4 +++ packages/material-ui/src/ListItem/ListItem.js | 17 +++++++----- .../material-ui/src/ListItem/ListItem.test.js | 9 +++++++ 9 files changed, 81 insertions(+), 54 deletions(-) diff --git a/docs/src/pages/components/lists/CheckboxList.tsx b/docs/src/pages/components/lists/CheckboxList.tsx index 18c6b6acd64bdd..8191bb179fa6ad 100644 --- a/docs/src/pages/components/lists/CheckboxList.tsx +++ b/docs/src/pages/components/lists/CheckboxList.tsx @@ -3,7 +3,6 @@ import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import Checkbox from '@material-ui/core/Checkbox'; import IconButton from '@material-ui/core/IconButton'; @@ -31,7 +30,15 @@ export default function CheckboxList() { const labelId = `checkbox-list-label-${value}`; return ( - + + + + } + > - - - - - ); })} diff --git a/docs/src/pages/components/lists/CheckboxListSecondary.tsx b/docs/src/pages/components/lists/CheckboxListSecondary.tsx index b08876460548bd..efafd6b20af45e 100644 --- a/docs/src/pages/components/lists/CheckboxListSecondary.tsx +++ b/docs/src/pages/components/lists/CheckboxListSecondary.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemText from '@material-ui/core/ListItemText'; import ListItemAvatar from '@material-ui/core/ListItemAvatar'; import Checkbox from '@material-ui/core/Checkbox'; @@ -28,22 +28,26 @@ export default function CheckboxListSecondary() { {[0, 1, 2, 3].map((value) => { const labelId = `checkbox-list-secondary-label-${value}`; return ( - - - - - - + - + } + > + + + + + + ); })} diff --git a/docs/src/pages/components/lists/GutterlessList.tsx b/docs/src/pages/components/lists/GutterlessList.tsx index 778869d08ee37b..0c6d3fedfe92fd 100644 --- a/docs/src/pages/components/lists/GutterlessList.tsx +++ b/docs/src/pages/components/lists/GutterlessList.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import CommentIcon from '@material-ui/icons/Comment'; import IconButton from '@material-ui/core/IconButton'; @@ -10,13 +9,16 @@ export default function GutterlessList() { return ( {[1, 2, 3].map((value) => ( - - - + - + } + > + ))} diff --git a/docs/src/pages/components/lists/InteractiveList.tsx b/docs/src/pages/components/lists/InteractiveList.tsx index 64f55d4132eb7f..77e5c56246bc4f 100644 --- a/docs/src/pages/components/lists/InteractiveList.tsx +++ b/docs/src/pages/components/lists/InteractiveList.tsx @@ -5,7 +5,6 @@ import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemAvatar from '@material-ui/core/ListItemAvatar'; import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import Avatar from '@material-ui/core/Avatar'; import IconButton from '@material-ui/core/IconButton'; @@ -124,7 +123,13 @@ export default function InteractiveList() { {generate( - + + + + } + > @@ -134,11 +139,6 @@ export default function InteractiveList() { primary="Single-line item" secondary={secondary ? 'Secondary text' : null} /> - - - - - , )} diff --git a/docs/src/pages/components/lists/UsageGuideList.tsx b/docs/src/pages/components/lists/UsageGuideList.tsx index 3791d980b87368..c30357288bd36f 100644 --- a/docs/src/pages/components/lists/UsageGuideList.tsx +++ b/docs/src/pages/components/lists/UsageGuideList.tsx @@ -5,7 +5,6 @@ import ListItem from '@material-ui/core/ListItem'; import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import IconButton from '@material-ui/core/IconButton'; import Divider from '@material-ui/core/Divider'; import InboxIcon from '@material-ui/icons/Inbox'; @@ -16,16 +15,17 @@ export default function UsageGuideList() { return ( - + + + + } + > - - - - - @@ -45,15 +45,16 @@ export default function UsageGuideList() { - - - - - + - + } + > + + + diff --git a/docs/src/pages/components/transitions/TransitionGroupExample.tsx b/docs/src/pages/components/transitions/TransitionGroupExample.tsx index 4a99ecfae1d6f4..9d3cf01b5c5896 100644 --- a/docs/src/pages/components/transitions/TransitionGroupExample.tsx +++ b/docs/src/pages/components/transitions/TransitionGroupExample.tsx @@ -5,7 +5,6 @@ import Collapse from '@material-ui/core/Collapse'; import IconButton from '@material-ui/core/IconButton'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import DeleteIcon from '@material-ui/icons/Delete'; import { TransitionGroup } from 'react-transition-group'; @@ -25,9 +24,8 @@ interface RenderItemOptions { function renderItem({ item, handleRemoveFruit }: RenderItemOptions) { return ( - - - + - + } + > + ); } diff --git a/packages/material-ui/src/ListItem/ListItem.d.ts b/packages/material-ui/src/ListItem/ListItem.d.ts index c8d8fbcd42b422..7ed31f6394d58e 100644 --- a/packages/material-ui/src/ListItem/ListItem.d.ts +++ b/packages/material-ui/src/ListItem/ListItem.d.ts @@ -61,6 +61,10 @@ interface ListItemBaseProps { * @default false */ divider?: boolean; + /** + * The action to display at the end of ListItem. + */ + action?: React.ReactNode; /** * Use to apply selected styling. * @default false diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 1de946eec8d8af..bedbf1dd09f10e 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -13,6 +13,7 @@ import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; import listItemClasses, { getListItemUtilityClass } from './listItemClasses'; import { listItemButtonClasses } from '../ListItemButton'; +import ListItemSecondaryAction from '../ListItemSecondaryAction'; // TODO remove these in v6 // - button related (styling and logic) like autoFocus, focusVisible, disabled @@ -141,12 +142,11 @@ export const ListItemRoot = experimentalStyled('div', { }, }), /* Styles applied to the component element if `children` includes `ListItemSecondaryAction`. */ - ...(!styleProps.hasListItemButton && - styleProps.hasSecondaryAction && { - // Add some space to avoid collision as `ListItemSecondaryAction` - // is absolutely positioned. - paddingRight: 48, - }), + ...((styleProps.hasSecondaryAction || !!styleProps.action) && { + // Add some space to avoid collision as `ListItemSecondaryAction` + // is absolutely positioned. + paddingRight: 48, + }), ...(styleProps.hasListItemButton && styleProps.hasSecondaryAction && { [`& > .${listItemButtonClasses.root}`]: { @@ -169,6 +169,7 @@ const ListItemContainer = experimentalStyled('li', { const ListItem = React.forwardRef(function ListItem(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiListItem' }); const { + action, alignItems = 'center', autoFocus = false, button = false, @@ -209,6 +210,8 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { }, [autoFocus]); const children = React.Children.toArray(childrenProp); + + // v4 implementation, deprecated in v5, will be removed in v6 const hasSecondaryAction = children.length && isMuiElement(children[children.length - 1], ['ListItemSecondaryAction']); const hasListItemButton = children.some((child) => isMuiElement(child, ['ListItemButton'])); @@ -252,6 +255,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { Component = ButtonBase; } + // v4 implementation, deprecated in v5, will be removed in v6 if (hasSecondaryAction) { // Use div by default. Component = !componentProps.component && !componentProp ? 'div' : Component; @@ -303,6 +307,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { {...componentProps} > {children} + {action && {action}} ); diff --git a/packages/material-ui/src/ListItem/ListItem.test.js b/packages/material-ui/src/ListItem/ListItem.test.js index febe8cfaa5dd6e..0d7919b681bc5c 100644 --- a/packages/material-ui/src/ListItem/ListItem.test.js +++ b/packages/material-ui/src/ListItem/ListItem.test.js @@ -74,6 +74,14 @@ describe('', () => { }); }); + describe('action', () => { + it('should show action if provided', () => { + const { getByText } = render(); + expect(getByText('foo')).toBeVisible(); + }); + }); + + // TODO remove in v6 in favor of ListItemButton describe('secondary action', () => { it('should wrap with a container', () => { const { getByRole } = render( @@ -188,6 +196,7 @@ describe('', () => { }); }); + // TODO remove in v6 in favor of ListItemButton describe('prop: focusVisibleClassName', () => { it('should merge the class names', () => { const { getByRole } = render( From aeb3eb37e9e6308a5d278df806294881cd72c9ea Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 11:05:19 +0700 Subject: [PATCH 12/61] run proptypes, docs:api, docs:typescript --- docs/pages/api-docs/list-item.json | 6 +++++ .../pages/components/lists/CheckboxList.js | 16 ++++++----- .../components/lists/CheckboxListSecondary.js | 26 ++++++++++-------- .../pages/components/lists/GutterlessList.js | 12 +++++---- .../pages/components/lists/InteractiveList.js | 14 +++++----- .../pages/components/lists/UsageGuideList.js | 27 ++++++++++--------- .../transitions/TransitionGroupExample.js | 10 +++---- .../api-docs/list-item/list-item.json | 1 + packages/material-ui/src/ListItem/ListItem.js | 12 +++++++++ 9 files changed, 76 insertions(+), 48 deletions(-) diff --git a/docs/pages/api-docs/list-item.json b/docs/pages/api-docs/list-item.json index 375c4260553304..f41811c647b4c0 100644 --- a/docs/pages/api-docs/list-item.json +++ b/docs/pages/api-docs/list-item.json @@ -1,5 +1,11 @@ { "props": { + "action": { + "type": { + "name": "union", + "description": "node
| func
| { current?: { focusVisible: func } }" + } + }, "alignItems": { "type": { "name": "enum", "description": "'center'
| 'flex-start'" }, "default": "'center'" diff --git a/docs/src/pages/components/lists/CheckboxList.js b/docs/src/pages/components/lists/CheckboxList.js index bf81516335886e..fba0c7ff55ffd7 100644 --- a/docs/src/pages/components/lists/CheckboxList.js +++ b/docs/src/pages/components/lists/CheckboxList.js @@ -3,7 +3,6 @@ import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import Checkbox from '@material-ui/core/Checkbox'; import IconButton from '@material-ui/core/IconButton'; @@ -31,7 +30,15 @@ export default function CheckboxList() { const labelId = `checkbox-list-label-${value}`; return ( - + + + + } + > - - - - - ); })} diff --git a/docs/src/pages/components/lists/CheckboxListSecondary.js b/docs/src/pages/components/lists/CheckboxListSecondary.js index d2752922a66a79..4c1baae9845b92 100644 --- a/docs/src/pages/components/lists/CheckboxListSecondary.js +++ b/docs/src/pages/components/lists/CheckboxListSecondary.js @@ -1,7 +1,7 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemText from '@material-ui/core/ListItemText'; import ListItemAvatar from '@material-ui/core/ListItemAvatar'; import Checkbox from '@material-ui/core/Checkbox'; @@ -28,22 +28,26 @@ export default function CheckboxListSecondary() { {[0, 1, 2, 3].map((value) => { const labelId = `checkbox-list-secondary-label-${value}`; return ( - - - - - - + - + } + > + + + + + + ); })} diff --git a/docs/src/pages/components/lists/GutterlessList.js b/docs/src/pages/components/lists/GutterlessList.js index 778869d08ee37b..0c6d3fedfe92fd 100644 --- a/docs/src/pages/components/lists/GutterlessList.js +++ b/docs/src/pages/components/lists/GutterlessList.js @@ -1,7 +1,6 @@ import * as React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import CommentIcon from '@material-ui/icons/Comment'; import IconButton from '@material-ui/core/IconButton'; @@ -10,13 +9,16 @@ export default function GutterlessList() { return ( {[1, 2, 3].map((value) => ( - - - + - + } + > + ))} diff --git a/docs/src/pages/components/lists/InteractiveList.js b/docs/src/pages/components/lists/InteractiveList.js index d814bcf837008b..1efcae8d197343 100644 --- a/docs/src/pages/components/lists/InteractiveList.js +++ b/docs/src/pages/components/lists/InteractiveList.js @@ -5,7 +5,6 @@ import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemAvatar from '@material-ui/core/ListItemAvatar'; import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import Avatar from '@material-ui/core/Avatar'; import IconButton from '@material-ui/core/IconButton'; @@ -124,7 +123,13 @@ export default function InteractiveList() { {generate( - + + + + } + > @@ -134,11 +139,6 @@ export default function InteractiveList() { primary="Single-line item" secondary={secondary ? 'Secondary text' : null} /> - - - - - , )} diff --git a/docs/src/pages/components/lists/UsageGuideList.js b/docs/src/pages/components/lists/UsageGuideList.js index 3791d980b87368..c30357288bd36f 100644 --- a/docs/src/pages/components/lists/UsageGuideList.js +++ b/docs/src/pages/components/lists/UsageGuideList.js @@ -5,7 +5,6 @@ import ListItem from '@material-ui/core/ListItem'; import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import IconButton from '@material-ui/core/IconButton'; import Divider from '@material-ui/core/Divider'; import InboxIcon from '@material-ui/icons/Inbox'; @@ -16,16 +15,17 @@ export default function UsageGuideList() { return ( - + + + + } + > - - - - - @@ -45,15 +45,16 @@ export default function UsageGuideList() { - - - - - + - + } + > + + + diff --git a/docs/src/pages/components/transitions/TransitionGroupExample.js b/docs/src/pages/components/transitions/TransitionGroupExample.js index a8cab244792515..4eb6869aa1ba1d 100644 --- a/docs/src/pages/components/transitions/TransitionGroupExample.js +++ b/docs/src/pages/components/transitions/TransitionGroupExample.js @@ -5,7 +5,6 @@ import Collapse from '@material-ui/core/Collapse'; import IconButton from '@material-ui/core/IconButton'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import DeleteIcon from '@material-ui/icons/Delete'; import { TransitionGroup } from 'react-transition-group'; @@ -20,9 +19,8 @@ const FRUITS = [ function renderItem({ item, handleRemoveFruit }) { return ( - - - + - + } + > + ); } diff --git a/docs/translations/api-docs/list-item/list-item.json b/docs/translations/api-docs/list-item/list-item.json index fdccfcfb9d1e60..f545572ae550ad 100644 --- a/docs/translations/api-docs/list-item/list-item.json +++ b/docs/translations/api-docs/list-item/list-item.json @@ -1,6 +1,7 @@ { "componentDescription": "Uses an additional container component if `ListItemSecondaryAction` is the last child.", "propDescriptions": { + "action": "The action to display at the end of ListItem.", "alignItems": "Defines the align-items style property.", "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", "button": "If true, the list item is a button (using ButtonBase). Props intended for ButtonBase can then be applied to ListItem.", diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index bedbf1dd09f10e..4728ff9aae3c43 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -318,6 +318,18 @@ ListItem.propTypes /* remove-proptypes */ = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- + /** + * The action to display at the end of ListItem. + */ + action: PropTypes.oneOfType([ + PropTypes.node, + PropTypes.func, + PropTypes.shape({ + current: PropTypes.shape({ + focusVisible: PropTypes.func.isRequired, + }), + }), + ]), /** * Defines the `align-items` style property. * @default 'center' From 4edef7d3daa5a04db846136bc601ce644970816b Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 14:17:41 +0700 Subject: [PATCH 13/61] add customized demo and theme component props --- .../pages/components/lists/CustomizedList.js | 196 ++++++++++++++++++ .../pages/components/lists/CustomizedList.tsx | 196 ++++++++++++++++++ .../pages/components/lists/UsageGuideList.js | 62 ------ .../pages/components/lists/UsageGuideList.tsx | 62 ------ docs/src/pages/components/lists/lists.md | 39 +--- packages/material-ui/src/ListItem/ListItem.js | 48 +++-- .../src/ListItemButton/ListItemButton.js | 2 +- .../material-ui/src/styles/components.d.ts | 4 + .../material-ui/src/styles/overrides.d.ts | 2 + packages/material-ui/src/styles/props.d.ts | 2 + 10 files changed, 434 insertions(+), 179 deletions(-) create mode 100644 docs/src/pages/components/lists/CustomizedList.js create mode 100644 docs/src/pages/components/lists/CustomizedList.tsx delete mode 100644 docs/src/pages/components/lists/UsageGuideList.js delete mode 100644 docs/src/pages/components/lists/UsageGuideList.tsx diff --git a/docs/src/pages/components/lists/CustomizedList.js b/docs/src/pages/components/lists/CustomizedList.js new file mode 100644 index 00000000000000..bb71db2a24aea3 --- /dev/null +++ b/docs/src/pages/components/lists/CustomizedList.js @@ -0,0 +1,196 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import { + experimentalStyled as styled, + ThemeProvider, + createTheme, +} from '@material-ui/core/styles'; +import Divider from '@material-ui/core/Divider'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Paper from '@material-ui/core/Paper'; +import IconButton from '@material-ui/core/IconButton'; + +import ArrowRight from '@material-ui/icons/ArrowRight'; +import KeyboardArrowDown from '@material-ui/icons/KeyboardArrowDown'; +import Home from '@material-ui/icons/Home'; +import Settings from '@material-ui/icons/Settings'; +import People from '@material-ui/icons/People'; +import PermMedia from '@material-ui/icons/PermMedia'; +import Dns from '@material-ui/icons/Dns'; +import Public from '@material-ui/icons/Public'; + +const data = [ + { icon: , label: 'Authentication' }, + { icon: , label: 'Database' }, + { icon: , label: 'Storage' }, + { icon: , label: 'Hosting' }, +]; + +const FireNav = styled(List)({ + '& .MuiListItem-root, .MuiListItemButton-root': { + paddingLeft: 24, + paddingRight: 24, + }, + '& .MuiListItemIcon-root': { + minWidth: 0, + marginRight: 16, + }, + '& .MuiSvgIcon-root': { + fontSize: 20, + }, +}); + +export default function CustomizedList() { + const [open, setOpen] = React.useState(false); + return ( + + + + + + 🔥 + + + + + + + + } + > + + + + + + + + + + setOpen(!open)} + sx={{ + px: 3, + pt: 2.5, + pb: open ? 0 : 2.5, + '&:hover': { '& svg': { opacity: open ? 1 : 0 } }, + }} + > + + + + {open && + data.map((item) => ( + + + {item.icon} + + + + ))} + + + + + + ); +} diff --git a/docs/src/pages/components/lists/CustomizedList.tsx b/docs/src/pages/components/lists/CustomizedList.tsx new file mode 100644 index 00000000000000..fa0ddee2c6ee09 --- /dev/null +++ b/docs/src/pages/components/lists/CustomizedList.tsx @@ -0,0 +1,196 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import { + experimentalStyled as styled, + ThemeProvider, + createTheme, +} from '@material-ui/core/styles'; +import Divider from '@material-ui/core/Divider'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemButton from '@material-ui/core/ListItemButton'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Paper from '@material-ui/core/Paper'; +import IconButton from '@material-ui/core/IconButton'; + +import ArrowRight from '@material-ui/icons/ArrowRight'; +import KeyboardArrowDown from '@material-ui/icons/KeyboardArrowDown'; +import Home from '@material-ui/icons/Home'; +import Settings from '@material-ui/icons/Settings'; +import People from '@material-ui/icons/People'; +import PermMedia from '@material-ui/icons/PermMedia'; +import Dns from '@material-ui/icons/Dns'; +import Public from '@material-ui/icons/Public'; + +const data = [ + { icon: , label: 'Authentication' }, + { icon: , label: 'Database' }, + { icon: , label: 'Storage' }, + { icon: , label: 'Hosting' }, +]; + +const FireNav = styled(List)<{ component?: React.ElementType }>({ + '& .MuiListItem-root, .MuiListItemButton-root': { + paddingLeft: 24, + paddingRight: 24, + }, + '& .MuiListItemIcon-root': { + minWidth: 0, + marginRight: 16, + }, + '& .MuiSvgIcon-root': { + fontSize: 20, + }, +}); + +export default function CustomizedList() { + const [open, setOpen] = React.useState(false); + return ( + + + + + + 🔥 + + + + + + + + } + > + + + + + + + + + + setOpen(!open)} + sx={{ + px: 3, + pt: 2.5, + pb: open ? 0 : 2.5, + '&:hover': { '& svg': { opacity: open ? 1 : 0 } }, + }} + > + + + + {open && + data.map((item) => ( + + + {item.icon} + + + + ))} + + + + + + ); +} diff --git a/docs/src/pages/components/lists/UsageGuideList.js b/docs/src/pages/components/lists/UsageGuideList.js deleted file mode 100644 index c30357288bd36f..00000000000000 --- a/docs/src/pages/components/lists/UsageGuideList.js +++ /dev/null @@ -1,62 +0,0 @@ -import * as React from 'react'; -import Box from '@material-ui/core/Box'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemButton from '@material-ui/core/ListItemButton'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import IconButton from '@material-ui/core/IconButton'; -import Divider from '@material-ui/core/Divider'; -import InboxIcon from '@material-ui/icons/Inbox'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; -import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight'; - -export default function UsageGuideList() { - return ( - - - - - - } - > - - - - - - - - - - - - - - - - - - - - - - - } - > - - - - - - - ); -} diff --git a/docs/src/pages/components/lists/UsageGuideList.tsx b/docs/src/pages/components/lists/UsageGuideList.tsx deleted file mode 100644 index c30357288bd36f..00000000000000 --- a/docs/src/pages/components/lists/UsageGuideList.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import * as React from 'react'; -import Box from '@material-ui/core/Box'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemButton from '@material-ui/core/ListItemButton'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import IconButton from '@material-ui/core/IconButton'; -import Divider from '@material-ui/core/Divider'; -import InboxIcon from '@material-ui/icons/Inbox'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; -import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight'; - -export default function UsageGuideList() { - return ( - - - - - - } - > - - - - - - - - - - - - - - - - - - - - - - - } - > - - - - - - - ); -} diff --git a/docs/src/pages/components/lists/lists.md b/docs/src/pages/components/lists/lists.md index 1668b4819803d7..7df8ef69ced13d 100644 --- a/docs/src/pages/components/lists/lists.md +++ b/docs/src/pages/components/lists/lists.md @@ -13,38 +13,6 @@ Lists are a continuous group of text or images. They are composed of items conta {{"component": "modules/components/ComponentLinkHeader.js"}} -## Usage guide - -To have good HTML list markup, always start with `` (render `ul`) and use `` (render `li`) as children for static text. - -If the item needs to be actionable (the whole area of the item), use ``. Take a look at the sample code below about how to insert icon, primary and secondary text, and secondary action. - -For the case of button item + secondary action, wrap `` inside `` - -```jsx - - - - -``` - -{{"demo": "pages/components/lists/UsageGuideList.js", "bg": true}} - -💡 `List`, `ListItem`, `ListItemButton` accept `dense` prop that reduce the gap and text size. `dense` also inherit from the top level without needing to define in every element. - -```jsx - - // dense applied - // dense applied - - - - - // dense applied - - -``` - ## Simple List {{"demo": "pages/components/lists/SimpleList.js", "bg": true}} @@ -134,6 +102,13 @@ Virtualization helps with performance issues. The use of [react-window](https://github.com/bvaughn/react-window) when possible is encouraged. If this library doesn't cover your use case, you should consider using [react-virtualized](https://github.com/bvaughn/react-virtualized), then alternatives like [react-virtuoso](https://github.com/petyosi/react-virtuoso). +## Customized List + +Here are some examples of customizing the component. You can learn more about this in the +[overrides documentation page](/customization/how-to-customize/). + +{{"demo": "pages/components/lists/CustomizedList.js"}} + ## Customization 🎨 If you are looking for inspiration, you can check [MUI Treasury's customization examples](https://mui-treasury.com/styles/list-item). diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 4728ff9aae3c43..3e2d5d35261546 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -77,10 +77,24 @@ export const ListItemRoot = experimentalStyled('div', { width: '100%', boxSizing: 'border-box', textAlign: 'left', - ...(!styleProps.hasListItemButton && { - paddingTop: 8, - paddingBottom: 8, - }), + paddingTop: 8, + paddingBottom: 8, + [`& .${listItemButtonClasses.root}`]: { + marginTop: -8, + marginBottom: -8, + ...(styleProps.dense && { + marginTop: -4, + marginBottom: -4, + }), + ...(!styleProps.disableGutters && { + marginLeft: -16, + marginRight: -16, + }), + ...(styleProps.action && { + marginRight: -48, + paddingRight: 48, + }), + }, [`&.${listItemClasses.focusVisible}`]: { backgroundColor: theme.palette.action.focus, }, @@ -97,11 +111,10 @@ export const ListItemRoot = experimentalStyled('div', { opacity: theme.palette.action.disabledOpacity, }, /* Styles applied to the component element if dense. */ - ...(!styleProps.hasListItemButton && - styleProps.dense && { - paddingTop: 4, - paddingBottom: 4, - }), + ...(styleProps.dense && { + paddingTop: 4, + paddingBottom: 4, + }), /* Styles applied to the component element if `alignItems="flex-start"`. */ ...(styleProps.alignItems === 'flex-start' && { alignItems: 'flex-start', @@ -112,11 +125,10 @@ export const ListItemRoot = experimentalStyled('div', { backgroundClip: 'padding-box', }), /* Styles applied to the inner `component` element unless `disableGutters={true}`. */ - ...(!styleProps.hasListItemButton && - !styleProps.disableGutters && { - paddingLeft: 16, - paddingRight: 16, - }), + ...(!styleProps.disableGutters && { + paddingLeft: 16, + paddingRight: 16, + }), /* Styles applied to the inner `component` element if `button={true}`. */ ...(styleProps.button && { transition: theme.transitions.create('background-color', { @@ -147,12 +159,6 @@ export const ListItemRoot = experimentalStyled('div', { // is absolutely positioned. paddingRight: 48, }), - ...(styleProps.hasListItemButton && - styleProps.hasSecondaryAction && { - [`& > .${listItemButtonClasses.root}`]: { - paddingRight: 48, - }, - }), })); const ListItemContainer = experimentalStyled('li', { @@ -214,7 +220,6 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { // v4 implementation, deprecated in v5, will be removed in v6 const hasSecondaryAction = children.length && isMuiElement(children[children.length - 1], ['ListItemSecondaryAction']); - const hasListItemButton = children.some((child) => isMuiElement(child, ['ListItemButton'])); const styleProps = { ...props, @@ -226,7 +231,6 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { disableGutters, divider, hasSecondaryAction, - hasListItemButton, selected, }; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index 17a8bbf49a6d99..ab07f973605f73 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -53,11 +53,11 @@ const ListItemButtonRoot = experimentalStyled(ButtonBase, { overridesResolver, })(({ theme, styleProps }) => ({ display: 'flex', + flexGrow: 1, justifyContent: 'flex-start', alignItems: 'center', position: 'relative', textDecoration: 'none', - width: '100%', boxSizing: 'border-box', textAlign: 'left', paddingTop: 8, diff --git a/packages/material-ui/src/styles/components.d.ts b/packages/material-ui/src/styles/components.d.ts index 079fa4a86db933..3b763612e59cbf 100644 --- a/packages/material-ui/src/styles/components.d.ts +++ b/packages/material-ui/src/styles/components.d.ts @@ -250,6 +250,10 @@ export interface Components { defaultProps?: ComponentsProps['MuiListItem']; styleOverrides?: ComponentsOverrides['MuiListItem']; }; + MuiListItemButton?: { + defaultProps?: ComponentsProps['MuiListItemButton']; + styleOverrides?: ComponentsOverrides['MuiListItemButton']; + }; MuiListItemAvatar?: { defaultProps?: ComponentsProps['MuiListItemAvatar']; styleOverrides?: ComponentsOverrides['MuiListItemAvatar']; diff --git a/packages/material-ui/src/styles/overrides.d.ts b/packages/material-ui/src/styles/overrides.d.ts index ad2e4f191255a2..31ad8ba9ce09f5 100644 --- a/packages/material-ui/src/styles/overrides.d.ts +++ b/packages/material-ui/src/styles/overrides.d.ts @@ -57,6 +57,7 @@ import { LinkClassKey } from '../Link'; import { ListClassKey } from '../List'; import { ListItemAvatarClassKey } from '../ListItemAvatar'; import { ListItemClassKey } from '../ListItem'; +import { ListItemButtonClassKey } from '../ListItemButton'; import { ListItemIconClassKey } from '../ListItemIcon'; import { ListItemSecondaryActionClassKey } from '../ListItemSecondaryAction'; import { ListItemTextClassKey } from '../ListItemText'; @@ -181,6 +182,7 @@ export interface ComponentNameToClassKey { MuiLink: LinkClassKey; MuiList: ListClassKey; MuiListItem: ListItemClassKey; + MuiListItemButton: ListItemButtonClassKey; MuiListItemAvatar: ListItemAvatarClassKey; MuiListItemIcon: ListItemIconClassKey; MuiListItemSecondaryAction: ListItemSecondaryActionClassKey; diff --git a/packages/material-ui/src/styles/props.d.ts b/packages/material-ui/src/styles/props.d.ts index 1457e0eee7f543..543e5bbbf60384 100644 --- a/packages/material-ui/src/styles/props.d.ts +++ b/packages/material-ui/src/styles/props.d.ts @@ -57,6 +57,7 @@ import { LinkProps } from '../Link'; import { ListItemAvatarProps } from '../ListItemAvatar'; import { ListItemIconProps } from '../ListItemIcon'; import { ListItemProps } from '../ListItem'; +import { ListItemButtonProps } from '../ListItemButton'; import { ListItemSecondaryActionProps } from '../ListItemSecondaryAction'; import { ListItemTextProps } from '../ListItemText'; import { ListProps } from '../List'; @@ -177,6 +178,7 @@ export interface ComponentsPropsList { MuiLink: LinkProps; MuiList: ListProps; MuiListItem: ListItemProps; + MuiListItemButton: ListItemButtonProps; MuiListItemAvatar: ListItemAvatarProps; MuiListItemIcon: ListItemIconProps; MuiListItemSecondaryAction: ListItemSecondaryActionProps; From 4f931d0252bc193713ccf34e31b6305af05aa68b Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 14:28:48 +0700 Subject: [PATCH 14/61] update demo --- .../pages/components/lists/CustomizedList.js | 74 +++++++++---------- .../pages/components/lists/CustomizedList.tsx | 72 +++++++++--------- 2 files changed, 69 insertions(+), 77 deletions(-) diff --git a/docs/src/pages/components/lists/CustomizedList.js b/docs/src/pages/components/lists/CustomizedList.js index bb71db2a24aea3..906e733a755496 100644 --- a/docs/src/pages/components/lists/CustomizedList.js +++ b/docs/src/pages/components/lists/CustomizedList.js @@ -7,7 +7,7 @@ import { } from '@material-ui/core/styles'; import Divider from '@material-ui/core/Divider'; import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; + import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; @@ -79,43 +79,8 @@ export default function CustomizedList() { /> - - - - - } - > - + + @@ -128,7 +93,38 @@ export default function CustomizedList() { }} /> - + + + + + - - - - - } - > - + + @@ -128,7 +93,38 @@ export default function CustomizedList() { }} /> - + + + + + Date: Thu, 3 Jun 2021 17:10:17 +0700 Subject: [PATCH 15/61] refactor ListItem.d.ts --- docs/pages/api-docs/list-item.json | 7 +- framer/Material-UI.framerfx/code/ListItem.tsx | 6 + .../material-ui/src/ListItem/ListItem.d.ts | 229 ++++++++---------- packages/material-ui/src/ListItem/ListItem.js | 18 +- .../src/ListItem/ListItem.spec.tsx | 22 +- packages/material-ui/src/MenuItem/MenuItem.js | 2 +- 6 files changed, 130 insertions(+), 154 deletions(-) diff --git a/docs/pages/api-docs/list-item.json b/docs/pages/api-docs/list-item.json index f41811c647b4c0..320606c594e168 100644 --- a/docs/pages/api-docs/list-item.json +++ b/docs/pages/api-docs/list-item.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "node
| func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "node" } }, "alignItems": { "type": { "name": "enum", "description": "'center'
| 'flex-start'" }, "default": "'center'" diff --git a/framer/Material-UI.framerfx/code/ListItem.tsx b/framer/Material-UI.framerfx/code/ListItem.tsx index e1fedabe321086..4bbe4924047d44 100644 --- a/framer/Material-UI.framerfx/code/ListItem.tsx +++ b/framer/Material-UI.framerfx/code/ListItem.tsx @@ -12,6 +12,7 @@ import { Icon } from './Icon'; import { IconButton } from './IconButton'; interface Props { + action?: node | func | shape; alignItems: 'center' | 'flex-start'; autoFocus: boolean; button: boolean; @@ -133,6 +134,11 @@ ListItem.defaultProps = { }; addPropertyControls(ListItem, { + action: { + type: ControlType.Union, + title: 'Action', + options: [node, func, shape], + }, alignItems: { type: ControlType.Enum, title: 'Align items', diff --git a/packages/material-ui/src/ListItem/ListItem.d.ts b/packages/material-ui/src/ListItem/ListItem.d.ts index 7ed31f6394d58e..f72fb037735846 100644 --- a/packages/material-ui/src/ListItem/ListItem.d.ts +++ b/packages/material-ui/src/ListItem/ListItem.d.ts @@ -1,106 +1,107 @@ import * as React from 'react'; import { SxProps } from '@material-ui/system'; import { Theme } from '@material-ui/core/styles'; -import { ExtendButtonBase } from '../ButtonBase'; +import { ButtonBaseTypeMap } from '../ButtonBase'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; import { ListItemClasses } from './listItemClasses'; -interface ListItemBaseProps { - /** - * Defines the `align-items` style property. - * @default 'center' - */ - alignItems?: 'flex-start' | 'center'; - /** - * If `true`, the list item is focused during the first mount. - * Focus will also be triggered if the value changes from false to true. - * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead - */ - autoFocus?: boolean; - /** - * The content of the component if a `ListItemSecondaryAction` is used it must - * be the last child. - */ - children?: React.ReactNode; - /** - * Override or extend the styles applied to the component. - */ - classes?: Partial; - /** - * The container component used when a `ListItemSecondaryAction` is the last child. - * @default 'li' - * @deprecated will be removed in v6 - */ - ContainerComponent?: React.ElementType>; - /** - * Props applied to the container component if used. - * @default {} - * @deprecated will be removed in v6 - */ - ContainerProps?: React.HTMLAttributes; - /** - * If `true`, compact vertical padding designed for keyboard and mouse input is used. - * The prop defaults to the value inherited from the parent List component. - * @default false - */ - dense?: boolean; - /** - * If `true`, the component is disabled. - * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead - */ - disabled?: boolean; - /** - * If `true`, the left and right padding is removed. - * @default false - */ - disableGutters?: boolean; - /** - * If `true`, a 1px light border is added to the bottom of the list item. - * @default false - */ - divider?: boolean; - /** - * The action to display at the end of ListItem. - */ - action?: React.ReactNode; - /** - * Use to apply selected styling. - * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead - */ - selected?: boolean; - /** - * The system prop that allows defining system overrides as well as additional CSS styles. - */ - sx?: SxProps; -} - -export interface ListItemTypeMap { - props: P & - ListItemBaseProps & { - /** - * The components used for each slot inside the InputBase. - * Either a string to use a HTML element or a component. - * @default {} - */ - components?: { - Root?: React.ElementType; - }; - /** - * The props used for each slot inside the Input. - * @default {} - */ - componentsProps?: { - root?: { - as: React.ElementType; - styleProps?: Omit & { - dense?: boolean; - }; - }; +export interface ListItemTypeMap

{ + props: P & { + /** + * The action to display at the end of ListItem. + */ + action?: React.ReactNode; + /** + * Defines the `align-items` style property. + * @default 'center' + */ + alignItems?: 'flex-start' | 'center'; + /** + * If `true`, the list item is focused during the first mount. + * Focus will also be triggered if the value changes from false to true. + * @default false + * @deprecated will be removed in v6, see `ListItemButton` instead + */ + autoFocus?: boolean; + /** + * If `true`, the list item is a button (using `ButtonBase`). Props intended + * for `ButtonBase` can then be applied to `ListItem`. + * @default false + * @deprecated will be removed in v6, see `ListItemButton` instead + */ + button?: boolean; + /** + * The content of the component if a `ListItemSecondaryAction` is used it must + * be the last child. + */ + children?: React.ReactNode; + /** + * Override or extend the styles applied to the component. + */ + classes?: Partial; + /** + * The container component used when a `ListItemSecondaryAction` is the last child. + * @default 'li' + * @deprecated will be removed in v6 + */ + ContainerComponent?: React.ElementType>; + /** + * Props applied to the container component if used. + * @default {} + * @deprecated will be removed in v6 + */ + ContainerProps?: React.HTMLAttributes; + /** + * If `true`, compact vertical padding designed for keyboard and mouse input is used. + * The prop defaults to the value inherited from the parent List component. + * @default false + */ + dense?: boolean; + /** + * If `true`, the component is disabled. + * @default false + * @deprecated will be removed in v6, see `ListItemButton` instead + */ + disabled?: boolean; + /** + * If `true`, the left and right padding is removed. + * @default false + */ + disableGutters?: boolean; + /** + * If `true`, a 1px light border is added to the bottom of the list item. + * @default false + */ + divider?: boolean; + /** + * The components used for each slot inside the InputBase. + * Either a string to use a HTML element or a component. + * @default {} + */ + components?: { + Root?: React.ElementType; + }; + /** + * The props used for each slot inside the Input. + * @default {} + */ + componentsProps?: { + root?: { + as: React.ElementType; + styleProps?: Omit; }; }; + /** + * Use to apply selected styling. + * @default false + * @deprecated will be removed in v6, see `ListItemButton` instead + */ + selected?: boolean; + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx?: SxProps; + } & Omit; defaultComponent: D; } @@ -116,39 +117,11 @@ export interface ListItemTypeMap { * * - [ListItem API](https://material-ui.com/api/list-item/) */ -declare const ListItem: OverridableComponent< - ListItemTypeMap< - { - /** - * If `true`, the list item is a button (using `ButtonBase`). Props intended - * for `ButtonBase` can then be applied to `ListItem`. - * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead - */ - button?: false; - }, - 'li' - > -> & - ExtendButtonBase< - ListItemTypeMap< - { - /** - * If `true`, the list item is a button (using `ButtonBase`). Props intended - * for `ButtonBase` can then be applied to `ListItem`. - * @default false - * @depreacted will be removed in v6, checkout `ListItemButton` instead - * - */ - button: true; - }, - 'div' - > - >; +declare const ListItem: OverridableComponent; -export type ListItemProps = OverrideProps< - ListItemTypeMap, - D ->; +export type ListItemProps< + D extends React.ElementType = ListItemTypeMap['defaultComponent'], + P = {}, +> = OverrideProps, D>; export default ListItem; diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 3e2d5d35261546..0a77607ee97806 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -325,15 +325,7 @@ ListItem.propTypes /* remove-proptypes */ = { /** * The action to display at the end of ListItem. */ - action: PropTypes.oneOfType([ - PropTypes.node, - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: PropTypes.node, /** * Defines the `align-items` style property. * @default 'center' @@ -343,14 +335,14 @@ ListItem.propTypes /* remove-proptypes */ = { * If `true`, the list item is focused during the first mount. * Focus will also be triggered if the value changes from false to true. * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead + * @deprecated will be removed in v6, see `ListItemButton` instead */ autoFocus: PropTypes.bool, /** * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead + * @deprecated will be removed in v6, see `ListItemButton` instead */ button: PropTypes.bool, /** @@ -428,7 +420,7 @@ ListItem.propTypes /* remove-proptypes */ = { /** * If `true`, the component is disabled. * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead + * @deprecated will be removed in v6, see `ListItemButton` instead */ disabled: PropTypes.bool, /** @@ -448,7 +440,7 @@ ListItem.propTypes /* remove-proptypes */ = { /** * Use to apply selected styling. * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead + * @deprecated will be removed in v6, see `ListItemButton` instead */ selected: PropTypes.bool, /** diff --git a/packages/material-ui/src/ListItem/ListItem.spec.tsx b/packages/material-ui/src/ListItem/ListItem.spec.tsx index 159d3b71d26374..e6a87bcd38c601 100644 --- a/packages/material-ui/src/ListItem/ListItem.spec.tsx +++ b/packages/material-ui/src/ListItem/ListItem.spec.tsx @@ -1,16 +1,12 @@ import * as React from 'react'; +import { experimentalStyled as styled } from '@material-ui/core/styles'; import ListItem from '@material-ui/core/ListItem'; +// loose the type in v5 since `button` is deprecated, remove this in v6, // button: boolean function BooleanButtonTest() { // https://github.com/mui-org/material-ui/issues/14971 - function EditableItemFail(props: { editable: boolean }) { - const { editable } = props; - // @ts-expect-error 'boolean' is not assignable to type 'true' - return Editable? {editable}; - } - function EditableItemValid(props: { editable: boolean }) { const { editable } = props; if (editable) { @@ -18,8 +14,14 @@ function BooleanButtonTest() { } return Editable? No; } + + function EditableItemBoolean(props: { editable: boolean }) { + const { editable } = props; + return Editable? {editable}; + } } +// loose the type in v5 since `button` is deprecated, remove this in v6. // verify that https://github.com/mui-org/material-ui/issues/19756 already worked. function MouseEnterTest() { function handleMouseEnter(event: React.MouseEvent) {} @@ -28,5 +30,13 @@ function MouseEnterTest() { function handleMouseEnterButton(event: React.MouseEvent) {} // @ts-expect-error ; // desired: missing property button + // @ts-expect-error ; } + +// https://github.com/mui-org/material-ui/issues/26469 + +const StyledListItem = styled(ListItem)({}); +function TestStyledComponent() { + return ; +} diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index 3f33d66ebc319f..7000fa9f71efdc 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -144,7 +144,7 @@ MenuItem.propTypes /* remove-proptypes */ = { */ sx: PropTypes.object, /** - * @ignore + * @default 0 */ tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), }; From 6b1e037042b13722ab02ce0a49aa760b4127697e Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 17:57:04 +0700 Subject: [PATCH 16/61] add disablePadding prop --- docs/pages/api-docs/list-item.json | 1 + .../api-docs/list-item/list-item.json | 1 + framer/Material-UI.framerfx/code/ListItem.tsx | 11 ++-- .../material-ui/src/ListItem/ListItem.d.ts | 5 ++ packages/material-ui/src/ListItem/ListItem.js | 53 +++++++++++-------- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/docs/pages/api-docs/list-item.json b/docs/pages/api-docs/list-item.json index 320606c594e168..9385c67e25c928 100644 --- a/docs/pages/api-docs/list-item.json +++ b/docs/pages/api-docs/list-item.json @@ -23,6 +23,7 @@ "dense": { "type": { "name": "bool" } }, "disabled": { "type": { "name": "bool" } }, "disableGutters": { "type": { "name": "bool" } }, + "disablePadding": { "type": { "name": "bool" } }, "divider": { "type": { "name": "bool" } }, "selected": { "type": { "name": "bool" } }, "sx": { "type": { "name": "object" } } diff --git a/docs/translations/api-docs/list-item/list-item.json b/docs/translations/api-docs/list-item/list-item.json index f545572ae550ad..b87d9d45eb6cf7 100644 --- a/docs/translations/api-docs/list-item/list-item.json +++ b/docs/translations/api-docs/list-item/list-item.json @@ -15,6 +15,7 @@ "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", "disabled": "If true, the component is disabled.", "disableGutters": "If true, the left and right padding is removed.", + "disablePadding": "If true, all padding is removed.", "divider": "If true, a 1px light border is added to the bottom of the list item.", "selected": "Use to apply selected styling.", "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." diff --git a/framer/Material-UI.framerfx/code/ListItem.tsx b/framer/Material-UI.framerfx/code/ListItem.tsx index 4bbe4924047d44..b8f899b345d971 100644 --- a/framer/Material-UI.framerfx/code/ListItem.tsx +++ b/framer/Material-UI.framerfx/code/ListItem.tsx @@ -12,13 +12,14 @@ import { Icon } from './Icon'; import { IconButton } from './IconButton'; interface Props { - action?: node | func | shape; + action?: React.ReactNode; alignItems: 'center' | 'flex-start'; autoFocus: boolean; button: boolean; dense: boolean; disabled: boolean; disableGutters: boolean; + disablePadding: boolean; divider: boolean; selected: boolean; width: number | string; @@ -119,6 +120,7 @@ ListItem.defaultProps = { dense: false, disabled: false, disableGutters: false, + disablePadding: false, divider: false, selected: false, width: 568, @@ -135,9 +137,8 @@ ListItem.defaultProps = { addPropertyControls(ListItem, { action: { - type: ControlType.Union, + type: ControlType.Node, title: 'Action', - options: [node, func, shape], }, alignItems: { type: ControlType.Enum, @@ -164,6 +165,10 @@ addPropertyControls(ListItem, { type: ControlType.Boolean, title: 'Disable gutters', }, + disablePadding: { + type: ControlType.Boolean, + title: 'Disable padding', + }, divider: { type: ControlType.Boolean, title: 'Divider', diff --git a/packages/material-ui/src/ListItem/ListItem.d.ts b/packages/material-ui/src/ListItem/ListItem.d.ts index f72fb037735846..8f7567d263774f 100644 --- a/packages/material-ui/src/ListItem/ListItem.d.ts +++ b/packages/material-ui/src/ListItem/ListItem.d.ts @@ -68,6 +68,11 @@ export interface ListItemTypeMap

{ * @default false */ disableGutters?: boolean; + /** + * If `true`, all padding is removed. + * @default false + */ + disablePadding?: boolean; /** * If `true`, a 1px light border is added to the bottom of the list item. * @default false diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 0a77607ee97806..1a7f396d0ae55a 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -41,6 +41,7 @@ const useUtilityClasses = (styleProps) => { dense, disabled, disableGutters, + disablePadding, divider, hasSecondaryAction, selected, @@ -53,6 +54,7 @@ const useUtilityClasses = (styleProps) => { !disableGutters && 'gutters', divider && 'divider', disabled && 'disabled', + disablePadding && 'disablePadding', button && 'button', alignItems === 'flex-start' && 'alignItemsFlexStart', hasSecondaryAction && 'secondaryAction', @@ -77,24 +79,32 @@ export const ListItemRoot = experimentalStyled('div', { width: '100%', boxSizing: 'border-box', textAlign: 'left', - paddingTop: 8, - paddingBottom: 8, - [`& .${listItemButtonClasses.root}`]: { - marginTop: -8, - marginBottom: -8, + /* Styles applied to the component element if `disablePadding={false}`. */ + ...(!styleProps.disablePadding && { + paddingTop: 8, + paddingBottom: 8, + /* Styles applied to the component element if dense and `disablePadding={false}`. */ ...(styleProps.dense && { - marginTop: -4, - marginBottom: -4, + paddingTop: 4, + paddingBottom: 4, }), + /* Styles applied to the inner `component` element unless `disableGutters={true}` and `disablePadding={true}`. */ ...(!styleProps.disableGutters && { - marginLeft: -16, - marginRight: -16, + paddingLeft: 16, + paddingRight: 16, }), - ...(styleProps.action && { - marginRight: -48, + /* Styles applied to the component element if `action` is not nil and `disablePadding={false}`. */ + ...(!!styleProps.action && { + // Add some space to avoid collision as `ListItemSecondaryAction` + // is absolutely positioned. paddingRight: 48, }), - }, + }), + ...(!!styleProps.action && { + [`& > .${listItemButtonClasses.root}`]: { + paddingRight: 48, + }, + }), [`&.${listItemClasses.focusVisible}`]: { backgroundColor: theme.palette.action.focus, }, @@ -110,11 +120,6 @@ export const ListItemRoot = experimentalStyled('div', { [`&.${listItemClasses.disabled}`]: { opacity: theme.palette.action.disabledOpacity, }, - /* Styles applied to the component element if dense. */ - ...(styleProps.dense && { - paddingTop: 4, - paddingBottom: 4, - }), /* Styles applied to the component element if `alignItems="flex-start"`. */ ...(styleProps.alignItems === 'flex-start' && { alignItems: 'flex-start', @@ -124,11 +129,6 @@ export const ListItemRoot = experimentalStyled('div', { borderBottom: `1px solid ${theme.palette.divider}`, backgroundClip: 'padding-box', }), - /* Styles applied to the inner `component` element unless `disableGutters={true}`. */ - ...(!styleProps.disableGutters && { - paddingLeft: 16, - paddingRight: 16, - }), /* Styles applied to the inner `component` element if `button={true}`. */ ...(styleProps.button && { transition: theme.transitions.create('background-color', { @@ -154,7 +154,7 @@ export const ListItemRoot = experimentalStyled('div', { }, }), /* Styles applied to the component element if `children` includes `ListItemSecondaryAction`. */ - ...((styleProps.hasSecondaryAction || !!styleProps.action) && { + ...(styleProps.hasSecondaryAction && { // Add some space to avoid collision as `ListItemSecondaryAction` // is absolutely positioned. paddingRight: 48, @@ -189,6 +189,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { dense = false, disabled = false, disableGutters = false, + disablePadding = false, divider = false, focusVisibleClassName, selected = false, @@ -229,6 +230,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { dense: childContext.dense, disabled, disableGutters, + disablePadding, divider, hasSecondaryAction, selected, @@ -428,6 +430,11 @@ ListItem.propTypes /* remove-proptypes */ = { * @default false */ disableGutters: PropTypes.bool, + /** + * If `true`, all padding is removed. + * @default false + */ + disablePadding: PropTypes.bool, /** * If `true`, a 1px light border is added to the bottom of the list item. * @default false From 7040bccf5b2985cca3a565ed36f6627b95b48009 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 17:57:15 +0700 Subject: [PATCH 17/61] update demo to use disablePadding --- docs/src/pages/components/lists/CheckboxList.js | 1 + docs/src/pages/components/lists/CheckboxList.tsx | 1 + .../pages/components/lists/CheckboxListSecondary.js | 1 + .../pages/components/lists/CheckboxListSecondary.tsx | 1 + docs/src/pages/components/lists/CustomizedList.js | 10 +++++----- docs/src/pages/components/lists/CustomizedList.tsx | 8 ++++---- docs/src/pages/components/lists/InsetList.js | 4 ++-- docs/src/pages/components/lists/InsetList.tsx | 4 ++-- docs/src/pages/components/lists/VirtualizedList.js | 2 +- docs/src/pages/components/lists/VirtualizedList.tsx | 2 +- 10 files changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/src/pages/components/lists/CheckboxList.js b/docs/src/pages/components/lists/CheckboxList.js index fba0c7ff55ffd7..873b6cc9b1aa99 100644 --- a/docs/src/pages/components/lists/CheckboxList.js +++ b/docs/src/pages/components/lists/CheckboxList.js @@ -38,6 +38,7 @@ export default function CheckboxList() { } + disablePadding > diff --git a/docs/src/pages/components/lists/CheckboxList.tsx b/docs/src/pages/components/lists/CheckboxList.tsx index 8191bb179fa6ad..95d5d28e761c91 100644 --- a/docs/src/pages/components/lists/CheckboxList.tsx +++ b/docs/src/pages/components/lists/CheckboxList.tsx @@ -38,6 +38,7 @@ export default function CheckboxList() { } + disablePadding > diff --git a/docs/src/pages/components/lists/CheckboxListSecondary.js b/docs/src/pages/components/lists/CheckboxListSecondary.js index 4c1baae9845b92..6f94f6e6b2d773 100644 --- a/docs/src/pages/components/lists/CheckboxListSecondary.js +++ b/docs/src/pages/components/lists/CheckboxListSecondary.js @@ -38,6 +38,7 @@ export default function CheckboxListSecondary() { inputProps={{ 'aria-labelledby': labelId }} /> } + disablePadding > diff --git a/docs/src/pages/components/lists/CheckboxListSecondary.tsx b/docs/src/pages/components/lists/CheckboxListSecondary.tsx index efafd6b20af45e..700b5ef6377489 100644 --- a/docs/src/pages/components/lists/CheckboxListSecondary.tsx +++ b/docs/src/pages/components/lists/CheckboxListSecondary.tsx @@ -38,6 +38,7 @@ export default function CheckboxListSecondary() { inputProps={{ 'aria-labelledby': labelId }} /> } + disablePadding > diff --git a/docs/src/pages/components/lists/CustomizedList.js b/docs/src/pages/components/lists/CustomizedList.js index 906e733a755496..5dfd15448f455d 100644 --- a/docs/src/pages/components/lists/CustomizedList.js +++ b/docs/src/pages/components/lists/CustomizedList.js @@ -7,7 +7,7 @@ import { } from '@material-ui/core/styles'; import Divider from '@material-ui/core/Divider'; import List from '@material-ui/core/List'; - +import ListItem from '@material-ui/core/ListItem'; import ListItemButton from '@material-ui/core/ListItemButton'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; @@ -31,7 +31,7 @@ const data = [ ]; const FireNav = styled(List)({ - '& .MuiListItem-root, .MuiListItemButton-root': { + '& .MuiListItem-root:not(.MuiListItem-disablePadding), .MuiListItemButton-root': { paddingLeft: 24, paddingRight: 24, }, @@ -45,7 +45,7 @@ const FireNav = styled(List)({ }); export default function CustomizedList() { - const [open, setOpen] = React.useState(false); + const [open, setOpen] = React.useState(true); return ( - + @@ -124,7 +124,7 @@ export default function CustomizedList() { - + ({ - '& .MuiListItem-root, .MuiListItemButton-root': { + '& .MuiListItem-root:not(.MuiListItem-disablePadding), .MuiListItemButton-root': { paddingLeft: 24, paddingRight: 24, }, @@ -45,7 +45,7 @@ const FireNav = styled(List)<{ component?: React.ElementType }>({ }); export default function CustomizedList() { - const [open, setOpen] = React.useState(false); + const [open, setOpen] = React.useState(true); return ( - + @@ -124,7 +124,7 @@ export default function CustomizedList() { - + - + @@ -21,7 +21,7 @@ export default function InsetList() { - + diff --git a/docs/src/pages/components/lists/InsetList.tsx b/docs/src/pages/components/lists/InsetList.tsx index f23139f2e81953..249772d304676a 100644 --- a/docs/src/pages/components/lists/InsetList.tsx +++ b/docs/src/pages/components/lists/InsetList.tsx @@ -13,7 +13,7 @@ export default function InsetList() { component="nav" aria-label="contacts" > - + @@ -21,7 +21,7 @@ export default function InsetList() { - + diff --git a/docs/src/pages/components/lists/VirtualizedList.js b/docs/src/pages/components/lists/VirtualizedList.js index f966fd790c5e40..5ffb9986aaff9f 100644 --- a/docs/src/pages/components/lists/VirtualizedList.js +++ b/docs/src/pages/components/lists/VirtualizedList.js @@ -9,7 +9,7 @@ function renderRow(props) { const { index, style } = props; return ( - + diff --git a/docs/src/pages/components/lists/VirtualizedList.tsx b/docs/src/pages/components/lists/VirtualizedList.tsx index 4592e89b452fa6..19e72525888ce1 100644 --- a/docs/src/pages/components/lists/VirtualizedList.tsx +++ b/docs/src/pages/components/lists/VirtualizedList.tsx @@ -9,7 +9,7 @@ function renderRow(props: ListChildComponentProps) { const { index, style } = props; return ( - + From 0884aa6d4e4cda6722d4f82d10853916a2a5d014 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 18:03:56 +0700 Subject: [PATCH 18/61] follow disablePadding in List --- docs/src/pages/components/lists/CustomizedList.js | 2 +- docs/src/pages/components/lists/CustomizedList.tsx | 2 +- packages/material-ui/src/ListItem/ListItem.js | 3 ++- packages/material-ui/src/ListItem/listItemClasses.ts | 3 +++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/src/pages/components/lists/CustomizedList.js b/docs/src/pages/components/lists/CustomizedList.js index 5dfd15448f455d..17034a372a8822 100644 --- a/docs/src/pages/components/lists/CustomizedList.js +++ b/docs/src/pages/components/lists/CustomizedList.js @@ -31,7 +31,7 @@ const data = [ ]; const FireNav = styled(List)({ - '& .MuiListItem-root:not(.MuiListItem-disablePadding), .MuiListItemButton-root': { + '& .MuiListItemButton-root': { paddingLeft: 24, paddingRight: 24, }, diff --git a/docs/src/pages/components/lists/CustomizedList.tsx b/docs/src/pages/components/lists/CustomizedList.tsx index 08c1f11e275490..f285bc8f27ea71 100644 --- a/docs/src/pages/components/lists/CustomizedList.tsx +++ b/docs/src/pages/components/lists/CustomizedList.tsx @@ -31,7 +31,7 @@ const data = [ ]; const FireNav = styled(List)<{ component?: React.ElementType }>({ - '& .MuiListItem-root:not(.MuiListItem-disablePadding), .MuiListItemButton-root': { + '& .MuiListItemButton-root': { paddingLeft: 24, paddingRight: 24, }, diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index 1a7f396d0ae55a..cdd8bef644f2e1 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -28,6 +28,7 @@ export const overridesResolver = (props, styles) => { ...(styleProps.alignItems === 'flex-start' && styles.alignItemsFlexStart), ...(styleProps.divider && styles.divider), ...(!styleProps.disableGutters && styles.gutters), + ...(!styleProps.disablePadding && styles.padding), ...(styleProps.button && styles.button), ...(styleProps.hasSecondaryAction && styles.secondaryAction), }; @@ -52,9 +53,9 @@ const useUtilityClasses = (styleProps) => { 'root', dense && 'dense', !disableGutters && 'gutters', + !disablePadding && 'padding', divider && 'divider', disabled && 'disabled', - disablePadding && 'disablePadding', button && 'button', alignItems === 'flex-start' && 'alignItemsFlexStart', hasSecondaryAction && 'secondaryAction', diff --git a/packages/material-ui/src/ListItem/listItemClasses.ts b/packages/material-ui/src/ListItem/listItemClasses.ts index dd05a4df5704bd..646e202c912a00 100644 --- a/packages/material-ui/src/ListItem/listItemClasses.ts +++ b/packages/material-ui/src/ListItem/listItemClasses.ts @@ -17,6 +17,8 @@ export interface ListItemClasses { divider: string; /** Styles applied to the inner `component` element unless `disableGutters={true}`. */ gutters: string; + /** Styles applied to the root element unless `disablePadding={true}`. */ + padding: string; /** Styles applied to the inner `component` element if `button={true}`. */ button: string; /** Styles applied to the component element if `children` includes `ListItemSecondaryAction`. */ @@ -40,6 +42,7 @@ const listItemClasses: ListItemClasses = generateUtilityClasses('MuiListItem', [ 'disabled', 'divider', 'gutters', + 'padding', 'button', 'secondaryAction', 'selected', From 36ff3d159dc108c9b9ff2177745db584d441bb4b Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 18:19:57 +0700 Subject: [PATCH 19/61] rename `action` to `secondaryAction` due to type conflict with ButtonBase --- docs/pages/api-docs/list-item.json | 3 +- .../pages/components/lists/CheckboxList.js | 2 +- .../pages/components/lists/CheckboxList.tsx | 2 +- .../components/lists/CheckboxListSecondary.js | 2 +- .../lists/CheckboxListSecondary.tsx | 2 +- .../pages/components/lists/GutterlessList.js | 2 +- .../pages/components/lists/GutterlessList.tsx | 2 +- .../pages/components/lists/InteractiveList.js | 2 +- .../components/lists/InteractiveList.tsx | 2 +- .../api-docs/list-item/list-item.json | 7 +- .../material-ui/src/ListItem/ListItem.d.ts | 239 ++++++++++-------- packages/material-ui/src/ListItem/ListItem.js | 26 +- .../src/ListItem/ListItem.spec.tsx | 22 +- packages/material-ui/src/MenuItem/MenuItem.js | 2 +- 14 files changed, 169 insertions(+), 146 deletions(-) diff --git a/docs/pages/api-docs/list-item.json b/docs/pages/api-docs/list-item.json index 9385c67e25c928..eaa9d80f4cc6ec 100644 --- a/docs/pages/api-docs/list-item.json +++ b/docs/pages/api-docs/list-item.json @@ -1,6 +1,5 @@ { "props": { - "action": { "type": { "name": "node" } }, "alignItems": { "type": { "name": "enum", "description": "'center'
| 'flex-start'" }, "default": "'center'" @@ -25,6 +24,7 @@ "disableGutters": { "type": { "name": "bool" } }, "disablePadding": { "type": { "name": "bool" } }, "divider": { "type": { "name": "bool" } }, + "secondaryAction": { "type": { "name": "node" } }, "selected": { "type": { "name": "bool" } }, "sx": { "type": { "name": "object" } } }, @@ -39,6 +39,7 @@ "disabled", "divider", "gutters", + "padding", "button", "secondaryAction", "selected" diff --git a/docs/src/pages/components/lists/CheckboxList.js b/docs/src/pages/components/lists/CheckboxList.js index 873b6cc9b1aa99..3b44bcc0733a5a 100644 --- a/docs/src/pages/components/lists/CheckboxList.js +++ b/docs/src/pages/components/lists/CheckboxList.js @@ -33,7 +33,7 @@ export default function CheckboxList() { diff --git a/docs/src/pages/components/lists/CheckboxList.tsx b/docs/src/pages/components/lists/CheckboxList.tsx index 95d5d28e761c91..0575fb2b2acc94 100644 --- a/docs/src/pages/components/lists/CheckboxList.tsx +++ b/docs/src/pages/components/lists/CheckboxList.tsx @@ -33,7 +33,7 @@ export default function CheckboxList() { diff --git a/docs/src/pages/components/lists/CheckboxListSecondary.js b/docs/src/pages/components/lists/CheckboxListSecondary.js index 6f94f6e6b2d773..3b40e93692deed 100644 --- a/docs/src/pages/components/lists/CheckboxListSecondary.js +++ b/docs/src/pages/components/lists/CheckboxListSecondary.js @@ -30,7 +30,7 @@ export default function CheckboxListSecondary() { return ( diff --git a/docs/src/pages/components/lists/GutterlessList.tsx b/docs/src/pages/components/lists/GutterlessList.tsx index 0c6d3fedfe92fd..2d9d881efa123c 100644 --- a/docs/src/pages/components/lists/GutterlessList.tsx +++ b/docs/src/pages/components/lists/GutterlessList.tsx @@ -12,7 +12,7 @@ export default function GutterlessList() { diff --git a/docs/src/pages/components/lists/InteractiveList.js b/docs/src/pages/components/lists/InteractiveList.js index 1efcae8d197343..9964b3a224fd03 100644 --- a/docs/src/pages/components/lists/InteractiveList.js +++ b/docs/src/pages/components/lists/InteractiveList.js @@ -124,7 +124,7 @@ export default function InteractiveList() { {generate( diff --git a/docs/src/pages/components/lists/InteractiveList.tsx b/docs/src/pages/components/lists/InteractiveList.tsx index 77e5c56246bc4f..379544df5a28ff 100644 --- a/docs/src/pages/components/lists/InteractiveList.tsx +++ b/docs/src/pages/components/lists/InteractiveList.tsx @@ -124,7 +124,7 @@ export default function InteractiveList() { {generate( diff --git a/docs/translations/api-docs/list-item/list-item.json b/docs/translations/api-docs/list-item/list-item.json index b87d9d45eb6cf7..9aa57e420874e1 100644 --- a/docs/translations/api-docs/list-item/list-item.json +++ b/docs/translations/api-docs/list-item/list-item.json @@ -1,7 +1,6 @@ { "componentDescription": "Uses an additional container component if `ListItemSecondaryAction` is the last child.", "propDescriptions": { - "action": "The action to display at the end of ListItem.", "alignItems": "Defines the align-items style property.", "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", "button": "If true, the list item is a button (using ButtonBase). Props intended for ButtonBase can then be applied to ListItem.", @@ -17,6 +16,7 @@ "disableGutters": "If true, the left and right padding is removed.", "disablePadding": "If true, all padding is removed.", "divider": "If true, a 1px light border is added to the bottom of the list item.", + "secondaryAction": "The element to display at the end of ListItem.", "selected": "Use to apply selected styling.", "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, @@ -60,6 +60,11 @@ "nodeName": "the inner `component` element", "conditions": "disableGutters={true}" }, + "padding": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the root element", + "conditions": "disablePadding={true}" + }, "button": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the inner `component` element", diff --git a/packages/material-ui/src/ListItem/ListItem.d.ts b/packages/material-ui/src/ListItem/ListItem.d.ts index 8f7567d263774f..73f5822120c21a 100644 --- a/packages/material-ui/src/ListItem/ListItem.d.ts +++ b/packages/material-ui/src/ListItem/ListItem.d.ts @@ -1,112 +1,111 @@ import * as React from 'react'; import { SxProps } from '@material-ui/system'; import { Theme } from '@material-ui/core/styles'; -import { ButtonBaseTypeMap } from '../ButtonBase'; +import { ExtendButtonBase } from '../ButtonBase'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; import { ListItemClasses } from './listItemClasses'; -export interface ListItemTypeMap

{ - props: P & { - /** - * The action to display at the end of ListItem. - */ - action?: React.ReactNode; - /** - * Defines the `align-items` style property. - * @default 'center' - */ - alignItems?: 'flex-start' | 'center'; - /** - * If `true`, the list item is focused during the first mount. - * Focus will also be triggered if the value changes from false to true. - * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead - */ - autoFocus?: boolean; - /** - * If `true`, the list item is a button (using `ButtonBase`). Props intended - * for `ButtonBase` can then be applied to `ListItem`. - * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead - */ - button?: boolean; - /** - * The content of the component if a `ListItemSecondaryAction` is used it must - * be the last child. - */ - children?: React.ReactNode; - /** - * Override or extend the styles applied to the component. - */ - classes?: Partial; - /** - * The container component used when a `ListItemSecondaryAction` is the last child. - * @default 'li' - * @deprecated will be removed in v6 - */ - ContainerComponent?: React.ElementType>; - /** - * Props applied to the container component if used. - * @default {} - * @deprecated will be removed in v6 - */ - ContainerProps?: React.HTMLAttributes; - /** - * If `true`, compact vertical padding designed for keyboard and mouse input is used. - * The prop defaults to the value inherited from the parent List component. - * @default false - */ - dense?: boolean; - /** - * If `true`, the component is disabled. - * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead - */ - disabled?: boolean; - /** - * If `true`, the left and right padding is removed. - * @default false - */ - disableGutters?: boolean; - /** - * If `true`, all padding is removed. - * @default false - */ - disablePadding?: boolean; - /** - * If `true`, a 1px light border is added to the bottom of the list item. - * @default false - */ - divider?: boolean; - /** - * The components used for each slot inside the InputBase. - * Either a string to use a HTML element or a component. - * @default {} - */ - components?: { - Root?: React.ElementType; - }; - /** - * The props used for each slot inside the Input. - * @default {} - */ - componentsProps?: { - root?: { - as: React.ElementType; - styleProps?: Omit; +interface ListItemBaseProps { + /** + * Defines the `align-items` style property. + * @default 'center' + */ + alignItems?: 'flex-start' | 'center'; + /** + * If `true`, the list item is focused during the first mount. + * Focus will also be triggered if the value changes from false to true. + * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead + */ + autoFocus?: boolean; + /** + * The content of the component if a `ListItemSecondaryAction` is used it must + * be the last child. + */ + children?: React.ReactNode; + /** + * Override or extend the styles applied to the component. + */ + classes?: Partial; + /** + * The container component used when a `ListItemSecondaryAction` is the last child. + * @default 'li' + * @deprecated will be removed in v6 + */ + ContainerComponent?: React.ElementType>; + /** + * Props applied to the container component if used. + * @default {} + * @deprecated will be removed in v6 + */ + ContainerProps?: React.HTMLAttributes; + /** + * If `true`, compact vertical padding designed for keyboard and mouse input is used. + * The prop defaults to the value inherited from the parent List component. + * @default false + */ + dense?: boolean; + /** + * If `true`, the component is disabled. + * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead + */ + disabled?: boolean; + /** + * If `true`, the left and right padding is removed. + * @default false + */ + disableGutters?: boolean; + /** + * If `true`, all padding is removed. + * @default false + */ + disablePadding?: boolean; + /** + * If `true`, a 1px light border is added to the bottom of the list item. + * @default false + */ + divider?: boolean; + /** + * The element to display at the end of ListItem. + */ + secondaryAction?: React.ReactNode; + /** + * Use to apply selected styling. + * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead + */ + selected?: boolean; + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx?: SxProps; +} + +export interface ListItemTypeMap { + props: P & + ListItemBaseProps & { + /** + * The components used for each slot inside the InputBase. + * Either a string to use a HTML element or a component. + * @default {} + */ + components?: { + Root?: React.ElementType; + }; + /** + * The props used for each slot inside the Input. + * @default {} + */ + componentsProps?: { + root?: { + as: React.ElementType; + styleProps?: Omit & { + dense?: boolean; + }; + }; }; }; - /** - * Use to apply selected styling. - * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead - */ - selected?: boolean; - /** - * The system prop that allows defining system overrides as well as additional CSS styles. - */ - sx?: SxProps; - } & Omit; defaultComponent: D; } @@ -122,11 +121,39 @@ export interface ListItemTypeMap

{ * * - [ListItem API](https://material-ui.com/api/list-item/) */ -declare const ListItem: OverridableComponent; +declare const ListItem: OverridableComponent< + ListItemTypeMap< + { + /** + * If `true`, the list item is a button (using `ButtonBase`). Props intended + * for `ButtonBase` can then be applied to `ListItem`. + * @default false + * @deprecated will be removed in v6, checkout `ListItemButton` instead + */ + button?: false; + }, + 'li' + > +> & + ExtendButtonBase< + ListItemTypeMap< + { + /** + * If `true`, the list item is a button (using `ButtonBase`). Props intended + * for `ButtonBase` can then be applied to `ListItem`. + * @default false + * @depreacted will be removed in v6, checkout `ListItemButton` instead + * + */ + button: true; + }, + 'div' + > + >; -export type ListItemProps< - D extends React.ElementType = ListItemTypeMap['defaultComponent'], - P = {}, -> = OverrideProps, D>; +export type ListItemProps = OverrideProps< + ListItemTypeMap, + D +>; export default ListItem; diff --git a/packages/material-ui/src/ListItem/ListItem.js b/packages/material-ui/src/ListItem/ListItem.js index cdd8bef644f2e1..cbafaeed1e8004 100644 --- a/packages/material-ui/src/ListItem/ListItem.js +++ b/packages/material-ui/src/ListItem/ListItem.js @@ -94,14 +94,14 @@ export const ListItemRoot = experimentalStyled('div', { paddingLeft: 16, paddingRight: 16, }), - /* Styles applied to the component element if `action` is not nil and `disablePadding={false}`. */ - ...(!!styleProps.action && { + /* Styles applied to the component element if `secondaryAction` is not nil and `disablePadding={false}`. */ + ...(!!styleProps.secondaryAction && { // Add some space to avoid collision as `ListItemSecondaryAction` // is absolutely positioned. paddingRight: 48, }), }), - ...(!!styleProps.action && { + ...(!!styleProps.secondaryAction && { [`& > .${listItemButtonClasses.root}`]: { paddingRight: 48, }, @@ -176,7 +176,6 @@ const ListItemContainer = experimentalStyled('li', { const ListItem = React.forwardRef(function ListItem(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiListItem' }); const { - action, alignItems = 'center', autoFocus = false, button = false, @@ -193,6 +192,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { disablePadding = false, divider = false, focusVisibleClassName, + secondaryAction, selected = false, ...other } = props; @@ -314,7 +314,7 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { {...componentProps} > {children} - {action && {action}} + {secondaryAction && {secondaryAction}} ); @@ -325,10 +325,6 @@ ListItem.propTypes /* remove-proptypes */ = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- - /** - * The action to display at the end of ListItem. - */ - action: PropTypes.node, /** * Defines the `align-items` style property. * @default 'center' @@ -338,14 +334,14 @@ ListItem.propTypes /* remove-proptypes */ = { * If `true`, the list item is focused during the first mount. * Focus will also be triggered if the value changes from false to true. * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ autoFocus: PropTypes.bool, /** * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ button: PropTypes.bool, /** @@ -423,7 +419,7 @@ ListItem.propTypes /* remove-proptypes */ = { /** * If `true`, the component is disabled. * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ disabled: PropTypes.bool, /** @@ -445,10 +441,14 @@ ListItem.propTypes /* remove-proptypes */ = { * @ignore */ focusVisibleClassName: PropTypes.string, + /** + * The element to display at the end of ListItem. + */ + secondaryAction: PropTypes.node, /** * Use to apply selected styling. * @default false - * @deprecated will be removed in v6, see `ListItemButton` instead + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ selected: PropTypes.bool, /** diff --git a/packages/material-ui/src/ListItem/ListItem.spec.tsx b/packages/material-ui/src/ListItem/ListItem.spec.tsx index e6a87bcd38c601..159d3b71d26374 100644 --- a/packages/material-ui/src/ListItem/ListItem.spec.tsx +++ b/packages/material-ui/src/ListItem/ListItem.spec.tsx @@ -1,12 +1,16 @@ import * as React from 'react'; -import { experimentalStyled as styled } from '@material-ui/core/styles'; import ListItem from '@material-ui/core/ListItem'; -// loose the type in v5 since `button` is deprecated, remove this in v6, // button: boolean function BooleanButtonTest() { // https://github.com/mui-org/material-ui/issues/14971 + function EditableItemFail(props: { editable: boolean }) { + const { editable } = props; + // @ts-expect-error 'boolean' is not assignable to type 'true' + return Editable? {editable}; + } + function EditableItemValid(props: { editable: boolean }) { const { editable } = props; if (editable) { @@ -14,14 +18,8 @@ function BooleanButtonTest() { } return Editable? No; } - - function EditableItemBoolean(props: { editable: boolean }) { - const { editable } = props; - return Editable? {editable}; - } } -// loose the type in v5 since `button` is deprecated, remove this in v6. // verify that https://github.com/mui-org/material-ui/issues/19756 already worked. function MouseEnterTest() { function handleMouseEnter(event: React.MouseEvent) {} @@ -30,13 +28,5 @@ function MouseEnterTest() { function handleMouseEnterButton(event: React.MouseEvent) {} // @ts-expect-error ; // desired: missing property button - // @ts-expect-error ; } - -// https://github.com/mui-org/material-ui/issues/26469 - -const StyledListItem = styled(ListItem)({}); -function TestStyledComponent() { - return ; -} diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index 7000fa9f71efdc..3f33d66ebc319f 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -144,7 +144,7 @@ MenuItem.propTypes /* remove-proptypes */ = { */ sx: PropTypes.object, /** - * @default 0 + * @ignore */ tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), }; From fce2d50cb89d7576ece2060f1672bac4cf74dc2a Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 18:23:04 +0700 Subject: [PATCH 20/61] minor fix --- .../transitions/TransitionGroupExample.js | 2 +- .../transitions/TransitionGroupExample.tsx | 2 +- framer/Material-UI.framerfx/code/ListItem.tsx | 17 ++++++----------- .../material-ui/src/ListItem/ListItem.test.js | 2 +- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/docs/src/pages/components/transitions/TransitionGroupExample.js b/docs/src/pages/components/transitions/TransitionGroupExample.js index 4eb6869aa1ba1d..eaffa09162dbf4 100644 --- a/docs/src/pages/components/transitions/TransitionGroupExample.js +++ b/docs/src/pages/components/transitions/TransitionGroupExample.js @@ -20,7 +20,7 @@ const FRUITS = [ function renderItem({ item, handleRemoveFruit }) { return ( ', () => { describe('action', () => { it('should show action if provided', () => { - const { getByText } = render(); + const { getByText } = render(); expect(getByText('foo')).toBeVisible(); }); }); From eb9581241f49257b299c41ba1df224e5a2be34a6 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 3 Jun 2021 18:55:10 +0700 Subject: [PATCH 21/61] cleanup --- docs/src/pages/components/lists/CustomizedList.js | 6 +----- docs/src/pages/components/lists/CustomizedList.tsx | 6 +----- packages/material-ui/src/ListItemButton/ListItemButton.js | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/docs/src/pages/components/lists/CustomizedList.js b/docs/src/pages/components/lists/CustomizedList.js index 17034a372a8822..c62da29f93d5bc 100644 --- a/docs/src/pages/components/lists/CustomizedList.js +++ b/docs/src/pages/components/lists/CustomizedList.js @@ -1,10 +1,6 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -import { - experimentalStyled as styled, - ThemeProvider, - createTheme, -} from '@material-ui/core/styles'; +import { styled, ThemeProvider, createTheme } from '@material-ui/core/styles'; import Divider from '@material-ui/core/Divider'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; diff --git a/docs/src/pages/components/lists/CustomizedList.tsx b/docs/src/pages/components/lists/CustomizedList.tsx index f285bc8f27ea71..dde46ecfc54aad 100644 --- a/docs/src/pages/components/lists/CustomizedList.tsx +++ b/docs/src/pages/components/lists/CustomizedList.tsx @@ -1,10 +1,6 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -import { - experimentalStyled as styled, - ThemeProvider, - createTheme, -} from '@material-ui/core/styles'; +import { styled, ThemeProvider, createTheme } from '@material-ui/core/styles'; import Divider from '@material-ui/core/Divider'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index ab07f973605f73..f37ff45c3f76bd 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; import { alpha } from '../styles/colorManipulator'; -import experimentalStyled, { rootShouldForwardProp } from '../styles/experimentalStyled'; +import styled, { rootShouldForwardProp } from '../styles/styled'; import useThemeProps from '../styles/useThemeProps'; import ButtonBase from '../ButtonBase'; import useEnhancedEffect from '../utils/useEnhancedEffect'; @@ -46,7 +46,7 @@ const useUtilityClasses = (styleProps) => { }; }; -const ListItemButtonRoot = experimentalStyled(ButtonBase, { +const ListItemButtonRoot = styled(ButtonBase, { shouldForwardProp: (prop) => rootShouldForwardProp(prop) || prop === 'classes', name: 'MuiListItemButton', slot: 'Root', From 3ee7f40f0f6ff99a6cfa465e18489f6a0ed74e3a Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 09:56:55 +0700 Subject: [PATCH 22/61] fix types --- .../material-ui/src/ListItem/ListItem.d.ts | 18 +++++++++--------- .../material-ui/src/ListItem/ListItem.spec.tsx | 10 ++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/material-ui/src/ListItem/ListItem.d.ts b/packages/material-ui/src/ListItem/ListItem.d.ts index 73f5822120c21a..8ec1bb12e39853 100644 --- a/packages/material-ui/src/ListItem/ListItem.d.ts +++ b/packages/material-ui/src/ListItem/ListItem.d.ts @@ -121,33 +121,33 @@ export interface ListItemTypeMap { * * - [ListItem API](https://material-ui.com/api/list-item/) */ -declare const ListItem: OverridableComponent< +declare const ListItem: ExtendButtonBase< ListItemTypeMap< { /** * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false - * @deprecated will be removed in v6, checkout `ListItemButton` instead + * @depreacted will be removed in v6, checkout `ListItemButton` instead + * */ - button?: false; + button: true; }, - 'li' + 'div' > > & - ExtendButtonBase< + OverridableComponent< ListItemTypeMap< { /** * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false - * @depreacted will be removed in v6, checkout `ListItemButton` instead - * + * @deprecated will be removed in v6, checkout `ListItemButton` instead */ - button: true; + button?: false; }, - 'div' + 'li' > >; diff --git a/packages/material-ui/src/ListItem/ListItem.spec.tsx b/packages/material-ui/src/ListItem/ListItem.spec.tsx index 159d3b71d26374..d0b2c09cdea15b 100644 --- a/packages/material-ui/src/ListItem/ListItem.spec.tsx +++ b/packages/material-ui/src/ListItem/ListItem.spec.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { styled } from '@material-ui/core/styles'; import ListItem from '@material-ui/core/ListItem'; // button: boolean @@ -30,3 +31,12 @@ function MouseEnterTest() { ; // desired: missing property button ; } + +// https://github.com/mui-org/material-ui/issues/26469 +const StyledListItem = styled(ListItem)({}); +function StyledTest() { + ; + + // @ts-expect-error + ; // `button` is deprecated in v5, can be removed in v6 +} From 2db70c3dad7b094eced58a37ae597f4d274edddc Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 11:19:12 +0700 Subject: [PATCH 23/61] use classes from ListItemButton --- .../material-ui/src/MenuItem/MenuItem.d.ts | 13 +++++-------- .../src/MenuItem/menuItemClasses.ts | 18 +++++++----------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/packages/material-ui/src/MenuItem/MenuItem.d.ts b/packages/material-ui/src/MenuItem/MenuItem.d.ts index a10059a806343d..3ddd769637f1fa 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.d.ts +++ b/packages/material-ui/src/MenuItem/MenuItem.d.ts @@ -1,14 +1,13 @@ import { SxProps } from '@material-ui/system'; import { Theme } from '@material-ui/core/styles'; import { DistributiveOmit } from '@material-ui/types'; -import { ListItemTypeMap, ListItemProps } from '../ListItem'; +import { ListItemButtonTypeMap, ListItemButtonProps } from '../ListItemButton'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; -import { ExtendButtonBase } from '../ButtonBase'; import { MenuItemClasses } from './menuItemClasses'; export interface MenuItemTypeMap

{ props: P & - DistributiveOmit['props'], 'children' | 'classes'> & { + DistributiveOmit['props'], 'children' | 'classes'> & { /** * The content of the component. */ @@ -19,8 +18,9 @@ export interface MenuItemTypeMap

{ classes?: Partial; /** * `classes` prop applied to the [`ListItem`](/api/list-item/) element. + * @deprecated this prop will be removed in v6, use `classes` instead */ - ListItemClasses?: ListItemProps['classes']; + ListItemClasses?: ListItemButtonProps['classes']; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ @@ -40,10 +40,7 @@ export interface MenuItemTypeMap

{ * - [MenuItem API](https://material-ui.com/api/menu-item/) * - inherits [ListItem API](https://material-ui.com/api/list-item/) */ -declare const MenuItem: OverridableComponent< - MenuItemTypeMap<{ button: false }, MenuItemTypeMap['defaultComponent']> -> & - ExtendButtonBase>; +declare const MenuItem: OverridableComponent; export type MenuItemProps< D extends React.ElementType = MenuItemTypeMap['defaultComponent'], diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index ae4b7897b85e9b..52650f78d81089 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -1,15 +1,7 @@ import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; +import { ListItemButtonClasses } from '../ListItemButton'; -export interface MenuItemClasses { - /** Styles applied to the root element. */ - root: string; - /** Styles applied to the root element unless `disableGutters={true}`. */ - gutters: string; - /** Styles applied to the root element if `selected={true}`. */ - selected: string; - /** Styles applied to the root element if dense. */ - dense: string; -} +export interface MenuItemClasses extends ListItemButtonClasses {} export type MenuItemClassKey = keyof MenuItemClasses; @@ -19,9 +11,13 @@ export function getMenuItemUtilityClass(slot: string): string { const menuItemClasses: MenuItemClasses = generateUtilityClasses('MuiMenuItem', [ 'root', + 'focusVisible', + 'dense', + 'alignItemsFlexStart', + 'disabled', + 'divider', 'gutters', 'selected', - 'dense', ]); export default menuItemClasses; From 47e9310ef829d199d6855f70ce69dbb7db75ef2b Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 14:05:27 +0700 Subject: [PATCH 24/61] replace ListItem with ListItemButton --- docs/pages/api-docs/menu-item.json | 21 ++++- .../api-docs/menu-item/menu-item.json | 40 ++++++-- .../src/ListItemButton/ListItemButton.js | 2 +- packages/material-ui/src/MenuItem/MenuItem.js | 93 ++++++++++++------- 4 files changed, 111 insertions(+), 45 deletions(-) diff --git a/docs/pages/api-docs/menu-item.json b/docs/pages/api-docs/menu-item.json index 3fc70f2330d873..5bdbc9d6b22cff 100644 --- a/docs/pages/api-docs/menu-item.json +++ b/docs/pages/api-docs/menu-item.json @@ -1,5 +1,9 @@ { "props": { + "alignItems": { + "type": { "name": "enum", "description": "'center'
| 'flex-start'" }, + "default": "'center'" + }, "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" } }, "component": { "type": { "name": "elementType" } }, @@ -10,8 +14,21 @@ }, "name": "MenuItem", "styles": { - "classes": ["root", "gutters", "selected", "dense"], - "globalClasses": { "selected": "Mui-selected" }, + "classes": [ + "root", + "focusVisible", + "dense", + "alignItemsFlexStart", + "disabled", + "divider", + "gutters", + "selected" + ], + "globalClasses": { + "focusVisible": "Mui-focusVisible", + "disabled": "Mui-disabled", + "selected": "Mui-selected" + }, "name": "MuiMenuItem" }, "spread": true, diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index 8bd0c94914f53a..bcfa824702b9c7 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -1,6 +1,7 @@ { "componentDescription": "", "propDescriptions": { + "alignItems": "Defines the align-items style property.", "children": "The content of the component.", "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "component": "The component used for the root node. Either a string to use a HTML element or a component.", @@ -10,21 +11,44 @@ "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, "classDescriptions": { - "root": { "description": "Styles applied to the root element." }, + "root": { + "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", + "nodeName": "the (normally root) `component` element" + }, + "focusVisible": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop", + "conditions": "button={true}" + }, + "dense": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "dense" + }, + "alignItemsFlexStart": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the component element", + "conditions": "alignItems=\"flex-start\"" + }, + "disabled": { + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disabled={true}" + }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, "gutters": { "description": "Styles applied to {{nodeName}} unless {{conditions}}.", - "nodeName": "the root element", + "nodeName": "the inner `component` element", "conditions": "disableGutters={true}" }, "selected": { - "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", "conditions": "selected={true}" - }, - "dense": { - "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the root element", - "conditions": "dense" } } } diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index f37ff45c3f76bd..fa06fc5e5815ce 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -11,7 +11,7 @@ import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; import listItemButtonClasses, { getListItemButtonUtilityClass } from './listItemButtonClasses'; -const overridesResolver = (props, styles) => { +export const overridesResolver = (props, styles) => { const { styleProps } = props; return { diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index 4bb1706f6baf2c..5fb08f826b0234 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -1,12 +1,15 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import clsx from 'clsx'; import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; import styled, { rootShouldForwardProp } from '../styles/styled'; import useThemeProps from '../styles/useThemeProps'; import { getMenuItemUtilityClass } from './menuItemClasses'; -import ListItem from '../ListItem'; -import { overridesResolver as listItemOverridesResolver, ListItemRoot } from '../ListItem/ListItem'; +import ListContext from '../List/ListContext'; +import ListItemButton from '../ListItemButton'; +import { dividerClasses } from '../Divider'; +import { listItemIconClasses } from '../ListItemIcon'; +import { listItemTextClasses } from '../ListItemText'; +import { overridesResolver as listItemButtonOverridesResolver } from '../ListItemButton/ListItemButton'; const useUtilityClasses = (styleProps) => { const { selected, dense, classes } = styleProps; @@ -17,48 +20,72 @@ const useUtilityClasses = (styleProps) => { return composeClasses(slots, getMenuItemUtilityClass, classes); }; -const MenuItemRoot = styled(ListItemRoot, { +const MenuItemRoot = styled(ListItemButton, { shouldForwardProp: (prop) => rootShouldForwardProp(prop) || prop === 'classes', name: 'MuiMenuItem', slot: 'Root', - overridesResolver: (props, styles) => { - const { styleProps } = props; - return { - ...listItemOverridesResolver(props, styles), - ...(styleProps.dense && styles.dense), - }; - }, + overridesResolver: listItemButtonOverridesResolver, })(({ theme, styleProps }) => ({ ...theme.typography.body1, - minHeight: 48, paddingTop: 6, paddingBottom: 6, boxSizing: 'border-box', width: 'auto', whiteSpace: 'nowrap', - [theme.breakpoints.up('sm')]: { - minHeight: 'auto', + [`& + .${dividerClasses.root}`]: { + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), + }, + [`& .${listItemTextClasses.root}`]: { + marginTop: 0, + marginBottom: 0, + }, + [`& .${listItemTextClasses.inset}`]: { + paddingLeft: 36, }, - ...(styleProps.dense && { - ...theme.typography.body2, - minHeight: 'auto', + [`& .${listItemIconClasses.root}`]: { + minWidth: 36, + '& svg': { + fontSize: '1.25rem', + }, + }, + ...(!styleProps.dense && { + [theme.breakpoints.up('md')]: { + padding: '12px 24px', + [`& .${listItemTextClasses.inset}`]: { + paddingLeft: 44, + }, + [`& .${listItemIconClasses.root}`]: { + minWidth: 44, + '& svg': { + fontSize: '1.5rem', + }, + }, + }, }), })); const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiMenuItem' }); const { - className, + children, component = 'li', - dense = false, + dense: denseProp = false, disableGutters = false, - ListItemClasses, role = 'menuitem', selected, tabIndex: tabIndexProp, ...other } = props; + const context = React.useContext(ListContext); + const dense = denseProp || context.dense || false; + const childContext = { + dense: false, // fix dense to false, so ListItemText does not get smaller. + alignItems: props.alignItems || false, + disableGutters, + }; + const styleProps = { dense }; const classes = useUtilityClasses(props); @@ -69,20 +96,20 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { } return ( - + styleProps={styleProps} + classes={classes} + > + {children} + ); }); @@ -92,9 +119,10 @@ MenuItem.propTypes /* remove-proptypes */ = { // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- /** - * @ignore + * Defines the `align-items` style property. + * @default 'center' */ - button: PropTypes.bool, + alignItems: PropTypes.oneOf(['center', 'flex-start']), /** * The content of the component. */ @@ -103,10 +131,6 @@ MenuItem.propTypes /* remove-proptypes */ = { * Override or extend the styles applied to the component. */ classes: PropTypes.object, - /** - * @ignore - */ - className: PropTypes.string, /** * The component used for the root node. * Either a string to use a HTML element or a component. @@ -129,6 +153,7 @@ MenuItem.propTypes /* remove-proptypes */ = { disableGutters: PropTypes.bool, /** * `classes` prop applied to the [`ListItem`](/api/list-item/) element. + * @deprecated this prop will be removed in v6, use `classes` instead */ ListItemClasses: PropTypes.object, /** @@ -144,7 +169,7 @@ MenuItem.propTypes /* remove-proptypes */ = { */ sx: PropTypes.object, /** - * @ignore + * @default 0 */ tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), }; From ef9ac53beccbb88896e3d4202bc5ffac47cbf1a5 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 14:05:44 +0700 Subject: [PATCH 25/61] update Menu demos --- .../pages/components/menus/CustomizedMenus.js | 2 +- .../components/menus/CustomizedMenus.tsx | 2 +- docs/src/pages/components/menus/DenseMenu.js | 46 +++++++++++++++ docs/src/pages/components/menus/DenseMenu.tsx | 46 +++++++++++++++ .../src/pages/components/menus/DesktopMenu.js | 59 +++++++++++++++++++ .../pages/components/menus/DesktopMenu.tsx | 59 +++++++++++++++++++ docs/src/pages/components/menus/menus.md | 12 ++++ 7 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 docs/src/pages/components/menus/DenseMenu.js create mode 100644 docs/src/pages/components/menus/DenseMenu.tsx create mode 100644 docs/src/pages/components/menus/DesktopMenu.js create mode 100644 docs/src/pages/components/menus/DesktopMenu.tsx diff --git a/docs/src/pages/components/menus/CustomizedMenus.js b/docs/src/pages/components/menus/CustomizedMenus.js index b4e7be1759ca2a..08f7a11f58aba6 100644 --- a/docs/src/pages/components/menus/CustomizedMenus.js +++ b/docs/src/pages/components/menus/CustomizedMenus.js @@ -35,7 +35,7 @@ const StyledMenu = styled((props) => ( '& .MuiList-root': { padding: '4px 0', }, - '& .MuiListItem-root': { + '& .MuiListItemButton-root': { ...theme.typography.body1, '& .MuiSvgIcon-root': { fontSize: 18, diff --git a/docs/src/pages/components/menus/CustomizedMenus.tsx b/docs/src/pages/components/menus/CustomizedMenus.tsx index 9fea958d73cdc4..1060e33a46135a 100644 --- a/docs/src/pages/components/menus/CustomizedMenus.tsx +++ b/docs/src/pages/components/menus/CustomizedMenus.tsx @@ -35,7 +35,7 @@ const StyledMenu = styled((props: MenuProps) => ( '& .MuiList-root': { padding: '4px 0', }, - '& .MuiListItem-root': { + '& .MuiListItemButton-root': { ...theme.typography.body1, '& .MuiSvgIcon-root': { fontSize: 18, diff --git a/docs/src/pages/components/menus/DenseMenu.js b/docs/src/pages/components/menus/DenseMenu.js new file mode 100644 index 00000000000000..805428a0b3b36e --- /dev/null +++ b/docs/src/pages/components/menus/DenseMenu.js @@ -0,0 +1,46 @@ +import * as React from 'react'; +import Paper from '@material-ui/core/Paper'; +import Divider from '@material-ui/core/Divider'; +import MenuList from '@material-ui/core/MenuList'; +import MenuItem from '@material-ui/core/MenuItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; + +import Check from '@material-ui/icons/Check'; +import ArrowRight from '@material-ui/icons/ArrowRight'; + +export default function DenseMenu() { + return ( + + + + Single + + + 1.15 + + + Double + + + + + + Custom: 1.2 + + + + Add space before paragraph + + + Add space after paragraph + + + + + Custom spacing... + + + + ); +} diff --git a/docs/src/pages/components/menus/DenseMenu.tsx b/docs/src/pages/components/menus/DenseMenu.tsx new file mode 100644 index 00000000000000..805428a0b3b36e --- /dev/null +++ b/docs/src/pages/components/menus/DenseMenu.tsx @@ -0,0 +1,46 @@ +import * as React from 'react'; +import Paper from '@material-ui/core/Paper'; +import Divider from '@material-ui/core/Divider'; +import MenuList from '@material-ui/core/MenuList'; +import MenuItem from '@material-ui/core/MenuItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; + +import Check from '@material-ui/icons/Check'; +import ArrowRight from '@material-ui/icons/ArrowRight'; + +export default function DenseMenu() { + return ( + + + + Single + + + 1.15 + + + Double + + + + + + Custom: 1.2 + + + + Add space before paragraph + + + Add space after paragraph + + + + + Custom spacing... + + + + ); +} diff --git a/docs/src/pages/components/menus/DesktopMenu.js b/docs/src/pages/components/menus/DesktopMenu.js new file mode 100644 index 00000000000000..1c4da197dd4449 --- /dev/null +++ b/docs/src/pages/components/menus/DesktopMenu.js @@ -0,0 +1,59 @@ +import * as React from 'react'; + +import Divider from '@material-ui/core/Divider'; +import Paper from '@material-ui/core/Paper'; +import MenuList from '@material-ui/core/MenuList'; +import MenuItem from '@material-ui/core/MenuItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import Typography from '@material-ui/core/Typography'; + +import ArrowRight from '@material-ui/icons/ArrowRight'; +import ContentCut from '@material-ui/icons/ContentCut'; +import ContentCopy from '@material-ui/icons/ContentCopy'; +import ContentPaste from '@material-ui/icons/ContentPaste'; +import Cloud from '@material-ui/icons/Cloud'; + +export default function DesktopMenu() { + return ( + + + + + + + Cut + + ⌘X + + + + + + + Copy + + ⌘C + + + + + + + Paste + + ⌘V + + + + + + + + Web Clipboard + + + + + ); +} diff --git a/docs/src/pages/components/menus/DesktopMenu.tsx b/docs/src/pages/components/menus/DesktopMenu.tsx new file mode 100644 index 00000000000000..1c4da197dd4449 --- /dev/null +++ b/docs/src/pages/components/menus/DesktopMenu.tsx @@ -0,0 +1,59 @@ +import * as React from 'react'; + +import Divider from '@material-ui/core/Divider'; +import Paper from '@material-ui/core/Paper'; +import MenuList from '@material-ui/core/MenuList'; +import MenuItem from '@material-ui/core/MenuItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import Typography from '@material-ui/core/Typography'; + +import ArrowRight from '@material-ui/icons/ArrowRight'; +import ContentCut from '@material-ui/icons/ContentCut'; +import ContentCopy from '@material-ui/icons/ContentCopy'; +import ContentPaste from '@material-ui/icons/ContentPaste'; +import Cloud from '@material-ui/icons/Cloud'; + +export default function DesktopMenu() { + return ( + + + + + + + Cut + + ⌘X + + + + + + + Copy + + ⌘C + + + + + + + Paste + + ⌘V + + + + + + + + Web Clipboard + + + + + ); +} diff --git a/docs/src/pages/components/menus/menus.md b/docs/src/pages/components/menus/menus.md index f9f3967c3e282b..4b9d2362b6c872 100644 --- a/docs/src/pages/components/menus/menus.md +++ b/docs/src/pages/components/menus/menus.md @@ -24,6 +24,18 @@ Choosing an option should immediately ideally commit the option and close the me {{"demo": "pages/components/menus/BasicMenu.js"}} +## Desktop menu + +In desktop viewport, padding is increased to give more space to the menu. + +{{"demo": "pages/components/menus/DesktopMenu.js", "bg": true}} + +## Dense menu + +For the menu that has long list and long text, use `dense` to reduce the padding (this property only affect desktop viewport). + +{{"demo": "pages/components/menus/DenseMenu.js", "bg": true}} + ## Selected menu If used for item selection, when opened, simple menus places the initial focus on the selected menu item. From c80254e3876158d890ba911df5a9d5a97607f72f Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 14:08:27 +0700 Subject: [PATCH 26/61] removed deprecated tests --- .../material-ui/src/MenuItem/MenuItem.test.js | 49 +------------------ 1 file changed, 2 insertions(+), 47 deletions(-) diff --git a/packages/material-ui/src/MenuItem/MenuItem.test.js b/packages/material-ui/src/MenuItem/MenuItem.test.js index 601dd1f64c98b5..9536199829d7eb 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.test.js +++ b/packages/material-ui/src/MenuItem/MenuItem.test.js @@ -10,8 +10,7 @@ import { screen, } from 'test/utils'; import MenuItem, { menuItemClasses as classes } from '@material-ui/core/MenuItem'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import ListItemButton from '@material-ui/core/ListItemButton'; describe('', () => { const render = createClientRender(); @@ -19,7 +18,7 @@ describe('', () => { describeConformanceV5(, () => ({ classes, - inheritComponent: ListItem, + inheritComponent: ListItemButton, render, mount, refInstanceof: window.HTMLLIElement, @@ -127,54 +126,10 @@ describe('', () => { }); }); - // Regression test for #10452. - // Kept for backwards compatibility. - // In the future we should have a better pattern for this UI. - it('should not fail with a li > li error message', () => { - const { rerender } = render( - - -

- - , - ); - - expect(document.querySelectorAll('li')).to.have.length(1); - - rerender( - - -
- - , - ); - - expect(document.querySelectorAll('li')).to.have.length(1); - }); - it('can be disabled', () => { render(); const menuitem = screen.getByRole('menuitem'); expect(menuitem).to.have.attribute('aria-disabled', 'true'); }); - - describe('prop: ListItemClasses', () => { - it('should be able to change the style of ListItem', () => { - render( - , - ); - const menuitem = screen.getByRole('menuitem'); - - expect(menuitem).not.to.have.class('foo'); - expect(menuitem).to.have.class('bar'); - }); - }); }); From aa6f76449859153f8705a4d5d034d9c6011874b1 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 14:12:50 +0700 Subject: [PATCH 27/61] fix spec --- packages/material-ui/test/typescript/components.spec.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/material-ui/test/typescript/components.spec.tsx b/packages/material-ui/test/typescript/components.spec.tsx index 2eb1e0d397f881..e427e47edbcb7a 100644 --- a/packages/material-ui/test/typescript/components.spec.tsx +++ b/packages/material-ui/test/typescript/components.spec.tsx @@ -600,7 +600,6 @@ const MenuTest = () => { Link Item { expectType(elem); }} @@ -609,8 +608,6 @@ const MenuTest = () => { action={(action) => { buttonActionRef.current = action; }} - // @ts-expect-error 'false' is not assignable to true | undefined - button={false} ref={(elem) => { // inferred from `button={false}` instead of `action` expectType(elem); From 0cbb7afc0a95ad53ce83ab1e9c1f7e0dc308c23a Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 14:52:28 +0700 Subject: [PATCH 28/61] run proptypes and docs:api --- docs/pages/api-docs/menu-item.json | 2 +- packages/material-ui/src/ListItem/ListItem.d.ts | 2 +- packages/material-ui/src/MenuItem/MenuItem.d.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/api-docs/menu-item.json b/docs/pages/api-docs/menu-item.json index 5bdbc9d6b22cff..6da885e7111c64 100644 --- a/docs/pages/api-docs/menu-item.json +++ b/docs/pages/api-docs/menu-item.json @@ -34,7 +34,7 @@ "spread": true, "forwardsRefTo": "HTMLLIElement", "filename": "/packages/material-ui/src/MenuItem/MenuItem.js", - "inheritance": { "component": "ListItem", "pathname": "/api/list-item/" }, + "inheritance": { "component": "ListItemButton", "pathname": "/api/list-item-button/" }, "demos": "", "styledComponent": true, "cssComponent": false diff --git a/packages/material-ui/src/ListItem/ListItem.d.ts b/packages/material-ui/src/ListItem/ListItem.d.ts index 8ec1bb12e39853..ee244cf95bdc6b 100644 --- a/packages/material-ui/src/ListItem/ListItem.d.ts +++ b/packages/material-ui/src/ListItem/ListItem.d.ts @@ -128,7 +128,7 @@ declare const ListItem: ExtendButtonBase< * If `true`, the list item is a button (using `ButtonBase`). Props intended * for `ButtonBase` can then be applied to `ListItem`. * @default false - * @depreacted will be removed in v6, checkout `ListItemButton` instead + * @deprecated will be removed in v6, checkout `ListItemButton` instead * */ button: true; diff --git a/packages/material-ui/src/MenuItem/MenuItem.d.ts b/packages/material-ui/src/MenuItem/MenuItem.d.ts index 3ddd769637f1fa..734c4992c14169 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.d.ts +++ b/packages/material-ui/src/MenuItem/MenuItem.d.ts @@ -38,7 +38,7 @@ export interface MenuItemTypeMap

{ * API: * * - [MenuItem API](https://material-ui.com/api/menu-item/) - * - inherits [ListItem API](https://material-ui.com/api/list-item/) + * - inherits [ListItemButton API](https://material-ui.com/api/list-item-button/) */ declare const MenuItem: OverridableComponent; From 5af296dd33913782514ec1f067602d17fc2e7a92 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 15:39:32 +0700 Subject: [PATCH 29/61] pass dense to children --- packages/material-ui/src/MenuItem/MenuItem.js | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index 5fb08f826b0234..1e86e70b0dbd43 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -29,6 +29,7 @@ const MenuItemRoot = styled(ListItemButton, { ...theme.typography.body1, paddingTop: 6, paddingBottom: 6, + minWidth: 56, boxSizing: 'border-box', width: 'auto', whiteSpace: 'nowrap', @@ -49,26 +50,29 @@ const MenuItemRoot = styled(ListItemButton, { fontSize: '1.25rem', }, }, - ...(!styleProps.dense && { - [theme.breakpoints.up('md')]: { - padding: '12px 24px', - [`& .${listItemTextClasses.inset}`]: { - paddingLeft: 44, - }, - [`& .${listItemIconClasses.root}`]: { - minWidth: 44, - '& svg': { - fontSize: '1.5rem', + ...(styleProps.dense + ? { + ...theme.typography.body2, + } + : { + [theme.breakpoints.up('md')]: { + padding: '12px 24px', + [`& .${listItemTextClasses.inset}`]: { + paddingLeft: 44, + }, + [`& .${listItemIconClasses.root}`]: { + minWidth: 44, + '& svg': { + fontSize: '1.5rem', + }, + }, }, - }, - }, - }), + }), })); const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiMenuItem' }); const { - children, component = 'li', dense: denseProp = false, disableGutters = false, @@ -80,11 +84,6 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const context = React.useContext(ListContext); const dense = denseProp || context.dense || false; - const childContext = { - dense: false, // fix dense to false, so ListItemText does not get smaller. - alignItems: props.alignItems || false, - disableGutters, - }; const styleProps = { dense }; @@ -107,9 +106,7 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { {...other} styleProps={styleProps} classes={classes} - > - {children} - + /> ); }); From 7ca9341009059691061ecae15a6310053495eb31 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 16:32:00 +0700 Subject: [PATCH 30/61] add account menu demo --- .../src/pages/components/menus/AccountMenu.js | 99 +++++++++++++++++++ .../pages/components/menus/AccountMenu.tsx | 99 +++++++++++++++++++ docs/src/pages/components/menus/menus.md | 6 ++ 3 files changed, 204 insertions(+) create mode 100644 docs/src/pages/components/menus/AccountMenu.js create mode 100644 docs/src/pages/components/menus/AccountMenu.tsx diff --git a/docs/src/pages/components/menus/AccountMenu.js b/docs/src/pages/components/menus/AccountMenu.js new file mode 100644 index 00000000000000..17d181c17cb75f --- /dev/null +++ b/docs/src/pages/components/menus/AccountMenu.js @@ -0,0 +1,99 @@ +import * as React from 'react'; + +import Box from '@material-ui/core/Box'; +import Avatar from '@material-ui/core/Avatar'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import Divider from '@material-ui/core/Divider'; +import IconButton from '@material-ui/core/IconButton'; +import Typography from '@material-ui/core/Typography'; + +import PersonAdd from '@material-ui/icons/PersonAdd'; +import Settings from '@material-ui/icons/Settings'; +import Logout from '@material-ui/icons/Logout'; + +export default function AccountMenu() { + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + return ( + + + Contact + Profile + + M + + +

+ + Profile + + + My account + + + + + + + Add another account + + + + + + Settings + + + + + + Logout + + + + ); +} diff --git a/docs/src/pages/components/menus/AccountMenu.tsx b/docs/src/pages/components/menus/AccountMenu.tsx new file mode 100644 index 00000000000000..c0f46f49fe467e --- /dev/null +++ b/docs/src/pages/components/menus/AccountMenu.tsx @@ -0,0 +1,99 @@ +import * as React from 'react'; + +import Box from '@material-ui/core/Box'; +import Avatar from '@material-ui/core/Avatar'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import Divider from '@material-ui/core/Divider'; +import IconButton from '@material-ui/core/IconButton'; +import Typography from '@material-ui/core/Typography'; + +import PersonAdd from '@material-ui/icons/PersonAdd'; +import Settings from '@material-ui/icons/Settings'; +import Logout from '@material-ui/icons/Logout'; + +export default function AccountMenu() { + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + return ( + + + Contact + Profile + + M + + + + + Profile + + + My account + + + + + + + Add another account + + + + + + Settings + + + + + + Logout + + + + ); +} diff --git a/docs/src/pages/components/menus/menus.md b/docs/src/pages/components/menus/menus.md index 4b9d2362b6c872..86173b57024b03 100644 --- a/docs/src/pages/components/menus/menus.md +++ b/docs/src/pages/components/menus/menus.md @@ -61,6 +61,12 @@ The primary responsibility of the `MenuList` component is to handle the focus. {{"demo": "pages/components/menus/MenuListComposition.js", "bg": true}} +## Account menu + +`Menu` content can be mixed with other component like `Avatar`. + +{{"demo": "pages/components/menus/AccountMenu.js", "bg": true}} + ## Customized menu Here is an example of customizing the component. You can learn more about this in the From 692950cfa225c6f1414f6f6c166f34c6603c6745 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 4 Jun 2021 17:36:36 +0700 Subject: [PATCH 31/61] run proptypes --- docs/pages/api-docs/menu-item.json | 4 ---- docs/translations/api-docs/menu-item/menu-item.json | 1 - packages/material-ui/src/MenuItem/MenuItem.js | 5 ----- 3 files changed, 10 deletions(-) diff --git a/docs/pages/api-docs/menu-item.json b/docs/pages/api-docs/menu-item.json index 6da885e7111c64..e80faf5420cfbe 100644 --- a/docs/pages/api-docs/menu-item.json +++ b/docs/pages/api-docs/menu-item.json @@ -1,9 +1,5 @@ { "props": { - "alignItems": { - "type": { "name": "enum", "description": "'center'
| 'flex-start'" }, - "default": "'center'" - }, "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" } }, "component": { "type": { "name": "elementType" } }, diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index bcfa824702b9c7..1cf0d7daaf1c22 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -1,7 +1,6 @@ { "componentDescription": "", "propDescriptions": { - "alignItems": "Defines the align-items style property.", "children": "The content of the component.", "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "component": "The component used for the root node. Either a string to use a HTML element or a component.", diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index 1e86e70b0dbd43..edf93d80de6bc1 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -115,11 +115,6 @@ MenuItem.propTypes /* remove-proptypes */ = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- - /** - * Defines the `align-items` style property. - * @default 'center' - */ - alignItems: PropTypes.oneOf(['center', 'flex-start']), /** * The content of the component. */ From 0a358937f5b836dd0bb5d9de693d8996dd2232eb Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 8 Jun 2021 15:26:51 +0700 Subject: [PATCH 32/61] fix style and demos --- .../src/pages/components/menus/AccountMenu.js | 28 +++++++-------- .../pages/components/menus/AccountMenu.tsx | 28 +++++++-------- .../menus/{DesktopMenu.js => IconMenu.js} | 10 +++--- .../menus/{DesktopMenu.tsx => IconMenu.tsx} | 10 +++--- docs/src/pages/components/menus/menus.md | 4 +-- .../api-docs/menu-item/menu-item.json | 10 ++---- .../src/ListItemButton/ListItemButton.js | 2 +- packages/material-ui/src/MenuItem/MenuItem.js | 35 ++++++++----------- 8 files changed, 59 insertions(+), 68 deletions(-) rename docs/src/pages/components/menus/{DesktopMenu.js => IconMenu.js} (89%) rename docs/src/pages/components/menus/{DesktopMenu.tsx => IconMenu.tsx} (89%) diff --git a/docs/src/pages/components/menus/AccountMenu.js b/docs/src/pages/components/menus/AccountMenu.js index 17d181c17cb75f..e13067612ca972 100644 --- a/docs/src/pages/components/menus/AccountMenu.js +++ b/docs/src/pages/components/menus/AccountMenu.js @@ -8,6 +8,7 @@ import ListItemIcon from '@material-ui/core/ListItemIcon'; import Divider from '@material-ui/core/Divider'; import IconButton from '@material-ui/core/IconButton'; import Typography from '@material-ui/core/Typography'; +import Tooltip from '@material-ui/core/Tooltip'; import PersonAdd from '@material-ui/icons/PersonAdd'; import Settings from '@material-ui/icons/Settings'; @@ -27,18 +28,17 @@ export default function AccountMenu() { Contact Profile - - M - + + + M + + - + Add another account - + Settings - + Logout diff --git a/docs/src/pages/components/menus/AccountMenu.tsx b/docs/src/pages/components/menus/AccountMenu.tsx index c0f46f49fe467e..07e2b2beec7379 100644 --- a/docs/src/pages/components/menus/AccountMenu.tsx +++ b/docs/src/pages/components/menus/AccountMenu.tsx @@ -8,6 +8,7 @@ import ListItemIcon from '@material-ui/core/ListItemIcon'; import Divider from '@material-ui/core/Divider'; import IconButton from '@material-ui/core/IconButton'; import Typography from '@material-ui/core/Typography'; +import Tooltip from '@material-ui/core/Tooltip'; import PersonAdd from '@material-ui/icons/PersonAdd'; import Settings from '@material-ui/icons/Settings'; @@ -27,18 +28,17 @@ export default function AccountMenu() { Contact Profile - - M - + + + M + + - + Add another account - + Settings - + Logout diff --git a/docs/src/pages/components/menus/DesktopMenu.js b/docs/src/pages/components/menus/IconMenu.js similarity index 89% rename from docs/src/pages/components/menus/DesktopMenu.js rename to docs/src/pages/components/menus/IconMenu.js index 1c4da197dd4449..d768ea53bca7cb 100644 --- a/docs/src/pages/components/menus/DesktopMenu.js +++ b/docs/src/pages/components/menus/IconMenu.js @@ -14,13 +14,13 @@ import ContentCopy from '@material-ui/icons/ContentCopy'; import ContentPaste from '@material-ui/icons/ContentPaste'; import Cloud from '@material-ui/icons/Cloud'; -export default function DesktopMenu() { +export default function IconMenu() { return ( - + Cut @@ -29,7 +29,7 @@ export default function DesktopMenu() { - + Copy @@ -38,7 +38,7 @@ export default function DesktopMenu() { - + Paste @@ -48,7 +48,7 @@ export default function DesktopMenu() { - + Web Clipboard diff --git a/docs/src/pages/components/menus/DesktopMenu.tsx b/docs/src/pages/components/menus/IconMenu.tsx similarity index 89% rename from docs/src/pages/components/menus/DesktopMenu.tsx rename to docs/src/pages/components/menus/IconMenu.tsx index 1c4da197dd4449..d768ea53bca7cb 100644 --- a/docs/src/pages/components/menus/DesktopMenu.tsx +++ b/docs/src/pages/components/menus/IconMenu.tsx @@ -14,13 +14,13 @@ import ContentCopy from '@material-ui/icons/ContentCopy'; import ContentPaste from '@material-ui/icons/ContentPaste'; import Cloud from '@material-ui/icons/Cloud'; -export default function DesktopMenu() { +export default function IconMenu() { return ( - + Cut @@ -29,7 +29,7 @@ export default function DesktopMenu() { - + Copy @@ -38,7 +38,7 @@ export default function DesktopMenu() { - + Paste @@ -48,7 +48,7 @@ export default function DesktopMenu() { - + Web Clipboard diff --git a/docs/src/pages/components/menus/menus.md b/docs/src/pages/components/menus/menus.md index 86173b57024b03..7705b9a3c5ce5a 100644 --- a/docs/src/pages/components/menus/menus.md +++ b/docs/src/pages/components/menus/menus.md @@ -24,11 +24,11 @@ Choosing an option should immediately ideally commit the option and close the me {{"demo": "pages/components/menus/BasicMenu.js"}} -## Desktop menu +## Icon menu In desktop viewport, padding is increased to give more space to the menu. -{{"demo": "pages/components/menus/DesktopMenu.js", "bg": true}} +{{"demo": "pages/components/menus/IconMenu.js", "bg": true}} ## Dense menu diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index 1cf0d7daaf1c22..85a11942246918 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -10,14 +10,10 @@ "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, "classDescriptions": { - "root": { - "description": "Styles applied to {{nodeName}}. May be wrapped by a `container`.", - "nodeName": "the (normally root) `component` element" - }, + "root": { "description": "Styles applied to the root element." }, "focusVisible": { - "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the `component`'s `focusVisibleClassName` prop", - "conditions": "button={true}" + "description": "Pseudo-class applied to {{nodeName}}.", + "nodeName": "the `component`'s `focusVisibleClassName` prop" }, "dense": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index 2c563700f61d96..a9e44be8a5c86f 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -11,7 +11,7 @@ import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; import listItemButtonClasses, { getListItemButtonUtilityClass } from './listItemButtonClasses'; -const overridesResolver = (props, styles) => { +export const overridesResolver = (props, styles) => { const { styleProps } = props; return { diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index edf93d80de6bc1..189f8795bf266c 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -27,6 +27,7 @@ const MenuItemRoot = styled(ListItemButton, { overridesResolver: listItemButtonOverridesResolver, })(({ theme, styleProps }) => ({ ...theme.typography.body1, + minHeight: 48, paddingTop: 6, paddingBottom: 6, minWidth: 56, @@ -37,6 +38,9 @@ const MenuItemRoot = styled(ListItemButton, { marginTop: theme.spacing(1), marginBottom: theme.spacing(1), }, + [`& + .${dividerClasses.inset}`]: { + marginLeft: 52, + }, [`& .${listItemTextClasses.root}`]: { marginTop: 0, marginBottom: 0, @@ -46,28 +50,19 @@ const MenuItemRoot = styled(ListItemButton, { }, [`& .${listItemIconClasses.root}`]: { minWidth: 36, - '& svg': { + }, + ...(!styleProps.dense && { + [theme.breakpoints.up('sm')]: { + minHeight: 'auto', + }, + }), + ...(styleProps.dense && { + minHeight: 36, + ...theme.typography.body2, + [`& .${listItemIconClasses.root} svg`]: { fontSize: '1.25rem', }, - }, - ...(styleProps.dense - ? { - ...theme.typography.body2, - } - : { - [theme.breakpoints.up('md')]: { - padding: '12px 24px', - [`& .${listItemTextClasses.inset}`]: { - paddingLeft: 44, - }, - [`& .${listItemIconClasses.root}`]: { - minWidth: 44, - '& svg': { - fontSize: '1.5rem', - }, - }, - }, - }), + }), })); const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { From 9f24af1f8b5f769584b58dc1cb32183833c7e9e9 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 8 Jun 2021 15:31:29 +0700 Subject: [PATCH 33/61] remove min-width --- packages/material-ui/src/MenuItem/MenuItem.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index 189f8795bf266c..64bd36c0faf497 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -30,7 +30,6 @@ const MenuItemRoot = styled(ListItemButton, { minHeight: 48, paddingTop: 6, paddingBottom: 6, - minWidth: 56, boxSizing: 'border-box', width: 'auto', whiteSpace: 'nowrap', From 884ec77696a0050ba6def49acb60f7faf6d8d6ef Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 8 Jun 2021 15:45:00 +0700 Subject: [PATCH 34/61] replace ListItemClasses --- test/regressions/fixtures/Menu/MenuContentAnchors.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/regressions/fixtures/Menu/MenuContentAnchors.js b/test/regressions/fixtures/Menu/MenuContentAnchors.js index 30dfb8ea593528..52eed220a76c1b 100644 --- a/test/regressions/fixtures/Menu/MenuContentAnchors.js +++ b/test/regressions/fixtures/Menu/MenuContentAnchors.js @@ -46,13 +46,13 @@ function SimpleMenu({ selectedItem, ...props }) { {null} - + Item 1 - + Item 2 - Item 3 + Item 3 ); From 23790db3179a72c7627ed14d6e4b340336c9438c Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 10 Jun 2021 12:05:43 +0700 Subject: [PATCH 35/61] replace ListItemButton with ButtonBase --- docs/pages/api-docs/menu-item.json | 15 +- .../pages/components/menus/CustomizedMenus.js | 5 +- .../components/menus/CustomizedMenus.tsx | 5 +- .../api-docs/menu-item/menu-item.json | 21 +-- .../src/ListItemButton/ListItemButton.js | 2 +- .../material-ui/src/MenuItem/MenuItem.d.ts | 67 +++++--- packages/material-ui/src/MenuItem/MenuItem.js | 149 ++++++++++++++---- .../src/MenuItem/menuItemClasses.ts | 17 +- 8 files changed, 178 insertions(+), 103 deletions(-) diff --git a/docs/pages/api-docs/menu-item.json b/docs/pages/api-docs/menu-item.json index e80faf5420cfbe..c001ec036987c3 100644 --- a/docs/pages/api-docs/menu-item.json +++ b/docs/pages/api-docs/menu-item.json @@ -1,25 +1,16 @@ { "props": { + "autoFocus": { "type": { "name": "bool" } }, "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" } }, "component": { "type": { "name": "elementType" } }, "dense": { "type": { "name": "bool" } }, - "disableGutters": { "type": { "name": "bool" } }, - "ListItemClasses": { "type": { "name": "object" } }, + "focusVisibleClassName": { "type": { "name": "string" } }, "sx": { "type": { "name": "object" } } }, "name": "MenuItem", "styles": { - "classes": [ - "root", - "focusVisible", - "dense", - "alignItemsFlexStart", - "disabled", - "divider", - "gutters", - "selected" - ], + "classes": ["root", "focusVisible", "dense", "disabled", "selected"], "globalClasses": { "focusVisible": "Mui-focusVisible", "disabled": "Mui-disabled", diff --git a/docs/src/pages/components/menus/CustomizedMenus.js b/docs/src/pages/components/menus/CustomizedMenus.js index 08f7a11f58aba6..e1fca61c861d45 100644 --- a/docs/src/pages/components/menus/CustomizedMenus.js +++ b/docs/src/pages/components/menus/CustomizedMenus.js @@ -32,11 +32,10 @@ const StyledMenu = styled((props) => ( theme.palette.mode === 'light' ? 'rgb(55, 65, 81)' : theme.palette.grey[300], boxShadow: 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px', - '& .MuiList-root': { + '& .MuiMenu-list': { padding: '4px 0', }, - '& .MuiListItemButton-root': { - ...theme.typography.body1, + '& .MuiMenuItem-root': { '& .MuiSvgIcon-root': { fontSize: 18, color: theme.palette.text.secondary, diff --git a/docs/src/pages/components/menus/CustomizedMenus.tsx b/docs/src/pages/components/menus/CustomizedMenus.tsx index 1060e33a46135a..9bfcd2030aa7cf 100644 --- a/docs/src/pages/components/menus/CustomizedMenus.tsx +++ b/docs/src/pages/components/menus/CustomizedMenus.tsx @@ -32,11 +32,10 @@ const StyledMenu = styled((props: MenuProps) => ( theme.palette.mode === 'light' ? 'rgb(55, 65, 81)' : theme.palette.grey[300], boxShadow: 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px', - '& .MuiList-root': { + '& .MuiMenu-list': { padding: '4px 0', }, - '& .MuiListItemButton-root': { - ...theme.typography.body1, + '& .MuiMenuItem-root': { '& .MuiSvgIcon-root': { fontSize: 18, color: theme.palette.text.secondary, diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index 85a11942246918..416f16153d9fa4 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -1,12 +1,12 @@ { "componentDescription": "", "propDescriptions": { + "autoFocus": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true.", "children": "The content of the component.", "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "component": "The component used for the root node. Either a string to use a HTML element or a component.", - "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component.", - "disableGutters": "If true, the left and right padding is removed.", - "ListItemClasses": "classes prop applied to the ListItem element.", + "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent Menu component.", + "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, "classDescriptions": { @@ -20,26 +20,11 @@ "nodeName": "the component element", "conditions": "dense" }, - "alignItemsFlexStart": { - "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the component element", - "conditions": "alignItems=\"flex-start\"" - }, "disabled": { "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", "nodeName": "the inner `component` element", "conditions": "disabled={true}" }, - "divider": { - "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the inner `component` element", - "conditions": "divider={true}" - }, - "gutters": { - "description": "Styles applied to {{nodeName}} unless {{conditions}}.", - "nodeName": "the inner `component` element", - "conditions": "disableGutters={true}" - }, "selected": { "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.js b/packages/material-ui/src/ListItemButton/ListItemButton.js index a9e44be8a5c86f..86bf1262b374d4 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.js @@ -144,7 +144,7 @@ const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) { listItemRef.current.focus(); } else if (process.env.NODE_ENV !== 'production') { console.error( - 'Material-UI: Unable to set focus to a ListItem whose component has not been rendered.', + 'Material-UI: Unable to set focus to a ListItemButton whose component has not been rendered.', ); } } diff --git a/packages/material-ui/src/MenuItem/MenuItem.d.ts b/packages/material-ui/src/MenuItem/MenuItem.d.ts index 734c4992c14169..7e01d4a4bf0790 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.d.ts +++ b/packages/material-ui/src/MenuItem/MenuItem.d.ts @@ -1,33 +1,48 @@ import { SxProps } from '@material-ui/system'; import { Theme } from '@material-ui/core/styles'; -import { DistributiveOmit } from '@material-ui/types'; -import { ListItemButtonTypeMap, ListItemButtonProps } from '../ListItemButton'; -import { OverridableComponent, OverrideProps } from '../OverridableComponent'; +import { ExtendButtonBase, ExtendButtonBaseTypeMap } from '../ButtonBase'; +import { OverrideProps } from '../OverridableComponent'; import { MenuItemClasses } from './menuItemClasses'; -export interface MenuItemTypeMap

{ - props: P & - DistributiveOmit['props'], 'children' | 'classes'> & { - /** - * The content of the component. - */ - children?: React.ReactNode; - /** - * Override or extend the styles applied to the component. - */ - classes?: Partial; - /** - * `classes` prop applied to the [`ListItem`](/api/list-item/) element. - * @deprecated this prop will be removed in v6, use `classes` instead - */ - ListItemClasses?: ListItemButtonProps['classes']; - /** - * The system prop that allows defining system overrides as well as additional CSS styles. - */ - sx?: SxProps; - }; +export type MenuItemTypeMap

= ExtendButtonBaseTypeMap<{ + props: P & { + /** + * If `true`, the list item is focused during the first mount. + * Focus will also be triggered if the value changes from false to true. + * @default false + */ + autoFocus?: boolean; + /** + * The content of the component. + */ + children?: React.ReactNode; + /** + * Override or extend the styles applied to the component. + */ + classes?: Partial; + /** + * If `true`, compact vertical padding designed for keyboard and mouse input is used. + * The prop defaults to the value inherited from the parent Menu component. + * @default false + */ + dense?: boolean; + /** + * If `true`, the component is disabled. + * @default false + */ + disabled?: boolean; + /** + * Use to apply selected styling. + * @default false + */ + selected?: boolean; + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx?: SxProps; + }; defaultComponent: D; -} +}>; /** * @@ -40,7 +55,7 @@ export interface MenuItemTypeMap

{ * - [MenuItem API](https://material-ui.com/api/menu-item/) * - inherits [ListItemButton API](https://material-ui.com/api/list-item-button/) */ -declare const MenuItem: OverridableComponent; +declare const MenuItem: ExtendButtonBase; export type MenuItemProps< D extends React.ElementType = MenuItemTypeMap['defaultComponent'], diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index 64bd36c0faf497..ed2c48599508df 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -1,38 +1,91 @@ import * as React from 'react'; import PropTypes from 'prop-types'; +import clsx from 'clsx'; import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; +import { alpha } from '../styles/colorManipulator'; import styled, { rootShouldForwardProp } from '../styles/styled'; import useThemeProps from '../styles/useThemeProps'; -import { getMenuItemUtilityClass } from './menuItemClasses'; import ListContext from '../List/ListContext'; -import ListItemButton from '../ListItemButton'; +import ButtonBase from '../ButtonBase'; +import useEnhancedEffect from '../utils/useEnhancedEffect'; +import useForkRef from '../utils/useForkRef'; import { dividerClasses } from '../Divider'; import { listItemIconClasses } from '../ListItemIcon'; import { listItemTextClasses } from '../ListItemText'; -import { overridesResolver as listItemButtonOverridesResolver } from '../ListItemButton/ListItemButton'; +import menuItemClasses, { getMenuItemUtilityClass } from './menuItemClasses'; + +export const overridesResolver = (props, styles) => { + const { styleProps } = props; + + return { + ...styles.root, + ...(styleProps.dense && styles.dense), + }; +}; const useUtilityClasses = (styleProps) => { - const { selected, dense, classes } = styleProps; + const { disabled, dense, selected, classes } = styleProps; const slots = { - root: ['root', selected && 'selected', dense && 'dense'], + root: ['root', dense && 'dense', disabled && 'disabled', selected && 'selected'], }; - return composeClasses(slots, getMenuItemUtilityClass, classes); + const composedClasses = composeClasses(slots, getMenuItemUtilityClass, classes); + + return { + ...classes, + ...composedClasses, + }; }; -const MenuItemRoot = styled(ListItemButton, { +const MenuItemRoot = styled(ButtonBase, { shouldForwardProp: (prop) => rootShouldForwardProp(prop) || prop === 'classes', name: 'MuiMenuItem', slot: 'Root', - overridesResolver: listItemButtonOverridesResolver, + overridesResolver, })(({ theme, styleProps }) => ({ ...theme.typography.body1, + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + position: 'relative', + textDecoration: 'none', minHeight: 48, - paddingTop: 6, - paddingBottom: 6, + padding: '6px 16px', boxSizing: 'border-box', - width: 'auto', whiteSpace: 'nowrap', + '&:hover': { + textDecoration: 'none', + backgroundColor: theme.palette.action.hover, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + [`&.${menuItemClasses.selected}`]: { + backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + [`&.${menuItemClasses.focusVisible}`]: { + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), + }, + }, + [`&.${menuItemClasses.selected}:hover`]: { + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + }, + }, + [`&.${menuItemClasses.focusVisible}`]: { + backgroundColor: theme.palette.action.focus, + }, + [`&.${menuItemClasses.disabled}`]: { + opacity: theme.palette.action.disabledOpacity, + }, [`& + .${dividerClasses.root}`]: { marginTop: theme.spacing(1), marginBottom: theme.spacing(1), @@ -67,40 +120,61 @@ const MenuItemRoot = styled(ListItemButton, { const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiMenuItem' }); const { + autoFocus = false, component = 'li', dense: denseProp = false, - disableGutters = false, + focusVisibleClassName, role = 'menuitem', - selected, tabIndex: tabIndexProp, ...other } = props; const context = React.useContext(ListContext); const dense = denseProp || context.dense || false; + const childContext = { + dense, + }; - const styleProps = { dense }; + const menuItemRef = React.useRef(null); + useEnhancedEffect(() => { + if (autoFocus) { + if (menuItemRef.current) { + menuItemRef.current.focus(); + } else if (process.env.NODE_ENV !== 'production') { + console.error( + 'Material-UI: Unable to set focus to a MenuItem whose component has not been rendered.', + ); + } + } + }, [autoFocus]); + + const styleProps = { + ...props, + dense, + }; const classes = useUtilityClasses(props); + const handleRef = useForkRef(menuItemRef, ref); + let tabIndex; if (!props.disabled) { tabIndex = tabIndexProp !== undefined ? tabIndexProp : -1; } return ( - + + + ); }); @@ -109,6 +183,12 @@ MenuItem.propTypes /* remove-proptypes */ = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- + /** + * If `true`, the list item is focused during the first mount. + * Focus will also be triggered if the value changes from false to true. + * @default false + */ + autoFocus: PropTypes.bool, /** * The content of the component. */ @@ -124,7 +204,7 @@ MenuItem.propTypes /* remove-proptypes */ = { component: PropTypes.elementType, /** * If `true`, compact vertical padding designed for keyboard and mouse input is used. - * The prop defaults to the value inherited from the parent List component. + * The prop defaults to the value inherited from the parent Menu component. * @default false */ dense: PropTypes.bool, @@ -133,15 +213,14 @@ MenuItem.propTypes /* remove-proptypes */ = { */ disabled: PropTypes.bool, /** - * If `true`, the left and right padding is removed. - * @default false - */ - disableGutters: PropTypes.bool, - /** - * `classes` prop applied to the [`ListItem`](/api/list-item/) element. - * @deprecated this prop will be removed in v6, use `classes` instead + * This prop can help identify which element has keyboard focus. + * The class name will be applied when the element gains the focus through keyboard interaction. + * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo). + * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/master/explainer.md). + * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `focus-visible` class to other components + * if needed. */ - ListItemClasses: PropTypes.object, + focusVisibleClassName: PropTypes.string, /** * @ignore */ diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index 52650f78d81089..b122e59ac98544 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -1,7 +1,17 @@ import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; -import { ListItemButtonClasses } from '../ListItemButton'; -export interface MenuItemClasses extends ListItemButtonClasses {} +export interface MenuItemClasses { + /** Styles applied to the root element. */ + root: string; + /** Pseudo-class applied to the `component`'s `focusVisibleClassName` prop. */ + focusVisible: string; + /** Styles applied to the component element if dense. */ + dense: string; + /** Pseudo-class applied to the inner `component` element if `disabled={true}`. */ + disabled: string; + /** Pseudo-class applied to the root element if `selected={true}`. */ + selected: string; +} export type MenuItemClassKey = keyof MenuItemClasses; @@ -13,10 +23,7 @@ const menuItemClasses: MenuItemClasses = generateUtilityClasses('MuiMenuItem', [ 'root', 'focusVisible', 'dense', - 'alignItemsFlexStart', 'disabled', - 'divider', - 'gutters', 'selected', ]); From c6480b0886763e2079ddcbf338f7ed2c6074b077 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 10 Jun 2021 12:15:47 +0700 Subject: [PATCH 36/61] fix tests --- .../material-ui/src/ListItemButton/ListItemButton.test.js | 4 +++- packages/material-ui/src/MenuItem/MenuItem.test.js | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.test.js b/packages/material-ui/src/ListItemButton/ListItemButton.test.js index 6e7161de3db096..2d3d530bdba876 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.test.js +++ b/packages/material-ui/src/ListItemButton/ListItemButton.test.js @@ -2,6 +2,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { createMount, describeConformanceV5, act, createClientRender, fireEvent } from 'test/utils'; import ListItemButton, { listItemButtonClasses as classes } from '@material-ui/core/ListItemButton'; +import ButtonBase from '@material-ui/core/ButtonBase'; import ListContext from '../List/ListContext'; describe('', () => { @@ -10,10 +11,11 @@ describe('', () => { describeConformanceV5(, () => ({ classes, - inheritComponent: 'div', + inheritComponent: ButtonBase, render, mount, refInstanceof: window.HTMLDivElement, + testComponentPropWith: 'a', muiName: 'MuiListItemButton', testVariantProps: { dense: true }, skip: ['componentsProp'], diff --git a/packages/material-ui/src/MenuItem/MenuItem.test.js b/packages/material-ui/src/MenuItem/MenuItem.test.js index 9536199829d7eb..33122d0dcdd256 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.test.js +++ b/packages/material-ui/src/MenuItem/MenuItem.test.js @@ -10,7 +10,7 @@ import { screen, } from 'test/utils'; import MenuItem, { menuItemClasses as classes } from '@material-ui/core/MenuItem'; -import ListItemButton from '@material-ui/core/ListItemButton'; +import ButtonBase from '@material-ui/core/ButtonBase'; describe('', () => { const render = createClientRender(); @@ -18,13 +18,13 @@ describe('', () => { describeConformanceV5(, () => ({ classes, - inheritComponent: ListItemButton, + inheritComponent: ButtonBase, render, mount, refInstanceof: window.HTMLLIElement, testComponentPropWith: 'a', muiName: 'MuiMenuItem', - testVariantProps: { disableGutters: true }, + testVariantProps: { dense: true }, skip: ['componentsProp'], })); From 6febdafb97ab608ca8b0e4eaf80a575c1d8bc090 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 10 Jun 2021 12:30:24 +0700 Subject: [PATCH 37/61] bring back divider prop --- docs/pages/api-docs/list-item-button.json | 2 +- docs/pages/api-docs/menu-item.json | 5 +++-- .../pages/guides/migration-v4/migration-v4.md | 11 ++++++++++ .../api-docs/menu-item/menu-item.json | 6 +++++ .../src/ListItemButton/ListItemButton.d.ts | 1 + .../material-ui/src/MenuItem/MenuItem.d.ts | 7 +++++- packages/material-ui/src/MenuItem/MenuItem.js | 22 +++++++++++++++++-- .../src/MenuItem/menuItemClasses.ts | 3 +++ 8 files changed, 51 insertions(+), 6 deletions(-) diff --git a/docs/pages/api-docs/list-item-button.json b/docs/pages/api-docs/list-item-button.json index f25ff8d3172ffc..96e78a7956382b 100644 --- a/docs/pages/api-docs/list-item-button.json +++ b/docs/pages/api-docs/list-item-button.json @@ -38,7 +38,7 @@ "spread": true, "forwardsRefTo": "HTMLDivElement", "filename": "/packages/material-ui/src/ListItemButton/ListItemButton.js", - "inheritance": null, + "inheritance": { "component": "ButtonBase", "pathname": "/api/button-base/" }, "demos": "

", "styledComponent": true, "cssComponent": false diff --git a/docs/pages/api-docs/menu-item.json b/docs/pages/api-docs/menu-item.json index c001ec036987c3..71978982f29923 100644 --- a/docs/pages/api-docs/menu-item.json +++ b/docs/pages/api-docs/menu-item.json @@ -5,12 +5,13 @@ "classes": { "type": { "name": "object" } }, "component": { "type": { "name": "elementType" } }, "dense": { "type": { "name": "bool" } }, + "divider": { "type": { "name": "bool" } }, "focusVisibleClassName": { "type": { "name": "string" } }, "sx": { "type": { "name": "object" } } }, "name": "MenuItem", "styles": { - "classes": ["root", "focusVisible", "dense", "disabled", "selected"], + "classes": ["root", "focusVisible", "dense", "disabled", "divider", "selected"], "globalClasses": { "focusVisible": "Mui-focusVisible", "disabled": "Mui-disabled", @@ -21,7 +22,7 @@ "spread": true, "forwardsRefTo": "HTMLLIElement", "filename": "/packages/material-ui/src/MenuItem/MenuItem.js", - "inheritance": { "component": "ListItemButton", "pathname": "/api/list-item-button/" }, + "inheritance": { "component": "ButtonBase", "pathname": "/api/button-base/" }, "demos": "", "styledComponent": true, "cssComponent": false diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index d1701f2b06457b..ed2684dcae93ab 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -994,6 +994,17 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m You can use the [`use-transitionprops` codemod](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui-codemod#use-transitionprops) for automatic migration. +### MenuItem + +- the `ListItem` inheritance is replaced by `ButtonBase`. ClassNames related to "MuiListItem-*" are removed. Theming `ListItem` is no longer affect `MenuItem`. + + ```diff + -
  • + +
  • + ``` + +- prop `disabledGutters` is removed. + ### Modal - Remove the `disableBackdropClick` prop because it is redundant. diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index 416f16153d9fa4..2daa347052b391 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -6,6 +6,7 @@ "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "component": "The component used for the root node. Either a string to use a HTML element or a component.", "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent Menu component.", + "divider": "If true, a 1px light border is added to the bottom of the menu item.", "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, @@ -25,6 +26,11 @@ "nodeName": "the inner `component` element", "conditions": "disabled={true}" }, + "divider": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "divider={true}" + }, "selected": { "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts index 5996855958dbe6..71fef4684ea1d8 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts +++ b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts @@ -73,6 +73,7 @@ export type ListItemButtonTypeMap

    = * API: * * - [ListItemButton API](https://material-ui.com/api/list-item-button/) + * - inherits [ButtonBase API](https://material-ui.com/api/button-base/) */ declare const ListItemButton: ExtendButtonBase; diff --git a/packages/material-ui/src/MenuItem/MenuItem.d.ts b/packages/material-ui/src/MenuItem/MenuItem.d.ts index 7e01d4a4bf0790..eb7bdb38a8de9a 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.d.ts +++ b/packages/material-ui/src/MenuItem/MenuItem.d.ts @@ -31,6 +31,11 @@ export type MenuItemTypeMap

    = Extend * @default false */ disabled?: boolean; + /** + * If `true`, a 1px light border is added to the bottom of the menu item. + * @default false + */ + divider?: boolean; /** * Use to apply selected styling. * @default false @@ -53,7 +58,7 @@ export type MenuItemTypeMap

    = Extend * API: * * - [MenuItem API](https://material-ui.com/api/menu-item/) - * - inherits [ListItemButton API](https://material-ui.com/api/list-item-button/) + * - inherits [ButtonBase API](https://material-ui.com/api/button-base/) */ declare const MenuItem: ExtendButtonBase; diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index ed2c48599508df..e538c7ec709d2b 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -20,13 +20,20 @@ export const overridesResolver = (props, styles) => { return { ...styles.root, ...(styleProps.dense && styles.dense), + ...(styleProps.divider && styles.divider), }; }; const useUtilityClasses = (styleProps) => { - const { disabled, dense, selected, classes } = styleProps; + const { disabled, dense, divider, selected, classes } = styleProps; const slots = { - root: ['root', dense && 'dense', disabled && 'disabled', selected && 'selected'], + root: [ + 'root', + dense && 'dense', + disabled && 'disabled', + divider && 'divider', + selected && 'selected', + ], }; const composedClasses = composeClasses(slots, getMenuItemUtilityClass, classes); @@ -86,6 +93,10 @@ const MenuItemRoot = styled(ButtonBase, { [`&.${menuItemClasses.disabled}`]: { opacity: theme.palette.action.disabledOpacity, }, + ...(styleProps.divider && { + borderBottom: `1px solid ${theme.palette.divider}`, + backgroundClip: 'padding-box', + }), [`& + .${dividerClasses.root}`]: { marginTop: theme.spacing(1), marginBottom: theme.spacing(1), @@ -123,6 +134,7 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { autoFocus = false, component = 'li', dense: denseProp = false, + divider = false, focusVisibleClassName, role = 'menuitem', tabIndex: tabIndexProp, @@ -151,6 +163,7 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const styleProps = { ...props, dense, + divider, }; const classes = useUtilityClasses(props); @@ -212,6 +225,11 @@ MenuItem.propTypes /* remove-proptypes */ = { * @ignore */ disabled: PropTypes.bool, + /** + * If `true`, a 1px light border is added to the bottom of the menu item. + * @default false + */ + divider: PropTypes.bool, /** * This prop can help identify which element has keyboard focus. * The class name will be applied when the element gains the focus through keyboard interaction. diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index b122e59ac98544..5bde5faad5c9ea 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -9,6 +9,8 @@ export interface MenuItemClasses { dense: string; /** Pseudo-class applied to the inner `component` element if `disabled={true}`. */ disabled: string; + /** Styles applied to the inner `component` element if `divider={true}`. */ + divider: string; /** Pseudo-class applied to the root element if `selected={true}`. */ selected: string; } @@ -24,6 +26,7 @@ const menuItemClasses: MenuItemClasses = generateUtilityClasses('MuiMenuItem', [ 'focusVisible', 'dense', 'disabled', + 'divider', 'selected', ]); From c6804557d65dc1d621eb4c4705fe3d9f7eee7eca Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 10 Jun 2021 12:36:41 +0700 Subject: [PATCH 38/61] run prettier --- docs/src/pages/guides/migration-v4/migration-v4.md | 2 +- .../src/ListItemButton/ListItemButton.d.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index ed2684dcae93ab..af2b8247780ae7 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -996,7 +996,7 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m ### MenuItem -- the `ListItem` inheritance is replaced by `ButtonBase`. ClassNames related to "MuiListItem-*" are removed. Theming `ListItem` is no longer affect `MenuItem`. +- the `ListItem` inheritance is replaced by `ButtonBase`. ClassNames related to "MuiListItem-\*" are removed and theming `ListItem` is no longer affecting `MenuItem`. ```diff -

  • diff --git a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts index 71fef4684ea1d8..a452f58e486fc3 100644 --- a/packages/material-ui/src/ListItemButton/ListItemButton.d.ts +++ b/packages/material-ui/src/ListItemButton/ListItemButton.d.ts @@ -58,11 +58,13 @@ interface ListItemButtonBaseProps { sx?: SxProps; } -export type ListItemButtonTypeMap

    = - ExtendButtonBaseTypeMap<{ - props: P & ListItemButtonBaseProps; - defaultComponent: D; - }>; +export type ListItemButtonTypeMap< + P = {}, + D extends React.ElementType = 'div', +> = ExtendButtonBaseTypeMap<{ + props: P & ListItemButtonBaseProps; + defaultComponent: D; +}>; /** * From 2ab4564d569dcd52f1310a49e326f495cb54c047 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 10 Jun 2021 16:41:33 +0700 Subject: [PATCH 39/61] fix default anchorOrigin --- docs/src/pages/guides/migration-v4/migration-v4.md | 9 +++++++++ packages/material-ui/src/Menu/Menu.js | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index af2b8247780ae7..c19412ffe1c35e 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -994,6 +994,15 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m You can use the [`use-transitionprops` codemod](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui-codemod#use-transitionprops) for automatic migration. +- Default `anchorOrigin.vertical` is changed + + ```diff + { + - vertical: 'bottom', + + vertical: 'top', + } + ``` + ### MenuItem - the `ListItem` inheritance is replaced by `ButtonBase`. ClassNames related to "MuiListItem-\*" are removed and theming `ListItem` is no longer affecting `MenuItem`. diff --git a/packages/material-ui/src/Menu/Menu.js b/packages/material-ui/src/Menu/Menu.js index 77e3510f7c28a3..805eda4eb677b0 100644 --- a/packages/material-ui/src/Menu/Menu.js +++ b/packages/material-ui/src/Menu/Menu.js @@ -157,7 +157,10 @@ const Menu = React.forwardRef(function Menu(inProps, ref) { Date: Fri, 11 Jun 2021 09:08:12 +0700 Subject: [PATCH 40/61] Update packages/material-ui/src/MenuItem/menuItemClasses.ts Co-authored-by: Olivier Tassinari --- packages/material-ui/src/MenuItem/menuItemClasses.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index 5bde5faad5c9ea..b5d7eb9a4e75f4 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -9,7 +9,7 @@ export interface MenuItemClasses { dense: string; /** Pseudo-class applied to the inner `component` element if `disabled={true}`. */ disabled: string; - /** Styles applied to the inner `component` element if `divider={true}`. */ + /** Styles applied to the root element if `divider={true}`. */ divider: string; /** Pseudo-class applied to the root element if `selected={true}`. */ selected: string; From 04d03361cea2c9b297c8d0f36e106f05ac3655ca Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:08:23 +0700 Subject: [PATCH 41/61] Update docs/src/pages/components/menus/DenseMenu.tsx Co-authored-by: Olivier Tassinari --- docs/src/pages/components/menus/DenseMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/components/menus/DenseMenu.tsx b/docs/src/pages/components/menus/DenseMenu.tsx index 805428a0b3b36e..13e80f111bdf49 100644 --- a/docs/src/pages/components/menus/DenseMenu.tsx +++ b/docs/src/pages/components/menus/DenseMenu.tsx @@ -11,7 +11,7 @@ import ArrowRight from '@material-ui/icons/ArrowRight'; export default function DenseMenu() { return ( - + Single From fbb3db415265f503dabcda99d4a693906876f8d1 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:08:31 +0700 Subject: [PATCH 42/61] Update packages/material-ui/src/MenuItem/menuItemClasses.ts Co-authored-by: Olivier Tassinari --- packages/material-ui/src/MenuItem/menuItemClasses.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index b5d7eb9a4e75f4..9b8345939295bc 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -7,7 +7,7 @@ export interface MenuItemClasses { focusVisible: string; /** Styles applied to the component element if dense. */ dense: string; - /** Pseudo-class applied to the inner `component` element if `disabled={true}`. */ + /** Pseudo-class applied to the root element if `disabled={true}`. */ disabled: string; /** Styles applied to the root element if `divider={true}`. */ divider: string; From 907847d5570ccb74143f96cac9dc8bb1a14f24c8 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:08:39 +0700 Subject: [PATCH 43/61] Update docs/src/pages/components/menus/menus.md Co-authored-by: Olivier Tassinari --- docs/src/pages/components/menus/menus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/components/menus/menus.md b/docs/src/pages/components/menus/menus.md index 7705b9a3c5ce5a..1273cc46834a3e 100644 --- a/docs/src/pages/components/menus/menus.md +++ b/docs/src/pages/components/menus/menus.md @@ -65,7 +65,7 @@ The primary responsibility of the `MenuList` component is to handle the focus. `Menu` content can be mixed with other component like `Avatar`. -{{"demo": "pages/components/menus/AccountMenu.js", "bg": true}} +{{"demo": "pages/components/menus/AccountMenu.js"}} ## Customized menu From 9ba402b3d4bcb5e46bce87349cb686aecbc8c29f Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:08:47 +0700 Subject: [PATCH 44/61] Update docs/src/pages/components/menus/IconMenu.tsx Co-authored-by: Olivier Tassinari --- docs/src/pages/components/menus/IconMenu.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/pages/components/menus/IconMenu.tsx b/docs/src/pages/components/menus/IconMenu.tsx index d768ea53bca7cb..f81abf542744dd 100644 --- a/docs/src/pages/components/menus/IconMenu.tsx +++ b/docs/src/pages/components/menus/IconMenu.tsx @@ -7,7 +7,6 @@ import MenuItem from '@material-ui/core/MenuItem'; import ListItemText from '@material-ui/core/ListItemText'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import Typography from '@material-ui/core/Typography'; - import ArrowRight from '@material-ui/icons/ArrowRight'; import ContentCut from '@material-ui/icons/ContentCut'; import ContentCopy from '@material-ui/icons/ContentCopy'; From 7ae4c03b43e42606706efd46b3a42bfeda5390f9 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:08:55 +0700 Subject: [PATCH 45/61] Update docs/src/pages/components/menus/IconMenu.tsx Co-authored-by: Olivier Tassinari --- docs/src/pages/components/menus/IconMenu.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/pages/components/menus/IconMenu.tsx b/docs/src/pages/components/menus/IconMenu.tsx index f81abf542744dd..744b9a22a924d1 100644 --- a/docs/src/pages/components/menus/IconMenu.tsx +++ b/docs/src/pages/components/menus/IconMenu.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; - import Divider from '@material-ui/core/Divider'; import Paper from '@material-ui/core/Paper'; import MenuList from '@material-ui/core/MenuList'; From 79f9b555cb950396c3aa7b48860f0b1cf879504b Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:09:02 +0700 Subject: [PATCH 46/61] Update docs/src/pages/components/menus/DenseMenu.tsx Co-authored-by: Olivier Tassinari --- docs/src/pages/components/menus/DenseMenu.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/pages/components/menus/DenseMenu.tsx b/docs/src/pages/components/menus/DenseMenu.tsx index 13e80f111bdf49..38349fc125c4b7 100644 --- a/docs/src/pages/components/menus/DenseMenu.tsx +++ b/docs/src/pages/components/menus/DenseMenu.tsx @@ -5,7 +5,6 @@ import MenuList from '@material-ui/core/MenuList'; import MenuItem from '@material-ui/core/MenuItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; - import Check from '@material-ui/icons/Check'; import ArrowRight from '@material-ui/icons/ArrowRight'; From 6f6f588a7682c6ed03fc63f29b0d752dd5ae2c46 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:09:08 +0700 Subject: [PATCH 47/61] Update docs/src/pages/components/menus/AccountMenu.tsx Co-authored-by: Olivier Tassinari --- docs/src/pages/components/menus/AccountMenu.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/pages/components/menus/AccountMenu.tsx b/docs/src/pages/components/menus/AccountMenu.tsx index 07e2b2beec7379..4d747b964d0101 100644 --- a/docs/src/pages/components/menus/AccountMenu.tsx +++ b/docs/src/pages/components/menus/AccountMenu.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; - import Box from '@material-ui/core/Box'; import Avatar from '@material-ui/core/Avatar'; import Menu from '@material-ui/core/Menu'; From fc22985ed0fce9ee230fb7a2766ed8d7a9bc56ad Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 11 Jun 2021 09:14:04 +0700 Subject: [PATCH 48/61] update demos --- docs/src/pages/components/menus/AccountMenu.js | 1 - docs/src/pages/components/menus/DenseMenu.js | 5 +---- docs/src/pages/components/menus/DenseMenu.tsx | 2 -- docs/src/pages/components/menus/IconMenu.js | 2 -- docs/src/pages/components/menus/PositionedMenu.js | 2 +- docs/src/pages/components/menus/PositionedMenu.tsx | 2 +- docs/src/pages/components/menus/menus.md | 2 +- docs/translations/api-docs/menu-item/menu-item.json | 4 ++-- 8 files changed, 6 insertions(+), 14 deletions(-) diff --git a/docs/src/pages/components/menus/AccountMenu.js b/docs/src/pages/components/menus/AccountMenu.js index e13067612ca972..fbc93cc6437443 100644 --- a/docs/src/pages/components/menus/AccountMenu.js +++ b/docs/src/pages/components/menus/AccountMenu.js @@ -1,5 +1,4 @@ import * as React from 'react'; - import Box from '@material-ui/core/Box'; import Avatar from '@material-ui/core/Avatar'; import Menu from '@material-ui/core/Menu'; diff --git a/docs/src/pages/components/menus/DenseMenu.js b/docs/src/pages/components/menus/DenseMenu.js index 805428a0b3b36e..41643f16cb39ec 100644 --- a/docs/src/pages/components/menus/DenseMenu.js +++ b/docs/src/pages/components/menus/DenseMenu.js @@ -5,13 +5,11 @@ import MenuList from '@material-ui/core/MenuList'; import MenuItem from '@material-ui/core/MenuItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; - import Check from '@material-ui/icons/Check'; -import ArrowRight from '@material-ui/icons/ArrowRight'; export default function DenseMenu() { return ( - + Single @@ -34,7 +32,6 @@ export default function DenseMenu() { Add space after paragraph - diff --git a/docs/src/pages/components/menus/DenseMenu.tsx b/docs/src/pages/components/menus/DenseMenu.tsx index 38349fc125c4b7..41643f16cb39ec 100644 --- a/docs/src/pages/components/menus/DenseMenu.tsx +++ b/docs/src/pages/components/menus/DenseMenu.tsx @@ -6,7 +6,6 @@ import MenuItem from '@material-ui/core/MenuItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Check from '@material-ui/icons/Check'; -import ArrowRight from '@material-ui/icons/ArrowRight'; export default function DenseMenu() { return ( @@ -33,7 +32,6 @@ export default function DenseMenu() { Add space after paragraph - diff --git a/docs/src/pages/components/menus/IconMenu.js b/docs/src/pages/components/menus/IconMenu.js index d768ea53bca7cb..744b9a22a924d1 100644 --- a/docs/src/pages/components/menus/IconMenu.js +++ b/docs/src/pages/components/menus/IconMenu.js @@ -1,5 +1,4 @@ import * as React from 'react'; - import Divider from '@material-ui/core/Divider'; import Paper from '@material-ui/core/Paper'; import MenuList from '@material-ui/core/MenuList'; @@ -7,7 +6,6 @@ import MenuItem from '@material-ui/core/MenuItem'; import ListItemText from '@material-ui/core/ListItemText'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import Typography from '@material-ui/core/Typography'; - import ArrowRight from '@material-ui/icons/ArrowRight'; import ContentCut from '@material-ui/icons/ContentCut'; import ContentCopy from '@material-ui/icons/ContentCopy'; diff --git a/docs/src/pages/components/menus/PositionedMenu.js b/docs/src/pages/components/menus/PositionedMenu.js index 38ccd186946817..4cd9c813f5bc29 100644 --- a/docs/src/pages/components/menus/PositionedMenu.js +++ b/docs/src/pages/components/menus/PositionedMenu.js @@ -31,7 +31,7 @@ export default function PositionedMenu() { open={open} onClose={handleClose} anchorOrigin={{ - vertical: 'bottom', + vertical: 'top', horizontal: 'left', }} transformOrigin={{ diff --git a/docs/src/pages/components/menus/PositionedMenu.tsx b/docs/src/pages/components/menus/PositionedMenu.tsx index 251f9dbddbc253..44c044668f6457 100644 --- a/docs/src/pages/components/menus/PositionedMenu.tsx +++ b/docs/src/pages/components/menus/PositionedMenu.tsx @@ -31,7 +31,7 @@ export default function PositionedMenu() { open={open} onClose={handleClose} anchorOrigin={{ - vertical: 'bottom', + vertical: 'top', horizontal: 'left', }} transformOrigin={{ diff --git a/docs/src/pages/components/menus/menus.md b/docs/src/pages/components/menus/menus.md index 1273cc46834a3e..3b7520a787c993 100644 --- a/docs/src/pages/components/menus/menus.md +++ b/docs/src/pages/components/menus/menus.md @@ -47,7 +47,7 @@ To use a selected menu item without impacting the initial focus, set the `varian ## Positioned menu Because the `Menu` component uses the `Popover` component to position itself, you can use the same [positioning props](/components/popover/#anchor-playground) to position it. -For instance, you can display the menu below the anchor: +For instance, you can display the menu on top of the anchor: {{"demo": "pages/components/menus/PositionedMenu.js"}} diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index 2daa347052b391..e1cc63298c51db 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -23,12 +23,12 @@ }, "disabled": { "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the inner `component` element", + "nodeName": "the root element", "conditions": "disabled={true}" }, "divider": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the inner `component` element", + "nodeName": "the root element", "conditions": "divider={true}" }, "selected": { From 6165408c0005ef5445177c05490827117a39978a Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 11 Jun 2021 09:21:51 +0700 Subject: [PATCH 49/61] remove arrow from demo --- docs/src/pages/components/menus/IconMenu.js | 2 -- docs/src/pages/components/menus/IconMenu.tsx | 2 -- 2 files changed, 4 deletions(-) diff --git a/docs/src/pages/components/menus/IconMenu.js b/docs/src/pages/components/menus/IconMenu.js index 744b9a22a924d1..d20f15849ce337 100644 --- a/docs/src/pages/components/menus/IconMenu.js +++ b/docs/src/pages/components/menus/IconMenu.js @@ -6,7 +6,6 @@ import MenuItem from '@material-ui/core/MenuItem'; import ListItemText from '@material-ui/core/ListItemText'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import Typography from '@material-ui/core/Typography'; -import ArrowRight from '@material-ui/icons/ArrowRight'; import ContentCut from '@material-ui/icons/ContentCut'; import ContentCopy from '@material-ui/icons/ContentCopy'; import ContentPaste from '@material-ui/icons/ContentPaste'; @@ -49,7 +48,6 @@ export default function IconMenu() { Web Clipboard - diff --git a/docs/src/pages/components/menus/IconMenu.tsx b/docs/src/pages/components/menus/IconMenu.tsx index 744b9a22a924d1..d20f15849ce337 100644 --- a/docs/src/pages/components/menus/IconMenu.tsx +++ b/docs/src/pages/components/menus/IconMenu.tsx @@ -6,7 +6,6 @@ import MenuItem from '@material-ui/core/MenuItem'; import ListItemText from '@material-ui/core/ListItemText'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import Typography from '@material-ui/core/Typography'; -import ArrowRight from '@material-ui/icons/ArrowRight'; import ContentCut from '@material-ui/icons/ContentCut'; import ContentCopy from '@material-ui/icons/ContentCopy'; import ContentPaste from '@material-ui/icons/ContentPaste'; @@ -49,7 +48,6 @@ export default function IconMenu() { Web Clipboard - From 82152bbb5d7921da87bcb946d0ade7b71c578170 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 09:56:05 +0700 Subject: [PATCH 50/61] Apply suggestions from code review Co-authored-by: Olivier Tassinari --- packages/material-ui/src/MenuItem/menuItemClasses.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index 9b8345939295bc..7ddb1462f7c1a3 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -3,9 +3,9 @@ import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unsty export interface MenuItemClasses { /** Styles applied to the root element. */ root: string; - /** Pseudo-class applied to the `component`'s `focusVisibleClassName` prop. */ + /** Pseudo-class applied to the ButtonBase root element if the button is keyboard focused. */ focusVisible: string; - /** Styles applied to the component element if dense. */ + /** Styles applied to the root element if dense. */ dense: string; /** Pseudo-class applied to the root element if `disabled={true}`. */ disabled: string; From 99fafc0f02fffaa6d4acf83ee14e1bf99621b0da Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Fri, 11 Jun 2021 10:01:43 +0700 Subject: [PATCH 51/61] Apply suggestions from code review Co-authored-by: Olivier Tassinari --- docs/src/pages/guides/migration-v4/migration-v4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index c19412ffe1c35e..dd6efc60930076 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -1005,14 +1005,14 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m ### MenuItem -- the `ListItem` inheritance is replaced by `ButtonBase`. ClassNames related to "MuiListItem-\*" are removed and theming `ListItem` is no longer affecting `MenuItem`. +- The `ListItem` inheritance is replaced by `ButtonBase`. ClassNames related to "MuiListItem-\*" are removed and theming `ListItem` is no longer affecting `MenuItem`. ```diff -

  • +
  • ``` -- prop `disabledGutters` is removed. +- Remove the `disabledGutters` prop. ### Modal From fea2336974429a7877d932cb1841e7c5102ec275 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 11 Jun 2021 10:15:43 +0700 Subject: [PATCH 52/61] bring disableGutters back --- docs/pages/api-docs/menu-item.json | 3 +- .../pages/guides/migration-v4/migration-v4.md | 2 - .../api-docs/menu-item/menu-item.json | 13 +++++-- .../material-ui/src/MenuItem/MenuItem.d.ts | 5 +++ packages/material-ui/src/MenuItem/MenuItem.js | 34 ++++++++++++----- .../material-ui/src/MenuItem/MenuItem.test.js | 38 ++++++++++++++++++- .../src/MenuItem/menuItemClasses.ts | 3 ++ 7 files changed, 81 insertions(+), 17 deletions(-) diff --git a/docs/pages/api-docs/menu-item.json b/docs/pages/api-docs/menu-item.json index 71978982f29923..e73cb95a5bcfa1 100644 --- a/docs/pages/api-docs/menu-item.json +++ b/docs/pages/api-docs/menu-item.json @@ -5,13 +5,14 @@ "classes": { "type": { "name": "object" } }, "component": { "type": { "name": "elementType" } }, "dense": { "type": { "name": "bool" } }, + "disableGutters": { "type": { "name": "bool" } }, "divider": { "type": { "name": "bool" } }, "focusVisibleClassName": { "type": { "name": "string" } }, "sx": { "type": { "name": "object" } } }, "name": "MenuItem", "styles": { - "classes": ["root", "focusVisible", "dense", "disabled", "divider", "selected"], + "classes": ["root", "focusVisible", "dense", "disabled", "divider", "gutters", "selected"], "globalClasses": { "focusVisible": "Mui-focusVisible", "disabled": "Mui-disabled", diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index dd6efc60930076..b6b62758ea1da0 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -1012,8 +1012,6 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m +
  • ``` -- Remove the `disabledGutters` prop. - ### Modal - Remove the `disableBackdropClick` prop because it is redundant. diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index e1cc63298c51db..310a8a5765e73e 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -6,6 +6,7 @@ "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "component": "The component used for the root node. Either a string to use a HTML element or a component.", "dense": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent Menu component.", + "disableGutters": "If true, the left and right padding is removed.", "divider": "If true, a 1px light border is added to the bottom of the menu item.", "focusVisibleClassName": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the CSS :focus-visible selector. The rationale for using this feature is explained here. A polyfill can be used to apply a focus-visible class to other components if needed.", "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." @@ -13,12 +14,13 @@ "classDescriptions": { "root": { "description": "Styles applied to the root element." }, "focusVisible": { - "description": "Pseudo-class applied to {{nodeName}}.", - "nodeName": "the `component`'s `focusVisibleClassName` prop" + "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the ButtonBase root element", + "conditions": "the button is keyboard focused" }, "dense": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the component element", + "nodeName": "the root element", "conditions": "dense" }, "disabled": { @@ -31,6 +33,11 @@ "nodeName": "the root element", "conditions": "divider={true}" }, + "gutters": { + "description": "Styles applied to {{nodeName}} unless {{conditions}}.", + "nodeName": "the inner `component` element", + "conditions": "disableGutters={true}" + }, "selected": { "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", diff --git a/packages/material-ui/src/MenuItem/MenuItem.d.ts b/packages/material-ui/src/MenuItem/MenuItem.d.ts index eb7bdb38a8de9a..0b588ba439cf84 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.d.ts +++ b/packages/material-ui/src/MenuItem/MenuItem.d.ts @@ -31,6 +31,11 @@ export type MenuItemTypeMap

    = Extend * @default false */ disabled?: boolean; + /** + * If `true`, the left and right padding is removed. + * @default false + */ + disableGutters?: boolean; /** * If `true`, a 1px light border is added to the bottom of the menu item. * @default false diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index e538c7ec709d2b..c2d1943205fede 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -21,16 +21,18 @@ export const overridesResolver = (props, styles) => { ...styles.root, ...(styleProps.dense && styles.dense), ...(styleProps.divider && styles.divider), + ...(!styleProps.disableGutters && styles.gutters), }; }; const useUtilityClasses = (styleProps) => { - const { disabled, dense, divider, selected, classes } = styleProps; + const { disabled, dense, divider, disableGutters, selected, classes } = styleProps; const slots = { root: [ 'root', dense && 'dense', disabled && 'disabled', + !disableGutters && 'gutters', divider && 'divider', selected && 'selected', ], @@ -57,9 +59,18 @@ const MenuItemRoot = styled(ButtonBase, { position: 'relative', textDecoration: 'none', minHeight: 48, - padding: '6px 16px', + paddingTop: 6, + paddingBottom: 6, boxSizing: 'border-box', whiteSpace: 'nowrap', + ...(!styleProps.disableGutters && { + paddingLeft: 16, + paddingRight: 16, + }), + ...(styleProps.divider && { + borderBottom: `1px solid ${theme.palette.divider}`, + backgroundClip: 'padding-box', + }), '&:hover': { textDecoration: 'none', backgroundColor: theme.palette.action.hover, @@ -93,10 +104,6 @@ const MenuItemRoot = styled(ButtonBase, { [`&.${menuItemClasses.disabled}`]: { opacity: theme.palette.action.disabledOpacity, }, - ...(styleProps.divider && { - borderBottom: `1px solid ${theme.palette.divider}`, - backgroundClip: 'padding-box', - }), [`& + .${dividerClasses.root}`]: { marginTop: theme.spacing(1), marginBottom: theme.spacing(1), @@ -133,8 +140,9 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const { autoFocus = false, component = 'li', - dense: denseProp = false, + dense = false, divider = false, + disableGutters = false, focusVisibleClassName, role = 'menuitem', tabIndex: tabIndexProp, @@ -142,9 +150,9 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { } = props; const context = React.useContext(ListContext); - const dense = denseProp || context.dense || false; const childContext = { - dense, + dense: dense || context.dense || false, + disableGutters, }; const menuItemRef = React.useRef(null); @@ -162,8 +170,9 @@ const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const styleProps = { ...props, - dense, + dense: childContext.dense, divider, + disableGutters, }; const classes = useUtilityClasses(props); @@ -225,6 +234,11 @@ MenuItem.propTypes /* remove-proptypes */ = { * @ignore */ disabled: PropTypes.bool, + /** + * If `true`, the left and right padding is removed. + * @default false + */ + disableGutters: PropTypes.bool, /** * If `true`, a 1px light border is added to the bottom of the menu item. * @default false diff --git a/packages/material-ui/src/MenuItem/MenuItem.test.js b/packages/material-ui/src/MenuItem/MenuItem.test.js index 33122d0dcdd256..5d281e29c82dd2 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.test.js +++ b/packages/material-ui/src/MenuItem/MenuItem.test.js @@ -1,4 +1,3 @@ -// @ts-check import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; @@ -11,6 +10,7 @@ import { } from 'test/utils'; import MenuItem, { menuItemClasses as classes } from '@material-ui/core/MenuItem'; import ButtonBase from '@material-ui/core/ButtonBase'; +import ListContext from '../List/ListContext'; describe('', () => { const render = createClientRender(); @@ -132,4 +132,40 @@ describe('', () => { expect(menuitem).to.have.attribute('aria-disabled', 'true'); }); + + it('can be selected', () => { + render(); + const menuitem = screen.getByRole('menuitem'); + + expect(menuitem).to.have.class(classes.selected); + }); + + it('prop: disableGutters', () => { + const { rerender } = render(); + const menuitem = screen.getByRole('menuitem'); + + expect(menuitem).to.have.class(classes.gutters); + + rerender(); + + expect(menuitem).not.to.have.class(classes.gutters); + }); + + describe('context: dense', () => { + it('should forward the context', () => { + let context = null; + const { setProps } = render( + + + {(options) => { + context = options; + }} + + , + ); + expect(context).to.have.property('dense', false); + setProps({ dense: true }); + expect(context).to.have.property('dense', true); + }); + }); }); diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index 7ddb1462f7c1a3..ebbe81af98efe2 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -11,6 +11,8 @@ export interface MenuItemClasses { disabled: string; /** Styles applied to the root element if `divider={true}`. */ divider: string; + /** Styles applied to the inner `component` element unless `disableGutters={true}`. */ + gutters: string; /** Pseudo-class applied to the root element if `selected={true}`. */ selected: string; } @@ -27,6 +29,7 @@ const menuItemClasses: MenuItemClasses = generateUtilityClasses('MuiMenuItem', [ 'dense', 'disabled', 'divider', + 'gutters', 'selected', ]); From dabad8dee327de31b590e497d1bec4c5c5025ca0 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 11 Jun 2021 22:40:28 +0700 Subject: [PATCH 53/61] fix migration --- docs/src/pages/guides/migration-v4/migration-v4.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index b6b62758ea1da0..9e5d80cc1986c9 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -994,13 +994,14 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m You can use the [`use-transitionprops` codemod](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui-codemod#use-transitionprops) for automatic migration. -- Default `anchorOrigin.vertical` is changed - +- Change the default value of `anchorOrigin.vertical` to follow the Material Design guidelines. The menu now displays below the anchor instead of over it. You can restore the previous behavior with: + ```diff - { - - vertical: 'bottom', - + vertical: 'top', - } +

    Date: Sat, 12 Jun 2021 19:00:24 +0200 Subject: [PATCH 54/61] prettier --- docs/src/pages/components/menus/AccountMenu.js | 1 - docs/src/pages/components/menus/AccountMenu.tsx | 1 - docs/src/pages/guides/migration-v4/migration-v4.md | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/src/pages/components/menus/AccountMenu.js b/docs/src/pages/components/menus/AccountMenu.js index fbc93cc6437443..8a2523dca04afb 100644 --- a/docs/src/pages/components/menus/AccountMenu.js +++ b/docs/src/pages/components/menus/AccountMenu.js @@ -8,7 +8,6 @@ import Divider from '@material-ui/core/Divider'; import IconButton from '@material-ui/core/IconButton'; import Typography from '@material-ui/core/Typography'; import Tooltip from '@material-ui/core/Tooltip'; - import PersonAdd from '@material-ui/icons/PersonAdd'; import Settings from '@material-ui/icons/Settings'; import Logout from '@material-ui/icons/Logout'; diff --git a/docs/src/pages/components/menus/AccountMenu.tsx b/docs/src/pages/components/menus/AccountMenu.tsx index 4d747b964d0101..f4d01f670800b0 100644 --- a/docs/src/pages/components/menus/AccountMenu.tsx +++ b/docs/src/pages/components/menus/AccountMenu.tsx @@ -8,7 +8,6 @@ import Divider from '@material-ui/core/Divider'; import IconButton from '@material-ui/core/IconButton'; import Typography from '@material-ui/core/Typography'; import Tooltip from '@material-ui/core/Tooltip'; - import PersonAdd from '@material-ui/icons/PersonAdd'; import Settings from '@material-ui/icons/Settings'; import Logout from '@material-ui/icons/Logout'; diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index 9e5d80cc1986c9..104366790a027e 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -995,7 +995,7 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m You can use the [`use-transitionprops` codemod](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui-codemod#use-transitionprops) for automatic migration. - Change the default value of `anchorOrigin.vertical` to follow the Material Design guidelines. The menu now displays below the anchor instead of over it. You can restore the previous behavior with: - + ```diff Date: Sat, 12 Jun 2021 19:06:57 +0200 Subject: [PATCH 55/61] polish changelog --- docs/src/pages/guides/migration-v4/migration-v4.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index 104366790a027e..e9b789b47b5193 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -994,23 +994,23 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m You can use the [`use-transitionprops` codemod](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui-codemod#use-transitionprops) for automatic migration. -- Change the default value of `anchorOrigin.vertical` to follow the Material Design guidelines. The menu now displays below the anchor instead of over it. You can restore the previous behavior with: +- Change the default value of `anchorOrigin.vertical` to follow the Material Design guidelines. The menu now displays below the anchor instead of over it. + You can restore the previous behavior with: ```diff - - +
  • + -
  • + +
  • ``` ### Modal From 90a99cca0c0e7df277427f502458f0b6ad249fdb Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 12 Jun 2021 19:07:57 +0200 Subject: [PATCH 56/61] use same terminology as in the demo --- docs/src/pages/guides/migration-v4/migration-v4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index e9b789b47b5193..092fa15d000fa4 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -994,7 +994,7 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m You can use the [`use-transitionprops` codemod](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui-codemod#use-transitionprops) for automatic migration. -- Change the default value of `anchorOrigin.vertical` to follow the Material Design guidelines. The menu now displays below the anchor instead of over it. +- Change the default value of `anchorOrigin.vertical` to follow the Material Design guidelines. The menu now displays below the anchor instead of on top of it. You can restore the previous behavior with: ```diff From a1efeb837d3f01c49304d755cdb3a1109227aa61 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 12 Jun 2021 19:14:33 +0200 Subject: [PATCH 57/61] fix import --- packages/material-ui/src/MenuItem/MenuItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/MenuItem/MenuItem.js b/packages/material-ui/src/MenuItem/MenuItem.js index c2d1943205fede..4c0ff33ef3ff85 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.js +++ b/packages/material-ui/src/MenuItem/MenuItem.js @@ -2,7 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; -import { alpha } from '../styles/colorManipulator'; +import { alpha } from '@material-ui/system'; import styled, { rootShouldForwardProp } from '../styles/styled'; import useThemeProps from '../styles/useThemeProps'; import ListContext from '../List/ListContext'; From a92b8175dcff0ceb324da022ae131b6205c52768 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Mon, 14 Jun 2021 19:01:06 +0700 Subject: [PATCH 58/61] Apply suggestions from code review Co-authored-by: Marija Najdova --- docs/src/pages/components/menus/menus.md | 2 +- docs/src/pages/guides/migration-v4/migration-v4.md | 2 +- packages/material-ui/src/MenuItem/MenuItem.d.ts | 4 ---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/src/pages/components/menus/menus.md b/docs/src/pages/components/menus/menus.md index 3b7520a787c993..d4bda0c6c37276 100644 --- a/docs/src/pages/components/menus/menus.md +++ b/docs/src/pages/components/menus/menus.md @@ -32,7 +32,7 @@ In desktop viewport, padding is increased to give more space to the menu. ## Dense menu -For the menu that has long list and long text, use `dense` to reduce the padding (this property only affect desktop viewport). +For the menu that has long list and long text, use `dense` to reduce the padding (this property only affects desktop viewport). {{"demo": "pages/components/menus/DenseMenu.js", "bg": true}} diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index bffe96b9d88183..49a682bba5bedd 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -1015,7 +1015,7 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m + }} ``` -- The `MenuItem` component do no longer inherits `ListItem` but `ButtonBase`. +- The `MenuItem` component inherits the `ButtonBase` component instead of `ListItem`. The class names related to "MuiListItem-\*" are removed and theming `ListItem` is no longer affecting `MenuItem`. ```diff diff --git a/packages/material-ui/src/MenuItem/MenuItem.d.ts b/packages/material-ui/src/MenuItem/MenuItem.d.ts index 0b588ba439cf84..fdf6a840acaf61 100644 --- a/packages/material-ui/src/MenuItem/MenuItem.d.ts +++ b/packages/material-ui/src/MenuItem/MenuItem.d.ts @@ -12,10 +12,6 @@ export type MenuItemTypeMap

    = Extend * @default false */ autoFocus?: boolean; - /** - * The content of the component. - */ - children?: React.ReactNode; /** * Override or extend the styles applied to the component. */ From e941a0c0e87e64242004f0da12c4fd1e1687fa4b Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Wed, 16 Jun 2021 09:24:15 +0700 Subject: [PATCH 59/61] Update packages/material-ui/src/MenuItem/menuItemClasses.ts Co-authored-by: Olivier Tassinari --- packages/material-ui/src/MenuItem/menuItemClasses.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/MenuItem/menuItemClasses.ts b/packages/material-ui/src/MenuItem/menuItemClasses.ts index ebbe81af98efe2..02f5512f3dcb22 100644 --- a/packages/material-ui/src/MenuItem/menuItemClasses.ts +++ b/packages/material-ui/src/MenuItem/menuItemClasses.ts @@ -3,7 +3,7 @@ import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unsty export interface MenuItemClasses { /** Styles applied to the root element. */ root: string; - /** Pseudo-class applied to the ButtonBase root element if the button is keyboard focused. */ + /** Pseudo-class applied to the root element if keyboard focused. */ focusVisible: string; /** Styles applied to the root element if dense. */ dense: string; From 8b90383ca245e335b258056c71cdc5e4ab580cdb Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 16 Jun 2021 13:16:16 +0700 Subject: [PATCH 60/61] update migration --- docs/src/pages/guides/migration-v4/migration-v4.md | 11 +++++++++++ docs/translations/api-docs/menu-item/menu-item.json | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index 49a682bba5bedd..b66b55e80d8a06 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -1015,6 +1015,8 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m + }} ``` +### MenuItem + - The `MenuItem` component inherits the `ButtonBase` component instead of `ListItem`. The class names related to "MuiListItem-\*" are removed and theming `ListItem` is no longer affecting `MenuItem`. @@ -1023,6 +1025,15 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m +

  • ``` +- prop `listItemClasses` is removed, use `classes` instead. + + ```diff + - + + + ``` + + Read more about [MenuItem CSS API](/api/menu-item/#css) + ### Modal - Remove the `disableBackdropClick` prop because it is redundant. diff --git a/docs/translations/api-docs/menu-item/menu-item.json b/docs/translations/api-docs/menu-item/menu-item.json index 310a8a5765e73e..e1c8ac149b3a82 100644 --- a/docs/translations/api-docs/menu-item/menu-item.json +++ b/docs/translations/api-docs/menu-item/menu-item.json @@ -15,8 +15,8 @@ "root": { "description": "Styles applied to the root element." }, "focusVisible": { "description": "Pseudo-class applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the ButtonBase root element", - "conditions": "the button is keyboard focused" + "nodeName": "the root element", + "conditions": "keyboard focused" }, "dense": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", From 19d0eb87ba9c2648c954522efd65dd65aacf4e2f Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Wed, 16 Jun 2021 13:32:24 +0700 Subject: [PATCH 61/61] Apply suggestions from code review Co-authored-by: Sebastian Silbermann --- docs/src/pages/components/menus/menus.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/components/menus/menus.md b/docs/src/pages/components/menus/menus.md index d4bda0c6c37276..6e1f07908416ba 100644 --- a/docs/src/pages/components/menus/menus.md +++ b/docs/src/pages/components/menus/menus.md @@ -32,7 +32,7 @@ In desktop viewport, padding is increased to give more space to the menu. ## Dense menu -For the menu that has long list and long text, use `dense` to reduce the padding (this property only affects desktop viewport). +For the menu that has long list and long text, you can use the `dense` prop to reduce the padding (this property only affects desktop viewport). {{"demo": "pages/components/menus/DenseMenu.js", "bg": true}} @@ -63,7 +63,7 @@ The primary responsibility of the `MenuList` component is to handle the focus. ## Account menu -`Menu` content can be mixed with other component like `Avatar`. +`Menu` content can be mixed with other components like `Avatar`. {{"demo": "pages/components/menus/AccountMenu.js"}}