diff --git a/docs-ui/src/content/components/dialog.mdx b/docs-ui/src/content/components/dialog.mdx
new file mode 100644
index 0000000000..2524fc1a24
--- /dev/null
+++ b/docs-ui/src/content/components/dialog.mdx
@@ -0,0 +1,101 @@
+import { PropsTable } from '@/components/PropsTable';
+import { Snippet } from '@/components/Snippet';
+import { CodeBlock } from '@/components/CodeBlock';
+import {DialogSnippet} from '@/snippets/stories-snippets';
+import {
+ dialogPropDefs,
+ dialogTriggerPropDefs,
+ dialogHeaderPropDefs,
+ dialogBodyPropDefs,
+ dialogFooterPropDefs,
+ dialogClosePropDefs,
+ dialogUsageSnippet,
+ dialogDefaultSnippet,
+ dialogScrollableSnippet,
+ dialogWithFormSnippet,
+} from './dialog.props';
+import { PageTitle } from '@/components/PageTitle';
+import { Theming } from '@/components/Theming';
+import { ChangelogComponent } from '@/components/ChangelogComponent';
+
+
+
+}
+ code={dialogDefaultSnippet}
+/>
+
+## Usage
+
+
+
+## API reference
+
+### Dialog
+
+The main dialog container that renders as a modal overlay.
+
+
+
+### DialogTrigger
+
+Wraps a trigger element and the dialog content to handle open/close state.
+
+
+
+### DialogHeader
+
+Displays the dialog title with a built-in close button.
+
+
+
+### DialogBody
+
+The main content area of the dialog with optional scrolling.
+
+
+
+### DialogFooter
+
+Contains action buttons or other footer content.
+
+
+
+### DialogClose
+
+A button that closes the dialog when pressed.
+
+
+
+## Examples
+
+### Scrollable Content
+
+Dialog with a fixed height body that scrolls when content overflows.
+
+}
+ code={dialogScrollableSnippet}
+/>
+
+### Dialog with Form
+
+Dialog containing form elements for user input.
+
+}
+ code={dialogWithFormSnippet}
+/>
+
+
+
+
diff --git a/docs-ui/src/content/components/dialog.props.ts b/docs-ui/src/content/components/dialog.props.ts
new file mode 100644
index 0000000000..feefc4efd5
--- /dev/null
+++ b/docs-ui/src/content/components/dialog.props.ts
@@ -0,0 +1,139 @@
+import {
+ classNamePropDefs,
+ stylePropDefs,
+ type PropDef,
+} from '@/utils/propDefs';
+
+export const dialogPropDefs: Record = {
+ children: { type: 'enum', values: ['ReactNode'], responsive: false },
+ ...classNamePropDefs,
+ ...stylePropDefs,
+};
+
+export const dialogTriggerPropDefs: Record = {
+ children: { type: 'enum', values: ['ReactNode'], responsive: false },
+};
+
+export const dialogHeaderPropDefs: Record = {
+ children: { type: 'enum', values: ['ReactNode'], responsive: false },
+ ...classNamePropDefs,
+ ...stylePropDefs,
+};
+
+export const dialogBodyPropDefs: Record = {
+ children: { type: 'enum', values: ['ReactNode'], responsive: false },
+ height: {
+ type: 'enum',
+ values: ['number', 'string'],
+ responsive: false,
+ },
+ ...classNamePropDefs,
+ ...stylePropDefs,
+};
+
+export const dialogFooterPropDefs: Record = {
+ children: { type: 'enum', values: ['ReactNode'], responsive: false },
+ ...classNamePropDefs,
+ ...stylePropDefs,
+};
+
+export const dialogClosePropDefs: Record = {
+ variant: {
+ type: 'enum',
+ values: ['primary', 'secondary', 'tertiary'],
+ default: 'secondary',
+ responsive: false,
+ },
+ children: { type: 'enum', values: ['ReactNode'], responsive: false },
+ ...classNamePropDefs,
+ ...stylePropDefs,
+};
+
+export const dialogUsageSnippet = `import {
+ Dialog,
+ DialogTrigger,
+ DialogHeader,
+ DialogBody,
+ DialogFooter,
+ DialogClose
+} from '@backstage/ui';
+
+
+
+
+`;
+
+export const dialogDefaultSnippet = `
+
+
+`;
+
+export const dialogScrollableSnippet = `
+
+
+`;
+
+export const dialogWithFormSnippet = `
+
+
+`;
diff --git a/docs-ui/src/snippets/stories-snippets.tsx b/docs-ui/src/snippets/stories-snippets.tsx
index 5aa5b8c7d9..a84e790476 100644
--- a/docs-ui/src/snippets/stories-snippets.tsx
+++ b/docs-ui/src/snippets/stories-snippets.tsx
@@ -17,6 +17,7 @@ import * as MenuStories from '../../../packages/ui/src/components/Menu/Menu.stor
import * as LinkStories from '../../../packages/ui/src/components/Link/Link.stories';
import * as AvatarStories from '../../../packages/ui/src/components/Avatar/Avatar.stories';
import * as CollapsibleStories from '../../../packages/ui/src/components/Collapsible/Collapsible.stories';
+import * as DialogStories from '../../../packages/ui/src/components/Dialog/Dialog.stories';
import * as RadioGroupStories from '../../../packages/ui/src/components/RadioGroup/RadioGroup.stories';
import * as TabsStories from '../../../packages/ui/src/components/Tabs/Tabs.stories';
import * as SwitchStories from '../../../packages/ui/src/components/Switch/Switch.stories';
@@ -60,6 +61,7 @@ export const MenuSnippet = createSnippetComponent(MenuStories);
export const LinkSnippet = createSnippetComponent(LinkStories);
export const AvatarSnippet = createSnippetComponent(AvatarStories);
export const CollapsibleSnippet = createSnippetComponent(CollapsibleStories);
+export const DialogSnippet = createSnippetComponent(DialogStories);
export const RadioGroupSnippet = createSnippetComponent(RadioGroupStories);
export const TabsSnippet = createSnippetComponent(TabsStories);
export const SwitchSnippet = createSnippetComponent(SwitchStories);
diff --git a/docs-ui/src/utils/data.ts b/docs-ui/src/utils/data.ts
index 5e7305da28..dfe563c0d1 100644
--- a/docs-ui/src/utils/data.ts
+++ b/docs-ui/src/utils/data.ts
@@ -101,6 +101,11 @@ export const components: Page[] = [
slug: 'collapsible',
status: 'alpha',
},
+ {
+ title: 'Dialog',
+ slug: 'dialog',
+ status: 'alpha',
+ },
{
title: 'Header',
slug: 'header',
diff --git a/packages/ui/src/components/Dialog/Dialog.stories.tsx b/packages/ui/src/components/Dialog/Dialog.stories.tsx
index 47b62330f7..dacf6427b6 100644
--- a/packages/ui/src/components/Dialog/Dialog.stories.tsx
+++ b/packages/ui/src/components/Dialog/Dialog.stories.tsx
@@ -22,7 +22,7 @@ import {
DialogFooter,
DialogClose,
} from './Dialog';
-import { Button, Flex, Text } from '@backstage/ui';
+import { Button, Flex, Text, TextField, Select } from '@backstage/ui';
const meta = {
title: 'Components/Dialog',
@@ -33,64 +33,106 @@ export default meta;
type Story = StoryObj;
export const Default: Story = {
- args: {
- children: (
- <>
- Hello
+ render: () => (
+
+
+
),
};
-export const CustomBodyMaxHeight: Story = {
- args: {
- children: (
- <>
- Hello
-
- {Array.from({ length: 40 }).map((_, index) => (
-
- Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam,
- quos.
-
- ))}
+export const Scrollable: Story = {
+ render: () => (
+
+
+
+ Long Content Dialog
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
+ ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+ Duis aute irure dolor in reprehenderit in voluptate velit esse
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
+ cupidatat non proident, sunt in culpa qui officia deserunt mollit
+ anim id est laborum.
+
+
+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem
+ accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
+ quae ab illo inventore veritatis et quasi architecto beatae vitae
+ dicta sunt explicabo.
+
-
- Close
- console.log('Save')}>
- Save
-
-
+ Cancel
+ Accept
- >
- ),
- },
- render: args => (
-
-
-
+
+
+ ),
+};
+
+export const Confirmation: Story = {
+ render: () => (
+
+
+
+ Confirm Delete
+
+
+ Are you sure you want to delete this item? This action cannot be
+ undone.
+
+
+
+ Cancel
+ Delete
+
+
+
+ ),
+};
+
+export const WithForm: Story = {
+ render: () => (
+
+
+
+ Create New User
+
+
+
+
+
+
+
+
+ Cancel
+ Create User
+
+
),
};
diff --git a/packages/ui/src/components/Dialog/Dialog.styles.css b/packages/ui/src/components/Dialog/Dialog.styles.css
index 6186f5dc89..820e9ca094 100644
--- a/packages/ui/src/components/Dialog/Dialog.styles.css
+++ b/packages/ui/src/components/Dialog/Dialog.styles.css
@@ -9,6 +9,7 @@
display: flex;
align-items: center;
justify-content: center;
+ z-index: 1000;
}
.bui-Dialog[data-entering] {