@purpurds/modal 5.1.1 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- ._purpur-modal-content_1qmv6_1{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;overflow:auto;background-color:var(--purpur-color-background-primary);animation:_fadeIn_1qmv6_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}._purpur-modal-content_1qmv6_1:focus{outline:0}@media (min-width: 600px){._purpur-modal-content_1qmv6_1{inset:unset;top:50%;left:50%;width:720px;max-width:calc(100% - var(--purpur-spacing-300) * 2);min-height:320px;max-height:80%;overflow:hidden;border-radius:var(--purpur-border-radius-lg);box-sizing:border-box;transform:translate(-50%,-50%);box-shadow:var(--purpur-shadow-lg)}}@media (min-width: 600px){._purpur-modal-content__overlay_1qmv6_30{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--purpur-color-overlay-default);animation:_fadeIn_1qmv6_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}}._purpur-modal-content_1qmv6_1 ._purpur-modal-content__close-button_1qmv6_37{position:absolute;top:var(--purpur-spacing-100);right:var(--purpur-spacing-100);z-index:2}@media (min-width: 600px){._purpur-modal-content_1qmv6_1 ._purpur-modal-content__close-button_1qmv6_37{top:var(--purpur-spacing-150)}}._purpur-modal-content__wrapper_1qmv6_48{height:100%;overflow:auto}@media (min-width: 600px){._purpur-modal-content__wrapper_1qmv6_48{display:flex;flex-direction:column;overflow:hidden}}._purpur-modal-content__wrapper-inner_1qmv6_59{display:flex;flex-direction:column}@media (min-width: 600px){._purpur-modal-content__wrapper-inner_1qmv6_59{overflow:hidden}}._purpur-modal-content__image-wrapper_1qmv6_68{position:relative;flex-shrink:0;order:-1;width:100%;aspect-ratio:2/1;overflow:hidden}@media (((min-width: 600px) and (max-width: 649px) and (max-height: 720px)) or ((min-width: 650px) and (max-height: 820px))){._purpur-modal-content__image-wrapper_1qmv6_68{aspect-ratio:3/1}}._purpur-modal-content__image-wrapper_1qmv6_68 img{position:absolute;top:50%;left:50%;display:block;width:100%;height:auto;transform:translate(-50%,-50%)}._purpur-modal-content__header_1qmv6_91{position:sticky;top:0;flex-grow:0;padding:var(--purpur-spacing-200) calc(var(--purpur-spacing-600) + var(--purpur-spacing-150)) 0 var(--purpur-spacing-200);background:var(--purpur-color-background-primary)}@media (min-width: 600px){._purpur-modal-content__header_1qmv6_91{position:static;padding:var(--purpur-spacing-250) calc(var(--purpur-spacing-800) + var(--purpur-spacing-50)) 0 var(--purpur-spacing-300)}}._purpur-modal-content__title_1qmv6_104,._purpur-modal-content__description_1qmv6_107{margin:0}._purpur-modal-content__body_1qmv6_110{padding:var(--purpur-spacing-200) var(--purpur-spacing-200) 0}@media (min-width: 600px){._purpur-modal-content__body_1qmv6_110{height:100%;overflow:auto;padding:var(--purpur-spacing-250) var(--purpur-spacing-300) 0}}._purpur-modal-content__body-inner_1qmv6_120{position:relative;display:flex;flex-direction:column;gap:var(--purpur-spacing-400);padding-bottom:var(--purpur-spacing-250)}@media (min-width: 600px){._purpur-modal-content__body-inner_1qmv6_120{padding-bottom:var(--purpur-spacing-300)}}._purpur-modal-content__actions-buttons_1qmv6_132{display:flex;flex-direction:column;gap:var(--purpur-spacing-200);margin-top:auto}@media (min-width: 600px){._purpur-modal-content__actions-buttons_1qmv6_132{flex-direction:row-reverse;flex-grow:0}}._purpur-modal-content__actions-button_1qmv6_132{width:100%}@media (min-width: 600px){._purpur-modal-content__actions-button_1qmv6_132{width:auto}._purpur-modal-content__actions-button_1qmv6_132:nth-child(3){margin-right:auto}}._purpur-modal-content--with-image_1qmv6_155:not(._purpur-modal-content--overflow_1qmv6_155) ._purpur-modal-content__header_1qmv6_91{padding-top:var(--purpur-spacing-250)}@media (min-width: 600px){._purpur-modal-content--overflow_1qmv6_155:not(._purpur-modal-content--with-image_1qmv6_155) ._purpur-modal-content__header_1qmv6_91{position:relative}._purpur-modal-content--overflow_1qmv6_155:not(._purpur-modal-content--with-image_1qmv6_155) ._purpur-modal-content__close-button_1qmv6_37{top:50%;transform:translateY(-50%)}}._purpur-modal-content--overflow_1qmv6_155 ._purpur-modal-content__header_1qmv6_91{padding-bottom:var(--purpur-spacing-200);border-bottom:1px solid var(--purpur-color-border-weak)}._purpur-modal-content--overflow_1qmv6_155 ._purpur-modal-content__body_1qmv6_110{padding-top:var(--purpur-spacing-300)}@media (min-width: 600px){._purpur-modal-content--overflow_1qmv6_155 ._purpur-modal-content__body_1qmv6_110{padding-top:var(--purpur-spacing-400)}}._purpur-modal-content--overflow_1qmv6_155 ._purpur-modal-content__actions_1qmv6_132{position:relative}._purpur-modal-content--overflow_1qmv6_155 ._purpur-modal-content__actions-buttons_1qmv6_132{position:relative;z-index:2}._purpur-modal-content--overflow_1qmv6_155 ._purpur-modal-content__actions-separator_1qmv6_186{position:absolute;bottom:calc(100% - 1px);left:0;z-index:1;width:calc(100% - var(--purpur-spacing-300));height:calc(var(--purpur-spacing-400) + var(--purpur-spacing-100));background:linear-gradient(180deg,rgba(255,255,255,0) 0%,var(--purpur-color-background-primary) 100%);pointer-events:none}._purpur-modal-content--overflow_1qmv6_155._purpur-modal-content--sticky-footer_1qmv6_196 ._purpur-modal-content__actions-buttons_1qmv6_132{border-top:1px solid var(--purpur-color-border-weak)}._purpur-modal-content--sticky-footer_1qmv6_196 ._purpur-modal-content__body-inner_1qmv6_120{padding-bottom:var(--purpur-spacing-300)}._purpur-modal-content--sticky-footer_1qmv6_196 ._purpur-modal-content__actions-buttons_1qmv6_132{padding:var(--purpur-spacing-200)}@media (min-width: 600px){._purpur-modal-content--sticky-footer_1qmv6_196 ._purpur-modal-content__actions-buttons_1qmv6_132{padding-left:var(--purpur-spacing-300);padding-right:var(--purpur-spacing-300)}}@keyframes _fadeIn_1qmv6_1{0%{opacity:0}to{opacity:1}}
1
+ ._purpur-notification_10qwf_1{display:flex;flex-direction:column;padding:var(--purpur-spacing-200) var(--purpur-spacing-200) var(--purpur-spacing-200) var(--purpur-spacing-250);box-sizing:border-box;width:100%;background:var(--purpur-color-background-primary);border-radius:var(--purpur-border-radius-md);border:var(--purpur-border-width-sm) solid;border-left:var(--purpur-border-width-lg) solid;gap:var(--purpur-spacing-150);position:relative}._purpur-notification__top_10qwf_14{display:flex;align-items:flex-start;align-self:stretch;justify-content:space-between}._purpur-notification__header_10qwf_20{display:flex;align-items:center;gap:var(--purpur-spacing-100)}._purpur-notification__close-button_10qwf_25{position:absolute;right:calc(var(--purpur-spacing-50) + var(--purpur-spacing-25));top:calc(var(--purpur-spacing-50) + var(--purpur-spacing-25))}._purpur-notification__icon_10qwf_30{flex-shrink:0}._purpur-notification__body_10qwf_33{padding:var(--purpur-spacing-0) var(--purpur-spacing-150) var(--purpur-spacing-50) var(--purpur-spacing-0)}._purpur-notification--success_10qwf_36{border-color:var(--purpur-color-border-status-success)}._purpur-notification--success_10qwf_36 ._purpur-notification__heading_10qwf_39{color:var(--purpur-color-text-status-success-strong)}._purpur-notification--success_10qwf_36 ._purpur-notification__icon_10qwf_30{color:var(--purpur-color-text-status-success-medium)}._purpur-notification--warning_10qwf_45{border-color:var(--purpur-color-border-status-warning)}._purpur-notification--warning_10qwf_45 ._purpur-notification__heading_10qwf_39{color:var(--purpur-color-text-status-warning-strong)}._purpur-notification--warning_10qwf_45 ._purpur-notification__icon_10qwf_30{color:var(--purpur-color-text-status-warning-medium)}._purpur-notification--error_10qwf_54{border-color:var(--purpur-color-border-status-error)}._purpur-notification--error_10qwf_54 ._purpur-notification__heading_10qwf_39{color:var(--purpur-color-text-status-error-strong)}._purpur-notification--error_10qwf_54 ._purpur-notification__icon_10qwf_30{color:var(--purpur-color-text-status-error-medium)}._purpur-notification--info_10qwf_63{border-color:var(--purpur-color-border-status-info)}._purpur-notification--info_10qwf_63 ._purpur-notification__heading_10qwf_39{color:var(--purpur-color-text-status-info-strong)}._purpur-notification--info_10qwf_63 ._purpur-notification__icon_10qwf_30{color:var(--purpur-color-text-status-info-medium)}._purpur-notification--hidden_10qwf_72{display:none;visibility:hidden}._purpur-notification--has-close-button_10qwf_76 ._purpur-notification__top_10qwf_14{padding-right:var(--purpur-spacing-400)}._purpur-modal-content_ofk9m_1{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;overflow:auto;background-color:var(--purpur-color-background-primary);animation:_fadeIn_ofk9m_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}._purpur-modal-content_ofk9m_1:focus{outline:0}@media (min-width: 600px){._purpur-modal-content_ofk9m_1{inset:unset;top:50%;left:50%;width:720px;max-width:calc(100% - var(--purpur-spacing-300) * 2);min-height:320px;max-height:80%;overflow:hidden;border-radius:var(--purpur-border-radius-lg);box-sizing:border-box;transform:translate(-50%,-50%);box-shadow:var(--purpur-shadow-lg)}}@media (min-width: 600px){._purpur-modal-content__overlay_ofk9m_30{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--purpur-color-overlay-default);animation:_fadeIn_ofk9m_1 var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}}._purpur-modal-content_ofk9m_1 ._purpur-modal-content__close-button_ofk9m_37{position:absolute;top:var(--purpur-spacing-100);right:var(--purpur-spacing-100);z-index:2}@media (min-width: 600px){._purpur-modal-content_ofk9m_1 ._purpur-modal-content__close-button_ofk9m_37{top:var(--purpur-spacing-150)}}._purpur-modal-content__wrapper_ofk9m_48{height:100%;overflow:auto}@media (min-width: 600px){._purpur-modal-content__wrapper_ofk9m_48{display:flex;flex-direction:column;overflow:hidden}}._purpur-modal-content__wrapper-inner_ofk9m_59{display:flex;flex-direction:column}@media (min-width: 600px){._purpur-modal-content__wrapper-inner_ofk9m_59{overflow:hidden}}._purpur-modal-content__image-wrapper_ofk9m_68{position:relative;flex-shrink:0;order:-1;width:100%;aspect-ratio:2/1;overflow:hidden}@media (((min-width: 600px) and (max-width: 649px) and (max-height: 720px)) or ((min-width: 650px) and (max-height: 820px))){._purpur-modal-content__image-wrapper_ofk9m_68{aspect-ratio:3/1}}._purpur-modal-content__image-wrapper_ofk9m_68 img{position:absolute;top:50%;left:50%;display:block;width:100%;height:auto;transform:translate(-50%,-50%)}._purpur-modal-content__header_ofk9m_91{position:sticky;top:0;flex-grow:0;padding:var(--purpur-spacing-200) calc(var(--purpur-spacing-600) + var(--purpur-spacing-150)) 0 var(--purpur-spacing-200);background:var(--purpur-color-background-primary)}@media (min-width: 600px){._purpur-modal-content__header_ofk9m_91{position:static;padding:var(--purpur-spacing-250) calc(var(--purpur-spacing-800) + var(--purpur-spacing-50)) 0 var(--purpur-spacing-300)}}._purpur-modal-content__title_ofk9m_104,._purpur-modal-content__description_ofk9m_107{margin:0}._purpur-modal-content__body_ofk9m_110{padding:var(--purpur-spacing-200) var(--purpur-spacing-200) 0}@media (min-width: 600px){._purpur-modal-content__body_ofk9m_110{height:100%;overflow:auto;padding:var(--purpur-spacing-250) var(--purpur-spacing-300) 0}}._purpur-modal-content__body-inner_ofk9m_120{position:relative;display:flex;flex-direction:column;gap:var(--purpur-spacing-400);padding-bottom:var(--purpur-spacing-250)}@media (min-width: 600px){._purpur-modal-content__body-inner_ofk9m_120{padding-bottom:var(--purpur-spacing-300)}}._purpur-modal-content__actions-buttons_ofk9m_132{display:flex;flex-direction:column;gap:var(--purpur-spacing-200);margin-top:auto}@media (min-width: 600px){._purpur-modal-content__actions-buttons_ofk9m_132{flex-direction:row-reverse;flex-grow:0}}._purpur-modal-content__actions-button_ofk9m_132{width:100%}@media (min-width: 600px){._purpur-modal-content__actions-button_ofk9m_132{width:auto}._purpur-modal-content__actions-button_ofk9m_132:nth-child(3){margin-right:auto}}._purpur-modal-content__notification_ofk9m_155{padding-top:var(--purpur-spacing-300)}._purpur-modal-content--with-image_ofk9m_158:not(._purpur-modal-content--overflow_ofk9m_158) ._purpur-modal-content__header_ofk9m_91{padding-top:var(--purpur-spacing-250)}@media (min-width: 600px){._purpur-modal-content--overflow_ofk9m_158:not(._purpur-modal-content--with-image_ofk9m_158) ._purpur-modal-content__header_ofk9m_91{position:relative}._purpur-modal-content--overflow_ofk9m_158:not(._purpur-modal-content--with-image_ofk9m_158) ._purpur-modal-content__close-button_ofk9m_37{top:50%;transform:translateY(-50%)}}._purpur-modal-content--overflow_ofk9m_158 ._purpur-modal-content__header_ofk9m_91{padding-bottom:var(--purpur-spacing-200);border-bottom:1px solid var(--purpur-color-border-weak)}._purpur-modal-content--overflow_ofk9m_158 ._purpur-modal-content__body_ofk9m_110{padding-top:var(--purpur-spacing-300)}@media (min-width: 600px){._purpur-modal-content--overflow_ofk9m_158 ._purpur-modal-content__body_ofk9m_110{padding-top:var(--purpur-spacing-400)}}._purpur-modal-content--overflow_ofk9m_158 ._purpur-modal-content__actions_ofk9m_132{position:relative}._purpur-modal-content--overflow_ofk9m_158 ._purpur-modal-content__actions-buttons_ofk9m_132{position:relative;z-index:2}._purpur-modal-content--overflow_ofk9m_158 ._purpur-modal-content__actions-separator_ofk9m_189{position:absolute;bottom:calc(100% - 1px);left:0;z-index:1;width:calc(100% - var(--purpur-spacing-300));height:calc(var(--purpur-spacing-400) + var(--purpur-spacing-100));background:linear-gradient(180deg,rgba(255,255,255,0) 0%,var(--purpur-color-background-primary) 100%);pointer-events:none}._purpur-modal-content--overflow_ofk9m_158._purpur-modal-content--sticky-footer_ofk9m_199 ._purpur-modal-content__actions-buttons_ofk9m_132{border-top:1px solid var(--purpur-color-border-weak)}._purpur-modal-content--sticky-footer_ofk9m_199 ._purpur-modal-content__body-inner_ofk9m_120{padding-bottom:var(--purpur-spacing-300)}._purpur-modal-content--sticky-footer_ofk9m_199 ._purpur-modal-content__actions-buttons_ofk9m_132{padding:var(--purpur-spacing-200)}@media (min-width: 600px){._purpur-modal-content--sticky-footer_ofk9m_199 ._purpur-modal-content__actions-buttons_ofk9m_132{padding-left:var(--purpur-spacing-300);padding-right:var(--purpur-spacing-300)}}._purpur-modal-content--sticky-footer_ofk9m_199 ._purpur-modal-content__notification_ofk9m_155{padding:var(--purpur-spacing-100) var(--purpur-spacing-300) var(--purpur-spacing-200)}@keyframes _fadeIn_ofk9m_1{0%{opacity:0}to{opacity:1}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purpurds/modal",
3
- "version": "5.1.1",
3
+ "version": "5.2.0",
4
4
  "license": "AGPL-3.0-only",
5
5
  "main": "./dist/modal.cjs.js",
6
6
  "types": "./dist/modal.d.ts",
@@ -16,13 +16,14 @@
16
16
  "dependencies": {
17
17
  "@radix-ui/react-dialog": "~1.0.5",
18
18
  "classnames": "~2.5.0",
19
- "@purpurds/button": "5.1.1",
20
- "@purpurds/heading": "5.1.1",
21
- "@purpurds/paragraph": "5.1.1",
22
- "@purpurds/visually-hidden": "5.1.1",
23
- "@purpurds/text-spacing": "5.1.1",
24
- "@purpurds/tokens": "5.1.1",
25
- "@purpurds/icon": "5.1.1"
19
+ "@purpurds/button": "5.2.0",
20
+ "@purpurds/paragraph": "5.2.0",
21
+ "@purpurds/icon": "5.2.0",
22
+ "@purpurds/tokens": "5.2.0",
23
+ "@purpurds/heading": "5.2.0",
24
+ "@purpurds/text-spacing": "5.2.0",
25
+ "@purpurds/visually-hidden": "5.2.0",
26
+ "@purpurds/notification": "5.2.0"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@rushstack/eslint-patch": "~1.10.0",
@@ -163,6 +163,10 @@ $fadeIn: fadeIn var(--purpur-motion-duration-200) var(--purpur-motion-easing-eas
163
163
  }
164
164
  }
165
165
 
166
+ &__notification {
167
+ padding-top: var(--purpur-spacing-300);
168
+ }
169
+
166
170
  &--with-image:not(#{$root}--overflow) #{$root}__header {
167
171
  padding-top: var(--purpur-spacing-250);
168
172
  }
@@ -234,6 +238,10 @@ $fadeIn: fadeIn var(--purpur-motion-duration-200) var(--purpur-motion-easing-eas
234
238
  padding-right: var(--purpur-spacing-300);
235
239
  }
236
240
  }
