diff --git a/app/mail/mail-app-shell.tsx b/app/mail/mail-app-shell.tsx
index 90abba5..1f5b952 100644
--- a/app/mail/mail-app-shell.tsx
+++ b/app/mail/mail-app-shell.tsx
@@ -4,12 +4,13 @@ import {
Suspense,
useCallback,
useEffect,
+ useLayoutEffect,
useMemo,
useState,
type CSSProperties,
} from "react"
-import dynamic from "next/dynamic"
-import { useIsXs } from "@/hooks/use-xs"
+import { readXsMatches, useIsXs } from "@/hooks/use-xs"
+import { MobileBottomBar } from "@/components/gmail/mobile-bottom-bar"
import { Toaster } from "sonner"
import { useRouter, usePathname } from "next/navigation"
import { Sidebar } from "@/components/gmail/sidebar"
@@ -24,14 +25,6 @@ import { ComposeModalManager } from "@/components/gmail/compose-modal"
import { SidebarNavProvider } from "@/lib/sidebar-nav-context"
import { mailNavVisitKey } from "@/lib/mail-folder-display"
import { useMailStore } from "@/lib/stores/mail-store"
-
-const MobileBottomBar = dynamic(
- () =>
- import("@/components/gmail/mobile-bottom-bar").then(
- (m) => m.MobileBottomBar
- ),
- { ssr: false }
-)
import {
parseMailSegments,
buildMailPath,
@@ -54,7 +47,12 @@ function MailAppInner() {
const isXs = useIsXs()
const pushRecentFolderVisit = useMailStore((s) => s.pushRecentFolderVisit)
- const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
+ /** Start closed so narrow viewports match SSR/CSS before JS runs; desktop opens in layout. */
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(true)
+
+ useLayoutEffect(() => {
+ if (!readXsMatches()) setSidebarCollapsed(false)
+ }, [])
useEffect(() => {
if (isXs) setSidebarCollapsed(true)
@@ -91,9 +89,9 @@ function MailAppInner() {
page: 1,
mailId: null,
})
- if (isXs) setSidebarCollapsed(true)
+ if (readXsMatches()) setSidebarCollapsed(true)
},
- [navigateRoute, isXs]
+ [navigateRoute]
)
return (
@@ -109,36 +107,33 @@ function MailAppInner() {
}
>
- {!isXs && (
+
setSidebarCollapsed(!sidebarCollapsed)}
/>
- )}
+
- {isXs && !sidebarCollapsed && (
+ {!sidebarCollapsed && (
- {isXs && (
-
setSidebarCollapsed((c) => !c)}
- />
- )}
+ setSidebarCollapsed((c) => !c)}
+ />
)
@@ -179,7 +172,7 @@ export function MailAppShell({
-
+
}
diff --git a/components/gmail/compose-modal.tsx b/components/gmail/compose-modal.tsx
index 92cba0a..f806d31 100644
--- a/components/gmail/compose-modal.tsx
+++ b/components/gmail/compose-modal.tsx
@@ -10,6 +10,8 @@ import {
lazy,
Suspense,
} from "react"
+import { useIsXs } from "@/hooks/use-xs"
+import { Sheet, SheetContent, SheetTitle } from "@/components/ui/sheet"
import { useEditor, EditorContent } from "@tiptap/react"
import { Editor, Node as TipTapNode, mergeAttributes, type Extensions } from "@tiptap/core"
import StarterKit from "@tiptap/starter-kit"
@@ -141,6 +143,9 @@ function insertSignatureHtml(html: string, sigId: string | null) {
return clean + ``
}
+/** Menus/popovers Radix default z-50 ; compose sheet content uses z-61+. */
+const COMPOSE_PORTAL_Z = "z-[100]"
+
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
function RecipientField({
@@ -408,7 +413,10 @@ function AlignmentDropdown({
-
+
editor.chain().focus().setTextAlign("left").run()}
className={cn(editor.isActive({ textAlign: "left" }) && "bg-[#e8eaed]")}
@@ -483,7 +491,10 @@ function FontDropdown({
-
+
{FONT_FAMILIES.map((f) => (
-
+
{FONT_SIZES.map((s) => (
- e.preventDefault()}>
+ e.preventDefault()}
+ >