UNPKG

16.5 kBJavaScriptView Raw
1import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
2import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
3import _extends from "@babel/runtime/helpers/esm/extends";
4import * as React from 'react';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import { unstable_composeClasses as composeClasses, isHostComponent } from '@mui/base';
8import { chainPropTypes, elementTypeAcceptingRef } from '@mui/utils';
9import { alpha } from '@mui/system';
10import styled from '../styles/styled';
11import useThemeProps from '../styles/useThemeProps';
12import ButtonBase from '../ButtonBase';
13import isMuiElement from '../utils/isMuiElement';
14import useEnhancedEffect from '../utils/useEnhancedEffect';
15import useForkRef from '../utils/useForkRef';
16import ListContext from '../List/ListContext';
17import listItemClasses, { getListItemUtilityClass } from './listItemClasses';
18import { listItemButtonClasses } from '../ListItemButton';
19import ListItemSecondaryAction from '../ListItemSecondaryAction';
20import { jsx as _jsx } from "react/jsx-runtime";
21import { jsxs as _jsxs } from "react/jsx-runtime";
22export var overridesResolver = function overridesResolver(props, styles) {
23 var ownerState = props.ownerState;
24 return [styles.root, ownerState.dense && styles.dense, ownerState.alignItems === 'flex-start' && styles.alignItemsFlexStart, ownerState.divider && styles.divider, !ownerState.disableGutters && styles.gutters, !ownerState.disablePadding && styles.padding, ownerState.button && styles.button, ownerState.hasSecondaryAction && styles.secondaryAction];
25};
26
27var useUtilityClasses = function useUtilityClasses(ownerState) {
28 var alignItems = ownerState.alignItems,
29 button = ownerState.button,
30 classes = ownerState.classes,
31 dense = ownerState.dense,
32 disabled = ownerState.disabled,
33 disableGutters = ownerState.disableGutters,
34 disablePadding = ownerState.disablePadding,
35 divider = ownerState.divider,
36 hasSecondaryAction = ownerState.hasSecondaryAction,
37 selected = ownerState.selected;
38 var slots = {
39 root: ['root', dense && 'dense', !disableGutters && 'gutters', !disablePadding && 'padding', divider && 'divider', disabled && 'disabled', button && 'button', alignItems === 'flex-start' && 'alignItemsFlexStart', hasSecondaryAction && 'secondaryAction', selected && 'selected'],
40 container: ['container']
41 };
42 return composeClasses(slots, getListItemUtilityClass, classes);
43};
44
45export var ListItemRoot = styled('div', {
46 name: 'MuiListItem',
47 slot: 'Root',
48 overridesResolver: overridesResolver
49})(function (_ref) {
50 var _extends2;
51
52 var theme = _ref.theme,
53 ownerState = _ref.ownerState;
54 return _extends({
55 display: 'flex',
56 justifyContent: 'flex-start',
57 alignItems: 'center',
58 position: 'relative',
59 textDecoration: 'none',
60 width: '100%',
61 boxSizing: 'border-box',
62 textAlign: 'left'
63 }, !ownerState.disablePadding && _extends({
64 paddingTop: 8,
65 paddingBottom: 8
66 }, ownerState.dense && {
67 paddingTop: 4,
68 paddingBottom: 4
69 }, !ownerState.disableGutters && {
70 paddingLeft: 16,
71 paddingRight: 16
72 }, !!ownerState.secondaryAction && {
73 // Add some space to avoid collision as `ListItemSecondaryAction`
74 // is absolutely positioned.
75 paddingRight: 48
76 }), !!ownerState.secondaryAction && _defineProperty({}, "& > .".concat(listItemButtonClasses.root), {
77 paddingRight: 48
78 }), (_extends2 = {}, _defineProperty(_extends2, "&.".concat(listItemClasses.focusVisible), {
79 backgroundColor: (theme.vars || theme).palette.action.focus
80 }), _defineProperty(_extends2, "&.".concat(listItemClasses.selected), _defineProperty({
81 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / ").concat(theme.vars.palette.action.selectedOpacity, ")") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity)
82 }, "&.".concat(listItemClasses.focusVisible), {
83 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / calc(").concat(theme.vars.palette.action.selectedOpacity, " + ").concat(theme.vars.palette.action.focusOpacity, "))") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity)
84 })), _defineProperty(_extends2, "&.".concat(listItemClasses.disabled), {
85 opacity: (theme.vars || theme).palette.action.disabledOpacity
86 }), _extends2), ownerState.alignItems === 'flex-start' && {
87 alignItems: 'flex-start'
88 }, ownerState.divider && {
89 borderBottom: "1px solid ".concat((theme.vars || theme).palette.divider),
90 backgroundClip: 'padding-box'
91 }, ownerState.button && _defineProperty({
92 transition: theme.transitions.create('background-color', {
93 duration: theme.transitions.duration.shortest
94 }),
95 '&:hover': {
96 textDecoration: 'none',
97 backgroundColor: (theme.vars || theme).palette.action.hover,
98 // Reset on touch devices, it doesn't add specificity
99 '@media (hover: none)': {
100 backgroundColor: 'transparent'
101 }
102 }
103 }, "&.".concat(listItemClasses.selected, ":hover"), {
104 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / calc(").concat(theme.vars.palette.action.selectedOpacity, " + ").concat(theme.vars.palette.action.hoverOpacity, "))") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
105 // Reset on touch devices, it doesn't add specificity
106 '@media (hover: none)': {
107 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / ").concat(theme.vars.palette.action.selectedOpacity, ")") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity)
108 }
109 }), ownerState.hasSecondaryAction && {
110 // Add some space to avoid collision as `ListItemSecondaryAction`
111 // is absolutely positioned.
112 paddingRight: 48
113 });
114});
115var ListItemContainer = styled('li', {
116 name: 'MuiListItem',
117 slot: 'Container',
118 overridesResolver: function overridesResolver(props, styles) {
119 return styles.container;
120 }
121})({
122 position: 'relative'
123});
124/**
125 * Uses an additional container component if `ListItemSecondaryAction` is the last child.
126 */
127
128var ListItem = /*#__PURE__*/React.forwardRef(function ListItem(inProps, ref) {
129 var props = useThemeProps({
130 props: inProps,
131 name: 'MuiListItem'
132 });
133 var _props$alignItems = props.alignItems,
134 alignItems = _props$alignItems === void 0 ? 'center' : _props$alignItems,
135 _props$autoFocus = props.autoFocus,
136 autoFocus = _props$autoFocus === void 0 ? false : _props$autoFocus,
137 _props$button = props.button,
138 button = _props$button === void 0 ? false : _props$button,
139 childrenProp = props.children,
140 className = props.className,
141 componentProp = props.component,
142 _props$components = props.components,
143 components = _props$components === void 0 ? {} : _props$components,
144 _props$componentsProp = props.componentsProps,
145 componentsProps = _props$componentsProp === void 0 ? {} : _props$componentsProp,
146 _props$ContainerCompo = props.ContainerComponent,
147 ContainerComponent = _props$ContainerCompo === void 0 ? 'li' : _props$ContainerCompo,
148 _props$ContainerProps = props.ContainerProps;
149 _props$ContainerProps = _props$ContainerProps === void 0 ? {} : _props$ContainerProps;
150
151 var ContainerClassName = _props$ContainerProps.className,
152 ContainerProps = _objectWithoutProperties(_props$ContainerProps, ["className"]),
153 _props$dense = props.dense,
154 dense = _props$dense === void 0 ? false : _props$dense,
155 _props$disabled = props.disabled,
156 disabled = _props$disabled === void 0 ? false : _props$disabled,
157 _props$disableGutters = props.disableGutters,
158 disableGutters = _props$disableGutters === void 0 ? false : _props$disableGutters,
159 _props$disablePadding = props.disablePadding,
160 disablePadding = _props$disablePadding === void 0 ? false : _props$disablePadding,
161 _props$divider = props.divider,
162 divider = _props$divider === void 0 ? false : _props$divider,
163 focusVisibleClassName = props.focusVisibleClassName,
164 secondaryAction = props.secondaryAction,
165 _props$selected = props.selected,
166 selected = _props$selected === void 0 ? false : _props$selected,
167 other = _objectWithoutProperties(props, ["alignItems", "autoFocus", "button", "children", "className", "component", "components", "componentsProps", "ContainerComponent", "ContainerProps", "dense", "disabled", "disableGutters", "disablePadding", "divider", "focusVisibleClassName", "secondaryAction", "selected"]);
168
169 var context = React.useContext(ListContext);
170 var childContext = {
171 dense: dense || context.dense || false,
172 alignItems: alignItems,
173 disableGutters: disableGutters
174 };
175 var listItemRef = React.useRef(null);
176 useEnhancedEffect(function () {
177 if (autoFocus) {
178 if (listItemRef.current) {
179 listItemRef.current.focus();
180 } else if (process.env.NODE_ENV !== 'production') {
181 console.error('MUI: Unable to set focus to a ListItem whose component has not been rendered.');
182 }
183 }
184 }, [autoFocus]);
185 var children = React.Children.toArray(childrenProp); // v4 implementation, deprecated in v5, will be removed in v6
186
187 var hasSecondaryAction = children.length && isMuiElement(children[children.length - 1], ['ListItemSecondaryAction']);
188
189 var ownerState = _extends({}, props, {
190 alignItems: alignItems,
191 autoFocus: autoFocus,
192 button: button,
193 dense: childContext.dense,
194 disabled: disabled,
195 disableGutters: disableGutters,
196 disablePadding: disablePadding,
197 divider: divider,
198 hasSecondaryAction: hasSecondaryAction,
199 selected: selected
200 });
201
202 var classes = useUtilityClasses(ownerState);
203 var handleRef = useForkRef(listItemRef, ref);
204 var Root = components.Root || ListItemRoot;
205 var rootProps = componentsProps.root || {};
206
207 var componentProps = _extends({
208 className: clsx(classes.root, rootProps.className, className),
209 disabled: disabled
210 }, other);
211
212 var Component = componentProp || 'li';
213
214 if (button) {
215 componentProps.component = componentProp || 'div';
216 componentProps.focusVisibleClassName = clsx(listItemClasses.focusVisible, focusVisibleClassName);
217 Component = ButtonBase;
218 } // v4 implementation, deprecated in v5, will be removed in v6
219
220
221 if (hasSecondaryAction) {
222 // Use div by default.
223 Component = !componentProps.component && !componentProp ? 'div' : Component; // Avoid nesting of li > li.
224
225 if (ContainerComponent === 'li') {
226 if (Component === 'li') {
227 Component = 'div';
228 } else if (componentProps.component === 'li') {
229 componentProps.component = 'div';
230 }
231 }
232
233 return /*#__PURE__*/_jsx(ListContext.Provider, {
234 value: childContext,
235 children: /*#__PURE__*/_jsxs(ListItemContainer, _extends({
236 as: ContainerComponent,
237 className: clsx(classes.container, ContainerClassName),
238 ref: handleRef,
239 ownerState: ownerState
240 }, ContainerProps, {
241 children: [/*#__PURE__*/_jsx(Root, _extends({}, rootProps, !isHostComponent(Root) && {
242 as: Component,
243 ownerState: _extends({}, ownerState, rootProps.ownerState)
244 }, componentProps, {
245 children: children
246 })), children.pop()]
247 }))
248 });
249 }
250
251 return /*#__PURE__*/_jsx(ListContext.Provider, {
252 value: childContext,
253 children: /*#__PURE__*/_jsxs(Root, _extends({}, rootProps, {
254 as: Component,
255 ref: handleRef,
256 ownerState: ownerState
257 }, !isHostComponent(Root) && {
258 ownerState: _extends({}, ownerState, rootProps.ownerState)
259 }, componentProps, {
260 children: [children, secondaryAction && /*#__PURE__*/_jsx(ListItemSecondaryAction, {
261 children: secondaryAction
262 })]
263 }))
264 });
265});
266process.env.NODE_ENV !== "production" ? ListItem.propTypes
267/* remove-proptypes */
268= {
269 // ----------------------------- Warning --------------------------------
270 // | These PropTypes are generated from the TypeScript type definitions |
271 // | To update them edit the d.ts file and run "yarn proptypes" |
272 // ----------------------------------------------------------------------
273
274 /**
275 * Defines the `align-items` style property.
276 * @default 'center'
277 */
278 alignItems: PropTypes.oneOf(['center', 'flex-start']),
279
280 /**
281 * If `true`, the list item is focused during the first mount.
282 * Focus will also be triggered if the value changes from false to true.
283 * @default false
284 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
285 */
286 autoFocus: PropTypes.bool,
287
288 /**
289 * If `true`, the list item is a button (using `ButtonBase`). Props intended
290 * for `ButtonBase` can then be applied to `ListItem`.
291 * @default false
292 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
293 */
294 button: PropTypes.bool,
295
296 /**
297 * The content of the component if a `ListItemSecondaryAction` is used it must
298 * be the last child.
299 */
300 children: chainPropTypes(PropTypes.node, function (props) {
301 var children = React.Children.toArray(props.children); // React.Children.toArray(props.children).findLastIndex(isListItemSecondaryAction)
302
303 var secondaryActionIndex = -1;
304
305 for (var i = children.length - 1; i >= 0; i -= 1) {
306 var child = children[i];
307
308 if (isMuiElement(child, ['ListItemSecondaryAction'])) {
309 secondaryActionIndex = i;
310 break;
311 }
312 } // is ListItemSecondaryAction the last child of ListItem
313
314
315 if (secondaryActionIndex !== -1 && secondaryActionIndex !== children.length - 1) {
316 return new Error('MUI: You used an element after ListItemSecondaryAction. ' + 'For ListItem to detect that it has a secondary action ' + 'you must pass it as the last child to ListItem.');
317 }
318
319 return null;
320 }),
321
322 /**
323 * Override or extend the styles applied to the component.
324 */
325 classes: PropTypes.object,
326
327 /**
328 * @ignore
329 */
330 className: PropTypes.string,
331
332 /**
333 * The component used for the root node.
334 * Either a string to use a HTML element or a component.
335 */
336 component: PropTypes.elementType,
337
338 /**
339 * The components used for each slot inside the InputBase.
340 * Either a string to use a HTML element or a component.
341 * @default {}
342 */
343 components: PropTypes.shape({
344 Root: PropTypes.elementType
345 }),
346
347 /**
348 * The props used for each slot inside the Input.
349 * @default {}
350 */
351 componentsProps: PropTypes.shape({
352 root: PropTypes.object
353 }),
354
355 /**
356 * The container component used when a `ListItemSecondaryAction` is the last child.
357 * @default 'li'
358 * @deprecated
359 */
360 ContainerComponent: elementTypeAcceptingRef,
361
362 /**
363 * Props applied to the container component if used.
364 * @default {}
365 * @deprecated
366 */
367 ContainerProps: PropTypes.object,
368
369 /**
370 * If `true`, compact vertical padding designed for keyboard and mouse input is used.
371 * The prop defaults to the value inherited from the parent List component.
372 * @default false
373 */
374 dense: PropTypes.bool,
375
376 /**
377 * If `true`, the component is disabled.
378 * @default false
379 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
380 */
381 disabled: PropTypes.bool,
382
383 /**
384 * If `true`, the left and right padding is removed.
385 * @default false
386 */
387 disableGutters: PropTypes.bool,
388
389 /**
390 * If `true`, all padding is removed.
391 * @default false
392 */
393 disablePadding: PropTypes.bool,
394
395 /**
396 * If `true`, a 1px light border is added to the bottom of the list item.
397 * @default false
398 */
399 divider: PropTypes.bool,
400
401 /**
402 * @ignore
403 */
404 focusVisibleClassName: PropTypes.string,
405
406 /**
407 * The element to display at the end of ListItem.
408 */
409 secondaryAction: PropTypes.node,
410
411 /**
412 * Use to apply selected styling.
413 * @default false
414 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
415 */
416 selected: PropTypes.bool,
417
418 /**
419 * The system prop that allows defining system overrides as well as additional CSS styles.
420 */
421 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
422} : void 0;
423export default ListItem;
\No newline at end of file