Remove DialogClose and add width and height props
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -11,9 +11,10 @@ import {
|
||||
dialogClosePropDefs,
|
||||
dialogUsageSnippet,
|
||||
dialogDefaultSnippet,
|
||||
dialogScrollableSnippet,
|
||||
dialogFixedWidthAndHeightSnippet,
|
||||
dialogWithFormSnippet,
|
||||
dialogWithNoTriggerSnippet,
|
||||
dialogCloseSnippet,
|
||||
} from './dialog.props';
|
||||
import { PageTitle } from '@/components/PageTitle';
|
||||
import { Theming } from '@/components/Theming';
|
||||
@@ -37,18 +38,18 @@ import { ChangelogComponent } from '@/components/ChangelogComponent';
|
||||
|
||||
## API reference
|
||||
|
||||
### Dialog
|
||||
|
||||
The main dialog container that renders as a modal overlay.
|
||||
|
||||
<PropsTable data={dialogPropDefs} />
|
||||
|
||||
### DialogTrigger
|
||||
|
||||
Wraps a trigger element and the dialog content to handle open/close state.
|
||||
|
||||
<PropsTable data={dialogTriggerPropDefs} />
|
||||
|
||||
### Dialog
|
||||
|
||||
The main dialog container that renders as a modal overlay.
|
||||
|
||||
<PropsTable data={dialogPropDefs} />
|
||||
|
||||
### DialogHeader
|
||||
|
||||
Displays the dialog title with a built-in close button.
|
||||
@@ -67,23 +68,21 @@ Contains action buttons or other footer content.
|
||||
|
||||
<PropsTable data={dialogFooterPropDefs} />
|
||||
|
||||
### DialogClose
|
||||
If you want to close the dialog while pressing a button, you can use the `slot="close"` prop on the button.
|
||||
|
||||
A button that closes the dialog when pressed.
|
||||
|
||||
<PropsTable data={dialogClosePropDefs} />
|
||||
<CodeBlock code={dialogCloseSnippet} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Scrollable Content
|
||||
### Fixed Width and Height
|
||||
|
||||
Dialog with a fixed height body that scrolls when content overflows.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<DialogSnippet story="PreviewScrollable" />}
|
||||
code={dialogScrollableSnippet}
|
||||
preview={<DialogSnippet story="PreviewFixedWidthAndHeight" />}
|
||||
code={dialogFixedWidthAndHeightSnippet}
|
||||
/>
|
||||
|
||||
### Dialog with Form
|
||||
|
||||
@@ -4,14 +4,52 @@ import {
|
||||
type PropDef,
|
||||
} from '@/utils/propDefs';
|
||||
|
||||
export const dialogPropDefs: Record<string, PropDef> = {
|
||||
children: { type: 'enum', values: ['ReactNode'], responsive: false },
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const dialogTriggerPropDefs: Record<string, PropDef> = {
|
||||
children: { type: 'enum', values: ['ReactNode'], responsive: false },
|
||||
isOpen: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the overlay is open by default (controlled).',
|
||||
},
|
||||
defaultOpen: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the overlay is open by default (uncontrolled).',
|
||||
},
|
||||
onOpenChange: {
|
||||
type: 'enum',
|
||||
values: ['(isOpen: boolean) => void'],
|
||||
description:
|
||||
"Handler that is called when the overlay's open state changes.",
|
||||
},
|
||||
};
|
||||
|
||||
export const dialogPropDefs: Record<string, PropDef> = {
|
||||
children: { type: 'enum', values: ['ReactNode'], responsive: false },
|
||||
isOpen: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the overlay is open by default (controlled).',
|
||||
},
|
||||
defaultOpen: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the overlay is open by default (uncontrolled).',
|
||||
},
|
||||
onOpenChange: {
|
||||
type: 'enum',
|
||||
values: ['(isOpen: boolean) => void'],
|
||||
description:
|
||||
"Handler that is called when the overlay's open state changes.",
|
||||
},
|
||||
width: {
|
||||
type: 'enum',
|
||||
values: ['number', 'string'],
|
||||
responsive: false,
|
||||
},
|
||||
height: {
|
||||
type: 'enum',
|
||||
values: ['number', 'string'],
|
||||
responsive: false,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const dialogHeaderPropDefs: Record<string, PropDef> = {
|
||||
@@ -55,7 +93,6 @@ export const dialogUsageSnippet = `import {
|
||||
DialogHeader,
|
||||
DialogBody,
|
||||
DialogFooter,
|
||||
DialogClose
|
||||
} from '@backstage/ui';
|
||||
|
||||
<DialogTrigger>
|
||||
@@ -64,7 +101,7 @@ export const dialogUsageSnippet = `import {
|
||||
<DialogHeader>Title</DialogHeader>
|
||||
<DialogBody>Content</DialogBody>
|
||||
<DialogFooter>
|
||||
<DialogClose>Close</DialogClose>
|
||||
<Button variant="secondary" slot="close">Close</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>`;
|
||||
@@ -77,39 +114,22 @@ export const dialogDefaultSnippet = `<DialogTrigger>
|
||||
<Text>This is a basic dialog example.</Text>
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<DialogClose>Close</DialogClose>
|
||||
<DialogClose variant="primary">Save</DialogClose>
|
||||
<Button variant="secondary" slot="close">Close</Button>
|
||||
<Button variant="primary" slot="close">Save</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>`;
|
||||
|
||||
export const dialogScrollableSnippet = `<DialogTrigger>
|
||||
export const dialogFixedWidthAndHeightSnippet = `<DialogTrigger>
|
||||
<Button variant="secondary">Scrollable Dialog</Button>
|
||||
<Dialog>
|
||||
<DialogHeader>Long Content Dialog</DialogHeader>
|
||||
<DialogBody height={200}>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<DialogBody width={600} height={400}>
|
||||
...
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<Flex gap="2" justify="end">
|
||||
<DialogClose>Cancel</DialogClose>
|
||||
<DialogClose variant="primary">Accept</DialogClose>
|
||||
</Flex>
|
||||
<Button variant="secondary" slot="close">Cancel</Button>
|
||||
<Button variant="primary" slot="close">Accept</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>`;
|
||||
@@ -130,10 +150,8 @@ export const dialogWithFormSnippet = `<DialogTrigger>
|
||||
</Flex>
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<Flex gap="2" justify="end">
|
||||
<DialogClose>Cancel</DialogClose>
|
||||
<DialogClose variant="primary">Create User</DialogClose>
|
||||
</Flex>
|
||||
<Button variant="secondary" slot="close">Cancel</Button>
|
||||
<Button variant="primary" slot="close">Create User</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>`;
|
||||
@@ -146,9 +164,9 @@ export const dialogWithNoTriggerSnippet = `const [isOpen, setIsOpen] = useState(
|
||||
Your content
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<Flex gap="2" justify="end">
|
||||
<DialogClose>Cancel</DialogClose>
|
||||
<DialogClose variant="primary">Create User</DialogClose>
|
||||
</Flex>
|
||||
<Button variant="secondary" slot="close">Cancel</Button>
|
||||
<Button variant="primary" slot="close">Create User</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>`;
|
||||
|
||||
export const dialogCloseSnippet = `<Button slot="close">Close</Button>`;
|
||||
|
||||
@@ -443,8 +443,8 @@ export const componentDefinitions: {
|
||||
};
|
||||
readonly Dialog: {
|
||||
readonly classNames: {
|
||||
readonly root: 'bui-Dialog';
|
||||
readonly content: 'bui-DialogContent';
|
||||
readonly overlay: 'bui-DialogOverlay';
|
||||
readonly dialog: 'bui-Dialog';
|
||||
readonly header: 'bui-DialogHeader';
|
||||
readonly headerTitle: 'bui-DialogHeaderTitle';
|
||||
readonly body: 'bui-DialogBody';
|
||||
@@ -729,19 +729,6 @@ export interface DialogBodyProps {
|
||||
children?: React.ReactNode;
|
||||
// (undocumented)
|
||||
className?: string;
|
||||
// (undocumented)
|
||||
height?: number | string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const DialogClose: ForwardRefExoticComponent<
|
||||
DialogCloseProps & RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
// @public
|
||||
export interface DialogCloseProps extends Omit<ButtonProps, 'slot'> {
|
||||
// (undocumented)
|
||||
variant?: 'primary' | 'secondary' | 'tertiary';
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -772,6 +759,10 @@ export interface DialogProps extends ModalOverlayProps {
|
||||
children?: React.ReactNode;
|
||||
// (undocumented)
|
||||
className?: string;
|
||||
// (undocumented)
|
||||
height?: number | string;
|
||||
// (undocumented)
|
||||
width?: number | string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
DialogHeader,
|
||||
DialogBody,
|
||||
DialogFooter,
|
||||
DialogClose,
|
||||
} from './Dialog';
|
||||
import { Button, Flex, Text, TextField, Select } from '@backstage/ui';
|
||||
import { useArgs } from 'storybook/preview-api';
|
||||
@@ -44,16 +43,20 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: args => {
|
||||
return (
|
||||
<DialogTrigger {...args}>
|
||||
<DialogTrigger>
|
||||
<Button variant="secondary">Open Dialog</Button>
|
||||
<Dialog>
|
||||
<Dialog {...args}>
|
||||
<DialogHeader>Example Dialog</DialogHeader>
|
||||
<DialogBody>
|
||||
<Text>This is a basic dialog example.</Text>
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<DialogClose>Close</DialogClose>
|
||||
<DialogClose variant="primary">Save</DialogClose>
|
||||
<Button variant="secondary" slot="close">
|
||||
Close
|
||||
</Button>
|
||||
<Button variant="primary" slot="close">
|
||||
Save
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>
|
||||
@@ -87,52 +90,89 @@ export const NoTrigger: Story = {
|
||||
<Text>This is a basic dialog example.</Text>
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<DialogClose>Close</DialogClose>
|
||||
<DialogClose variant="primary">Save</DialogClose>
|
||||
<Button variant="secondary" slot="close">
|
||||
Close
|
||||
</Button>
|
||||
<Button variant="primary" slot="close">
|
||||
Save
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const Scrollable: Story = {
|
||||
export const FixedWidth: Story = {
|
||||
args: {
|
||||
isOpen: true,
|
||||
defaultOpen: true,
|
||||
width: 600,
|
||||
},
|
||||
render: args => (
|
||||
<DialogTrigger {...args}>
|
||||
<Button variant="secondary">Scrollable Dialog</Button>
|
||||
<Dialog>
|
||||
<DialogTrigger>
|
||||
<Button variant="secondary">Open Dialog</Button>
|
||||
<Dialog {...args}>
|
||||
<DialogHeader>Long Content Dialog</DialogHeader>
|
||||
<DialogBody height={200}>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<DialogBody>
|
||||
<Flex direction="column" gap="3">
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
</Flex>
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<DialogClose>Cancel</DialogClose>
|
||||
<DialogClose variant="primary">Accept</DialogClose>
|
||||
<Button variant="secondary" slot="close">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="primary" slot="close">
|
||||
Accept
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>
|
||||
),
|
||||
};
|
||||
|
||||
export const FixedHeight: Story = {
|
||||
args: {
|
||||
defaultOpen: true,
|
||||
height: 500,
|
||||
},
|
||||
render: FixedWidth.render,
|
||||
};
|
||||
|
||||
export const FixedWidthAndHeight: Story = {
|
||||
args: {
|
||||
defaultOpen: true,
|
||||
width: 600,
|
||||
height: 400,
|
||||
},
|
||||
render: FixedWidth.render,
|
||||
};
|
||||
|
||||
export const FullWidthAndHeight: Story = {
|
||||
args: {
|
||||
defaultOpen: true,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
render: FixedWidth.render,
|
||||
};
|
||||
|
||||
export const Confirmation: Story = {
|
||||
args: {
|
||||
isOpen: true,
|
||||
@@ -149,8 +189,12 @@ export const Confirmation: Story = {
|
||||
</Text>
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<DialogClose>Cancel</DialogClose>
|
||||
<DialogClose variant="primary">Delete</DialogClose>
|
||||
<Button variant="secondary" slot="close">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="primary" slot="close">
|
||||
Delete
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>
|
||||
@@ -181,26 +225,30 @@ export const WithForm: Story = {
|
||||
</Flex>
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<DialogClose>Cancel</DialogClose>
|
||||
<DialogClose variant="primary">Create User</DialogClose>
|
||||
<Button variant="secondary" slot="close">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="primary" slot="close">
|
||||
Create User
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</DialogTrigger>
|
||||
),
|
||||
};
|
||||
|
||||
export const PreviewScrollable: Story = {
|
||||
export const PreviewFixedWidthAndHeight: Story = {
|
||||
args: {
|
||||
...Scrollable.args,
|
||||
isOpen: false,
|
||||
defaultOpen: undefined,
|
||||
width: 600,
|
||||
height: 400,
|
||||
},
|
||||
render: Scrollable.render,
|
||||
render: FixedWidth.render,
|
||||
};
|
||||
|
||||
export const PreviewWithForm: Story = {
|
||||
args: {
|
||||
...WithForm.args,
|
||||
isOpen: false,
|
||||
defaultOpen: undefined,
|
||||
},
|
||||
render: WithForm.render,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Backdrop */
|
||||
.bui-Dialog {
|
||||
.bui-DialogOverlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -16,34 +16,36 @@
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.bui-Dialog[data-entering] {
|
||||
.bui-DialogOverlay[data-entering] {
|
||||
animation: fade-in 200ms ease-out forwards;
|
||||
}
|
||||
|
||||
.bui-Dialog[data-exiting] {
|
||||
.bui-DialogOverlay[data-exiting] {
|
||||
animation: fade-out 150ms ease-out forwards;
|
||||
}
|
||||
|
||||
.bui-DialogContent {
|
||||
.bui-Dialog {
|
||||
background: var(--bui-bg-surface-1);
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid var(--bui-border);
|
||||
color: var(--bui-fg-primary);
|
||||
position: relative;
|
||||
width: 24rem;
|
||||
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));
|
||||
max-height: calc(100vh - 3rem);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Dialog entering animation */
|
||||
.bui-Dialog[data-entering] .bui-DialogContent {
|
||||
.bui-DialogOverlay[data-entering] .bui-Dialog {
|
||||
animation: dialog-enter 150ms ease-out forwards;
|
||||
}
|
||||
|
||||
/* Dialog exiting animation */
|
||||
.bui-Dialog[data-exiting] .bui-DialogContent {
|
||||
.bui-DialogOverlay[data-exiting] .bui-Dialog {
|
||||
animation: dialog-exit 150ms ease-out forwards;
|
||||
}
|
||||
|
||||
@@ -74,6 +76,8 @@
|
||||
|
||||
.bui-DialogBody {
|
||||
padding: var(--bui-space-3);
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Keyframe animations */
|
||||
|
||||
@@ -27,11 +27,9 @@ import type {
|
||||
DialogHeaderProps,
|
||||
DialogProps,
|
||||
DialogBodyProps,
|
||||
DialogCloseProps,
|
||||
} from './types';
|
||||
import './Dialog.styles.css';
|
||||
import { RiCloseLine } from '@remixicon/react';
|
||||
import { ScrollArea } from '../ScrollArea';
|
||||
import { Button } from '../Button';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
import { Flex } from '../Flex';
|
||||
@@ -41,6 +39,41 @@ export const DialogTrigger = (props: DialogTriggerProps) => {
|
||||
return <RADialogTrigger {...props} />;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(
|
||||
({ className, children, width, height, style, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Dialog');
|
||||
|
||||
return (
|
||||
<Modal
|
||||
ref={ref}
|
||||
className={clsx(classNames.overlay)}
|
||||
isDismissable
|
||||
isKeyboardDismissDisabled={false}
|
||||
{...props}
|
||||
>
|
||||
<RADialog
|
||||
className={clsx(classNames.dialog, className)}
|
||||
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',
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RADialog>
|
||||
</Modal>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Dialog.displayName = 'Dialog';
|
||||
|
||||
/** @public */
|
||||
export const DialogHeader = forwardRef<
|
||||
React.ElementRef<'div'>,
|
||||
@@ -63,27 +96,13 @@ DialogHeader.displayName = 'DialogHeader';
|
||||
|
||||
/** @public */
|
||||
export const DialogBody = forwardRef<React.ElementRef<'div'>, DialogBodyProps>(
|
||||
({ className, children, height, ...props }, ref) => {
|
||||
({ className, children, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Dialog');
|
||||
|
||||
return (
|
||||
<ScrollArea.Root
|
||||
className={clsx(classNames.body, className)}
|
||||
style={{
|
||||
height: height
|
||||
? typeof height === 'number'
|
||||
? `${height}px`
|
||||
: height
|
||||
: undefined,
|
||||
}}
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<ScrollArea.Viewport>{children}</ScrollArea.Viewport>
|
||||
<ScrollArea.Scrollbar orientation="vertical">
|
||||
<ScrollArea.Thumb />
|
||||
</ScrollArea.Scrollbar>
|
||||
</ScrollArea.Root>
|
||||
<div className={clsx(classNames.body, className)} ref={ref} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -104,43 +123,3 @@ export const DialogFooter = forwardRef<
|
||||
);
|
||||
});
|
||||
DialogFooter.displayName = 'DialogFooter';
|
||||
|
||||
/** @public */
|
||||
export const DialogClose = forwardRef<
|
||||
React.ElementRef<typeof Button>,
|
||||
DialogCloseProps
|
||||
>(({ className, variant = 'secondary', children, ...props }, ref) => {
|
||||
return (
|
||||
<Button
|
||||
ref={ref}
|
||||
slot="close"
|
||||
variant={variant}
|
||||
className={className}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
});
|
||||
DialogClose.displayName = 'DialogClose';
|
||||
|
||||
/** @public */
|
||||
export const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(
|
||||
({ className, children, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Dialog');
|
||||
|
||||
return (
|
||||
<Modal
|
||||
ref={ref}
|
||||
className={clsx(classNames.root, className)}
|
||||
isDismissable
|
||||
isKeyboardDismissDisabled={false}
|
||||
{...props}
|
||||
>
|
||||
<RADialog className="bui-DialogContent">{children}</RADialog>
|
||||
</Modal>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Dialog.displayName = 'Dialog';
|
||||
|
||||
@@ -19,7 +19,6 @@ import type {
|
||||
ModalOverlayProps as RAModalProps,
|
||||
HeadingProps as RAHeadingProps,
|
||||
} from 'react-aria-components';
|
||||
import type { ButtonProps } from '../Button';
|
||||
|
||||
/**
|
||||
* Props for the DialogTrigger component.
|
||||
@@ -27,6 +26,17 @@ import type { ButtonProps } from '../Button';
|
||||
*/
|
||||
export interface DialogTriggerProps extends RADialogTriggerProps {}
|
||||
|
||||
/**
|
||||
* Props for the Dialog component.
|
||||
* @public
|
||||
*/
|
||||
export interface DialogProps extends RAModalProps {
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Props for the DialogHeader component.
|
||||
* @public
|
||||
@@ -43,22 +53,4 @@ export interface DialogHeaderProps extends RAHeadingProps {
|
||||
export interface DialogBodyProps {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
height?: number | string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Props for the DialogClose component.
|
||||
* @public
|
||||
*/
|
||||
export interface DialogCloseProps extends Omit<ButtonProps, 'slot'> {
|
||||
variant?: 'primary' | 'secondary' | 'tertiary';
|
||||
}
|
||||
|
||||
/**
|
||||
* Props for the Dialog component.
|
||||
* @public
|
||||
*/
|
||||
export interface DialogProps extends RAModalProps {
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ export const componentDefinitions = {
|
||||
},
|
||||
Dialog: {
|
||||
classNames: {
|
||||
root: 'bui-Dialog',
|
||||
content: 'bui-DialogContent',
|
||||
overlay: 'bui-DialogOverlay',
|
||||
dialog: 'bui-Dialog',
|
||||
header: 'bui-DialogHeader',
|
||||
headerTitle: 'bui-DialogHeaderTitle',
|
||||
body: 'bui-DialogBody',
|
||||
|
||||
Reference in New Issue
Block a user