UNPKG

5.8 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3import * as React from 'react';
4import { isFragment } from 'react-is';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import withStyles from '../styles/withStyles';
8import Typography from '../Typography';
9import BreadcrumbCollapsed from './BreadcrumbCollapsed';
10export const styles = {
11 /* Styles applied to the root element. */
12 root: {},
13
14 /* Styles applied to the ol element. */
15 ol: {
16 display: 'flex',
17 flexWrap: 'wrap',
18 alignItems: 'center',
19 padding: 0,
20 margin: 0,
21 listStyle: 'none'
22 },
23
24 /* Styles applied to the li element. */
25 li: {},
26
27 /* Styles applied to the separator element. */
28 separator: {
29 display: 'flex',
30 userSelect: 'none',
31 marginLeft: 8,
32 marginRight: 8
33 }
34};
35
36function insertSeparators(items, className, separator) {
37 return items.reduce((acc, current, index) => {
38 if (index < items.length - 1) {
39 acc = acc.concat(current, /*#__PURE__*/React.createElement("li", {
40 "aria-hidden": true,
41 key: `separator-${index}`,
42 className: className
43 }, separator));
44 } else {
45 acc.push(current);
46 }
47
48 return acc;
49 }, []);
50}
51
52const Breadcrumbs = /*#__PURE__*/React.forwardRef(function Breadcrumbs(props, ref) {
53 const {
54 children,
55 classes,
56 className,
57 component: Component = 'nav',
58 expandText = 'Show path',
59 itemsAfterCollapse = 1,
60 itemsBeforeCollapse = 1,
61 maxItems = 8,
62 separator = '/'
63 } = props,
64 other = _objectWithoutPropertiesLoose(props, ["children", "classes", "className", "component", "expandText", "itemsAfterCollapse", "itemsBeforeCollapse", "maxItems", "separator"]);
65
66 const [expanded, setExpanded] = React.useState(false);
67
68 const renderItemsBeforeAndAfter = allItems => {
69 const handleClickExpand = event => {
70 setExpanded(true); // The clicked element received the focus but gets removed from the DOM.
71 // Let's keep the focus in the component after expanding.
72
73 const focusable = event.currentTarget.parentNode.querySelector('a[href],button,[tabindex]');
74
75 if (focusable) {
76 focusable.focus();
77 }
78 }; // This defends against someone passing weird input, to ensure that if all
79 // items would be shown anyway, we just show all items without the EllipsisItem
80
81
82 if (itemsBeforeCollapse + itemsAfterCollapse >= allItems.length) {
83 if (process.env.NODE_ENV !== 'production') {
84 console.error(['Material-UI: You have provided an invalid combination of props to the Breadcrumbs.', `itemsAfterCollapse={${itemsAfterCollapse}} + itemsBeforeCollapse={${itemsBeforeCollapse}} >= maxItems={${maxItems}}`].join('\n'));
85 }
86
87 return allItems;
88 }
89
90 return [...allItems.slice(0, itemsBeforeCollapse), /*#__PURE__*/React.createElement(BreadcrumbCollapsed, {
91 "aria-label": expandText,
92 key: "ellipsis",
93 onClick: handleClickExpand
94 }), ...allItems.slice(allItems.length - itemsAfterCollapse, allItems.length)];
95 };
96
97 const allItems = React.Children.toArray(children).filter(child => {
98 if (process.env.NODE_ENV !== 'production') {
99 if (isFragment(child)) {
100 console.error(["Material-UI: The Breadcrumbs component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
101 }
102 }
103
104 return /*#__PURE__*/React.isValidElement(child);
105 }).map((child, index) => /*#__PURE__*/React.createElement("li", {
106 className: classes.li,
107 key: `child-${index}`
108 }, child));
109 return /*#__PURE__*/React.createElement(Typography, _extends({
110 ref: ref,
111 component: Component,
112 color: "textSecondary",
113 className: clsx(classes.root, className)
114 }, other), /*#__PURE__*/React.createElement("ol", {
115 className: classes.ol
116 }, insertSeparators(expanded || maxItems && allItems.length <= maxItems ? allItems : renderItemsBeforeAndAfter(allItems), classes.separator, separator)));
117});
118process.env.NODE_ENV !== "production" ? Breadcrumbs.propTypes = {
119 // ----------------------------- Warning --------------------------------
120 // | These PropTypes are generated from the TypeScript type definitions |
121 // | To update them edit the d.ts file and run "yarn proptypes" |
122 // ----------------------------------------------------------------------
123
124 /**
125 * The breadcrumb children.
126 */
127 children: PropTypes.node,
128
129 /**
130 * Override or extend the styles applied to the component.
131 * See [CSS API](#css) below for more details.
132 */
133 classes: PropTypes.object,
134
135 /**
136 * @ignore
137 */
138 className: PropTypes.string,
139
140 /**
141 * The component used for the root node.
142 * Either a string to use a HTML element or a component.
143 */
144 component: PropTypes
145 /* @typescript-to-proptypes-ignore */
146 .elementType,
147
148 /**
149 * Override the default label for the expand button.
150 *
151 * For localization purposes, you can use the provided [translations](/guides/localization/).
152 */
153 expandText: PropTypes.string,
154
155 /**
156 * If max items is exceeded, the number of items to show after the ellipsis.
157 */
158 itemsAfterCollapse: PropTypes.number,
159
160 /**
161 * If max items is exceeded, the number of items to show before the ellipsis.
162 */
163 itemsBeforeCollapse: PropTypes.number,
164
165 /**
166 * Specifies the maximum number of breadcrumbs to display. When there are more
167 * than the maximum number, only the first `itemsBeforeCollapse` and last `itemsAfterCollapse`
168 * will be shown, with an ellipsis in between.
169 */
170 maxItems: PropTypes.number,
171
172 /**
173 * Custom separator node.
174 */
175 separator: PropTypes.node
176} : void 0;
177export default withStyles(styles, {
178 name: 'MuiBreadcrumbs'
179})(Breadcrumbs);
\No newline at end of file