From 638d38298f65a33ebaa429b1cc81d5966efc5def Mon Sep 17 00:00:00 2001
From: Dennis Torres <dtorres@spear.ai>
Date: Tue, 3 Sep 2024 16:35:45 -0400
Subject: [PATCH] Rework Dialog component(s) to scroll with long content (#358)

---
 .changeset/tender-deers-hear.md               |  6 +++
 .../src/components/dialog/index.stories.tsx   | 40 +++++++++++++++++--
 packages/ui/src/components/dialog.tsx         |  9 +++--
 3 files changed, 49 insertions(+), 6 deletions(-)
 create mode 100644 .changeset/tender-deers-hear.md

diff --git a/.changeset/tender-deers-hear.md b/.changeset/tender-deers-hear.md
new file mode 100644
index 00000000..61857118
--- /dev/null
+++ b/.changeset/tender-deers-hear.md
@@ -0,0 +1,6 @@
+---
+"@spear-ai/storybook": major
+"@spear-ai/ui": major
+---
+
+Reworked Dialog component(s) to scroll with long content.
diff --git a/packages/storybook/src/components/dialog/index.stories.tsx b/packages/storybook/src/components/dialog/index.stories.tsx
index 2154e349..d19d59cd 100644
--- a/packages/storybook/src/components/dialog/index.stories.tsx
+++ b/packages/storybook/src/components/dialog/index.stories.tsx
@@ -16,11 +16,12 @@ import { useStorybook } from "@/components/storybook-provider/storybook-provider
 
 const PreviewDialog = (properties: {
   hasCloseButton: boolean;
+  hasLongContent: boolean;
   hasTitle: boolean;
   isAlert: boolean;
   isDismissable: boolean;
 }) => {
-  const { hasCloseButton, hasTitle, isAlert, isDismissable } = properties;
+  const { hasCloseButton, hasLongContent, hasTitle, isAlert, isDismissable } = properties;
   const intl = useIntl();
   const { portalContainer } = useStorybook();
 
@@ -36,7 +37,7 @@ const PreviewDialog = (properties: {
         {...(portalContainer === undefined ? {} : { UNSTABLE_portalContainer: portalContainer })}
         isDismissable={isDismissable}
       >
-        <DialogModal className="w-full sm:max-w-sm">
+        <DialogModal className="w-full sm:max-w-md">
           <Dialog className="px-4 pb-4 pt-5 sm:p-6" role={isAlert ? "alertdialog" : "dialog"}>
             {hasCloseButton ? (
               <DialogCloseIconButton>
@@ -51,7 +52,7 @@ const PreviewDialog = (properties: {
                 })}
               </DialogTitle>
             ) : null}
-            <div className="mt-2">
+            <div className="prose mt-2">
               <p className="text-sm text-neutral-11 rtl:text-right">
                 {intl.formatMessage({
                   defaultMessage:
@@ -59,6 +60,38 @@ const PreviewDialog = (properties: {
                   id: "Osc/oA",
                 })}
               </p>
+              {hasLongContent ? (
+                <>
+                  <p className="text-sm text-neutral-11 rtl:text-right">
+                    {intl.formatMessage({
+                      defaultMessage:
+                        "Nullam dui sem, tempor in iaculis id, porttitor ut magna. Nam non ipsum sed enim commodo ullamcorper id ut magna. Ut scelerisque justo nunc, id placerat lectus elementum id. Vestibulum suscipit justo in felis fringilla imperdiet. Vivamus ornare placerat dignissim. Aliquam porttitor odio pellentesque dui luctus, sed bibendum libero scelerisque. Quisque libero quam, cursus nec urna sit amet, rhoncus mattis ipsum. In vel vehicula nisl, eget faucibus magna. Nunc sagittis nulla turpis, at vehicula dolor lacinia eget. Vivamus sed elit sollicitudin, tincidunt ex ultrices, consequat neque. Morbi congue porttitor lorem id fermentum. Aliquam rhoncus, nisi sed semper mollis, eros orci consectetur magna, ut mattis risus purus in ipsum. Quisque vel risus molestie, tristique purus ac, gravida mi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas pellentesque felis laoreet sapien aliquam, ut tempus orci porttitor.",
+                      id: "lAX58e",
+                    })}
+                  </p>
+                  <p className="text-sm text-neutral-11 rtl:text-right">
+                    {intl.formatMessage({
+                      defaultMessage:
+                        "Integer sit amet est lobortis turpis tempor vestibulum. Pellentesque malesuada, libero eu fermentum fermentum, metus odio luctus felis, eu eleifend elit mi quis tellus. Donec facilisis ipsum at luctus pulvinar. Suspendisse a sapien non odio aliquet rhoncus sed sed nunc. Nam consequat, eros at tempus accumsan, orci sapien dignissim massa, vel mattis lectus augue non turpis. Aenean orci urna, condimentum eget suscipit id, fermentum vel ante. Integer et lobortis justo, id consequat mauris. Nam pellentesque dui ullamcorper ante rhoncus semper. Donec ac feugiat urna, ut tincidunt turpis. Vestibulum libero eros, tristique et metus nec, tincidunt vestibulum tellus.",
+                      id: "O5j1An",
+                    })}
+                  </p>
+                  <p className="text-sm text-neutral-11 rtl:text-right">
+                    {intl.formatMessage({
+                      defaultMessage:
+                        "Aliquam ultrices dolor arcu, id tristique mi sodales id. Vivamus finibus hendrerit metus, sed bibendum ligula mattis sed. Sed a dui et quam hendrerit finibus vitae eget quam. Donec massa felis, vehicula sit amet pulvinar quis, ornare mattis est. Nam id felis a odio consectetur maximus. Nunc molestie sed ligula at tincidunt. Donec pellentesque tellus non purus fringilla, quis eleifend elit pulvinar.",
+                      id: "K/rLJ4",
+                    })}
+                  </p>
+                  <p className="text-sm text-neutral-11 rtl:text-right">
+                    {intl.formatMessage({
+                      defaultMessage:
+                        "Nam eget interdum magna, at iaculis diam. Mauris pulvinar, elit eget interdum egestas, est orci ultricies lectus, et aliquet tellus ex sit amet purus. Donec in varius nunc. Phasellus in odio magna. Aenean auctor pulvinar nisl, nec aliquam ipsum elementum vitae. Proin vitae mi lacinia velit euismod congue. Sed condimentum purus eu blandit suscipit. Donec eget neque neque. Pellentesque libero tortor, lacinia quis urna quis, mattis semper risus. Pellentesque eget ante neque.",
+                      id: "ifSXtN",
+                    })}
+                  </p>
+                </>
+              ) : null}
             </div>
             <div className="mt-5 sm:mt-6">
               <DialogCloseButtonPrimitive className="inline-flex w-full cursor-default justify-center rounded-md bg-primary-9 px-3 py-2 text-sm font-semibold text-primary-contrast shadow-sm hover:bg-primary-10">
@@ -84,6 +117,7 @@ type Story = StoryObj<typeof meta>;
 export const Standard: Story = {
   args: {
     hasCloseButton: true,
+    hasLongContent: false,
     hasTitle: true,
     isAlert: false,
     isDismissable: true,
diff --git a/packages/ui/src/components/dialog.tsx b/packages/ui/src/components/dialog.tsx
index 8e67d8c0..0fcd8d7b 100644
--- a/packages/ui/src/components/dialog.tsx
+++ b/packages/ui/src/components/dialog.tsx
@@ -17,7 +17,7 @@ export const DialogModalOverlay = forwardRef<
   ComponentPropsWithoutRef<typeof ModalOverlayPrimitive> & { className?: string | undefined }
 >(({ className, ...properties }, reference) => {
   const mergedClassName = cx(
-    "exiting:animate-out exiting:fade-out exiting:duration-200 exiting:ease-in entering:animate-in entering:fade-in entering:duration-300 entering:ease-out bg-black-a-6 dark:bg-black-a-8 fixed inset-0 z-10 flex min-h-full items-end justify-center overflow-y-auto p-4 text-center backdrop-blur sm:items-center sm:p-0",
+    "before:exiting:animate-out before:exiting:fade-out before:exiting:duration-200 before:exiting:ease-in before:entering:animate-in before:entering:fade-in before:entering:duration-200 before:entering:ease-out before:bg-black-a-6 before:dark:bg-black-a-8 fixed inset-0 grid min-h-full w-screen grid-rows-[1fr_auto] justify-items-center overflow-y-auto p-4 pt-6 before:pointer-events-none before:fixed before:inset-0 before:backdrop-blur before:content-[''] sm:grid-rows-[1fr_auto_3fr]",
     className,
   );
   return <ModalOverlayPrimitive className={mergedClassName} {...properties} ref={reference} />;
@@ -30,7 +30,7 @@ export const DialogModal = forwardRef<
   ComponentPropsWithoutRef<typeof ModalPrimitive> & { className?: string | undefined }
 >(({ className, ...properties }, reference) => {
   const mergedClassName = cx(
-    "exiting:animate-out exiting:slide-out-from-top-4 exiting:sm:slide-out-from-top-0 exiting:sm:zoom-out-95 exiting:ease-in exiting:duration-200 entering:animate-in entering:sm:zoom-in-95 entering:slide-in-from-bottom-4 entering:sm:slide-in-from-bottom-0 entering:ease-out entering:duration-300 dark:bg-neutral-2 outline-neutral-6 overflow-hidden rounded-2xl bg-white text-left align-middle shadow-xl outline-1 -outline-offset-1 dark:outline",
+    "entering:fade-in exiting:fade-out exiting:animate-out exiting:slide-out-from-top-4 exiting:sm:slide-out-from-top-0 exiting:sm:zoom-out-95 exiting:ease-in exiting:duration-100 entering:animate-in entering:sm:zoom-in-95 entering:slide-in-from-bottom-4 entering:sm:slide-in-from-bottom-0 entering:ease-out entering:duration-200 row-start-2",
     className,
   );
   return <ModalPrimitive className={mergedClassName} {...properties} ref={reference} />;
@@ -42,7 +42,10 @@ export const Dialog = forwardRef<
   ElementRef<typeof DialogPrimitive>,
   ComponentPropsWithoutRef<typeof DialogPrimitive> & { className?: string | undefined }
 >(({ className, ...properties }, reference) => {
-  const mergedClassName = cx("relative outline-none", className);
+  const mergedClassName = cx(
+    "dark:bg-neutral-2 outline-neutral-6 relative w-full min-w-0 rounded-2xl bg-white shadow-lg outline-none outline-1 -outline-offset-1 transition duration-100 will-change-transform sm:mb-auto sm:max-w-xl dark:outline",
+    className,
+  );
   return <DialogPrimitive className={mergedClassName} {...properties} ref={reference} />;
 });