241
+
242
+ #{$root}__notification {
243
+ padding: var(--purpur-spacing-100) var(--purpur-spacing-300) var(--purpur-spacing-200);
244
+ }
237
245
  }
238
246
  }
239
247
 
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { Notification } from "@purpurds/notification";
2
3
  import { Paragraph } from "@purpurds/paragraph";
3
4
  import { TextSpacing } from "@purpurds/text-spacing";
4
5
  import * as RadixDialog from "@radix-ui/react-dialog";
@@ -117,3 +118,45 @@ export const ModalContentWithImage: Story = {
117
118
  );
118
119
  },
119
120
  };
121
+
122
+ export const ModalContentWithNotification: Story = {
123
+ args: {
124
+ ...defaultArgs,
125
+ notification: (
126
+ <Notification status="error" heading="Notification heading">
127
+ Notification text
128
+ </Notification>
129
+ ),
130
+ },
131
+ parameters: {
132
+ design: [
133
+ {
134
+ name: "Modal",
135
+ type: "figma",
136
+ url: "https://www.figma.com/file/TggtRkYyKpwgKTU0LxuYFN/Modal-redesign?type=design&node-id=104-731&mode=design&t=sm44NPLlG3tjpFQb-0",
137
+ },
138
+ ],
139
+ },
140
+ argTypes,
141
+ render: (args) => {
142
+ return (
143
+ <RadixDialog.Root open>
144
+ <ModalContentCmp {...args}>
145
+ <TextSpacing>
146
+ <Paragraph variant="paragraph-100">
147
+ Lorem ipsum dolor sit amet consectetur. Diam vitae leo amet tortor ut faucibus diam
148
+ faucibus eu. Pellentesque quis pellentesque sit fermentum. Mi id aenean aliquam nibh
149
+ placerat.Lorem ipsum dolor sit amet consectetur. Diam vitae leo amet tortor ut
150
+ faucibus diam faucibus eu.
151
+ </Paragraph>
152
+ <Paragraph variant="paragraph-100">
153
+ Pellentesque quis pellentesque sit fermentum. Mi id aenean aliquam nibh placerat.Lorem
154
+ ipsum dolor sit amet consectetur. Diam vitae leo amet tortor ut faucibus diam faucibus
155
+ eu. Pellentesque quis pellentesque sit fermentum. Mi id aenean aliquam nibh placerat.
156
+ </Paragraph>
157
+ </TextSpacing>
158
+ </ModalContentCmp>
159
+ </RadixDialog.Root>
160
+ );
161
+ },
162
+ };
@@ -1,10 +1,11 @@
1
1
  import React from "react";
