From 31c86012019dde4b9cdf22a2004b104598039941 Mon Sep 17 00:00:00 2001
From: Gildas Garcia <1122076+djhi@users.noreply.github.com>
Date: Thu, 21 May 2026 15:30:03 +0200
Subject: [PATCH] Chore/migrate modals 1 (#46216)
## Problem
We still use the deprecated `Modal` component in many places.
## Solution
Migrate to the new `Dialog` component.
Removed the design system page that was missing anyway:
https://supabase.com/design-system/docs/fragments/modal
This PR focuses on the design system and docs related components.
## How to test
- Docs videos:
- prod: https://supabase.com/docs/guides/auth
- staging:
https://docs-git-chore-migrate-modals-1-supabase.vercel.app/docs/guides/auth
- Feedback modal: not sure how to show it on staging but it should look
identical
- Privacy settings: not sure how to show it on staging but it should
look identical
- `PopupFrame`: this one is not used anywhere AFAIK. If confirmed I
could delete it.
## Summary by CodeRabbit
## Release Notes
* **Chores**
* Removed Modal component documentation entries and example patterns
from the design system.
* Migrated internal modal and dialog implementations to use the Dialog
component suite for standardized behavior and improved consistency
across the application.
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46216?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
---
apps/design-system/config/docs.ts | 5 -
.../default/example/modal-aligned-footer.tsx | 43 -----
.../default/example/modal-custom-footer.tsx | 51 ------
.../default/example/modal-hide-footer.tsx | 43 -----
.../default/example/modal-vertical-layout.tsx | 43 -----
apps/docs/components/Feedback/Feedback.tsx | 15 +-
.../components/Feedback/FeedbackModal.tsx | 147 ++++++++++--------
.../ui-patterns/src/ExpandableVideo/index.tsx | 91 ++++-------
packages/ui-patterns/src/PopupFrame/index.tsx | 65 ++------
.../ui-patterns/src/PrivacySettings/index.tsx | 139 ++++++++---------
10 files changed, 201 insertions(+), 441 deletions(-)
delete mode 100644 apps/design-system/registry/default/example/modal-aligned-footer.tsx
delete mode 100644 apps/design-system/registry/default/example/modal-custom-footer.tsx
delete mode 100644 apps/design-system/registry/default/example/modal-hide-footer.tsx
delete mode 100644 apps/design-system/registry/default/example/modal-vertical-layout.tsx
diff --git a/apps/design-system/config/docs.ts b/apps/design-system/config/docs.ts
index a43abe06a40..a74316e46d3 100644
--- a/apps/design-system/config/docs.ts
+++ b/apps/design-system/config/docs.ts
@@ -132,11 +132,6 @@ export const docsConfig: DocsConfig = {
href: '/docs/fragments/empty-state-presentational',
items: [],
},
- {
- title: 'Modal',
- href: '/docs/fragments/modal',
- items: [],
- },
{
title: 'Page Container',
href: '/docs/fragments/page-container',
diff --git a/apps/design-system/registry/default/example/modal-aligned-footer.tsx b/apps/design-system/registry/default/example/modal-aligned-footer.tsx
deleted file mode 100644
index cd8c6b239ca..00000000000
--- a/apps/design-system/registry/default/example/modal-aligned-footer.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Link2 } from 'lucide-react'
-import { useState } from 'react'
-import { Button, Modal } from 'ui'
-
-export default function ModalVerticalAlignedFooter() {
- const [visible, setVisible] = useState(false)
-
- return (
- <>
-
- setVisible(!visible)}
- onConfirm={() => setVisible(!visible)}
- title="This is the title of the modal"
- description="And i am the description"
- alignFooter="right"
- size="medium"
- hideClose={false}
- header={
-
-
-
-
-
-
This is the title
- This is the title
-
-
- }
- >
-
-
- Modal content is inserted here, if you need to insert anything into the Modal you can do
- so via `children`.
-
-
-
- >
- )
-}
diff --git a/apps/design-system/registry/default/example/modal-custom-footer.tsx b/apps/design-system/registry/default/example/modal-custom-footer.tsx
deleted file mode 100644
index e9012c3d1b2..00000000000
--- a/apps/design-system/registry/default/example/modal-custom-footer.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Link2 } from 'lucide-react'
-import { useState } from 'react'
-import { Badge, Button, Modal } from 'ui'
-
-export default function ModalVerticalCustomFooter() {
- const [visible, setVisible] = useState(false)
-
- return (
- <>
-
- setVisible(!visible)}
- onConfirm={() => setVisible(!visible)}
- title="This is the title of the modal"
- description="And i am the description"
- size="medium"
- hideClose={false}
- header={
-
-
-
-
-
-
This is the title
- This is the title
-
-
- }
- customFooter={
-
-
- Proceed with caution
-
-
-
-
- }
- >
-
-
- Modal content is inserted here, if you need to insert anything into the Modal you can do
- so via `children`.
-
-
-
- >
- )
-}
diff --git a/apps/design-system/registry/default/example/modal-hide-footer.tsx b/apps/design-system/registry/default/example/modal-hide-footer.tsx
deleted file mode 100644
index ff14e8bf566..00000000000
--- a/apps/design-system/registry/default/example/modal-hide-footer.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Link2 } from 'lucide-react'
-import { useState } from 'react'
-import { Button, Modal } from 'ui'
-
-export default function ModalVerticalHideFooter() {
- const [visible, setVisible] = useState(false)
-
- return (
- <>
-
- setVisible(!visible)}
- onConfirm={() => setVisible(!visible)}
- title="This is the title of the modal"
- description="And i am the description"
- hideFooter={true}
- size="medium"
- hideClose={false}
- header={
-
-
-
-
-
-
This is the title
- This is the title
-
-
- }
- >
-
-
- Modal content is inserted here, if you need to insert anything into the Modal you can do
- so via `children`.
-
-
-
- >
- )
-}
diff --git a/apps/design-system/registry/default/example/modal-vertical-layout.tsx b/apps/design-system/registry/default/example/modal-vertical-layout.tsx
deleted file mode 100644
index e1578fb2660..00000000000
--- a/apps/design-system/registry/default/example/modal-vertical-layout.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Link2 } from 'lucide-react'
-import { useState } from 'react'
-import { Button, Modal } from 'ui'
-
-export default function ModalVerticalLayout() {
- const [visible, setVisible] = useState(false)
-
- return (
- <>
-
- setVisible(!visible)}
- onConfirm={() => setVisible(!visible)}
- title="This is the title of the modal"
- description="And i am the description"
- layout="vertical"
- size="medium"
- hideClose={false}
- header={
-
-
-
-
-
-
This is the title
- This is the title
-
-
- }
- >
-
-
- Modal content is inserted here, if you need to insert anything into the Modal you can do
- so via `children`.
-
-
-
- >
- )
-}
diff --git a/apps/docs/components/Feedback/Feedback.tsx b/apps/docs/components/Feedback/Feedback.tsx
index 74ed2947dbf..d62a9f0f475 100644
--- a/apps/docs/components/Feedback/Feedback.tsx
+++ b/apps/docs/components/Feedback/Feedback.tsx
@@ -1,25 +1,24 @@
'use client'
import { createClient } from '@supabase/supabase-js'
+import { IS_PLATFORM } from '~/lib/constants'
+import { useSendFeedbackMutation } from '~/lib/fetch/feedback'
+import { useSendTelemetryEvent } from '~/lib/telemetry'
+import { useConstant, useIsLoggedIn, type Database } from 'common'
import { Check, MessageSquareQuote, X } from 'lucide-react'
import { usePathname } from 'next/navigation'
import {
- type CSSProperties,
- type MouseEventHandler,
forwardRef,
useReducer,
useRef,
useState,
+ type CSSProperties,
+ type MouseEventHandler,
} from 'react'
-
-import { type Database, useConstant, useIsLoggedIn } from 'common'
import { Button, cn } from 'ui'
-import { IS_PLATFORM } from '~/lib/constants'
-import { useSendFeedbackMutation } from '~/lib/fetch/feedback'
-import { useSendTelemetryEvent } from '~/lib/telemetry'
import { getLinearTeam, getSanitizedTabParams } from './Feedback.utils'
-import { type FeedbackFields, FeedbackModal } from './FeedbackModal'
+import { FeedbackModal, type FeedbackFields } from './FeedbackModal'
const FeedbackButton = forwardRef<
HTMLButtonElement,
diff --git a/apps/docs/components/Feedback/FeedbackModal.tsx b/apps/docs/components/Feedback/FeedbackModal.tsx
index 8667fff80ff..8022817fb61 100644
--- a/apps/docs/components/Feedback/FeedbackModal.tsx
+++ b/apps/docs/components/Feedback/FeedbackModal.tsx
@@ -1,6 +1,20 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { SubmitHandler, useForm } from 'react-hook-form'
-import { Button, Form, FormControl, FormField, Input, Modal, Textarea } from 'ui'
+import {
+ Button,
+ Dialog,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogSection,
+ DialogSectionSeparator,
+ DialogTitle,
+ Form,
+ FormControl,
+ FormField,
+ Input,
+ Textarea,
+} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import * as z from 'zod'
@@ -24,6 +38,7 @@ function FeedbackModal({ visible, page, onCancel, onSubmit }: FeedbackModalProps
defaultValues: { page, title: '', comment: '' },
resolver: zodResolver(formSchema),
})
+ const formId = 'feedback-form'
const { reset } = form
const { isSubmitting } = form.formState
@@ -38,75 +53,69 @@ function FeedbackModal({ visible, page, onCancel, onSubmit }: FeedbackModalProps
}
return (
-
-