UNPKG

8.96 kBJavaScriptView Raw
1import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2import _extends from "@babel/runtime/helpers/esm/extends";
3const _excluded = ["alignItems", "autoFocus", "component", "children", "dense", "disableGutters", "divider", "focusVisibleClassName", "selected"];
4import * as React from 'react';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import { unstable_composeClasses as composeClasses } from '@mui/base';
8import { alpha } from '@mui/system';
9import styled, { rootShouldForwardProp } from '../styles/styled';
10import useThemeProps from '../styles/useThemeProps';
11import ButtonBase from '../ButtonBase';
12import useEnhancedEffect from '../utils/useEnhancedEffect';
13import useForkRef from '../utils/useForkRef';
14import ListContext from '../List/ListContext';
15import listItemButtonClasses, { getListItemButtonUtilityClass } from './listItemButtonClasses';
16import { jsx as _jsx } from "react/jsx-runtime";
17export const overridesResolver = (props, styles) => {
18 const {
19 ownerState
20 } = props;
21 return [styles.root, ownerState.dense && styles.dense, ownerState.alignItems === 'flex-start' && styles.alignItemsFlexStart, ownerState.divider && styles.divider, !ownerState.disableGutters && styles.gutters];
22};
23
24const useUtilityClasses = ownerState => {
25 const {
26 alignItems,
27 classes,
28 dense,
29 disabled,
30 disableGutters,
31 divider,
32 selected
33 } = ownerState;
34 const slots = {
35 root: ['root', dense && 'dense', !disableGutters && 'gutters', divider && 'divider', disabled && 'disabled', alignItems === 'flex-start' && 'alignItemsFlexStart', selected && 'selected']
36 };
37 const composedClasses = composeClasses(slots, getListItemButtonUtilityClass, classes);
38 return _extends({}, classes, composedClasses);
39};
40
41const ListItemButtonRoot = styled(ButtonBase, {
42 shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
43 name: 'MuiListItemButton',
44 slot: 'Root',
45 overridesResolver
46})(({
47 theme,
48 ownerState
49}) => _extends({
50 display: 'flex',
51 flexGrow: 1,
52 justifyContent: 'flex-start',
53 alignItems: 'center',
54 position: 'relative',
55 textDecoration: 'none',
56 minWidth: 0,
57 boxSizing: 'border-box',
58 textAlign: 'left',
59 paddingTop: 8,
60 paddingBottom: 8,
61 transition: theme.transitions.create('background-color', {
62 duration: theme.transitions.duration.shortest
63 }),
64 '&:hover': {
65 textDecoration: 'none',
66 backgroundColor: (theme.vars || theme).palette.action.hover,
67 // Reset on touch devices, it doesn't add specificity
68 '@media (hover: none)': {
69 backgroundColor: 'transparent'
70 }
71 },
72 [`&.${listItemButtonClasses.selected}`]: {
73 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
74 [`&.${listItemButtonClasses.focusVisible}`]: {
75 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity)
76 }
77 },
78 [`&.${listItemButtonClasses.selected}:hover`]: {
79 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
80 // Reset on touch devices, it doesn't add specificity
81 '@media (hover: none)': {
82 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity)
83 }
84 },
85 [`&.${listItemButtonClasses.focusVisible}`]: {
86 backgroundColor: (theme.vars || theme).palette.action.focus
87 },
88 [`&.${listItemButtonClasses.disabled}`]: {
89 opacity: (theme.vars || theme).palette.action.disabledOpacity
90 }
91}, ownerState.divider && {
92 borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`,
93 backgroundClip: 'padding-box'
94}, ownerState.alignItems === 'flex-start' && {
95 alignItems: 'flex-start'
96}, !ownerState.disableGutters && {
97 paddingLeft: 16,
98 paddingRight: 16
99}, ownerState.dense && {
100 paddingTop: 4,
101 paddingBottom: 4
102}));
103const ListItemButton = /*#__PURE__*/React.forwardRef(function ListItemButton(inProps, ref) {
104 const props = useThemeProps({
105 props: inProps,
106 name: 'MuiListItemButton'
107 });
108
109 const {
110 alignItems = 'center',
111 autoFocus = false,
112 component = 'div',
113 children,
114 dense = false,
115 disableGutters = false,
116 divider = false,
117 focusVisibleClassName,
118 selected = false
119 } = props,
120 other = _objectWithoutPropertiesLoose(props, _excluded);
121
122 const context = React.useContext(ListContext);
123 const childContext = {
124 dense: dense || context.dense || false,
125 alignItems,
126 disableGutters
127 };
128 const listItemRef = React.useRef(null);
129 useEnhancedEffect(() => {
130 if (autoFocus) {
131 if (listItemRef.current) {
132 listItemRef.current.focus();
133 } else if (process.env.NODE_ENV !== 'production') {
134 console.error('MUI: Unable to set focus to a ListItemButton whose component has not been rendered.');
135 }
136 }
137 }, [autoFocus]);
138
139 const ownerState = _extends({}, props, {
140 alignItems,
141 dense: childContext.dense,
142 disableGutters,
143 divider,
144 selected
145 });
146
147 const classes = useUtilityClasses(ownerState);
148 const handleRef = useForkRef(listItemRef, ref);
149 return /*#__PURE__*/_jsx(ListContext.Provider, {
150 value: childContext,
151 children: /*#__PURE__*/_jsx(ListItemButtonRoot, _extends({
152 ref: handleRef,
153 href: other.href || other.to,
154 component: (other.href || other.to) && component === 'div' ? 'a' : component,
155 focusVisibleClassName: clsx(classes.focusVisible, focusVisibleClassName),
156 ownerState: ownerState
157 }, other, {
158 classes: classes,
159 children: children
160 }))
161 });
162});
163process.env.NODE_ENV !== "production" ? ListItemButton.propTypes
164/* remove-proptypes */
165= {
166 // ----------------------------- Warning --------------------------------
167 // | These PropTypes are generated from the TypeScript type definitions |
168 // | To update them edit the d.ts file and run "yarn proptypes" |
169 // ----------------------------------------------------------------------
170
171 /**
172 * Defines the `align-items` style property.
173 * @default 'center'
174 */
175 alignItems: PropTypes.oneOf(['center', 'flex-start']),
176
177 /**
178 * If `true`, the list item is focused during the first mount.
179 * Focus will also be triggered if the value changes from false to true.
180 * @default false
181 */
182 autoFocus: PropTypes.bool,
183
184 /**
185 * The content of the component if a `ListItemSecondaryAction` is used it must
186 * be the last child.
187 */
188 children: PropTypes.node,
189
190 /**
191 * Override or extend the styles applied to the component.
192 */
193 classes: PropTypes.object,
194
195 /**
196 * The component used for the root node.
197 * Either a string to use a HTML element or a component.
198 */
199 component: PropTypes.elementType,
200
201 /**
202 * If `true`, compact vertical padding designed for keyboard and mouse input is used.
203 * The prop defaults to the value inherited from the parent List component.
204 * @default false
205 */
206 dense: PropTypes.bool,
207
208 /**
209 * If `true`, the component is disabled.
210 * @default false
211 */
212 disabled: PropTypes.bool,
213
214 /**
215 * If `true`, the left and right padding is removed.
216 * @default false
217 */
218 disableGutters: PropTypes.bool,
219
220 /**
221 * If `true`, a 1px light border is added to the bottom of the list item.
222 * @default false
223 */
224 divider: PropTypes.bool,
225
226 /**
227 * This prop can help identify which element has keyboard focus.
228 * The class name will be applied when the element gains the focus through keyboard interaction.
229 * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo).
230 * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/HEAD/explainer.md).
231 * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `focus-visible` class to other components
232 * if needed.
233 */
234 focusVisibleClassName: PropTypes.string,
235
236 /**
237 * @ignore
238 */
239 href: PropTypes.string,
240
241 /**
242 * Use to apply selected styling.
243 * @default false
244 */
245 selected: PropTypes.bool,
246
247 /**
248 * The system prop that allows defining system overrides as well as additional CSS styles.
249 */
250 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
251} : void 0;
252export default ListItemButton;
\No newline at end of file