Breadcrumbs: Improve responsiveness (#67955)

* Breadcrumbs: Improve responsiveness

* More tweaks and fixes

* more adapative logic

* reduce min-width on mobile
This commit is contained in:
Torkel Ödegaard 2023-05-10 16:11:40 +02:00 committed by GitHub
parent f8cf67347f
commit 260c4544cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 23 deletions

View File

@ -48,7 +48,7 @@ export function NavToolbar({
onClick={onToggleMegaMenu} onClick={onToggleMegaMenu}
/> />
</div> </div>
<Breadcrumbs breadcrumbs={breadcrumbs} className={styles.breadcrumbs} /> <Breadcrumbs breadcrumbs={breadcrumbs} className={styles.breadcrumbsWrapper} />
<div className={styles.actions}> <div className={styles.actions}>
{actions} {actions}
{actions && <NavToolbarSeparator />} {actions && <NavToolbarSeparator />}
@ -74,8 +74,12 @@ export function NavToolbar({
const getStyles = (theme: GrafanaTheme2) => { const getStyles = (theme: GrafanaTheme2) => {
return { return {
breadcrumbs: css({ breadcrumbsWrapper: css({
maxWidth: '50%', display: 'flex',
overflow: 'hidden',
[theme.breakpoints.down('sm')]: {
minWidth: '50%',
},
}), }),
pageToolbar: css({ pageToolbar: css({
height: TOP_BAR_LEVEL_HEIGHT, height: TOP_BAR_LEVEL_HEIGHT,

View File

@ -10,9 +10,11 @@ import { Breadcrumb } from './types';
type Props = Breadcrumb & { type Props = Breadcrumb & {
isCurrent: boolean; isCurrent: boolean;
index: number;
flexGrow: number;
}; };
export function BreadcrumbItem({ href, isCurrent, text }: Props) { export function BreadcrumbItem({ href, isCurrent, text, index, flexGrow }: Props) {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const onBreadcrumbClick = () => { const onBreadcrumbClick = () => {
@ -20,9 +22,14 @@ export function BreadcrumbItem({ href, isCurrent, text }: Props) {
}; };
return ( return (
<li className={styles.breadcrumbWrapper}> <li className={styles.breadcrumbWrapper} style={{ flexGrow }}>
{isCurrent ? ( {isCurrent ? (
<span data-testid={Components.Breadcrumbs.breadcrumb(text)} className={styles.breadcrumb} aria-current="page"> <span
data-testid={Components.Breadcrumbs.breadcrumb(text)}
className={styles.breadcrumb}
aria-current="page"
title={text}
>
{text} {text}
</span> </span>
) : ( ) : (
@ -31,6 +38,7 @@ export function BreadcrumbItem({ href, isCurrent, text }: Props) {
onClick={onBreadcrumbClick} onClick={onBreadcrumbClick}
data-testid={Components.Breadcrumbs.breadcrumb(text)} data-testid={Components.Breadcrumbs.breadcrumb(text)}
className={cx(styles.breadcrumb, styles.breadcrumbLink)} className={cx(styles.breadcrumb, styles.breadcrumbLink)}
title={text}
href={href} href={href}
> >
{text} {text}
@ -45,10 +53,6 @@ export function BreadcrumbItem({ href, isCurrent, text }: Props) {
} }
const getStyles = (theme: GrafanaTheme2) => { const getStyles = (theme: GrafanaTheme2) => {
const separator = css({
color: theme.colors.text.secondary,
});
return { return {
breadcrumb: css({ breadcrumb: css({
display: 'block', display: 'block',
@ -75,25 +79,19 @@ const getStyles = (theme: GrafanaTheme2) => {
// logic for small screens // logic for small screens
// hide any breadcrumbs that aren't the second to last child (the parent) // hide any breadcrumbs that aren't the second to last child (the parent)
// unless there's only one breadcrumb, in which case we show it // unless there's only one breadcrumb, in which case we show it
[theme.breakpoints.down('md')]: { [theme.breakpoints.down('sm')]: {
display: 'none', display: 'none',
'&:nth-last-child(2)': { '&:nth-last-child(2)': {
display: 'flex', display: 'flex',
flexDirection: 'row-reverse', minWidth: '40px',
[`.${separator}`]: {
transform: 'rotate(180deg)',
},
}, },
'&:first-child&:last-child': { '&:last-child': {
display: 'flex', display: 'flex',
[`.${separator}`]: {
display: 'none',
},
}, },
}, },
}), }),
separator, separator: css({
color: theme.colors.text.secondary,
}),
}; };
}; };

View File

@ -19,19 +19,38 @@ export function Breadcrumbs({ breadcrumbs, className }: Props) {
<nav aria-label="Breadcrumbs" className={className}> <nav aria-label="Breadcrumbs" className={className}>
<ol className={styles.breadcrumbs}> <ol className={styles.breadcrumbs}>
{breadcrumbs.map((breadcrumb, index) => ( {breadcrumbs.map((breadcrumb, index) => (
<BreadcrumbItem {...breadcrumb} isCurrent={index === breadcrumbs.length - 1} key={index} /> <BreadcrumbItem
{...breadcrumb}
isCurrent={index === breadcrumbs.length - 1}
key={index}
index={index}
flexGrow={getFlexGrow(index, breadcrumbs.length)}
/>
))} ))}
</ol> </ol>
</nav> </nav>
); );
} }
function getFlexGrow(index: number, length: number) {
if (length < 5 && index > 0 && index < length - 2) {
return 4;
}
if (length > 6 && index > 1 && index < length - 3) {
return 4;
}
return 10;
}
const getStyles = (theme: GrafanaTheme2) => { const getStyles = (theme: GrafanaTheme2) => {
return { return {
breadcrumbs: css({ breadcrumbs: css({
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
flexWrap: 'nowrap', flexWrap: 'nowrap',
overflow: 'hidden',
}), }),
}; };
}; };