2
+ import { Notification } from "@purpurds/notification";
2
3
  import * as matchers from "@testing-library/jest-dom/matchers";
3
4
  import { cleanup, fireEvent, render, screen } from "@testing-library/react";
4
5
  import { afterEach, describe, expect, it, vi } from "vitest";
5
6
 
6
7
  import { Modal } from "./modal";
7
- import { ModalActions, MAX_NUMBER_OF_ACTIONS } from "./modal-content";
8
+ import { MAX_NUMBER_OF_ACTIONS, ModalActions } from "./modal-content";
8
9
 
9
10
  expect.extend(matchers);
10
11
 
@@ -138,4 +139,17 @@ describe("ModalActions", () => {
138
139
  expect(testActions[1].onClick).toHaveBeenCalledTimes(1);
139
140
  expect(testActions[2].onClick).toHaveBeenCalledTimes(1);
140
141
  });
142
+
143
+ it("should render an error notification given the notification prop", async () => {
144
+ const notification = (
145
+ <Notification data-testid="notification" heading="title">
146
+ text
147
+ </Notification>
148
+ );
149
+
150
+ render(<ModalActions actions={testActions} notification={notification} />);
151
+
152
+ const notificationElement = await screen.findByTestId("notification");
153
+ expect(notificationElement).toBeInTheDocument();
154
+ });
141
155
  });
