diff --git a/.changeset/little-beans-laugh.md b/.changeset/little-beans-laugh.md
new file mode 100644
index 0000000000..775fe54ee4
--- /dev/null
+++ b/.changeset/little-beans-laugh.md
@@ -0,0 +1,6 @@
+---
+'@twilio-paste/alert-dialog': minor
+'@twilio-paste/core': minor
+---
+
+[Alert Dialog] Add prop `onConfirmDisabled` to allow for the confirm button on destructive Alert Dialogs to be conditionally disabled. This interaction is primarily for use in the High Severity Delete Pattern.
diff --git a/packages/paste-core/components/alert-dialog/__tests__/index.spec.tsx b/packages/paste-core/components/alert-dialog/__tests__/index.spec.tsx
index 20574e449d..4da7f1a06d 100644
--- a/packages/paste-core/components/alert-dialog/__tests__/index.spec.tsx
+++ b/packages/paste-core/components/alert-dialog/__tests__/index.spec.tsx
@@ -3,7 +3,11 @@ import {render, screen} from '@testing-library/react';
import type {RenderOptions} from '@testing-library/react';
import {Theme} from '@twilio-paste/theme';
-import {AlertDialogWithTwoActions, DestructiveAlertDialog} from '../stories/index.stories';
+import {
+ AlertDialogWithTwoActions,
+ DestructiveAlertDialog,
+ DisabledButtonDestructiveAlertDialog,
+} from '../stories/index.stories';
const ThemeWrapper: RenderOptions['wrapper'] = ({children}) => (
{children}
@@ -29,6 +33,12 @@ describe('Alert Dialog', () => {
expect(button).toHaveStyleRule('background-color', 'rgb(214, 31, 31)');
});
+ it('Should have a disabled destructive button style when the onConfirmDisabled prop is included', () => {
+ render(, {wrapper: ThemeWrapper});
+ const button = screen.getByRole('button', {name: 'Delete'});
+ expect(button).toHaveStyleRule('background-color', 'rgb(225, 227, 234)');
+ });
+
it('Should have a heading the same as the heading prop', () => {
render();
expect(screen.getByRole('heading')).toHaveTextContent('Submit application');
@@ -48,6 +58,11 @@ describe('Alert Dialog', () => {
);
});
+ it('Should have correct attributes when button is disabled', () => {
+ render(, {wrapper: ThemeWrapper});
+ expect(screen.getByRole('button', {name: 'Delete'})).toHaveAttribute('disabled');
+ });
+
it('Should have the initial focus land on the first focusable item', () => {
render();
expect(document.activeElement).toEqual(screen.getAllByRole('button')[0]);
diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx
index 73fb2e3d5a..9112c5c6fc 100644
--- a/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx
+++ b/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx
@@ -12,11 +12,21 @@ export interface AlertDialogFooterProps extends HTMLPasteProps<'div'>, Pick void;
onDismissLabel: string;
+ onConfirmDisabled?: boolean;
}
export const AlertDialogFooter = React.forwardRef(
(
- {destructive, element = 'ALERT_DIALOG_FOOTER', onConfirm, onConfirmLabel, onDismiss, onDismissLabel, ...props},
+ {
+ destructive,
+ element = 'ALERT_DIALOG_FOOTER',
+ onConfirm,
+ onConfirmLabel,
+ onDismiss,
+ onDismissLabel,
+ onConfirmDisabled = false,
+ ...props
+ },
ref
) => {
const primaryVariant = destructive ? 'destructive' : 'primary';
@@ -38,7 +48,7 @@ export const AlertDialogFooter = React.forwardRef
{onDismissLabel}
-