1 | 'use client';
|
2 |
|
3 | import * as React from 'react';
|
4 | import { isFragment } from 'react-is';
|
5 | import PropTypes from 'prop-types';
|
6 | import clsx from 'clsx';
|
7 | import integerPropType from '@mui/utils/integerPropType';
|
8 | import composeClasses from '@mui/utils/composeClasses';
|
9 | import useSlotProps from '@mui/utils/useSlotProps';
|
10 | import { styled } from "../zero-styled/index.js";
|
11 | import { useDefaultProps } from "../DefaultPropsProvider/index.js";
|
12 | import Typography from "../Typography/index.js";
|
13 | import BreadcrumbCollapsed from "./BreadcrumbCollapsed.js";
|
14 | import breadcrumbsClasses, { getBreadcrumbsUtilityClass } from "./breadcrumbsClasses.js";
|
15 | import { jsx as _jsx } from "react/jsx-runtime";
|
16 | const useUtilityClasses = ownerState => {
|
17 | const {
|
18 | classes
|
19 | } = ownerState;
|
20 | const slots = {
|
21 | root: ['root'],
|
22 | li: ['li'],
|
23 | ol: ['ol'],
|
24 | separator: ['separator']
|
25 | };
|
26 | return composeClasses(slots, getBreadcrumbsUtilityClass, classes);
|
27 | };
|
28 | const BreadcrumbsRoot = styled(Typography, {
|
29 | name: 'MuiBreadcrumbs',
|
30 | slot: 'Root',
|
31 | overridesResolver: (props, styles) => {
|
32 | return [{
|
33 | [`& .${breadcrumbsClasses.li}`]: styles.li
|
34 | }, styles.root];
|
35 | }
|
36 | })({});
|
37 | const BreadcrumbsOl = styled('ol', {
|
38 | name: 'MuiBreadcrumbs',
|
39 | slot: 'Ol',
|
40 | overridesResolver: (props, styles) => styles.ol
|
41 | })({
|
42 | display: 'flex',
|
43 | flexWrap: 'wrap',
|
44 | alignItems: 'center',
|
45 | padding: 0,
|
46 | margin: 0,
|
47 | listStyle: 'none'
|
48 | });
|
49 | const BreadcrumbsSeparator = styled('li', {
|
50 | name: 'MuiBreadcrumbs',
|
51 | slot: 'Separator',
|
52 | overridesResolver: (props, styles) => styles.separator
|
53 | })({
|
54 | display: 'flex',
|
55 | userSelect: 'none',
|
56 | marginLeft: 8,
|
57 | marginRight: 8
|
58 | });
|
59 | function insertSeparators(items, className, separator, ownerState) {
|
60 | return items.reduce((acc, current, index) => {
|
61 | if (index < items.length - 1) {
|
62 | acc = acc.concat(current, _jsx(BreadcrumbsSeparator, {
|
63 | "aria-hidden": true,
|
64 | className: className,
|
65 | ownerState: ownerState,
|
66 | children: separator
|
67 | }, `separator-${index}`));
|
68 | } else {
|
69 | acc.push(current);
|
70 | }
|
71 | return acc;
|
72 | }, []);
|
73 | }
|
74 | const Breadcrumbs = React.forwardRef(function Breadcrumbs(inProps, ref) {
|
75 | const props = useDefaultProps({
|
76 | props: inProps,
|
77 | name: 'MuiBreadcrumbs'
|
78 | });
|
79 | const {
|
80 | children,
|
81 | className,
|
82 | component = 'nav',
|
83 | slots = {},
|
84 | slotProps = {},
|
85 | expandText = 'Show path',
|
86 | itemsAfterCollapse = 1,
|
87 | itemsBeforeCollapse = 1,
|
88 | maxItems = 8,
|
89 | separator = '/',
|
90 | ...other
|
91 | } = props;
|
92 | const [expanded, setExpanded] = React.useState(false);
|
93 | const ownerState = {
|
94 | ...props,
|
95 | component,
|
96 | expanded,
|
97 | expandText,
|
98 | itemsAfterCollapse,
|
99 | itemsBeforeCollapse,
|
100 | maxItems,
|
101 | separator
|
102 | };
|
103 | const classes = useUtilityClasses(ownerState);
|
104 | const collapsedIconSlotProps = useSlotProps({
|
105 | elementType: slots.CollapsedIcon,
|
106 | externalSlotProps: slotProps.collapsedIcon,
|
107 | ownerState
|
108 | });
|
109 | const listRef = React.useRef(null);
|
110 | const renderItemsBeforeAndAfter = allItems => {
|
111 | const handleClickExpand = () => {
|
112 | setExpanded(true);
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | const focusable = listRef.current.querySelector('a[href],button,[tabindex]');
|
119 | if (focusable) {
|
120 | focusable.focus();
|
121 | }
|
122 | };
|
123 |
|
124 |
|
125 |
|
126 | if (itemsBeforeCollapse + itemsAfterCollapse >= allItems.length) {
|
127 | if (process.env.NODE_ENV !== 'production') {
|
128 | console.error(['MUI: You have provided an invalid combination of props to the Breadcrumbs.', `itemsAfterCollapse={${itemsAfterCollapse}} + itemsBeforeCollapse={${itemsBeforeCollapse}} >= maxItems={${maxItems}}`].join('\n'));
|
129 | }
|
130 | return allItems;
|
131 | }
|
132 | return [...allItems.slice(0, itemsBeforeCollapse), _jsx(BreadcrumbCollapsed, {
|
133 | "aria-label": expandText,
|
134 | slots: {
|
135 | CollapsedIcon: slots.CollapsedIcon
|
136 | },
|
137 | slotProps: {
|
138 | collapsedIcon: collapsedIconSlotProps
|
139 | },
|
140 | onClick: handleClickExpand
|
141 | }, "ellipsis"), ...allItems.slice(allItems.length - itemsAfterCollapse, allItems.length)];
|
142 | };
|
143 | const allItems = React.Children.toArray(children).filter(child => {
|
144 | if (process.env.NODE_ENV !== 'production') {
|
145 | if (isFragment(child)) {
|
146 | console.error(["MUI: The Breadcrumbs component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
|
147 | }
|
148 | }
|
149 | return React.isValidElement(child);
|
150 | }).map((child, index) => _jsx("li", {
|
151 | className: classes.li,
|
152 | children: child
|
153 | }, `child-${index}`));
|
154 | return _jsx(BreadcrumbsRoot, {
|
155 | ref: ref,
|
156 | component: component,
|
157 | color: "textSecondary",
|
158 | className: clsx(classes.root, className),
|
159 | ownerState: ownerState,
|
160 | ...other,
|
161 | children: _jsx(BreadcrumbsOl, {
|
162 | className: classes.ol,
|
163 | ref: listRef,
|
164 | ownerState: ownerState,
|
165 | children: insertSeparators(expanded || maxItems && allItems.length <= maxItems ? allItems : renderItemsBeforeAndAfter(allItems), classes.separator, separator, ownerState)
|
166 | })
|
167 | });
|
168 | });
|
169 | process.env.NODE_ENV !== "production" ? Breadcrumbs.propTypes = {
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | |
175 |
|
176 |
|
177 | children: PropTypes.node,
|
178 | |
179 |
|
180 |
|
181 | classes: PropTypes.object,
|
182 | |
183 |
|
184 |
|
185 | className: PropTypes.string,
|
186 | |
187 |
|
188 |
|
189 |
|
190 | component: PropTypes.elementType,
|
191 | |
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 | expandText: PropTypes.string,
|
198 | |
199 |
|
200 |
|
201 |
|
202 | itemsAfterCollapse: integerPropType,
|
203 | |
204 |
|
205 |
|
206 |
|
207 | itemsBeforeCollapse: integerPropType,
|
208 | |
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 | maxItems: integerPropType,
|
215 | |
216 |
|
217 |
|
218 |
|
219 | separator: PropTypes.node,
|
220 | |
221 |
|
222 |
|
223 |
|
224 | slotProps: PropTypes.shape({
|
225 | collapsedIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
|
226 | }),
|
227 | |
228 |
|
229 |
|
230 |
|
231 |
|
232 | slots: PropTypes.shape({
|
233 | CollapsedIcon: PropTypes.elementType
|
234 | }),
|
235 | |
236 |
|
237 |
|
238 | sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
239 | } : void 0;
|
240 | export default Breadcrumbs; |
\ | No newline at end of file |