ultisuite-client/components/gmail/sidebar/sidebar-nav-options-sheet.tsx
2026-05-25 13:52:40 +02:00

148 lines
4.2 KiB
TypeScript

"use client"
import type { ReactNode } from "react"
import { Check } from "lucide-react"
import {
Sheet,
SheetClose,
SheetContent,
SheetTitle,
} from "@/components/ui/sheet"
import { XIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { NavColorDot } from "@/components/gmail/nav/nav-color-dot"
import { NavColorPicker } from "@/components/gmail/nav/nav-color-picker"
const sheetContentClass =
"max-h-[min(85vh,560px)] gap-0 overflow-hidden rounded-t-2xl border-[#dadce0] px-0 pb-[max(1rem,env(safe-area-inset-bottom))] pt-0 select-none left-1/2 right-auto w-[calc(100%-2rem)] max-w-md -translate-x-1/2 sm:max-w-lg"
export function SidebarNavSheetAction({
children,
onClick,
destructive,
}: {
children: ReactNode
onClick: () => void
destructive?: boolean
}) {
return (
<button
type="button"
className={cn(
"flex w-full items-center gap-3 px-4 py-3 text-left text-sm transition-colors active:bg-[#e8eaed]",
destructive
? "text-red-600 hover:bg-red-50 active:bg-red-100"
: "text-[#3c4043] hover:bg-[#f1f3f4]"
)}
onClick={onClick}
>
{children}
</button>
)
}
export function SidebarNavSheetSectionLabel({ children }: { children: ReactNode }) {
return (
<div className="px-4 py-1.5 text-[11px] font-medium uppercase tracking-wide text-[#5f6368]">
{children}
</div>
)
}
export function SidebarNavSheetDivider() {
return <div className="mx-4 border-b border-[#eceff1]" />
}
export function SidebarNavSheetCheckOption({
checked,
onPick,
children,
}: {
checked: boolean
onPick: () => void
children: ReactNode
}) {
return (
<button
type="button"
className="flex w-full items-center justify-between gap-3 px-4 py-3 text-left text-sm text-[#3c4043] transition-colors hover:bg-[#f1f3f4] active:bg-[#e8eaed]"
onClick={onPick}
>
<span className="min-w-0 flex-1">{children}</span>
<span className="flex size-4 shrink-0 items-center justify-center" aria-hidden={!checked}>
{checked ? <Check className="size-4 text-gray-900" strokeWidth={2} /> : null}
</span>
</button>
)
}
export function SidebarNavSheetColorPicker({
title,
dotClass,
swatches,
onPick,
}: {
title: string
dotClass: string
swatches: readonly string[]
onPick: (swatch: string) => void
}) {
return (
<div className="px-4 py-2">
<div className="mb-2 flex items-center gap-2 text-sm text-[#3c4043]">
<span className="flex size-5 shrink-0 items-center justify-center rounded-full border border-gray-300 bg-white">
<NavColorDot color={dotClass} />
</span>
{title}
</div>
<NavColorPicker
variant="sheet"
value={dotClass}
swatches={swatches}
onChange={onPick}
/>
</div>
)
}
export function SidebarNavOptionsSheet({
open,
onOpenChange,
title,
colorDotClass,
children,
}: {
open: boolean
onOpenChange: (open: boolean) => void
title: string
colorDotClass?: string
children: ReactNode
}) {
return (
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent side="bottom" hideClose className={sheetContentClass}>
<div className="relative flex items-center gap-3 border-b border-[#eceff1] px-4 py-3 pr-12">
{colorDotClass ? (
<span
className="flex size-5 shrink-0 items-center justify-center rounded-full border border-gray-300 bg-white"
aria-hidden
>
<NavColorDot color={colorDotClass} />
</span>
) : null}
<SheetTitle className="min-w-0 flex-1 truncate text-left text-base font-medium leading-5 text-[#3c4043]">
{title}
</SheetTitle>
<SheetClose
className="absolute right-4 top-1/2 flex size-8 -translate-y-1/2 items-center justify-center rounded-xs text-[#5f6368] opacity-80 outline-none transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-ring/50"
aria-label="Fermer"
>
<XIcon className="size-4" />
</SheetClose>
</div>
<div className="flex flex-col overflow-y-auto py-1">{children}</div>
</SheetContent>
</Sheet>
)
}