From b99f6d5a9360ec04a41ebf5a3df35a95cbbdf549 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Sat, 14 Mar 2026 07:18:06 +0000 Subject: [PATCH] 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 Made-with: Cursor --- .changeset/fix-dialog-height-overflow.md | 7 ++++ .../src/components/Dialog/Dialog.module.css | 9 +++-- .../src/components/Dialog/Dialog.stories.tsx | 33 +++++++++++++++++++ packages/ui/src/components/Dialog/Dialog.tsx | 11 ++++--- 4 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 .changeset/fix-dialog-height-overflow.md diff --git a/.changeset/fix-dialog-height-overflow.md b/.changeset/fix-dialog-height-overflow.md new file mode 100644 index 0000000000..bf91d882dd --- /dev/null +++ b/.changeset/fix-dialog-height-overflow.md @@ -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 diff --git a/packages/ui/src/components/Dialog/Dialog.module.css b/packages/ui/src/components/Dialog/Dialog.module.css index da82509134..194128ec4d 100644 --- a/packages/ui/src/components/Dialog/Dialog.module.css +++ b/packages/ui/src/components/Dialog/Dialog.module.css @@ -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; } diff --git a/packages/ui/src/components/Dialog/Dialog.stories.tsx b/packages/ui/src/components/Dialog/Dialog.stories.tsx index 9084bfa7e4..8892cb2314 100644 --- a/packages/ui/src/components/Dialog/Dialog.stories.tsx +++ b/packages/ui/src/components/Dialog/Dialog.stories.tsx @@ -247,6 +247,39 @@ export const WithForm = meta.story({ ), }); +export const OverflowWithoutHeight = meta.story({ + args: { + defaultOpen: true, + }, + render: args => ( + + + + Overflow Without Height + + + {Array.from({ length: 20 }, (_, i) => ( + + Line {i + 1}: Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Sed do eiusmod tempor incididunt ut labore et dolore magna + aliqua. + + ))} + + + + + + + + + ), +}); + export const PreviewFixedWidthAndHeight = FixedWidth.extend({ args: { defaultOpen: undefined, diff --git a/packages/ui/src/components/Dialog/Dialog.tsx b/packages/ui/src/components/Dialog/Dialog.tsx index fad5e10ea2..3a23ee27c9 100644 --- a/packages/ui/src/components/Dialog/Dialog.tsx +++ b/packages/ui/src/components/Dialog/Dialog.tsx @@ -67,11 +67,12 @@ export const Dialog = forwardRef, 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, }} >