UNPKG

17.8 kBJavaScriptView Raw
1'use client';
2
3import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
5import _extends from "@babel/runtime/helpers/esm/extends";
6import * as React from 'react';
7import PropTypes from 'prop-types';
8import clsx from 'clsx';
9import { isHostComponent } from '@mui/base/utils';
10import composeClasses from '@mui/utils/composeClasses';
11import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef';
12import chainPropTypes from '@mui/utils/chainPropTypes';
13import { alpha } from '@mui/system/colorManipulator';
14import styled from '../styles/styled';
15import { useDefaultProps } from '../DefaultPropsProvider';
16import ButtonBase from '../ButtonBase';
17import isMuiElement from '../utils/isMuiElement';
18import useEnhancedEffect from '../utils/useEnhancedEffect';
19import useForkRef from '../utils/useForkRef';
20import ListContext from '../List/ListContext';
21import listItemClasses, { getListItemUtilityClass } from './listItemClasses';
22import { listItemButtonClasses } from '../ListItemButton';
23import ListItemSecondaryAction from '../ListItemSecondaryAction';
24import { jsx as _jsx } from "react/jsx-runtime";
25import { jsxs as _jsxs } from "react/jsx-runtime";
26export var overridesResolver = function overridesResolver(props, styles) {
27 var ownerState = props.ownerState;
28 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];
29};
30var useUtilityClasses = function useUtilityClasses(ownerState) {
31 var alignItems = ownerState.alignItems,
32 button = ownerState.button,
33 classes = ownerState.classes,
34 dense = ownerState.dense,
35 disabled = ownerState.disabled,
36 disableGutters = ownerState.disableGutters,
37 disablePadding = ownerState.disablePadding,
38 divider = ownerState.divider,
39 hasSecondaryAction = ownerState.hasSecondaryAction,
40 selected = ownerState.selected;
41 var slots = {
42 root: ['root', dense && 'dense', !disableGutters && 'gutters', !disablePadding && 'padding', divider && 'divider', disabled && 'disabled', button && 'button', alignItems === 'flex-start' && 'alignItemsFlexStart', hasSecondaryAction && 'secondaryAction', selected && 'selected'],
43 container: ['container']
44 };
45 return composeClasses(slots, getListItemUtilityClass, classes);
46};
47export var ListItemRoot = styled('div', {
48 name: 'MuiListItem',
49 slot: 'Root',
50 overridesResolver: overridesResolver
51})(function (_ref) {
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 }), _defineProperty(_defineProperty(_defineProperty({}, "&.".concat(listItemClasses.focusVisible), {
79 backgroundColor: (theme.vars || theme).palette.action.focus
80 }), "&.".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 })), "&.".concat(listItemClasses.disabled), {
85 opacity: (theme.vars || theme).palette.action.disabledOpacity
86 }), 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/**
126 * Uses an additional container component if `ListItemSecondaryAction` is the last child.
127 */
128var ListItem = /*#__PURE__*/React.forwardRef(function ListItem(inProps, ref) {
129 var props = useDefaultProps({
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$ContainerProps2 = _props$ContainerProps === void 0 ? {} : _props$ContainerProps,
150 ContainerClassName = _props$ContainerProps2.className,
151 ContainerProps = _objectWithoutProperties(_props$ContainerProps2, ["className"]),
152 _props$dense = props.dense,
153 dense = _props$dense === void 0 ? false : _props$dense,
154 _props$disabled = props.disabled,
155 disabled = _props$disabled === void 0 ? false : _props$disabled,
156 _props$disableGutters = props.disableGutters,
157 disableGutters = _props$disableGutters === void 0 ? false : _props$disableGutters,
158 _props$disablePadding = props.disablePadding,
159 disablePadding = _props$disablePadding === void 0 ? false : _props$disablePadding,
160 _props$divider = props.divider,
161 divider = _props$divider === void 0 ? false : _props$divider,
162 focusVisibleClassName = props.focusVisibleClassName,
163 secondaryAction = props.secondaryAction,
164 _props$selected = props.selected,
165 selected = _props$selected === void 0 ? false : _props$selected,
166 _props$slotProps = props.slotProps,
167 slotProps = _props$slotProps === void 0 ? {} : _props$slotProps,
168 _props$slots = props.slots,
169 slots = _props$slots === void 0 ? {} : _props$slots,
170 other = _objectWithoutProperties(props, ["alignItems", "autoFocus", "button", "children", "className", "component", "components", "componentsProps", "ContainerComponent", "ContainerProps", "dense", "disabled", "disableGutters", "disablePadding", "divider", "focusVisibleClassName", "secondaryAction", "selected", "slotProps", "slots"]);
171 var context = React.useContext(ListContext);
172 var childContext = React.useMemo(function () {
173 return {
174 dense: dense || context.dense || false,
175 alignItems: alignItems,
176 disableGutters: disableGutters
177 };
178 }, [alignItems, context.dense, dense, disableGutters]);
179 var listItemRef = React.useRef(null);
180 useEnhancedEffect(function () {
181 if (autoFocus) {
182 if (listItemRef.current) {
183 listItemRef.current.focus();
184 } else if (process.env.NODE_ENV !== 'production') {
185 console.error('MUI: Unable to set focus to a ListItem whose component has not been rendered.');
186 }
187 }
188 }, [autoFocus]);
189 var children = React.Children.toArray(childrenProp);
190
191 // v4 implementation, deprecated in v5, will be removed in v6
192 var hasSecondaryAction = children.length && isMuiElement(children[children.length - 1], ['ListItemSecondaryAction']);
193 var ownerState = _extends({}, props, {
194 alignItems: alignItems,
195 autoFocus: autoFocus,
196 button: button,
197 dense: childContext.dense,
198 disabled: disabled,
199 disableGutters: disableGutters,
200 disablePadding: disablePadding,
201 divider: divider,
202 hasSecondaryAction: hasSecondaryAction,
203 selected: selected
204 });
205 var classes = useUtilityClasses(ownerState);
206 var handleRef = useForkRef(listItemRef, ref);
207 var Root = slots.root || components.Root || ListItemRoot;
208 var rootProps = slotProps.root || componentsProps.root || {};
209 var componentProps = _extends({
210 className: clsx(classes.root, rootProps.className, className),
211 disabled: disabled
212 }, other);
213 var Component = componentProp || 'li';
214 if (button) {
215 componentProps.component = componentProp || 'div';
216 componentProps.focusVisibleClassName = clsx(listItemClasses.focusVisible, focusVisibleClassName);
217 Component = ButtonBase;
218 }
219
220 // v4 implementation, deprecated in v5, will be removed in v6
221 if (hasSecondaryAction) {
222 // Use div by default.
223 Component = !componentProps.component && !componentProp ? 'div' : Component;
224
225 // Avoid nesting of li > li.
226 if (ContainerComponent === 'li') {
227 if (Component === 'li') {
228 Component = 'div';
229 } else if (componentProps.component === 'li') {
230 componentProps.component = 'div';
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 return /*#__PURE__*/_jsx(ListContext.Provider, {
251 value: childContext,
252 children: /*#__PURE__*/_jsxs(Root, _extends({}, rootProps, {
253 as: Component,
254 ref: handleRef
255 }, !isHostComponent(Root) && {
256 ownerState: _extends({}, ownerState, rootProps.ownerState)
257 }, componentProps, {
258 children: [children, secondaryAction && /*#__PURE__*/_jsx(ListItemSecondaryAction, {
259 children: secondaryAction
260 })]
261 }))
262 });
263});
264process.env.NODE_ENV !== "production" ? ListItem.propTypes /* remove-proptypes */ = {
265 // ┌────────────────────────────── Warning ──────────────────────────────┐
266 // │ These PropTypes are generated from the TypeScript type definitions. │
267 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
268 // └─────────────────────────────────────────────────────────────────────┘
269 /**
270 * Defines the `align-items` style property.
271 * @default 'center'
272 */
273 alignItems: PropTypes.oneOf(['center', 'flex-start']),
274 /**
275 * If `true`, the list item is focused during the first mount.
276 * Focus will also be triggered if the value changes from false to true.
277 * @default false
278 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
279 */
280 autoFocus: PropTypes.bool,
281 /**
282 * If `true`, the list item is a button (using `ButtonBase`). Props intended
283 * for `ButtonBase` can then be applied to `ListItem`.
284 * @default false
285 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
286 */
287 button: PropTypes.bool,
288 /**
289 * The content of the component if a `ListItemSecondaryAction` is used it must
290 * be the last child.
291 */
292 children: chainPropTypes(PropTypes.node, function (props) {
293 var children = React.Children.toArray(props.children);
294
295 // React.Children.toArray(props.children).findLastIndex(isListItemSecondaryAction)
296 var secondaryActionIndex = -1;
297 for (var i = children.length - 1; i >= 0; i -= 1) {
298 var child = children[i];
299 if (isMuiElement(child, ['ListItemSecondaryAction'])) {
300 secondaryActionIndex = i;
301 break;
302 }
303 }
304
305 // is ListItemSecondaryAction the last child of ListItem
306 if (secondaryActionIndex !== -1 && secondaryActionIndex !== children.length - 1) {
307 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.');
308 }
309 return null;
310 }),
311 /**
312 * Override or extend the styles applied to the component.
313 */
314 classes: PropTypes.object,
315 /**
316 * @ignore
317 */
318 className: PropTypes.string,
319 /**
320 * The component used for the root node.
321 * Either a string to use a HTML element or a component.
322 */
323 component: PropTypes.elementType,
324 /**
325 * The components used for each slot inside.
326 *
327 * This prop is an alias for the `slots` prop.
328 * It's recommended to use the `slots` prop instead.
329 *
330 * @default {}
331 */
332 components: PropTypes.shape({
333 Root: PropTypes.elementType
334 }),
335 /**
336 * The extra props for the slot components.
337 * You can override the existing props or add new ones.
338 *
339 * This prop is an alias for the `slotProps` prop.
340 * It's recommended to use the `slotProps` prop instead, as `componentsProps` will be deprecated in the future.
341 *
342 * @default {}
343 */
344 componentsProps: PropTypes.shape({
345 root: PropTypes.object
346 }),
347 /**
348 * The container component used when a `ListItemSecondaryAction` is the last child.
349 * @default 'li'
350 * @deprecated
351 */
352 ContainerComponent: elementTypeAcceptingRef,
353 /**
354 * Props applied to the container component if used.
355 * @default {}
356 * @deprecated
357 */
358 ContainerProps: PropTypes.object,
359 /**
360 * If `true`, compact vertical padding designed for keyboard and mouse input is used.
361 * The prop defaults to the value inherited from the parent List component.
362 * @default false
363 */
364 dense: PropTypes.bool,
365 /**
366 * If `true`, the component is disabled.
367 * @default false
368 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
369 */
370 disabled: PropTypes.bool,
371 /**
372 * If `true`, the left and right padding is removed.
373 * @default false
374 */
375 disableGutters: PropTypes.bool,
376 /**
377 * If `true`, all padding is removed.
378 * @default false
379 */
380 disablePadding: PropTypes.bool,
381 /**
382 * If `true`, a 1px light border is added to the bottom of the list item.
383 * @default false
384 */
385 divider: PropTypes.bool,
386 /**
387 * @ignore
388 */
389 focusVisibleClassName: PropTypes.string,
390 /**
391 * The element to display at the end of ListItem.
392 */
393 secondaryAction: PropTypes.node,
394 /**
395 * Use to apply selected styling.
396 * @default false
397 * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead
398 */
399 selected: PropTypes.bool,
400 /**
401 * The extra props for the slot components.
402 * You can override the existing props or add new ones.
403 *
404 * This prop is an alias for the `componentsProps` prop, which will be deprecated in the future.
405 *
406 * @default {}
407 */
408 slotProps: PropTypes.shape({
409 root: PropTypes.object
410 }),
411 /**
412 * The components used for each slot inside.
413 *
414 * This prop is an alias for the `components` prop, which will be deprecated in the future.
415 *
416 * @default {}
417 */
418 slots: PropTypes.shape({
419 root: PropTypes.elementType
420 }),
421 /**
422 * The system prop that allows defining system overrides as well as additional CSS styles.
423 */
424 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
425} : void 0;
426export default ListItem;
\No newline at end of file