ultisuite-client/components/gmail/compose/compose-emoji-picker.tsx
2026-05-20 18:22:36 +02:00

80 lines
2.0 KiB
TypeScript

"use client"
import {
useState,
useCallback,
lazy,
Suspense,
} from "react"
import { type Editor } from "@tiptap/react"
import { Smile } from "lucide-react"
import { useTheme } from "next-themes"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import data from "@emoji-mart/data"
import { cn } from "@/lib/utils"
import { MAIL_COMPOSE_BOTTOM_ICON_BTN } from "@/lib/mail-chrome-classes"
import { COMPOSE_PORTAL_Z } from "./compose-shared"
const LazyPicker = lazy(() => import("@emoji-mart/react"))
function ComposeEmojiPicker({ onSelect }: { onSelect: (emoji: { native: string }) => void }) {
const { resolvedTheme } = useTheme()
return (
<Suspense fallback={<div className="flex h-[435px] w-[352px] items-center justify-center text-sm text-muted-foreground">Chargement</div>}>
<LazyPicker
data={data}
onEmojiSelect={onSelect}
locale="fr"
theme={resolvedTheme === "dark" ? "dark" : "light"}
previewPosition="none"
skinTonePosition="search"
set="native"
/>
</Suspense>
)
}
export function ComposeEmojiButton({
editor,
}: {
editor: Editor | null
}) {
const [open, setOpen] = useState(false)
const handleSelect = useCallback(
(emoji: { native: string }) => {
editor?.chain().focus().insertContent(emoji.native).run()
setOpen(false)
},
[editor]
)
if (!editor) return null
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<button
type="button"
className={MAIL_COMPOSE_BOTTOM_ICON_BTN}
title="Insérer un emoji"
>
<Smile className="h-[18px] w-[18px]" />
</button>
</PopoverTrigger>
<PopoverContent
align="start"
side="top"
className={cn("w-auto border-0 bg-popover p-0 shadow-xl", COMPOSE_PORTAL_Z)}
onOpenAutoFocus={(e) => e.preventDefault()}
>
<ComposeEmojiPicker onSelect={handleSelect} />
</PopoverContent>
</Popover>
)
}