Skip to content

Commit

Permalink
add alert dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
PixeledCode committed Mar 24, 2023
1 parent 82fbbc6 commit 2faae5d
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import '../../../styles/common';

.AlertDialog {
border: 1px solid black;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Meta, StoryObj } from '@storybook/react';
import { Button } from '../Button';
import { Dialog, Content, Trigger } from './AlertDialog';

/**
* A modal dialog that interrupts the user with important content and expects a response.
*
* Reference: https://www.radix-ui.com/docs/primitives/components/alert-dialog
*/
const meta = {
component: Content,
} satisfies Meta<typeof Content>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
render: ({ ...args }) => {
return (
<Dialog>
<Trigger>
<Button>Discard Changes</Button>
</Trigger>
<Content {...args} />
</Dialog>
);
},
args: {
title: 'Dialog Title',
children: 'Are you sure you want to discard all of your notes?',
primaryAction: {
content: 'Yes, discard',
onAction: () => console.log('discard'),
destructive: true,
},
secondaryActions: [
{
content: 'No, keep changes',
onAction: () => console.log('no'),
},
],
},
};
13 changes: 13 additions & 0 deletions packages/opub-ui/src/components/AlertDialog/AlertDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import { AlertDialog } from "./AlertDialog";

describe("AlertDialog Tests", () => {
beforeEach(() => {
render(<AlertDialog>Component</AlertDialog>);
});

test("should show Component text all the time", () => {
expect(screen.getByText(/Component/i)).toBeInTheDocument();
});
});
99 changes: 99 additions & 0 deletions packages/opub-ui/src/components/AlertDialog/AlertDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as AlertDialog from '@radix-ui/react-alert-dialog';
import cx from 'classnames';
import React, { forwardRef, Ref } from 'react';
import { Footer, FooterProps } from '../Dialog/components';
import styles from '../Dialog/Dialog.module.scss';
import { Header } from './components';

const Dialog = AlertDialog.Root;

interface TriggerProps extends AlertDialog.DialogTriggerProps {}
const Trigger = forwardRef(
(
{ children, ...props }: TriggerProps,
ref: Ref<HTMLButtonElement> | undefined
) => {
return (
<AlertDialog.Trigger {...props} asChild ref={ref}>
{children}
</AlertDialog.Trigger>
);
}
);

type ContentProps = {
/** The content to display inside modal */
children: React.ReactNode;
/** Inner content of the footer */
footer?: React.ReactNode;
/** The content for the title of the modal */
title: string | React.ReactNode;
/**
* Hide the title in the modal
* @default false
*/
titleHidden?: boolean;
/** id for the dialog */
id?: string;
/** Disable animations and open modal instantly */
instant?: boolean;
/** Increases the modal width */
large?: boolean;
/** Decreases the modal width */
small?: boolean;
/** Limits modal height on large sceens with scrolling */
limitHeight?: boolean;
/** Sets modal to the height of the viewport on small screens */
fullScreen?: boolean;
} & AlertDialog.DialogContentProps &
FooterProps;

const Content = forwardRef((props: ContentProps, ref: any) => {
const {
children,
title,
titleHidden = false,
id,
instant,
large,
small,
limitHeight,
fullScreen,
footer,
primaryAction,
secondaryActions,
...others
} = props;
const rId = React.useId();
const finalId = props.id || rId;

const classname = cx(
styles.Dialog,
small && styles.sizeSmall,
large && styles.sizeLarge,
limitHeight && styles.limitHeight,
fullScreen && styles.fullScreen
);

return (
<div className={`opub-Dialog`}>
<AlertDialog.Portal>
<AlertDialog.Overlay className={styles.Overlay} />
<AlertDialog.Content ref={ref} className={classname} {...others}>
<div className="sr-only">
<AlertDialog.Title>{title}</AlertDialog.Title>
</div>
<Header id={finalId} titleHidden={titleHidden} children={title} />
<div className={styles.Content}>{children}</div>
<Footer
children={footer}
primaryAction={primaryAction}
secondaryActions={secondaryActions}
/>
</AlertDialog.Content>
</AlertDialog.Portal>
</div>
);
});

export { Dialog, Trigger, Content };
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { AlertDialogCancel } from '@radix-ui/react-alert-dialog';
import { CloseButton } from '@ui/components/Dialog/components';
import { Flex } from '@ui/components/Flex';
import React from 'react';
import { Box } from '../../../Box';
import { Text } from '../../../Text';

export interface HeaderProps {
id: string;
titleHidden: boolean;
children?: React.ReactNode;
onClose?(): void;
}

export function Header({ id, children, titleHidden, onClose }: HeaderProps) {
const titleHiddenMarkup = (
<Box position="absolute" insetInlineEnd="0" zIndex="1">
<Flex gap="var(--space-4)" justifyContent="end" alignItems="center">
<CloseButton titleHidden={titleHidden} onClick={onClose} />
</Flex>
</Box>
);
if (titleHidden || !children) {
return titleHiddenMarkup;
}

return (
<Box
paddingBlockStart="4"
paddingBlockEnd="4"
paddingInlineStart="5"
paddingInlineEnd="5"
borderBlockEnd="divider"
>
<Flex
gap="var(--space-4)"
alignItems="center"
justifyContent="space-between"
>
<Text id={id} as="h2" variant="headingLg" breakWord>
{children}
</Text>
<AlertDialogCancel asChild>
<CloseButton titleHidden={titleHidden} onClick={onClose} />
</AlertDialogCancel>
</Flex>
</Box>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Header } from './Header/Header';
1 change: 1 addition & 0 deletions packages/opub-ui/src/components/AlertDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AlertDialog } from "./AlertDialog";
7 changes: 1 addition & 6 deletions packages/opub-ui/src/components/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,7 @@ const Content = forwardRef((props: ContentProps, ref: any) => {
<div className={`opub-Dialog`}>
<DialogRadix.Portal>
<DialogRadix.Overlay className={styles.Overlay} />
<DialogRadix.Content
ref={ref}
className={classname}
{...others}
// asChild
>
<DialogRadix.Content ref={ref} className={classname} {...others}>
<div className="sr-only">
<DialogRadix.Title>{title}</DialogRadix.Title>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/opub-ui/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ export { Thumbnail } from './Thumbnail';
export { Tooltip } from './Tooltip';
export { Dialog } from "./Dialog";
export { Icon } from "./Icon";
export { AlertDialog } from "./AlertDialog";

0 comments on commit 2faae5d

Please # to comment.