"use client" import { DialogDescription, DialogTitle } from "@radix-ui/react-dialog" import React, { ComponentProps, ComponentPropsWithoutRef, createContext, ElementRef, forwardRef, useContext, useMemo, } from "react" import { tv, type VariantProps } from "tailwind-variants" import { Drawer as SheetPrimitive } from "vaul" import { ChevronLeft, ChevronRight, Close } from "../../icons" import { overlayVariants } from "../../styles/utils/overlay" import { classNames } from "../../utils" import { Block, BlockProps } from "../Block" import { FlexCenter, FlexCenterProps } from "../FlexCenter" import { Media } from "../Media" import { Text } from "../Text" const sheetVariants = tv({ base: classNames( "fixed inset-y-0 z-sheet flex max-h-full w-full flex-col focus-visible:outline-hidden lg:max-w-[460px]", "bg-bg-app shadow-sm", ), variants: { direction: { left: "left-0", right: "right-0", }, }, }) export type SideSheetProps = Pick< ComponentProps, | "open" | "onOpenChange" | "modal" | "shouldScaleBackground" | "disablePreventScroll" | "repositionInputs" | "handleOnly" > & Omit, "content"> & VariantProps & { content: React.ReactNode withCloseIcon?: boolean overrides?: { Overlay: ComponentProps } } const SideSheetContext = createContext<{ direction: "left" | "right" withCloseIcon: boolean }>({ direction: "left", withCloseIcon: true, }) const SideSheetBase = forwardRef< ElementRef, SideSheetProps >(function SideSheet( { open, onOpenChange, content, children, className, overrides, modal, direction = "left", withCloseIcon = true, repositionInputs = false, handleOnly = true, ...props }, ref, ) { const value = useMemo( () => ({ direction, withCloseIcon }), [direction, withCloseIcon], ) return ( {children} {content} ) }) export const SideSheetHeader = ({ className, children, ...props }: FlexCenterProps) => { const { direction, withCloseIcon } = useContext(SideSheetContext) const MobileCloseIcon = direction === "left" ? ChevronLeft : ChevronRight return ( {children} {withCloseIcon && ( <> )} ) } export const SideSheetHeaderTitle = forwardRef< ElementRef, ComponentPropsWithoutRef >(function SideSheetTitle({ className, children, ...props }, ref) { return ( {children} ) }) export const SideSheetBody = forwardRef, BlockProps>( function SideSheetBody({ children, className, ...props }, ref) { return ( {children} ) }, ) export const SideSheetDescription = forwardRef< ElementRef, ComponentPropsWithoutRef >(function BottomSheetDescription({ className, content, ...props }, ref) { return ( {content} ) }) /** * Displays content that complements the main content of the screen. * The bottom variant of this is a common pattern for mobile devices. */ export const SideSheet = Object.assign(SideSheetBase, { Header: Object.assign(SideSheetHeader, { Title: SideSheetHeaderTitle }), Body: SideSheetBody, Description: SideSheetDescription, })