fix(ui): fix Dialog content overflowing when no height prop is set

Replaces the invalid `min(auto, calc(100vh - 3rem))` CSS pattern with a
flex-based layout. The dialog now grows with its content by default and
scrolls when the content exceeds the viewport height. A fixed height can
still be applied via the `height` prop.

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
Made-with: Cursor
This commit is contained in:
Charles de Dreuille
2026-03-14 07:18:06 +00:00
parent fcaac3b8bd
commit b99f6d5a93
4 changed files with 53 additions and 7 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/ui': patch
---
Fixed `Dialog` content overflowing when no `height` prop is set. The dialog now grows with its content and scrolls when content exceeds the viewport height.
**Affected components**: Dialog
@@ -50,9 +50,11 @@
border: 1px solid var(--bui-border-1);
color: var(--bui-fg-primary);
position: relative;
display: flex;
flex-direction: column;
width: min(var(--bui-dialog-min-width, 400px), calc(100vw - 3rem));
max-width: calc(100vw - 3rem);
height: min(var(--bui-dialog-min-height, auto), calc(100vh - 3rem));
height: var(--bui-dialog-height, auto);
max-height: calc(100vh - 3rem);
outline: none;
}
@@ -61,7 +63,9 @@
display: flex;
flex-direction: column;
border-radius: var(--dialog-border-radius);
height: 100%;
flex: 1;
min-height: 0;
overflow: hidden;
}
/* Dialog entering animation */
@@ -102,6 +106,7 @@
.bui-DialogBody {
padding: var(--bui-space-3);
flex: 1;
min-height: 0;
overflow-y: auto;
}
@@ -247,6 +247,39 @@ export const WithForm = meta.story({
),
});
export const OverflowWithoutHeight = meta.story({
args: {
defaultOpen: true,
},
render: args => (
<DialogTrigger>
<Button variant="secondary">Open Dialog</Button>
<Dialog {...args}>
<DialogHeader>Overflow Without Height</DialogHeader>
<DialogBody>
<Flex direction="column" gap="3">
{Array.from({ length: 20 }, (_, i) => (
<Text key={i}>
Line {i + 1}: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
</Text>
))}
</Flex>
</DialogBody>
<DialogFooter>
<Button variant="secondary" slot="close">
Cancel
</Button>
<Button variant="primary" slot="close">
Confirm
</Button>
</DialogFooter>
</Dialog>
</DialogTrigger>
),
});
export const PreviewFixedWidthAndHeight = FixedWidth.extend({
args: {
defaultOpen: undefined,
+6 -5
View File
@@ -67,11 +67,12 @@ export const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(
style={{
['--bui-dialog-min-width' as keyof React.CSSProperties]:
typeof width === 'number' ? `${width}px` : width || '400px',
['--bui-dialog-min-height' as keyof React.CSSProperties]: height
? typeof height === 'number'
? `${height}px`
: height
: 'auto',
...(height
? {
['--bui-dialog-height' as keyof React.CSSProperties]:
typeof height === 'number' ? `${height}px` : height,
}
: {}),
...style,
}}
>