163 lines
5.5 KiB
TypeScript
163 lines
5.5 KiB
TypeScript
"use client"
|
||
|
||
import {
|
||
Menu,
|
||
X,
|
||
Pencil,
|
||
Search,
|
||
Archive,
|
||
FolderInput,
|
||
Reply,
|
||
} from "lucide-react"
|
||
import { Button } from "@/components/ui/button"
|
||
import {
|
||
DropdownMenu,
|
||
DropdownMenuContent,
|
||
DropdownMenuTrigger,
|
||
} from "@/components/ui/dropdown-menu"
|
||
import { useComposeActions } from "@/lib/compose-context"
|
||
import { MoveToDropdownItems } from "@/components/gmail/move-to-menu-items"
|
||
import { MAIL_MENU_SURFACE_CLASS } from "@/lib/mail-chrome-classes"
|
||
import type { MailXsViewChrome } from "@/lib/mail-xs-view-chrome"
|
||
import { cn } from "@/lib/utils"
|
||
|
||
interface MobileBottomBarProps {
|
||
sidebarOpen: boolean
|
||
onToggleSidebar: () => void
|
||
/** Lecture message xs : barre d’actions à la place du menu / recherche. */
|
||
xsViewChrome?: MailXsViewChrome | null
|
||
onOpenSearch?: () => void
|
||
searchQuery?: string
|
||
onClearSearch?: () => void
|
||
}
|
||
|
||
const ROUNDED_BAR_BTN =
|
||
"size-11 shrink-0 rounded-full border border-gray-200 bg-white/80 text-[#444746] shadow-md backdrop-blur hover:bg-white"
|
||
|
||
export function MobileBottomBar({
|
||
sidebarOpen,
|
||
onToggleSidebar,
|
||
xsViewChrome = null,
|
||
onOpenSearch,
|
||
searchQuery,
|
||
onClearSearch,
|
||
}: MobileBottomBarProps) {
|
||
const { openCompose } = useComposeActions()
|
||
const inMailView = Boolean(xsViewChrome)
|
||
|
||
return (
|
||
<div className="fixed inset-x-0 bottom-0 z-50 flex flex-col items-center pb-[env(safe-area-inset-bottom)] sm:hidden">
|
||
<div className={cn(
|
||
"pointer-events-none absolute inset-0 bg-gradient-to-t to-transparent",
|
||
inMailView
|
||
? "dark:from-black/90 dark:via-black/50 from-mail-surface/90 via-mail-surface/50"
|
||
: "from-mail-surface/95 via-mail-surface/70 dark:from-background/95 dark:via-background/70"
|
||
)} />
|
||
|
||
<div className="relative z-10 flex w-full items-center gap-2 px-3 pb-3 pt-2">
|
||
{inMailView && xsViewChrome ? (
|
||
<div className="flex shrink-0 overflow-hidden rounded-full border border-gray-200 bg-white/80 shadow-md backdrop-blur">
|
||
<Button
|
||
type="button"
|
||
variant="ghost"
|
||
size="icon"
|
||
className="size-11 rounded-none text-[#444746] hover:bg-[#f1f3f4]"
|
||
onClick={xsViewChrome.onArchive}
|
||
aria-label="Archiver"
|
||
>
|
||
<Archive className="size-5" strokeWidth={1.5} />
|
||
</Button>
|
||
<span className="w-px shrink-0 self-stretch bg-gray-200" aria-hidden />
|
||
<DropdownMenu>
|
||
<DropdownMenuTrigger asChild>
|
||
<Button
|
||
type="button"
|
||
variant="ghost"
|
||
size="icon"
|
||
className="size-11 rounded-none text-[#444746] hover:bg-[#f1f3f4]"
|
||
aria-label="Déplacer dans un dossier"
|
||
>
|
||
<FolderInput className="size-5" strokeWidth={1.5} />
|
||
</Button>
|
||
</DropdownMenuTrigger>
|
||
<DropdownMenuContent
|
||
align="start"
|
||
side="top"
|
||
sideOffset={8}
|
||
className={cn(MAIL_MENU_SURFACE_CLASS, "max-h-80 overflow-y-auto")}
|
||
>
|
||
<MoveToDropdownItems
|
||
targets={xsViewChrome.moveTargets}
|
||
onMoveTo={xsViewChrome.onMoveTo}
|
||
/>
|
||
</DropdownMenuContent>
|
||
</DropdownMenu>
|
||
<span className="w-px shrink-0 self-stretch bg-gray-200" aria-hidden />
|
||
<Button
|
||
type="button"
|
||
variant="ghost"
|
||
size="icon"
|
||
className="size-11 rounded-none text-[#444746] hover:bg-[#f1f3f4]"
|
||
onClick={xsViewChrome.onReply}
|
||
aria-label="Répondre"
|
||
>
|
||
<Reply className="size-5" strokeWidth={1.5} />
|
||
</Button>
|
||
</div>
|
||
) : (
|
||
<>
|
||
<Button
|
||
variant="ghost"
|
||
size="icon"
|
||
className={ROUNDED_BAR_BTN}
|
||
onClick={onToggleSidebar}
|
||
aria-label={sidebarOpen ? "Fermer le menu" : "Ouvrir le menu"}
|
||
>
|
||
{sidebarOpen ? (
|
||
<X className="size-5" />
|
||
) : (
|
||
<Menu className="size-5" />
|
||
)}
|
||
</Button>
|
||
|
||
{!sidebarOpen && (
|
||
<button
|
||
type="button"
|
||
className="relative flex min-w-0 flex-1 items-center"
|
||
onClick={onOpenSearch}
|
||
>
|
||
<div className="pointer-events-none absolute left-3 z-10 flex items-center text-gray-500">
|
||
<Search className="size-5" />
|
||
</div>
|
||
<div
|
||
className="flex h-11 w-full items-center rounded-full border border-gray-200 bg-white/80 pl-10 pr-4 text-left text-sm shadow-md backdrop-blur"
|
||
>
|
||
<span className={searchQuery ? "truncate text-gray-900 dark:text-gray-100" : "text-gray-400"}>
|
||
{searchQuery || "Rechercher"}
|
||
</span>
|
||
</div>
|
||
</button>
|
||
)}
|
||
</>
|
||
)}
|
||
|
||
{!sidebarOpen && (
|
||
<Button
|
||
variant="ghost"
|
||
size="icon"
|
||
className={cn(ROUNDED_BAR_BTN, inMailView && "ml-auto")}
|
||
onClick={searchQuery ? onClearSearch : openCompose}
|
||
aria-label={searchQuery ? "Quitter la recherche" : "Nouveau message"}
|
||
>
|
||
{searchQuery ? (
|
||
<X className="size-5" />
|
||
) : (
|
||
<Pencil className="size-5" />
|
||
)}
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|