UNPKG

8.63 kBJavaScriptView Raw
1import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2import _extends from "@babel/runtime/helpers/esm/extends";
3import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
5import * as React from 'react';
6import { isFragment } from 'react-is';
7import PropTypes from 'prop-types';
8import clsx from 'clsx';
9import { integerPropType } from '@mui/utils';
10import { unstable_composeClasses as composeClasses } from '@mui/base';
11import styled from '../styles/styled';
12import useThemeProps from '../styles/useThemeProps';
13import Typography from '../Typography';
14import BreadcrumbCollapsed from './BreadcrumbCollapsed';
15import breadcrumbsClasses, { getBreadcrumbsUtilityClass } from './breadcrumbsClasses';
16import { jsx as _jsx } from "react/jsx-runtime";
17
18var useUtilityClasses = function useUtilityClasses(ownerState) {
19 var classes = ownerState.classes;
20 var slots = {
21 root: ['root'],
22 li: ['li'],
23 ol: ['ol'],
24 separator: ['separator']
25 };
26 return composeClasses(slots, getBreadcrumbsUtilityClass, classes);
27};
28
29var BreadcrumbsRoot = styled(Typography, {
30 name: 'MuiBreadcrumbs',
31 slot: 'Root',
32 overridesResolver: function overridesResolver(props, styles) {
33 return [_defineProperty({}, "& .".concat(breadcrumbsClasses.li), styles.li), styles.root];
34 }
35})({});
36var BreadcrumbsOl = styled('ol', {
37 name: 'MuiBreadcrumbs',
38 slot: 'Ol',
39 overridesResolver: function overridesResolver(props, styles) {
40 return styles.ol;
41 }
42})({
43 display: 'flex',
44 flexWrap: 'wrap',
45 alignItems: 'center',
46 padding: 0,
47 margin: 0,
48 listStyle: 'none'
49});
50var BreadcrumbsSeparator = styled('li', {
51 name: 'MuiBreadcrumbs',
52 slot: 'Separator',
53 overridesResolver: function overridesResolver(props, styles) {
54 return styles.separator;
55 }
56})({
57 display: 'flex',
58 userSelect: 'none',
59 marginLeft: 8,
60 marginRight: 8
61});
62
63function insertSeparators(items, className, separator, ownerState) {
64 return items.reduce(function (acc, current, index) {
65 if (index < items.length - 1) {
66 acc = acc.concat(current, /*#__PURE__*/_jsx(BreadcrumbsSeparator, {
67 "aria-hidden": true,
68 className: className,
69 ownerState: ownerState,
70 children: separator
71 }, "separator-".concat(index)));
72 } else {
73 acc.push(current);
74 }
75
76 return acc;
77 }, []);
78}
79
80var Breadcrumbs = /*#__PURE__*/React.forwardRef(function Breadcrumbs(inProps, ref) {
81 var props = useThemeProps({
82 props: inProps,
83 name: 'MuiBreadcrumbs'
84 });
85
86 var children = props.children,
87 className = props.className,
88 _props$component = props.component,
89 component = _props$component === void 0 ? 'nav' : _props$component,
90 _props$expandText = props.expandText,
91 expandText = _props$expandText === void 0 ? 'Show path' : _props$expandText,
92 _props$itemsAfterColl = props.itemsAfterCollapse,
93 itemsAfterCollapse = _props$itemsAfterColl === void 0 ? 1 : _props$itemsAfterColl,
94 _props$itemsBeforeCol = props.itemsBeforeCollapse,
95 itemsBeforeCollapse = _props$itemsBeforeCol === void 0 ? 1 : _props$itemsBeforeCol,
96 _props$maxItems = props.maxItems,
97 maxItems = _props$maxItems === void 0 ? 8 : _props$maxItems,
98 _props$separator = props.separator,
99 separator = _props$separator === void 0 ? '/' : _props$separator,
100 other = _objectWithoutProperties(props, ["children", "className", "component", "expandText", "itemsAfterCollapse", "itemsBeforeCollapse", "maxItems", "separator"]);
101
102 var _React$useState = React.useState(false),
103 expanded = _React$useState[0],
104 setExpanded = _React$useState[1];
105
106 var ownerState = _extends({}, props, {
107 component: component,
108 expanded: expanded,
109 expandText: expandText,
110 itemsAfterCollapse: itemsAfterCollapse,
111 itemsBeforeCollapse: itemsBeforeCollapse,
112 maxItems: maxItems,
113 separator: separator
114 });
115
116 var classes = useUtilityClasses(ownerState);
117 var listRef = React.useRef(null);
118
119 var renderItemsBeforeAndAfter = function renderItemsBeforeAndAfter(allItems) {
120 var handleClickExpand = function handleClickExpand() {
121 setExpanded(true); // The clicked element received the focus but gets removed from the DOM.
122 // Let's keep the focus in the component after expanding.
123 // Moving it to the <ol> or <nav> does not cause any announcement in NVDA.
124 // By moving it to some link/button at least we have some announcement.
125
126 var focusable = listRef.current.querySelector('a[href],button,[tabindex]');
127
128 if (focusable) {
129 focusable.focus();
130 }
131 }; // This defends against someone passing weird input, to ensure that if all
132 // items would be shown anyway, we just show all items without the EllipsisItem
133
134
135 if (itemsBeforeCollapse + itemsAfterCollapse >= allItems.length) {
136 if (process.env.NODE_ENV !== 'production') {
137 console.error(['MUI: You have provided an invalid combination of props to the Breadcrumbs.', "itemsAfterCollapse={".concat(itemsAfterCollapse, "} + itemsBeforeCollapse={").concat(itemsBeforeCollapse, "} >= maxItems={").concat(maxItems, "}")].join('\n'));
138 }
139
140 return allItems;
141 }
142
143 return [].concat(_toConsumableArray(allItems.slice(0, itemsBeforeCollapse)), [/*#__PURE__*/_jsx(BreadcrumbCollapsed, {
144 "aria-label": expandText,
145 onClick: handleClickExpand
146 }, "ellipsis")], _toConsumableArray(allItems.slice(allItems.length - itemsAfterCollapse, allItems.length)));
147 };
148
149 var allItems = React.Children.toArray(children).filter(function (child) {
150 if (process.env.NODE_ENV !== 'production') {
151 if (isFragment(child)) {
152 console.error(["MUI: The Breadcrumbs component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
153 }
154 }
155
156 return /*#__PURE__*/React.isValidElement(child);
157 }).map(function (child, index) {
158 return /*#__PURE__*/_jsx("li", {
159 className: classes.li,
160 children: child
161 }, "child-".concat(index));
162 });
163 return /*#__PURE__*/_jsx(BreadcrumbsRoot, _extends({
164 ref: ref,
165 component: component,
166 color: "text.secondary",
167 className: clsx(classes.root, className),
168 ownerState: ownerState
169 }, other, {
170 children: /*#__PURE__*/_jsx(BreadcrumbsOl, {
171 className: classes.ol,
172 ref: listRef,
173 ownerState: ownerState,
174 children: insertSeparators(expanded || maxItems && allItems.length <= maxItems ? allItems : renderItemsBeforeAndAfter(allItems), classes.separator, separator, ownerState)
175 })
176 }));
177});
178process.env.NODE_ENV !== "production" ? Breadcrumbs.propTypes
179/* remove-proptypes */
180= {
181 // ----------------------------- Warning --------------------------------
182 // | These PropTypes are generated from the TypeScript type definitions |
183 // | To update them edit the d.ts file and run "yarn proptypes" |
184 // ----------------------------------------------------------------------
185
186 /**
187 * The content of the component.
188 */
189 children: PropTypes.node,
190
191 /**
192 * Override or extend the styles applied to the component.
193 */
194 classes: PropTypes.object,
195
196 /**
197 * @ignore
198 */
199 className: PropTypes.string,
200
201 /**
202 * The component used for the root node.
203 * Either a string to use a HTML element or a component.
204 */
205 component: PropTypes.elementType,
206
207 /**
208 * Override the default label for the expand button.
209 *
210 * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).
211 * @default 'Show path'
212 */
213 expandText: PropTypes.string,
214
215 /**
216 * If max items is exceeded, the number of items to show after the ellipsis.
217 * @default 1
218 */
219 itemsAfterCollapse: integerPropType,
220
221 /**
222 * If max items is exceeded, the number of items to show before the ellipsis.
223 * @default 1
224 */
225 itemsBeforeCollapse: integerPropType,
226
227 /**
228 * Specifies the maximum number of breadcrumbs to display. When there are more
229 * than the maximum number, only the first `itemsBeforeCollapse` and last `itemsAfterCollapse`
230 * will be shown, with an ellipsis in between.
231 * @default 8
232 */
233 maxItems: integerPropType,
234
235 /**
236 * Custom separator node.
237 * @default '/'
238 */
239 separator: PropTypes.node,
240
241 /**
242 * The system prop that allows defining system overrides as well as additional CSS styles.
243 */
244 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
245} : void 0;
246export default Breadcrumbs;
\No newline at end of file