我正在尝试使 MUI 组件
Breadcrumbs
响应式:
当
Breadcrumbs
组件占据其所有空间时,其项目会使用省略号缩小,就像任何设置了 Typography
属性的 noWrap
组件一样。
我知道它有
itemsBeforeCollapse
、itemsAfterCollapse
和 maxItems
道具,但这些道具是关于项目编号与视口大小的比较,而不是关于每个项目的宽度。
我尝试将
noWrap
属性设置为 Typography
和 Link
组件(因为它扩展了 Typography
道具),但是省略号没有显示,并且 Link
或 Typography
组件也没有收缩。
<Breadcrumbs>
{links.map((link, i) =>
i !== links.length - 1 ? (
<Link
key={i}
underline={'hover'}
noWrap
>
{link}
</Link>
) : (
<Typography noWrap key={i}>
{link}
</Typography>
),
)}
</Breadcrumbs>
您可以在此 codeSandbox 上重现该问题:
如果我理解正确的话,问题是
noWrap
样式不会影响正确的元素。
为什么?
noWrap
影响其宽度限制为显式(例如 width: 100px
)或隐式(通过父级宽度)的元素。
在您的情况下,
Link
和Typography
的宽度不受限制。
你能做什么?
Breadcrumbs
使用 ol
渲染 display: flex
。为了迫使孩子们 (li
) 排队(在你的情况下,请排第三队),你应该给它 flex: 1
。从这一点开始,您可以为 li
指定省略号样式。
最后一部分,如何赋予
li
这些样式? css 部分描述了一些方法。
我会采取
styled
方法,这就是它的样子
import * as React from "react";
import Typography from "@mui/material/Typography";
import Breadcrumbs from "@mui/material/Breadcrumbs";
import Link from "@mui/material/Link";
import { styled } from "@mui/material/styles";
const StyledBreadcrumbs = styled(Breadcrumbs)`
.MuiBreadcrumbs-li {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
`;
export default function BasicBreadcrumbs() {
const links = [
"this is a waaaaaaaaaaaaay too long link",
"and another link that can be long too",
"this is the last link and guess what? It's waaaaaaaaaaaaaaaaaaayyy more longer"
];
return (
<StyledBreadcrumbs>
{links.map((link, i) =>
i !== links.length - 1 ? (
<Link key={i} underline={"hover"}>
{link}
</Link>
) : (
<Typography key={i}>
{link}
</Typography>
)
)}
</StyledBreadcrumbs>
);
}
https://codesandbox.io/s/basicbreadcrumbs-material-demo-forked-y1bbo?file=/demo.js
这是我的解决方案。注意
StyledBreadcrumbs
里面的sx
和<Breadcrumbs>
。
这会缩小除最后一项之外的所有项目。如果您想缩小最后一个,只需删除其中一个样式选择器中的
:not(:last-of-type)
即可。
import type { ReactElement } from 'react';
import type { BreadcrumbsProps } from '@mui/material';
import React, { MouseEventHandler } from 'react';
import { Link, Breadcrumbs as MUIBreadcrumbs, Typography, styled } from '@mui/material';
const StyledBreadcrumbs = styled(MUIBreadcrumbs)({
maxWidth: '100%',
'.MuiBreadcrumbs-ol': {
flexWrap: 'nowrap'
},
'.MuiBreadcrumbs-separator': {
flexShrink: 0
},
'.MuiBreadcrumbs-li:not(:last-of-type)': {
overflow: 'hidden'
}
});
export type Breadcrumb = {
text: React.ReactNode;
href?: string;
onClick?: MouseEventHandler<HTMLAnchorElement>;
};
type Props = {
breadcrumbs: Breadcrumb[];
} & Omit<BreadcrumbsProps, 'children'>;
export function Breadcrumbs({ breadcrumbs, ...props }: Props): ReactElement {
return <StyledBreadcrumbs {...props}>
{breadcrumbs.map(({ text, href, onClick }, index) => {
const sx = index === breadcrumbs.length - 1 ? {} : {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
};
if (href || onClick) {
return (
<Link key={index} color='inherit' href={href} onClick={onClick} sx={sx}>
{text}
</Link>
);
}
return (
<Typography key={index} color='inherit' sx={sx}>
{text}
</Typography>
);
})}
</StyledBreadcrumbs>;
}