Merge pull request #30634 from backstage/blam/entity-page-scrolling

`nfs`: Fixing scrolling behavior for the `info` Cards in the sidebar
This commit is contained in:
Patrik Oldsberg
2025-07-29 16:35:32 +02:00
committed by GitHub
2 changed files with 56 additions and 22 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Fix card scrolling behaviour
@@ -41,7 +41,7 @@ const useStyles = makeStyles<
flexFlow: 'column nowrap',
gap: theme.spacing(3),
},
contentArea: {
mainContent: {
display: 'flex',
flexFlow: 'column',
gap: theme.spacing(3),
@@ -51,9 +51,13 @@ const useStyles = makeStyles<
infoArea: {
display: 'flex',
flexFlow: 'column nowrap',
alignItems: 'stretch',
alignItems: 'flex-start',
gap: theme.spacing(3),
minWidth: 0,
'& > *': {
flexShrink: 0,
flexGrow: 0,
},
},
summaryArea: {
minWidth: 0,
@@ -65,10 +69,17 @@ const useStyles = makeStyles<
marginLeft: theme.spacing(3),
},
},
contentArea: {
display: 'flex',
flexFlow: 'column',
gap: theme.spacing(3),
alignItems: 'stretch',
minWidth: 0,
},
[theme.breakpoints.up('md')]: {
root: {
display: 'grid',
gap: 0,
gap: theme.spacing(3),
gridTemplateAreas: ({ summaryCards }) => `
"${summaryCards ? 'summary' : 'content'} info"
"content info"
@@ -76,11 +87,8 @@ const useStyles = makeStyles<
gridTemplateColumns: ({ infoCards }) => (infoCards ? '2fr 1fr' : '1fr'),
alignItems: 'start',
},
infoArea: {
gridArea: 'info',
position: 'sticky',
top: theme.spacing(3),
marginLeft: theme.spacing(3),
mainContent: {
display: 'contents',
},
contentArea: {
gridArea: 'content',
@@ -89,6 +97,25 @@ const useStyles = makeStyles<
gridArea: 'summary',
marginBottom: theme.spacing(3),
},
infoArea: {
gridArea: 'info',
position: 'sticky',
top: theme.spacing(3),
// this is a little unfortunate, but it's required to make the info cards scrollable
// in a fixed container of the full height when it's stuck.
// 100% doesn't work as that's the height of the entire layout, which is what powers the card scrolling.
maxHeight: '100vh',
overflowY: 'auto',
alignSelf: 'start',
alignItems: 'stretch',
// Hide the scrollbar for the inner info cards
// kind of an accessibility nightmare, but we see.
scrollbarWidth: 'none',
msOverflowStyle: 'none',
'&::-webkit-scrollbar': {
display: 'none',
},
},
},
}));
@@ -144,20 +171,22 @@ export function DefaultEntityContentLayout(props: EntityContentLayoutProps) {
{infoCards.map(card => card.element)}
</div>
) : null}
{summaryCards.length > 0 ? (
<div className={classes.summaryArea}>
<HorizontalScrollGrid scrollStep={400} scrollSpeed={100}>
{summaryCards.map(card => (
<div className={classes.summaryCard}>{card.element}</div>
))}
</HorizontalScrollGrid>
</div>
) : null}
{contentCards.length > 0 ? (
<div className={classes.contentArea}>
{contentCards.map(card => card.element)}
</div>
) : null}
<div className={classes.mainContent}>
{summaryCards.length > 0 ? (
<div className={classes.summaryArea}>
<HorizontalScrollGrid scrollStep={400} scrollSpeed={100}>
{summaryCards.map(card => (
<div className={classes.summaryCard}>{card.element}</div>
))}
</HorizontalScrollGrid>
</div>
) : null}
{contentCards.length > 0 ? (
<div className={classes.contentArea}>
{contentCards.map(card => card.element)}
</div>
) : null}
</div>
</div>
</>
);