@@ -1,12 +1,5 @@
1
- import React, {
2
- ForwardedRef,
3
- forwardRef,
4
- ReactNode,
5
- useCallback,
6
- useEffect,
7
- useRef,
8
- useState,
9
- } from "react";
1
+ import type { ForwardedRef, ReactNode } from "react";
2
+ import React, { forwardRef, useCallback, useEffect, useRef, useState } from "react";
10
3
  import { Button, ButtonVariant } from "@purpurds/button";
11
4
  import { Heading } from "@purpurds/heading";
12
5
  import { IconClose } from "@purpurds/icon";
@@ -16,8 +9,8 @@ import { VisuallyHidden } from "@purpurds/visually-hidden";
16
9
  import * as RadixDialog from "@radix-ui/react-dialog";
17
10
  import c from "classnames/bind";
18
11
 
12
+ import "@purpurds/notification/styles";
19
13
  import styles from "./modal-content.module.scss";
20
-
21
14
  export const primaryActionVariants = ["primary", "expressive", "destructive"] as const;
22
15
 
23
16
  export type PrimaryActionVariant = (typeof primaryActionVariants)[number];
@@ -46,6 +39,10 @@ export type DefaultProps = {
46
39
  * An optional image to be displayed at the top of the modal.
47
40
  * */
48
41
  image?: ReactNode;
42
+ /**
43
+ * Provide a Purpur Notification which will render beneath the modal buttons, otherwise leave it undefined.
44
+ * */
45
+ notification?: ReactNode;
49
46
  /**
50
47
  * The variant for the primary action button.
51
48
  * */
@@ -105,6 +102,7 @@ export const ModalContent = forwardRef(
105
102
  primaryActionVariant = "primary",
106
103
  stickyButtons = true,
107
104
  title,
105
+ notification = undefined,
108
106
  ...props
109
107
  }: ModalContentProps,
110
108
  ref: ForwardedRef<HTMLDivElement>
@@ -170,6 +168,10 @@ export const ModalContent = forwardRef(
170
168
  };
171
169
  }, [handleContentOverflow]);
172
170
 
171
+ useEffect(() => {
172
+ handleContentOverflow();
173
+ }, [notification, handleContentOverflow]);
174
+
173
175
  return (
174
176
  <RadixDialog.Portal>
175
177
  <RadixDialog.Overlay className={cx(`${rootClassName}__overlay`)} />
@@ -237,14 +239,23 @@ export const ModalContent = forwardRef(
237
239
  )}
238
240
  <div>{children}</div>
239
241
  {!stickyButtons && (
240
- <ModalActions actions={actions} primaryActionVariant={primaryActionVariant} />
242
+ <ModalActions
243
+ actions={actions}
244
+ primaryActionVariant={primaryActionVariant}
245
+ notification={notification}
246
+ />
241
247
  )}
242
248
  </div>
243
249
  </div>
244
250
  </div>
245
251
  </div>
252
+
246
253
  {stickyButtons && (
247
- <ModalActions actions={actions} primaryActionVariant={primaryActionVariant} />
254
+ <ModalActions
255
+ actions={actions}
256
+ primaryActionVariant={primaryActionVariant}
257
+ notification={notification}
258
+ />
248
259
  )}
249
260
  </RadixDialog.Content>
250
261
  </RadixDialog.Portal>
@@ -263,7 +274,8 @@ const CloseButton = ({
263
274
  }) => (
264
275
  <RadixDialog.Close asChild>
265
276
  <Button
266
- variant={hasImage ? "primary-negative" : "tertiary-purple"}
277
+ variant={hasImage ? "primary" : "tertiary-purple"}
278
+ negative={hasImage}
267
279
  size="sm"
268
280
  iconOnly
269
281
  aria-label={allyLabel}
@@ -280,9 +292,17 @@ export const MAX_NUMBER_OF_ACTIONS = 3;
280
292
  export const ModalActions = ({
281
293
  actions,
282
294
  primaryActionVariant,
283
- }: Pick<ModalContentProps, "actions" | "primaryActionVariant">) => {
295
+ notification,
296
+ }: Pick<ModalContentProps, "actions" | "primaryActionVariant" | "notification">) => {
297
+ const notificationRef = useRef<HTMLDivElement>(null);
284
298
  const buttonVariants = [primaryActionVariant, "secondary", "text"];
285
299
 
300
+ useEffect(() => {
301
+ if (notification) {
302
+ notificationRef?.current?.scrollIntoView?.(false);
303
+ }
304
+ }, [notification]);
305
+
286
306
  return actions && actions.length > 0 ? (
287
307
  <div className={cx(`${rootClassName}__actions`)}>
288
308
  <div className={cx(`${rootClassName}__actions-buttons`)} data-testid="modal actions">
@@ -298,6 +318,11 @@ export const ModalActions = ({
298
318
  </Button>
299
319
  ))}
300
320
  </div>
321
+ {notification && (
322
+ <div className={cx(`${rootClassName}__notification`)} ref={notificationRef}>
323
+ {notification}
324
+ </div>
325
+ )}
301
326
  <span className={cx(`${rootClassName}__actions-separator`)} />
302
327
  </div>
303
328
  ) : null;